discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

Any where to find the doc for lc-each, lc-else and lc-for-c ?

R
runsun
Mon, Oct 31, 2016 4:22 PM

Ronaldo wrote

We are discussing two different matters: the benefits of the if-else
filter in list comprehension and your alternative sintax of it.

I'd strongly suggest not to categorize "if-else" construct as a "filter". A
filter means pick something and discard the rest based on a condition. With
the "if-else", nothing can be discarded (just like cond?a:b), so it
shouldn't be considered a filter. Treating it a filter only add more
confusion 'cos it's the role "if" (w/o else) plays.

The first point of my last message was about the benefits. So, your
recoding above mix the two things and did not help.

Sorry I don't get this part.

The second issue (your alternative to if-else filter) has it own
drawbacks. With my trivial example:

[ for(a=A) a+(if (a==0) 1) ]

I meant:

[ for(a=A) if (a==0) a+1 ]

which is a filter

Re-arranging "if(a==0) a+1" to "a+(if (a==0)1)" and suggesting they are the
same doesn't make any sense at all. If "a" is subject to the conditional
pick/drop, why would it be placed BEFORE if ? I couldn't ever imagine an
"if" can simultaneously decide the fate of the code before it (a) and after
it (1). That is a mess-up of scopes and only makes it more confusing.

If you ask "why not 'if' shows up here / there if it is allowed in
cond?if(...):if(...)", then with the same logic, since "if" shows up in

[ for (...) if(...) ]

why not it is allowed in in

[ for(...) cond?if(...):if(...) ]

?
To me that's simply a choice of language design.


$  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 ); $ Apps: rollApp , blockscad , openjscad , on AWS ( pdf )

View this message in context: http://forum.openscad.org/Any-where-to-find-the-doc-for-lc-each-lc-else-and-lc-for-c-tp18823p18844.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

Ronaldo wrote > We are discussing two different matters: the benefits of the if-else > filter in list comprehension and your alternative sintax of it. I'd strongly suggest not to categorize "if-else" construct as a "filter". A filter means pick something and discard the rest based on a condition. With the "if-else", nothing can be discarded (just like cond?a:b), so it shouldn't be considered a filter. Treating it a filter only add more confusion 'cos it's the role "if" (w/o else) plays. > The first point of my last message was about the benefits. So, your > recoding above mix the two things and did not help. Sorry I don't get this part. > The second issue (your alternative to if-else filter) has it own > drawbacks. With my trivial example: >> [ for(a=A) a+(if (a==0) 1) ] > I meant: >> [ for(a=A) if (a==0) a+1 ] > which is a filter Re-arranging "if(a==0) a+1" to "a+(if (a==0)1)" and suggesting they are the same doesn't make any sense at all. If "a" is subject to the conditional pick/drop, why would it be placed BEFORE if ? I couldn't ever imagine an "if" can simultaneously decide the fate of the code before it (a) and after it (1). That is a mess-up of scopes and only makes it more confusing. If you ask "why not 'if' shows up here / there if it is allowed in cond?if(...):if(...)", then with the same logic, since "if" shows up in > [ for (...) if(...) ] why not it is allowed in in > [ for(...) cond?if(...):if(...) ] ? To me that's simply a choice of language design. ----- $ 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 ); $ Apps: rollApp , blockscad , openjscad , on AWS ( pdf ) -- View this message in context: http://forum.openscad.org/Any-where-to-find-the-doc-for-lc-each-lc-else-and-lc-for-c-tp18823p18844.html Sent from the OpenSCAD mailing list archive at Nabble.com.
R
runsun
Mon, Oct 31, 2016 5:13 PM

After getting more familiar with this, I have this thought:

[ for(...) if(A) xxx else yyy ]  // allowed
[ for(...) if(A) (if(B) xxx ) else yyy ]  // allowed
[ for(...) if(A) xxx else (if(B)yyy ) ]  // allowed

They are basically the same as  :

[ for(...) A? xxx : yyy ]  // allowed
[ for(...) A? (if(B)xxx) : yyy ]  // NOT allowed
[ for(...) A? xxx : (if(B) yyy) ]  // NOT allowed

Since ALL "if-else" (w/o the filter (if(B) yyy)) are the same as
"cond?~:~" (both are either-or conditional forks), the only purpose of
introducing "else" seems to allow a filter (if(B) yyy) be valid.

That is, in order for a filter (if(B) yyy) to be legitimate, instead of
making it legitimate in the already-existing construct "cond?~:~", we create
a new one "if-else" that changes the role of "if", making it a source of
confusion.

