Why a semicolon right after module definition line not a syntax error

classic Classic list List threaded Threaded
13 messages Options
Reply | Threaded
Open this post in threaded view
|

Why a semicolon right after module definition line not a syntax error

runsun
I just found a weird behavior of OpenSCAD:

module m();
{ echo("test");
   cube(3);
}

Note that there's a ";" right after m(). Surprisingly, this is not a syntax
error, AND the module get executed.

I found this in a hard way in which I had commented out a call to a large
module, but it still got executed. Cleaning cach, restarting OpenSCAD ...
everything I tried failed, until 30 min later I accidentally found that a
extra ";" appeared there.

I tried other possible usage of this feature but couldn't find any. I
believe this should have been a syntax error.



-----

$  Runsun Pan, PhD $ libs: scadx , doctest , faces ( git ), offline doc ( git ), runscad.py ( 2 , git ), editor of choice: CudaText  ( OpenSCAD lexer ); $ Tips ; $ Snippets

--
Sent from: http://forum.openscad.org/

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
$ Runsun Pan, PhD
$ libs: scadx, doctest, faces(git), offline doc(git), runscad.py(2,git), editor of choice: CudaText ( OpenSCAD lexer); $ Tips; $ Snippets
Reply | Threaded
Open this post in threaded view
|

Re: Why a semicolon right after module definition line not a syntax error

JordanBrown
On 3/30/2018 8:31 PM, runsun wrote:
I just found a weird behavior of OpenSCAD:

module m();
{ echo("test");
   cube(3);
}

Note that there's a ";" right after m(). Surprisingly, this is not a syntax
error, AND the module get executed.

I found this in a hard way in which I had commented out a call to a large
module, but it still got executed. Cleaning cach, restarting OpenSCAD ...
everything I tried failed, until 30 min later I accidentally found that a
extra ";" appeared there. 

I tried other possible usage of this feature but couldn't find any. I
believe this should have been a syntax error. 

First, try executing a file that contains a single semicolon.  Note that it does nothing, successfully.

Now, to your case:

The module did *not* execute.

The module has a single empty statement in it.

What executed was the main line of the file, the { echo ... cube ... } that followed the module definition.

The two relevant questions would be
1)  Should one-statement modules be allowed, or should braces be required?  (But I bet that ties into the treatment of other block constructs like "if" and "for".)
2)  Should empty statements be allowed?



_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Why a semicolon right after module definition line not a syntax error

boxcarmib
Sure ‘empty' statements and single statement modules are annoying, but empty statements being ‘allowable’ has been around since the beginning of time (i.e. c)  I’ve not encountered the problem you did (yet), but for my part, I’ve been frustrated by that widowed semicolon far more often by sticking one inadvertently in the midst of a string of module calls… who hasn’t done something like this in the midst of some large program...

rotate([0,5,0])
        translate([15,5,4]);
                _cube([5,10,15]);

And then pulled your hair for hours wondering why the cube wasn’t rotated or translated to its proper position?
I guess we could split modules into those that just manipulate an object about and those that actually draw something and then require all statements lists that beginning with a non-rendering module call end with a rendering module call, but that seems like a lot of work for creating a syntax error out of something I just shouldn’t have done in the first place.
Common GOTCHA’s are frustrating and painful things, but handling them is just part of the programming madness that has gripped us all… and once I've gone crazy a couple of times figuring out what the cause of an annoying problem is, then even though I may repeat the same mistake again (and again <sigh>) the speed with which I’m able to identify the problem becomes shorter and shorter.
No doubt the syntax of the OpenSCAD language specifies a module definition may be composed of a single statement which may be empty and sometimes a single statement module is all you want or need. However, when my program doesn’t do what I want it to do, it’s rarely syntax, it’s usually semantics… and even with AI getting better and better all the time, there’s still no programming language that you can direct to “do what I mean to do, not what I tell you to do”.



