DM
                 
                
                                            Doug Moen
                                    
             
            
                Tue, Oct 1, 2019 3:50 AM
            
         
                            
    
    
    
    [...] It's not something very high at my personal wish-list at
this point [...]
 
     
This is perhaps the most highly desired feature request I have. Though it's unclear to me how it would be handled in a function context, since let() only sets the value of a variable for the parts of a function subordinate to the let(). Also, mutable variables become much more useful with a while() conditional loop statement.
 
     
     
                
>>> 1. Mutable variables.
>> 
>> [...] It's not something very high at my personal wish-list at
>> this point [...]
> 
> This is perhaps the most highly desired feature request I have. Though it's unclear to me how it would be handled in a function context, since `let()` only sets the value of a variable for the parts of a function subordinate to the `let()`. Also, mutable variables become much more useful with a `while()` conditional loop statement.
It would be possible to borrow the syntax that Curv uses for mutable variables. It would fit in to OpenSCAD with only minor changes. You can use assignment statements and while statements inside a function, or inside a list comprehension.
https://github.com/curv3d/curv/blob/master/docs/language/Statements.rst
        
    
    
             
    
        
            
                
                    
                    NH
                 
                
                                            nop head
                                    
             
            
                Tue, Oct 1, 2019 7:00 AM
            
         
                            Doesn't the current C like for(..;..;)  syntax effectively allow a while
loop and mutable variables in the loop?
On Tue, 1 Oct 2019 at 04:51, Doug Moen doug@moens.org wrote:
 
    
- Mutable variables.
 
[...] It's not something very high at my personal wish-list at
this point [...]
This is perhaps the most highly desired feature request I have. Though
it's unclear to me how it would be handled in a function context, since
let() only sets the value of a variable for the parts of a function
subordinate to the let().  Also, mutable variables become much more
useful with a while() conditional loop statement.
It would be possible to borrow the syntax that Curv uses for mutable
variables. It would fit in to OpenSCAD with only minor changes. You can use
assignment statements and while statements inside a function, or inside a
list comprehension.
https://github.com/curv3d/curv/blob/master/docs/language/Statements.rst
OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
 
    
     
                Doesn't the current C like for(..;..;)  syntax effectively allow a while
loop and mutable variables in the loop?
On Tue, 1 Oct 2019 at 04:51, Doug Moen <doug@moens.org> wrote:
>
> 1. Mutable variables.
>
>
> [...] It's not something very high at my personal wish-list at
> this point [...]
>
>
> This is perhaps the most highly desired feature request I have. Though
> it's unclear to me how it would be handled in a function context, since
> `let()` only sets the value of a variable for the parts of a function
> subordinate to the `let()`.  Also, mutable variables become much more
> useful with a `while()` conditional loop statement.
>
>
> It would be possible to borrow the syntax that Curv uses for mutable
> variables. It would fit in to OpenSCAD with only minor changes. You can use
> assignment statements and while statements inside a function, or inside a
> list comprehension.
>
> https://github.com/curv3d/curv/blob/master/docs/language/Statements.rst
> _______________________________________________
> OpenSCAD mailing list
> Discuss@lists.openscad.org
> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
>
        
    
    
             
    
        
            
                
                    
                    NH
                 
                
                                            nop head
                                    
             
            
                Tue, Oct 1, 2019 7:02 AM
            
         
                            People say it is hard to write algorithms without mutable variables. Does
that mean it is hard to write algorithms in Haskell or does that have them
as well?
On Tue, 1 Oct 2019 at 08:00, nop head nop.head@gmail.com wrote:
 
    
Doesn't the current C like for(..;..;)  syntax effectively allow a while
loop and mutable variables in the loop?
On Tue, 1 Oct 2019 at 04:51, Doug Moen doug@moens.org wrote:
 
    
- Mutable variables.
 
[...] It's not something very high at my personal wish-list at
this point [...]
This is perhaps the most highly desired feature request I have. Though
it's unclear to me how it would be handled in a function context, since
let() only sets the value of a variable for the parts of a function
subordinate to the let().  Also, mutable variables become much more
useful with a while() conditional loop statement.
It would be possible to borrow the syntax that Curv uses for mutable
variables. It would fit in to OpenSCAD with only minor changes. You can use
assignment statements and while statements inside a function, or inside a
list comprehension.
https://github.com/curv3d/curv/blob/master/docs/language/Statements.rst
OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
 
    
     
     
                People say it is hard to write algorithms without mutable variables. Does
