discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

let() syntax

FH
Father Horton
Fri, Dec 23, 2022 8:27 PM

From my previous post on recursion:

function recurse(i) =
let (dummy= (0 == i % 100) ? echo(i) : 0)
recurse(i+1);

The syntax of let() always confuses me. It just sort of hangs there,
attached to the statement which follows it without any necessary
connection. Is it a function? A whitespace equivalent that happens to do
something? Or what is it?

From my previous post on recursion: function recurse(i) = let (dummy= (0 == i % 100) ? echo(i) : 0) recurse(i+1); The syntax of let() always confuses me. It just sort of hangs there, attached to the statement which follows it without any necessary connection. Is it a function? A whitespace equivalent that happens to do something? Or what is it?
LM
Leonard Martin Struttmann
Fri, Dec 23, 2022 9:27 PM

As I understand it, let() allows you to define intermediate constants that
you can use later in the function.

Suppose you had a function that used sin(x) multiple times:

function myCalculation( x, y ) = sin(x) + 2 * sin(x) + 10 * y * sin(x);

It's easier (and maybe more efficient) to only calculate the sin() once:

function myCalculation( x, y ) =
sin(x) + 2 * sin(x) + 10 * y * sin(x);

On Fri, Dec 23, 2022 at 2:31 PM Father Horton fatherhorton@gmail.com
wrote:

From my previous post on recursion:

function recurse(i) =
let (dummy= (0 == i % 100) ? echo(i) : 0)
recurse(i+1);

The syntax of let() always confuses me. It just sort of hangs there,
attached to the statement which follows it without any necessary
connection. Is it a function? A whitespace equivalent that happens to do
something? Or what is it?


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

As I understand it, let() allows you to define intermediate constants that you can use later in the function. Suppose you had a function that used sin(x) multiple times: function myCalculation( x, y ) = sin(x) + 2 * sin(x) + 10 * y * sin(x); It's easier (and maybe more efficient) to only calculate the sin() once: function myCalculation( x, y ) = sin(x) + 2 * sin(x) + 10 * y * sin(x); On Fri, Dec 23, 2022 at 2:31 PM Father Horton <fatherhorton@gmail.com> wrote: > From my previous post on recursion: > > function recurse(i) = > let (dummy= (0 == i % 100) ? echo(i) : 0) > recurse(i+1); > > The syntax of let() always confuses me. It just sort of hangs there, > attached to the statement which follows it without any necessary > connection. Is it a function? A whitespace equivalent that happens to do > something? Or what is it? > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
LM
Leonard Martin Struttmann
Fri, Dec 23, 2022 9:28 PM

Leonard Martin Struttmann
3:27 PM (0 minutes ago)
Reply
to OpenSCAD
As I understand it, let() allows you to define intermediate constants that
you can use later in the function.

Suppose you had a function that used sin(x) multiple times:

function myCalculation( x, y ) = sin(x) + 2 * sin(x) + 10 * y * sin(x);

It's easier (and maybe more efficient) to only calculate the sin() once:

function myCalculation( x, y ) =
let ( sinx = sin(x) )
sinx + 2 * sinx + 10 * y * sinx;

On Fri, Dec 23, 2022 at 3:27 PM Leonard Martin Struttmann <
lenstruttmann@gmail.com> wrote:

As I understand it, let() allows you to define intermediate constants that
you can use later in the function.

Suppose you had a function that used sin(x) multiple times:

function myCalculation( x, y ) = sin(x) + 2 * sin(x) + 10 * y * sin(x);

It's easier (and maybe more efficient) to only calculate the sin() once:

function myCalculation( x, y ) =
sin(x) + 2 * sin(x) + 10 * y * sin(x);

On Fri, Dec 23, 2022 at 2:31 PM Father Horton fatherhorton@gmail.com
wrote:

From my previous post on recursion:

function recurse(i) =
let (dummy= (0 == i % 100) ? echo(i) : 0)
recurse(i+1);

