discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

Feedback for 'each' operator

DM
doug moen
Sun, Nov 13, 2016 6:59 PM

The OpenSCAD snapshot has a new 'each' operator.

I have noticed that most actual use cases are the pattern 'each [a,b,c]':
the argument to 'each' is usually a list constructor.

Here's an example recently posted by Marius:
function circle(R,N) =
[ for (w = [0:round(360/N):359])
if (w==180) each [[Rcos(w),Rsin(w)],
[Rcos(w)+1,Rsin(w)],
[Rcos(w)+1,Rsin(w)+1],
[Rcos(w),Rsin(w)+1]]
else [Rcos(w),Rsin(w)]
];

I'm in the middle of implementing list comprehensions for my OpenSCAD2
prototype, and I've noticed, from working with the grammar, that there is a
more natural syntax available for this use case. Instead of writing 'each
[a,b,c]', you could write '(a,b,c)'.

Here's Marius's example rewritten using this syntax:
function circle(R,N) =
[
for (w = [0:round(360/N):359])
if (w==180) (
[Rcos(w),Rsin(w)],
[Rcos(w)+1,Rsin(w)],
[Rcos(w)+1,Rsin(w)+1],
[Rcos(w),Rsin(w)+1]
) else
[Rcos(w),Rsin(w)]
];

This proposed syntax falls out naturally, if you take the following as the
syntax for list constructors:

list-constructor ::= '[' generator ']'
generator ::= <empty>
generator ::= expression
generator ::= generator ',' generator ',' ... ',' generator
generator ::= '(' generator ')'
generator ::= 'if' '(' expression ')' generator
generator ::= 'if' '(' expression ')' generator 'else' generator
generator ::= 'for' '(' identifier '=' expression ')' generator
generator ::= 'let' '(' definitions ')' generator

With this grammar, '()' generates 0 values and '(a,b,c)' generates 3 values.

'if (c) (x,y,z) else ()' generates 3 values if c is true, or zero values if
it is false. As an abbreviation, you can omit the 'else ()' and just write
'if (c) (x,y,z)'.

The net result is that I get the new syntax "for free", just by writing my
grammar in a particular way. And that's why I think it is a "more natural"
syntax. We already use commas at the top level of a list constructor to
separate items in a sequence, and with Torsten's latest change, we already
allow generator phrases to be parenthesized. So my proposed syntax is
actually just removing a restriction from the grammar, so that a
parenthesized comma separated list is also a legal generator.

The OpenSCAD snapshot has a new 'each' operator. I have noticed that most actual use cases are the pattern 'each [a,b,c]': the argument to 'each' is usually a list constructor. Here's an example recently posted by Marius: function circle(R,N) = [ for (w = [0:round(360/N):359]) if (w==180) each [[R*cos(w),R*sin(w)], [R*cos(w)+1,R*sin(w)], [R*cos(w)+1,R*sin(w)+1], [R*cos(w),R*sin(w)+1]] else [R*cos(w),R*sin(w)] ]; I'm in the middle of implementing list comprehensions for my OpenSCAD2 prototype, and I've noticed, from working with the grammar, that there is a more natural syntax available for this use case. Instead of writing 'each [a,b,c]', you could write '(a,b,c)'. Here's Marius's example rewritten using this syntax: function circle(R,N) = [ for (w = [0:round(360/N):359]) if (w==180) ( [R*cos(w),R*sin(w)], [R*cos(w)+1,R*sin(w)], [R*cos(w)+1,R*sin(w)+1], [R*cos(w),R*sin(w)+1] ) else [R*cos(w),R*sin(w)] ]; This proposed syntax falls out naturally, if you take the following as the syntax for list constructors: list-constructor ::= '[' generator ']' generator ::= <empty> generator ::= expression generator ::= generator ',' generator ',' ... ',' generator generator ::= '(' generator ')' generator ::= 'if' '(' expression ')' generator generator ::= 'if' '(' expression ')' generator 'else' generator generator ::= 'for' '(' identifier '=' expression ')' generator generator ::= 'let' '(' definitions ')' generator With this grammar, '()' generates 0 values and '(a,b,c)' generates 3 values. 'if (c) (x,y,z) else ()' generates 3 values if c is true, or zero values if it is false. As an abbreviation, you can omit the 'else ()' and just write 'if (c) (x,y,z)'. The net result is that I get the new syntax "for free", just by writing my grammar in a particular way. And that's why I think it is a "more natural" syntax. We already use commas at the top level of a list constructor to separate items in a sequence, and with Torsten's latest change, we already allow generator phrases to be parenthesized. So my proposed syntax is actually just removing a restriction from the grammar, so that a parenthesized comma separated list is also a legal generator.
RP
Ronaldo Persiano
Sun, Nov 13, 2016 7:25 PM

