JG
Jonathan Gilbert
Fri, Oct 14, 2022 12:15 AM
Here's a poser that I haven't really found a good answer to.
There seem to be a subset of function calls that work within user-defined
functions without any sort of special handling, that don't return anything,
and allow you to stack or chain without returning a value. An example might
be the use of let() or assert() here: these calls don't return a value,
maybe they impart some scoped change, maybe not, but ultimately the value
of m
is what's returned from myfunc():
function myfunc(arg) = let(m = 1 + arg ) assert(arg > 0, "arg must be
(I'm not sure what we're calling this behavior in OpenSCAD parlance;
functions that return no value? void functions? chained functions? I've no
idea. [1] below seems to imply that functions have children they can opt to
return or not, though it's probably something quite different than the
children() that are available to modules.)
Regardless of whatever term used to describe this behavior: Can we create
user functions of the same type? A function that returns nothing, that
can't be misinterpreted as a return value for another user function? I'm
thinking something along the lines of this (admittedly contrived) example:
function mylog(msg) = echo( ($preview) ? msg : undef );
function myfunc(arg) = let( m = 1 + arg ) mylog(str("using ", m, " for
whatever")) m;
g = myfunc(5);
And, if not, how would you implement this behavior? Right now, I think
the easiest way is to capture and discard the return of whatever function
you're calling within a let():
function myfunc(arg) = let( m = 1 + arg, _ = mylog(str("using ", m, " for
...but that gets a little ugly when you're doing that 8 or 10 or more than
20 times in a single let() call. Is there a better way?
--
Here's a poser that I haven't really found a good answer to.
There seem to be a subset of function calls that work within user-defined
functions without any sort of special handling, that don't return anything,
and allow you to stack or chain without returning a value. An example might
be the use of let() or assert() here: these calls don't return a value,
maybe they impart some scoped change, maybe not, but ultimately the value
of `m` is what's returned from myfunc():
function myfunc(arg) = let(m = 1 + arg ) assert(arg > 0, "arg must be
> greater than zero") m;
(I'm not sure what we're calling this behavior in OpenSCAD parlance;
functions that return no value? void functions? chained functions? I've no
idea. [1] below seems to imply that functions have children they can opt to
return or not, though it's probably something quite different than the
children() that are available to modules.)
Regardless of whatever term used to describe this behavior: Can we create
user functions of the same type? A function that returns nothing, that
can't be misinterpreted as a return value for another user function? I'm
thinking something along the lines of this (admittedly contrived) example:
function mylog(msg) = echo( ($preview) ? msg : undef );
> function myfunc(arg) = let( m = 1 + arg ) mylog(str("using ", m, " for
> whatever")) m;
> g = myfunc(5);
And, if not, how would you implement this behavior? Right now, I _think_
the easiest way is to capture and discard the return of whatever function
you're calling within a let():
function myfunc(arg) = let( m = 1 + arg, _ = mylog(str("using ", m, " for
> whatever")) ) m;
...but that gets a little ugly when you're doing that 8 or 10 or more than
20 times in a single let() call. Is there a better way?
[1]:
https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Other_Language_Features#Using_assertions_in_function
--
- Jon Gilbert
jong@jong.org / jgilbertsjc@gmail.com
AM
Adrian Mariano
Fri, Oct 14, 2022 12:26 AM
There are unfortunately several circumstances where you have to use a dummy
return value. I do this all the time:
let( blah, blah, blah, dummy=echo(something), ....)
More subtly, if you are writing a module with asserts or echoes you may
need to do the same thing:
module foo(x){
dummyA = echo(x);
dummy = assert(x>0);
y = 17/x;
....
}
Why are dummy variables necessary? Because assignments run before modules,
and if you don't use the dummy assignment, then echo and assert are
modules, so then y=17/x runs first, and you get an error if x is zero
instead of catching it with your assert. And the echo never runs because
the error happens first! With dummy variables, the assert and echo
statements become assignments and run in the obvious order, and you'll see
your echo output, and hit the assert before you try to compute with x.
On Thu, Oct 13, 2022 at 8:17 PM Jonathan Gilbert jong@jong.org wrote:
Here's a poser that I haven't really found a good answer to.
There seem to be a subset of function calls that work within user-defined
functions without any sort of special handling, that don't return anything,
and allow you to stack or chain without returning a value. An example might
be the use of let() or assert() here: these calls don't return a value,
maybe they impart some scoped change, maybe not, but ultimately the value
of m
is what's returned from myfunc():
function myfunc(arg) = let(m = 1 + arg ) assert(arg > 0, "arg must be
(I'm not sure what we're calling this behavior in OpenSCAD parlance;
functions that return no value? void functions? chained functions? I've no
idea. [1] below seems to imply that functions have children they can opt to
return or not, though it's probably something quite different than the
children() that are available to modules.)
Regardless of whatever term used to describe this behavior: Can we create
user functions of the same type? A function that returns nothing, that
can't be misinterpreted as a return value for another user function? I'm
thinking something along the lines of this (admittedly contrived) example:
function mylog(msg) = echo( ($preview) ? msg : undef );
function myfunc(arg) = let( m = 1 + arg ) mylog(str("using ", m, " for
whatever")) m;
g = myfunc(5);
And, if not, how would you implement this behavior? Right now, I think
the easiest way is to capture and discard the return of whatever function
you're calling within a let():
function myfunc(arg) = let( m = 1 + arg, _ = mylog(str("using ", m, " for
...but that gets a little ugly when you're doing that 8 or 10 or more than
20 times in a single let() call. Is there a better way?
--
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
There are unfortunately several circumstances where you have to use a dummy
return value. I do this all the time:
let( blah, blah, blah, dummy=echo(something), ....)
More subtly, if you are writing a module with asserts or echoes you may
need to do the same thing:
module foo(x){
dummyA = echo(x);
dummy = assert(x>0);
y = 17/x;
....
}
Why are dummy variables necessary? Because assignments run before modules,
and if you don't use the dummy assignment, then echo and assert are
modules, so then y=17/x runs first, and you get an error if x is zero
instead of catching it with your assert. And the echo never runs because
the error happens first! With dummy variables, the assert and echo
statements become assignments and run in the obvious order, and you'll see
your echo output, and hit the assert before you try to compute with x.
On Thu, Oct 13, 2022 at 8:17 PM Jonathan Gilbert <jong@jong.org> wrote:
> Here's a poser that I haven't really found a good answer to.
>
> There seem to be a subset of function calls that work within user-defined
> functions without any sort of special handling, that don't return anything,
> and allow you to stack or chain without returning a value. An example might
> be the use of let() or assert() here: these calls don't return a value,
> maybe they impart some scoped change, maybe not, but ultimately the value
> of `m` is what's returned from myfunc():
>
> function myfunc(arg) = let(m = 1 + arg ) assert(arg > 0, "arg must be
>> greater than zero") m;
>
>
> (I'm not sure what we're calling this behavior in OpenSCAD parlance;
> functions that return no value? void functions? chained functions? I've no
> idea. [1] below seems to imply that functions have children they can opt to
> return or not, though it's probably something quite different than the
> children() that are available to modules.)
>
> Regardless of whatever term used to describe this behavior: Can we create
> user functions of the same type? A function that returns nothing, that
> can't be misinterpreted as a return value for another user function? I'm
> thinking something along the lines of this (admittedly contrived) example:
>
> function mylog(msg) = echo( ($preview) ? msg : undef );
>> function myfunc(arg) = let( m = 1 + arg ) mylog(str("using ", m, " for
>> whatever")) m;
>> g = myfunc(5);
>
>
> And, if not, how would you implement this behavior? Right now, I _think_
> the easiest way is to capture and discard the return of whatever function
> you're calling within a let():
>
> function myfunc(arg) = let( m = 1 + arg, _ = mylog(str("using ", m, " for
>> whatever")) ) m;
>
>
> ...but that gets a little ugly when you're doing that 8 or 10 or more than
> 20 times in a single let() call. Is there a better way?
>
> [1]:
> https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Other_Language_Features#Using_assertions_in_function
>
> --
> - Jon Gilbert
> jong@jong.org / jgilbertsjc@gmail.com
> _______________________________________________
> OpenSCAD mailing list
> To unsubscribe send an email to discuss-leave@lists.openscad.org
>
LM
Leonard Martin Struttmann
Fri, Oct 14, 2022 12:33 AM
You can approximate...
function mylog(msg) = echo( ($preview) ? msg : undef );
...wth
module mylog(msg) { echo( ($preview) ? msg : undef ); }
// Example usage:
$preview = true;
mylog("HI");
On Thu, Oct 13, 2022 at 7:28 PM Adrian Mariano avm4@cornell.edu wrote:
There are unfortunately several circumstances where you have to use a
dummy return value. I do this all the time:
let( blah, blah, blah, dummy=echo(something), ....)
More subtly, if you are writing a module with asserts or echoes you may
need to do the same thing:
module foo(x){
dummyA = echo(x);
dummy = assert(x>0);
y = 17/x;
....
}
Why are dummy variables necessary? Because assignments run before
modules, and if you don't use the dummy assignment, then echo and assert
are modules, so then y=17/x runs first, and you get an error if x is zero
instead of catching it with your assert. And the echo never runs because
the error happens first! With dummy variables, the assert and echo
statements become assignments and run in the obvious order, and you'll see
your echo output, and hit the assert before you try to compute with x.
On Thu, Oct 13, 2022 at 8:17 PM Jonathan Gilbert jong@jong.org wrote:
Here's a poser that I haven't really found a good answer to.
There seem to be a subset of function calls that work within user-defined
functions without any sort of special handling, that don't return anything,
and allow you to stack or chain without returning a value. An example might
be the use of let() or assert() here: these calls don't return a value,
maybe they impart some scoped change, maybe not, but ultimately the value
of m
is what's returned from myfunc():
function myfunc(arg) = let(m = 1 + arg ) assert(arg > 0, "arg must be
(I'm not sure what we're calling this behavior in OpenSCAD parlance;
functions that return no value? void functions? chained functions? I've no
idea. [1] below seems to imply that functions have children they can opt to
return or not, though it's probably something quite different than the
children() that are available to modules.)
Regardless of whatever term used to describe this behavior: Can we create
user functions of the same type? A function that returns nothing, that
can't be misinterpreted as a return value for another user function? I'm
thinking something along the lines of this (admittedly contrived) example:
function mylog(msg) = echo( ($preview) ? msg : undef );
function myfunc(arg) = let( m = 1 + arg ) mylog(str("using ", m, " for
whatever")) m;
g = myfunc(5);
And, if not, how would you implement this behavior? Right now, I think
the easiest way is to capture and discard the return of whatever function
you're calling within a let():
function myfunc(arg) = let( m = 1 + arg, _ = mylog(str("using ", m, " for
...but that gets a little ugly when you're doing that 8 or 10 or more
than 20 times in a single let() call. Is there a better way?
--
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
You can approximate...
function mylog(msg) = echo( ($preview) ? msg : undef );
...wth
module mylog(msg) { echo( ($preview) ? msg : undef ); }
// Example usage:
$preview = true;
mylog("HI");
On Thu, Oct 13, 2022 at 7:28 PM Adrian Mariano <avm4@cornell.edu> wrote:
> There are unfortunately several circumstances where you have to use a
> dummy return value. I do this all the time:
>
> let( blah, blah, blah, dummy=echo(something), ....)
>
> More subtly, if you are writing a module with asserts or echoes you may
> need to do the same thing:
>
> module foo(x){
> dummyA = echo(x);
> dummy = assert(x>0);
> y = 17/x;
> ....
> }
>
> Why are dummy variables necessary? Because assignments run before
> modules, and if you don't use the dummy assignment, then echo and assert
> are modules, so then y=17/x runs first, and you get an error if x is zero
> instead of catching it with your assert. And the echo never runs because
> the error happens first! With dummy variables, the assert and echo
> statements become assignments and run in the obvious order, and you'll see
> your echo output, and hit the assert before you try to compute with x.
>
>
>
>
>
>
> On Thu, Oct 13, 2022 at 8:17 PM Jonathan Gilbert <jong@jong.org> wrote:
>
>> Here's a poser that I haven't really found a good answer to.
>>
>> There seem to be a subset of function calls that work within user-defined
>> functions without any sort of special handling, that don't return anything,
>> and allow you to stack or chain without returning a value. An example might
>> be the use of let() or assert() here: these calls don't return a value,
>> maybe they impart some scoped change, maybe not, but ultimately the value
>> of `m` is what's returned from myfunc():
>>
>> function myfunc(arg) = let(m = 1 + arg ) assert(arg > 0, "arg must be
>>> greater than zero") m;
>>
>>
>> (I'm not sure what we're calling this behavior in OpenSCAD parlance;
>> functions that return no value? void functions? chained functions? I've no
>> idea. [1] below seems to imply that functions have children they can opt to
>> return or not, though it's probably something quite different than the
>> children() that are available to modules.)
>>
>> Regardless of whatever term used to describe this behavior: Can we create
>> user functions of the same type? A function that returns nothing, that
>> can't be misinterpreted as a return value for another user function? I'm
>> thinking something along the lines of this (admittedly contrived) example:
>>
>> function mylog(msg) = echo( ($preview) ? msg : undef );
>>> function myfunc(arg) = let( m = 1 + arg ) mylog(str("using ", m, " for
>>> whatever")) m;
>>> g = myfunc(5);
>>
>>
>> And, if not, how would you implement this behavior? Right now, I _think_
>> the easiest way is to capture and discard the return of whatever function
>> you're calling within a let():
>>
>> function myfunc(arg) = let( m = 1 + arg, _ = mylog(str("using ", m, " for
>>> whatever")) ) m;
>>
>>
>> ...but that gets a little ugly when you're doing that 8 or 10 or more
>> than 20 times in a single let() call. Is there a better way?
>>
>> [1]:
>> https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Other_Language_Features#Using_assertions_in_function
>>
>> --
>> - Jon Gilbert
>> jong@jong.org / jgilbertsjc@gmail.com
>> _______________________________________________
>> 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
>
AM
Adrian Mariano
Fri, Oct 14, 2022 12:37 AM
You can't use a module inside a let(), so that won't work. There is no way
to do what he wants to do.
On Thu, Oct 13, 2022 at 8:34 PM Leonard Martin Struttmann <
lenstruttmann@gmail.com> wrote:
You can approximate...
function mylog(msg) = echo( ($preview) ? msg : undef );
...wth
module mylog(msg) { echo( ($preview) ? msg : undef ); }
// Example usage:
$preview = true;
mylog("HI");
On Thu, Oct 13, 2022 at 7:28 PM Adrian Mariano avm4@cornell.edu wrote:
There are unfortunately several circumstances where you have to use a
dummy return value. I do this all the time:
let( blah, blah, blah, dummy=echo(something), ....)
More subtly, if you are writing a module with asserts or echoes you may
need to do the same thing:
module foo(x){
dummyA = echo(x);
dummy = assert(x>0);
y = 17/x;
....
}
Why are dummy variables necessary? Because assignments run before
modules, and if you don't use the dummy assignment, then echo and assert
are modules, so then y=17/x runs first, and you get an error if x is zero
instead of catching it with your assert. And the echo never runs because
the error happens first! With dummy variables, the assert and echo
statements become assignments and run in the obvious order, and you'll see
your echo output, and hit the assert before you try to compute with x.
On Thu, Oct 13, 2022 at 8:17 PM Jonathan Gilbert jong@jong.org wrote:
Here's a poser that I haven't really found a good answer to.
There seem to be a subset of function calls that work within
user-defined functions without any sort of special handling, that don't
return anything, and allow you to stack or chain without returning a value.
An example might be the use of let() or assert() here: these calls don't
return a value, maybe they impart some scoped change, maybe not, but
ultimately the value of m
is what's returned from myfunc():
function myfunc(arg) = let(m = 1 + arg ) assert(arg > 0, "arg must be
(I'm not sure what we're calling this behavior in OpenSCAD parlance;
functions that return no value? void functions? chained functions? I've no
idea. [1] below seems to imply that functions have children they can opt to
return or not, though it's probably something quite different than the
children() that are available to modules.)
Regardless of whatever term used to describe this behavior: Can we
create user functions of the same type? A function that returns nothing,
that can't be misinterpreted as a return value for another user function?
I'm thinking something along the lines of this (admittedly
contrived) example:
function mylog(msg) = echo( ($preview) ? msg : undef );
function myfunc(arg) = let( m = 1 + arg ) mylog(str("using ", m, " for
whatever")) m;
g = myfunc(5);
And, if not, how would you implement this behavior? Right now, I think
the easiest way is to capture and discard the return of whatever function
you're calling within a let():
function myfunc(arg) = let( m = 1 + arg, _ = mylog(str("using ", m, "
...but that gets a little ugly when you're doing that 8 or 10 or more
than 20 times in a single let() call. Is there a better way?
--
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
You can't use a module inside a let(), so that won't work. There is no way
to do what he wants to do.
On Thu, Oct 13, 2022 at 8:34 PM Leonard Martin Struttmann <
lenstruttmann@gmail.com> wrote:
> You can approximate...
>
> function mylog(msg) = echo( ($preview) ? msg : undef );
>
> ...wth
>
> module mylog(msg) { echo( ($preview) ? msg : undef ); }
>
> // Example usage:
> $preview = true;
> mylog("HI");
>
>
> On Thu, Oct 13, 2022 at 7:28 PM Adrian Mariano <avm4@cornell.edu> wrote:
>
>> There are unfortunately several circumstances where you have to use a
>> dummy return value. I do this all the time:
>>
>> let( blah, blah, blah, dummy=echo(something), ....)
>>
>> More subtly, if you are writing a module with asserts or echoes you may
>> need to do the same thing:
>>
>> module foo(x){
>> dummyA = echo(x);
>> dummy = assert(x>0);
>> y = 17/x;
>> ....
>> }
>>
>> Why are dummy variables necessary? Because assignments run before
>> modules, and if you don't use the dummy assignment, then echo and assert
>> are modules, so then y=17/x runs first, and you get an error if x is zero
>> instead of catching it with your assert. And the echo never runs because
>> the error happens first! With dummy variables, the assert and echo
>> statements become assignments and run in the obvious order, and you'll see
>> your echo output, and hit the assert before you try to compute with x.
>>
>>
>>
>>
>>
>>
>> On Thu, Oct 13, 2022 at 8:17 PM Jonathan Gilbert <jong@jong.org> wrote:
>>
>>> Here's a poser that I haven't really found a good answer to.
>>>
>>> There seem to be a subset of function calls that work within
>>> user-defined functions without any sort of special handling, that don't
>>> return anything, and allow you to stack or chain without returning a value.
>>> An example might be the use of let() or assert() here: these calls don't
>>> return a value, maybe they impart some scoped change, maybe not, but
>>> ultimately the value of `m` is what's returned from myfunc():
>>>
>>> function myfunc(arg) = let(m = 1 + arg ) assert(arg > 0, "arg must be
>>>> greater than zero") m;
>>>
>>>
>>> (I'm not sure what we're calling this behavior in OpenSCAD parlance;
>>> functions that return no value? void functions? chained functions? I've no
>>> idea. [1] below seems to imply that functions have children they can opt to
>>> return or not, though it's probably something quite different than the
>>> children() that are available to modules.)
>>>
>>> Regardless of whatever term used to describe this behavior: Can we
>>> create user functions of the same type? A function that returns nothing,
>>> that can't be misinterpreted as a return value for another user function?
>>> I'm thinking something along the lines of this (admittedly
>>> contrived) example:
>>>
>>> function mylog(msg) = echo( ($preview) ? msg : undef );
>>>> function myfunc(arg) = let( m = 1 + arg ) mylog(str("using ", m, " for
>>>> whatever")) m;
>>>> g = myfunc(5);
>>>
>>>
>>> And, if not, how would you implement this behavior? Right now, I _think_
>>> the easiest way is to capture and discard the return of whatever function
>>> you're calling within a let():
>>>
>>> function myfunc(arg) = let( m = 1 + arg, _ = mylog(str("using ", m, "
>>>> for whatever")) ) m;
>>>
>>>
>>> ...but that gets a little ugly when you're doing that 8 or 10 or more
>>> than 20 times in a single let() call. Is there a better way?
>>>
>>> [1]:
>>> https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Other_Language_Features#Using_assertions_in_function
>>>
>>> --
>>> - Jon Gilbert
>>> jong@jong.org / jgilbertsjc@gmail.com
>>> _______________________________________________
>>> 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
>>
> _______________________________________________
> OpenSCAD mailing list
> To unsubscribe send an email to discuss-leave@lists.openscad.org
>
JB
Jordan Brown
Fri, Oct 14, 2022 1:39 AM
On 10/13/2022 5:15 PM, Jonathan Gilbert wrote:
There seem to be a subset of function calls that work within
user-defined functions without any sort of special handling, that
don't return anything, and allow you to stack or chain without
returning a value.
Yeah, those aren't really functions. They are more like statements in
the sub-language of expressions... and as Adrian says, there's no way to
define them from a user program.
You can do something sort of similar by passing the value that follows
them as an argument to your function.
Say you have:
function f(arg) = echo(arg) arg*2;
You want to replace echo() with your own function. (Which, note, can't
take an unspecified number of arguments like echo can.)
function myecho(msg, val) = echo(str("myecho: ", msg)) val;
and then your original becomes:
function f(arg) = myecho(arg, arg*2);
On 10/13/2022 5:15 PM, Jonathan Gilbert wrote:
> There seem to be a subset of function calls that work within
> user-defined functions without any sort of special handling, that
> don't return anything, and allow you to stack or chain without
> returning a value.
Yeah, those aren't really functions. They are more like statements in
the sub-language of expressions... and as Adrian says, there's no way to
define them from a user program.
You can do something sort of similar by passing the value that follows
them as an argument to your function.
Say you have:
function f(arg) = echo(arg) arg*2;
You want to replace echo() with your own function. (Which, note, can't
take an unspecified number of arguments like echo can.)
function myecho(msg, val) = echo(str("myecho: ", msg)) val;
and then your original becomes:
function f(arg) = myecho(arg, arg*2);