discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

Polygon using relative points rather than absolute?

DM
doug moen
Tue, May 31, 2016 2:09 PM

Hi Parkinbot. Just a note about constant vs variable declarations.

In Algol 68:
real pi = 3.1416;    // constant declaration
real x := 0;            // variable declaration, initialized to 0
x := x + 1;              // assignment statement
In Pascal:
const pi = 3.1416;  // constant declaration
var x := 0;              // variable declaration
x := x + 1;              // assignment statement
In Javascript:
const pi = 3.1416;
var x = 0;
x = x + 1;
In OpenSCAD (with mutable variables)
pi = 3.1416;    // constant declaration
var x := 0;      // variable declaration
x := x + 1;      // assignment statement

There is no imperative language that uses the same syntax for both a
constant declaration and for an assignment statement. It's too late to
change OpenSCAD to use a different syntax for constant declarations. So I
can't use '=' for the assignment statement.

You said: "It is a bit misleading and hard to
understand for novices (or mainly imperative programmers, like me) that
immutable variables are allowed as L-values after first use in OpenSCAD and
that the last assignment will kind-of supersede all other assignments"

That's a design flaw in the language, which I propose to fix.

It's a side effect of an important feature. You can include a script that
contains a top level constant declaration X, then you override the value of
X in the parent script.
include <lib.scad>  // defines X
X = 1;  // override X

The problem is that the include statement just mashes the included file
into the same input stream as the parent, and OpenSCAD doesn't tag constant
declarations with the original source file in which they are defined
(yet--Marius has a branch that will fix this).
So we have no way to issue an error message for
X = 0;
X = 1;
because the first X=0 could have originated in an include file, and the
second X=1 could be an override in the parent, we just don't know.

Once Marius merges his branch, then it will be possible to issue a warning
or error message for a duplicate constant declaration, both in the same
source file, and we can stop pretending that this is legal code.

On 31 May 2016 at 08:10, Parkinbot rudolf@parkinbot.com wrote:

Doug,

yeah the design now looks a lot simpler and straight forward. I'd be able
to
live with it, so please take my annotations as suggestions to keep the
discussion going on.
There is by far no Frankenstein monster coming up. Hey, even Mac OS can be
run on PC-hardware meanwhile and the world is still revolving. Escaping the
'const' restrictions and random write access is unavoidable for a modern
language, as to many inelegant and time consuming work arounds have to be
used to accomplish even simple tasks like summing up or matrix
manipulation.

Also I wouldn't sweep Neon's argument from the carpet to use a full grown
language in declarative embedding. I'm just afraid, this will take away
most
of the fun the dev team is having to create an own thing. If I had time,
I'd
try to blow up Matlab with a toolbox written in native C++ that can act as
a
fast OpenGL viewer at CSG level. I guess such a component is already
available and its just a question of interfacing. By building on an already
mighty language you can concentrate on the important things. Blender ist a
good example for this approach. Also similar approaches, not being so much
overloaded, are currently popping up.

Personally I'm still not very happy with the keyword 'do' which is being
used for procedural things (mainly oops) in other languages. But, it has an
imperative connotation. So why not.

Also having '=' and ':=' in the same language for assignments, WILL be
confusing, anyway you look at it. I started programming with ALGOL68, where
':=' was used solely for variable declaration with init, while later
reassignments where done with '='. This is, what your 'var' keyword does.
Later I was programming in Pascal/Delphi/C++/VB in a kind of mixed fashion
and I really got crazy about this, especially when trying to reuse code
that
crossed borders.

But in those (imperative) languages immutable (=const) variables just are
not allowed to be noted as L-values. It is a bit misleading and hard to
understand for novices (or mainly imperative programmers, like me) that
immutable variables are allowed as L-values after first use in OpenSCAD and
that the last assignment will kind-of supersede all other assignments,
while
some scoping rules (that only seem to be perfectly known only by the
interpreter :-) ) are enforced for expressions like A = A+1. As far as I
remember, those rules have changed over time, and it was not allowed in
earlier versions, but it has somehow drippled in und I guess has to be kept
for compatibility reasons.

Maybe I am wrong with all this, because I never started to seriously use
this language for productive things nor did any documentation on it.
Usually
I struggle my way through, writing also a lot superfluous test code and
stuff, to find out interrogatively which opinion a compiler or interpreter
has on certain expressions - at least in lack of a debugger. But this just
as background, because most multi-language users (who is not in our days?)
will be in the same 'Babylonian' situation.