The syntax of let() always confuses me. It just sort of hangs there,
attached to the statement which follows it without any necessary
connection. Is it a function? A whitespace equivalent that happens to do
something? Or what is it?


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

Leonard Martin Struttmann 3:27 PM (0 minutes ago) Reply to OpenSCAD As I understand it, let() allows you to define intermediate constants that you can use later in the function. Suppose you had a function that used sin(x) multiple times: function myCalculation( x, y ) = sin(x) + 2 * sin(x) + 10 * y * sin(x); It's easier (and maybe more efficient) to only calculate the sin() once: function myCalculation( x, y ) = let ( sinx = sin(x) ) sinx + 2 * sinx + 10 * y * sinx; On Fri, Dec 23, 2022 at 3:27 PM Leonard Martin Struttmann < lenstruttmann@gmail.com> wrote: > As I understand it, let() allows you to define intermediate constants that > you can use later in the function. > > Suppose you had a function that used sin(x) multiple times: > > function myCalculation( x, y ) = sin(x) + 2 * sin(x) + 10 * y * sin(x); > > It's easier (and maybe more efficient) to only calculate the sin() once: > > function myCalculation( x, y ) = > sin(x) + 2 * sin(x) + 10 * y * sin(x); > > > On Fri, Dec 23, 2022 at 2:31 PM Father Horton <fatherhorton@gmail.com> > wrote: > >> From my previous post on recursion: >> >> function recurse(i) = >> let (dummy= (0 == i % 100) ? echo(i) : 0) >> recurse(i+1); >> >> The syntax of let() always confuses me. It just sort of hangs there, >> attached to the statement which follows it without any necessary >> connection. Is it a function? A whitespace equivalent that happens to do >> something? Or what is it? >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org >> >
FH
Father Horton
Fri, Dec 23, 2022 9:45 PM

I understand what it does; it just seems an outlier to me in OpenSCAD
syntax.

On Fri, Dec 23, 2022 at 3:28 PM Leonard Martin Struttmann <
lenstruttmann@gmail.com> wrote:

As I understand it, let() allows you to define intermediate constants that
you can use later in the function.

Suppose you had a function that used sin(x) multiple times:

function myCalculation( x, y ) = sin(x) + 2 * sin(x) + 10 * y * sin(x);

It's easier (and maybe more efficient) to only calculate the sin() once:

function myCalculation( x, y ) =
sin(x) + 2 * sin(x) + 10 * y * sin(x);

On Fri, Dec 23, 2022 at 2:31 PM Father Horton fatherhorton@gmail.com
wrote:

From my previous post on recursion:

function recurse(i) =
let (dummy= (0 == i % 100) ? echo(i) : 0)
recurse(i+1);

The syntax of let() always confuses me. It just sort of hangs there,
attached to the statement which follows it without any necessary
connection. Is it a function? A whitespace equivalent that happens to do
something? Or what is it?


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

I understand what it does; it just seems an outlier to me in OpenSCAD syntax. On Fri, Dec 23, 2022 at 3:28 PM Leonard Martin Struttmann < lenstruttmann@gmail.com> wrote: > As I understand it, let() allows you to define intermediate constants that > you can use later in the function. > > Suppose you had a function that used sin(x) multiple times: > > function myCalculation( x, y ) = sin(x) + 2 * sin(x) + 10 * y * sin(x); > > It's easier (and maybe more efficient) to only calculate the sin() once: > > function myCalculation( x, y ) = > sin(x) + 2 * sin(x) + 10 * y * sin(x); > > > On Fri, Dec 23, 2022 at 2:31 PM Father Horton <fatherhorton@gmail.com> > wrote: > >> From my previous post on recursion: >> >> function recurse(i) = >> let (dummy= (0 == i % 100) ? echo(i) : 0) >> recurse(i+1); >> >> The syntax of let() always confuses me. It just sort of hangs there, >> attached to the statement which follows it without any necessary >> connection. Is it a function? A whitespace equivalent that happens to do >> something? Or what is it? >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org >> > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
JB
Jordan Brown
Fri, Dec 23, 2022 9:53 PM