Nice. I have noticed that 'each' in the snapshot version unwraps ranges. So:

each [3:-1:1] is equivalent to each [3,2,1]

Does your proposed grammar produce similar results? Or, is ( [3:-1:1] )
equivalent to (3,2,1) ?

Nice. I have noticed that 'each' in the snapshot version unwraps ranges. So: each [3:-1:1] is equivalent to each [3,2,1] Does your proposed grammar produce similar results? Or, is ( [3:-1:1] ) equivalent to (3,2,1) ? >
DM
doug moen
Sun, Nov 13, 2016 7:51 PM

Ronaldo: yes, in my implementation, ranges are generators, and you don't
need special syntax to unwrap them. [1:3] and [1,2,3] are semantically
equivalent. Also, you can write [1:3,10] and you'll get [1,2,3,10]. Here's
the github issue for this extension:

https://github.com/openscad/openscad/issues/1583

On 13 November 2016 at 14:25, Ronaldo Persiano rcmpersiano@gmail.com
wrote:

Nice. I have noticed that 'each' in the snapshot version unwraps ranges.
So:

each [3:-1:1] is equivalent to each [3,2,1]

Does your proposed grammar produce similar results? Or, is ( [3:-1:1] )
equivalent to (3,2,1) ?

Ronaldo: yes, in my implementation, ranges are generators, and you don't need special syntax to unwrap them. [1:3] and [1,2,3] are semantically equivalent. Also, you can write [1:3,10] and you'll get [1,2,3,10]. Here's the github issue for this extension: https://github.com/openscad/openscad/issues/1583 On 13 November 2016 at 14:25, Ronaldo Persiano <rcmpersiano@gmail.com> wrote: > Nice. I have noticed that 'each' in the snapshot version unwraps ranges. > So: > > each [3:-1:1] is equivalent to each [3,2,1] > > Does your proposed grammar produce similar results? Or, is ( [3:-1:1] ) > equivalent to (3,2,1) ? > > > >> > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org > >
MK
Marius Kintel
Sun, Nov 13, 2016 10:55 PM

Hi Doug,

Thanks for that!
One question: If the generator content is created by a function, how would we do that?

This is using the each keyword:

function create_special_case(R,w) = [
[Rcos(w),Rsin(w)],
[Rcos(w)+1,Rsin(w)],
[Rcos(w)+1,Rsin(w)+1],
[Rcos(w),Rsin(w)+1]
];

function circle(R,N) = [
for (w = [0:round(360/N):359])
if (w==180) each create_special_case(R,w)
else [Rcos(w),Rsin(w)]
];

-Marius

Hi Doug, Thanks for that! One question: If the generator content is created by a function, how would we do that? This is using the each keyword: function create_special_case(R,w) = [ [R*cos(w),R*sin(w)], [R*cos(w)+1,R*sin(w)], [R*cos(w)+1,R*sin(w)+1], [R*cos(w),R*sin(w)+1] ]; function circle(R,N) = [ for (w = [0:round(360/N):359]) if (w==180) each create_special_case(R,w) else [R*cos(w),R*sin(w)] ]; -Marius
P
Parkinbot
Mon, Nov 14, 2016 1:16 AM

I'd guess it would be:

function circle(R,N) = [
for (w = [0:round(360/N):359])
if (w==180) (create_special_case(R,w))
else [Rcos(w),Rsin(w)]
];

To me this is not very intuitive (neither readable) using (list) instead
of each list.
I would expect (list) to eval to list like (5) evals to 5 in an
expression.

--
View this message in context: http://forum.openscad.org/Feedback-for-each-operator-tp19074p19086.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