I'd still say

function myfunc = do{
var x := 1;
...

is triple marking. But better than nothing :-) Omitting things in later
versions is better than having forgot crucial things in earlier versions.

--
View this message in context:
http://forum.openscad.org/Polygon-using-relative-points-rather-than-absolute-tp17414p17483.html
Sent from the OpenSCAD mailing list archive at Nabble.com.


OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

Hi Parkinbot. Just a note about constant vs variable declarations. In Algol 68: real pi = 3.1416; // constant declaration real x := 0; // variable declaration, initialized to 0 x := x + 1; // assignment statement In Pascal: const pi = 3.1416; // constant declaration var x := 0; // variable declaration x := x + 1; // assignment statement In Javascript: const pi = 3.1416; var x = 0; x = x + 1; In OpenSCAD (with mutable variables) pi = 3.1416; // constant declaration var x := 0; // variable declaration x := x + 1; // assignment statement There is no imperative language that uses the same syntax for both a constant declaration and for an assignment statement. It's too late to change OpenSCAD to use a different syntax for constant declarations. So I can't use '=' for the assignment statement. You said: "It is a bit misleading and hard to understand for novices (or mainly imperative programmers, like me) that immutable variables are allowed as L-values after first use in OpenSCAD and that the last assignment will kind-of supersede all other assignments" That's a design flaw in the language, which I propose to fix. It's a side effect of an important feature. You can include a script that contains a top level constant declaration X, then you override the value of X in the parent script. include <lib.scad> // defines X X = 1; // override X The problem is that the include statement just mashes the included file into the same input stream as the parent, and OpenSCAD doesn't tag constant declarations with the original source file in which they are defined (yet--Marius has a branch that will fix this). So we have no way to issue an error message for X = 0; X = 1; because the first X=0 *could* have originated in an include file, and the second X=1 *could* be an override in the parent, we just don't know. Once Marius merges his branch, then it will be possible to issue a warning or error message for a duplicate constant declaration, both in the same source file, and we can stop pretending that this is legal code. On 31 May 2016 at 08:10, Parkinbot <rudolf@parkinbot.com> wrote: > Doug, > > yeah the design now looks a lot simpler and straight forward. I'd be able > to > live with it, so please take my annotations as suggestions to keep the > discussion going on. > There is by far no Frankenstein monster coming up. Hey, even Mac OS can be > run on PC-hardware meanwhile and the world is still revolving. Escaping the > 'const' restrictions and random write access is unavoidable for a modern > language, as to many inelegant and time consuming work arounds have to be > used to accomplish even simple tasks like summing up or matrix > manipulation. > > Also I wouldn't sweep Neon's argument from the carpet to use a full grown > language in declarative embedding. I'm just afraid, this will take away > most > of the fun the dev team is having to create an own thing. If I had time, > I'd > try to blow up Matlab with a toolbox written in native C++ that can act as > a > fast OpenGL viewer at CSG level. I guess such a component is already > available and its just a question of interfacing. By building on an already > mighty language you can concentrate on the important things. Blender ist a > good example for this approach. Also similar approaches, not being so much > overloaded, are currently popping up. > > Personally I'm still not very happy with the keyword 'do' which is being > used for procedural things (mainly oops) in other languages. But, it has an > imperative connotation. So why not. > > Also having '=' and ':=' in the same language for assignments, WILL be > confusing, anyway you look at it. I started programming with ALGOL68, where > ':=' was used solely for variable declaration with init, while later > reassignments where done with '='. This is, what your 'var' keyword does. > Later I was programming in Pascal/Delphi/C++/VB in a kind of mixed fashion > and I really got crazy about this, especially when trying to reuse code > that > crossed borders. > > But in those (imperative) languages immutable (=const) variables just are > not allowed to be noted as L-values. It is a bit misleading and hard to > understand for novices (or mainly imperative programmers, like me) that > immutable variables are allowed as L-values after first use in OpenSCAD and > that the last assignment will kind-of supersede all other assignments, > while > some scoping rules (that only seem to be perfectly known only by the > interpreter :-) ) are enforced for expressions like A = A+1. As far as I > remember, those rules have changed over time, and it was not allowed in > earlier versions, but it has somehow drippled in und I guess has to be kept > for compatibility reasons. > > Maybe I am wrong with all this, because I never started to seriously use > this language for productive things nor did any documentation on it. > Usually > I struggle my way through, writing also a lot superfluous test code and > stuff, to find out interrogatively which opinion a compiler or interpreter > has on certain expressions - at least in lack of a debugger. But this just > as background, because most multi-language users (who is not in our days?) > will be in the same 'Babylonian' situation. > > I'd still say > > function myfunc = do{ > var x := 1; > ... > > is triple marking. But better than nothing :-) Omitting things in later > versions is better than having forgot crucial things in earlier versions. > > > > > > > -- > View this message in context: > http://forum.openscad.org/Polygon-using-relative-points-rather-than-absolute-tp17414p17483.html > Sent from the OpenSCAD mailing list archive at Nabble.com. > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org > > >
CA
Carsten Arnholm
Tue, May 31, 2016 2:46 PM