So a legitimate question is: why not just allow the filter (if(B) yyy) in
a "cond?~:~" ?


$  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 ); $ Apps: rollApp , blockscad , openjscad , on AWS ( pdf )

View this message in context: http://forum.openscad.org/Any-where-to-find-the-doc-for-lc-each-lc-else-and-lc-for-c-tp18823p18845.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

After getting more familiar with this, I have this thought: [ for(...) if(A) xxx else yyy ] // allowed [ for(...) if(A) (*if(B) xxx )* else yyy ] // allowed [ for(...) if(A) xxx else *(if(B)yyy )* ] // allowed They are basically the same as : [ for(...) A? xxx : yyy ] // allowed [ for(...) A? *(if(B)xxx)* : yyy ] // NOT allowed [ for(...) A? xxx : *(if(B) yyy)* ] // NOT allowed Since ALL "if-else" (w/o the filter *(if(B) yyy)*) are the same as "cond?~:~" (both are *either-or conditional forks*), the only purpose of introducing "else" seems to allow a filter *(if(B) yyy)* be valid. That is, in order for a filter *(if(B) yyy)* to be legitimate, instead of making it legitimate in the already-existing construct "cond?~:~", we create a new one "if-else" that changes the role of "if", making it a source of confusion. So a legitimate question is: why not just allow the filter *(if(B) yyy)* in a "cond?~:~" ? ----- $ 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 ); $ Apps: rollApp , blockscad , openjscad , on AWS ( pdf ) -- View this message in context: http://forum.openscad.org/Any-where-to-find-the-doc-for-lc-each-lc-else-and-lc-for-c-tp18823p18845.html Sent from the OpenSCAD mailing list archive at Nabble.com.
R
Ronaldo
Mon, Oct 31, 2016 6:50 PM

runsun wrote

So a legitimate question is: why not just allow the filter

(if(B) yyy)

in a "cond?~:~" ?

You have answered the question in your preceding message:

runsun wrote

Re-arranging "if(a==0) a+1" to "a+(if (a==0)1)" and suggesting they are
the
same doesn't make any sense at all. If "a" is subject to the conditional
pick/drop, why would it be placed BEFORE if ? I couldn't ever imagine an
"if" can simultaneously decide the fate of the code before it (a) and
after
it (1). That is a mess-up of scopes and only makes it more confusing.

That is exactly what is happening when you write something like:

[for (a=A) a % 2 == 0 ? a: if (a!=1) a*10 ]

the filter /if/ is deciding "the fate of the conditional before it". In
fact, the conditional expression above would not act as an expression but as
a filter. And that is confusing!

I agree that is inappropriate to call the construct if-else a filter and
that it is just a conditional that accepts filtering. But it is not
equivalent to ?: because it is not an expression either.

--
View this message in context: http://forum.openscad.org/Any-where-to-find-the-doc-for-lc-each-lc-else-and-lc-for-c-tp18823p18846.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

runsun wrote > So a legitimate question is: why not just allow the filter * > (if(B) yyy) * > in a "cond?~:~" ? You have answered the question in your preceding message: runsun wrote > Re-arranging "if(a==0) a+1" to "a+(if (a==0)1)" and suggesting they are > the > same doesn't make any sense at all. If "a" is subject to the conditional > pick/drop, why would it be placed BEFORE if ? I couldn't ever imagine an > "if" can simultaneously decide the fate of the code before it (a) and > after > it (1). That is a mess-up of scopes and only makes it more confusing. That is exactly what is happening when you write something like: > [for (a=A) a % 2 == 0 ? a: if (a!=1) a*10 ] the filter /if/ *is deciding "the fate of the conditional before it"*. In fact, the conditional expression above would not act as an expression but as a filter. And that is confusing! I agree that is inappropriate to call the construct if-else a filter and that it is just a conditional that accepts filtering. But it is not equivalent to ?: because it is not an expression either. -- View this message in context: http://forum.openscad.org/Any-where-to-find-the-doc-for-lc-each-lc-else-and-lc-for-c-tp18823p18846.html Sent from the OpenSCAD mailing list archive at Nabble.com.
R
runsun
Mon, Oct 31, 2016 8:03 PM

Ronaldo wrote

runsun wrote

So a legitimate question is: why not just allow the filter

(if(B) yyy)

in a "cond?~:~" ?

You have answered the question in your preceding message:

My message was to explain that your trivial example is illogical. How could
anyone invent an illogical usage of an idea in order to argue against that
idea ?

That is exactly what is happening when you write something like:

[for (a=A) a % 2 == 0 ? a: if (a!=1) a*10 ]

the filter

/

if

/

is deciding "the fate of the conditional before it"

.

No! it is to decide the fate of the variable AFTER it ... when the condition
"a%2==0" is met, the previous variable of if's, a, is then decided without
invoking the if-filter. So it's not decided by the "if-filter". The 'if'
filter comes into play only when "a%2==0" is not met. Under that condition,
the 'if' filter is to decide the variable/code AFTER it, just like anywhere
'if' is used in this and other languages.

In fact, the conditional expression above would not act as an expression
but as a filter. And that is confusing!

No, the condition expression (the ?:) is not a filter. The "if (a!=1) a*10"
is, working only when condition "a % 2 == 0" is not met.

Re-write it to the currently accepted form:

[ for (a=A) if(a % 2 == 0 ) a else if (a!=1) a*10 ]

Now you have two if's, the 2nd one is a filter but the 1st is not. That's
where the confusion comes.

I agree that is inappropriate to call the construct if-else a filter and
that it is just a conditional that accepts filtering. But it is not
equivalent to ?: because it is not an expression either.

Yes, "if-else" is a conditional that accepts filtering is the best way to
describe it. Better if added: "if" w/o "else" serves as a filter.

But, other than the filtering, show me an example that can only be expressed
by "if-else" but not "?:".

I don't think you could, because they serve the exact same role (other than
the filtering).


$  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 ); $ Apps: rollApp , blockscad , openjscad , on AWS ( pdf )

View this message in context: http://forum.openscad.org/Any-where-to-find-the-doc-for-lc-each-lc-else-and-lc-for-c-tp18823p18847.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

Ronaldo wrote > > runsun wrote >> So a legitimate question is: why not just allow the filter * >> (if(B) yyy) * >> in a "cond?~:~" ? > You have answered the question in your preceding message: My message was to explain that your trivial example is illogical. How could anyone invent an illogical usage of an idea in order to argue against that idea ? > That is exactly what is happening when you write something like: >> [for (a=A) a % 2 == 0 ? a: if (a!=1) a*10 ] > the filter / > if / > * > is deciding "the fate of the conditional before it" * > . No! it is to decide the fate of the variable AFTER it ... when the condition "a%2==0" is met, the previous variable of if's, a, is then decided without invoking the if-filter. So it's not decided by the "if-filter". The 'if' filter comes into play only when "a%2==0" is not met. Under that condition, the 'if' filter is to decide the variable/code AFTER it, just like anywhere 'if' is used in this and other languages. > In fact, the conditional expression above would not act as an expression > but as a filter. And that is confusing! No, the condition expression (the ?:) is not a filter. The "if (a!=1) a*10" is, working only when condition "a % 2 == 0" is not met. Re-write it to the currently accepted form: [ for (a=A) if(a % 2 == 0 ) a else if (a!=1) a*10 ] Now you have two if's, the 2nd one is a filter but the 1st is not. That's where the confusion comes. > I agree that is inappropriate to call the construct if-else a filter and > that it is just a conditional that accepts filtering. But it is not > equivalent to ?: because it is not an expression either. Yes, *"if-else" is a conditional that accepts filtering* is the best way to describe it. Better if added: *"if" w/o "else" serves as a filter*. But, other than the filtering, show me an example that can only be expressed by "if-else" but not "?:". I don't think you could, because they serve the exact same role (other than the filtering). ----- $ 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 ); $ Apps: rollApp , blockscad , openjscad , on AWS ( pdf ) -- View this message in context: http://forum.openscad.org/Any-where-to-find-the-doc-for-lc-each-lc-else-and-lc-for-c-tp18823p18847.html Sent from the OpenSCAD mailing list archive at Nabble.com.
R
Ronaldo
Mon, Oct 31, 2016 10:04 PM

This will be my third message trying to clarify my point about your proposed
syntax. And, I promise, it will be the last one.

The operator ?: is a ternary operator. As such, it requires 3 operand, no
more no less. In the expression you prefer:

a % 2 == 0 ? a: if (a!=1) a*10

when a=3 the operator ?: receives the following operands: true, 3 and
<nothing>. That is, it receives just 2 operands as the filter if returns
nothing at all. And you expect the operator ?: returns nothing at all in
this case. That is a twisted (and confusing) behavior of it.