> On Mar 30, 2018, at 11:42 PM, Jordan Brown <[hidden email]> wrote:
>
> On 3/30/2018 8:31 PM, runsun wrote:
>> I just found a weird behavior of OpenSCAD:
>>
>> module m();
>> { echo("test");
>>    cube(3);
>> }
>>
>> Note that there's a ";" right after m(). Surprisingly, this is not a syntax
>> error, AND the module get executed.
>>
>> I found this in a hard way in which I had commented out a call to a large
>> module, but it still got executed. Cleaning cach, restarting OpenSCAD ...
>> everything I tried failed, until 30 min later I accidentally found that a
>> extra ";" appeared there.
>>
>> I tried other possible usage of this feature but couldn't find any. I
>> believe this should have been a syntax error.
>
> First, try executing a file that contains a single semicolon.  Note that it does nothing, successfully.
>
> Now, to your case:
>
> The module did *not* execute.
>
> The module has a single empty statement in it.
>
> What executed was the main line of the file, the { echo ... cube ... } that followed the module definition.
>
> The two relevant questions would be
> 1)  Should one-statement modules be allowed, or should braces be required?  (But I bet that ties into the treatment of other block constructs like "if" and "for".)
> 2)  Should empty statements be allowed?
>
>
> _______________________________________________
> OpenSCAD mailing list
> [hidden email]
> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Why a semicolon right after module definition line not a syntax error

JordanBrown
Summary:  some musing on language design, with no solid proposals for improvement.  Can probably be ignored.

On 3/31/2018 1:10 AM, Hugo Jackson wrote:
Sure ‘empty' statements and single statement modules are annoying, but empty statements being ‘allowable’ has been around since the beginning of time (i.e. c)

Yes, and I'm sure that OpenSCAD inherited them from C.  I know why they are useful in C (e.g. empty loop bodies and some macro cases), but I wasn't coming up with how they were useful in OpenSCAD until you pointed this out....

I guess we could split modules into those that just manipulate an object about and those that actually draw something and then require all statements lists that beginning with a non-rendering module call end with a rendering module call,

Ah, right.  An empty statement conveys "no children" at the end of a sequence of module invocations.

but that seems like a lot of work for creating a syntax error out of something I just shouldn’t have done in the first place.

You just hit on one of my favorite professional topics.

Thesis