I'd guess it would be: > function circle(R,N) = [ > for (w = [0:round(360/N):359]) > if (w==180) (create_special_case(R,w)) > else [R*cos(w),R*sin(w)] > ]; To me this is not very intuitive (neither readable) using *(list)* instead of *each list*. I would expect *(list)* to eval to *list* like *(5)* evals to *5* in an expression. -- View this message in context: http://forum.openscad.org/Feedback-for-each-operator-tp19074p19086.html Sent from the OpenSCAD mailing list archive at Nabble.com.
DM
doug moen
Mon, Nov 14, 2016 1:41 AM

Parkinbot said:
I'd guess it would be:

function circle(R,N) = [
for (w = [0:round(360/N):359])
if (w==180) (create_special_case(R,w))
else [Rcos(w),Rsin(w)]
];

In Marius's code, create_special_case(R,w) returns a list value, so this
would simply insert the list value without expanding it the way that each
does. Try it and see; you can test it using the current snapshot.

The simple answer to Marius's question is that this is an example of a use
case for each which doesn't go away with my proposed new syntax, which
isn't being used here.

On 13 November 2016 at 20:16, Parkinbot rudolf@parkinbot.com wrote:

I'd guess it would be:

function circle(R,N) = [
for (w = [0:round(360/N):359])
if (w==180) (create_special_case(R,w))
else [Rcos(w),Rsin(w)]
];

To me this is not very intuitive (neither readable) using (list) instead
of each list.
I would expect (list) to eval to list like (5) evals to 5 in an
expression.

--
View this message in context: http://forum.openscad.org/
Feedback-for-each-operator-tp19074p19086.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 said: I'd guess it would be: > function circle(R,N) = [ > for (w = [0:round(360/N):359]) > if (w==180) (create_special_case(R,w)) > else [R*cos(w),R*sin(w)] > ]; In Marius's code, create_special_case(R,w) returns a list value, so this would simply insert the list value without expanding it the way that `each` does. Try it and see; you can test it using the current snapshot. The simple answer to Marius's question is that this is an example of a use case for `each` which doesn't go away with my proposed new syntax, which isn't being used here. On 13 November 2016 at 20:16, Parkinbot <rudolf@parkinbot.com> wrote: > I'd guess it would be: > > > > function circle(R,N) = [ > > for (w = [0:round(360/N):359]) > > if (w==180) (create_special_case(R,w)) > > else [R*cos(w),R*sin(w)] > > ]; > > To me this is not very intuitive (neither readable) using *(list)* instead > of *each list*. > I would expect *(list)* to eval to *list* like *(5)* evals to *5* in an > expression. > > > > -- > View this message in context: http://forum.openscad.org/ > Feedback-for-each-operator-tp19074p19086.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 > > >
R
runsun
Mon, Nov 14, 2016 2:04 AM

doug.moen wrote

In Marius's code, create_special_case(R,w) returns a list value, so this
would simply insert the list value without expanding it the way that
each
does. Try it and see; you can test it using the current snapshot.

In my computer --- echo( circle(10,6) ) gives an array of 9 items:

[[10, 0], [5, 8.66025], [-5, 8.66025], [-10, 0], [-9, 0], [-9, 1], [-10, 1],
[-5, -8.66025], [5, -8.66025]]

seems that it does unwrap.


$  Runsun Pan, PhD $ libs: doctest , faces ( git ), offline doc ( git ), runscad.py ( 2 , git ), synwrite ( 2 );   $ tips: hash ( 2 ), matrix ( 2 , 3 ), sweep ( 2 , 3 ), var ( 2 ), lerp , animation ( gif , prodVid , animlib ), precision ( 2 ), xl-control , type , rounded polygon , chfont , tailRecur ( 2, 3 ), isosphere ( 2 ), area , vol/center , RGB , CurvedImg , tests ( 2 ), text ; $ Apps: rollApp , blockscad , openjscad , on AWS ( pdf )

View this message in context: http://forum.openscad.org/Feedback-for-each-operator-tp19074p19088.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