that mean it is hard to write algorithms in Haskell or does that have them
as well?
On Tue, 1 Oct 2019 at 08:00, nop head <nop.head@gmail.com> wrote:
> Doesn't the current C like for(..;..;)  syntax effectively allow a while
> loop and mutable variables in the loop?
>
> On Tue, 1 Oct 2019 at 04:51, Doug Moen <doug@moens.org> wrote:
>
>>
>> 1. Mutable variables.
>>
>>
>> [...] It's not something very high at my personal wish-list at
>> this point [...]
>>
>>
>> This is perhaps the most highly desired feature request I have. Though
>> it's unclear to me how it would be handled in a function context, since
>> `let()` only sets the value of a variable for the parts of a function
>> subordinate to the `let()`.  Also, mutable variables become much more
>> useful with a `while()` conditional loop statement.
>>
>>
>> It would be possible to borrow the syntax that Curv uses for mutable
>> variables. It would fit in to OpenSCAD with only minor changes. You can use
>> assignment statements and while statements inside a function, or inside a
>> list comprehension.
>>
>> https://github.com/curv3d/curv/blob/master/docs/language/Statements.rst
>> _______________________________________________
>> OpenSCAD mailing list
>> Discuss@lists.openscad.org
>> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
>>
>
        
    
    
             
    
        
            
                
                    
                    R
                 
                
                                            Robin2
                                    
             
            
                Tue, Oct 1, 2019 8:08 AM
            
         
                            
    