The if-else construct on the other hand has the very special property
that it returns nothing if the followed branch (either true or false)
receives nothing. And that is the reason why it cannot be used (like filter*
if*) as a operand of any other operator except itself and the filter* if*.

If we allow the operator ?: receives less that 3 operands why not allow
the sum operator* +* receives less that two?

--
View this message in context: http://forum.openscad.org/Any-where-to-find-the-doc-for-lc-each-lc-else-and-lc-for-c-tp18823p18848.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

This will be my third message trying to clarify my point about your proposed syntax. And, I promise, it will be the last one. The operator *?:* is a ternary operator. As such, it requires 3 operand, no more no less. In the expression you prefer: > a % 2 == 0 ? a: if (a!=1) a*10 when a=3 the operator *?:* receives the following operands: true, 3 and <nothing>. That is, it receives just 2 operands as the filter *if* returns nothing at all. And you expect the operator *?:* returns nothing at all in this case. That is a twisted (and confusing) behavior of it. The *if-else* construct on the other hand has the *very special property* that it returns nothing if the followed branch (either true or false) receives nothing. And that is the reason why it cannot be used (like filter* if*) as a operand of any other operator except itself and the filter* if*. If we allow the operator *?:* receives less that 3 operands why not allow the sum operator* +* receives less that two? -- View this message in context: http://forum.openscad.org/Any-where-to-find-the-doc-for-lc-each-lc-else-and-lc-for-c-tp18823p18848.html Sent from the OpenSCAD mailing list archive at Nabble.com.
P
Parkinbot
Tue, Nov 1, 2016 12:47 PM

Ronaldo, as you write it, ?: is a ternary operator. So it has to return a
result, as it is the outer expression. You seem to argue that this result
may also be nothing, which afaik currently is only an implicit feature (or
call it a hack) of "if".

Ronaldo wrote

a % 2 == 0 ? a: if (a!=1) a*10

I guess, you can always express a filter like this in the right order:
if (a!=1) (a % 2 == 0)? a : a*10

--
View this message in context: http://forum.openscad.org/Any-where-to-find-the-doc-for-lc-each-lc-else-and-lc-for-c-tp18823p18850.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

Ronaldo, as you write it, ?: is a ternary operator. So it has to return a result, as it is the outer expression. You seem to argue that this result may also be nothing, which afaik currently is only an implicit feature (or call it a hack) of "if". Ronaldo wrote > a % 2 == 0 ? a: if (a!=1) a*10 I guess, you can always express a filter like this in the right order: if (a!=1) (a % 2 == 0)? a : a*10 -- View this message in context: http://forum.openscad.org/Any-where-to-find-the-doc-for-lc-each-lc-else-and-lc-for-c-tp18823p18850.html Sent from the OpenSCAD mailing list archive at Nabble.com.
R
Ronaldo
Tue, Nov 1, 2016 3:58 PM

Parkinbot wrote

Ronaldo, as you write it, ?: is a ternary operator. So it has to return a
result, as it is the outer expression. You seem to argue that this result
may also be nothing, which afaik currently is only an implicit feature (or
call it a hack) of "if".

I couldn't say it better.

Parkinbot wrote

I guess, you can always express a filter like this in the right order:
if (a!=1) (a % 2 == 0)? a : a*10

Surely, we always can but after hard work and at the expenses of clarity in
less obvious cases. The snapshot version syntax solves this and we certainly
can replace all ?: by if-else without fear.

--
View this message in context: http://forum.openscad.org/Any-where-to-find-the-doc-for-lc-each-lc-else-and-lc-for-c-tp18823p18851.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

Parkinbot wrote > Ronaldo, as you write it, ?: is a ternary operator. So it has to return a > result, as it is the outer expression. You seem to argue that this result > may also be nothing, which afaik currently is only an implicit feature (or > call it a hack) of "if". I couldn't say it better. Parkinbot wrote > I guess, you can always express a filter like this in the right order: > if (a!=1) (a % 2 == 0)? a : a*10 Surely, we always can but after hard work and at the expenses of clarity in less obvious cases. The snapshot version syntax solves this and we certainly can replace all ?: by if-else without fear. -- View this message in context: http://forum.openscad.org/Any-where-to-find-the-doc-for-lc-each-lc-else-and-lc-for-c-tp18823p18851.html Sent from the OpenSCAD mailing list archive at Nabble.com.
R
runsun
Tue, Nov 1, 2016 7:01 PM

Parkinbot wrote

Ronaldo wrote