doug.moen wrote > In Marius's code, create_special_case(R,w) returns a list value, so this > would simply insert the list value without expanding it the way that > `each` > does. Try it and see; you can test it using the current snapshot. In my computer --- echo( circle(10,6) ) gives an array of 9 items: [[10, 0], [5, 8.66025], [-5, 8.66025], [-10, 0], [-9, 0], [-9, 1], [-10, 1], [-5, -8.66025], [5, -8.66025]] seems that it does unwrap. ----- $ Runsun Pan, PhD $ libs: doctest , faces ( git ), offline doc ( git ), runscad.py ( 2 , git ), synwrite ( 2 ); &nbsp; $ tips: hash ( 2 ), matrix ( 2 , 3 ), sweep ( 2 , 3 ), var ( 2 ), lerp , animation ( gif , prodVid , animlib ), precision ( 2 ), xl-control , type , rounded polygon , chfont , tailRecur ( 2, 3 ), isosphere ( 2 ), area , vol/center , RGB , CurvedImg , tests ( 2 ), text ; $ Apps: rollApp , blockscad , openjscad , on AWS ( pdf ) -- View this message in context: http://forum.openscad.org/Feedback-for-each-operator-tp19074p19088.html Sent from the OpenSCAD mailing list archive at Nabble.com.
DM
doug moen
Mon, Nov 14, 2016 2:09 AM

Hi Marius. I think I understand the subtext behind your question.

Back around June 2014, you were encouraging me to add the concept of a
"function that returns a generator" to OpenSCAD2. At that time, I didn't
like the idea. I wasn't sure about the implementation, but I also had a
philosophical objection. If we add this, then there are now two ways for a
function to return a sequence of values: either it returns a list value, or
it returns a generator. And you have to call the function differently,
depending on which protocol it uses.

  • If a function returns a generator, then use [f(x)] to convert its result
    to a list.
  • If a function returns a list, then use 'each f(x)' to convert its result
    to a generator.

So, my objection is that this feature would create complexity and
confusion. It may be better to have a small, fixed set of generator
operations that can't be extended.

Now that I have working code, I can see that this is really easy to
implement. I just tested it now: with my code base, I just have to add one
virtual function to one class, and it works. Here's what your example looks
like using this new feature, and using OpenSCAD2 style function definitions:

create_special_case(R,w) = (
[Rcos(w),Rsin(w)],
[Rcos(w)+1,Rsin(w)],
[Rcos(w)+1,Rsin(w)+1],
[Rcos(w),Rsin(w)+1]
);

circle(R,N) = [
for (w = [0:round(360/N):359])
if (w==180) create_special_case(R,w)
else [Rcos(w),Rsin(w)]
];

Note that the body of create_special_case is now a parenthesized list, not
a bracketed list, so it returns a generator instead of returning a list
value. And note that 'each' is no longer being used. So we have eliminated
the need to use 'each' in your example, and I think that was maybe your
goal.

The other thing I noticed is that I can now define 'each' directly in
OpenSCAD2, by writing
each(a) = for (i=a) i;

That seems pretty interesting, and it's exactly what you requested a few
years ago.

But I am still of two minds about the feature. I'm still worried that it
could create confusion. So I'm not going to commit my change. I'd like to
think about it some more.

Without this feature, then it is still necessary to use 'each' in the use
case that you identified. Or use 'for (i=create_special_case(R,w) i', which
is uglier.

On 13 November 2016 at 17:55, Marius Kintel marius@kintel.net wrote:

Hi Doug,

Thanks for that!
One question: If the generator content is created by a function, how would
we do that?

This is using the each keyword:

function create_special_case(R,w) = [
[Rcos(w),Rsin(w)],
[Rcos(w)+1,Rsin(w)],
[Rcos(w)+1,Rsin(w)+1],
[Rcos(w),Rsin(w)+1]
];

function circle(R,N) = [
for (w = [0:round(360/N):359])
if (w==180) each create_special_case(R,w)
else [Rcos(w),Rsin(w)]
];

-Marius


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