To the greatest extent possible, languages should be designed so that common mistakes are detected as errors (be they syntax errors or constraint violations), rather than continuing to result in undesired behavior.  The compiler examines every single line of the program, while even the best test plan only covers a fraction of the cases.  Detecting errors at compile time is thus the second-best way to handle errors.  (The best is to arrange that it isn't possible to make the error in the first place, which is usually quite difficult in a programming language.) Third-best is to detect the error at run time.

Put differently, it isn't reasonable to expect programmers to write perfect programs.  They will make mistakes, and one of the goals of the language and the tools should be to detect those mistakes as early as possible.  When you do something you shouldn't have done in the first place, the tools should detect it and tell you.

How does that apply here?  Is there a way to design the language so as to detect "bad" empty statements, but allow "good" empty statements? Don't know.

Minor Tweaks

Maybe some modules (e.g. translate, rotate, ...) should demand children.  If you try to give translate an empty list of children, maybe that should be a runtime error.  Maybe that requirement could be conveyed in the syntax, so that a problem could be detected even in a sequence that isn't executed on this particular run.  I suspect that the requirement would have to be for a non-empty list of direct children, not that there be any actual objects in the tree.  "translate([1,1,1]) ;" should be an error, but "translate([1,1,1]) if (x) cube();" should not, even though if x is false there are no objects.  (But there is a group() node.)  Should "translate([1,1,1]) { }" be an error?  It has no real meaning, but "translate([1,1,1]) { /* cube() */ }" might well be something you'd have as you develop your program.  But no matter what you do here, there are modules that can accept either an empty list of children, or real children, and

One answer to this precise problem would be to eliminate semicolons entirely, and always require braces around children.  Missing braces would seem more obvious than that extraneous semicolon.  However, the need to wrap braces around every level in a translate-rotate-scale-extrude-... sequence would be onerous, worse than the problem it's fixing.  (But:  at work, in C and JavaScript, that seems to be exactly where we're heading, requiring braces around every "if" and loop body, because when you do that it's harder to make certain classes of errors.)

Programming Convention

From a programming convention standpoint (that is, how you choose to write your programs, not what the language requires), you could adopt two conventions that would, in conjunction, mostly prevent this problem, at little cost:
  • If you have a stack of operations that extends onto more than one line, put braces around the subsequent lines.
  • Put the open brace on the end of the first line of a multi-line sequence.
That is, you could say
translate(t) rotate(r) cube();

but if you split it into multiple lines you would say

translate(t) {
	rotate(r) cube();
}

and you would never say

translate(t)
	rotate(r) cube();

without the braces.

With those two conventions, it would be hard to both have a spurious semicolon and have operations that are intended to be children; you'd have to say

translate(t); {
	rotate(r) cube();
}
and that would be a fairly obvious mistake.

Emulate Python, not C

There's a decent argument that Python got this right:  structure is conveyed through indentation, not through punctuation.  In a hypothetical Python-derived OpenSCAD, you wouldn't use semicolons at all, and the structure would be obvious:
translate(t)
	rotate(r) cube()
would have the rotated cube be a child of the translate, while
translate(t)
rotate(r) cube()

would have them as two independent stacks of operations.

(Yes, Python has semicolons.  I don't know why.  Yes, maybe in a Python-derived language you'd want a colon when you are introducing children, though I don't know why Python has that requirement.)



_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Why a semicolon right after module definition line not a syntax error

runsun
In reply to this post by JordanBrown
@ JordanBrown: Ahhh... you brought in the light !! I was so blinded by my
frustration such that I didn't see it. I forgot that I used to put {} around
a function so my editor can fold the code. Or to group several related
modules with a pair of {} so they can be folded together.

I still think that a statement like "module m();" should be an error.  It
seems to serve no purpose other than confusing users.



-----

$  Runsun Pan, PhD $ libs: scadx , doctest , faces ( git ), offline doc ( git ), runscad.py ( 2 , git ), editor of choice: CudaText  ( OpenSCAD lexer );&nbsp;$ Tips ;&nbsp;$ Snippets

--
Sent from: http://forum.openscad.org/

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
$ Runsun Pan, PhD
$ libs: scadx, doctest, faces(git), offline doc(git), runscad.py(2,git), editor of choice: CudaText ( OpenSCAD lexer); $ Tips; $ Snippets
tp3
Reply | Threaded
Open this post in threaded view
|

Re: Why a semicolon right after module definition line not a syntax error

tp3
In reply to this post by JordanBrown
On 03/31/2018 07:27 PM, Jordan Brown wrote:
> There's a decent argument that Python got this right: structure
> is conveyed through indentation, *not* through punctuation.  In a
> hypothetical Python-derived OpenSCAD, you wouldn't use semicolons
> at all, and the structure would be obvious:
>
...until you copy code from emails or web pages where
the indentation gets lost and result in a mess. I did
have those cases from time to time and that is massively
annoying too.

So no, indentation is not the magic bullet for everyone.

Also that can't be resolved, ever. Same as vi vs. emacs or
spaces vs. tabs :-).

I tend to think that's one of the not so important things,
for me it's all tools to get something done. Using multiple
tools can be the best way to get the needed result.

OpenSCAD uses python in the test framework and that's
very useful. It was a bit of a pain to make it compatible
with python2 and python3 but that's something we maybe
can learn from as OpenSCAD probably needs quite some
changes to actually go forward.

Anyway, I'm not sure the language should be changed to
actually make the empty module an error. It would be nice
to have warnings for those cases. Maybe even with a way
to disable those for special uses. But with everyone busy
rewriting OpenSCAD in python, that's probably not going
to happen soon ;-) (...just kidding).

ciao,
   Torsten.

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
-- Torsten
Reply | Threaded
Open this post in threaded view
|

Re: Why a semicolon right after module definition line not a syntax error

MichaelAtOz
Administrator
In reply to this post by runsun
runsun wrote
> I still think that a statement like "module m();" should be an error.  It
> seems to serve no purpose other than confusing users.

module null(); is quite useful.





-----
Admin - PM me if you need anything, or if I've done something stupid...

Unless specifically shown otherwise above, my contribution is in the Public Domain; to the extent possible under law, I have waived all copyright and related or neighbouring rights to this work. Obviously inclusion of works of previous authors is not included in the above.

The TPP is no simple “trade agreement.”   Fight it! http://www.ourfairdeal.org/   time is running out!
--
Sent from: http://forum.openscad.org/

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Admin - email* me if you need anything,
or if I've done something stupid...
* click on my MichaelAtOz label, there is a link to email me.

Unless specifically shown otherwise above, my contribution is in the Public Domain; to the extent possible under law, I have waived all copyright and related or neighbouring rights to this work.
Obviously inclusion of works of previous authors is not included in the above.


The TPP is no simple “trade agreement.” Fight it! http://www.ourfairdeal.org/ time is running out!
Reply | Threaded
Open this post in threaded view
|

Re: Why a semicolon right after module definition line not a syntax error

runsun
In reply to this post by tp3
I have the same concern. Python is my move favorite language and I love
everything about it --- except the indentation. I wasted a lot of time
trying to make the indent right when changing editors. It's a real pain in
the ass to check that for a large collection of files.


tp3 wrote