a % 2 == 0 ? a: if (a!=1) a*10

I guess, you can always express a filter like this in the right order:
if (a!=1) (a % 2 == 0)? a : a*10

This is exactly the same as "if-else" case. The example in the WIP:

echo( [ for (a = [ 1 : 8 ]) if (a % 2 == 0) a else

if (a!=1)

a*10 ] );

could be written /in the right order/, as you wish, as :

echo( [ for (a = [ 1 : 8 ])

if (a!=1)

if (a % 2 == 0) a else  a*10 ] );

and they return the same thing, which once again implies that "?:" behaves
exactly like "if-else", which is what I've been arguing all along.

Parkinbot wrote

Ronaldo, as you write it, ?: is a ternary operator. So it has to return a
result, as it is the outer expression. You seem to argue that this result
may also be nothing, which afaik currently is only an implicit feature (or
call it a hack) of "if".

I believe that this belief of what "if-else" is is the source of conflict
that causes conversations between Ronaldo and I went parallel.

Afaik, "if-else" by itself has to return something for every single item it
handles, therefor is a "catch-all" construct and shouldn't be considered a
filter. Ronaldo, on the other hand, thinks "if-else" is a filter, that it
"has the very special property that it returns nothing if the followed
branch (either true or false) receives nothing," therefor it can be used
with "if(w/o else)" filter, but "?:" cannot.

Ronaldo forgot one thing: the "special property" he mentioned is a result
of our design, NOT the reason for our design
. One cannot design a behavior,
then turn around to argue that having that behavior is the reason we need to
design that behavior, or even go further to argue that we cannot add that
same behavior to others because they don't have it.

"if-else" by itself is never a filter. Even in OpenSCAD when we allow
"if(w/o else)" to be in "if-else" branch, it's the "if(w/o else)" that
executes the filtering, not the "if-else". The ability of  "if-else" to
accept "if(w/o else)" and turn its branch into a filter is NOT a nature of
"if-else", but an add-on feature we intentionally put it in.

In terms of language feature, having a filter in a conditional expression is
a novel and welcomed idea. But mixing "if-else" and "if(w/o else)" means
that users have to deal with that an "if" in OpenSCAD list comprehension is
sometimes a filter, sometimes not. That's where the confusion is.


$  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 ); $ Apps: rollApp , blockscad , openjscad , on AWS ( pdf )

View this message in context: http://forum.openscad.org/Any-where-to-find-the-doc-for-lc-each-lc-else-and-lc-for-c-tp18823p18856.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

Parkinbot wrote > > Ronaldo wrote >> a % 2 == 0 ? a: if (a!=1) a*10 > I guess, you can always express a filter like this in the right order: > if (a!=1) (a % 2 == 0)? a : a*10 This is exactly the same as "if-else" case. The example in the WIP: > echo( [ for (a = [ 1 : 8 ]) if (a % 2 == 0) a else * > if (a!=1) * > a*10 ] ); could be written /in the right order/, as you wish, as : > > echo( [ for (a = [ 1 : 8 ]) * > if (a!=1) * > if (a % 2 == 0) a else a*10 ] ); and they return the same thing, which once again implies that "?:" behaves exactly like "if-else", which is what I've been arguing all along. Parkinbot wrote > Ronaldo, as you write it, ?: is a ternary operator. So it has to return a > result, as it is the outer expression. You seem to argue that this result > may also be nothing, which afaik currently is only an implicit feature (or > call it a hack) of "if". I believe that this belief of what "if-else" is is the source of conflict that causes conversations between Ronaldo and I went parallel. Afaik, "if-else" by itself has to return something for every single item it handles, therefor is a "catch-all" construct and shouldn't be considered a filter. Ronaldo, on the other hand, thinks "if-else" is a filter, that it "has the very special property that it returns nothing if the followed branch (either true or false) receives nothing," therefor it can be used with "if(w/o else)" filter, but "?:" cannot. Ronaldo forgot one thing: *the "special property" he mentioned is a result of our design, NOT the reason for our design*. One cannot design a behavior, then turn around to argue that having that behavior is the reason we need to design that behavior, or even go further to argue that we cannot add that same behavior to others because they don't have it. "if-else" by itself is never a filter. Even in OpenSCAD when we allow "if(w/o else)" to be in "if-else" branch, it's the "if(w/o else)" that executes the filtering, not the "if-else". The ability of "if-else" to accept "if(w/o else)" and turn its branch into a filter is NOT a nature of "if-else", but an add-on feature we intentionally put it in. In terms of language feature, having a filter in a conditional expression is a novel and welcomed idea. But mixing "if-else" and "if(w/o else)" means that users have to deal with that an "if" in OpenSCAD list comprehension is sometimes a filter, sometimes not. That's where the confusion is. ----- $ 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 ); $ Apps: rollApp , blockscad , openjscad , on AWS ( pdf ) -- View this message in context: http://forum.openscad.org/Any-where-to-find-the-doc-for-lc-each-lc-else-and-lc-for-c-tp18823p18856.html Sent from the OpenSCAD mailing list archive at Nabble.com.
P
Parkinbot
Tue, Nov 1, 2016 7:17 PM