When I first go into 3D printing I looked around as many of the CAD like
offering as I could try, I even considered commercial software (but most
were out of my $'range).
I found the 'traditional' mouse driven CAD cumbersome, if you want
accuracy
you have to do various mousing-about then click on things to open
parameters
then type in values etc.
Then I came across OpenSCAD, as I had a programming background it seemed
good, you just type out your specification for the thing, press F5 and
there
it is. (after debugging...)
 
    This echoes my own experience perfectly.
But then I got tired of all the typing and realised that I can have the best
of both worlds. I don't want to discourage the people who prefer to type in
their code. But I think that a front-end that allows the lazy (like me) to
avoid it would be a benefit.
...R
--
Sent from: http://forum.openscad.org/
 
     
                MichaelAtOz wrote
> When I first go into 3D printing I looked around as many of the CAD like
> offering as I could try, I even considered commercial software (but most
> were out of my $'range).
> I found the 'traditional' mouse driven CAD cumbersome, if you want
> accuracy
> you have to do various mousing-about then click on things to open
> parameters
> then type in values etc.
> 
> Then I came across OpenSCAD, as I had a programming background it seemed
> good, you just type out your specification for the thing, press F5 and
> there
> it is. (after debugging...)
This echoes my own experience perfectly.
But then I got tired of all the typing and realised that I can have the best
of both worlds. I don't want to discourage the people who prefer to type in
their code. But I think that a front-end that allows the lazy (like me) to
avoid it would be a benefit.
...R
--
Sent from: http://forum.openscad.org/
        
    
    
             
    
        
            
                
                    
                    DM
                 
                
                                            Doug Moen
                                    
             
            
                Tue, Oct 1, 2019 1:30 PM
            
         
                            On Tue, Oct 1, 2019, at 3:00 AM, nop head wrote:
 
    
Doesn't the current C like for(..;..;) syntax effectively allow a while loop and mutable variables in the loop?
 
    If we add mutable variables, an assignment statement, and a while loop to OpenSCAD, then we enable a rich set of coding patterns:
- conditional assignment statements
 
- assignments inside a 
for or while statement which modify an accumulator variable
And these patterns can be nested and sequenced. 
The C-like for (;;) syntax is only available inside list comprehensions, where it is used for generating a sequence of list elements. I do not think that list comprehensions are in any way a replacement for general imperative programming features.
Here is a Curv function that I used for generating a shape based on voronoi diagrams. I think it would be quite painful to translate this into OpenSCAD using tail recursion and list comprehensions. I ported this code from another language. A major benefit of imperative programming in Curv is that I could port the code trivially, doing a line-for-line transliteration, without wholesale restructuring of the code to use entirely different coding patterns.
// input: 2D coordinate, output: distance to cell border
voronoi x =
let
n = floor(x - 1.5);
f = x - n;
md = 8;
in do
// first pass: distance to cell centre
local mr = [0,0];
for (j in 0 .. 3)
for (i in 0 .. 3) (
local g = [i,j];
local o = hash2x2(n + g);
local r = g + o - f;
local d = dot(r,r);
if (d < md) (
md := d;
mr := r;
);
);
// second pass: distance to border
md := 8.0;
for (j in 0 .. 3)
for (i in 0 .. 3) (
local g = [i,j];
local o = hash2x2( n + g );
local r = g + o - f;
if (dot(mr-r,mr-r)>EPSILON) // skip the same cell
md := smooth_min(md, dot(0.5*(mr+r), normalize(r-mr)),.2);
);
in md;
 
     
                On Tue, Oct 1, 2019, at 3:00 AM, nop head wrote:
> Doesn't the current C like for(..;..;) syntax effectively allow a while loop and mutable variables in the loop?
If we add mutable variables, an assignment statement, and a while loop to OpenSCAD, then we enable a rich set of coding patterns:
* conditional assignment statements
* assignments inside a `for` or `while` statement which modify an accumulator variable
And these patterns can be nested and sequenced.
The C-like for (;;) syntax is only available inside list comprehensions, where it is used for generating a sequence of list elements. I do not think that list comprehensions are in any way a replacement for general imperative programming features.
Here is a Curv function that I used for generating a shape based on voronoi diagrams. I think it would be quite painful to translate this into OpenSCAD using tail recursion and list comprehensions. I ported this code from another language. A major benefit of imperative programming in Curv is that I could port the code trivially, doing a line-for-line transliteration, without wholesale restructuring of the code to use entirely different coding patterns.
// input: 2D coordinate, output: distance to cell border
voronoi x =
 let
 n = floor(x - 1.5);
 f = x - n;
 md = 8;
 in do
 // first pass: distance to cell centre
 local mr = [0,0];
 for (j in 0 .. 3)
 for (i in 0 .. 3) (
 local g = [i,j];
 local o = hash2x2(n + g);
 local r = g + o - f;
 local d = dot(r,r);
 if (d < md) (
 md := d;
 mr := r;
 );
 );
 // second pass: distance to border
 md := 8.0;
 for (j in 0 .. 3)
 for (i in 0 .. 3) (
 local g = [i,j];
 local o = hash2x2( n + g );
 local r = g + o - f;
 if (dot(mr-r,mr-r)>EPSILON) // skip the same cell
 md := smooth_min(md, dot(0.5*(mr+r), normalize(r-mr)),.2);
 );
 in md;
        
    
    
             
    
        
            
                
                    
                    DM
                 
                
                                            Doug Moen
                                    
             
            
                Tue, Oct 1, 2019 3:08 PM
            
         
                            On Tue, Oct 1, 2019, at 3:02 AM, nop head wrote:
 
    
People say it is hard to write algorithms without mutable variables. Does that mean it is hard to write algorithms in Haskell or does that have them as well?
 
    Haskell and OpenSCAD are at opposite ends of the spectrum, in terms of expressive power. It's true that Haskell and OpenSCAD are both declarative languages with immutable variables, but aside from that, they are totally different.
Haskell has many features and idioms which are not available/not possible in OpenSCAD, which are used as an alternative to mutable variables.
- 
Haskell has generalized tail recursion optimization. The corresponding feature in OpenSCAD is restricted to one specific code pattern, and only works for self-recursive functions, not mutually recursive functions.
 
- 
Haskell has combinators, which are functions that take functions as arguments, and return functions as results. There is a large standard library of combinators, which are used as functional control structures, and replace most uses of tail recursion. These library combinators use tail recursion internally, and encapsulate high level patterns of tail recursion. Tail recursion is considered to be a "low level" coding pattern, which you only resort to when necessary.
 
This style of programming will become possible in OpenSCAD once function values are added to the language. To fully support this style of programming, we would want better tail recursion support, and a very terse syntax for anonymous function literals.
- 
Haskell has lazy data structures. Notably, it has lazy lists. A lazy list is a potentially infinite list, in which list elements are only computed the first time you access them, then the element values are cached. Using lazy lists, you can decompose an imperative loop into two pieces: the piece that generates the sequence of elements is encapsulated as a lazy list. The piece that consumes the sequence of elements is now separate. This enables a new kind of modularity and a new style of programming.
 
- 
Haskell has monads, which are a generalization of sequentially executed statements in imperative programming. In OpenSCAD, you can use sequences of if statements and for statements at the top level, or inside a module, to construct an "implicit union" of shapes. In Haskell terminology, we would call that the "union monad". In OpenSCAD, you can also use this same statement syntax inside a list comprehension, to construct a sequence of list values. This corresponds to the List Monad in Haskell. Haskell has many other monads, and it's easy to define new ones.
 
One of the things that originally impressed me about OpenSCAD is the fact that it has monads (which are declarative) dressed up to look exactly like C statements and control structures (which are imperative). In Curv, I've created something that is essentially a "mutable variable monad". It looks just like imperative programming, but it is syntactic sugar for something that is actually declarative and referentially transparent.
Haskell monads are notoriously difficult to learn (due to the way they are presented). In F#, the same feature is called "computation expressions". The syntax and presentation of computation expressions is much more friendly to imperative programmers. In F#, the "list monad" is called the "sequence builder", and F# sequence expressions are very similar to OpenSCAD list comprehensions, except that there are more statement types, including a "while" statement.
- In imperative programming languages, you use mutable variables to incrementally build up a compound data structure. You can assign an individual component of an array using 
a[i] = newvalue, and this is an efficient operation. Haskell has functional data structures, which support efficient incremental update without mutation, and Haskell has an "optics" library for efficiently constructing and composing get and set operations on individual elements of a large data structure. Think of optics as a declarative query language. 
I think that function values are an essential programming feature, and they will allow us to cherry pick some of the easiest to understand idioms from Haskell. But I also think that imperative style programming idioms are easier for the OpenSCAD community than the corresponding Haskell idioms that are used for doing the same job.
 
     
                On Tue, Oct 1, 2019, at 3:02 AM, nop head wrote:
> People say it is hard to write algorithms without mutable variables. Does that mean it is hard to write algorithms in Haskell or does that have them as well?
Haskell and OpenSCAD are at opposite ends of the spectrum, in terms of expressive power. It's true that Haskell and OpenSCAD are both declarative languages with immutable variables, but aside from that, they are totally different.
Haskell has many features and idioms which are not available/not possible in OpenSCAD, which are used as an alternative to mutable variables.
0. Haskell has generalized tail recursion optimization. The corresponding feature in OpenSCAD is restricted to one specific code pattern, and only works for self-recursive functions, not mutually recursive functions.
1. Haskell has combinators, which are functions that take functions as arguments, and return functions as results. There is a large standard library of combinators, which are used as functional control structures, and replace most uses of tail recursion. These library combinators use tail recursion internally, and encapsulate high level patterns of tail recursion. Tail recursion is considered to be a "low level" coding pattern, which you only resort to when necessary.
This style of programming will become possible in OpenSCAD once function values are added to the language. To fully support this style of programming, we would want better tail recursion support, and a very terse syntax for anonymous function literals.
2. Haskell has lazy data structures. Notably, it has lazy lists. A lazy list is a potentially infinite list, in which list elements are only computed the first time you access them, then the element values are cached. Using lazy lists, you can decompose an imperative loop into two pieces: the piece that generates the sequence of elements is encapsulated as a lazy list. The piece that consumes the sequence of elements is now separate. This enables a new kind of modularity and a new style of programming.
3. Haskell has monads, which are a generalization of sequentially executed statements in imperative programming. In OpenSCAD, you can use sequences of if statements and for statements at the top level, or inside a module, to construct an "implicit union" of shapes. In Haskell terminology, we would call that the "union monad". In OpenSCAD, you can also use this same statement syntax inside a list comprehension, to construct a sequence of list values. This corresponds to the List Monad in Haskell. Haskell has many other monads, and it's easy to define new ones.
One of the things that originally impressed me about OpenSCAD is the fact that it has monads (which are declarative) dressed up to look exactly like C statements and control structures (which are imperative). In Curv, I've created something that is essentially a "mutable variable monad". It looks just like imperative programming, but it is syntactic sugar for something that is actually declarative and referentially transparent.
Haskell monads are notoriously difficult to learn (due to the way they are presented). In F#, the same feature is called "computation expressions". The syntax and presentation of computation expressions is much more friendly to imperative programmers. In F#, the "list monad" is called the "sequence builder", and F# sequence expressions are very similar to OpenSCAD list comprehensions, except that there are more statement types, including a "while" statement.
4. In imperative programming languages, you use mutable variables to incrementally build up a compound data structure. You can assign an individual component of an array using `a[i] = newvalue`, and this is an efficient operation. Haskell has functional data structures, which support efficient incremental update without mutation, and Haskell has an "optics" library for efficiently constructing and composing get and set operations on individual elements of a large data structure. Think of optics as a declarative query language.
I think that function values are an essential programming feature, and they will allow us to cherry pick some of the easiest to understand idioms from Haskell. But I also think that imperative style programming idioms are easier for the OpenSCAD community than the corresponding Haskell idioms that are used for doing the same job.
        
    
    
             
    
        
            
                
                    
                    NH
                 
                
                                            nop head
                                    
             
            
                Tue, Oct 1, 2019 3:41 PM
            
         
                            Thanks for the detailed explanation.  I never program anything complicated
enough in OpenSCAD to need anything mutable variables.
On Tue, 1 Oct 2019 at 16:09, Doug Moen doug@moens.org wrote:
 
    
On Tue, Oct 1, 2019, at 3:02 AM, nop head wrote:
People say it is hard to write algorithms without mutable variables. Does
that mean it is hard to write algorithms in Haskell or does that have them
as well?
Haskell and OpenSCAD are at opposite ends of the spectrum, in terms of
expressive power. It's true that Haskell and OpenSCAD are both declarative
languages with immutable variables, but aside from that, they are totally
different.
Haskell has many features and idioms which are not available/not possible
in OpenSCAD, which are used as an alternative to mutable variables.
- 
Haskell has generalized tail recursion optimization. The corresponding
feature in OpenSCAD is restricted to one specific code pattern, and only
works for self-recursive functions, not mutually recursive functions.
 
- 
Haskell has combinators, which are functions that take functions as
arguments, and return functions as results. There is a large standard
library of combinators, which are used as functional control structures,
and replace most uses of tail recursion. These library combinators use tail
recursion internally, and encapsulate high level patterns of tail
recursion. Tail recursion is considered to be a "low level" coding pattern,
which you only resort to when necessary.
 
This style of programming will become possible in OpenSCAD once function
values are added to the language. To fully support this style of
programming, we would want better tail recursion support, and a very terse
syntax for anonymous function literals.
- 
Haskell has lazy data structures. Notably, it has lazy lists. A lazy
list is a potentially infinite list, in which list elements are only
computed the first time you access them, then the element values are
cached. Using lazy lists, you can decompose an imperative loop into two
pieces: the piece that generates the sequence of elements is encapsulated
as a lazy list. The piece that consumes the sequence of elements is now
separate. This enables a new kind of modularity and a new style of
programming.
 
- 
Haskell has monads, which are a generalization of sequentially executed
statements in imperative programming. In OpenSCAD, you can use sequences of
if statements and for statements at the top level, or inside a module, to
construct an "implicit union" of shapes. In Haskell terminology, we would
call that the "union monad". In OpenSCAD, you can also use this same
statement syntax inside a list comprehension, to construct a sequence of
list values. This corresponds to the List Monad in Haskell. Haskell has
many other monads, and it's easy to define new ones.
 
One of the things that originally impressed me about OpenSCAD is the fact
that it has monads (which are declarative) dressed up to look exactly like
C statements and control structures (which are imperative). In Curv, I've
created something that is essentially a "mutable variable monad". It looks
just like imperative programming, but it is syntactic sugar for something
that is actually declarative and referentially transparent.
Haskell monads are notoriously difficult to learn (due to the way they are
presented). In F#, the same feature is called "computation expressions".
The syntax and presentation of computation expressions is much more
friendly to imperative programmers. In F#, the "list monad" is called the
"sequence builder", and F# sequence expressions are very similar to
OpenSCAD list comprehensions, except that there are more statement types,
including a "while" statement.
- In imperative programming languages, you use mutable variables to
incrementally build up a compound data structure. You can assign an
individual component of an array using a[i] = newvalue, and this is an
efficient operation. Haskell has functional data structures, which support
efficient incremental update without mutation, and Haskell has an "optics"
library for efficiently constructing and composing get and set operations
on individual elements of a large data structure. Think of optics as a
declarative query language. 
I think that function values are an essential programming feature, and
they will allow us to cherry pick some of the easiest to understand idioms
from Haskell. But I also think that imperative style programming idioms are
easier for the OpenSCAD community than the corresponding Haskell idioms
that are used for doing the same job.
OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
 
    
     
                Thanks for the detailed explanation.  I never program anything complicated
enough in OpenSCAD to need anything mutable variables.
On Tue, 1 Oct 2019 at 16:09, Doug Moen <doug@moens.org> wrote:
> On Tue, Oct 1, 2019, at 3:02 AM, nop head wrote:
>
> People say it is hard to write algorithms without mutable variables. Does
> that mean it is hard to write algorithms in Haskell or does that have them
> as well?
>
>
> Haskell and OpenSCAD are at opposite ends of the spectrum, in terms of
> expressive power. It's true that Haskell and OpenSCAD are both declarative
> languages with immutable variables, but aside from that, they are totally
> different.
>
> Haskell has many features and idioms which are not available/not possible
> in OpenSCAD, which are used as an alternative to mutable variables.
>
> 0. Haskell has generalized tail recursion optimization. The corresponding
> feature in OpenSCAD is restricted to one specific code pattern, and only
> works for self-recursive functions, not mutually recursive functions.
>
> 1. Haskell has combinators, which are functions that take functions as
> arguments, and return functions as results. There is a large standard
> library of combinators, which are used as functional control structures,
> and replace most uses of tail recursion. These library combinators use tail
> recursion internally, and encapsulate high level patterns of tail
> recursion. Tail recursion is considered to be a "low level" coding pattern,
> which you only resort to when necessary.
>
> This style of programming will become possible in OpenSCAD once function
> values are added to the language. To fully support this style of
> programming, we would want better tail recursion support, and a very terse
> syntax for anonymous function literals.
>
> 2. Haskell has lazy data structures. Notably, it has lazy lists. A lazy
> list is a potentially infinite list, in which list elements are only
> computed the first time you access them, then the element values are
> cached. Using lazy lists, you can decompose an imperative loop into two
> pieces: the piece that generates the sequence of elements is encapsulated
> as a lazy list. The piece that consumes the sequence of elements is now
> separate. This enables a new kind of modularity and a new style of
> programming.
>
> 3. Haskell has monads, which are a generalization of sequentially executed
> statements in imperative programming. In OpenSCAD, you can use sequences of
> if statements and for statements at the top level, or inside a module, to
> construct an "implicit union" of shapes. In Haskell terminology, we would
> call that the "union monad". In OpenSCAD, you can also use this same
> statement syntax inside a list comprehension, to construct a sequence of
> list values. This corresponds to the List Monad in Haskell. Haskell has
> many other monads, and it's easy to define new ones.
>
> One of the things that originally impressed me about OpenSCAD is the fact
> that it has monads (which are declarative) dressed up to look exactly like
> C statements and control structures (which are imperative). In Curv, I've
> created something that is essentially a "mutable variable monad". It looks
> just like imperative programming, but it is syntactic sugar for something
> that is actually declarative and referentially transparent.
>
> Haskell monads are notoriously difficult to learn (due to the way they are
> presented). In F#, the same feature is called "computation expressions".
> The syntax and presentation of computation expressions is much more
> friendly to imperative programmers. In F#, the "list monad" is called the
> "sequence builder", and F# sequence expressions are very similar to
> OpenSCAD list comprehensions, except that there are more statement types,
> including a "while" statement.
>
> 4. In imperative programming languages, you use mutable variables to
> incrementally build up a compound data structure. You can assign an
> individual component of an array using `a[i] = newvalue`, and this is an
> efficient operation. Haskell has functional data structures, which support
> efficient incremental update without mutation, and Haskell has an "optics"
> library for efficiently constructing and composing get and set operations
> on individual elements of a large data structure. Think of optics as a
> declarative query language.
>
> I think that function values are an essential programming feature, and
> they will allow us to cherry pick some of the easiest to understand idioms
> from Haskell. But I also think that imperative style programming idioms are
> easier for the OpenSCAD community than the corresponding Haskell idioms
> that are used for doing the same job.
> _______________________________________________
> OpenSCAD mailing list
> Discuss@lists.openscad.org
> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
>
        
    
    
             
    
        
            
                
                    
                    RP
                 
                
                                            Ronaldo Persiano
                                    
             
            
                Tue, Oct 1, 2019 4:55 PM
            
         
                            I have learned how to code without mutable variables with OpenSCAD. Most of
time. But the lack of mutable data structures is a drawback for instance to
express in OpenSCAD language efficient algorithms to triangulate a set of
points.
A terça, 1/10/2019, 16:43, nop head nop.head@gmail.com escreveu:
 
    
Thanks for the detailed explanation.  I never program anything complicated
enough in OpenSCAD to need anything mutable variables.
On Tue, 1 Oct 2019 at 16:09, Doug Moen doug@moens.org wrote:
 
    
On Tue, Oct 1, 2019, at 3:02 AM, nop head wrote:
People say it is hard to write algorithms without mutable variables. Does
that mean it is hard to write algorithms in Haskell or does that have them
as well?
Haskell and OpenSCAD are at opposite ends of the spectrum, in terms of
expressive power. It's true that Haskell and OpenSCAD are both declarative
languages with immutable variables, but aside from that, they are totally
different.
Haskell has many features and idioms which are not available/not possible
in OpenSCAD, which are used as an alternative to mutable variables.
- 
Haskell has generalized tail recursion optimization. The corresponding
feature in OpenSCAD is restricted to one specific code pattern, and only
works for self-recursive functions, not mutually recursive functions.
 
- 
Haskell has combinators, which are functions that take functions as
arguments, and return functions as results. There is a large standard
library of combinators, which are used as functional control structures,
and replace most uses of tail recursion. These library combinators use tail
recursion internally, and encapsulate high level patterns of tail
recursion. Tail recursion is considered to be a "low level" coding pattern,
which you only resort to when necessary.
 
This style of programming will become possible in OpenSCAD once function
values are added to the language. To fully support this style of
programming, we would want better tail recursion support, and a very terse
syntax for anonymous function literals.
- 
Haskell has lazy data structures. Notably, it has lazy lists. A lazy
list is a potentially infinite list, in which list elements are only
computed the first time you access them, then the element values are
cached. Using lazy lists, you can decompose an imperative loop into two
pieces: the piece that generates the sequence of elements is encapsulated
as a lazy list. The piece that consumes the sequence of elements is now
separate. This enables a new kind of modularity and a new style of
programming.
 
- 
Haskell has monads, which are a generalization of sequentially
executed statements in imperative programming. In OpenSCAD, you can use
sequences of if statements and for statements at the top level, or inside a
module, to construct an "implicit union" of shapes. In Haskell terminology,
we would call that the "union monad". In OpenSCAD, you can also use this
same statement syntax inside a list comprehension, to construct a sequence
of list values. This corresponds to the List Monad in Haskell. Haskell has
many other monads, and it's easy to define new ones.
 
One of the things that originally impressed me about OpenSCAD is the fact
that it has monads (which are declarative) dressed up to look exactly like
C statements and control structures (which are imperative). In Curv, I've
created something that is essentially a "mutable variable monad". It looks
just like imperative programming, but it is syntactic sugar for something
that is actually declarative and referentially transparent.
Haskell monads are notoriously difficult to learn (due to the way they
are presented). In F#, the same feature is called "computation
expressions". The syntax and presentation of computation expressions is
much more friendly to imperative programmers. In F#, the "list monad" is
called the "sequence builder", and F# sequence expressions are very similar
to OpenSCAD list comprehensions, except that there are more statement
types, including a "while" statement.
- In imperative programming languages, you use mutable variables to
incrementally build up a compound data structure. You can assign an
individual component of an array using a[i] = newvalue, and this is an
efficient operation. Haskell has functional data structures, which support
efficient incremental update without mutation, and Haskell has an "optics"
library for efficiently constructing and composing get and set operations
on individual elements of a large data structure. Think of optics as a
declarative query language. 
I think that function values are an essential programming feature, and
they will allow us to cherry pick some of the easiest to understand idioms
from Haskell. But I also think that imperative style programming idioms are
easier for the OpenSCAD community than the corresponding Haskell idioms
that are used for doing the same job.
OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
 
    
     
     
                I have learned how to code without mutable variables with OpenSCAD. Most of
time. But the lack of mutable data structures is a drawback for instance to
express in OpenSCAD language efficient algorithms to triangulate a set of
points.
A terça, 1/10/2019, 16:43, nop head <nop.head@gmail.com> escreveu:
> Thanks for the detailed explanation.  I never program anything complicated
> enough in OpenSCAD to need anything mutable variables.
>
> On Tue, 1 Oct 2019 at 16:09, Doug Moen <doug@moens.org> wrote:
>
>> On Tue, Oct 1, 2019, at 3:02 AM, nop head wrote:
>>
>> People say it is hard to write algorithms without mutable variables. Does
>> that mean it is hard to write algorithms in Haskell or does that have them
>> as well?
>>
>>
>> Haskell and OpenSCAD are at opposite ends of the spectrum, in terms of
>> expressive power. It's true that Haskell and OpenSCAD are both declarative
>> languages with immutable variables, but aside from that, they are totally
>> different.
>>
>> Haskell has many features and idioms which are not available/not possible
>> in OpenSCAD, which are used as an alternative to mutable variables.
>>
>> 0. Haskell has generalized tail recursion optimization. The corresponding
>> feature in OpenSCAD is restricted to one specific code pattern, and only
>> works for self-recursive functions, not mutually recursive functions.
>>
>> 1. Haskell has combinators, which are functions that take functions as
>> arguments, and return functions as results. There is a large standard
>> library of combinators, which are used as functional control structures,
>> and replace most uses of tail recursion. These library combinators use tail
>> recursion internally, and encapsulate high level patterns of tail
>> recursion. Tail recursion is considered to be a "low level" coding pattern,
>> which you only resort to when necessary.
>>
>> This style of programming will become possible in OpenSCAD once function
>> values are added to the language. To fully support this style of
>> programming, we would want better tail recursion support, and a very terse
>> syntax for anonymous function literals.
>>
>> 2. Haskell has lazy data structures. Notably, it has lazy lists. A lazy
>> list is a potentially infinite list, in which list elements are only
>> computed the first time you access them, then the element values are
>> cached. Using lazy lists, you can decompose an imperative loop into two
>> pieces: the piece that generates the sequence of elements is encapsulated
>> as a lazy list. The piece that consumes the sequence of elements is now
>> separate. This enables a new kind of modularity and a new style of
>> programming.
>>
>> 3. Haskell has monads, which are a generalization of sequentially
>> executed statements in imperative programming. In OpenSCAD, you can use
>> sequences of if statements and for statements at the top level, or inside a
>> module, to construct an "implicit union" of shapes. In Haskell terminology,
>> we would call that the "union monad". In OpenSCAD, you can also use this
>> same statement syntax inside a list comprehension, to construct a sequence
>> of list values. This corresponds to the List Monad in Haskell. Haskell has
>> many other monads, and it's easy to define new ones.
>>
>> One of the things that originally impressed me about OpenSCAD is the fact
>> that it has monads (which are declarative) dressed up to look exactly like
>> C statements and control structures (which are imperative). In Curv, I've
>> created something that is essentially a "mutable variable monad". It looks
>> just like imperative programming, but it is syntactic sugar for something
>> that is actually declarative and referentially transparent.
>>
>> Haskell monads are notoriously difficult to learn (due to the way they
>> are presented). In F#, the same feature is called "computation
>> expressions". The syntax and presentation of computation expressions is
>> much more friendly to imperative programmers. In F#, the "list monad" is
>> called the "sequence builder", and F# sequence expressions are very similar
>> to OpenSCAD list comprehensions, except that there are more statement
>> types, including a "while" statement.
>>
>> 4. In imperative programming languages, you use mutable variables to
>> incrementally build up a compound data structure. You can assign an
>> individual component of an array using `a[i] = newvalue`, and this is an
>> efficient operation. Haskell has functional data structures, which support
>> efficient incremental update without mutation, and Haskell has an "optics"
>> library for efficiently constructing and composing get and set operations
>> on individual elements of a large data structure. Think of optics as a
>> declarative query language.
>>
>> I think that function values are an essential programming feature, and
>> they will allow us to cherry pick some of the easiest to understand idioms
>> from Haskell. But I also think that imperative style programming idioms are
>> easier for the OpenSCAD community than the corresponding Haskell idioms
>> that are used for doing the same job.
>> _______________________________________________
>> 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
>
        
    
    
             
    
        
            
                
                    
                    RD
                 
                
                                            Revar Desmera
                                    
             
            
                Tue, Oct 1, 2019 6:16 PM
            
         
                            Just because a language is Turing Complete, does not mean it is efficient or developer friendly.
 
    
On Oct 1, 2019, at 12:04 AM, nop head nop.head@gmail.com wrote:
People say it is hard to write algorithms without mutable variables. Does that mean it is hard to write algorithms in Haskell or does that have them as well?
 
    
On Tue, 1 Oct 2019 at 08:00, nop head nop.head@gmail.com wrote:
Doesn't the current C like for(..;..;)  syntax effectively allow a while loop and mutable variables in the loop?
 
    
    
    
    
    [...] It's not something very high at my personal wish-list at
this point [...]
 
     
This is perhaps the most highly desired feature request I have. Though it's unclear to me how it would be handled in a function context, since let() only sets the value of a variable for the parts of a function subordinate to the let().  Also, mutable variables become much more useful with a while() conditional loop statement.
 
     
     
     
     
     
                Just because a language is Turing Complete, does not mean it is efficient or developer friendly. 
- Revar
> On Oct 1, 2019, at 12:04 AM, nop head <nop.head@gmail.com> wrote:
> 
> 
> People say it is hard to write algorithms without mutable variables. Does that mean it is hard to write algorithms in Haskell or does that have them as well?
> 
>> On Tue, 1 Oct 2019 at 08:00, nop head <nop.head@gmail.com> wrote:
>> Doesn't the current C like for(..;..;)  syntax effectively allow a while loop and mutable variables in the loop?
>> 
>>> On Tue, 1 Oct 2019 at 04:51, Doug Moen <doug@moens.org> wrote:
>>> 
>>>>>> 1. Mutable variables.
>>>>> 
>>>>> [...] It's not something very high at my personal wish-list at
>>>>> this point [...]
>>>> 
>>>> This is perhaps the most highly desired feature request I have. Though it's unclear to me how it would be handled in a function context, since `let()` only sets the value of a variable for the parts of a function subordinate to the `let()`.  Also, mutable variables become much more useful with a `while()` conditional loop statement.
>>> 
>>> It would be possible to borrow the syntax that Curv uses for mutable variables. It would fit in to OpenSCAD with only minor changes. You can use assignment statements and while statements inside a function, or inside a list comprehension.
>>> 
>>> https://github.com/curv3d/curv/blob/master/docs/language/Statements.rst
>>> _______________________________________________
>>> 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
        
    
    
             
    
        
            
                
                    
                    RD
                 
                
                                            Revar Desmera
                                    
             
            
                Tue, Oct 1, 2019 6:22 PM
            
         
                            Actually, it might. Slightly awkward, but it should be abusable to allow more complex algorithms. Honestly I’d forgotten that syntax existed.  Thanks.
 
    
On Oct 1, 2019, at 12:02 AM, nop head nop.head@gmail.com wrote:
Doesn't the current C like for(..;..;)  syntax effectively allow a while loop and mutable variables in the loop?
 
    
    
    
    
    [...] It's not something very high at my personal wish-list at
this point [...]
 
     
This is perhaps the most highly desired feature request I have. Though it's unclear to me how it would be handled in a function context, since let() only sets the value of a variable for the parts of a function subordinate to the let().  Also, mutable variables become much more useful with a while() conditional loop statement.
 
     
     
     
     
                Actually, it might. Slightly awkward, but it should be abusable to allow more complex algorithms. Honestly I’d forgotten that syntax existed.  Thanks. 
- Revar
> On Oct 1, 2019, at 12:02 AM, nop head <nop.head@gmail.com> wrote:
> 
> 
> Doesn't the current C like for(..;..;)  syntax effectively allow a while loop and mutable variables in the loop?
> 
>> On Tue, 1 Oct 2019 at 04:51, Doug Moen <doug@moens.org> wrote:
>> 
>>>>> 1. Mutable variables.
>>>> 
>>>> [...] It's not something very high at my personal wish-list at
>>>> this point [...]
>>> 
>>> This is perhaps the most highly desired feature request I have. Though it's unclear to me how it would be handled in a function context, since `let()` only sets the value of a variable for the parts of a function subordinate to the `let()`.  Also, mutable variables become much more useful with a `while()` conditional loop statement.
>> 
>> It would be possible to borrow the syntax that Curv uses for mutable variables. It would fit in to OpenSCAD with only minor changes. You can use assignment statements and while statements inside a function, or inside a list comprehension.
>> 
>> https://github.com/curv3d/curv/blob/master/docs/language/Statements.rst
>> _______________________________________________
>> 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