On 12/23/2022 12:27 PM, Father Horton wrote:

function recurse(i) =
    let (dummy= (0 == i % 100) ? echo(i) : 0)
    recurse(i+1);

The syntax of let() always confuses me. It just sort of hangs there,
attached to the statement which follows it without any necessary
connection. Is it a function? A whitespace equivalent that happens to
do something? Or what is it?

Technically, it's part of the syntax of expressions.  You can use it,
echo, and assert in front of any expression (including buried inside an
expression).

Practically, it's part of a micro-language usable in expression
contexts, where the full language isn't available.

I don't like it, because it means that non-trivial functions are written
in a different language than modules are written in.

On 12/23/2022 12:27 PM, Father Horton wrote: > function recurse(i) = >     let (dummy= (0 == i % 100) ? echo(i) : 0) >     recurse(i+1); > > The syntax of let() always confuses me. It just sort of hangs there, > attached to the statement which follows it without any necessary > connection. Is it a function? A whitespace equivalent that happens to > do something? Or what is it? > Technically, it's part of the syntax of expressions.  You can use it, echo, and assert in front of any expression (including buried inside an expression). Practically, it's part of a micro-language usable in expression contexts, where the full language isn't available. I don't like it, because it means that non-trivial functions are written in a different language than modules are written in.
AM
Adrian Mariano
Fri, Dec 23, 2022 10:55 PM

Yeah, it is obnoxious that functions and modules have a different syntax.
If you want to convert code between function and module you have to change
it.

If you want a way of seeing let() as fitting in with openscad syntax, you
can interpret let() as similar to a module with a child.

On Fri, Dec 23, 2022 at 4:53 PM Jordan Brown openscad@jordan.maileater.net
wrote:

On 12/23/2022 12:27 PM, Father Horton wrote:

function recurse(i) =
let (dummy= (0 == i % 100) ? echo(i) : 0)
recurse(i+1);

The syntax of let() always confuses me. It just sort of hangs there,
attached to the statement which follows it without any necessary
connection. Is it a function? A whitespace equivalent that happens to do
something? Or what is it?

Technically, it's part of the syntax of expressions.  You can use it,
echo, and assert in front of any expression (including buried inside an
expression).

Practically, it's part of a micro-language usable in expression contexts,
where the full language isn't available.

I don't like it, because it means that non-trivial functions are written
in a different language than modules are written in.


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

Yeah, it is obnoxious that functions and modules have a different syntax. If you want to convert code between function and module you have to change it. If you want a way of seeing let() as fitting in with openscad syntax, you can interpret let() as similar to a module with a child. On Fri, Dec 23, 2022 at 4:53 PM Jordan Brown <openscad@jordan.maileater.net> wrote: > On 12/23/2022 12:27 PM, Father Horton wrote: > > function recurse(i) = > let (dummy= (0 == i % 100) ? echo(i) : 0) > recurse(i+1); > > The syntax of let() always confuses me. It just sort of hangs there, > attached to the statement which follows it without any necessary > connection. Is it a function? A whitespace equivalent that happens to do > something? Or what is it? > > > Technically, it's part of the syntax of expressions. You can use it, > echo, and assert in front of any expression (including buried inside an > expression). > > Practically, it's part of a micro-language usable in expression contexts, > where the full language isn't available. > > I don't like it, because it means that non-trivial functions are written > in a different language than modules are written in. > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
FH
Father Horton
Fri, Dec 23, 2022 11:16 PM

I checked the "make OpenSCAD normal" thread on github. Multiline functions
came up with several responses along the lines of "Well, you can do it with
let." That's true, but (as Adrian notes) "obnoxious." I'm not a C/C++ guy,
but I at least vote that if someone wanted to do it, I'd be happy.

On Fri, Dec 23, 2022 at 4:56 PM Adrian Mariano avm4@cornell.edu wrote:

Yeah, it is obnoxious that functions and modules have a different syntax.
If you want to convert code between function and module you have to change
it.

