discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

Polygon using relative points rather than absolute?

P
Parkinbot
Sun, May 29, 2016 3:13 AM

Hi Doug,

that's a great paper. Thanks for accepting the challenge. It reads
interesting and I can almost smell the wind of progress, it will bring into
the language. I never really understood, why functions in OpenSCAD shouldn't
be imperative, as they provide a well defined interface to interact with
modules in a purely functional context. Your paper shows, that this path is
viable.

I'm not as deep into the matter as you are, so allow me some questions and
thoughts concerning some 'redundancies'.

valof{ expr};
marks 'expr' as imperative. I understand it as the central modifier (context
switch) to annouce imperative code. However, as I read it, it will allow for
'mixed' semantics, which makes things complicated. For this reason more
markers have to be introduced.

var x := expr;
marks 'x' as mutable and will be allowed only within valof{} expressions.
Isn't 'valof{}' + 'var' + ':=' kind of triple marking? 'var' is ok in a
function/procedure prototype to mark output variables.
In a non-mixed context 'let' and  '=' might have just overloaded semantics,
like in 'for' headers (more obvious in C-style), where mutable variables
also may be declared in common style.

do{list};
is it used as a separator between both worlds? Wouldn't it be obsolet in a
non-mixture enviroment?

To be able to define functional semantics code within an imperative context,
some counterpart modifier could be introduced ...

Rudolf

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

Hi Doug, that's a great paper. Thanks for accepting the challenge. It reads interesting and I can almost smell the wind of progress, it will bring into the language. I never really understood, why functions in OpenSCAD shouldn't be imperative, as they provide a well defined interface to interact with modules in a purely functional context. Your paper shows, that this path is viable. I'm not as deep into the matter as you are, so allow me some questions and thoughts concerning some 'redundancies'. valof{ expr}; marks 'expr' as imperative. I understand it as the central modifier (context switch) to annouce imperative code. However, as I read it, it will allow for 'mixed' semantics, which makes things complicated. For this reason more markers have to be introduced. var x := expr; marks 'x' as mutable and will be allowed only within valof{} expressions. Isn't 'valof{}' + 'var' + ':=' kind of triple marking? 'var' is ok in a function/procedure prototype to mark output variables. In a non-mixed context 'let' and '=' might have just overloaded semantics, like in 'for' headers (more obvious in C-style), where mutable variables also may be declared in common style. do{list}; is it used as a separator between both worlds? Wouldn't it be obsolet in a non-mixture enviroment? To be able to define functional semantics code within an imperative context, some counterpart modifier could be introduced ... Rudolf -- View this message in context: http://forum.openscad.org/Polygon-using-relative-points-rather-than-absolute-tp17414p17452.html Sent from the OpenSCAD mailing list archive at Nabble.com.
DM
doug moen
Sun, May 29, 2016 2:00 PM

First of all, I agree that the new syntax kind of sucks, and is not C-like.
That's a compromise which is required by the design goals I set for myself:

  • backward compatibility
  • preserve the meaning and declarative semantics of existing code

I couldn't change the meaning of existing syntax, so I had to invent all
new syntax for the bolted-on imperative programming extension. Maybe the
syntax is revolting enough to make the whole idea unacceptable.

