Is there a reason why list comprehensions can't have a comma separated list
of elements after the for(..) instead of the just a single element? That
would eliminate the need for flatten in some cases.
This proposed extension is also part of the OpenSCAD2 proposal. So I agree.
Generalised list comprehensions:
https://github.com/doug-moen/openscad2/blob/master/rfc/Generators.md
On Thursday, 24 December 2015, nop head nop.head@gmail.com wrote:
Is there a reason why list comprehensions can't have a comma separated
list of elements after the for(..) instead of the just a single element?
That would eliminate the need for flatten in some cases.
If I unterstand your question well, there is a good work-around for this. Use
a second loop variable within your loop and enumerate your vector with it:
echo([for(i=[0:10], j=[0:1]) let (a= [i, i*i]) a[j]]);
-Rudolf
--
View this message in context: http://forum.openscad.org/List-comprehensions-tp15321p15323.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
Yes that is a good trick but a comma would be much simpler.
On 24 December 2015 at 15:03, Parkinbot rudolf@parkinbot.com wrote:
If I unterstand your question well, there is a good work-around for this.
Use
a second loop variable within your loop and enumerate your vector with it:
echo([for(i=[0:10], j=[0:1]) let (a= [i, i*i]) a[j]]);
-Rudolf
--
View this message in context:
http://forum.openscad.org/List-comprehensions-tp15321p15323.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
On 12/24/2015 04:16 PM, nop head wrote:
Yes that is a good trick but a comma would be much simpler.
I think that's relatively simple to add. I've created a patch
that allows multiple comma separated expressions and seems
to pass all the existing tests.
function f(x) = xxx;
echo([for (a = [1:2:10]) a, a*a, f(a)]);
// ECHO: [1, 1, 1, 3, 9, 27, 5, 25, 125, 7, 49, 343, 9, 81, 729]
It should be fine regarding compatibility as that syntax is
currently just an error.
I guess it still needs some more examples for testing though.
ciao,
Torsten.
Also, to step a bit into the direction of
https://github.com/doug-moen/openscad2/blob/master/rfc/Generators.md
echo([for (a = [1:5]) if (a % 2 == 0) "even", a, [aa] else "odd", a, [aa*a]]);
// ECHO: ["odd", 1, [1], "even", 2, [4], "odd", 3, [27], "even", 4, [16], "odd", 5, [125]]
ciao,
Torsten.
On 12/24/2015 03:48 PM, doug moen wrote:
This proposed extension is also part of the OpenSCAD2 proposal.
So I agree.
Generalised list comprehensions:
https://github.com/doug-moen/openscad2/blob/master/rfc/Generators.md
On Thursday, 24 December 2015, nop head nop.head@gmail.com wrote:
Is there a reason why list comprehensions can't have a comma separated
list of elements after the for(..) instead of the just a single
element? That would eliminate the need for flatten in some cases.
Actually it's not the same. I just realized that after discussion with
Marius. The initial question was about having the list comprehension
expression as vector (without the []), like:
echo([ for (a = [2 : 4]) a, a*a ]);
which would result in:
ECHO: [ 2, 4, 3, 9, 4, 16 ]
The generalized solution (as is my understanding now) does not allow that,
it would result in "a*a" producing a warning that "a" is not defined at
this point as this part does not belong to the for() expression.
I think the solution following the suggested feature set would look like:
echo([ for (a = [2 : 4]) each [ a, a*a ] ]);
// ECHO: [2, 4, 3, 9, 4, 16]
which is a bit more verbose for this specific case, but having multiple
generators in one expression also allows for things like:
echo([ -1, for (a = [0:1:3]) a, for (b = [3:-1:0]) b, -1 ]);
// ECHO: [-1, 0, 1, 2, 3, 3, 2, 1, 0, -1]
I don't think we can have both, because the parser would have a hard
time to decide what the "," means.
The if/else is also implemented:
echo([ for (a = [0:2]) if (a == 1) "A" else "B" ]);
// ECHO: ["B", "A", "B"]
// nested list comprehension expressions with if/else
echo([ for (a = [0:3]) if ((a % 2) == 0) for (b = ["a", "b"]) b else each ["x", "y"] ]);
// ECHO: ["a", "b", "x", "y", "a", "b", "x", "y"]
AFAICS this should implement all the features of the "Using Generators in
List Literals" section with the exception of the "*" operator. What's the
rationale to have that shortcut?
ciao,
Torsten.
Any thought of accessing the item(s) generated (still in the buffer), in the
middle of looping, before the loop is completed ?
Something like:
[ for(i=[1:4])
if(i==1) 1
else ((@-1)+i)*i
]
=> [ 1
, (1+2)*2 // = 6
, (6+3)*3 // = 27
, (27+4)*4 // = 124
]
=> [ 1,6,27,124 ]
$ Runsun Pan, PhD
$ libs:
doctest ,
faces ( git ),
offline doc ( git ),
runscad.py( 1 , 2 , git ),
synwrite( 1 , 2 );
$ tips:
hash( 1 , 2 ),
sweep ,
var( 1 , 2 ),
lerp ,
animGif ,
precision( 1 , 2 ),
xl-control
--
View this message in context: http://forum.openscad.org/List-comprehensions-tp15321p15491.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
The reason for the * operator in OpenSCAD2 is that I unified the
"statement" and "expression" syntax to the maximum extent possible. The
prefix * operator already exists in OpenSCAD at the statement level, and I
made it available in expression syntax for consistency.
That's not a compelling reason for you to add it right now, it only really
makes sense later, assuming we decide to use the backward compatibility
scheme that I outline in the design doc. If we were to use a less rigid
backward compatibility system, one which allows some of the core syntax to
change, then we might decide to rename the prefix * operator to something
more mnemonic, like 'ignore'.
function f(x) = x;
module g(x) cube(x);
[ f(1), for (a = [2:4]) f(a), for (b = [4:-1:2]) f(b), f(1), ]
{ g(1); for (a = [2:4]) g(a); for (b = [4:-1:2]) g(b); g(1); }
Notice how the 2 lines above are structurally the same, and in OpenSCAD2
the 'for' operator has the same semantics in both cases. The first is a
list expression, the second is a "statement" (in OpenSCAD) or an "object
expression" (in OpenSCAD2). Note that the trailing , in the list expression
is optional in OpenSCAD, and I hope to make the trailing ; optional in the
object expression in OpenSCAD2.
Yes, the 'each' operator is verbose. I tried using an operator character,
&, in a previous draft, but it didn't get a very positive response from
Marius, because it doesn't look like anything familiar.
On 4 January 2016 at 20:10, Torsten Paul Torsten.Paul@gmx.de wrote:
On 12/24/2015 03:48 PM, doug moen wrote:
This proposed extension is also part of the OpenSCAD2 proposal.
So I agree.
Generalised list comprehensions:
https://github.com/doug-moen/openscad2/blob/master/rfc/Generators.md
On Thursday, 24 December 2015, nop head nop.head@gmail.com wrote:
Is there a reason why list comprehensions can't have a comma separated
list of elements after the for(..) instead of the just a single
element? That would eliminate the need for flatten in some cases.
Actually it's not the same. I just realized that after discussion with
Marius. The initial question was about having the list comprehension
expression as vector (without the []), like:
echo([ for (a = [2 : 4]) a, a*a ]);
which would result in:
ECHO: [ 2, 4, 3, 9, 4, 16 ]
The generalized solution (as is my understanding now) does not allow that,
it would result in "a*a" producing a warning that "a" is not defined at
this point as this part does not belong to the for() expression.
I think the solution following the suggested feature set would look like:
echo([ for (a = [2 : 4]) each [ a, a*a ] ]);
// ECHO: [2, 4, 3, 9, 4, 16]
which is a bit more verbose for this specific case, but having multiple
generators in one expression also allows for things like:
echo([ -1, for (a = [0:1:3]) a, for (b = [3:-1:0]) b, -1 ]);
// ECHO: [-1, 0, 1, 2, 3, 3, 2, 1, 0, -1]
I don't think we can have both, because the parser would have a hard
time to decide what the "," means.
The if/else is also implemented:
echo([ for (a = [0:2]) if (a == 1) "A" else "B" ]);
// ECHO: ["B", "A", "B"]
// nested list comprehension expressions with if/else
echo([ for (a = [0:3]) if ((a % 2) == 0) for (b = ["a", "b"]) b else each
["x", "y"] ]);
// ECHO: ["a", "b", "x", "y", "a", "b", "x", "y"]
AFAICS this should implement all the features of the "Using Generators in
List Literals" section with the exception of the "*" operator. What's the
rationale to have that shortcut?
ciao,
Torsten.
OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
On 01/05/2016 02:35 AM, runsun wrote:
Any thought of accessing the item(s) generated (still in the buffer), in the
middle of looping, before the loop is completed ?
Hmm, the first two thoughts were
Still, it might be possible. Do you have a specific use-case where that
would help. It's more compact than the matching recursive function,
but also looks a bit scary :).
Something like:
[ for(i=[1:4])
if(i==1) 1
else ((@-1)+i)*i
]
=> [ 1
, (1+2)*2 // = 6
, (6+3)*3 // = 27
, (27+4)*4 // = 124
]
=> [ 1,6,27,124 ]
// the tail-recursive version is a bit more verbose
function f(i, x, r = []) = i <= x ? f(i + 1, x, concat(r, i == 1 ? 1 : (r[len(r)-1] + i) * i)) : r;
// could be written using "each" too :)
function f(i, x, r = []) = i <= x ? f(i + 1, x, [ each r, i == 1 ? 1 : (r[len(r)-1] + i) * i ]) : r;
echo(f(1, 4));
// ECHO: [1, 6, 27, 124]
ciao,
Torsten.