If you want a way of seeing let() as fitting in with openscad syntax, you
can interpret let() as similar to a module with a child.

On Fri, Dec 23, 2022 at 4:53 PM Jordan Brown <
openscad@jordan.maileater.net> wrote:

On 12/23/2022 12:27 PM, Father Horton wrote:

function recurse(i) =
let (dummy= (0 == i % 100) ? echo(i) : 0)
recurse(i+1);

The syntax of let() always confuses me. It just sort of hangs there,
attached to the statement which follows it without any necessary
connection. Is it a function? A whitespace equivalent that happens to do
something? Or what is it?

Technically, it's part of the syntax of expressions.  You can use it,
echo, and assert in front of any expression (including buried inside an
expression).

Practically, it's part of a micro-language usable in expression contexts,
where the full language isn't available.

I don't like it, because it means that non-trivial functions are written
in a different language than modules are written in.


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

I checked the "make OpenSCAD normal" thread on github. Multiline functions came up with several responses along the lines of "Well, you can do it with let." That's true, but (as Adrian notes) "obnoxious." I'm not a C/C++ guy, but I at least vote that if someone wanted to do it, I'd be happy. On Fri, Dec 23, 2022 at 4:56 PM Adrian Mariano <avm4@cornell.edu> wrote: > Yeah, it is obnoxious that functions and modules have a different syntax. > If you want to convert code between function and module you have to change > it. > > If you want a way of seeing let() as fitting in with openscad syntax, you > can interpret let() as similar to a module with a child. > > On Fri, Dec 23, 2022 at 4:53 PM Jordan Brown < > openscad@jordan.maileater.net> wrote: > >> On 12/23/2022 12:27 PM, Father Horton wrote: >> >> function recurse(i) = >> let (dummy= (0 == i % 100) ? echo(i) : 0) >> recurse(i+1); >> >> The syntax of let() always confuses me. It just sort of hangs there, >> attached to the statement which follows it without any necessary >> connection. Is it a function? A whitespace equivalent that happens to do >> something? Or what is it? >> >> >> Technically, it's part of the syntax of expressions. You can use it, >> echo, and assert in front of any expression (including buried inside an >> expression). >> >> Practically, it's part of a micro-language usable in expression contexts, >> where the full language isn't available. >> >> I don't like it, because it means that non-trivial functions are written >> in a different language than modules are written in. >> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org >> > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
BC
Bob Carlson
Fri, Dec 23, 2022 11:54 PM

Jordan Browns explanation is certainly correct. Perhaps another way to understand it is this. Any time you use braces { … }, inside those braces you have a new context in which you can create new names. Those names exist inside the braces only. Let allows you to create new named values that exist only inside the function expression. I use it to break down functions into smaller calculations that are easier to read. If placed in the function expression in line, they would be really hard to read. It also allow the use of echo and assert in a function.

And I do think Let is probably the ugliest, most counter intuitive feature of the language, but unfortunately necessary in the current situation.

-Bob
Tucson AZ

On Dec 23, 2022, at 13:27, Father Horton fatherhorton@gmail.com wrote:

From my previous post on recursion:

function recurse(i) =
let (dummy= (0 == i % 100) ? echo(i) : 0)
recurse(i+1);

The syntax of let() always confuses me. It just sort of hangs there, attached to the statement which follows it without any necessary connection. Is it a function? A whitespace equivalent that happens to do something? Or what is it?


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

Jordan Browns explanation is certainly correct. Perhaps another way to understand it is this. Any time you use braces { … }, inside those braces you have a new context in which you can create new names. Those names exist inside the braces only. Let allows you to create new named values that exist only inside the function expression. I use it to break down functions into smaller calculations that are easier to read. If placed in the function expression in line, they would be really hard to read. It also allow the use of echo and assert in a function. And I do think Let is probably the ugliest, most counter intuitive feature of the language, but unfortunately necessary in the current situation. -Bob Tucson AZ On Dec 23, 2022, at 13:27, Father Horton <fatherhorton@gmail.com> wrote: From my previous post on recursion: function recurse(i) = let (dummy= (0 == i % 100) ? echo(i) : 0) recurse(i+1); The syntax of let() always confuses me. It just sort of hangs there, attached to the statement which follows it without any necessary connection. Is it a function? A whitespace equivalent that happens to do something? Or what is it? _______________________________________________ OpenSCAD mailing list To unsubscribe send an email to discuss-leave@lists.openscad.org
JB
Jordan Brown
Sat, Dec 24, 2022 12:43 AM