On 31. mai 2016 16:09, doug moen wrote:

Hi Parkinbot. Just a note about constant vs variable declarations.

In Algol 68:
real pi = 3.1416;    // constant declaration
real x := 0;            // variable declaration, initialized to 0
x := x + 1;              // assignment statement
In Pascal:
const pi = 3.1416;  // constant declaration
var x := 0;              // variable declaration
x := x + 1;              // assignment statement
In Javascript:
const pi = 3.1416;
var x = 0;
x = x + 1;
In OpenSCAD (with mutable variables)
pi = 3.1416;    // constant declaration
var x := 0;      // variable declaration
x := x + 1;      // assignment statement

There is no imperative language that uses the same syntax for both a
constant declaration and for an assignment statement.

Try this:

In C++
const double pi = 3.1416;  // constant declaration
double x = 0;              // variable declaration, initialized to 0
x = x + 1;                // assignment statement

In Angelscript:
const double pi = 3.1416;  // constant declaration
double x = 0;              // variable declaration, initialized to 0
x = x + 1;                // assignment statement

Carsten Arnholm

On 31. mai 2016 16:09, doug moen wrote: > Hi Parkinbot. Just a note about constant vs variable declarations. > > In Algol 68: > real pi = 3.1416; // constant declaration > real x := 0; // variable declaration, initialized to 0 > x := x + 1; // assignment statement > In Pascal: > const pi = 3.1416; // constant declaration > var x := 0; // variable declaration > x := x + 1; // assignment statement > In Javascript: > const pi = 3.1416; > var x = 0; > x = x + 1; > In OpenSCAD (with mutable variables) > pi = 3.1416; // constant declaration > var x := 0; // variable declaration > x := x + 1; // assignment statement > > There is no imperative language that uses the same syntax for both a > constant declaration and for an assignment statement. Try this: In C++ const double pi = 3.1416; // constant declaration double x = 0; // variable declaration, initialized to 0 x = x + 1; // assignment statement In Angelscript: const double pi = 3.1416; // constant declaration double x = 0; // variable declaration, initialized to 0 x = x + 1; // assignment statement Carsten Arnholm
P
Parkinbot
Tue, May 31, 2016 3:13 PM

Oh my god, half of my Algol68 is gone ;-) I admit I could have looked it up.
I just remember there were monster terms like 'REF REAL x = LOC REAL := pi'
from which most parts could be omitted. But anyway, the main problem was the
struggle with the punch cards ...

The difference is all about modifiers and not about the operator, which can
easily be overloaded for each modifier (as it is for the different data
types). But never mind, ':=' is not such a bad deal and you are on the safer
side. Lazy people like me prefer to write Tx(10) instead of translate([10,
0, 0]) and to use short variable names like 'x' plus maybe a comment on
first use, instead of 'My_Main_Diameter_For_Circular_Integration' but this
is really a matter of taste.

It's a side effect of an important feature. You can include a script that
contains a top level constant declaration X, then you override the value
of X in the parent script.

include 

<lib.scad>
// defines X
X = 1;  // override X

which will (another flaw?) not hold for

use
<lib.scad>

So putting

$fn=4;

globally into a lib, can be nasty, especially if the included lib does the
'use'. But this leads into the qualifier discussion, which should not be
neglected.

--
View this message in context: http://forum.openscad.org/Polygon-using-relative-points-rather-than-absolute-tp17414p17486.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