Just to clarify, my proposal allows mutable variables to be defined and
used in any context:

  • in the body of a function (that's where 'valof' is needed)
  • in the body of a module, or in any {...} expression
  • inside a list comprehension
  • at the top level

Last month there was a forum post by Experimentalist asking why variables
don't work as they do in an imperative language:

module Test(choice = 1) {
echo(choice=choice);
myVar = 0;

if (choice==1) {
    myVar = 1;
} else if (choice == 2) {
    myVar = 2;
} else {
     myVar = 3;
}

echo(myVar=myVar);

}
<<<

To rewrite this using the imperative programming extension:

module Test(choice = 1) {
echo(choice=choice);
var myVar := 0;

if (choice==1) do {
    myVar := 1;
} else if (choice == 2) do {
    myVar := 2;
} else do {
     myVar := 3;
}

echo(myVar=myVar);

}
<<<

Why the weird syntax?

The 'var' keyword is needed to define a new mutable variable. The
definition syntax has to be different from the reassignment syntax, so that
the scope of a mutable variable can be determined. That's true in most
other imperative languages as well. Javascript uses almost the same syntax:
'var X = 0' to define variable X, and 'X = 1' to reassign it.

The ':=' operator is needed to distinguish 'myVar = 1', which defines a new
immutable variable with its own local scope, from 'myVar := 1', which
reassigns an existing mutable variable which is defined elsewhere.

The new 'do {...}' syntax is needed because the existing '{...}' syntax
doesn't have the same meaning it has in C: it's actually an expression that
constructs a 'group' data structure. You can see this by looking at the CSG
tree. Adding {...} to your code adds new groups to the CSG tree. This
distinction is probably not very important to most people right now, but it
becomes much more important in OpenSCAD2, where you start using {...}
expressions in all sorts of new contexts, like x = {...};

So the existing {...} is actually a kind of expression. Expressions need to
be referentially transparent (OpenSCAD is a declarative language), so they
can't modify mutable variables defined in an outer scope.

So I had to introduce the 'do {...}' syntax, which is a compound statement:
it has the same meaning as '{...}' does in C, Javascript and other C-like
imperative languages. As an alternative, I considered inventing a new kind
of bracket: {| ... |}, but it's hard to type and to pronounce.

I admit it is messed up to have a hybrid functional/imperative language
where the functional side is expressed using C syntax, and the imperative
side is expressed using non-C syntax. If backwards compatibility wasn't an
issue, it would be better to use '{...}' as the compound statement syntax,
instead of 'do {...}'.

I'd like to stress that 'do {...}' does not construct a data structure.
It's a kind of bracket that doesn't introduce nesting. That's potentially
useful in a list comprehension, or when generating geometry.

In a list comprehension,
[ for (i=0:10:90) do { i, i+1 } ]
generates
[ 0, 1, 10, 11, 20, 21, ... ]

This:
if (true) {
cube(10);
sphere(6);
}
wraps a group() around the cube and sphere, so it's equivalent to
group() {
cube(10);
sphere(6);
}
By contrast,
if (true) do {
cube(10);
sphere(6);
}
does not construct a new group(). Instead, it drops the cube and sphere at
the same level as the 'if' statement.

On 28 May 2016 at 23:13, Parkinbot rudolf@parkinbot.com wrote:

Hi Doug,

that's a great paper. Thanks for accepting the challenge. It reads
interesting and I can almost smell the wind of progress, it will bring into
the language. I never really understood, why functions in OpenSCAD
shouldn't
be imperative, as they provide a well defined interface to interact with
modules in a purely functional context. Your paper shows, that this path is
viable.

I'm not as deep into the matter as you are, so allow me some questions and
thoughts concerning some 'redundancies'.

valof{ expr};
marks 'expr' as imperative. I understand it as the central modifier
(context
switch) to annouce imperative code. However, as I read it, it will allow
for
'mixed' semantics, which makes things complicated. For this reason more
markers have to be introduced.

var x := expr;
marks 'x' as mutable and will be allowed only within valof{} expressions.
Isn't 'valof{}' + 'var' + ':=' kind of triple marking? 'var' is ok in a
function/procedure prototype to mark output variables.
In a non-mixed context 'let' and  '=' might have just overloaded semantics,
like in 'for' headers (more obvious in C-style), where mutable variables
also may be declared in common style.

do{list};
is it used as a separator between both worlds? Wouldn't it be obsolet in a
non-mixture enviroment?

To be able to define functional semantics code within an imperative
context,
some counterpart modifier could be introduced ...

Rudolf

--
View this message in context:
http://forum.openscad.org/Polygon-using-relative-points-rather-than-absolute-tp17414p17452.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

First of all, I agree that the new syntax kind of sucks, and is not C-like. That's a compromise which is required by the design goals I set for myself: * backward compatibility * preserve the meaning and declarative semantics of existing code I couldn't change the meaning of existing syntax, so I had to invent all new syntax for the bolted-on imperative programming extension. Maybe the syntax is revolting enough to make the whole idea unacceptable. Just to clarify, my proposal allows mutable variables to be defined and used in any context: * in the body of a function (that's where 'valof' is needed) * in the body of a module, or in any {...} expression * inside a list comprehension * at the top level Last month there was a forum post by Experimentalist asking why variables don't work as they do in an imperative language: >>> module Test(choice = 1) { echo(choice=choice); myVar = 0; if (choice==1) { myVar = 1; } else if (choice == 2) { myVar = 2; } else { myVar = 3; } echo(myVar=myVar); } <<< To rewrite this using the imperative programming extension: >>> module Test(choice = 1) { echo(choice=choice); var myVar := 0; if (choice==1) do { myVar := 1; } else if (choice == 2) do { myVar := 2; } else do { myVar := 3; } echo(myVar=myVar); } <<< Why the weird syntax? The 'var' keyword is needed to define a new mutable variable. The definition syntax has to be different from the reassignment syntax, so that the scope of a mutable variable can be determined. That's true in most other imperative languages as well. Javascript uses almost the same syntax: 'var X = 0' to define variable X, and 'X = 1' to reassign it. The ':=' operator is needed to distinguish 'myVar = 1', which defines a new immutable variable with its own local scope, from 'myVar := 1', which reassigns an existing mutable variable which is defined elsewhere. The new 'do {...}' syntax is needed because the existing '{...}' syntax doesn't have the same meaning it has in C: it's actually an expression that constructs a 'group' data structure. You can see this by looking at the CSG tree. Adding {...} to your code adds new groups to the CSG tree. This distinction is probably not very important to most people right now, but it becomes much more important in OpenSCAD2, where you start using {...} expressions in all sorts of new contexts, like x = {...}; So the existing {...} is actually a kind of expression. Expressions need to be referentially transparent (OpenSCAD is a declarative language), so they can't modify mutable variables defined in an outer scope. So I had to introduce the 'do {...}' syntax, which is a compound statement: it has the same meaning as '{...}' does in C, Javascript and other C-like imperative languages. As an alternative, I considered inventing a new kind of bracket: {| ... |}, but it's hard to type and to pronounce. I admit it is messed up to have a hybrid functional/imperative language where the functional side is expressed using C syntax, and the imperative side is expressed using non-C syntax. If backwards compatibility wasn't an issue, it would be better to use '{...}' as the compound statement syntax, instead of 'do {...}'. I'd like to stress that 'do {...}' does not construct a data structure. It's a kind of bracket that doesn't introduce nesting. That's potentially useful in a list comprehension, or when generating geometry. In a list comprehension, [ for (i=0:10:90) do { i, i+1 } ] generates [ 0, 1, 10, 11, 20, 21, ... ] This: if (true) { cube(10); sphere(6); } wraps a group() around the cube and sphere, so it's equivalent to group() { cube(10); sphere(6); } By contrast, if (true) do { cube(10); sphere(6); } does not construct a new group(). Instead, it drops the cube and sphere at the same level as the 'if' statement. On 28 May 2016 at 23:13, Parkinbot <rudolf@parkinbot.com> wrote: > Hi Doug, > > that's a great paper. Thanks for accepting the challenge. It reads > interesting and I can almost smell the wind of progress, it will bring into > the language. I never really understood, why functions in OpenSCAD > shouldn't > be imperative, as they provide a well defined interface to interact with > modules in a purely functional context. Your paper shows, that this path is > viable. > > I'm not as deep into the matter as you are, so allow me some questions and > thoughts concerning some 'redundancies'. > > valof{ expr}; > marks 'expr' as imperative. I understand it as the central modifier > (context > switch) to annouce imperative code. However, as I read it, it will allow > for > 'mixed' semantics, which makes things complicated. For this reason more > markers have to be introduced. > > var x := expr; > marks 'x' as mutable and will be allowed only within valof{} expressions. > Isn't 'valof{}' + 'var' + ':=' kind of triple marking? 'var' is ok in a > function/procedure prototype to mark output variables. > In a non-mixed context 'let' and '=' might have just overloaded semantics, > like in 'for' headers (more obvious in C-style), where mutable variables > also may be declared in common style. > > do{list}; > is it used as a separator between both worlds? Wouldn't it be obsolet in a > non-mixture enviroment? > > To be able to define functional semantics code within an imperative > context, > some counterpart modifier could be introduced ... > > Rudolf > > > > > > -- > View this message in context: > http://forum.openscad.org/Polygon-using-relative-points-rather-than-absolute-tp17414p17452.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 > > >
P
Parkinbot
Sun, May 29, 2016 7:50 PM

Doug,

thanks for elaborating on your paper. I think I understood your thoughts by
having read your paper quite intensively. Ok, maybe not in all implications
and consequences, so please correct me, if I am getting on the wrong path,
when trying to explain my expectation while building upon your approach.

Semantics is used to evaluate expressions and functions on the first hand,
which currently may appear in global, module and list comprehension context.
We are talking about two partially differing semantics and how they can
coexist. Let’s assume that OpenSCAD can be equipped with either of them,
without losing its declarative character, neither in mixed fashion. (This
will have to be shown, but not now, as we are still in a phase of 'creative
discussion'.)

If I was to implement a second semantics, I'd separate to two near to the
root of the syntax tree, and not near the leaves, as you try in your paper.
And I’d use an own parser for each of them for easy operator overload. (Of
course one would use a common parser with a slightly different language and
semantics, which has the same effect.) Think about the task of including
inline assembler code while programming the ‘slow’ code in C.

So, for clearness, let's rename valof{} into imp{} and give it a counterpart
named func{}. Both serve as modifier to an expression (or a {}-list of
expressions), with func{} being the default to keep up compatibility with
all old code. In list comprehension we could use func[…] and imp[…]
respectively, instead of imp{[…]} - but possible omissions are already the
details.

Any function or module body is by default declared as func{}, which can also
be written explicitly for clearness. If a body is declared as func{},
variables are non-mutable i.e. value-overriding – current functional
semantics. If a body is declared as imp{} any local variable declared in
this context will be mutable. Most notable difference: expressions like a =
a+1 will evaluate as 'expected'. Currently

B = 1;
B = B+1;
echo (B);

is not allowed in global context, but in function context:

echo (test());      // ECHO: 2
function test() = let (A = 1)  let (A = A+1) A;

while is does ‘strange’ things, when used like this:

echo (test());      // ECHO: [1, 2, 3]
function test() = let (A = 1) [for (i=[0:2]) let (A = A+i) A];

so if we defined test() like this

echo (test());      // ECHO: [1, 2, 4]
function test() = imp { let (A = 1) [for (i=[0:2]) let (A = A+i) A]};

the ‘second’ parser will regard 'A' as mutable and generate code with
imperative semantics. That means, variables will always be treated (typed)
according to the modifier of the scope they are introduced (think about a
‘const’ declaration in C++), and operators will be interpreted according to
the current scope modifier. The rule is: Outer scope mutable variables are
not mutable within code declared with func{} and outer scope non-mutable
variables are not mutable within code declared with imp{}.

Mixed mode is easy to achieve. Any expression or statement list {…} will
‘inherit’ its modifier from its parent. So if global code is declared as
imp{}, all code will be parsed with imperative semantics and vice versa. Any
inherited modifier can be overridden to enforce either semantics for any
piece of code. So you can compose code using semantics in colorful mixture -
in sequenced and in structured layout.

Library code will have its own modifier - same rules apply. Thus ‘legacy’
code, even if imported within a imp{} chunk, will be func{} by default.

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

Doug, thanks for elaborating on your paper. I think I understood your thoughts by having read your paper quite intensively. Ok, maybe not in all implications and consequences, so please correct me, if I am getting on the wrong path, when trying to explain my expectation while building upon your approach. Semantics is used to evaluate expressions and functions on the first hand, which currently may appear in global, module and list comprehension context. We are talking about two partially differing semantics and how they can coexist. Let’s assume that OpenSCAD can be equipped with either of them, without losing its declarative character, neither in mixed fashion. (This will have to be shown, but not now, as we are still in a phase of 'creative discussion'.) If I was to implement a second semantics, I'd separate to two near to the root of the syntax tree, and not near the leaves, as you try in your paper. And I’d use an own parser for each of them for easy operator overload. (Of course one would use a common parser with a slightly different language and semantics, which has the same effect.) Think about the task of including inline assembler code while programming the ‘slow’ code in C. So, for clearness, let's rename valof{} into imp{} and give it a counterpart named func{}. Both serve as modifier to an expression (or a {}-list of expressions), with func{} being the default to keep up compatibility with *all* old code. In list comprehension we could use func[…] and imp[…] respectively, instead of imp{[…]} - but possible omissions are already the details. Any function or module body is by default declared as func{}, which can also be written explicitly for clearness. If a body is declared as func{}, variables are non-mutable i.e. value-overriding – current functional semantics. If a body is declared as imp{} any local variable declared in this context will be mutable. Most notable difference: expressions like a = a+1 will evaluate as 'expected'. Currently > B = 1; > B = B+1; > echo (B); is not allowed in global context, but in function context: > echo (test()); // ECHO: 2 > function test() = let (A = 1) let (A = A+1) A; while is does ‘strange’ things, when used like this: > echo (test()); // ECHO: [1, 2, 3] > function test() = let (A = 1) [for (i=[0:2]) let (A = A+i) A]; so if we defined test() like this > echo (test()); // ECHO: [1, 2, 4] > function test() = imp { let (A = 1) [for (i=[0:2]) let (A = A+i) A]}; the ‘second’ parser will regard 'A' as mutable and generate code with imperative semantics. That means, variables will always be treated (typed) according to the modifier of the scope they are introduced (think about a ‘const’ declaration in C++), and operators will be interpreted according to the current scope modifier. The rule is: Outer scope mutable variables are not mutable within code declared with func{} and outer scope non-mutable variables are not mutable within code declared with imp{}. Mixed mode is easy to achieve. Any expression or statement list {…} will ‘inherit’ its modifier from its parent. So if global code is declared as imp{}, all code will be parsed with imperative semantics and vice versa. Any inherited modifier can be overridden to enforce either semantics for any piece of code. So you can compose code using semantics in colorful mixture - in sequenced and in structured layout. Library code will have its own modifier - same rules apply. Thus ‘legacy’ code, even if imported within a imp{} chunk, will be func{} by default. -- View this message in context: http://forum.openscad.org/Polygon-using-relative-points-rather-than-absolute-tp17414p17465.html Sent from the OpenSCAD mailing list archive at Nabble.com.
M
MichaelAtOz
Sun, May 29, 2016 10:09 PM

doug.moen wrote

Hi Parkinbot. I have accepted your challenge, and designed a way to add
mutable variables to OpenSCAD without violating the declarative semantics.

Just because you can doesn't mean you should.

The drawback is: more language complexity. OpenSCAD is now a hybrid of a
declarative language with an imperative language.

Yes, it is turning into a Frankenstein's monster of a language.

I honestly don't know if we actually want to make this change. Do we want
to turn OpenSCAD into a general purpose programming language? However,
it's
worth having the discussion, since the topic is often raised in the forum,
so I wrote a design paper to show people what this would look like.

No, I don't think we do. If this happens then the imperative programmers
will just wine about the limitation you have imposed and want more. There
are already OpenSCAD-esc imperative languages, OpenJSCAD etc, no need to
pollute this one.

Also, this would also inhibit parallelism, which I believe would be much
more beneficial.

So, thanks for opening the discussion, but, IMO no thanks...


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!

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

doug.moen wrote > Hi Parkinbot. I have accepted your challenge, and designed a way to add > mutable variables to OpenSCAD without violating the declarative semantics. Just because you can doesn't mean you should. > The drawback is: more language complexity. OpenSCAD is now a hybrid of a > declarative language with an imperative language. Yes, it is turning into a Frankenstein's monster of a language. > I honestly don't know if we actually want to make this change. Do we want > to turn OpenSCAD into a general purpose programming language? However, > it's > worth having the discussion, since the topic is often raised in the forum, > so I wrote a design paper to show people what this would look like. No, I don't think we do. If this happens then the imperative programmers will just wine about the limitation you have imposed and want more. There are already OpenSCAD-esc imperative languages, OpenJSCAD etc, no need to pollute this one. Also, this would also inhibit parallelism, which I believe would be much more beneficial. So, thanks for opening the discussion, but, IMO no thanks... ----- 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! -- View this message in context: http://forum.openscad.org/Polygon-using-relative-points-rather-than-absolute-tp17414p17466.html Sent from the OpenSCAD mailing list archive at Nabble.com.
MS
Mark Schafer
Sun, May 29, 2016 10:32 PM

This has been very interesting and I appreciate all the work Doug (and
others) have put into this.
I would describe the resulting problem raised by mixing these two
approaches into OpenSCAD as resulting in a syntax mish-mash (for want of
a better term).

How about a slightly compromised way of thinking about it.

I know there is already some wrappers for OpenSCAD in other languages.
What if OpenSCAD was more fully integrated into one of these languages.
Lets choose Python for sake of the argument.

We would then gain the advantages of a fully defined imperative language
with all of its data-structures etc. As well as the declarative
structure of OpenSCAD.

To make this work better than existing implementations would involve
making it easier to describe the final declarative description of the
Tree. Current implementations basically construct a scad file, and
execute it. But if we could evaluate and then interrogate the result
within something like Python, then the advantages could be realised with
less effort and ongoing maintenance etc.

We might even be able to get to the complex issues surrounding problems
similar to (say) building an N-part mold of convex parts.

The advantage of choosing a single programming to language to integrate
to is simply one of pragmatism. Of course the interface could be opened
up to all.

On 5/30/2016 10:09 AM, MichaelAtOz wrote:

doug.moen wrote

Hi Parkinbot. I have accepted your challenge, and designed a way to add
mutable variables to OpenSCAD without violating the declarative semantics.

Just because you can doesn't mean you should.

The drawback is: more language complexity. OpenSCAD is now a hybrid of a
declarative language with an imperative language.

Yes, it is turning into a Frankenstein's monster of a language.

I honestly don't know if we actually want to make this change. Do we want
to turn OpenSCAD into a general purpose programming language? However,
it's
worth having the discussion, since the topic is often raised in the forum,
so I wrote a design paper to show people what this would look like.

No, I don't think we do. If this happens then the imperative programmers
will just wine about the limitation you have imposed and want more. There
are already OpenSCAD-esc imperative languages, OpenJSCAD etc, no need to
pollute this one.

Also, this would also inhibit parallelism, which I believe would be much
more beneficial.

So, thanks for opening the discussion, but, IMO no thanks...


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!

View this message in context: http://forum.openscad.org/Polygon-using-relative-points-rather-than-absolute-tp17414p17466.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


No virus found in this message.
Checked by AVG - www.avg.com
Version: 2016.0.7598 / Virus Database: 4568/12320 - Release Date: 05/29/16

This has been very interesting and I appreciate all the work Doug (and others) have put into this. I would describe the resulting problem raised by mixing these two approaches into OpenSCAD as resulting in a syntax mish-mash (for want of a better term). How about a slightly compromised way of thinking about it. I know there is already some wrappers for OpenSCAD in other languages. What if OpenSCAD was more fully integrated into one of these languages. Lets choose Python for sake of the argument. We would then gain the advantages of a fully defined imperative language with all of its data-structures etc. As well as the declarative structure of OpenSCAD. To make this work better than existing implementations would involve making it easier to describe the final declarative description of the Tree. Current implementations basically construct a scad file, and execute it. But if we could evaluate and then interrogate the result within something like Python, then the advantages could be realised with less effort and ongoing maintenance etc. We might even be able to get to the complex issues surrounding problems similar to (say) building an N-part mold of convex parts. The advantage of choosing a single programming to language to integrate to is simply one of pragmatism. Of course the interface could be opened up to all. On 5/30/2016 10:09 AM, MichaelAtOz wrote: > doug.moen wrote >> Hi Parkinbot. I have accepted your challenge, and designed a way to add >> mutable variables to OpenSCAD without violating the declarative semantics. > Just because you can doesn't mean you should. > >> The drawback is: more language complexity. OpenSCAD is now a hybrid of a >> declarative language with an imperative language. > Yes, it is turning into a Frankenstein's monster of a language. > >> I honestly don't know if we actually want to make this change. Do we want >> to turn OpenSCAD into a general purpose programming language? However, >> it's >> worth having the discussion, since the topic is often raised in the forum, >> so I wrote a design paper to show people what this would look like. > No, I don't think we do. If this happens then the imperative programmers > will just wine about the limitation you have imposed and want more. There > are already OpenSCAD-esc imperative languages, OpenJSCAD etc, no need to > pollute this one. > > Also, this would also inhibit parallelism, which I believe would be much > more beneficial. > > So, thanks for opening the discussion, but, IMO no thanks... > > > > ----- > 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! > -- > View this message in context: http://forum.openscad.org/Polygon-using-relative-points-rather-than-absolute-tp17414p17466.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 > > > ----- > No virus found in this message. > Checked by AVG - www.avg.com > Version: 2016.0.7598 / Virus Database: 4568/12320 - Release Date: 05/29/16
DM
doug moen
Mon, May 30, 2016 12:13 AM

I've thought about the language integration approach. The language I would
choose to integrate with would be C. Most industrial strength programming
languages, including Python, have some way to interoperate with C code. So,
the C API could be used as a bridge between languages.

On 29 May 2016 at 18:32, Mark Schafer mschafer@wireframe.biz wrote:

This has been very interesting and I appreciate all the work Doug (and
others) have put into this.
I would describe the resulting problem raised by mixing these two
approaches into OpenSCAD as resulting in a syntax mish-mash (for want of a
better term).

How about a slightly compromised way of thinking about it.

I know there is already some wrappers for OpenSCAD in other languages.
What if OpenSCAD was more fully integrated into one of these languages.
Lets choose Python for sake of the argument.

We would then gain the advantages of a fully defined imperative language
with all of its data-structures etc. As well as the declarative structure
of OpenSCAD.

To make this work better than existing implementations would involve
making it easier to describe the final declarative description of the Tree.
Current implementations basically construct a scad file, and execute it.
But if we could evaluate and then interrogate the result within something
like Python, then the advantages could be realised with less effort and
ongoing maintenance etc.

We might even be able to get to the complex issues surrounding problems
similar to (say) building an N-part mold of convex parts.

The advantage of choosing a single programming to language to integrate to
is simply one of pragmatism. Of course the interface could be opened up to
all.

On 5/30/2016 10:09 AM, MichaelAtOz wrote:

doug.moen wrote

Hi Parkinbot. I have accepted your challenge, and designed a way to add
mutable variables to OpenSCAD without violating the declarative
semantics.

Just because you can doesn't mean you should.

The drawback is: more language complexity. OpenSCAD is now a hybrid of a

declarative language with an imperative language.

Yes, it is turning into a Frankenstein's monster of a language.

I honestly don't know if we actually want to make this change. Do we want

to turn OpenSCAD into a general purpose programming language? However,
it's
worth having the discussion, since the topic is often raised in the
forum,
so I wrote a design paper to show people what this would look like.

No, I don't think we do. If this happens then the imperative programmers
will just wine about the limitation you have imposed and want more. There
are already OpenSCAD-esc imperative languages, OpenJSCAD etc, no need to
pollute this one.

Also, this would also inhibit parallelism, which I believe would be much
more beneficial.

So, thanks for opening the discussion, but, IMO no thanks...


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!

View this message in context:
http://forum.openscad.org/Polygon-using-relative-points-rather-than-absolute-tp17414p17466.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


No virus found in this message.
Checked by AVG - www.avg.com
Version: 2016.0.7598 / Virus Database: 4568/12320 - Release Date: 05/29/16

I've thought about the language integration approach. The language I would choose to integrate with would be C. Most industrial strength programming languages, including Python, have some way to interoperate with C code. So, the C API could be used as a bridge between languages. On 29 May 2016 at 18:32, Mark Schafer <mschafer@wireframe.biz> wrote: > This has been very interesting and I appreciate all the work Doug (and > others) have put into this. > I would describe the resulting problem raised by mixing these two > approaches into OpenSCAD as resulting in a syntax mish-mash (for want of a > better term). > > How about a slightly compromised way of thinking about it. > > I know there is already some wrappers for OpenSCAD in other languages. > What if OpenSCAD was more fully integrated into one of these languages. > Lets choose Python for sake of the argument. > > We would then gain the advantages of a fully defined imperative language > with all of its data-structures etc. As well as the declarative structure > of OpenSCAD. > > To make this work better than existing implementations would involve > making it easier to describe the final declarative description of the Tree. > Current implementations basically construct a scad file, and execute it. > But if we could evaluate and then interrogate the result within something > like Python, then the advantages could be realised with less effort and > ongoing maintenance etc. > > We might even be able to get to the complex issues surrounding problems > similar to (say) building an N-part mold of convex parts. > > The advantage of choosing a single programming to language to integrate to > is simply one of pragmatism. Of course the interface could be opened up to > all. > > > > > On 5/30/2016 10:09 AM, MichaelAtOz wrote: > >> doug.moen wrote >> >>> Hi Parkinbot. I have accepted your challenge, and designed a way to add >>> mutable variables to OpenSCAD without violating the declarative >>> semantics. >>> >> Just because you can doesn't mean you should. >> >> The drawback is: more language complexity. OpenSCAD is now a hybrid of a >>> declarative language with an imperative language. >>> >> Yes, it is turning into a Frankenstein's monster of a language. >> >> I honestly don't know if we actually want to make this change. Do we want >>> to turn OpenSCAD into a general purpose programming language? However, >>> it's >>> worth having the discussion, since the topic is often raised in the >>> forum, >>> so I wrote a design paper to show people what this would look like. >>> >> No, I don't think we do. If this happens then the imperative programmers >> will just wine about the limitation you have imposed and want more. There >> are already OpenSCAD-esc imperative languages, OpenJSCAD etc, no need to >> pollute this one. >> >> Also, this would also inhibit parallelism, which I believe would be much >> more beneficial. >> >> So, thanks for opening the discussion, but, IMO no thanks... >> >> >> >> ----- >> 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! >> -- >> View this message in context: >> http://forum.openscad.org/Polygon-using-relative-points-rather-than-absolute-tp17414p17466.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 >> >> >> ----- >> No virus found in this message. >> Checked by AVG - www.avg.com >> Version: 2016.0.7598 / Virus Database: 4568/12320 - Release Date: 05/29/16 >> > > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >
P
Parkinbot
Mon, May 30, 2016 11:27 AM

MichaelAtOz wrote

imperative programmers will just wine about the limitation you have
imposed and want more.

Yeah, they are so demanding, once you give them an inch, they'll take a
mile. If they do not want to calculate sums in O(n²) by writing recursive
functions, they'd better go elsewhere.

Btw, isn't list-comprehension an imperative embedding? Is has brought so
much value - and new syntax - to OpenSCAD. Do you want to deny that?

Your second argument is nuts. Parallelism and imperative elements is NOT an
either-or decision - especially not in a declarative embedding.

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

MichaelAtOz wrote > imperative programmers will just wine about the limitation you have > imposed and want more. Yeah, they are so demanding, once you give them an inch, they'll take a mile. If they do not want to calculate sums in O(n²) by writing recursive functions, they'd better go elsewhere. Btw, isn't list-comprehension an imperative embedding? Is has brought so much value - and new syntax - to OpenSCAD. Do you want to deny that? Your second argument is nuts. Parallelism and imperative elements is NOT an either-or decision - especially not in a declarative embedding. -- View this message in context: http://forum.openscad.org/Polygon-using-relative-points-rather-than-absolute-tp17414p17473.html Sent from the OpenSCAD mailing list archive at Nabble.com.
DM
doug moen
Mon, May 30, 2016 4:46 PM

Parkinbot wrote:

If they do not want to calculate sums in O(n²) by writing recursive

functions, they'd better go elsewhere.

There's actually two issues in there. The main one is the "everything you
know about programming doesn't work here" experience that imperative
programmers experience when learning OpenSCAD. The other is performance.
The mutable variable proposal tries to address the first issue, but in it's
current state, it's a really ugly hack.

Performance is an independent issue. I'm doing some prototyping work to
build a really fast evaluator. The #1 most important thing, in my opinion,
is to compile OpenSCAD into a form that can be efficiently executed. That
includes optimizations, where high level patterns (like tail recursion) are
compiled into more efficient forms (like loops). I don't think mutable
variables will be required for performance, but we'll see. Measurement is
the final arbiter of truth.

Btw, isn't list-comprehension an imperative embedding?

Yes, but only in OpenSCAD. This has been my main contribution so far:
making list comprehensions look like C code. In other programming
languages, list comprehensions are an ASCII-ized version of set builder
notation from mathematics.
Eg, math notation:
{ x² | x ∊ ℕ ∧ x ≤ 10 }
Haskell:
[ x^2 | x <- [0..10] ]
OpenSCAD:
[ for (x = [0:10]) pow(x,2) ]

Ditto for the still-experimental and not yet approved "C style for". It's
the result of defining a list library for OpenSCAD2, inspired by the
Haskell list library, but redesigned for ease of use. Haskell has an
'unfold' operation, which is potentially useful, but the interface is hard
to understand:

let fibonacci n =
unfoldr ((a,b) -> if a < n then Just (a,(b,a+b)) else Nothing) (0,1)

My big idea was that 'unfold' can be expressed using C syntax:

function fibonacci(n) =
[for (a=0, b=1; a < n; t=a, a=b, b=t+b) a];

And once again, this looks like an imperative embedding. One of the
threads I've been pursuing, while working on OpenSCAD, is how to make
functional programming easier to use, and more acceptable to imperative
programmers.

On 30 May 2016 at 07:27, Parkinbot rudolf@parkinbot.com wrote:

MichaelAtOz wrote

imperative programmers will just wine about the limitation you have
imposed and want more.

Yeah, they are so demanding, once you give them an inch, they'll take a
mile. If they do not want to calculate sums in O(n²) by writing recursive
functions, they'd better go elsewhere.

Btw, isn't list-comprehension an imperative embedding? Is has brought so
much value - and new syntax - to OpenSCAD. Do you want to deny that?

Your second argument is nuts. Parallelism and imperative elements is NOT an
either-or decision - especially not in a declarative embedding.

--
View this message in context:
http://forum.openscad.org/Polygon-using-relative-points-rather-than-absolute-tp17414p17473.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

Parkinbot wrote: > If they do not want to calculate sums in O(n²) by writing recursive functions, they'd better go elsewhere. There's actually two issues in there. The main one is the "everything you know about programming doesn't work here" experience that imperative programmers experience when learning OpenSCAD. The other is performance. The mutable variable proposal tries to address the first issue, but in it's current state, it's a really ugly hack. Performance is an independent issue. I'm doing some prototyping work to build a really fast evaluator. The #1 most important thing, in my opinion, is to compile OpenSCAD into a form that can be efficiently executed. That includes optimizations, where high level patterns (like tail recursion) are compiled into more efficient forms (like loops). I don't think mutable variables will be required for performance, but we'll see. Measurement is the final arbiter of truth. > Btw, isn't list-comprehension an imperative embedding? Yes, but only in OpenSCAD. This has been my main contribution so far: making list comprehensions look like C code. In other programming languages, list comprehensions are an ASCII-ized version of set builder notation from mathematics. Eg, math notation: { x² | x ∊ ℕ ∧ x ≤ 10 } Haskell: [ x^2 | x <- [0..10] ] OpenSCAD: [ for (x = [0:10]) pow(x,2) ] Ditto for the still-experimental and not yet approved "C style for". It's the result of defining a list library for OpenSCAD2, inspired by the Haskell list library, but redesigned for ease of use. Haskell has an 'unfold' operation, which is potentially useful, but the interface is hard to understand: let fibonacci n = unfoldr (\(a,b) -> if a < n then Just (a,(b,a+b)) else Nothing) (0,1) My big idea was that 'unfold' can be expressed using C syntax: function fibonacci(n) = [for (a=0, b=1; a < n; t=a, a=b, b=t+b) a]; And once again, this *looks like* an imperative embedding. One of the threads I've been pursuing, while working on OpenSCAD, is how to make functional programming easier to use, and more acceptable to imperative programmers. On 30 May 2016 at 07:27, Parkinbot <rudolf@parkinbot.com> wrote: > MichaelAtOz wrote > > imperative programmers will just wine about the limitation you have > > imposed and want more. > > Yeah, they are so demanding, once you give them an inch, they'll take a > mile. If they do not want to calculate sums in O(n²) by writing recursive > functions, they'd better go elsewhere. > > Btw, isn't list-comprehension an imperative embedding? Is has brought so > much value - and new syntax - to OpenSCAD. Do you want to deny that? > > Your second argument is nuts. Parallelism and imperative elements is NOT an > either-or decision - especially not in a declarative embedding. > > > > > > > -- > View this message in context: > http://forum.openscad.org/Polygon-using-relative-points-rather-than-absolute-tp17414p17473.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 >
DM
doug moen
Tue, May 31, 2016 2:35 AM

Hi Parkinbot. Thanks for reading the paper and making comments. I updated
the Mutable Variables design doc, somewhat along the lines that you
suggested. The keyword 'do' is now consistently used to switch into the
imperative sublanguage, and {...} is now a compound statement in the
imperative language, as desired. I got rid of the 'call' keyword, so that a
procedure call is just 'p(x);'. So the syntax is more C-like, less
surprising.

The original paper made it possible for a library to export a mutable
variable defined at the top level. That was a bad mistake, it's fixed.
Mutable variables can now only be defined locally within a 'do' block or a
procedure definition.

I kept the ':=' operator because it's important to make a clear distinction
between reassigning a mutable variable, and defining an immutable variable.
We can't use '=' for both, otherwise it will be very confusing, and we'd
theoretically have a lot of forum posts asking why x=x+1 works in some
contexts and fails in other contexts. For what it's worth, Pascal and a lot
of related languages use '=' for defining constants and ':=' for
reassigning a mutable variable, so my syntax is consistent with that.

I think the new design is simpler and cleaner. The imperative sublanguage
is now more cleanly segregated. However, MichaelAtOz's main objection still
stands, it's still a hybrid language (aka "Frankenstein monster"), so I
think it is unlikely that this will be implemented.

Doug.

On 29 May 2016 at 15:50, Parkinbot rudolf@parkinbot.com wrote:

Doug,

thanks for elaborating on your paper. I think I understood your thoughts by
having read your paper quite intensively. Ok, maybe not in all implications
and consequences, so please correct me, if I am getting on the wrong path,
when trying to explain my expectation while building upon your approach.

Semantics is used to evaluate expressions and functions on the first hand,
which currently may appear in global, module and list comprehension
context.
We are talking about two partially differing semantics and how they can
coexist. Let’s assume that OpenSCAD can be equipped with either of them,
without losing its declarative character, neither in mixed fashion. (This
will have to be shown, but not now, as we are still in a phase of 'creative
discussion'.)

If I was to implement a second semantics, I'd separate to two near to the
root of the syntax tree, and not near the leaves, as you try in your paper.
And I’d use an own parser for each of them for easy operator overload. (Of
course one would use a common parser with a slightly different language and
semantics, which has the same effect.) Think about the task of including
inline assembler code while programming the ‘slow’ code in C.

So, for clearness, let's rename valof{} into imp{} and give it a
counterpart
named func{}. Both serve as modifier to an expression (or a {}-list of
expressions), with func{} being the default to keep up compatibility with
all old code. In list comprehension we could use func[…] and imp[…]
respectively, instead of imp{[…]} - but possible omissions are already the
details.

Any function or module body is by default declared as func{}, which can
also
be written explicitly for clearness. If a body is declared as func{},
variables are non-mutable i.e. value-overriding – current functional
semantics. If a body is declared as imp{} any local variable declared in
this context will be mutable. Most notable difference: expressions like a =
a+1 will evaluate as 'expected'. Currently

B = 1;
B = B+1;
echo (B);

is not allowed in global context, but in function context:

echo (test());      // ECHO: 2
function test() = let (A = 1)  let (A = A+1) A;

while is does ‘strange’ things, when used like this:

echo (test());      // ECHO: [1, 2, 3]
function test() = let (A = 1) [for (i=[0:2]) let (A = A+i) A];

so if we defined test() like this

echo (test());      // ECHO: [1, 2, 4]
function test() = imp { let (A = 1) [for (i=[0:2]) let (A = A+i) A]};

the ‘second’ parser will regard 'A' as mutable and generate code with
imperative semantics. That means, variables will always be treated (typed)
according to the modifier of the scope they are introduced (think about a
‘const’ declaration in C++), and operators will be interpreted according to
the current scope modifier. The rule is: Outer scope mutable variables are
not mutable within code declared with func{} and outer scope non-mutable
variables are not mutable within code declared with imp{}.

Mixed mode is easy to achieve. Any expression or statement list {…} will
‘inherit’ its modifier from its parent. So if global code is declared as
imp{}, all code will be parsed with imperative semantics and vice versa.
Any
inherited modifier can be overridden to enforce either semantics for any
piece of code. So you can compose code using semantics in colorful mixture

in sequenced and in structured layout.

Library code will have its own modifier - same rules apply. Thus ‘legacy’
code, even if imported within a imp{} chunk, will be func{} by default.

--
View this message in context:
http://forum.openscad.org/Polygon-using-relative-points-rather-than-absolute-tp17414p17465.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. Thanks for reading the paper and making comments. I updated the Mutable Variables design doc, somewhat along the lines that you suggested. The keyword 'do' is now consistently used to switch into the imperative sublanguage, and {...} is now a compound statement in the imperative language, as desired. I got rid of the 'call' keyword, so that a procedure call is just 'p(x);'. So the syntax is more C-like, less surprising. The original paper made it possible for a library to export a mutable variable defined at the top level. That was a bad mistake, it's fixed. Mutable variables can now only be defined locally within a 'do' block or a procedure definition. I kept the ':=' operator because it's important to make a clear distinction between reassigning a mutable variable, and defining an immutable variable. We can't use '=' for both, otherwise it will be very confusing, and we'd theoretically have a lot of forum posts asking why x=x+1 works in some contexts and fails in other contexts. For what it's worth, Pascal and a lot of related languages use '=' for defining constants and ':=' for reassigning a mutable variable, so my syntax is consistent with that. I think the new design is simpler and cleaner. The imperative sublanguage is now more cleanly segregated. However, MichaelAtOz's main objection still stands, it's still a hybrid language (aka "Frankenstein monster"), so I think it is unlikely that this will be implemented. Doug. On 29 May 2016 at 15:50, Parkinbot <rudolf@parkinbot.com> wrote: > Doug, > > thanks for elaborating on your paper. I think I understood your thoughts by > having read your paper quite intensively. Ok, maybe not in all implications > and consequences, so please correct me, if I am getting on the wrong path, > when trying to explain my expectation while building upon your approach. > > Semantics is used to evaluate expressions and functions on the first hand, > which currently may appear in global, module and list comprehension > context. > We are talking about two partially differing semantics and how they can > coexist. Let’s assume that OpenSCAD can be equipped with either of them, > without losing its declarative character, neither in mixed fashion. (This > will have to be shown, but not now, as we are still in a phase of 'creative > discussion'.) > > If I was to implement a second semantics, I'd separate to two near to the > root of the syntax tree, and not near the leaves, as you try in your paper. > And I’d use an own parser for each of them for easy operator overload. (Of > course one would use a common parser with a slightly different language and > semantics, which has the same effect.) Think about the task of including > inline assembler code while programming the ‘slow’ code in C. > > So, for clearness, let's rename valof{} into imp{} and give it a > counterpart > named func{}. Both serve as modifier to an expression (or a {}-list of > expressions), with func{} being the default to keep up compatibility with > *all* old code. In list comprehension we could use func[…] and imp[…] > respectively, instead of imp{[…]} - but possible omissions are already the > details. > > Any function or module body is by default declared as func{}, which can > also > be written explicitly for clearness. If a body is declared as func{}, > variables are non-mutable i.e. value-overriding – current functional > semantics. If a body is declared as imp{} any local variable declared in > this context will be mutable. Most notable difference: expressions like a = > a+1 will evaluate as 'expected'. Currently > > > B = 1; > > B = B+1; > > echo (B); > > is not allowed in global context, but in function context: > > > echo (test()); // ECHO: 2 > > function test() = let (A = 1) let (A = A+1) A; > > while is does ‘strange’ things, when used like this: > > > echo (test()); // ECHO: [1, 2, 3] > > function test() = let (A = 1) [for (i=[0:2]) let (A = A+i) A]; > > so if we defined test() like this > > > echo (test()); // ECHO: [1, 2, 4] > > function test() = imp { let (A = 1) [for (i=[0:2]) let (A = A+i) A]}; > > the ‘second’ parser will regard 'A' as mutable and generate code with > imperative semantics. That means, variables will always be treated (typed) > according to the modifier of the scope they are introduced (think about a > ‘const’ declaration in C++), and operators will be interpreted according to > the current scope modifier. The rule is: Outer scope mutable variables are > not mutable within code declared with func{} and outer scope non-mutable > variables are not mutable within code declared with imp{}. > > Mixed mode is easy to achieve. Any expression or statement list {…} will > ‘inherit’ its modifier from its parent. So if global code is declared as > imp{}, all code will be parsed with imperative semantics and vice versa. > Any > inherited modifier can be overridden to enforce either semantics for any > piece of code. So you can compose code using semantics in colorful mixture > - > in sequenced and in structured layout. > > Library code will have its own modifier - same rules apply. Thus ‘legacy’ > code, even if imported within a imp{} chunk, will be func{} by default. > > > > > -- > View this message in context: > http://forum.openscad.org/Polygon-using-relative-points-rather-than-absolute-tp17414p17465.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 >
P
Parkinbot
Tue, May 31, 2016 12:10 PM

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.

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.