On 12/23/2022 3:16 PM, Father Horton wrote:

I checked the "make OpenSCAD normal" thread on github. Multiline
functions came up with several responses along the lines of "Well, you
can do it with let." That's true, but (as Adrian notes) "obnoxious."
I'm not a C/C++ guy, but I at least vote that if someone wanted to do
it, I'd be happy.

Could we come up with a syntax for functions that allowed standard
OpenSCAD syntax, perhaps with a new "return()" statement?

Note that if() and for() would have only limited value, because of the
inability to get any data out of them.

For the basic "function" declaration syntax, we could have

function f(args) { ... body ... return(val); }

because standard "function" requires an "=".

For function literals we couldn't do that, or rather it would collide
with planned object syntax:

f = function (args) { ... body ... };

would collide with a current-syntax function literal that returns an
object.  (Objects are not nailed down yet, but it's very likely that {
something } is going to be an object.


I would never claim that it's pretty, but I have an experimental where
this kind of incidentally already works:

function f(x) = {( y = x*2; return = y+1; )}.return;
echo(f(2));

{(...)} is temporary syntax for a "hybrid" object literal, using a
definition where the object literal is arbitrary OpenSCAD-language, with
the elements of the object derived from the assignments and any geometry
created is brought along as an invisible part of the object that can be
added to the model later.  What I've said above has the function create
an object with members "y" and "return", and then return only the value
of the "return" member.

It's temporary syntax because that experimental also supports
JavaScript-style { a: 1, b: "hello" } object literals, and {{ ...
arbitrary OpenSCAD ...}} geometry literals that yield a geometry value. 
I wanted to have both variations available to play with.  If we go with
the "hybrid" style, I'll switch it over to being { ... arbitrary
OpenSCAD ... }.

On 12/23/2022 3:16 PM, Father Horton wrote: > I checked the "make OpenSCAD normal" thread on github. Multiline > functions came up with several responses along the lines of "Well, you > can do it with let." That's true, but (as Adrian notes) "obnoxious." > I'm not a C/C++ guy, but I at least vote that if someone wanted to do > it, I'd be happy. Could we come up with a syntax for functions that allowed standard OpenSCAD syntax, perhaps with a new "return()" statement? Note that if() and for() would have only limited value, because of the inability to get any data out of them. For the basic "function" declaration syntax, we could have function f(args) { ... body ... return(val); } because standard "function" requires an "=". For function literals we couldn't do that, or rather it would collide with planned object syntax: f = function (args) { ... body ... }; would collide with a current-syntax function literal that returns an object.  (Objects are not nailed down yet, but it's very likely that { something } is going to be an object. --- I would never claim that it's pretty, but I have an experimental where this kind of incidentally already works: function f(x) = {( y = x*2; return = y+1; )}.return; echo(f(2)); {(...)} is temporary syntax for a "hybrid" object literal, using a definition where the object literal is arbitrary OpenSCAD-language, with the elements of the object derived from the assignments and any geometry created is brought along as an invisible part of the object that can be added to the model later.  What I've said above has the function create an object with members "y" and "return", and then return only the value of the "return" member. It's temporary syntax because that experimental also supports JavaScript-style { a: 1, b: "hello" } object literals, and {{ ... arbitrary OpenSCAD ...}} geometry literals that yield a geometry value.  I wanted to have both variations available to play with.  If we go with the "hybrid" style, I'll switch it over to being { ... arbitrary OpenSCAD ... }.