digitalmars.D - Extra semicolons, Errors or not ?
- =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> Feb 20 2005
- Derek Parnell <derek psych.ward> Feb 20 2005
- "Matthew" <admin stlsoft.dot.dot.dot.dot.org> Feb 20 2005
- "Unknown W. Brackets" <unknown simplemachines.org> Feb 20 2005
- "Regan Heath" <regan netwin.co.nz> Feb 20 2005
- "Unknown W. Brackets" <unknown simplemachines.org> Feb 20 2005
- "Regan Heath" <regan netwin.co.nz> Feb 20 2005
- brad domain.invalid Feb 20 2005
- "Regan Heath" <regan netwin.co.nz> Feb 20 2005
- "Jarrett Billingsley" <kb3ctd2 yahoo.com> Feb 20 2005
- "Matthew" <admin stlsoft.dot.dot.dot.dot.org> Feb 20 2005
- "Regan Heath" <regan netwin.co.nz> Feb 20 2005
- brad domain.invalid Feb 20 2005
- "Regan Heath" <regan netwin.co.nz> Feb 20 2005
- Manfred Nowak <svv1999 hotmail.com> Feb 21 2005
- "Regan Heath" <regan netwin.co.nz> Feb 21 2005
- "Matthew" <admin stlsoft.dot.dot.dot.dot.org> Feb 20 2005
- John Reimer <brk_6502 yahoo.com> Feb 20 2005
- "Regan Heath" <regan netwin.co.nz> Feb 20 2005
- zwang <nehzgnaw gmail.com> Feb 20 2005
- John Reimer <brk_6502 yahoo.com> Feb 20 2005
- =?ISO-8859-15?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> Feb 20 2005
- MicroWizard <MicroWizard_member pathlink.com> Feb 21 2005
- "Regan Heath" <regan netwin.co.nz> Feb 21 2005
- Georg Wrede <georg.wrede nospam.org> Feb 21 2005
- "Matthew" <admin stlsoft.dot.dot.dot.dot.org> Feb 20 2005
- zwang <nehzgnaw gmail.com> Feb 20 2005
- =?UTF-8?B?VGhvbWFzIEvDvGhuZQ==?= Feb 20 2005
Are any of these extra semicolons really errors ?void f() { }; class C { }; struct S { char c; }; union U { char c; }; void main() { if (false) { }; foreach(char c; "") { }; ; null; }
They all pass the current D compiler silently... --anders PS. Not the "char c;" one, but the rest of them.
Feb 20 2005
On Mon, 21 Feb 2005 00:22:49 +0100, Anders F Björklund wrote:Are any of these extra semicolons really errors ?void f() { }; class C { }; struct S { char c; }; union U { char c; }; void main() { if (false) { }; foreach(char c; "") { }; ; null; }
They all pass the current D compiler silently...
Not to me ;-) But a naked semi-colon and the 'null;' is fairly meaningless to point where one may think that the coder has made a mistake. However note that if (true); foreach(char c; ""); while(true); are compiler errors. -- Derek Melbourne, Australia 21/02/2005 10:35:03 AM
Feb 20 2005
"Derek Parnell" <derek psych.ward> wrote in message news:fewqzt2viqdl.btneu9e85pr2$.dlg 40tude.net...On Mon, 21 Feb 2005 00:22:49 +0100, Anders F Björklund wrote:Are any of these extra semicolons really errors ?void f() { }; class C { }; struct S { char c; }; union U { char c; }; void main() { if (false) { }; foreach(char c; "") { }; ; null; }
They all pass the current D compiler silently...
Not to me ;-) But a naked semi-colon and the 'null;' is fairly meaningless to point where one may think that the coder has made a mistake. However note that if (true); foreach(char c; ""); while(true); are compiler errors.
I presume that one needs to do if(true) {} foreach(char c; "") {} while(true) {} ??
Feb 20 2005
Yep, or, in the more common cases:
foreach (char c; "")
continue;
while (true)
continue;
Which makes it a lot cleaner and more readable imho (but obviously
cannot be done for if.)
-[Unknown]
"Derek Parnell" <derek psych.ward> wrote in message
news:fewqzt2viqdl.btneu9e85pr2$.dlg 40tude.net...
On Mon, 21 Feb 2005 00:22:49 +0100, Anders F Björklund wrote:
Are any of these extra semicolons really errors ?
void f()
{
};
class C
{
};
struct S
{
char c;
};
union U
{
char c;
};
void main()
{
if (false)
{
};
foreach(char c; "")
{
};
;
null;
}
They all pass the current D compiler silently...
Not to me ;-) But a naked semi-colon and the 'null;' is fairly
meaningless
to point where one may think that the coder has made a mistake.
However note that
if (true);
foreach(char c; "");
while(true);
are compiler errors.
I presume that one needs to do
if(true)
{}
foreach(char c; "")
{}
while(true)
{}
??
Feb 20 2005
On Sun, 20 Feb 2005 17:07:59 -0800, Unknown W. Brackets <unknown simplemachines.org> wrote:Yep, or, in the more common cases: foreach (char c; "") continue; while (true) continue; Which makes it a lot cleaner and more readable imho (but obviously cannot be done for if.) -[Unknown]
<snip rest of upside down reply> Or we could add a "noop" expression, to more exactly specify the programmers intent. eg. foreach(char c; "") noop; while(true) noop; if (true) noop; Regan
Feb 20 2005
I would think that most compilers would be able to tell this:
while (true)
{
}
Is the same as this:
while (true)
continue;
So a "noop" wouldn't be required... and, in most cases, when you do:
if (true)
{
}
Well, I can only imagine that being useful for an else/else if
simlpification, which is ugly imho and hopefully is optimized out anyway.
I can't really think of a case where a "noop" would be required... and
anyway, couldn't you do this:
if (true)
0;
-[Unknown]
On Sun, 20 Feb 2005 17:07:59 -0800, Unknown W. Brackets
<unknown simplemachines.org> wrote:
Yep, or, in the more common cases:
foreach (char c; "")
continue;
while (true)
continue;
Which makes it a lot cleaner and more readable imho (but obviously
cannot be done for if.)
-[Unknown]
<snip rest of upside down reply>
Or we could add a "noop" expression, to more exactly specify the
programmers intent.
eg.
foreach(char c; "") noop;
while(true) noop;
if (true) noop;
Regan
Feb 20 2005
On Sun, 20 Feb 2005 17:55:13 -0800, Unknown W. Brackets <unknown simplemachines.org> wrote:I would think that most compilers would be able to tell this: while (true) { } Is the same as this: while (true) continue;
Maybe, but why should they have to? Having several ways to achieve the same thing is generally a bad idea.So a "noop" wouldn't be required... and, in most cases, when you do: if (true) { } Well, I can only imagine that being useful for an else/else if simlpification, which is ugly imho and hopefully is optimized out anyway. I can't really think of a case where a "noop" would be required...
That's because you're thinking of this idea in different terms. I'm not trying to suggest noop is 'required' in order to achieve some program logic, what I'm suggesting is that it might improve readability and avoid bugs.and anyway, couldn't you do this: if (true) 0;
I have no idea. It's beside the point I am trying to make. Is using "noop" more obvious that the various connotations you've shown so far for telling other programmers that you intend for nothing to happen at that point in the code? [For] - If there is only 1 way, then once you learn that 1 way, it's obvious. - It's unlikely you'll type "noop" by accident and if the other methods are made illegal then you cannot accidently type a no-op i.e. for(s = bf; *s != '\0'; s++); <- accidental semicolon here length++ [Against] - One more keyword to learn. Regan-[Unknown]On Sun, 20 Feb 2005 17:07:59 -0800, Unknown W. Brackets <unknown simplemachines.org> wrote:Yep, or, in the more common cases: foreach (char c; "") continue; while (true) continue; Which makes it a lot cleaner and more readable imho (but obviously cannot be done for if.) -[Unknown]
Or we could add a "noop" expression, to more exactly specify the programmers intent. eg. foreach(char c; "") noop; while(true) noop; if (true) noop; Regan
Feb 20 2005
[Against] - One more keyword to learn.
Ie, noop is pure syntactic sugar. the NOP instruction in an assembler instruction that is often used to control pipeline flushing, etc. I would hope anyone needing a genuine NOP would check the assembler output, but maybe not. Brad
Feb 20 2005
On Mon, 21 Feb 2005 16:16:47 +1300, <brad domain.invalid> wrote:[Against] - One more keyword to learn.
Ie, noop is pure syntactic sugar. the NOP instruction in an assembler instruction that is often used to control pipeline flushing, etc. I would hope anyone needing a genuine NOP would check the assembler output, but maybe not.
Good point, is there another better keyword maybe? or do you think it's a bad idea in general? Regan
Feb 20 2005
Is using "noop" more obvious that the various connotations you've shown so far for telling other programmers that you intend for nothing to happen at that point in the code?
How about a comment? ;) if(x) { // nothing happens here. really. }
Feb 20 2005
I have a personal coding standard that says an empty block *must* be
represented with
{}
and not
{
}
or
{;}
or
;
etc.
This makes it very easy to not get caught up on false +ves. (Of course,
false -ves are poss. <G>)
But since it's a personal one, others may have something different that
works equally well ...
"Unknown W. Brackets" <unknown simplemachines.org> wrote in message
news:cvbc9d$129h$1 digitaldaemon.com...
Yep, or, in the more common cases:
foreach (char c; "")
continue;
while (true)
continue;
Which makes it a lot cleaner and more readable imho (but obviously
cannot be done for if.)
-[Unknown]
"Derek Parnell" <derek psych.ward> wrote in message
news:fewqzt2viqdl.btneu9e85pr2$.dlg 40tude.net...
On Mon, 21 Feb 2005 00:22:49 +0100, Anders F Björklund wrote:
Are any of these extra semicolons really errors ?
void f()
{
};
class C
{
};
struct S
{
char c;
};
union U
{
char c;
};
void main()
{
if (false)
{
};
foreach(char c; "")
{
};
;
null;
}
They all pass the current D compiler silently...
Not to me ;-) But a naked semi-colon and the 'null;' is fairly
meaningless
to point where one may think that the coder has made a mistake.
However note that
if (true);
foreach(char c; "");
while(true);
are compiler errors.
I presume that one needs to do
if(true)
{}
foreach(char c; "")
{}
while(true)
{}
??
Feb 20 2005
What do you think of creating a keyword for it, and making the rest
illegal.
eg.
if (true)
<keyword>
instead of all the possible premutations.
; has been made illegal in cases like the above as it's a source of bugs,
having a keyword does the same, plus makes the code more obvious to others.
Can the compiler optimise if it's told this explicitly?
At the cost of adding another keyword.
I suggested "noop" but Brad suggested it might get confused with the NOP
assembler instruction.
This was really just a random thought passing through my head, I'm not
sure there is a problem that needs solving, the possible error cases i.e.
using ';' are illegal the rest are unlikely to be done accidently and make
sense to most people (everyone?)
Regan
On Mon, 21 Feb 2005 13:56:21 +1100, Matthew
<admin stlsoft.dot.dot.dot.dot.org> wrote:
I have a personal coding standard that says an empty block *must* be
represented with
{}
and not
{
}
or
{;}
or
;
etc.
This makes it very easy to not get caught up on false +ves. (Of course,
false -ves are poss. <G>)
But since it's a personal one, others may have something different that
works equally well ...
"Unknown W. Brackets" <unknown simplemachines.org> wrote in message
news:cvbc9d$129h$1 digitaldaemon.com...
Yep, or, in the more common cases:
foreach (char c; "")
continue;
while (true)
continue;
Which makes it a lot cleaner and more readable imho (but obviously
cannot be done for if.)
-[Unknown]
"Derek Parnell" <derek psych.ward> wrote in message
news:fewqzt2viqdl.btneu9e85pr2$.dlg 40tude.net...
On Mon, 21 Feb 2005 00:22:49 +0100, Anders F Björklund wrote:
Are any of these extra semicolons really errors ?
void f()
{
};
class C
{
};
struct S
{
char c;
};
union U
{
char c;
};
void main()
{
if (false)
{
};
foreach(char c; "")
{
};
;
null;
}
They all pass the current D compiler silently...
Not to me ;-) But a naked semi-colon and the 'null;' is fairly
meaningless
to point where one may think that the coder has made a mistake.
However note that
if (true);
foreach(char c; "");
while(true);
are compiler errors.
I presume that one needs to do
if(true)
{}
foreach(char c; "")
{}
while(true)
{}
??
Feb 20 2005
Regan Heath wrote:What do you think of creating a keyword for it, and making the rest illegal. eg. if (true) <keyword>
comment it - ie: while (wait_on_some_event () { /* do nothing */ }; I don't see that having a compiler keyword helps or hinders the programmer either way. Brad
Feb 20 2005
On Mon, 21 Feb 2005 16:35:46 +1300, <brad domain.invalid> wrote:Regan Heath wrote:What do you think of creating a keyword for it, and making the rest illegal. eg. if (true) <keyword>
comment it - ie: while (wait_on_some_event () { /* do nothing */ }; I don't see that having a compiler keyword helps or hinders the programmer either way.
Sure, but A comment is not 'required'. Regan
Feb 20 2005
"Regan Heath" wrote: [...]Sure, but A comment is not 'required'.
Nor is it a keyword: `if()op=op;' -manfred
Feb 21 2005
On Mon, 21 Feb 2005 20:09:01 +0000 (UTC), Manfred Nowak <svv1999 hotmail.com> wrote:"Regan Heath" wrote: [...]Sure, but A comment is not 'required'.
Nor is it a keyword: `if()op=op;'
Touche.. but it could be :) Regan
Feb 21 2005
"Regan Heath" <regan netwin.co.nz> wrote in message news:opsmi2tdqc23k2f5 ally...What do you think of creating a keyword for it, and making the rest illegal.
Not much
Feb 20 2005
The way it is right now is sufficient {}. Why make a new keyword for
this? There are plenty of other more important areas to concentrate on in
D.
On Mon, 21 Feb 2005 16:33:03 +1300, Regan Heath wrote:
What do you think of creating a keyword for it, and making the rest
illegal.
eg.
if (true)
<keyword>
instead of all the possible premutations.
; has been made illegal in cases like the above as it's a source of bugs,
having a keyword does the same, plus makes the code more obvious to others.
Can the compiler optimise if it's told this explicitly?
At the cost of adding another keyword.
I suggested "noop" but Brad suggested it might get confused with the NOP
assembler instruction.
This was really just a random thought passing through my head, I'm not
sure there is a problem that needs solving, the possible error cases i.e.
using ';' are illegal the rest are unlikely to be done accidently and make
sense to most people (everyone?)
Regan
On Mon, 21 Feb 2005 13:56:21 +1100, Matthew
<admin stlsoft.dot.dot.dot.dot.org> wrote:
I have a personal coding standard that says an empty block *must* be
represented with
{}
and not
{
}
or
{;}
or
;
etc.
This makes it very easy to not get caught up on false +ves. (Of course,
false -ves are poss. <G>)
But since it's a personal one, others may have something different that
works equally well ...
"Unknown W. Brackets" <unknown simplemachines.org> wrote in message
news:cvbc9d$129h$1 digitaldaemon.com...
Yep, or, in the more common cases:
foreach (char c; "")
continue;
while (true)
continue;
Which makes it a lot cleaner and more readable imho (but obviously
cannot be done for if.)
-[Unknown]
"Derek Parnell" <derek psych.ward> wrote in message
news:fewqzt2viqdl.btneu9e85pr2$.dlg 40tude.net...
On Mon, 21 Feb 2005 00:22:49 +0100, Anders F Björklund wrote:
Are any of these extra semicolons really errors ?
void f()
{
};
class C
{
};
struct S
{
char c;
};
union U
{
char c;
};
void main()
{
if (false)
{
};
foreach(char c; "")
{
};
;
null;
}
They all pass the current D compiler silently...
Not to me ;-) But a naked semi-colon and the 'null;' is fairly
meaningless
to point where one may think that the coder has made a mistake.
However note that
if (true);
foreach(char c; "");
while(true);
are compiler errors.
I presume that one needs to do
if(true)
{}
foreach(char c; "")
{}
while(true)
{}
??
Feb 20 2005
On Sun, 20 Feb 2005 20:00:03 -0800, John Reimer <brk_6502 yahoo.com> wrote:The way it is right now is sufficient {}.
Cool.Why make a new keyword for this?
I was just asking.There are plenty of other more important areas to concentrate on in D.
Sure, and once they're done? ReganOn Mon, 21 Feb 2005 16:33:03 +1300, Regan Heath wrote:What do you think of creating a keyword for it, and making the rest illegal. eg. if (true) <keyword> instead of all the possible premutations. ; has been made illegal in cases like the above as it's a source of bugs, having a keyword does the same, plus makes the code more obvious to others. Can the compiler optimise if it's told this explicitly? At the cost of adding another keyword. I suggested "noop" but Brad suggested it might get confused with the NOP assembler instruction. This was really just a random thought passing through my head, I'm not sure there is a problem that needs solving, the possible error cases i.e. using ';' are illegal the rest are unlikely to be done accidently and make sense to most people (everyone?) Regan On Mon, 21 Feb 2005 13:56:21 +1100, Matthew <admin stlsoft.dot.dot.dot.dot.org> wrote:I have a personal coding standard that says an empty block *must* be represented with {} and not { } or {;} or ; etc. This makes it very easy to not get caught up on false +ves. (Of course, false -ves are poss. <G>) But since it's a personal one, others may have something different that works equally well ... "Unknown W. Brackets" <unknown simplemachines.org> wrote in message news:cvbc9d$129h$1 digitaldaemon.com...Yep, or, in the more common cases: foreach (char c; "") continue; while (true) continue; Which makes it a lot cleaner and more readable imho (but obviously cannot be done for if.) -[Unknown]"Derek Parnell" <derek psych.ward> wrote in message news:fewqzt2viqdl.btneu9e85pr2$.dlg 40tude.net...On Mon, 21 Feb 2005 00:22:49 +0100, Anders F Björklund wrote:Are any of these extra semicolons really errors ?void f() { }; class C { }; struct S { char c; }; union U { char c; }; void main() { if (false) { }; foreach(char c; "") { }; ; null; }
They all pass the current D compiler silently...
Not to me ;-) But a naked semi-colon and the 'null;' is fairly meaningless to point where one may think that the coder has made a mistake. However note that if (true); foreach(char c; ""); while(true); are compiler errors.
I presume that one needs to do if(true) {} foreach(char c; "") {} while(true) {} ??
Feb 20 2005
Regan Heath wrote:There are plenty of other more important areas to concentrate on in D.
Sure, and once they're done? Regan
Once they're done, I bet there are already a load of other problems more important than the cosmetic "noop" issue.
Feb 20 2005
On Mon, 21 Feb 2005 12:28:37 +0800, zwang wrote:Regan Heath wrote:There are plenty of other more important areas to concentrate on in D.
Sure, and once they're done? Regan
Once they're done, I bet there are already a load of other problems more important than the cosmetic "noop" issue.
I tend to agree.
Feb 20 2005
zwang wrote:There are plenty of other more important areas to concentrate on in D.
Sure, and once they're done? Regan
Once they're done, I bet there are already a load of other problems more important than the cosmetic "noop" issue.
And we've been discussing those as well, both "high" and "low"... I've commented in quite a few areas, like "void main", "writeln" "str", "imaginary real", "Object.printf" and such important ones ? This thread was just about a "new" brace style, using semicolons. --anders
Feb 20 2005
Once we are so serious we have to choose the Python way :-)
..What code looks fine => that code works fine => any code that is
not so precise => must be wrong => compiler error...
(This is the opposite side and I really do not share this idea.)
When we finish to discuss "important D things" think a little bit!
Our common goal is to form D a language, which is easy to learn,
easy to use, easy to read and easy to understand but powerful
in any way we can imagine. How to do it is the question only.
A simple and unambigous syntax is real need. It makes the compiler
able to catch the most common mistakes...
Strong types, few automatic type conversion and a consequent runtime library
helps the compiler to detect the real point of error...
[...]
Regarding the original issue: my opinion is ...
for(...blablabla..) is correct, the comment shows the intention
{
//
}
nop; is ugly and misleading, thumb down
(perhaps nop; statement could have other important meaning)
----------
Tamas Nagy
In article <cvc39u$1qnt$2 digitaldaemon.com>,
=?ISO-8859-15?Q?Anders_F_Bj=F6rklund?= says...
zwang wrote:
There are plenty of other more important areas to concentrate on in
Sure, and once they're done?
more important than the cosmetic "noop" issue.
And we've been discussing those as well, both "high" and "low"...
I've commented in quite a few areas, like "void main", "writeln"
"str", "imaginary real", "Object.printf" and such important ones ?
This thread was just about a "new" brace style, using semicolons.
--anders
Feb 21 2005
On Mon, 21 Feb 2005 22:17:35 +0000 (UTC), MicroWizard <MicroWizard_member pathlink.com> wrote:Once we are so serious we have to choose the Python way :-) ..What code looks fine => that code works fine => any code that is not so precise => must be wrong => compiler error... (This is the opposite side and I really do not share this idea.) When we finish to discuss "important D things" think a little bit! Our common goal is to form D a language, which is easy to learn, easy to use, easy to read and easy to understand but powerful in any way we can imagine. How to do it is the question only. A simple and unambigous syntax is real need. It makes the compiler able to catch the most common mistakes... Strong types, few automatic type conversion and a consequent runtime library helps the compiler to detect the real point of error... [...] Regarding the original issue: my opinion is ... for(...blablabla..) is correct, the comment shows the intention { // } nop; is ugly and misleading, thumb down (perhaps nop; statement could have other important meaning)
Well... I've given up on the idea, but, I would like you to qualify why you think its misleading? Regan
Feb 21 2005
Matthew wrote:I have a personal coding standard that says an empty block *must* be represented with {}
It's easy to search for, easy to spot in code. And explicit. I'll adopt it.
Feb 21 2005
They all look ok to me "Anders F Björklund" <afb algonet.se> wrote in message news:cvb649$qva$1 digitaldaemon.com...Are any of these extra semicolons really errors ?void f() { }; class C { }; struct S { char c; }; union U { char c; }; void main() { if (false) { }; foreach(char c; "") { }; ; null; }
They all pass the current D compiler silently... --anders PS. Not the "char c;" one, but the rest of them.
Feb 20 2005
I agree. They are harmless anyway. Matthew wrote:They all look ok to me "Anders F Björklund" <afb algonet.se> wrote in message news:cvb649$qva$1 digitaldaemon.com...Are any of these extra semicolons really errors ?void f() { }; class C { }; struct S { char c; }; union U { char c; }; void main() { if (false) { }; foreach(char c; "") { }; ; null; }
They all pass the current D compiler silently... --anders PS. Not the "char c;" one, but the rest of them.
Feb 20 2005
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Matthew wrote:
| "Anders F Björklund" <afb algonet.se> wrote in message
| news:cvb649$qva$1 digitaldaemon.com...
|
|>Are any of these extra semicolons really errors ?
|>
|>
|>>void f()
|>>{
|>>
|>>};
|>>
|>>class C
|>>{
|>>
|>>};
|>>
|>>struct S
|>>{
|>> char c;
|>>};
|>>
|>>union U
|>>{
|>> char c;
|>>};
|>>
|>>void main()
|>>{
|>> if (false)
|>> {
|>>
|>> };
|>>
|>> foreach(char c; "")
|>> {
|>>
|>> };
|>>
|>> ;
|>> null;
|>>}
|>
|>They all pass the current D compiler silently...
|>
|
| They all look ok to me
|
http://digitalmars.com/d/statement.html#expression
# Expressions that have no affect, like (x + x), are illegal in
# expression statements.
Thomas
PS Use GDC withe the dstar patches to catch those statements
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.0 (MingW32)
iD8DBQFCGUE23w+/yD4P9tIRAhCeAKCJ8HZigrdIh+YYRi+/PxNKpANu7QCgsnuv
h2fq0dW3rz3rBn2biapYGxU=
=tUv+
-----END PGP SIGNATURE-----
Feb 20 2005
Thomas Kühne wrote:|>Are any of these extra semicolons really errors ? |>
|>>void main() |>>{ |>> null; |>>} |> |>They all pass the current D compiler silently... | | They all look ok to me http://digitalmars.com/d/statement.html#expression # Expressions that have no affect, like (x + x), are illegal in # expression statements.
OK, that would make the last meaningless "null;" (or "0;" or whatever) illegal. It seems that GCC takes an issue with it as well, when I tried: "warning: statement with no effect" The other ones seem to be OK to all (GDC, GCC, and the rest of you) So I guess it's just another Brace Style to getting used to then... --anders PS. The last example was bad anyway, as it's not an "extra semicolon"
Feb 20 2005









"Regan Heath" <regan netwin.co.nz> 