Hi Marius. I think I understand the subtext behind your question. Back around June 2014, you were encouraging me to add the concept of a "function that returns a generator" to OpenSCAD2. At that time, I didn't like the idea. I wasn't sure about the implementation, but I also had a philosophical objection. If we add this, then there are now two ways for a function to return a sequence of values: either it returns a list value, or it returns a generator. And you have to call the function differently, depending on which protocol it uses. * If a function returns a generator, then use [f(x)] to convert its result to a list. * If a function returns a list, then use 'each f(x)' to convert its result to a generator. So, my objection is that this feature would create complexity and confusion. It may be better to have a small, fixed set of generator operations that can't be extended. Now that I have working code, I can see that this is really easy to implement. I just tested it now: with my code base, I just have to add one virtual function to one class, and it works. Here's what your example looks like using this new feature, and using OpenSCAD2 style function definitions: create_special_case(R,w) = ( [R*cos(w),R*sin(w)], [R*cos(w)+1,R*sin(w)], [R*cos(w)+1,R*sin(w)+1], [R*cos(w),R*sin(w)+1] ); circle(R,N) = [ for (w = [0:round(360/N):359]) if (w==180) create_special_case(R,w) else [R*cos(w),R*sin(w)] ]; Note that the body of create_special_case is now a parenthesized list, not a bracketed list, so it returns a generator instead of returning a list value. And note that 'each' is no longer being used. So we have eliminated the need to use 'each' in your example, and I think that was maybe your goal. The other thing I noticed is that I can now define 'each' directly in OpenSCAD2, by writing each(a) = for (i=a) i; That seems pretty interesting, and it's exactly what you requested a few years ago. But I am still of two minds about the feature. I'm still worried that it could create confusion. So I'm not going to commit my change. I'd like to think about it some more. Without this feature, then it is still necessary to use 'each' in the use case that you identified. Or use 'for (i=create_special_case(R,w) i', which is uglier. On 13 November 2016 at 17:55, Marius Kintel <marius@kintel.net> wrote: > Hi Doug, > > Thanks for that! > One question: If the generator content is created by a function, how would > we do that? > > This is using the each keyword: > > function create_special_case(R,w) = [ > [R*cos(w),R*sin(w)], > [R*cos(w)+1,R*sin(w)], > [R*cos(w)+1,R*sin(w)+1], > [R*cos(w),R*sin(w)+1] > ]; > > function circle(R,N) = [ > for (w = [0:round(360/N):359]) > if (w==180) each create_special_case(R,w) > else [R*cos(w),R*sin(w)] > ]; > > -Marius > > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org > > >
DM
doug moen
Mon, Nov 14, 2016 2:46 AM

Runsun:

In my computer --- echo( circle(10,6) ) gives an array of 9 items:
[[10, 0], [5, 8.66025], [-5, 8.66025], [-10, 0], [-9, 0], [-9, 1], [-10,
1],
[-5, -8.66025], [5, -8.66025]]
seems that it does unwrap.

Yes, that is correct. But I was responding to Parkinbot's proposal that
replacing 'each create_special_case(R,w)' with '(create_special_case(R,w))'
in Marius's code should produce the same result, that the 'each' operation
should be implied if the expression is wrapped in parentheses. That's not
how it works now, and it's not a good change. (And it has nothing to do
with the new comma syntax that I proposed at the start of this thread.)

On 13 November 2016 at 21:04, runsun runsun@gmail.com wrote:

doug.moen wrote

In Marius's code, create_special_case(R,w) returns a list value, so this
would simply insert the list value without expanding it the way that
each
does. Try it and see; you can test it using the current snapshot.

In my computer --- echo( circle(10,6) ) gives an array of 9 items:

[[10, 0], [5, 8.66025], [-5, 8.66025], [-10, 0], [-9, 0], [-9, 1], [-10,
1],
[-5, -8.66025], [5, -8.66025]]

seems that it does unwrap.


$  Runsun Pan, PhD $ libs: doctest , faces ( git ), offline doc ( git ),
runscad.py ( 2 , git ), synwrite ( 2 );   $ tips: hash ( 2 ), matrix (
2 , 3 ), sweep ( 2 , 3 ), var ( 2 ), lerp , animation ( gif , prodVid ,
animlib ), precision ( 2 ), xl-control , type , rounded polygon , chfont ,
tailRecur ( 2, 3 ), isosphere ( 2 ), area , vol/center , RGB , CurvedImg ,
tests ( 2 ), text ; $ Apps: rollApp , blockscad , openjscad , on AWS ( pdf )

View this message in context: http://forum.openscad.org/
Feedback-for-each-operator-tp19074p19088.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