Oh my god, half of my Algol68 is gone ;-) I admit I could have looked it up. I just remember there were monster terms like 'REF REAL x = LOC REAL := pi' from which most parts could be omitted. But anyway, the main problem was the struggle with the punch cards ... The difference is all about modifiers and not about the operator, which can easily be overloaded for each modifier (as it is for the different data types). But never mind, ':=' is not such a bad deal and you are on the safer side. Lazy people like me prefer to write Tx(10) instead of translate([10, 0, 0]) and to use short variable names like 'x' plus maybe a comment on first use, instead of 'My_Main_Diameter_For_Circular_Integration' but this is really a matter of taste. > It's a side effect of an important feature. You can include a script that > contains a top level constant declaration X, then you override the value > of X in the parent script. >> include >> <lib.scad> >> // defines X >> X = 1; // override X which will (another flaw?) not hold for > use > <lib.scad> So putting > $fn=4; globally into a lib, can be nasty, especially if the included lib does the 'use'. But this leads into the qualifier discussion, which should not be neglected. -- View this message in context: http://forum.openscad.org/Polygon-using-relative-points-rather-than-absolute-tp17414p17486.html Sent from the OpenSCAD mailing list archive at Nabble.com.
LT
Len Trigg
Tue, May 31, 2016 8:41 PM

On 1 June 2016 at 02:46, Carsten Arnholm arnholm@arnholm.org wrote:

In C++
const double pi = 3.1416;  // constant declaration
double x = 0;              // variable declaration, initialized to 0
x = x + 1;                // assignment statement

In Angelscript:
const double pi = 3.1416;  // constant declaration
double x = 0;              // variable declaration, initialized to 0

Those are not the same syntax -- the constant declarations have "const" in
front (and the same for the Javascript example), and the assignment doesn't
:-)

On 1 June 2016 at 02:46, Carsten Arnholm <arnholm@arnholm.org> wrote: > In C++ > const double pi = 3.1416; // constant declaration > double x = 0; // variable declaration, initialized to 0 > x = x + 1; // assignment statement > > In Angelscript: > const double pi = 3.1416; // constant declaration > double x = 0; // variable declaration, initialized to 0 > Those are not the same syntax -- the constant declarations have "const" in front (and the same for the Javascript example), and the assignment doesn't :-)
CA
Carsten Arnholm
Tue, May 31, 2016 9:39 PM

On 31. mai 2016 22:41, Len Trigg wrote:

On 1 June 2016 at 02:46, Carsten Arnholm wrote:

In C++
const double pi = 3.1416;  // constant declaration
double x = 0;              // variable declaration, initialized to 0
x = x + 1;                // assignment statement

In Angelscript:
const double pi = 3.1416;  // constant declaration
double x = 0;              // variable declaration, initialized to 0
x = x + 1;                // assignment statement

Those are not the same syntax -- the constant declarations have "const"
in front (and the same for the Javascript example), and the assignment
doesn't :-)

Without const they would not be constant declarations. If you want a
variable declaration, then drop the const. The constant declaration
syntax using '=' is the same as for variable declarations and
assignments, unlike the other examples.

My point is that simple concepts should ideally be expressed directly
and consistently, not in subtle and indirect ways that few will
understand and accept.

Carsten Arnholm

On 31. mai 2016 22:41, Len Trigg wrote: > > On 1 June 2016 at 02:46, Carsten Arnholm wrote: > > In C++ > const double pi = 3.1416; // constant declaration > double x = 0; // variable declaration, initialized to 0 > x = x + 1; // assignment statement > > In Angelscript: > const double pi = 3.1416; // constant declaration > double x = 0; // variable declaration, initialized to 0 > x = x + 1; // assignment statement > > > Those are not the same syntax -- the constant declarations have "const" > in front (and the same for the Javascript example), and the assignment > doesn't :-) Without const they would not be constant declarations. If you want a variable declaration, then drop the const. The constant declaration syntax using '=' is the same as for variable declarations and assignments, unlike the other examples. My point is that simple concepts should ideally be expressed directly and consistently, not in subtle and indirect ways that few will understand and accept. Carsten Arnholm
W
wolf
Thu, Jun 2, 2016 7:59 AM

With "https://github.com/openscad/openscad/wiki/Mutable-Variables" doug.moen
has written a specification for imperative extensions to the
OpenSCADlanguage that in version 2.0 is full of design bugs. So are the
comments written so far.

Before I deal with them, remember that the lowest level of computer language
is assembler. Within assembler, you are permitted to MOV (write, in English)
a value from one location to another (e.g. from a register onto the stack).
If that MOV went to the location it was supposed to go, great. But if it
went somewhere else, you have a BUG! If you use a compiler as intermediate
between your program and assembler, you have a good chance of catching it
before the bug does irreparable damage, and your program fails. In catching
a bug, a functional language has an advantage over an imperative language,
since the compiler knows (almost) everything about the programmer's
intentions.