> On 03/31/2018 07:27 PM, Jordan Brown wrote:
>> There's a decent argument that Python got this right: structure
>> is conveyed through indentation, *not* through punctuation.  In a
>> hypothetical Python-derived OpenSCAD, you wouldn't use semicolons
>> at all, and the structure would be obvious:
>>
> ...until you copy code from emails or web pages where
> the indentation gets lost and result in a mess. I did
> have those cases from time to time and that is massively
> annoying too.





-----

$  Runsun Pan, PhD $ libs: scadx , doctest , faces ( git ), offline doc ( git ), runscad.py ( 2 , git ), editor of choice: CudaText  ( OpenSCAD lexer );&nbsp;$ Tips ;&nbsp;$ Snippets

--
Sent from: http://forum.openscad.org/

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
$ Runsun Pan, PhD
$ libs: scadx, doctest, faces(git), offline doc(git), runscad.py(2,git), editor of choice: CudaText ( OpenSCAD lexer); $ Tips; $ Snippets
Reply | Threaded
Open this post in threaded view
|

Re: Why a semicolon right after module definition line not a syntax error

runsun
In reply to this post by MichaelAtOz
MichaelAtOz wrote
> module null(); is quite useful.

Example usage ?




-----

$  Runsun Pan, PhD $ libs: scadx , doctest , faces ( git ), offline doc ( git ), runscad.py ( 2 , git ), editor of choice: CudaText  ( OpenSCAD lexer );&nbsp;$ Tips ;&nbsp;$ Snippets

--
Sent from: http://forum.openscad.org/

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
$ Runsun Pan, PhD
$ libs: scadx, doctest, faces(git), offline doc(git), runscad.py(2,git), editor of choice: CudaText ( OpenSCAD lexer); $ Tips; $ Snippets
Reply | Threaded
Open this post in threaded view
|

Re: Why a semicolon right after module definition line not a syntax error

MichaelAtOz
Administrator
runsun wrote
> MichaelAtOz wrote
>> module null(); is quite useful.
>
> Example usage ?

It acts the same as the '*' operator, but the '*' operator is not valid in
some situations such as for '{' bracketed blocks.





-----
Admin - PM me if you need anything, or if I've done something stupid...

Unless specifically shown otherwise above, my contribution is in the Public Domain; to the extent possible under law, I have waived all copyright and related or neighbouring rights to this work. Obviously inclusion of works of previous authors is not included in the above.

The TPP is no simple “trade agreement.”   Fight it! http://www.ourfairdeal.org/   time is running out!
--
Sent from: http://forum.openscad.org/

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Admin - email* me if you need anything,
or if I've done something stupid...
* click on my MichaelAtOz label, there is a link to email me.

Unless specifically shown otherwise above, my contribution is in the Public Domain; to the extent possible under law, I have waived all copyright and related or neighbouring rights to this work.
Obviously inclusion of works of previous authors is not included in the above.


The TPP is no simple “trade agreement.” Fight it! http://www.ourfairdeal.org/ time is running out!
Ivo
Reply | Threaded
Open this post in threaded view
|

Re: Why a semicolon right after module definition line not a syntax error

Ivo
In reply to this post by MichaelAtOz
MichaelAtOz wrote
> runsun wrote
>> I still think that a statement like "module m();" should be an error.  It
>> seems to serve no purpose other than confusing users.
>
> module null(); is quite useful.

module null() {};

would do the same and not break syntax.

Cheers, Ivo



--
Sent from: http://forum.openscad.org/

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Ivo
Reply | Threaded
Open this post in threaded view
|

Re: Why a semicolon right after module definition line not a syntax error

Ivo
In reply to this post by runsun
runsun wrote
> MichaelAtOz wrote
>> module null(); is quite useful.
>
> Example usage ?

I use

module empty() {};

To be able to pass empty children to other functions.



--
Sent from: http://forum.openscad.org/

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Why a semicolon right after module definition line not a syntax error

Troberg
In reply to this post by tp3
> ...until you copy code from emails or web pages where
the indentation gets lost and result in a mess. I did
have those cases from time to time and that is massively
annoying too.

Or when you write a code generator. When piecing together snippets of code,
it's much easier if you don't have to bother about how deeply indented it
needs to be, and instead just makes a second pass based on control
structures such as braces (or whatever is used in the language you are
generating) to fix indentation.

> It would be nice to have warnings for those cases.

I agree, this is a warning issue, not an error. With the current lack of
meaningful error messages, I'd say that this one is a low priority.



--
Sent from: http://forum.openscad.org/

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org