I had to remove one of my weblog entries from public view, at least for the moment. I'll explain later if and when the entry is no longer problematic.
I was born & raised in Seattle, Washington, and growing up I always enjoyed the local editorial cartoonists for the Seattle Times (Brian Basset, whom the paper unfortunately released years ago) and the Seattle Post-Intelligencer (David Horsey, who has won a couple of Pulitzer Prizes).
David Horsey is still at it, and he has come up with some gems, particularly recently. Today's is just an absolute gas (pun not intended).
This is mainly about my BigDecimal implementation in JavaScript.
One of the things I found out while writing that script is that multiplication provided correct values only when the number of digits in each part was no greater than 7. 7 digits * 7 digits = 14 digits, perfectly. 8 digits * 8 digits = problems. (With sixteen digits in a number value, you get funny results.)
So, I specifically coded BigDecimal not to store any final results in sections more than 7 digits. The gist of the mathematical operation was:
for (a = 0; a < this.digitArray.length; a++) {
for (b = 0; b < rightSide.digitArray.length; b++) {
response.digitArray[a + b + offset] += this.digitArray[a] * rightSide.digitArray[b]
}
}
Well, in revisiting the concept, I realized this afternoon that I didn't have to be quite that tight. If you have:
p = a + b, where a = n * 10^7 and b = some other n (< 10^7)
and also q = c + d, where c and d have corresponding values, then:
p * q = (a + b) * (c + d)
Breaking this down, it becomes:
p * q = (n_a * n_c) * 10^14 + ((n_a * n_d) + (n_b * n_c)) * 10^7 + (n_b * n_d)
(n_a * n_c) simply gets shifted one section to the left, so we don't have to worry about that. What should I do with the other three values, which could easily total over 10^14 anyway?
Well, there's no need to directly set a section's value, is there? Why not have a special function handle that, and when it detects a condition that would lead to an out-of-bounds value, handle it? That would eliminate the need for after-the-fact carrying operations.
for (a = 0; a < this.digitArray.length; a++) {
for (b = 0; b < rightSide.digitArray.length; b++) {
var this_1stHalf = Math.floor(this.digitArray[a] / 10000000);
var this_2ndHalf = this.digitArray[a] % 10000000;
var right_1stHalf = Math.floor(rightSide.digitArray[a] / 10000000);
var right_2ndHalf = rightSide.digitArray[a] % 10000000;
// addValue does our carry operations
response.addValue(a + b + offset - 1, this_1stHalf * right_1stHalf);
response.addValue(a + b + offset, this_1stHalf * right_2ndHalf * 10000000);
response.addValue(a + b + offset, this_2ndHalf * right_1stHalf * 10000000);
response.addValue(a + b + offset, this_2ndHalf * right_2ndHalf);
}
}
With that done, I could safely double the length of digits back up to 14, and thus double the number of digits the script could handle.
As an afterthought: with the integral types D provides, I don't have to do Math.floor() operations.
Oh, and that bitrot happens bit in the title? Well, I took one look at the coding style of the BigDecimal.js script as I posted it, and I could only stare in amazed horror. It works, but there's no way I'd write it that way now...
Earlier today, I managed to get a D language compiler working on my Linux operating system. I've been tinkering with the language, primarily working on translating my JavaScript-based BigDecimal library script to D. I'd written the script several years ago, and I figured it would be a good project to teach myself D.
According to the official D website, it's not too dissimilar to C++. But I do find a couple of the features very interesting. My design-by-contract script was inspired by this language, and the "unit test" concept is very nice...
I very seriously doubt mozilla.org will ever allow any D programming into their codebase within the next, oh, twenty to thirty years. All the same, I would be interested in seeing D utilized in writing XPCOM components.
I wonder what it would take to write a "DXPCOM", like "PyXPCOM" does for Python-based XPCOM components. Bear in mind, this is entirely idle speculation. There are other advances which I'm greatly interested in seeing in Mozilla (XTF, SVG to name a couple... Alex Fritze's work is quite impressive, and work on his code should take a much higher priority after the aviary 1.0's, imho).
On a separate note, when I first heard about the D language in 2002 (after reading the only article in Dr. Dobb's Journal that I ever understood!), I visited the DigitalMars D website. They have a concept of D in HTML which, although interesting, is semantically flawed. The idea is that D code goes inside <code>...</code> elements. I tried to convince them at the time that this was wrong, but apparently they haven't done anything about it. The script element is more appropriate for this, with a special type attribute. Would anyone care to evangelize them on this?
Maybe after I finish this script, I'll start learning how to tinker with the appearance of elements in Mozilla. CSS-3 text decoration is interesting to me, and I might seriously want to implement that. (I have a biased interest in that, as I want to make some non-linear text decorations as well, such as an arc over two letters to indicate the arc of a circle... or I can just wait for SVG on that...)
This bug is an evil Firefox 1.0 blocker. I can't figure out what's going on in the source code (nsDownloadManager.cpp, possibly nsExternalAppHandlerService.cpp) well enough to start working on a patch.
helpwanted: I don't know yet if this is a Windows-only bug or if it affects other platforms. I also don't know where in the code this is taking a turn for the worse. I need help determining these issues, so that a patch can be developed.
In this case, the bug is blocking me from releasing another nice little feature for this blog.
Please don't comment to this blog entry about whatever you discover. File your comments in the bug.
The "Featured Bug for Research" column is a new one for this blog, basically asking people to help me out on bugs that interest me and are not necessarily trivial to figure out. I'll use it primarily for issues where I'm just stuck.
UPDATE: Well, this blog entry got some attention. Within a few hours of me noting it here, a number of developers leaped on it, pointed out the basic flaw in the code, created a patch (porting another patch that already applied to Mozilla trunk), r+sr'd, and checked it in. We're waiting on the patch to finish baking on tbox and grab a nightly to test. Prospects are good.
UPDATE 2: Penalty flag on the kicker, offsides. We're still showing this bug as of a nightly grabbed from Tinderbox, internal timestamp 2004092506.
FINAL UPDATE: Ladies and gentlemen, this bug has been fixed. I apologize for retracting the entry, but due to its security-sensitive status, I felt I had to retract it momentarily.
Since the early days of HTML, people have designed their web sites such that pages within a certain domain name or directory shared common features. For instance, every page you read of this weblog has the title "Burning Chrome" at the top of the page.
With CGI scripts, PHP, ASP, etc., dynamic effects became possible. Many pages became a combination of static and dynamic, generated content. This weblog's individual entries are generated dynamically every time I update the database with a new entry. Also, when I approve a comment, it is readable through the URI of the page.
None of this, of course, is new.
However, when you think about it, a lot of bandwidth goes to downloading the static content along with the dynamic content. Wouldn't it be nice if you could have that static content cached? Sure, Mozilla's cache will store images and other complete objects... but when an HTML page changes (static + dynamic), the cached page gets thrown away, and a new complete set of static + dynamic markup is downloaded for that page.
Well, with a chrome application, it would be possible to "install" static content and query the server for the dynamic content...
Why not? If you make an XPI of your site's static content, and your site generates X(HT)ML anyway, then the client Mozilla-based browser could just HTTP GET a special XML document with just the dynamic content. A little rearranging of source markup, an iframe, and your site appears to the user.
I haven't started anything more than the concept on this, but if it turns out to be feasible (and if you think it's a good idea), I might just go ahead and ask for shortsite.mozdev.org to implement this.
At the very least, it could significantly cut down on the bandwidth of a host server. I would probably use shortsite on itself, just to demonstrate it.
UPDATE: biesi is right in his comment. XSLT is probably a better way to go than manually reconstructing the page from a chrome app. (I chose the name of this article as a pun, and I'm not afraid to toss a good idea, or a bad one, in favor of a better one.)
Still, the idea of using chrome to cache static content is appealing. Maybe the XSLT stylesheet itself is static...
This is a question I've been meaning to ask for ages. Although you could implement it through XBL, I get the distinct impression that's the wrong way to go.
So, I'm just looking for a list of steps, things I would have to learn, in order to do this.
Here's my guess-list:
(1) Write the specification behind the language and post it.
(2) Write the C++ code that determines how it looks.
(3) Write the C++ code that implements each element's DOM (probably each element should inherit from nsGenericElement.cpp, but that's another guess).
(4) Does it require a special class of document, perhaps inherited from XMLDocument? If so, write that document's implementation
(5) Write the code necessary to hook it into Mozilla's code natively. That is, how do you make sure your <foo:foo> element, when inserted in a XHTML document, actually calls on that element's C++ implementation?
(6) If you have a special document class for your language, does it require a special viewer?
(7) Don't forget your default CSS settings! (Where you'd install that is a mystery, though I'm guessing somewhere in resource:///)
(8) Package all this up as an XPI (is it even possible to install a new XML language by XPI? If not, it should be.)
Feedback strongly requested, and if you can come up with a working example (even just one element in a new language), I'll be delighted.
Whoops.
I'm kicking myself pretty hard right now. I've said for a very long time, "The first step in confirming there is a bug in someone else's work is confirming there are none in your own." Once again, I've violated my own favorite dictum.
There are bugs in the TreeWalker code I was working on. But what I was writing patches for was even worse: a flawed idea that didn't match the W3C Recommendation's text.
I'm going to go back to square one on my work, write a much humbler patch, write testcases specifically for that patch, and then file a bug.
UPDATE: Bug 260293. This one's much smaller, and I can back this one up with the Traversal spec.
SECOND UPDATE: Nope. I was wrong there too. TreeWalker spec sucks.
The open source community has always prided itself on the idea that if something is bugging you in an open-source product, you swat it.
Those of you who follow this blog should know I am just now learning C++. For those of you experienced with C++, I wonder: what are the differences between writing C++ under most circumstances, and writing C++ for Mozilla-based applications? nsCOMPtr was never in my copy of "Teach Yourself C++ in 24 Hours"...
Some of you might think I'm actually gainfully employed working on technology. That could not be farther from the truth...
I work at OfficeMax as a sales associate. For $7.50/hr. For whatever hours they want me to work. Although for a brief time I was getting 32 hours a week, they went overbudget on hours for the whole store and right now I'm getting 4.
This tech stuff I do whenever I can, as long as the bills get paid. It's a sad fact of life, particularly when my talents as a web developer get cut off whenever I don't have an Internet connection at home... I only recently launched the Abacus site, and I've had that ready to go for a while.
Now, I've recently had an offer to do some contract work for the local Knights of Columbus hall, which I am a member of. (Council 874; we celebrate our 100th anniversary next month.) $10/hr, lots of work to be done, and the guy wants to hire me. I want to work for him.
Then comes the question, "Oh, by the way, do you have any health coverage?"
*nnnnng*
I'm not going to lie to the guy (a potential employer and fellow Knight) about anything, much less that! It's a very legitimate question. Fortunately, it doesn't take much math to see that I would make more money doing the job and paying the cost of health insurance than I would by not taking the job. (This time.)
Still, health care coverage is something we all agree too many of us do without. But no one here in the United States can find a solution that's affordable financially. You can't even ask the government to provide health care for everyone because of the funding required to pay for it. (There would be a huge tax revolt if Congress were to ever try it.)
On another note: as I said earlier, I do this stuff when I can. If there's anyone who can help -- preferably with a job offer, but I'll take what I can get -- I'd appreciate it! I don't drink, and I don't smoke, so my expenses are really bare-bones minimum for a tech.
In the tradition of ecmaDebug.js and <xul:serverpost/>, here's another little idea I had and coded up.
Sometimes a function needs to be run once (as a cleanup operation, perhaps), but other functions call it more than once. In Abacus, I have at least one function (two, I think) that are run more often than they need to be. They should run, yes, but they can run after all other currently-running processes are done.
setTimeout is great, but what happens when two functions call for the same setTimeout?
I came up with setTimeoutOnce. Basically, if you have function A() call B() and C(), and both of these have the line:
setTimeoutOnce("D()", 0);
then after A() runs all the way through, D() executes once. Not twice, as a setTimeout would force.
It's a very tiny script, but I've tested it and it works nicely. It should allow me to save some processor time in Abacus. You might also
find it useful in your own scripts.
Feedback, including bugs in the implementation, is welcome. (Remember, per the rules of my current GMail contest, useful comments here earn invites if no one else has a higher-priority claim...)
I often go to the library here in Vallejo, which doesn't use Mozilla. Instead, they use Internet Explorer, despite all the little warnings about how big a piece of junk it is.
So, I want to check my GMail account using Internet Explorer. According to GMail's own site, IE5.5+ is supported.
http://gmail.google.com/gmail/help/about.html
According to IE6, GMail is broken.
Object expected Line: 54 Char: 16 ...
I figured, okay, I might as well tell Google about it. This IS a beta-test service, right? So I went looking for an e-mail address to say to Google, "Hey, you've got a bug here." Just being the good little tech that most of the invites have gone to.
Except there doesn't seem to be an e-mail address for them... no way, in fact, to contact GMail's developers or tech support if anything is wrong. GMail doesn't appear on any of Google's About pages, so that's a dead end too.
If you can't give feedback during a beta-test, what's the point of the beta-test?!? I'm not as upset about not being able to access GMail from IE (like they claimed I could) as I am about not having a way to really beta-test this thing.
Is it beta-testing, or marketing disguised as beta-testing?
I dearly hope Google is beta-testing the service as they claimed, and that they are looking for feedback. Maybe one of them will stumble across this blog entry (and if any of you have contacts @ Google, please point them to this!), and let us developers, hackers, techs and people testing their system tell them what we think they can improve! I would not be writing this blog entry if I could contact them directly.
Six more. I'll be giving them away based on the following priorities:
(1) Being the first to fix or file a valid bug against Mozilla which hinders development of Abacus. Basically, when something is broken or doesn't work in the Abacus code, and Abacus's source code is written correctly. (I expect very few people to come up with these, so don't sweat about it too much.) The more serious and specific bugs will get higher priority than vague, trivial bugs.
(2) Being the first to fix a bug in Abacus. There's lots of them, and some of them are pretty darned easy! All you would have to do is file the bug (if someone else hasn't), and then file a patch for review.
(3) Being the first to file a valid bug against Abacus. http://abacus.mozdev.org/bugs.html Again, many of these are easy... in some cases, the strict warnings tell you what I know about but haven't gotten around to getting done yet.
(4) Useful comments on subjects this weblog talks about. FYI, no one really took a look at my <xul:serverpost/> idea the last time I offered invites...
First-come, first-served does NOT apply. I'm looking for quality, not speed or quantity. Duplicate bug reports do not count!
UPDATE: For those looking to earn gmail invites per this entry: I've only given away one. So please add a comment to this blog entry if you qualify by one of the means above. Include first & last name so I can actually fill in the blanks GMail provides. Also, if you are filing a bug in Mozilla's bugzilla, please cc me! ajvincent@gmail. If you file a bug at MozDev, and I didn't get a copy of it, cc me and send me a private e-mail so I can notify the mozdev people.
(For the record, I gave away that invite unfairly. I clearly stated "valid", and right now it's UNCO, so mea culpa on that one. Further, it doesn't hinder Abacus operations at all, so big mea culpa on it! I'll try not to do it again, in case the bug turns out to be invalid or duplicate.)
(Still, don't let that stop you from filing bugs against Mozilla! More bug reports that are valid and meaningful are better than less.)
There are a number of (unfiled) bugs in Abacus, and there are some bugs in Mozilla which Abacus tries to work around. I'd really, really appreciate having some developers hammer with it a bit, file bugs as appropriate (in the right bug database), and start fixing them.
I really don't want to be the only developer on Abacus. I've spent too much time on this alone, and there's a lot to do. I really, really need help at this point.
On another note, one feature I would like to implement for Bugzilla would be a "transfer between installations" feature. It would probably be something like setting dependencies between one database and another. The easy part would be writing code and MySQL tables to store the dependencies. The hard part would be writing protocols for Bugzilla installations to talk to each other... including failure cases for when a cross-database dependency doesn't take effect. I wouldn't mind hearing opinions on how we could do this.
Incidentally, this is my 100th blog entry.
The website is up!!!
As of this moment, the XPI file for Abacus isn't quite available yet (I don't know why, it got checked in with everything else). I assume it is propagating to the download servers as we speak.
I am once again a happy man.
UPDATE: Yes, the XPI file is available. I have just tested the screenshots, and the files are horked on my local drive. I'm checking it now.
Incidentally, there is a Windows crash bug 258365 with Abacus right now. It appears to affect only Windows on 1.7+ builds. Be warned.
UPDATE 2: Screenshots have been fixed.
I've got six more. As stated in my last blog entry, all I ask is that you take a good look around this blog's archives and see if some entry I've written about interests you and/or is useful. If so, file a comment there, file a comment here, and I'll try to accomodate you.
It may not be first-come, first-served this time. Be aware that last time, I was able to react fairly quickly. It won't be until late afternoon today (PDT) before I can start handing them out.
UPDATE: Closed! Sorry, guys, but I had six and gave out six. The lucky six know who you are.
I've had a few people offering their own invites (one even allowed me to judge for them who should get them!), but I'm not going to go out of my way on this. It's all well and good for commenters here to privately contact each other, though.
I appreciate everyone who did take the time to look through my blog and respond. I restricted them to people who specifically commented in useful ways on the weblog. A couple people didn't qualify in my eyes (though I approved your comments anyway), so my apologies if you think you earned one and I didn't give one to you. I did say it wouldn't necessarily be first-come, first-served... I didn't have enough to hand them out willy-nilly.
Tying the last two paragraphs together: if you didn't get an invite from me and want one anyway, I have two options for you. (1) Contact someone who said they had invites, and ask them. From the looks of it, most appear to be more generous than I am. (2) Wait a few days for me to get more invites, and I'll do it all again for NEW comments. (In other words, comments you've already posted don't count for future goodies!)
Cheers!
Good Lord! I've blogged about a MathML editor, tools for editing XUL better, blogspam, build suggestions... and I get very little feedback.
I post ONE notice about GMail invites, and my weblog is flooded with responses!
If I get more invites, I'm going to politely ask that people actually give me feedback on the stuff I play with.
If I get a third round and no one does give me that feedback, I'll insist on it. :-)
Yes, I have six GMail invites if anyone wants them. I accepted an invite from a fellow CodingForums.com moderator, and so they're here if you want them.
I, however, am not entirely enthused about having a whole gigabyte of e-mail storage.
I cannot, for the life of me, figure out what I'd do with it!
http://www.w3.org/TR/2004/WD-sXBL-20040901/
Thank you, Ian Hickson. Thank you, David Hyatt. And also Jon Ferraiolo. I haven't read past the first example, that of inline XBL, and I like it already.
(which I did, and many thanks to bsmedberg for the -z 9 advice)
Although I was successful this time in pulling the tree, I'm thinking there are some little tweaks we can do to make the process more friendly for dialup developers (an oxymoron in the 21st century, but I fit in the category).
(1) SeamonkeyAll is a huge beast to pull. One foul-up in the pull (such as a disconnect that you don't catch in time), and your whole pull is hosed. I wonder if there's some way to identify all the directories SeamonkeyAll actually grabs for the user, stuff it into a list that the make process can parse while pulling, and then store that separately. That way, if an error happens, you still have a portion of the tree, and a logical point to restart.
(2) Pull-by-date should become mandatory in a dialup pull. I'm glad to see the .mozconfig script has that, and it should be used. I didn't use it earlier, and now I regret it.
(3) The client.mk process doesn't have a restart option. This is not good. Of course, the assumption inherent is that the checkout and/or build process failed because something was horked on the process, not in something beyond the process's control.
I'm not advocating an automatic restart. The developer doing a CVS update will be able to tell what's really at fault for a bad pull.
Could a script be written to (a) set the pull date, and (b) log which portions have or have not been pulled yet for said pull date? That way, we could include a special option in .mozconfig (--may-disconnect), which would run this script each time the client.mk process started up. Concurrent with a little user feedback (answering one or two questions about the last pull, and whether he wants a fresh update or to complete an earlier update), it would be a huge timesaver.
Broadband users would be advocated not to enable this option. :) Opinions?