Runsun: > > In my computer --- echo( circle(10,6) ) gives an array of 9 items: > [[10, 0], [5, 8.66025], [-5, 8.66025], [-10, 0], [-9, 0], [-9, 1], [-10, > 1], > [-5, -8.66025], [5, -8.66025]] > seems that it does unwrap. Yes, that is correct. But I was responding to Parkinbot's proposal that replacing 'each create_special_case(R,w)' with '(create_special_case(R,w))' in Marius's code should produce the same result, that the 'each' operation should be implied if the expression is wrapped in parentheses. That's not how it works now, and it's not a good change. (And it has nothing to do with the new comma syntax that I proposed at the start of this thread.) On 13 November 2016 at 21:04, runsun <runsun@gmail.com> wrote: > doug.moen wrote > > In Marius's code, create_special_case(R,w) returns a list value, so this > > would simply insert the list value without expanding it the way that > > `each` > > does. Try it and see; you can test it using the current snapshot. > > In my computer --- echo( circle(10,6) ) gives an array of 9 items: > > [[10, 0], [5, 8.66025], [-5, 8.66025], [-10, 0], [-9, 0], [-9, 1], [-10, > 1], > [-5, -8.66025], [5, -8.66025]] > > seems that it does unwrap. > > > > ----- > > $ Runsun Pan, PhD $ libs: doctest , faces ( git ), offline doc ( git ), > runscad.py ( 2 , git ), synwrite ( 2 ); &nbsp; $ tips: hash ( 2 ), matrix ( > 2 , 3 ), sweep ( 2 , 3 ), var ( 2 ), lerp , animation ( gif , prodVid , > animlib ), precision ( 2 ), xl-control , type , rounded polygon , chfont , > tailRecur ( 2, 3 ), isosphere ( 2 ), area , vol/center , RGB , CurvedImg , > tests ( 2 ), text ; $ Apps: rollApp , blockscad , openjscad , on AWS ( pdf ) > -- > View this message in context: http://forum.openscad.org/ > Feedback-for-each-operator-tp19074p19088.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 > > >
R
runsun
Mon, Nov 14, 2016 6:45 PM

doug.moen wrote

in Marius's code should produce the same result, that the 'each' operation
should be implied if the expression is wrapped in parentheses. That's not
how it works now,

Ok. Thought you asked to test it out with the current snapshot.

Yea, turning ([...]) into something other than a list might break many of my
codes, 'cos
in a lots of complicated functions, I use () to wrap the content:

function f()=
(
< returning a list >
);


$  Runsun Pan, PhD $ libs: doctest , faces ( git ), offline doc ( git ), runscad.py ( 2 , git ), synwrite ( 2 );   $ tips: hash ( 2 ), matrix ( 2 , 3 ), sweep ( 2 , 3 ), var ( 2 ), lerp , animation ( gif , prodVid , animlib ), precision ( 2 ), xl-control , type , rounded polygon , chfont , tailRecur ( 2, 3 ), isosphere ( 2 ), area , vol/center , RGB , CurvedImg , tests ( 2 ), text ; $ Apps: rollApp , blockscad , openjscad , on AWS ( pdf )

View this message in context: http://forum.openscad.org/Feedback-for-each-operator-tp19074p19096.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

doug.moen wrote > in Marius's code should produce the same result, that the 'each' operation > should be implied if the expression is wrapped in parentheses. That's not > how it works now, Ok. Thought you asked to test it out with the current snapshot. Yea, turning ([...]) into something other than a list might break many of my codes, 'cos in a lots of complicated functions, I use () to wrap the content: > function f()= > ( > < returning a list > > ); ----- $ Runsun Pan, PhD $ libs: doctest , faces ( git ), offline doc ( git ), runscad.py ( 2 , git ), synwrite ( 2 ); &nbsp; $ tips: hash ( 2 ), matrix ( 2 , 3 ), sweep ( 2 , 3 ), var ( 2 ), lerp , animation ( gif , prodVid , animlib ), precision ( 2 ), xl-control , type , rounded polygon , chfont , tailRecur ( 2, 3 ), isosphere ( 2 ), area , vol/center , RGB , CurvedImg , tests ( 2 ), text ; $ Apps: rollApp , blockscad , openjscad , on AWS ( pdf ) -- View this message in context: http://forum.openscad.org/Feedback-for-each-operator-tp19074p19096.html Sent from the OpenSCAD mailing list archive at Nabble.com.