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
function circle(R,N) = [
for (w = [0:round(360/N):359])
if (w==180) (create_special_case(R,w))
else [Rcos(w),Rsin(w)]
];
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:
function circle(R,N) = [
for (w = [0:round(360/N):359])
if (w==180) (create_special_case(R,w))
else [Rcos(w),Rsin(w)]
];
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
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 ); $ 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
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:
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 ); $ 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
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 ); $ 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.