A Haskel fan has this to write
(http://www.haskellforall.com/2012/01/haskell-for-c-programmers-for-loops.html)
"Haskell is an excellent language because functional programming is the
perfect foundation for rigorously building more sophisticated abstractions.
Imperative languages can't do this because they can't opt-out of state and
side effects, making it incredibly difficult to reason about the correctness
of abstractions."
"state and side effects" is just a way of fudging the real issue: if you
don't read or write the proper memory location, your program state is likely
to be busted, and you have side effects.

The Rust programming language (https://doc.rust-lang.org/book/unsafe.html)
is more clear about the issues at stake here. It clearly distinguishes
between writing safe and unsafe code:
"Safe, in the context of Rust, means ‘doesn’t do anything unsafe’. It’s also
important to know that there are certain behaviors that are probably not
desirable in your code, but are expressly not unsafe. . . Rust cannot
prevent all kinds of software problems. Buggy code can and will be written
in Rust."
The paper then goes on to describe what the compiler cannot be expected to
catch, safe mode or unsafe mode.

Doug.moen has written his "Mutable-Variables" paper from the viewpoint of a
user. Had he used the viewpoint of a compiler, he would have realized the
bugs he has introduced.

Here they are:

c=3.1416;        // this defines an immutable variable (a constant). The
compiler does not need more information, it can
define
the data type itself
var x;
var x:=0;        // the compiler needs more information, it does not know is
this a double or single precision number, an
integer, or a
character? There is a need for what in C is called a
header.
x=x+1;          // the use of a colon is not necessary and has been omitted
here. Since x is already defined as mutable
elsewhere, the
compiler has all the necessary information. x=x+1
is perfectly
acceptable.
c=c+1;          // This is illegal code, as c is auto-typed by the compiler
as immutable. The compiler should flag it as
"Variable not
assigned". If done so, no unexperienced user is
likely to lug
his/her lack of understanding onto this forum.

With regards to the use of procedures (if, as I assume, he means Pascal-type
procedures), I fail to see their utility. A procedure does exactly the same
as a function, except that it does not return a value. Rather, I would like
to see a clean-up of how a function is currently written so that it is
possible to build a function from compound statements. This would also make
functions much more easily readable. Readability is more of an issue here
than capability, in particular if you want to scope a mutable variable to be
limited to that function. And from what I can gather from the paper, a "do
block" would be just another name for a procedure: another function that
writes some memory area, but does not return anything and would not expand
on OpenSCAD's ability to create shapes.

What "assert()" is supposed to do I cannot make out at all.

If, while and for are great to have, provided C-style programming is
avoided. What I want to have is an OpenSCAD that is easy to learn, without
first becoming an expert in C. Therefore, no C-style anywhere. C-style is
good for C programmers only, for all others it is a pain in the backside and
barely readable. If you can read English, you should be able to read
OpenSCAD. If not, improve the language and make it more like English. Be
verbose where you must; if you really want to be universal, program in
assembler. And if you want to be truly concise, maybe you should use
Haskell?

I am very much in favour of using "mutable variables". But there are limits,
as I pointed out elsewhere
(http://forum.openscad.org/feedback-on-quot-C-style-for-quot-td17512.html).
Rust has defined these limits in terms of "safe" vs "unsafe" code. I suggest
that the OpenSCAD developer community do something similar for OpenSCAD, if
they fear imperative programming taking over their beloved functional style
nonsense and poor readability (in places).

Keep OpenSCAD simple, focused upon the creation of shapes, and implement
OpenSCAD2 as soon as possible. For those who want extensions to the
language, allow them to write a library (and its associated manual) and add
it to OpenSCAD for a limited number of years, the same way MCAD got added.
Throw the library out if it, or its manual, is not maintained or does not
get used.

That is enough criticism (hopefully constructive). The other bugs in the
discussion so far you should be able to discern yourself, once to see the
issues from a compiler's perspective.

wolf

--
View this message in context: http://forum.openscad.org/Polygon-using-relative-points-rather-than-absolute-tp17414p17522.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

With "https://github.com/openscad/openscad/wiki/Mutable-Variables" doug.moen has written a specification for imperative extensions to the OpenSCADlanguage that in version 2.0 is full of design bugs. So are the comments written so far. Before I deal with them, remember that the lowest level of computer language is assembler. Within assembler, you are permitted to MOV (write, in English) a value from one location to another (e.g. from a register onto the stack). If that MOV went to the location it was supposed to go, great. But if it went somewhere else, you have a BUG! If you use a compiler as intermediate between your program and assembler, you have a good chance of catching it before the bug does irreparable damage, and your program fails. In catching a bug, a functional language has an advantage over an imperative language, since the compiler knows (almost) everything about the programmer's intentions. A Haskel fan has this to write (http://www.haskellforall.com/2012/01/haskell-for-c-programmers-for-loops.html) "Haskell is an excellent language because functional programming is the perfect foundation for rigorously building more sophisticated abstractions. Imperative languages can't do this because they can't opt-out of state and side effects, making it incredibly difficult to reason about the correctness of abstractions." "state and side effects" is just a way of fudging the real issue: if you don't read or write the proper memory location, your program state is likely to be busted, and you have side effects. The Rust programming language (https://doc.rust-lang.org/book/unsafe.html) is more clear about the issues at stake here. It clearly distinguishes between writing safe and unsafe code: "Safe, in the context of Rust, means ‘doesn’t do anything unsafe’. It’s also important to know that there are certain behaviors that are probably not desirable in your code, but are expressly not unsafe. . . Rust cannot prevent all kinds of software problems. Buggy code can and will be written in Rust." The paper then goes on to describe what the compiler cannot be expected to catch, safe mode or unsafe mode. Doug.moen has written his "Mutable-Variables" paper from the viewpoint of a user. Had he used the viewpoint of a compiler, he would have realized the bugs he has introduced. Here they are: c=3.1416; // this defines an immutable variable (a constant). The compiler does not need more information, it can define the data type itself var x; var x:=0; // the compiler needs more information, it does not know is this a double or single precision number, an integer, or a character? There is a need for what in C is called a header. x=x+1; // the use of a colon is not necessary and has been omitted here. Since x is already defined as mutable elsewhere, the compiler has all the necessary information. x=x+1 is perfectly acceptable. c=c+1; // This is illegal code, as c is auto-typed by the compiler as immutable. The compiler should flag it as "Variable not assigned". If done so, no unexperienced user is likely to lug his/her lack of understanding onto this forum. With regards to the use of procedures (if, as I assume, he means Pascal-type procedures), I fail to see their utility. A procedure does exactly the same as a function, except that it does not return a value. Rather, I would like to see a clean-up of how a function is currently written so that it is possible to build a function from compound statements. This would also make functions much more easily readable. Readability is more of an issue here than capability, in particular if you want to scope a mutable variable to be limited to that function. And from what I can gather from the paper, a "do block" would be just another name for a procedure: another function that writes some memory area, but does not return anything and would not expand on OpenSCAD's ability to create shapes. What "assert()" is supposed to do I cannot make out at all. If, while and for are great to have, provided C-style programming is avoided. What I want to have is an OpenSCAD that is easy to learn, without first becoming an expert in C. Therefore, no C-style anywhere. C-style is good for C programmers only, for all others it is a pain in the backside and barely readable. If you can read English, you should be able to read OpenSCAD. If not, improve the language and make it more like English. Be verbose where you must; if you really want to be universal, program in assembler. And if you want to be truly concise, maybe you should use Haskell? I am very much in favour of using "mutable variables". But there are limits, as I pointed out elsewhere (http://forum.openscad.org/feedback-on-quot-C-style-for-quot-td17512.html). Rust has defined these limits in terms of "safe" vs "unsafe" code. I suggest that the OpenSCAD developer community do something similar for OpenSCAD, if they fear imperative programming taking over their beloved functional style nonsense and poor readability (in places). Keep OpenSCAD simple, focused upon the creation of shapes, and implement OpenSCAD2 as soon as possible. For those who want extensions to the language, allow them to write a library (and its associated manual) and add it to OpenSCAD for a limited number of years, the same way MCAD got added. Throw the library out if it, or its manual, is not maintained or does not get used. That is enough criticism (hopefully constructive). The other bugs in the discussion so far you should be able to discern yourself, once to see the issues from a compiler's perspective. wolf -- View this message in context: http://forum.openscad.org/Polygon-using-relative-points-rather-than-absolute-tp17414p17522.html Sent from the OpenSCAD mailing list archive at Nabble.com.