DM
doug moen
Thu, Jan 7, 2016 5:03 PM
Sorry about the negative tone of my response. I did get frustrated by your
original post, though. It's written in a pseudo-code, somewhere between
Lisp and OpenSCAD. Since you weren't proposing that as the final syntax, I
tried to translate your examples into OpenSCAD syntax, and what I finally
ended up with were list comprehensions + Haskell-inspired list functions.
Which is not what you were proposing.
The entire Genera OS was written in lisp on a lisp machine. Yes an entire
OS in Lisp. It remains the best development system I worked on.
I never had an opportunity to use a Lisp Machine. I'm a student of computer
history, though, and it's legendary. I'd like to spend time playing with
this software so that I can understand why it's the best development system
ever. Maybe somebody will resurrect this in an emulator one day.
- add structured assignment:
[for ([a b]=[[1 2] [3 4] [5 6]]) [b a] ]
giving [[2 1] [4 3] [6 5]]
I completely agree with adding structured assignment. I've been writing
OpenSCAD2 code as part of a project, and I've added structured assignment,
because it is so convenient for destructuring 2-vectors and 3-vectors in
the style of geometric programming I'm playing with.
Your example is pseudo code, so I'll translate to OpenSCAD syntax:
[ for ([a,b] = [[1,2], [3,4], [5,6]]) [b,a] ]
In my version of structured assignment,
[a,b] = x
produces a run-time error if x is not a list of length 2. The syntax works
in definitions, function formal parameter lists, and for statements.
- add from
[ for (i=[1:10], j from 2) i*j ]
where j starts at 2 and counts up. the i variable sets the termination of
the loop
from could not appear on its own without a termination clause.
You intend this to mean 2 loops running in parallel, instead of being
nested. In OpenSCAD, the syntax
for (i=[1:10], j=[2:11]) ...
looks like it would be good syntax for two parallel loops, but it's not. It
actually means nested loops, same as
for (i=[1:10]) for (j=[2:11]) ...
So I think there is a backward compatibility problem with expressing
parallel loops in the way you suggest. The problem is in violating the
expectations of OpenSCAD programmers, who expect 'for (i=.., j=..)' to mean
nested loops.
Your previous post had several examples of parallel loops. Here's one:
- Create pairs
[for x = [1:5]
for y = ["A","B","C","D","E"]
do [x y] ]
giving [[1 A] [2 B] [3 C] [4 D] [5 E]]
This is more pseudo-code. The problem is that if we convert this into
OpenSCAD syntax, we get nested loops:
[for (x = [1:5])
for (y = ["A","B","C","D","E"])
[x,y]]
and the result is a list of 25 pairs.
In functional style programming, you would create the pairs by calling
transpose, which in OpenSCAD is matrix transpose from linear algebra.
transpose([[1:5], ["A","B","C","D","E"]])
=> [[1,"A"], [2,"B"], [3,"C"], [4,"D"], [5,"E"]]
(This works in OpenSCAD2 because [1:5] is operationally equivalent to
[1,2,3,4,5] in all contexts.)
We could invent a new syntax for parallel loops in OpenSCAD. Maybe this
would work:
for (x = xlist | y = ylist) ...
Or we could just use transpose. Because this also works:
for ([x,y] = transpose(xlist, ylist)) ...
- loop terminatoin with while, or until, or just one and use not operator
for the other - for readability
[ for (x=1,2,3,4,5,6], while prime(x)) [ x, x*x] ]
returning list of [x,x^2] until first non-prime encountered.
I'm not sure about the , before the while, for reasons previously
discussed. And the argument of 'while' should be parenthesized, for
consistency with the rest of OpenSCAD syntax. So maybe this:
[ for (x=[1,2,3,4,5,6] | while(prime(x))) [x, x*x] ]
In functional programming, you'd implement this using take_while, which
returns the longest prefix of a sequence that matches a predicate. In
OpenSCAD2, the code would look like this:
[ for (x=[1,2,3,4,5,6] >> take_while(prime)) [x, x*x] ]
It's not much worse, and no additional syntax is added to the language,
since take_while is a library function. There is also a drop_while function
which discards initial elements that match the predicate, and I'm not sure
if this is expressible using the LOOP macro.
- define more internal loop variables. inner scope only
[for (x=1,2,3,4,5,6], start=12) x*start ]
But we already have syntax for this.
[for (x=[1,2,3,4,5,6]) let (start=12) x*start ]
- I can't imagine how to do if-then constructs and collect inside the
existing syntax.
I had the same problem, reading your previous post. You wrote:
- using conditionals within the loop (as an operator, not a regular if
statement)
[for x below 10
if odd(x)
collect x into odds
else
collect x into evens
finally [odds, evens] ]
gives [[1 3 5 7 9] [0 2 4 6 8]]
In functional programming, this would be done using 'partition'.
partition(odd)([0:9])
Here is the non-recursive definition:
partition(f)(s) =
let (p1 = [for (x=s) if (f(x)) x],
p2 = [for (x=s) if (!f(x)) x])
[p1,p2];
In summary, my counter-proposal is to add structured assignment to
OpenSCAD2, and then provide library functions to make writing loops and
list processing more convenient.
I'll admit I have a bias for the functional style of programming, since I'm
used to that, and I don't have any experience using the Lisp LOOP macros.
And I admit there's a learning curve; you need a cookbook to learn some of
the common programming patterns. I'll be interested to know what other
people think.
One thing to note: In my OpenSCAD2 list library, most functions have double
argument lists, with the list in the second or outmost argument list. This
allows you to chain together list operations the same way you can chain
together geometric transforms in OpenSCAD.
Sorry about the negative tone of my response. I did get frustrated by your
original post, though. It's written in a pseudo-code, somewhere between
Lisp and OpenSCAD. Since you weren't proposing that as the final syntax, I
tried to translate your examples into OpenSCAD syntax, and what I finally
ended up with were list comprehensions + Haskell-inspired list functions.
Which is not what you were proposing.
The entire Genera OS was written in lisp on a lisp machine. Yes an entire
> OS in Lisp. It remains the best development system I worked on.
>
I never had an opportunity to use a Lisp Machine. I'm a student of computer
history, though, and it's legendary. I'd like to spend time playing with
this software so that I can understand why it's the best development system
ever. Maybe somebody will resurrect this in an emulator one day.
> - add structured assignment:
> [for ([a b]=[[1 2] [3 4] [5 6]]) [b a] ]
> giving [[2 1] [4 3] [6 5]]
>
I completely agree with adding structured assignment. I've been writing
OpenSCAD2 code as part of a project, and I've added structured assignment,
because it is so convenient for destructuring 2-vectors and 3-vectors in
the style of geometric programming I'm playing with.
Your example is pseudo code, so I'll translate to OpenSCAD syntax:
[ for ([a,b] = [[1,2], [3,4], [5,6]]) [b,a] ]
In my version of structured assignment,
[a,b] = x
produces a run-time error if x is not a list of length 2. The syntax works
in definitions, function formal parameter lists, and for statements.
> - add from
> [ for (i=[1:10], j from 2) i*j ]
> where j starts at 2 and counts up. the i variable sets the termination of
> the loop
> from could not appear on its own without a termination clause.
>
You intend this to mean 2 loops running in parallel, instead of being
nested. In OpenSCAD, the syntax
for (i=[1:10], j=[2:11]) ...
looks like it would be good syntax for two parallel loops, but it's not. It
actually means nested loops, same as
for (i=[1:10]) for (j=[2:11]) ...
So I think there is a backward compatibility problem with expressing
parallel loops in the way you suggest. The problem is in violating the
expectations of OpenSCAD programmers, who expect 'for (i=.., j=..)' to mean
nested loops.
Your previous post had several examples of parallel loops. Here's one:
- Create pairs
[for x = [1:5]
for y = ["A","B","C","D","E"]
do [x y] ]
giving [[1 A] [2 B] [3 C] [4 D] [5 E]]
This is more pseudo-code. The problem is that if we convert this into
OpenSCAD syntax, we get nested loops:
[for (x = [1:5])
for (y = ["A","B","C","D","E"])
[x,y]]
and the result is a list of 25 pairs.
In functional style programming, you would create the pairs by calling
transpose, which in OpenSCAD is matrix transpose from linear algebra.
transpose([[1:5], ["A","B","C","D","E"]])
=> [[1,"A"], [2,"B"], [3,"C"], [4,"D"], [5,"E"]]
(This works in OpenSCAD2 because [1:5] is operationally equivalent to
[1,2,3,4,5] in all contexts.)
We could invent a new syntax for parallel loops in OpenSCAD. Maybe this
would work:
for (x = xlist | y = ylist) ...
Or we could just use transpose. Because this also works:
for ([x,y] = transpose(xlist, ylist)) ...
- loop terminatoin with while, or until, or just one and use not operator
> for the other - for readability
> [ for (x=1,2,3,4,5,6], while prime(x)) [ x, x*x] ]
> returning list of [x,x^2] until first non-prime encountered.
>
I'm not sure about the , before the while, for reasons previously
discussed. And the argument of 'while' should be parenthesized, for
consistency with the rest of OpenSCAD syntax. So maybe this:
[ for (x=[1,2,3,4,5,6] | while(prime(x))) [x, x*x] ]
In functional programming, you'd implement this using take_while, which
returns the longest prefix of a sequence that matches a predicate. In
OpenSCAD2, the code would look like this:
[ for (x=[1,2,3,4,5,6] >> take_while(prime)) [x, x*x] ]
It's not much worse, and no additional syntax is added to the language,
since take_while is a library function. There is also a drop_while function
which discards initial elements that match the predicate, and I'm not sure
if this is expressible using the LOOP macro.
- define more internal loop variables. inner scope only
> [for (x=1,2,3,4,5,6], start=12) x*start ]
>
But we already have syntax for this.
[for (x=[1,2,3,4,5,6]) let (start=12) x*start ]
> - I can't imagine how to do if-then constructs and collect inside the
> existing syntax.
>
I had the same problem, reading your previous post. You wrote:
- using conditionals within the loop (as an operator, not a regular if
statement)
[for x below 10
if odd(x)
collect x into odds
else
collect x into evens
finally [odds, evens] ]
gives [[1 3 5 7 9] [0 2 4 6 8]]
In functional programming, this would be done using 'partition'.
partition(odd)([0:9])
Here is the non-recursive definition:
partition(f)(s) =
let (p1 = [for (x=s) if (f(x)) x],
p2 = [for (x=s) if (!f(x)) x])
[p1,p2];
In summary, my counter-proposal is to add structured assignment to
OpenSCAD2, and then provide library functions to make writing loops and
list processing more convenient.
I'll admit I have a bias for the functional style of programming, since I'm
used to that, and I don't have any experience using the Lisp LOOP macros.
And I admit there's a learning curve; you need a cookbook to learn some of
the common programming patterns. I'll be interested to know what other
people think.
One thing to note: In my OpenSCAD2 list library, most functions have double
argument lists, with the list in the second or outmost argument list. This
allows you to chain together list operations the same way you can chain
together geometric transforms in OpenSCAD.
NH
nop head
Thu, Jan 7, 2016 5:40 PM
And I admit there's a learning curve; you need a cookbook to learn some of
the common programming patterns. I'll be interested to know what other
people think.
I think we just don't need such language complexity to describe 3D objects.
It there any 3D object that cannot be described by OpenScad as it stands
now?
I am far more interested in OpenScad producing numerically accurate results
and getting faster than being able to accept more programming paradigms.
Sure some things get expressed more succinctly but at the expense of being
more cryptic and bringing the need to read up on several languages to
understand the code.
I only started this thread to propose a way of not having to create nested
lists just to flatten them. It seems to have lead to a Frankenstein's
monster of a loop syntax that combines bits from everybody's favourite
languages.
Fiddling about with the syntax of the source code when fundamental things
like union and rotate don't produce the correct results seems pointless to
me.
On 7 January 2016 at 17:03, doug moen doug@moens.org wrote:
Sorry about the negative tone of my response. I did get frustrated by your
original post, though. It's written in a pseudo-code, somewhere between
Lisp and OpenSCAD. Since you weren't proposing that as the final syntax, I
tried to translate your examples into OpenSCAD syntax, and what I finally
ended up with were list comprehensions + Haskell-inspired list functions.
Which is not what you were proposing.
The entire Genera OS was written in lisp on a lisp machine. Yes an entire
OS in Lisp. It remains the best development system I worked on.
I never had an opportunity to use a Lisp Machine. I'm a student of
computer history, though, and it's legendary. I'd like to spend time
playing with this software so that I can understand why it's the best
development system ever. Maybe somebody will resurrect this in an emulator
one day.
- add structured assignment:
[for ([a b]=[[1 2] [3 4] [5 6]]) [b a] ]
giving [[2 1] [4 3] [6 5]]
I completely agree with adding structured assignment. I've been writing
OpenSCAD2 code as part of a project, and I've added structured assignment,
because it is so convenient for destructuring 2-vectors and 3-vectors in
the style of geometric programming I'm playing with.
Your example is pseudo code, so I'll translate to OpenSCAD syntax:
[ for ([a,b] = [[1,2], [3,4], [5,6]]) [b,a] ]
In my version of structured assignment,
[a,b] = x
produces a run-time error if x is not a list of length 2. The syntax works
in definitions, function formal parameter lists, and for statements.
- add from
[ for (i=[1:10], j from 2) i*j ]
where j starts at 2 and counts up. the i variable sets the termination
of
the loop
from could not appear on its own without a termination clause.
You intend this to mean 2 loops running in parallel, instead of being
nested. In OpenSCAD, the syntax
for (i=[1:10], j=[2:11]) ...
looks like it would be good syntax for two parallel loops, but it's not.
It actually means nested loops, same as
for (i=[1:10]) for (j=[2:11]) ...
So I think there is a backward compatibility problem with expressing
parallel loops in the way you suggest. The problem is in violating the
expectations of OpenSCAD programmers, who expect 'for (i=.., j=..)' to mean
nested loops.
Your previous post had several examples of parallel loops. Here's one:
- Create pairs
[for x = [1:5]
for y = ["A","B","C","D","E"]
do [x y] ]
giving [[1 A] [2 B] [3 C] [4 D] [5 E]]
This is more pseudo-code. The problem is that if we convert this into
OpenSCAD syntax, we get nested loops:
[for (x = [1:5])
for (y = ["A","B","C","D","E"])
[x,y]]
and the result is a list of 25 pairs.
In functional style programming, you would create the pairs by calling
transpose, which in OpenSCAD is matrix transpose from linear algebra.
transpose([[1:5], ["A","B","C","D","E"]])
=> [[1,"A"], [2,"B"], [3,"C"], [4,"D"], [5,"E"]]
(This works in OpenSCAD2 because [1:5] is operationally equivalent to
[1,2,3,4,5] in all contexts.)
We could invent a new syntax for parallel loops in OpenSCAD. Maybe this
would work:
for (x = xlist | y = ylist) ...
Or we could just use transpose. Because this also works:
for ([x,y] = transpose(xlist, ylist)) ...
- loop terminatoin with while, or until, or just one and use not operator
for the other - for readability
[ for (x=1,2,3,4,5,6], while prime(x)) [ x, x*x] ]
returning list of [x,x^2] until first non-prime encountered.
I'm not sure about the , before the while, for reasons previously
discussed. And the argument of 'while' should be parenthesized, for
consistency with the rest of OpenSCAD syntax. So maybe this:
[ for (x=[1,2,3,4,5,6] | while(prime(x))) [x, x*x] ]
In functional programming, you'd implement this using take_while, which
returns the longest prefix of a sequence that matches a predicate. In
OpenSCAD2, the code would look like this:
[ for (x=[1,2,3,4,5,6] >> take_while(prime)) [x, x*x] ]
It's not much worse, and no additional syntax is added to the language,
since take_while is a library function. There is also a drop_while function
which discards initial elements that match the predicate, and I'm not sure
if this is expressible using the LOOP macro.
- define more internal loop variables. inner scope only
[for (x=1,2,3,4,5,6], start=12) x*start ]
But we already have syntax for this.
[for (x=[1,2,3,4,5,6]) let (start=12) x*start ]
- I can't imagine how to do if-then constructs and collect inside the
existing syntax.
I had the same problem, reading your previous post. You wrote:
- using conditionals within the loop (as an operator, not a regular if
statement)
[for x below 10
if odd(x)
collect x into odds
else
collect x into evens
finally [odds, evens] ]
gives [[1 3 5 7 9] [0 2 4 6 8]]
In functional programming, this would be done using 'partition'.
partition(odd)([0:9])
Here is the non-recursive definition:
partition(f)(s) =
let (p1 = [for (x=s) if (f(x)) x],
p2 = [for (x=s) if (!f(x)) x])
[p1,p2];
In summary, my counter-proposal is to add structured assignment to
OpenSCAD2, and then provide library functions to make writing loops and
list processing more convenient.
I'll admit I have a bias for the functional style of programming, since
I'm used to that, and I don't have any experience using the Lisp LOOP
macros. And I admit there's a learning curve; you need a cookbook to learn
some of the common programming patterns. I'll be interested to know what
other people think.
One thing to note: In my OpenSCAD2 list library, most functions have
double argument lists, with the list in the second or outmost argument
list. This allows you to chain together list operations the same way you
can chain together geometric transforms in OpenSCAD.
OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
>And I admit there's a learning curve; you need a cookbook to learn some of
the common programming patterns. I'll be interested to know what other
people think.
I think we just don't need such language complexity to describe 3D objects.
It there any 3D object that cannot be described by OpenScad as it stands
now?
I am far more interested in OpenScad producing numerically accurate results
and getting faster than being able to accept more programming paradigms.
Sure some things get expressed more succinctly but at the expense of being
more cryptic and bringing the need to read up on several languages to
understand the code.
I only started this thread to propose a way of not having to create nested
lists just to flatten them. It seems to have lead to a Frankenstein's
monster of a loop syntax that combines bits from everybody's favourite
languages.
Fiddling about with the syntax of the source code when fundamental things
like union and rotate don't produce the correct results seems pointless to
me.
On 7 January 2016 at 17:03, doug moen <doug@moens.org> wrote:
> Sorry about the negative tone of my response. I did get frustrated by your
> original post, though. It's written in a pseudo-code, somewhere between
> Lisp and OpenSCAD. Since you weren't proposing that as the final syntax, I
> tried to translate your examples into OpenSCAD syntax, and what I finally
> ended up with were list comprehensions + Haskell-inspired list functions.
> Which is not what you were proposing.
>
> The entire Genera OS was written in lisp on a lisp machine. Yes an entire
>> OS in Lisp. It remains the best development system I worked on.
>>
>
> I never had an opportunity to use a Lisp Machine. I'm a student of
> computer history, though, and it's legendary. I'd like to spend time
> playing with this software so that I can understand why it's the best
> development system ever. Maybe somebody will resurrect this in an emulator
> one day.
>
>
>> - add structured assignment:
>> [for ([a b]=[[1 2] [3 4] [5 6]]) [b a] ]
>> giving [[2 1] [4 3] [6 5]]
>>
>
> I completely agree with adding structured assignment. I've been writing
> OpenSCAD2 code as part of a project, and I've added structured assignment,
> because it is so convenient for destructuring 2-vectors and 3-vectors in
> the style of geometric programming I'm playing with.
>
> Your example is pseudo code, so I'll translate to OpenSCAD syntax:
> [ for ([a,b] = [[1,2], [3,4], [5,6]]) [b,a] ]
>
> In my version of structured assignment,
> [a,b] = x
> produces a run-time error if x is not a list of length 2. The syntax works
> in definitions, function formal parameter lists, and for statements.
>
>
>> - add from
>> [ for (i=[1:10], j from 2) i*j ]
>> where j starts at 2 and counts up. the i variable sets the termination
>> of
>> the loop
>> from could not appear on its own without a termination clause.
>>
>
> You intend this to mean 2 loops running in parallel, instead of being
> nested. In OpenSCAD, the syntax
> for (i=[1:10], j=[2:11]) ...
> looks like it would be good syntax for two parallel loops, but it's not.
> It actually means nested loops, same as
> for (i=[1:10]) for (j=[2:11]) ...
> So I think there is a backward compatibility problem with expressing
> parallel loops in the way you suggest. The problem is in violating the
> expectations of OpenSCAD programmers, who expect 'for (i=.., j=..)' to mean
> nested loops.
>
> Your previous post had several examples of parallel loops. Here's one:
>
> - Create pairs
> [for x = [1:5]
> for y = ["A","B","C","D","E"]
> do [x y] ]
> giving [[1 A] [2 B] [3 C] [4 D] [5 E]]
>
> This is more pseudo-code. The problem is that if we convert this into
> OpenSCAD syntax, we get nested loops:
>
> [for (x = [1:5])
> for (y = ["A","B","C","D","E"])
> [x,y]]
> and the result is a list of 25 pairs.
>
> In functional style programming, you would create the pairs by calling
> transpose, which in OpenSCAD is matrix transpose from linear algebra.
> transpose([[1:5], ["A","B","C","D","E"]])
> => [[1,"A"], [2,"B"], [3,"C"], [4,"D"], [5,"E"]]
>
> (This works in OpenSCAD2 because [1:5] is operationally equivalent to
> [1,2,3,4,5] in all contexts.)
>
> We could invent a new syntax for parallel loops in OpenSCAD. Maybe this
> would work:
> for (x = xlist | y = ylist) ...
>
> Or we could just use transpose. Because this also works:
> for ([x,y] = transpose(xlist, ylist)) ...
>
> - loop terminatoin with while, or until, or just one and use not operator
>> for the other - for readability
>> [ for (x=1,2,3,4,5,6], while prime(x)) [ x, x*x] ]
>> returning list of [x,x^2] until first non-prime encountered.
>>
>
> I'm not sure about the , before the while, for reasons previously
> discussed. And the argument of 'while' should be parenthesized, for
> consistency with the rest of OpenSCAD syntax. So maybe this:
>
> [ for (x=[1,2,3,4,5,6] | while(prime(x))) [x, x*x] ]
>
> In functional programming, you'd implement this using take_while, which
> returns the longest prefix of a sequence that matches a predicate. In
> OpenSCAD2, the code would look like this:
>
> [ for (x=[1,2,3,4,5,6] >> take_while(prime)) [x, x*x] ]
>
> It's not much worse, and no additional syntax is added to the language,
> since take_while is a library function. There is also a drop_while function
> which discards initial elements that match the predicate, and I'm not sure
> if this is expressible using the LOOP macro.
>
> - define more internal loop variables. inner scope only
>> [for (x=1,2,3,4,5,6], start=12) x*start ]
>>
>
> But we already have syntax for this.
> [for (x=[1,2,3,4,5,6]) let (start=12) x*start ]
>
>
>> - I can't imagine how to do if-then constructs and collect inside the
>> existing syntax.
>>
>
> I had the same problem, reading your previous post. You wrote:
>
> - using conditionals within the loop (as an operator, not a regular if
> statement)
> [for x below 10
> if odd(x)
> collect x into odds
> else
> collect x into evens
> finally [odds, evens] ]
> gives [[1 3 5 7 9] [0 2 4 6 8]]
>
> In functional programming, this would be done using 'partition'.
> partition(odd)([0:9])
>
> Here is the non-recursive definition:
> partition(f)(s) =
> let (p1 = [for (x=s) if (f(x)) x],
> p2 = [for (x=s) if (!f(x)) x])
> [p1,p2];
>
> In summary, my counter-proposal is to add structured assignment to
> OpenSCAD2, and then provide library functions to make writing loops and
> list processing more convenient.
>
> I'll admit I have a bias for the functional style of programming, since
> I'm used to that, and I don't have any experience using the Lisp LOOP
> macros. And I admit there's a learning curve; you need a cookbook to learn
> some of the common programming patterns. I'll be interested to know what
> other people think.
>
> One thing to note: In my OpenSCAD2 list library, most functions have
> double argument lists, with the list in the second or outmost argument
> list. This allows you to chain together list operations the same way you
> can chain together geometric transforms in OpenSCAD.
>
> _______________________________________________
> OpenSCAD mailing list
> Discuss@lists.openscad.org
> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
>
>
DM
doug moen
Thu, Jan 7, 2016 5:47 PM
And I admit there's a learning curve; you need a cookbook to learn some
of the common programming patterns. I'll be interested to know what other
people think.
I think we just don't need such language complexity to describe 3D objects.
It there any 3D object that cannot be described by OpenScad as it stands
now?
I am far more interested in OpenScad producing numerically accurate
results and getting faster than being able to accept more programming
paradigms. Sure some things get expressed more succinctly but at the
expense of being more cryptic and bringing the need to read up on several
languages to understand the code.
I only started this thread to propose a way of not having to create nested
lists just to flatten them. It seems to have lead to a Frankenstein's
monster of a loop syntax that combines bits from everybody's favourite
languages.
Fiddling about with the syntax of the source code when fundamental things
like union and rotate don't produce the correct results seems pointless to
me.
On 7 January 2016 at 17:03, doug moen doug@moens.org wrote:
Sorry about the negative tone of my response. I did get frustrated by
your original post, though. It's written in a pseudo-code, somewhere
between Lisp and OpenSCAD. Since you weren't proposing that as the final
syntax, I tried to translate your examples into OpenSCAD syntax, and what I
finally ended up with were list comprehensions + Haskell-inspired list
functions. Which is not what you were proposing.
The entire Genera OS was written in lisp on a lisp machine. Yes an entire
OS in Lisp. It remains the best development system I worked on.
I never had an opportunity to use a Lisp Machine. I'm a student of
computer history, though, and it's legendary. I'd like to spend time
playing with this software so that I can understand why it's the best
development system ever. Maybe somebody will resurrect this in an emulator
one day.
- add structured assignment:
[for ([a b]=[[1 2] [3 4] [5 6]]) [b a] ]
giving [[2 1] [4 3] [6 5]]
I completely agree with adding structured assignment. I've been writing
OpenSCAD2 code as part of a project, and I've added structured assignment,
because it is so convenient for destructuring 2-vectors and 3-vectors in
the style of geometric programming I'm playing with.
Your example is pseudo code, so I'll translate to OpenSCAD syntax:
[ for ([a,b] = [[1,2], [3,4], [5,6]]) [b,a] ]
In my version of structured assignment,
[a,b] = x
produces a run-time error if x is not a list of length 2. The syntax
works in definitions, function formal parameter lists, and for statements.
- add from
[ for (i=[1:10], j from 2) i*j ]
where j starts at 2 and counts up. the i variable sets the termination
of
the loop
from could not appear on its own without a termination clause.
You intend this to mean 2 loops running in parallel, instead of being
nested. In OpenSCAD, the syntax
for (i=[1:10], j=[2:11]) ...
looks like it would be good syntax for two parallel loops, but it's not.
It actually means nested loops, same as
for (i=[1:10]) for (j=[2:11]) ...
So I think there is a backward compatibility problem with expressing
parallel loops in the way you suggest. The problem is in violating the
expectations of OpenSCAD programmers, who expect 'for (i=.., j=..)' to mean
nested loops.
Your previous post had several examples of parallel loops. Here's one:
- Create pairs
[for x = [1:5]
for y = ["A","B","C","D","E"]
do [x y] ]
giving [[1 A] [2 B] [3 C] [4 D] [5 E]]
This is more pseudo-code. The problem is that if we convert this into
OpenSCAD syntax, we get nested loops:
[for (x = [1:5])
for (y = ["A","B","C","D","E"])
[x,y]]
and the result is a list of 25 pairs.
In functional style programming, you would create the pairs by calling
transpose, which in OpenSCAD is matrix transpose from linear algebra.
transpose([[1:5], ["A","B","C","D","E"]])
=> [[1,"A"], [2,"B"], [3,"C"], [4,"D"], [5,"E"]]
(This works in OpenSCAD2 because [1:5] is operationally equivalent to
[1,2,3,4,5] in all contexts.)
We could invent a new syntax for parallel loops in OpenSCAD. Maybe this
would work:
for (x = xlist | y = ylist) ...
Or we could just use transpose. Because this also works:
for ([x,y] = transpose(xlist, ylist)) ...
- loop terminatoin with while, or until, or just one and use not operator
for the other - for readability
[ for (x=1,2,3,4,5,6], while prime(x)) [ x, x*x] ]
returning list of [x,x^2] until first non-prime encountered.
I'm not sure about the , before the while, for reasons previously
discussed. And the argument of 'while' should be parenthesized, for
consistency with the rest of OpenSCAD syntax. So maybe this:
[ for (x=[1,2,3,4,5,6] | while(prime(x))) [x, x*x] ]
In functional programming, you'd implement this using take_while, which
returns the longest prefix of a sequence that matches a predicate. In
OpenSCAD2, the code would look like this:
[ for (x=[1,2,3,4,5,6] >> take_while(prime)) [x, x*x] ]
It's not much worse, and no additional syntax is added to the language,
since take_while is a library function. There is also a drop_while function
which discards initial elements that match the predicate, and I'm not sure
if this is expressible using the LOOP macro.
- define more internal loop variables. inner scope only
[for (x=1,2,3,4,5,6], start=12) x*start ]
But we already have syntax for this.
[for (x=[1,2,3,4,5,6]) let (start=12) x*start ]
- I can't imagine how to do if-then constructs and collect inside the
existing syntax.
I had the same problem, reading your previous post. You wrote:
- using conditionals within the loop (as an operator, not a regular if
statement)
[for x below 10
if odd(x)
collect x into odds
else
collect x into evens
finally [odds, evens] ]
gives [[1 3 5 7 9] [0 2 4 6 8]]
In functional programming, this would be done using 'partition'.
partition(odd)([0:9])
Here is the non-recursive definition:
partition(f)(s) =
let (p1 = [for (x=s) if (f(x)) x],
p2 = [for (x=s) if (!f(x)) x])
[p1,p2];
In summary, my counter-proposal is to add structured assignment to
OpenSCAD2, and then provide library functions to make writing loops and
list processing more convenient.
I'll admit I have a bias for the functional style of programming, since
I'm used to that, and I don't have any experience using the Lisp LOOP
macros. And I admit there's a learning curve; you need a cookbook to learn
some of the common programming patterns. I'll be interested to know what
other people think.
One thing to note: In my OpenSCAD2 list library, most functions have
double argument lists, with the list in the second or outmost argument
list. This allows you to chain together list operations the same way you
can chain together geometric transforms in OpenSCAD.
OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Fair enough.
On 7 January 2016 at 12:40, nop head <nop.head@gmail.com> wrote:
> >And I admit there's a learning curve; you need a cookbook to learn some
> of the common programming patterns. I'll be interested to know what other
> people think.
>
> I think we just don't need such language complexity to describe 3D objects.
>
> It there any 3D object that cannot be described by OpenScad as it stands
> now?
>
> I am far more interested in OpenScad producing numerically accurate
> results and getting faster than being able to accept more programming
> paradigms. Sure some things get expressed more succinctly but at the
> expense of being more cryptic and bringing the need to read up on several
> languages to understand the code.
>
> I only started this thread to propose a way of not having to create nested
> lists just to flatten them. It seems to have lead to a Frankenstein's
> monster of a loop syntax that combines bits from everybody's favourite
> languages.
>
> Fiddling about with the syntax of the source code when fundamental things
> like union and rotate don't produce the correct results seems pointless to
> me.
>
>
> On 7 January 2016 at 17:03, doug moen <doug@moens.org> wrote:
>
>> Sorry about the negative tone of my response. I did get frustrated by
>> your original post, though. It's written in a pseudo-code, somewhere
>> between Lisp and OpenSCAD. Since you weren't proposing that as the final
>> syntax, I tried to translate your examples into OpenSCAD syntax, and what I
>> finally ended up with were list comprehensions + Haskell-inspired list
>> functions. Which is not what you were proposing.
>>
>> The entire Genera OS was written in lisp on a lisp machine. Yes an entire
>>> OS in Lisp. It remains the best development system I worked on.
>>>
>>
>> I never had an opportunity to use a Lisp Machine. I'm a student of
>> computer history, though, and it's legendary. I'd like to spend time
>> playing with this software so that I can understand why it's the best
>> development system ever. Maybe somebody will resurrect this in an emulator
>> one day.
>>
>>
>>> - add structured assignment:
>>> [for ([a b]=[[1 2] [3 4] [5 6]]) [b a] ]
>>> giving [[2 1] [4 3] [6 5]]
>>>
>>
>> I completely agree with adding structured assignment. I've been writing
>> OpenSCAD2 code as part of a project, and I've added structured assignment,
>> because it is so convenient for destructuring 2-vectors and 3-vectors in
>> the style of geometric programming I'm playing with.
>>
>> Your example is pseudo code, so I'll translate to OpenSCAD syntax:
>> [ for ([a,b] = [[1,2], [3,4], [5,6]]) [b,a] ]
>>
>> In my version of structured assignment,
>> [a,b] = x
>> produces a run-time error if x is not a list of length 2. The syntax
>> works in definitions, function formal parameter lists, and for statements.
>>
>>
>>> - add from
>>> [ for (i=[1:10], j from 2) i*j ]
>>> where j starts at 2 and counts up. the i variable sets the termination
>>> of
>>> the loop
>>> from could not appear on its own without a termination clause.
>>>
>>
>> You intend this to mean 2 loops running in parallel, instead of being
>> nested. In OpenSCAD, the syntax
>> for (i=[1:10], j=[2:11]) ...
>> looks like it would be good syntax for two parallel loops, but it's not.
>> It actually means nested loops, same as
>> for (i=[1:10]) for (j=[2:11]) ...
>> So I think there is a backward compatibility problem with expressing
>> parallel loops in the way you suggest. The problem is in violating the
>> expectations of OpenSCAD programmers, who expect 'for (i=.., j=..)' to mean
>> nested loops.
>>
>> Your previous post had several examples of parallel loops. Here's one:
>>
>> - Create pairs
>> [for x = [1:5]
>> for y = ["A","B","C","D","E"]
>> do [x y] ]
>> giving [[1 A] [2 B] [3 C] [4 D] [5 E]]
>>
>> This is more pseudo-code. The problem is that if we convert this into
>> OpenSCAD syntax, we get nested loops:
>>
>> [for (x = [1:5])
>> for (y = ["A","B","C","D","E"])
>> [x,y]]
>> and the result is a list of 25 pairs.
>>
>> In functional style programming, you would create the pairs by calling
>> transpose, which in OpenSCAD is matrix transpose from linear algebra.
>> transpose([[1:5], ["A","B","C","D","E"]])
>> => [[1,"A"], [2,"B"], [3,"C"], [4,"D"], [5,"E"]]
>>
>> (This works in OpenSCAD2 because [1:5] is operationally equivalent to
>> [1,2,3,4,5] in all contexts.)
>>
>> We could invent a new syntax for parallel loops in OpenSCAD. Maybe this
>> would work:
>> for (x = xlist | y = ylist) ...
>>
>> Or we could just use transpose. Because this also works:
>> for ([x,y] = transpose(xlist, ylist)) ...
>>
>> - loop terminatoin with while, or until, or just one and use not operator
>>> for the other - for readability
>>> [ for (x=1,2,3,4,5,6], while prime(x)) [ x, x*x] ]
>>> returning list of [x,x^2] until first non-prime encountered.
>>>
>>
>> I'm not sure about the , before the while, for reasons previously
>> discussed. And the argument of 'while' should be parenthesized, for
>> consistency with the rest of OpenSCAD syntax. So maybe this:
>>
>> [ for (x=[1,2,3,4,5,6] | while(prime(x))) [x, x*x] ]
>>
>> In functional programming, you'd implement this using take_while, which
>> returns the longest prefix of a sequence that matches a predicate. In
>> OpenSCAD2, the code would look like this:
>>
>> [ for (x=[1,2,3,4,5,6] >> take_while(prime)) [x, x*x] ]
>>
>> It's not much worse, and no additional syntax is added to the language,
>> since take_while is a library function. There is also a drop_while function
>> which discards initial elements that match the predicate, and I'm not sure
>> if this is expressible using the LOOP macro.
>>
>> - define more internal loop variables. inner scope only
>>> [for (x=1,2,3,4,5,6], start=12) x*start ]
>>>
>>
>> But we already have syntax for this.
>> [for (x=[1,2,3,4,5,6]) let (start=12) x*start ]
>>
>>
>>> - I can't imagine how to do if-then constructs and collect inside the
>>> existing syntax.
>>>
>>
>> I had the same problem, reading your previous post. You wrote:
>>
>> - using conditionals within the loop (as an operator, not a regular if
>> statement)
>> [for x below 10
>> if odd(x)
>> collect x into odds
>> else
>> collect x into evens
>> finally [odds, evens] ]
>> gives [[1 3 5 7 9] [0 2 4 6 8]]
>>
>> In functional programming, this would be done using 'partition'.
>> partition(odd)([0:9])
>>
>> Here is the non-recursive definition:
>> partition(f)(s) =
>> let (p1 = [for (x=s) if (f(x)) x],
>> p2 = [for (x=s) if (!f(x)) x])
>> [p1,p2];
>>
>> In summary, my counter-proposal is to add structured assignment to
>> OpenSCAD2, and then provide library functions to make writing loops and
>> list processing more convenient.
>>
>> I'll admit I have a bias for the functional style of programming, since
>> I'm used to that, and I don't have any experience using the Lisp LOOP
>> macros. And I admit there's a learning curve; you need a cookbook to learn
>> some of the common programming patterns. I'll be interested to know what
>> other people think.
>>
>> One thing to note: In my OpenSCAD2 list library, most functions have
>> double argument lists, with the list in the second or outmost argument
>> list. This allows you to chain together list operations the same way you
>> can chain together geometric transforms in OpenSCAD.
>>
>> _______________________________________________
>> OpenSCAD mailing list
>> Discuss@lists.openscad.org
>> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
>>
>>
>
> _______________________________________________
> OpenSCAD mailing list
> Discuss@lists.openscad.org
> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
>
>
JL
Jean-Paul Louis
Thu, Jan 7, 2016 5:58 PM
How do you describe a Moebius ring in OpenScad?
Just curious,
Jean-Paul
N1JPL
And I admit there's a learning curve; you need a cookbook to learn some of the common programming patterns. I'll be interested to know what other people think.
I think we just don't need such language complexity to describe 3D objects.
It there any 3D object that cannot be described by OpenScad as it stands now?
I am far more interested in OpenScad producing numerically accurate results and getting faster than being able to accept more programming paradigms. Sure some things get expressed more succinctly but at the expense of being more cryptic and bringing the need to read up on several languages to understand the code.
I only started this thread to propose a way of not having to create nested lists just to flatten them. It seems to have lead to a Frankenstein's monster of a loop syntax that combines bits from everybody's favourite languages.
Fiddling about with the syntax of the source code when fundamental things like union and rotate don't produce the correct results seems pointless to me.
On 7 January 2016 at 17:03, doug moen doug@moens.org wrote:
Sorry about the negative tone of my response. I did get frustrated by your original post, though. It's written in a pseudo-code, somewhere between Lisp and OpenSCAD. Since you weren't proposing that as the final syntax, I tried to translate your examples into OpenSCAD syntax, and what I finally ended up with were list comprehensions + Haskell-inspired list functions. Which is not what you were proposing.
The entire Genera OS was written in lisp on a lisp machine. Yes an entire OS in Lisp. It remains the best development system I worked on.
I never had an opportunity to use a Lisp Machine. I'm a student of computer history, though, and it's legendary. I'd like to spend time playing with this software so that I can understand why it's the best development system ever. Maybe somebody will resurrect this in an emulator one day.
- add structured assignment:
[for ([a b]=[[1 2] [3 4] [5 6]]) [b a] ]
giving [[2 1] [4 3] [6 5]]
I completely agree with adding structured assignment. I've been writing OpenSCAD2 code as part of a project, and I've added structured assignment, because it is so convenient for destructuring 2-vectors and 3-vectors in the style of geometric programming I'm playing with.
Your example is pseudo code, so I'll translate to OpenSCAD syntax:
[ for ([a,b] = [[1,2], [3,4], [5,6]]) [b,a] ]
In my version of structured assignment,
[a,b] = x
produces a run-time error if x is not a list of length 2. The syntax works in definitions, function formal parameter lists, and for statements.
- add from
[ for (i=[1:10], j from 2) i*j ]
where j starts at 2 and counts up. the i variable sets the termination of
the loop
from could not appear on its own without a termination clause.
You intend this to mean 2 loops running in parallel, instead of being nested. In OpenSCAD, the syntax
for (i=[1:10], j=[2:11]) ...
looks like it would be good syntax for two parallel loops, but it's not. It actually means nested loops, same as
for (i=[1:10]) for (j=[2:11]) ...
So I think there is a backward compatibility problem with expressing parallel loops in the way you suggest. The problem is in violating the expectations of OpenSCAD programmers, who expect 'for (i=.., j=..)' to mean nested loops.
Your previous post had several examples of parallel loops. Here's one:
- Create pairs
[for x = [1:5]
for y = ["A","B","C","D","E"]
do [x y] ]
giving [[1 A] [2 B] [3 C] [4 D] [5 E]]
This is more pseudo-code. The problem is that if we convert this into OpenSCAD syntax, we get nested loops:
[for (x = [1:5])
for (y = ["A","B","C","D","E"])
[x,y]]
and the result is a list of 25 pairs.
In functional style programming, you would create the pairs by calling transpose, which in OpenSCAD is matrix transpose from linear algebra.
transpose([[1:5], ["A","B","C","D","E"]])
=> [[1,"A"], [2,"B"], [3,"C"], [4,"D"], [5,"E"]]
(This works in OpenSCAD2 because [1:5] is operationally equivalent to [1,2,3,4,5] in all contexts.)
We could invent a new syntax for parallel loops in OpenSCAD. Maybe this would work:
for (x = xlist | y = ylist) ...
Or we could just use transpose. Because this also works:
for ([x,y] = transpose(xlist, ylist)) ...
- loop terminatoin with while, or until, or just one and use not operator
for the other - for readability
[ for (x=1,2,3,4,5,6], while prime(x)) [ x, x*x] ]
returning list of [x,x^2] until first non-prime encountered.
I'm not sure about the , before the while, for reasons previously discussed. And the argument of 'while' should be parenthesized, for consistency with the rest of OpenSCAD syntax. So maybe this:
[ for (x=[1,2,3,4,5,6] | while(prime(x))) [x, x*x] ]
In functional programming, you'd implement this using take_while, which returns the longest prefix of a sequence that matches a predicate. In OpenSCAD2, the code would look like this:
[ for (x=[1,2,3,4,5,6] >> take_while(prime)) [x, x*x] ]
It's not much worse, and no additional syntax is added to the language, since take_while is a library function. There is also a drop_while function which discards initial elements that match the predicate, and I'm not sure if this is expressible using the LOOP macro.
- define more internal loop variables. inner scope only
[for (x=1,2,3,4,5,6], start=12) x*start ]
But we already have syntax for this.
[for (x=[1,2,3,4,5,6]) let (start=12) x*start ]
- I can't imagine how to do if-then constructs and collect inside the
existing syntax.
I had the same problem, reading your previous post. You wrote:
- using conditionals within the loop (as an operator, not a regular if
statement)
[for x below 10
if odd(x)
collect x into odds
else
collect x into evens
finally [odds, evens] ]
gives [[1 3 5 7 9] [0 2 4 6 8]]
In functional programming, this would be done using 'partition'.
partition(odd)([0:9])
Here is the non-recursive definition:
partition(f)(s) =
let (p1 = [for (x=s) if (f(x)) x],
p2 = [for (x=s) if (!f(x)) x])
[p1,p2];
In summary, my counter-proposal is to add structured assignment to OpenSCAD2, and then provide library functions to make writing loops and list processing more convenient.
I'll admit I have a bias for the functional style of programming, since I'm used to that, and I don't have any experience using the Lisp LOOP macros. And I admit there's a learning curve; you need a cookbook to learn some of the common programming patterns. I'll be interested to know what other people think.
One thing to note: In my OpenSCAD2 list library, most functions have double argument lists, with the list in the second or outmost argument list. This allows you to chain together list operations the same way you can chain together geometric transforms in OpenSCAD.
OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
How do you describe a Moebius ring in OpenScad?
Just curious,
Jean-Paul
N1JPL
> On Jan 7, 2016, at 12:40 PM, nop head <nop.head@gmail.com> wrote:
>
> >And I admit there's a learning curve; you need a cookbook to learn some of the common programming patterns. I'll be interested to know what other people think.
>
> I think we just don't need such language complexity to describe 3D objects.
>
> It there any 3D object that cannot be described by OpenScad as it stands now?
>
> I am far more interested in OpenScad producing numerically accurate results and getting faster than being able to accept more programming paradigms. Sure some things get expressed more succinctly but at the expense of being more cryptic and bringing the need to read up on several languages to understand the code.
>
> I only started this thread to propose a way of not having to create nested lists just to flatten them. It seems to have lead to a Frankenstein's monster of a loop syntax that combines bits from everybody's favourite languages.
>
> Fiddling about with the syntax of the source code when fundamental things like union and rotate don't produce the correct results seems pointless to me.
>
>
> On 7 January 2016 at 17:03, doug moen <doug@moens.org> wrote:
> Sorry about the negative tone of my response. I did get frustrated by your original post, though. It's written in a pseudo-code, somewhere between Lisp and OpenSCAD. Since you weren't proposing that as the final syntax, I tried to translate your examples into OpenSCAD syntax, and what I finally ended up with were list comprehensions + Haskell-inspired list functions. Which is not what you were proposing.
>
> The entire Genera OS was written in lisp on a lisp machine. Yes an entire OS in Lisp. It remains the best development system I worked on.
>
> I never had an opportunity to use a Lisp Machine. I'm a student of computer history, though, and it's legendary. I'd like to spend time playing with this software so that I can understand why it's the best development system ever. Maybe somebody will resurrect this in an emulator one day.
>
> - add structured assignment:
> [for ([a b]=[[1 2] [3 4] [5 6]]) [b a] ]
> giving [[2 1] [4 3] [6 5]]
>
> I completely agree with adding structured assignment. I've been writing OpenSCAD2 code as part of a project, and I've added structured assignment, because it is so convenient for destructuring 2-vectors and 3-vectors in the style of geometric programming I'm playing with.
>
> Your example is pseudo code, so I'll translate to OpenSCAD syntax:
> [ for ([a,b] = [[1,2], [3,4], [5,6]]) [b,a] ]
>
> In my version of structured assignment,
> [a,b] = x
> produces a run-time error if x is not a list of length 2. The syntax works in definitions, function formal parameter lists, and for statements.
>
> - add from
> [ for (i=[1:10], j from 2) i*j ]
> where j starts at 2 and counts up. the i variable sets the termination of
> the loop
> from could not appear on its own without a termination clause.
>
> You intend this to mean 2 loops running in parallel, instead of being nested. In OpenSCAD, the syntax
> for (i=[1:10], j=[2:11]) ...
> looks like it would be good syntax for two parallel loops, but it's not. It actually means nested loops, same as
> for (i=[1:10]) for (j=[2:11]) ...
> So I think there is a backward compatibility problem with expressing parallel loops in the way you suggest. The problem is in violating the expectations of OpenSCAD programmers, who expect 'for (i=.., j=..)' to mean nested loops.
>
> Your previous post had several examples of parallel loops. Here's one:
>
> - Create pairs
> [for x = [1:5]
> for y = ["A","B","C","D","E"]
> do [x y] ]
> giving [[1 A] [2 B] [3 C] [4 D] [5 E]]
>
> This is more pseudo-code. The problem is that if we convert this into OpenSCAD syntax, we get nested loops:
>
> [for (x = [1:5])
> for (y = ["A","B","C","D","E"])
> [x,y]]
> and the result is a list of 25 pairs.
>
> In functional style programming, you would create the pairs by calling transpose, which in OpenSCAD is matrix transpose from linear algebra.
> transpose([[1:5], ["A","B","C","D","E"]])
> => [[1,"A"], [2,"B"], [3,"C"], [4,"D"], [5,"E"]]
>
> (This works in OpenSCAD2 because [1:5] is operationally equivalent to [1,2,3,4,5] in all contexts.)
>
> We could invent a new syntax for parallel loops in OpenSCAD. Maybe this would work:
> for (x = xlist | y = ylist) ...
>
> Or we could just use transpose. Because this also works:
> for ([x,y] = transpose(xlist, ylist)) ...
>
> - loop terminatoin with while, or until, or just one and use not operator
> for the other - for readability
> [ for (x=1,2,3,4,5,6], while prime(x)) [ x, x*x] ]
> returning list of [x,x^2] until first non-prime encountered.
>
> I'm not sure about the , before the while, for reasons previously discussed. And the argument of 'while' should be parenthesized, for consistency with the rest of OpenSCAD syntax. So maybe this:
>
> [ for (x=[1,2,3,4,5,6] | while(prime(x))) [x, x*x] ]
>
> In functional programming, you'd implement this using take_while, which returns the longest prefix of a sequence that matches a predicate. In OpenSCAD2, the code would look like this:
>
> [ for (x=[1,2,3,4,5,6] >> take_while(prime)) [x, x*x] ]
>
> It's not much worse, and no additional syntax is added to the language, since take_while is a library function. There is also a drop_while function which discards initial elements that match the predicate, and I'm not sure if this is expressible using the LOOP macro.
>
> - define more internal loop variables. inner scope only
> [for (x=1,2,3,4,5,6], start=12) x*start ]
>
> But we already have syntax for this.
> [for (x=[1,2,3,4,5,6]) let (start=12) x*start ]
>
> - I can't imagine how to do if-then constructs and collect inside the
> existing syntax.
>
> I had the same problem, reading your previous post. You wrote:
>
> - using conditionals within the loop (as an operator, not a regular if
> statement)
> [for x below 10
> if odd(x)
> collect x into odds
> else
> collect x into evens
> finally [odds, evens] ]
> gives [[1 3 5 7 9] [0 2 4 6 8]]
>
> In functional programming, this would be done using 'partition'.
> partition(odd)([0:9])
>
> Here is the non-recursive definition:
> partition(f)(s) =
> let (p1 = [for (x=s) if (f(x)) x],
> p2 = [for (x=s) if (!f(x)) x])
> [p1,p2];
>
> In summary, my counter-proposal is to add structured assignment to OpenSCAD2, and then provide library functions to make writing loops and list processing more convenient.
>
> I'll admit I have a bias for the functional style of programming, since I'm used to that, and I don't have any experience using the Lisp LOOP macros. And I admit there's a learning curve; you need a cookbook to learn some of the common programming patterns. I'll be interested to know what other people think.
>
> One thing to note: In my OpenSCAD2 list library, most functions have double argument lists, with the list in the second or outmost argument list. This allows you to chain together list operations the same way you can chain together geometric transforms in OpenSCAD.
>
> _______________________________________________
> OpenSCAD mailing list
> Discuss@lists.openscad.org
> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
>
>
> _______________________________________________
> OpenSCAD mailing list
> Discuss@lists.openscad.org
> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
MK
Marius Kintel
Thu, Jan 7, 2016 6:10 PM
On Jan 7, 2016, at 12:40 PM, nop head nop.head@gmail.com wrote:
Fiddling about with the syntax of the source code when fundamental things like union and rotate don't produce the correct results seems pointless to me.
Keep in mind that the skills, time and focus requirements for working on computational geometry problems are different than working on functional language constructs. There are also personal motivational aspects involved with contributing to Open Source projects.
We all contribute where knowledge, skills and time allows.
-Marius
> On Jan 7, 2016, at 12:40 PM, nop head <nop.head@gmail.com> wrote:
>
> Fiddling about with the syntax of the source code when fundamental things like union and rotate don't produce the correct results seems pointless to me.
>
Keep in mind that the skills, time and focus requirements for working on computational geometry problems are different than working on functional language constructs. There are also personal motivational aspects involved with contributing to Open Source projects.
We all contribute where knowledge, skills and time allows.
-Marius
NH
nop head
Thu, Jan 7, 2016 6:19 PM
How do you describe a Moebius ring in OpenScad?
Just curious,
Jean-Paul
N1JPL
And I admit there's a learning curve; you need a cookbook to learn some
of the common programming patterns. I'll be interested to know what other
people think.
I think we just don't need such language complexity to describe 3D
It there any 3D object that cannot be described by OpenScad as it stands
I am far more interested in OpenScad producing numerically accurate
results and getting faster than being able to accept more programming
paradigms. Sure some things get expressed more succinctly but at the
expense of being more cryptic and bringing the need to read up on several
languages to understand the code.
I only started this thread to propose a way of not having to create
nested lists just to flatten them. It seems to have lead to a
Frankenstein's monster of a loop syntax that combines bits from everybody's
favourite languages.
Fiddling about with the syntax of the source code when fundamental
things like union and rotate don't produce the correct results seems
pointless to me.
On 7 January 2016 at 17:03, doug moen doug@moens.org wrote:
Sorry about the negative tone of my response. I did get frustrated by
your original post, though. It's written in a pseudo-code, somewhere
between Lisp and OpenSCAD. Since you weren't proposing that as the final
syntax, I tried to translate your examples into OpenSCAD syntax, and what I
finally ended up with were list comprehensions + Haskell-inspired list
functions. Which is not what you were proposing.
The entire Genera OS was written in lisp on a lisp machine. Yes an
entire OS in Lisp. It remains the best development system I worked on.
I never had an opportunity to use a Lisp Machine. I'm a student of
computer history, though, and it's legendary. I'd like to spend time
playing with this software so that I can understand why it's the best
development system ever. Maybe somebody will resurrect this in an emulator
one day.
- add structured assignment:
[for ([a b]=[[1 2] [3 4] [5 6]]) [b a] ]
giving [[2 1] [4 3] [6 5]]
I completely agree with adding structured assignment. I've been writing
OpenSCAD2 code as part of a project, and I've added structured assignment,
because it is so convenient for destructuring 2-vectors and 3-vectors in
the style of geometric programming I'm playing with.
Your example is pseudo code, so I'll translate to OpenSCAD syntax:
[ for ([a,b] = [[1,2], [3,4], [5,6]]) [b,a] ]
In my version of structured assignment,
[a,b] = x
produces a run-time error if x is not a list of length 2. The syntax
works in definitions, function formal parameter lists, and for statements.
- add from
[ for (i=[1:10], j from 2) i*j ]
where j starts at 2 and counts up. the i variable sets the termination
the loop
from could not appear on its own without a termination clause.
You intend this to mean 2 loops running in parallel, instead of being
nested. In OpenSCAD, the syntax
for (i=[1:10], j=[2:11]) ...
looks like it would be good syntax for two parallel loops, but it's not.
It actually means nested loops, same as
for (i=[1:10]) for (j=[2:11]) ...
So I think there is a backward compatibility problem with expressing
parallel loops in the way you suggest. The problem is in violating the
expectations of OpenSCAD programmers, who expect 'for (i=.., j=..)' to mean
nested loops.
Your previous post had several examples of parallel loops. Here's one:
- Create pairs
[for x = [1:5]
for y = ["A","B","C","D","E"]
do [x y] ]
giving [[1 A] [2 B] [3 C] [4 D] [5 E]]
This is more pseudo-code. The problem is that if we convert this into
OpenSCAD syntax, we get nested loops:
[for (x = [1:5])
for (y = ["A","B","C","D","E"])
[x,y]]
and the result is a list of 25 pairs.
In functional style programming, you would create the pairs by calling
transpose, which in OpenSCAD is matrix transpose from linear algebra.
transpose([[1:5], ["A","B","C","D","E"]])
=> [[1,"A"], [2,"B"], [3,"C"], [4,"D"], [5,"E"]]
(This works in OpenSCAD2 because [1:5] is operationally equivalent to
[1,2,3,4,5] in all contexts.)
We could invent a new syntax for parallel loops in OpenSCAD. Maybe this
for (x = xlist | y = ylist) ...
Or we could just use transpose. Because this also works:
for ([x,y] = transpose(xlist, ylist)) ...
- loop terminatoin with while, or until, or just one and use not operator
for the other - for readability
[ for (x=1,2,3,4,5,6], while prime(x)) [ x, x*x] ]
returning list of [x,x^2] until first non-prime encountered.
I'm not sure about the , before the while, for reasons previously
discussed. And the argument of 'while' should be parenthesized, for
consistency with the rest of OpenSCAD syntax. So maybe this:
[ for (x=[1,2,3,4,5,6] | while(prime(x))) [x, x*x] ]
In functional programming, you'd implement this using take_while, which
returns the longest prefix of a sequence that matches a predicate. In
OpenSCAD2, the code would look like this:
[ for (x=[1,2,3,4,5,6] >> take_while(prime)) [x, x*x] ]
It's not much worse, and no additional syntax is added to the language,
since take_while is a library function. There is also a drop_while function
which discards initial elements that match the predicate, and I'm not sure
if this is expressible using the LOOP macro.
- define more internal loop variables. inner scope only
[for (x=1,2,3,4,5,6], start=12) x*start ]
But we already have syntax for this.
[for (x=[1,2,3,4,5,6]) let (start=12) x*start ]
- I can't imagine how to do if-then constructs and collect inside the
existing syntax.
I had the same problem, reading your previous post. You wrote:
- using conditionals within the loop (as an operator, not a regular if
statement)
[for x below 10
if odd(x)
collect x into odds
else
collect x into evens
finally [odds, evens] ]
gives [[1 3 5 7 9] [0 2 4 6 8]]
In functional programming, this would be done using 'partition'.
partition(odd)([0:9])
Here is the non-recursive definition:
partition(f)(s) =
let (p1 = [for (x=s) if (f(x)) x],
p2 = [for (x=s) if (!f(x)) x])
[p1,p2];
In summary, my counter-proposal is to add structured assignment to
OpenSCAD2, and then provide library functions to make writing loops and
list processing more convenient.
I'll admit I have a bias for the functional style of programming, since
I'm used to that, and I don't have any experience using the Lisp LOOP
macros. And I admit there's a learning curve; you need a cookbook to learn
some of the common programming patterns. I'll be interested to know what
other people think.
One thing to note: In my OpenSCAD2 list library, most functions have
double argument lists, with the list in the second or outmost argument
list. This allows you to chain together list operations the same way you
can chain together geometric transforms in OpenSCAD.
http://www.thingiverse.com/thing:239158
On 7 January 2016 at 17:58, Jean-Paul Louis <louijp@yahoo.com> wrote:
> How do you describe a Moebius ring in OpenScad?
>
> Just curious,
> Jean-Paul
> N1JPL
>
> > On Jan 7, 2016, at 12:40 PM, nop head <nop.head@gmail.com> wrote:
> >
> > >And I admit there's a learning curve; you need a cookbook to learn some
> of the common programming patterns. I'll be interested to know what other
> people think.
> >
> > I think we just don't need such language complexity to describe 3D
> objects.
> >
> > It there any 3D object that cannot be described by OpenScad as it stands
> now?
> >
> > I am far more interested in OpenScad producing numerically accurate
> results and getting faster than being able to accept more programming
> paradigms. Sure some things get expressed more succinctly but at the
> expense of being more cryptic and bringing the need to read up on several
> languages to understand the code.
> >
> > I only started this thread to propose a way of not having to create
> nested lists just to flatten them. It seems to have lead to a
> Frankenstein's monster of a loop syntax that combines bits from everybody's
> favourite languages.
> >
> > Fiddling about with the syntax of the source code when fundamental
> things like union and rotate don't produce the correct results seems
> pointless to me.
> >
> >
> > On 7 January 2016 at 17:03, doug moen <doug@moens.org> wrote:
> > Sorry about the negative tone of my response. I did get frustrated by
> your original post, though. It's written in a pseudo-code, somewhere
> between Lisp and OpenSCAD. Since you weren't proposing that as the final
> syntax, I tried to translate your examples into OpenSCAD syntax, and what I
> finally ended up with were list comprehensions + Haskell-inspired list
> functions. Which is not what you were proposing.
> >
> > The entire Genera OS was written in lisp on a lisp machine. Yes an
> entire OS in Lisp. It remains the best development system I worked on.
> >
> > I never had an opportunity to use a Lisp Machine. I'm a student of
> computer history, though, and it's legendary. I'd like to spend time
> playing with this software so that I can understand why it's the best
> development system ever. Maybe somebody will resurrect this in an emulator
> one day.
> >
> > - add structured assignment:
> > [for ([a b]=[[1 2] [3 4] [5 6]]) [b a] ]
> > giving [[2 1] [4 3] [6 5]]
> >
> > I completely agree with adding structured assignment. I've been writing
> OpenSCAD2 code as part of a project, and I've added structured assignment,
> because it is so convenient for destructuring 2-vectors and 3-vectors in
> the style of geometric programming I'm playing with.
> >
> > Your example is pseudo code, so I'll translate to OpenSCAD syntax:
> > [ for ([a,b] = [[1,2], [3,4], [5,6]]) [b,a] ]
> >
> > In my version of structured assignment,
> > [a,b] = x
> > produces a run-time error if x is not a list of length 2. The syntax
> works in definitions, function formal parameter lists, and for statements.
> >
> > - add from
> > [ for (i=[1:10], j from 2) i*j ]
> > where j starts at 2 and counts up. the i variable sets the termination
> of
> > the loop
> > from could not appear on its own without a termination clause.
> >
> > You intend this to mean 2 loops running in parallel, instead of being
> nested. In OpenSCAD, the syntax
> > for (i=[1:10], j=[2:11]) ...
> > looks like it would be good syntax for two parallel loops, but it's not.
> It actually means nested loops, same as
> > for (i=[1:10]) for (j=[2:11]) ...
> > So I think there is a backward compatibility problem with expressing
> parallel loops in the way you suggest. The problem is in violating the
> expectations of OpenSCAD programmers, who expect 'for (i=.., j=..)' to mean
> nested loops.
> >
> > Your previous post had several examples of parallel loops. Here's one:
> >
> > - Create pairs
> > [for x = [1:5]
> > for y = ["A","B","C","D","E"]
> > do [x y] ]
> > giving [[1 A] [2 B] [3 C] [4 D] [5 E]]
> >
> > This is more pseudo-code. The problem is that if we convert this into
> OpenSCAD syntax, we get nested loops:
> >
> > [for (x = [1:5])
> > for (y = ["A","B","C","D","E"])
> > [x,y]]
> > and the result is a list of 25 pairs.
> >
> > In functional style programming, you would create the pairs by calling
> transpose, which in OpenSCAD is matrix transpose from linear algebra.
> > transpose([[1:5], ["A","B","C","D","E"]])
> > => [[1,"A"], [2,"B"], [3,"C"], [4,"D"], [5,"E"]]
> >
> > (This works in OpenSCAD2 because [1:5] is operationally equivalent to
> [1,2,3,4,5] in all contexts.)
> >
> > We could invent a new syntax for parallel loops in OpenSCAD. Maybe this
> would work:
> > for (x = xlist | y = ylist) ...
> >
> > Or we could just use transpose. Because this also works:
> > for ([x,y] = transpose(xlist, ylist)) ...
> >
> > - loop terminatoin with while, or until, or just one and use not operator
> > for the other - for readability
> > [ for (x=1,2,3,4,5,6], while prime(x)) [ x, x*x] ]
> > returning list of [x,x^2] until first non-prime encountered.
> >
> > I'm not sure about the , before the while, for reasons previously
> discussed. And the argument of 'while' should be parenthesized, for
> consistency with the rest of OpenSCAD syntax. So maybe this:
> >
> > [ for (x=[1,2,3,4,5,6] | while(prime(x))) [x, x*x] ]
> >
> > In functional programming, you'd implement this using take_while, which
> returns the longest prefix of a sequence that matches a predicate. In
> OpenSCAD2, the code would look like this:
> >
> > [ for (x=[1,2,3,4,5,6] >> take_while(prime)) [x, x*x] ]
> >
> > It's not much worse, and no additional syntax is added to the language,
> since take_while is a library function. There is also a drop_while function
> which discards initial elements that match the predicate, and I'm not sure
> if this is expressible using the LOOP macro.
> >
> > - define more internal loop variables. inner scope only
> > [for (x=1,2,3,4,5,6], start=12) x*start ]
> >
> > But we already have syntax for this.
> > [for (x=[1,2,3,4,5,6]) let (start=12) x*start ]
> >
> > - I can't imagine how to do if-then constructs and collect inside the
> > existing syntax.
> >
> > I had the same problem, reading your previous post. You wrote:
> >
> > - using conditionals within the loop (as an operator, not a regular if
> > statement)
> > [for x below 10
> > if odd(x)
> > collect x into odds
> > else
> > collect x into evens
> > finally [odds, evens] ]
> > gives [[1 3 5 7 9] [0 2 4 6 8]]
> >
> > In functional programming, this would be done using 'partition'.
> > partition(odd)([0:9])
> >
> > Here is the non-recursive definition:
> > partition(f)(s) =
> > let (p1 = [for (x=s) if (f(x)) x],
> > p2 = [for (x=s) if (!f(x)) x])
> > [p1,p2];
> >
> > In summary, my counter-proposal is to add structured assignment to
> OpenSCAD2, and then provide library functions to make writing loops and
> list processing more convenient.
> >
> > I'll admit I have a bias for the functional style of programming, since
> I'm used to that, and I don't have any experience using the Lisp LOOP
> macros. And I admit there's a learning curve; you need a cookbook to learn
> some of the common programming patterns. I'll be interested to know what
> other people think.
> >
> > One thing to note: In my OpenSCAD2 list library, most functions have
> double argument lists, with the list in the second or outmost argument
> list. This allows you to chain together list operations the same way you
> can chain together geometric transforms in OpenSCAD.
> >
> > _______________________________________________
> > OpenSCAD mailing list
> > Discuss@lists.openscad.org
> > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
> >
> >
> > _______________________________________________
> > OpenSCAD mailing list
> > Discuss@lists.openscad.org
> > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
>
>
> _______________________________________________
> OpenSCAD mailing list
> Discuss@lists.openscad.org
> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
>
M
MichaelAtOz
Thu, Jan 7, 2016 9:56 PM
Sure some things get expressed more succinctly but at the expense of being
more cryptic and bringing the need to read up on several languages to
understand the code.
...
It seems to have lead to a Frankenstein's
monster of a loop syntax that combines bits from everybody's favourite
languages.
Keep in mind that the skills, time and focus requirements for working on
computational geometry problems are different than working on functional
language constructs. There are also personal motivational aspects involved
with contributing to Open Source projects.
Agreed, but transforming the language into something that can only be read
my Tibetan monks will solve your future maintenance issue.
Newly minted 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/List-comprehensions-tp15321p15552.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
nophead wrote
> Sure some things get expressed more succinctly but at the expense of being
> more cryptic and bringing the need to read up on several languages to
> understand the code.
> ...
> It seems to have lead to a Frankenstein's
> monster of a loop syntax that combines bits from everybody's favourite
> languages.
+1. I like the term syntactic syrup
<https://en.wikipedia.org/wiki/Syntactic_sugar> , /which is not a good
thing/.
kintel wrote
> Keep in mind that the skills, time and focus requirements for working on
> computational geometry problems are different than working on functional
> language constructs. There are also personal motivational aspects involved
> with contributing to Open Source projects.
Agreed, but transforming the language into something that can only be read
my Tibetan monks will solve your future maintenance issue.
-----
Newly minted 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/List-comprehensions-tp15321p15552.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
JL
Jean-Paul Louis
Thu, Jan 7, 2016 10:04 PM
nop head,
Thank you for the link.
I though there was tricky stuff, but solution is simple and elegant.
Jean-Paul
N1JPL
And I admit there's a learning curve; you need a cookbook to learn some of the common programming patterns. I'll be interested to know what other people think.
I think we just don't need such language complexity to describe 3D objects.
It there any 3D object that cannot be described by OpenScad as it stands now?
I am far more interested in OpenScad producing numerically accurate results and getting faster than being able to accept more programming paradigms. Sure some things get expressed more succinctly but at the expense of being more cryptic and bringing the need to read up on several languages to understand the code.
I only started this thread to propose a way of not having to create nested lists just to flatten them. It seems to have lead to a Frankenstein's monster of a loop syntax that combines bits from everybody's favourite languages.
Fiddling about with the syntax of the source code when fundamental things like union and rotate don't produce the correct results seems pointless to me.
On 7 January 2016 at 17:03, doug moen doug@moens.org wrote:
Sorry about the negative tone of my response. I did get frustrated by your original post, though. It's written in a pseudo-code, somewhere between Lisp and OpenSCAD. Since you weren't proposing that as the final syntax, I tried to translate your examples into OpenSCAD syntax, and what I finally ended up with were list comprehensions + Haskell-inspired list functions. Which is not what you were proposing.
The entire Genera OS was written in lisp on a lisp machine. Yes an entire OS in Lisp. It remains the best development system I worked on.
I never had an opportunity to use a Lisp Machine. I'm a student of computer history, though, and it's legendary. I'd like to spend time playing with this software so that I can understand why it's the best development system ever. Maybe somebody will resurrect this in an emulator one day.
- add structured assignment:
[for ([a b]=[[1 2] [3 4] [5 6]]) [b a] ]
giving [[2 1] [4 3] [6 5]]
I completely agree with adding structured assignment. I've been writing OpenSCAD2 code as part of a project, and I've added structured assignment, because it is so convenient for destructuring 2-vectors and 3-vectors in the style of geometric programming I'm playing with.
Your example is pseudo code, so I'll translate to OpenSCAD syntax:
[ for ([a,b] = [[1,2], [3,4], [5,6]]) [b,a] ]
In my version of structured assignment,
[a,b] = x
produces a run-time error if x is not a list of length 2. The syntax works in definitions, function formal parameter lists, and for statements.
- add from
[ for (i=[1:10], j from 2) i*j ]
where j starts at 2 and counts up. the i variable sets the termination of
the loop
from could not appear on its own without a termination clause.
You intend this to mean 2 loops running in parallel, instead of being nested. In OpenSCAD, the syntax
for (i=[1:10], j=[2:11]) ...
looks like it would be good syntax for two parallel loops, but it's not. It actually means nested loops, same as
for (i=[1:10]) for (j=[2:11]) ...
So I think there is a backward compatibility problem with expressing parallel loops in the way you suggest. The problem is in violating the expectations of OpenSCAD programmers, who expect 'for (i=.., j=..)' to mean nested loops.
Your previous post had several examples of parallel loops. Here's one:
- Create pairs
[for x = [1:5]
for y = ["A","B","C","D","E"]
do [x y] ]
giving [[1 A] [2 B] [3 C] [4 D] [5 E]]
This is more pseudo-code. The problem is that if we convert this into OpenSCAD syntax, we get nested loops:
[for (x = [1:5])
for (y = ["A","B","C","D","E"])
[x,y]]
and the result is a list of 25 pairs.
In functional style programming, you would create the pairs by calling transpose, which in OpenSCAD is matrix transpose from linear algebra.
transpose([[1:5], ["A","B","C","D","E"]])
=> [[1,"A"], [2,"B"], [3,"C"], [4,"D"], [5,"E"]]
(This works in OpenSCAD2 because [1:5] is operationally equivalent to [1,2,3,4,5] in all contexts.)
We could invent a new syntax for parallel loops in OpenSCAD. Maybe this would work:
for (x = xlist | y = ylist) ...
Or we could just use transpose. Because this also works:
for ([x,y] = transpose(xlist, ylist)) ...
- loop terminatoin with while, or until, or just one and use not operator
for the other - for readability
[ for (x=1,2,3,4,5,6], while prime(x)) [ x, x*x] ]
returning list of [x,x^2] until first non-prime encountered.
I'm not sure about the , before the while, for reasons previously discussed. And the argument of 'while' should be parenthesized, for consistency with the rest of OpenSCAD syntax. So maybe this:
[ for (x=[1,2,3,4,5,6] | while(prime(x))) [x, x*x] ]
In functional programming, you'd implement this using take_while, which returns the longest prefix of a sequence that matches a predicate. In OpenSCAD2, the code would look like this:
[ for (x=[1,2,3,4,5,6] >> take_while(prime)) [x, x*x] ]
It's not much worse, and no additional syntax is added to the language, since take_while is a library function. There is also a drop_while function which discards initial elements that match the predicate, and I'm not sure if this is expressible using the LOOP macro.
- define more internal loop variables. inner scope only
[for (x=1,2,3,4,5,6], start=12) x*start ]
But we already have syntax for this.
[for (x=[1,2,3,4,5,6]) let (start=12) x*start ]
- I can't imagine how to do if-then constructs and collect inside the
existing syntax.
I had the same problem, reading your previous post. You wrote:
- using conditionals within the loop (as an operator, not a regular if
statement)
[for x below 10
if odd(x)
collect x into odds
else
collect x into evens
finally [odds, evens] ]
gives [[1 3 5 7 9] [0 2 4 6 8]]
In functional programming, this would be done using 'partition'.
partition(odd)([0:9])
Here is the non-recursive definition:
partition(f)(s) =
let (p1 = [for (x=s) if (f(x)) x],
p2 = [for (x=s) if (!f(x)) x])
[p1,p2];
In summary, my counter-proposal is to add structured assignment to OpenSCAD2, and then provide library functions to make writing loops and list processing more convenient.
I'll admit I have a bias for the functional style of programming, since I'm used to that, and I don't have any experience using the Lisp LOOP macros. And I admit there's a learning curve; you need a cookbook to learn some of the common programming patterns. I'll be interested to know what other people think.
One thing to note: In my OpenSCAD2 list library, most functions have double argument lists, with the list in the second or outmost argument list. This allows you to chain together list operations the same way you can chain together geometric transforms in OpenSCAD.
OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
nop head,
Thank you for the link.
I though there was tricky stuff, but solution is simple and elegant.
Jean-Paul
N1JPL
> On Jan 7, 2016, at 1:19 PM, nop head <nop.head@gmail.com> wrote:
>
> http://www.thingiverse.com/thing:239158
>
> On 7 January 2016 at 17:58, Jean-Paul Louis <louijp@yahoo.com> wrote:
> How do you describe a Moebius ring in OpenScad?
>
> Just curious,
> Jean-Paul
> N1JPL
>
> > On Jan 7, 2016, at 12:40 PM, nop head <nop.head@gmail.com> wrote:
> >
> > >And I admit there's a learning curve; you need a cookbook to learn some of the common programming patterns. I'll be interested to know what other people think.
> >
> > I think we just don't need such language complexity to describe 3D objects.
> >
> > It there any 3D object that cannot be described by OpenScad as it stands now?
> >
> > I am far more interested in OpenScad producing numerically accurate results and getting faster than being able to accept more programming paradigms. Sure some things get expressed more succinctly but at the expense of being more cryptic and bringing the need to read up on several languages to understand the code.
> >
> > I only started this thread to propose a way of not having to create nested lists just to flatten them. It seems to have lead to a Frankenstein's monster of a loop syntax that combines bits from everybody's favourite languages.
> >
> > Fiddling about with the syntax of the source code when fundamental things like union and rotate don't produce the correct results seems pointless to me.
> >
> >
> > On 7 January 2016 at 17:03, doug moen <doug@moens.org> wrote:
> > Sorry about the negative tone of my response. I did get frustrated by your original post, though. It's written in a pseudo-code, somewhere between Lisp and OpenSCAD. Since you weren't proposing that as the final syntax, I tried to translate your examples into OpenSCAD syntax, and what I finally ended up with were list comprehensions + Haskell-inspired list functions. Which is not what you were proposing.
> >
> > The entire Genera OS was written in lisp on a lisp machine. Yes an entire OS in Lisp. It remains the best development system I worked on.
> >
> > I never had an opportunity to use a Lisp Machine. I'm a student of computer history, though, and it's legendary. I'd like to spend time playing with this software so that I can understand why it's the best development system ever. Maybe somebody will resurrect this in an emulator one day.
> >
> > - add structured assignment:
> > [for ([a b]=[[1 2] [3 4] [5 6]]) [b a] ]
> > giving [[2 1] [4 3] [6 5]]
> >
> > I completely agree with adding structured assignment. I've been writing OpenSCAD2 code as part of a project, and I've added structured assignment, because it is so convenient for destructuring 2-vectors and 3-vectors in the style of geometric programming I'm playing with.
> >
> > Your example is pseudo code, so I'll translate to OpenSCAD syntax:
> > [ for ([a,b] = [[1,2], [3,4], [5,6]]) [b,a] ]
> >
> > In my version of structured assignment,
> > [a,b] = x
> > produces a run-time error if x is not a list of length 2. The syntax works in definitions, function formal parameter lists, and for statements.
> >
> > - add from
> > [ for (i=[1:10], j from 2) i*j ]
> > where j starts at 2 and counts up. the i variable sets the termination of
> > the loop
> > from could not appear on its own without a termination clause.
> >
> > You intend this to mean 2 loops running in parallel, instead of being nested. In OpenSCAD, the syntax
> > for (i=[1:10], j=[2:11]) ...
> > looks like it would be good syntax for two parallel loops, but it's not. It actually means nested loops, same as
> > for (i=[1:10]) for (j=[2:11]) ...
> > So I think there is a backward compatibility problem with expressing parallel loops in the way you suggest. The problem is in violating the expectations of OpenSCAD programmers, who expect 'for (i=.., j=..)' to mean nested loops.
> >
> > Your previous post had several examples of parallel loops. Here's one:
> >
> > - Create pairs
> > [for x = [1:5]
> > for y = ["A","B","C","D","E"]
> > do [x y] ]
> > giving [[1 A] [2 B] [3 C] [4 D] [5 E]]
> >
> > This is more pseudo-code. The problem is that if we convert this into OpenSCAD syntax, we get nested loops:
> >
> > [for (x = [1:5])
> > for (y = ["A","B","C","D","E"])
> > [x,y]]
> > and the result is a list of 25 pairs.
> >
> > In functional style programming, you would create the pairs by calling transpose, which in OpenSCAD is matrix transpose from linear algebra.
> > transpose([[1:5], ["A","B","C","D","E"]])
> > => [[1,"A"], [2,"B"], [3,"C"], [4,"D"], [5,"E"]]
> >
> > (This works in OpenSCAD2 because [1:5] is operationally equivalent to [1,2,3,4,5] in all contexts.)
> >
> > We could invent a new syntax for parallel loops in OpenSCAD. Maybe this would work:
> > for (x = xlist | y = ylist) ...
> >
> > Or we could just use transpose. Because this also works:
> > for ([x,y] = transpose(xlist, ylist)) ...
> >
> > - loop terminatoin with while, or until, or just one and use not operator
> > for the other - for readability
> > [ for (x=1,2,3,4,5,6], while prime(x)) [ x, x*x] ]
> > returning list of [x,x^2] until first non-prime encountered.
> >
> > I'm not sure about the , before the while, for reasons previously discussed. And the argument of 'while' should be parenthesized, for consistency with the rest of OpenSCAD syntax. So maybe this:
> >
> > [ for (x=[1,2,3,4,5,6] | while(prime(x))) [x, x*x] ]
> >
> > In functional programming, you'd implement this using take_while, which returns the longest prefix of a sequence that matches a predicate. In OpenSCAD2, the code would look like this:
> >
> > [ for (x=[1,2,3,4,5,6] >> take_while(prime)) [x, x*x] ]
> >
> > It's not much worse, and no additional syntax is added to the language, since take_while is a library function. There is also a drop_while function which discards initial elements that match the predicate, and I'm not sure if this is expressible using the LOOP macro.
> >
> > - define more internal loop variables. inner scope only
> > [for (x=1,2,3,4,5,6], start=12) x*start ]
> >
> > But we already have syntax for this.
> > [for (x=[1,2,3,4,5,6]) let (start=12) x*start ]
> >
> > - I can't imagine how to do if-then constructs and collect inside the
> > existing syntax.
> >
> > I had the same problem, reading your previous post. You wrote:
> >
> > - using conditionals within the loop (as an operator, not a regular if
> > statement)
> > [for x below 10
> > if odd(x)
> > collect x into odds
> > else
> > collect x into evens
> > finally [odds, evens] ]
> > gives [[1 3 5 7 9] [0 2 4 6 8]]
> >
> > In functional programming, this would be done using 'partition'.
> > partition(odd)([0:9])
> >
> > Here is the non-recursive definition:
> > partition(f)(s) =
> > let (p1 = [for (x=s) if (f(x)) x],
> > p2 = [for (x=s) if (!f(x)) x])
> > [p1,p2];
> >
> > In summary, my counter-proposal is to add structured assignment to OpenSCAD2, and then provide library functions to make writing loops and list processing more convenient.
> >
> > I'll admit I have a bias for the functional style of programming, since I'm used to that, and I don't have any experience using the Lisp LOOP macros. And I admit there's a learning curve; you need a cookbook to learn some of the common programming patterns. I'll be interested to know what other people think.
> >
> > One thing to note: In my OpenSCAD2 list library, most functions have double argument lists, with the list in the second or outmost argument list. This allows you to chain together list operations the same way you can chain together geometric transforms in OpenSCAD.
> >
> > _______________________________________________
> > OpenSCAD mailing list
> > Discuss@lists.openscad.org
> > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
> >
> >
> > _______________________________________________
> > OpenSCAD mailing list
> > Discuss@lists.openscad.org
> > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
>
>
> _______________________________________________
> OpenSCAD mailing list
> Discuss@lists.openscad.org
> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
>
> _______________________________________________
> OpenSCAD mailing list
> Discuss@lists.openscad.org
> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
MK
Marius Kintel
Fri, Jan 8, 2016 1:44 AM
On Jan 7, 2016, at 16:56 PM, MichaelAtOz oz.at.michael@gmail.com wrote:
Agreed, but transforming the language into something that can only be read
my Tibetan monks will solve your future maintenance issue.
Definitely. One rule I like to follow is “make the easy stuff easy and the difficult stuff possible”. I think having good list comprehensions belong in the second half of that sentence.
Also note that in order to make more of the possible stuff easy in OpenSCAD2, we really need to clean up some of the language, and while at it make it more orthogonal, with more separation of concerns.
Some (or most?) of this will involve syntax nitpicking, which is really only interesting to a handful of people. I want to eventually make it easier for new users to participate in a discussion forum without having to click through a lot of internal and complex discussions. Ideas for how to achieve that would be welcome :)
-Marius
> On Jan 7, 2016, at 16:56 PM, MichaelAtOz <oz.at.michael@gmail.com> wrote:
>
> Agreed, but transforming the language into something that can only be read
> my Tibetan monks will solve your future maintenance issue.
>
Definitely. One rule I like to follow is “make the easy stuff easy and the difficult stuff possible”. I think having good list comprehensions belong in the second half of that sentence.
Also note that in order to make more of the possible stuff easy in OpenSCAD2, we really need to clean up some of the language, and while at it make it more orthogonal, with more separation of concerns.
Some (or most?) of this will involve syntax nitpicking, which is really only interesting to a handful of people. I want to eventually make it easier for new users to participate in a discussion forum without having to click through a lot of internal and complex discussions. Ideas for how to achieve that would be welcome :)
-Marius
M
MichaelAtOz
Fri, Jan 8, 2016 4:50 AM
I want to eventually make it easier for new users to participate in a
discussion forum without having to click through a lot of internal and
complex discussions. Ideas for how to achieve that would be welcome :)
Nabble can have sub forum (fora?), you could have an 'OpenSCAD Language
Development' sub-forum, it appears that a sub-forum can have a different
mailing-list archive, but I can't test as I don't have a mailing-list.
Where is lists.openscad.org hosted?
Newly minted 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/List-comprehensions-tp15321p15562.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
kintel wrote
> I want to eventually make it easier for new users to participate in a
> discussion forum without having to click through a lot of internal and
> complex discussions. Ideas for how to achieve that would be welcome :)
Nabble can have sub forum (fora?), you could have an 'OpenSCAD Language
Development' sub-forum, it appears that a sub-forum can have a different
mailing-list archive, but I can't test as I don't have a mailing-list.
Where is lists.openscad.org hosted?
-----
Newly minted 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/List-comprehensions-tp15321p15562.html
Sent from the OpenSCAD mailing list archive at Nabble.com.