digitalmars.D - Polishing D - suggestions and comments
- "Unknown W. Brackets" <unknown simplemachines.org> Jan 20 2008
- Walter Bright <newshound1 digitalmars.com> Jan 20 2008
- Jarrod <qwerty ytre.wq> Jan 21 2008
- Bjoern <nanali nospam-wanadoo.fr> Jan 21 2008
- Unknown W. Brackets <unknown simplemachines.org> Jan 21 2008
- Bjoern <nanali nospam-wanadoo.fr> Jan 22 2008
- Unknown W. Brackets <unknown simplemachines.org> Jan 22 2008
- Bjoern <nanali nospam-wanadoo.fr> Jan 22 2008
- Neal Alexander <wqeqweuqy hotmail.com> Jan 21 2008
- Unknown W. Brackets <unknown simplemachines.org> Jan 21 2008
- Daniel Lewis <murpsoft hotmail.com> Jan 21 2008
- Bill Baxter <dnewsgroup billbaxter.com> Jan 21 2008
- Unknown W. Brackets <unknown simplemachines.org> Jan 21 2008
- "Unknown W. Brackets" <unknown simplemachines.org> Jan 22 2008
- Daniel Lewis <murpsoft hotmail.com> Jan 22 2008
- Bill Baxter <dnewsgroup billbaxter.com> Jan 22 2008
- Bill Baxter <dnewsgroup billbaxter.com> Jan 22 2008
- Unknown W. Brackets <unknown simplemachines.org> Jan 22 2008
- Unknown W. Brackets <unknown simplemachines.org> Jan 22 2008
- Walter Bright <newshound1 digitalmars.com> Jan 23 2008
- Walter Bright <newshound1 digitalmars.com> Jan 22 2008
- Robert Fraser <fraserofthenight gmail.com> Jan 24 2008
- Dan <murpsoft hotmail.com> Jan 24 2008
- "Unknown W. Brackets" <unknown simplemachines.org> Jan 24 2008
I thought I might write down some of the many suggestions I have for making D really come into the spotlight as a language. They cover many areas, and I'm trying to address issues that I feel aren't being given - by what I've seen - enough attention. I'm sure many of you here will pick me apart, and I look forward to it. Hopefully some of the suggestions can improve D. I write these with experience with an open source project I lead the development of, and years of watching the Mozilla development process. I have no doubt that the majority of these things would be of great improvement, if they are possible and done. http://www.unknownbrackets.com/tutorials/polishing-d -[Unknown]
Jan 20 2008
Unknown W. Brackets wrote:I thought I might write down some of the many suggestions I have for making D really come into the spotlight as a language.
Thanks for taking the time to write this. I think your suggestions are very good.
Jan 20 2008
On Sun, 20 Jan 2008 21:32:45 -0800, Walter Bright wrote:Thanks for taking the time to write this. I think your suggestions are very good.
I think I should ask you here since it's in context with the Phobos suggestions. What are you planning to do with Tango? Personally I prefer the Phobos API for it's naming, organisation and documentation, but I also like the extra features tango adds and of course I don't want to say no to a faster garbage collector and less bugs, which leaves me torn. Perhaps it might be time to replace Phobos, or (even better) officially merge the two libraries? Better now than later.
Jan 21 2008
Unknown W. Brackets schrieb:I thought I might write down some of the many suggestions I have for making D really come into the spotlight as a language. http://www.unknownbrackets.com/tutorials/polishing-d
Interoptability : This will make IDE developers work extremely comfortable and will result in world class tools. Having this kind of interoptability (let me say interactive compiler) is a win win. Outstanding IDEs, making D even more productive, attractive, -> greater user base -> ... As a side effect I can imagine that dll/so support will be improved. f.i. Multithreading support. I really hope to see this features become reallity! Ergo : vote++ But for the moment just 2 little things : 1- make compiler output more consistent, in other words, easier to parse. (same is valid for profiler output) 2- write errors to stderr Regarding source-code-management/QA etc. : IMO this should be essential part of an D IDE. Simply having support for current systems like CVS/SVN,Mercurial, .. is not good enough. Excellent article Unknown ! Bjoern
Jan 21 2008
Thanks. It was just an idea I've had for a long time, I figured I'd throw into the end of the document as an example. I'm glad you think it's a good idea. Your point about stderr is a good one, and something I missed. This is important mainly on Linux. I mentioned the other somewhere. For management, I'm really talking about D itself. I'm mostly unconcerned about how people use D, as much as how D itself is developed and presented to them - I think that's what needs work, personally. -[Unknown] Bjoern Wrote:But for the moment just 2 little things : 1- make compiler output more consistent, in other words, easier to parse. (same is valid for profiler output) 2- write errors to stderr Regarding source-code-management/QA etc. : IMO this should be essential part of an D IDE. Simply having support for current systems like CVS/SVN,Mercurial, .. is not good enough. Excellent article Unknown ! Bjoern
Jan 21 2008
Unknown W. Brackets schrieb:For management, I'm really talking about D itself. I'm mostly unconcerned about how people use D, as much as how D itself is developed and presented to them - I think that's what needs work, personally. -[Unknown]
I just had the idea that you talked about developer Collaboration too... a bit hidden, behind the words...and I simply could not resist to say that current SCMs sux. (not ashamed) Bjoern
Jan 22 2008
Sorry, didn't mean to be patronizing, thought you might've skimmed the rest. Actually, you're right. I've had experience managing developers (as that's my current job in fact), and currently SCMs all seem to have their flaws. At the same time, all of them make things easier than nothing at all. -[Unknown] Bjoern Wrote:Yes I've recognized that :) I just had the idea that you talked about developer Collaboration too... a bit hidden, behind the words...and I simply could not resist to say that current SCMs sux. (not ashamed) Bjoern
Jan 22 2008
Unknown W. Brackets schrieb:Sorry, didn't mean to be patronizing, thought you might've skimmed the rest.
Actually, you're right. I've had experience managing developers (as that's my current job in fact), and currently SCMs all seem to have their flaws. At the same time, all of them make things easier than nothing at all. -[Unknown]
It is not my intention to waste your time but I'm curious (enough) about your opinion regarding using a RDBMS as SCM working-horse. Bjoern
Jan 22 2008
Honestly, I haven't followed recent developments - git for example - so I'm not going to go spout off unfounded opinions. But, from experience writing a CVS/RCS web viewer I would say a relational storage system would make things a lot more logical... -[Unknown] Bjoern wrote:Unknown W. Brackets schrieb:Sorry, didn't mean to be patronizing, thought you might've skimmed the rest.
Actually, you're right. I've had experience managing developers (as that's my current job in fact), and currently SCMs all seem to have their flaws. At the same time, all of them make things easier than nothing at all. -[Unknown]
It is not my intention to waste your time but I'm curious (enough) about your opinion regarding using a RDBMS as SCM working-horse. Bjoern
Jan 22 2008
Unknown W. Brackets wrote:I thought I might write down some of the many suggestions I have for making D really come into the spotlight as a language. They cover many areas, and I'm trying to address issues that I feel aren't being given - by what I've seen - enough attention. I'm sure many of you here will pick me apart, and I look forward to it. Hopefully some of the suggestions can improve D. I write these with experience with an open source project I lead the development of, and years of watching the Mozilla development process. I have no doubt that the majority of these things would be of great improvement, if they are possible and done. http://www.unknownbrackets.com/tutorials/polishing-d -[Unknown]
Having a highly optimized and pluggable GC would go a long way i think. It seems like sometimes a naive implementation in D can be slower than its Java counterpart -- kind of a kick in the teeth IMO. People tend to have a false sense of security that stuff will automatically be faster because its native compiled. It wouldn't hurt to have an article explaining the performance implications of some of the more exotic features of the language either. On an unrelated note: i've noticed a *lot* of code tends to use templated function parameters for stuff like read()/write() operations. This type of usage pattern should probably be supported in a different way IMO. Things to consider (off the top of my head): **** Avoid template code replication for different types by defining common attributes / operations -- some type of numerical interface that defines operations for built-in and user types. This doesnt have to mean that basic types become real classes but that the compiler knows how to generate stubs for each operation. t_interface ordinal { void inc(); void plus(ordinal); ... } t_interface copyable { void* ptr(); size_t size(); void copy(copyable); ... } Side note: Maybe the "copyable" interface could be overloaded to perform endian conversion or simple crypto etc. t_interface number : ordinal, copyable, ...; type double : number type int : number type char : ordinal, copyable; class user_t : number { uint64_t backing; size(){ return backing.sizeof; } inc(){ ++backing; } ... } void f(number x){ x.inc; printf("size=%d", x.size); } double d; int i; char c; user_t t; f(d); -> size=8 f(i); -> size=4 f(c); -> size=1 f(t); -> size=8 **** Function parameter assignment double d; file.read(d, offset=4); void read(copyable data, size_t offset = void, int flags = 1234){ ... } ("void" used to ignore options instead of hacks like size_t.max would be nice) I dunno, its kind of a half baked idea i guess, but something to consider.
Jan 21 2008
I tried to stay away from the language, syntax, style, etc. for the most part. There are things to talk about there, and plenty of opinions flying around. Even if I were an expert on compiler design and theory, that's getting enough attention. I'm more concerned about process. Whether or not D has a pluggable GC or better interface design won't really prevent D from becoming a widely used language. They are good things to think about and discuss, nonetheless. C/C++, Perl, PHP, Java, all languages have design flaws. But almost all of them have covered the issues I mentioned - or else they wouldn't have become well known languages. I think that's the biggest issue for D right now. -[Unknown] Neal Alexander Wrote:Having a highly optimized and pluggable GC would go a long way i think. It seems like sometimes a naive implementation in D can be slower than its Java counterpart -- kind of a kick in the teeth IMO. People tend to have a false sense of security that stuff will automatically be faster because its native compiled. It wouldn't hurt to have an article explaining the performance implications of some of the more exotic features of the language either. On an unrelated note: i've noticed a *lot* of code tends to use templated function parameters for stuff like read()/write() operations. This type of usage pattern should probably be supported in a different way IMO. Things to consider (off the top of my head): **** Avoid template code replication for different types by defining common attributes / operations -- some type of numerical interface that defines operations for built-in and user types. This doesnt have to mean that basic types become real classes but that the compiler knows how to generate stubs for each operation. t_interface ordinal { void inc(); void plus(ordinal); ... } t_interface copyable { void* ptr(); size_t size(); void copy(copyable); ... } Side note: Maybe the "copyable" interface could be overloaded to perform endian conversion or simple crypto etc. t_interface number : ordinal, copyable, ...; type double : number type int : number type char : ordinal, copyable; class user_t : number { uint64_t backing; size(){ return backing.sizeof; } inc(){ ++backing; } ... } void f(number x){ x.inc; printf("size=%d", x.size); } double d; int i; char c; user_t t; f(d); -> size=8 f(i); -> size=4 f(c); -> size=1 f(t); -> size=8 **** Function parameter assignment double d; file.read(d, offset=4); void read(copyable data, size_t offset = void, int flags = 1234){ ... } ("void" used to ignore options instead of hacks like size_t.max would be nice) I dunno, its kind of a half baked idea i guess, but something to consider.
Jan 21 2008
Content-Type: text/plain Walter, I'm volunteering to head up a web development project to revamp the 'site, should you be interested. I'm sure a shiny new website would certainly give D a toe up in the external appeal department. I'm not running a web design firm. I'm really not interested in advertising potential or the likes. I'd just like to commit something I can be proud of back to the community; and I should probably do the same for Walnut later anyways. I've been a web designer for the last 11 years, and I know most, if not all the tricks with CSS and AJAX and the rest. I fact, that's how I got into programming. I'm currently a Web Site Manager for one of the plethora of internal websites within Citi, and the only one I know of that's W3C standards conformant. It's also WAI AA conformant, and implements some cutting edge stuff that I haven't seen other people on the web do such as: - keyboard accessible multi-tier horizontal-or-vertical suckerfish menus with the fix for the IE6 select box overlay bug. - keyboard accessible toggle-able list-based suckerfish file tree generated from the file system. - automatic user authentication and authorization using Active Directory; which is honestly limited to intranet applications. - ajax SQL queries dumping into an embedded OWC excel spreadsheet. I've attached screenshots from two previous iterations of my website for Citi to ease worries. Regards, Daniel Lewis Unknown W. Brackets Wrote:I tried to stay away from the language, syntax, style, etc. for the most part. There are things to talk about there, and plenty of opinions flying around. Even if I were an expert on compiler design and theory, that's getting enough attention. I'm more concerned about process. Whether or not D has a pluggable GC or better interface design won't really prevent D from becoming a widely used language. They are good things to think about and discuss, nonetheless. C/C++, Perl, PHP, Java, all languages have design flaws. But almost all of them have covered the issues I mentioned - or else they wouldn't have become well known languages. I think that's the biggest issue for D right now. -[Unknown]
Jan 21 2008
Daniel Lewis wrote:Walter, I'm volunteering to head up a web development project to revamp the 'site, should you be interested. I'm sure a shiny new website would certainly give D a toe up in the external appeal department. I'm not running a web design firm. I'm really not interested in advertising potential or the likes. I'd just like to commit something I can be proud of back to the community; and I should probably do the same for Walnut later anyways. I've been a web designer for the last 11 years, and I know most, if not all the tricks with CSS and AJAX and the rest. I fact, that's how I got into programming. I'm currently a Web Site Manager for one of the plethora of internal websites within Citi, and the only one I know of that's W3C standards conformant. It's also WAI AA conformant, and implements some cutting edge stuff that I haven't seen other people on the web do such as: - keyboard accessible multi-tier horizontal-or-vertical suckerfish menus with the fix for the IE6 select box overlay bug. - keyboard accessible toggle-able list-based suckerfish file tree generated from the file system. - automatic user authentication and authorization using Active Directory; which is honestly limited to intranet applications. - ajax SQL queries dumping into an embedded OWC excel spreadsheet. I've attached screenshots from two previous iterations of my website for Citi to ease worries. Regards, Daniel Lewis
That would be fabulous. My vote would be for a design at around the Slashdot level of glitz. Not too much popup bling-bling or shiny faux glass junk. The Citi pages look a little too shiny to me. Good for Citi I think but not for a grass-roots programming language website. In terms of functionality, making the user-comments in-line would be a big help. Most people don't notice the "comments" button at the top of each doc page, and obviously the comments on those external pages don't show up when you do a Ctrl-F find-on-page search. --bb
Jan 21 2008
Aha, I thought that was somewhere... but couldn't find it. I touched on this briefly. It also represents problems as far as SEO (something that could be improved on D's pages.) For example, the fact that these two, entirely separate in Google's eyes, URLs work is bad: http://www.digitalmars.com/d/changelog.html http://digitalmars.com/d/changelog.html In addition, really, all the pages within d/ should 301 redirect to 2.0/ so that 1.0 and 2.0 are each present in their pages' URLs. This would make searching for documentation on a specific tree simpler and most likely improve relevancy. But, this is more specific than I really wanted to get with the website's needs. The important thing is making the decision to get the changes done, and taking the time to review who to work with on it. Maybe an internal team of volunteers, maybe an outside agency. This can't happen until responsibility is better dispersed... As a side note, I work for a web company, and we use PHP primarily - which language I do like. But it would be cool to see D eat its own dogfood here, and host the website on its own, lightweight webserver with D-coded dynamic pages. This wouldn't be hard to write at all, and would really show the versatility of D (as well as efficiency, assuming it handled load well.) Maybe not practically the best, though. -[Unknown] Bill Baxter Wrote:In terms of functionality, making the user-comments in-line would be a big help. Most people don't notice the "comments" button at the top of each doc page, and obviously the comments on those external pages don't show up when you do a Ctrl-F find-on-page search.
Jan 21 2008
Well, I noticed that this is being done, which is great. However, it's been done using http-equiv Refresh redirects. This is not going to improve Google PageRanks. Really those redirects need to be 301 results coming from Apache. Easiest way to do this is with an .htaccess file or in httpd.conf. It can be done with Redirect or RewriteEngine/RewriteRule. Here's an example: RewriteRule ^d/(phobos/.*)$ d/2.0/$1 [NS,L,R=301] RewriteRule ^d/([^/]+\.html$ d/2.0/$1 [NS,L,R=301] Or something similar. Just my suggestion to maintain as much ranking and relevance for current pages as possible. -[Unknown] Unknown W. Brackets wrote:Aha, I thought that was somewhere... but couldn't find it. I touched on this briefly. It also represents problems as far as SEO (something that could be improved on D's pages.) For example, the fact that these two, entirely separate in Google's eyes, URLs work is bad: http://www.digitalmars.com/d/changelog.html http://digitalmars.com/d/changelog.html In addition, really, all the pages within d/ should 301 redirect to 2.0/ so that 1.0 and 2.0 are each present in their pages' URLs. This would make searching for documentation on a specific tree simpler and most likely improve relevancy. But, this is more specific than I really wanted to get with the website's needs. The important thing is making the decision to get the changes done, and taking the time to review who to work with on it. Maybe an internal team of volunteers, maybe an outside agency. This can't happen until responsibility is better dispersed... As a side note, I work for a web company, and we use PHP primarily - which language I do like. But it would be cool to see D eat its own dogfood here, and host the website on its own, lightweight webserver with D-coded dynamic pages. This wouldn't be hard to write at all, and would really show the versatility of D (as well as efficiency, assuming it handled load well.) Maybe not practically the best, though. -[Unknown] Bill Baxter Wrote:In terms of functionality, making the user-comments in-line would be a big help. Most people don't notice the "comments" button at the top of each doc page, and obviously the comments on those external pages don't show up when you do a Ctrl-F find-on-page search.
Jan 22 2008
Well, I haven't heard a word. I guess he figures he'll keep doing it himself.
Last night I hacked on Walnut some more; removed the block allocator crap,
reorganized the parser file, made it handle for() and automatic semicolon
insertion, as well as escape characters in strings.
Not much left to do before the parser is done; some tree shuffling and a few
statements.
A question; how does one differentiate between an object literal and a code
block in ECMAScript?
I find the following:
{ bob: "hello" }
Is this:
a) an object
b) a code block with a label, bob, referring to a statement only containing a
string?
I can create more elaborate examples which could be either, and to be honest
the best I can think to do is parse it as an Object literal unless we get an
invalid token?
Unknown W. Brackets Wrote:
Well, I noticed that this is being done, which is great. However, it's
been done using http-equiv Refresh redirects. This is not going to
improve Google PageRanks. Really those redirects need to be 301 results
coming from Apache.
Easiest way to do this is with an .htaccess file or in httpd.conf. It
can be done with Redirect or RewriteEngine/RewriteRule. Here's an example:
RewriteRule ^d/(phobos/.*)$ d/2.0/$1 [NS,L,R=301]
RewriteRule ^d/([^/]+\.html$ d/2.0/$1 [NS,L,R=301]
Or something similar. Just my suggestion to maintain as much ranking
and relevance for current pages as possible.
-[Unknown]
Jan 22 2008
Daniel Lewis wrote:Well, I haven't heard a word. I guess he figures he'll keep doing it himself.
Why don't you try emailing him directly. He does have an email address. And it's not that hard to find for someone as web savvy as you. ;-) --bb
Jan 22 2008
Bill Baxter wrote:Daniel Lewis wrote:Well, I haven't heard a word. I guess he figures he'll keep doing it himself.
Why don't you try emailing him directly. He does have an email address. And it's not that hard to find for someone as web savvy as you. ;-)
But let me guess at his reservations -- from what I understand, he has a system that works now and is mostly automated, generating most of the html automatically using ddoc. So if I were Walter I'd be leery of the situation where someone spends a week making a great website, drops it and a hundred files of whiz-bang PHP/CSS/perl/javascript code in my lap, and then disappears. The good thing about the current system is that Walter understands it completely because he wrote it. That means that when something goes wrong, or he urgently needs to make the D2.0 pages purple, he knows how. So the question is: is there some way you can overhaul the website that won't force him to change his workflow? At least I'm guessing that's what he'd want to know. :-) --bb
Jan 22 2008
Well, that would be silly. I work for one of many companies that creates sites for people with the very specific intent that the client becomes able to manage the site (sans major updates) completely on their own with no programming knowledge. This has been popular since like 2001 or something. It's nothing new, a covered problem. In any case, it's holding onto everything and wanting to be able to pick things up on any aspect that would limit D. Sometimes you have to trust other people, and do things in a standard enough way that you won't deep fry if your trust is misplaced. Sorry if I just keep repeating that.... -[Unknown] Bill Baxter Wrote:But let me guess at his reservations -- from what I understand, he has a system that works now and is mostly automated, generating most of the html automatically using ddoc. So if I were Walter I'd be leery of the situation where someone spends a week making a great website, drops it and a hundred files of whiz-bang PHP/CSS/perl/javascript code in my lap, and then disappears. The good thing about the current system is that Walter understands it completely because he wrote it. That means that when something goes wrong, or he urgently needs to make the D2.0 pages purple, he knows how. So the question is: is there some way you can overhaul the website that won't force him to change his workflow? At least I'm guessing that's what he'd want to know. :-) --bb
Jan 22 2008
From memory, not looking at the spec, aren't code blocks always proceeded by
function () or similar?
Example:
var f = function ()
{
label:
"hello"
}
var o = {
label: "hello"
};
I may be wrong. But that's what I remember...
-[Unknown]
Daniel Lewis Wrote:
Well, I haven't heard a word. I guess he figures he'll keep doing it himself.
Last night I hacked on Walnut some more; removed the block allocator crap,
reorganized the parser file, made it handle for() and automatic semicolon
insertion, as well as escape characters in strings.
Not much left to do before the parser is done; some tree shuffling and a few
statements.
A question; how does one differentiate between an object literal and a code
block in ECMAScript?
I find the following:
{ bob: "hello" }
Is this:
a) an object
b) a code block with a label, bob, referring to a statement only containing a
string?
I can create more elaborate examples which could be either, and to be honest
the best I can think to do is parse it as an Object literal unless we get an
invalid token?
Jan 22 2008
Daniel Lewis wrote:I'm volunteering to head up a web development project to revamp the 'site, should you be interested. I'm sure a shiny new website would certainly give D a toe up in the external appeal department.
That would be great! Would you like to start with a revamped style.css ?
Jan 23 2008
Unknown W. Brackets wrote:http://www.unknownbrackets.com/tutorials/polishing-d
Now on Reddit: http://reddit.com/r/programming/info/669pe/comments/
Jan 22 2008
You mentioned IDEs a couple times, specifically in that they should be able to access DMD via some sort of API. While this would be great, Descent (in trunk, sadly the kinks are still being worked out...) takes a different approach. We have a full Java port of the DMD semantic front-end, which we are using to do things like display errors inline as the user types. From working with Descent, I can say that having programatic access to the AST would be nice, but since most advanced IDEs would want to extend it anyway, it's a lot of work for a small gain.
Jan 24 2008
Robert Fraser Wrote:You mentioned IDEs a couple times, specifically in that they should be able to access DMD via some sort of API. While this would be great, Descent (in trunk, sadly the kinks are still being worked out...) takes a different approach. We have a full Java port of the DMD semantic front-end, which we are using to do things like display errors inline as the user types. From working with Descent, I can say that having programatic access to the AST would be nice, but since most advanced IDEs would want to extend it anyway, it's a lot of work for a small gain.
Yeah, D exposing the AST would be a *huge* benefit to modifying the compiler, and allowing things like third party profilers and optimizers. For profiling, I've always argued that I want this: ~~~ I can't rightly find out all the things that modify my variable 'x' without an AST; so how am I supposed to notice when I write if(x < 0) x = Math_bla(x); before the only three places calling a function, and then inside the function deep in another file it's already got int Math_bla(x) { if(x > 0) do something if(x == 0) do something else if(x == double.nan) ... } ~~~ This really should be noticed by a profiler/optimizer, so that the programmer can detect impossible branch cases. There's more. We really ought to have a "potential range filter" for numbers; so when we do this: x ^= 1; And later we go: switch(x) { case 1: case 2: case 3: case 4: } When we look at x in that switch, we see that it's inherently even. The problem is intractable without an AST; and even then, the optimizer/profiler will be a grand project.
Jan 24 2008
Actually, I'm much more interested in basic things: proper highlighting that stays up to date with the language, basic syntax checking that really works, proper error file/line integration that doesn't suffer from pretty printing, etc. This is from my experience trying to write a D highlighter/language service using the VSIP package for Visual Studio. But really that's just a thought. I would like to see D do something else "cool" other than just the language itself, but the other things I noted are (imho) much bigger issues. -[Unknown] Robert Fraser wrote:You mentioned IDEs a couple times, specifically in that they should be able to access DMD via some sort of API. While this would be great, Descent (in trunk, sadly the kinks are still being worked out...) takes a different approach. We have a full Java port of the DMD semantic front-end, which we are using to do things like display errors inline as the user types. From working with Descent, I can say that having programatic access to the AST would be nice, but since most advanced IDEs would want to extend it anyway, it's a lot of work for a small gain.
Jan 24 2008









Jarrod <qwerty ytre.wq> 