Surely, we always can but after hard work and at the expenses of clarity
in less obvious cases. The snapshot version syntax solves this and we
certainly can replace all ?: by if-else without fear.

I must admit that the idea of having if/else, if within an expression
having this semantics is a bit awkward. Personally I wouldn't introduce it,
but implement the filter by introducing a new symbol like null that
explicates what happens:

a==v? a : null

in lc-context null could resolve to nothing and in expression context to 0
(or maybe undef).
In the second step I'd define a binary operator op1?op2 that defaults to
the ternary operator op1?op2:null. This new binary operator can then be
used anywhere.

--
View this message in context: http://forum.openscad.org/Any-where-to-find-the-doc-for-lc-each-lc-else-and-lc-for-c-tp18823p18857.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

> Surely, we always can but after hard work and at the expenses of clarity > in less obvious cases. The snapshot version syntax solves this and we > certainly can replace all ?: by if-else without fear. I must admit that the idea of having *if/else*, *if* within an expression having this semantics is a bit awkward. Personally I wouldn't introduce it, but implement the filter by introducing a new symbol like *null* that explicates what happens: > a==v? a : null in lc-context *null* could resolve to nothing and in expression context to 0 (or maybe *undef*). In the second step I'd define a binary operator *op1?op2* that defaults to the ternary operator *op1?op2:null*. This new binary operator can then be used anywhere. -- View this message in context: http://forum.openscad.org/Any-where-to-find-the-doc-for-lc-each-lc-else-and-lc-for-c-tp18823p18857.html Sent from the OpenSCAD mailing list archive at Nabble.com.
NH
nop head
Tue, Nov 1, 2016 7:29 PM

As I said earlier: in conjunction with each if / else can add different
numbers of elements to a list, which ? : can't as it is a single expression.

E.g.
if(a %2) a else each a, a * a

On 1 November 2016 at 19:17, Parkinbot rudolf@parkinbot.com wrote:

Surely, we always can but after hard work and at the expenses of clarity
in less obvious cases. The snapshot version syntax solves this and we
certainly can replace all ?: by if-else without fear.

I must admit that the idea of having if/else, if within an expression
having this semantics is a bit awkward. Personally I wouldn't introduce it,
but implement the filter by introducing a new symbol like null that
explicates what happens:

a==v? a : null

in lc-context null could resolve to nothing and in expression context to
0
(or maybe undef).
In the second step I'd define a binary operator op1?op2 that defaults to
the ternary operator op1?op2:null. This new binary operator can then be
used anywhere.

--
View this message in context: http://forum.openscad.org/Any-
where-to-find-the-doc-for-lc-each-lc-else-and-lc-for-c-tp18823p18857.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

As I said earlier: in conjunction with each if / else can add different numbers of elements to a list, which ? : can't as it is a single expression. E.g. if(a %2) a else each a, a * a On 1 November 2016 at 19:17, Parkinbot <rudolf@parkinbot.com> wrote: > > > Surely, we always can but after hard work and at the expenses of clarity > > in less obvious cases. The snapshot version syntax solves this and we > > certainly can replace all ?: by if-else without fear. > > I must admit that the idea of having *if/else*, *if* within an expression > having this semantics is a bit awkward. Personally I wouldn't introduce it, > but implement the filter by introducing a new symbol like *null* that > explicates what happens: > > > a==v? a : null > > in lc-context *null* could resolve to nothing and in expression context to > 0 > (or maybe *undef*). > In the second step I'd define a binary operator *op1?op2* that defaults to > the ternary operator *op1?op2:null*. This new binary operator can then be > used anywhere. > > > > -- > View this message in context: http://forum.openscad.org/Any- > where-to-find-the-doc-for-lc-each-lc-else-and-lc-for-c-tp18823p18857.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 >