discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

possible bug when using echo inside of a function.

TP
Torsten Paul
Mon, Feb 10, 2025 12:43 AM

On 10.02.25 01:36, Adrian Mariano via Discuss wrote:

I would argue that it has everything to do with echo()

function a(x) = x;

function f(x) = let(y = 2 * x, a(2)) y;

a = f(3);

Same scenario, same warning, no echo() anywhere. Case
closed for me at least. Yes, echo() is special but that's
a different story.

ciao,
Torsten.

On 10.02.25 01:36, Adrian Mariano via Discuss wrote: > I would argue that it has everything to do with echo() function a(x) = x; function f(x) = let(y = 2 * x, a(2)) y; a = f(3); Same scenario, same warning, no echo() anywhere. Case closed for me at least. Yes, echo() is special but that's a different story. ciao, Torsten.
AM
Adrian Mariano
Mon, Feb 10, 2025 1:12 AM

Except that the only reason you think that's the same scenario is that you
have a complete understanding of the weirdness of echo.  (You may not be
well positioned to understand how new users are going to think about this.
I may not be either, but I at least can remember the experience of being
really confused about this stuff.)  Without an understanding of echo, the
example above gives no insight whatsoever into why you get an error when
you write

let(
echo(foo),
a=3
)

since it looks nothing like what you wrote.  Without understanding the
special behavior of echo it's impossible understand why that's an error or
why changing it to dummy=echo(foo) makes it work.  Without understanding
the special behavior of echo it's basically impossible to fit either of
those statements into any kind of framework to understand what's going on.
So I'd say understanding echo and it's weirdness is primary here.  Only if
you understand that are you able to make the link to the example you posted
that produces the same error.

I'll agree that a solid understanding of let() would help you realize when
you see the above that you must not understand echo, but it doesn't really
provide any answers, just more confusion.

On Sun, Feb 9, 2025 at 7:43 PM Torsten Paul via Discuss <
discuss@lists.openscad.org> wrote:

On 10.02.25 01:36, Adrian Mariano via Discuss wrote:

I would argue that it has everything to do with echo()

function a(x) = x;

function f(x) = let(y = 2 * x, a(2)) y;

a = f(3);

Same scenario, same warning, no echo() anywhere. Case
closed for me at least. Yes, echo() is special but that's
a different story.

ciao,
Torsten.


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

Except that the only reason you think that's the same scenario is that you have a complete understanding of the weirdness of echo. (You may not be well positioned to understand how new users are going to think about this. I may not be either, but I at least can remember the experience of being really confused about this stuff.) Without an understanding of echo, the example above gives no insight whatsoever into why you get an error when you write let( echo(foo), a=3 ) since it looks nothing like what you wrote. Without understanding the special behavior of echo it's impossible understand why that's an error or why changing it to dummy=echo(foo) makes it work. Without understanding the special behavior of echo it's basically impossible to fit either of those statements into any kind of framework to understand what's going on. So I'd say understanding echo and it's weirdness is primary here. Only if you understand that are you able to make the link to the example you posted that produces the same error. I'll agree that a solid understanding of let() would help you realize when you see the above that you must not understand echo, but it doesn't really provide any answers, just more confusion. On Sun, Feb 9, 2025 at 7:43 PM Torsten Paul via Discuss < discuss@lists.openscad.org> wrote: > On 10.02.25 01:36, Adrian Mariano via Discuss wrote: > > I would argue that it has everything to do with echo() > > function a(x) = x; > > function f(x) = let(y = 2 * x, a(2)) y; > > a = f(3); > > Same scenario, same warning, no echo() anywhere. Case > closed for me at least. Yes, echo() is special but that's > a different story. > > ciao, > Torsten. > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
JD
John David
Mon, Feb 10, 2025 1:16 AM

After the echo, I returned 'a'.  I tried it with a comma, without, and
more.  The question is where can I place an echo to look at the variables.

Adrian, I have never had an issue with using an echo inside a module, or
outside those contexts.  I also knew that there were both function and
method versions of echo.  That said, are you telling me that the function
version of the echo is ALWAYS called when inside a function, even when
there is no return used?  That may be, but I would wonder if that is a bug
in the function parser.  I have not seen any place that every line inside a
let() has to assign a value.  If that is the rule here, then I will adjust
my world view and code accordingly.  Up until last night, I could not
figure out what was happening at all -- because the warning/error is not
descriptive enough for me to have figured it out.

On Sun, Feb 9, 2025 at 7:43 PM Torsten Paul via Discuss <
discuss@lists.openscad.org> wrote:

On 10.02.25 01:36, Adrian Mariano via Discuss wrote:

I would argue that it has everything to do with echo()

function a(x) = x;

function f(x) = let(y = 2 * x, a(2)) y;

a = f(3);

Same scenario, same warning, no echo() anywhere. Case
closed for me at least. Yes, echo() is special but that's
a different story.

ciao,
Torsten.


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

After the echo, I returned 'a'. I tried it with a comma, without, and more. The question is where can I place an echo to look at the variables. Adrian, I have never had an issue with using an echo inside a module, or outside those contexts. I also knew that there were both function and method versions of echo. That said, are you telling me that the function version of the echo is ALWAYS called when inside a function, even when there is no return used? That may be, but I would wonder if that is a bug in the function parser. I have not seen any place that every line inside a let() has to assign a value. If that is the rule here, then I will adjust my world view and code accordingly. Up until last night, I could not figure out what was happening at all -- because the warning/error is not descriptive enough for me to have figured it out. On Sun, Feb 9, 2025 at 7:43 PM Torsten Paul via Discuss < discuss@lists.openscad.org> wrote: > On 10.02.25 01:36, Adrian Mariano via Discuss wrote: > > I would argue that it has everything to do with echo() > > function a(x) = x; > > function f(x) = let(y = 2 * x, a(2)) y; > > a = f(3); > > Same scenario, same warning, no echo() anywhere. Case > closed for me at least. Yes, echo() is special but that's > a different story. > > ciao, > Torsten. > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
JD
John David
Mon, Feb 10, 2025 1:22 AM

Adrian, on your second reply (I was writing mine when you posted yours...),
I'll dive more into let(), and study all the replies provided to see if I
can get my OpenSCAD Fu on.  BTW, I have learned a thing or two with reading
through the nurbs code.  What other well written code should be studied as
expemplats?

On Sun, Feb 9, 2025 at 8:16 PM John David ebo.2112@gmail.com wrote:

After the echo, I returned 'a'.  I tried it with a comma, without, and
more.  The question is where can I place an echo to look at the variables.

Adrian, I have never had an issue with using an echo inside a module, or
outside those contexts.  I also knew that there were both function and
method versions of echo.  That said, are you telling me that the function
version of the echo is ALWAYS called when inside a function, even when
there is no return used?  That may be, but I would wonder if that is a bug
in the function parser.  I have not seen any place that every line inside a
let() has to assign a value.  If that is the rule here, then I will adjust
my world view and code accordingly.  Up until last night, I could not
figure out what was happening at all -- because the warning/error is not
descriptive enough for me to have figured it out.

On Sun, Feb 9, 2025 at 7:43 PM Torsten Paul via Discuss <
discuss@lists.openscad.org> wrote:

On 10.02.25 01:36, Adrian Mariano via Discuss wrote:

I would argue that it has everything to do with echo()

function a(x) = x;

function f(x) = let(y = 2 * x, a(2)) y;

a = f(3);

Same scenario, same warning, no echo() anywhere. Case
closed for me at least. Yes, echo() is special but that's
a different story.

ciao,
Torsten.


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

Adrian, on your second reply (I was writing mine when you posted yours...), I'll dive more into let(), and study all the replies provided to see if I can get my OpenSCAD Fu on. BTW, I have learned a thing or two with reading through the nurbs code. What other well written code should be studied as expemplats? On Sun, Feb 9, 2025 at 8:16 PM John David <ebo.2112@gmail.com> wrote: > After the echo, I returned 'a'. I tried it with a comma, without, and > more. The question is where can I place an echo to look at the variables. > > Adrian, I have never had an issue with using an echo inside a module, or > outside those contexts. I also knew that there were both function and > method versions of echo. That said, are you telling me that the function > version of the echo is ALWAYS called when inside a function, even when > there is no return used? That may be, but I would wonder if that is a bug > in the function parser. I have not seen any place that every line inside a > let() has to assign a value. If that is the rule here, then I will adjust > my world view and code accordingly. Up until last night, I could not > figure out what was happening at all -- because the warning/error is not > descriptive enough for me to have figured it out. > > On Sun, Feb 9, 2025 at 7:43 PM Torsten Paul via Discuss < > discuss@lists.openscad.org> wrote: > >> On 10.02.25 01:36, Adrian Mariano via Discuss wrote: >> > I would argue that it has everything to do with echo() >> >> function a(x) = x; >> >> function f(x) = let(y = 2 * x, a(2)) y; >> >> a = f(3); >> >> Same scenario, same warning, no echo() anywhere. Case >> closed for me at least. Yes, echo() is special but that's >> a different story. >> >> ciao, >> Torsten. >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org >> >
AM
Adrian Mariano
Mon, Feb 10, 2025 2:29 AM

John,

the way I use echo is always with a dummy return.

So in a let where I want to display a I would do this.

let(
a = f(x),
dummy = echo(a=a)
)

If I wanted to display a and b on separate lines, perhaps because they are
long lists, I'd write dummy=echo(a=a)echo(b=b).

A let statement is defined to be a series of assignments, so yes, every
comma separated entry given to let must be an assignment.  As I have
argued, there is not a function version of echo, but more a function
context version of echo which is some different kind of object than a
function.  Inside a let statement everything is a function context.  It
makes no sense to expect otherwise, so it's not a bug that echo is always
interpreted in a function context inside a let.  You can't make geometry
there so modules don't make any sense.

For automating time tests it might be possible to run OpenSCAD from the
command line with varying inputs, capture the console output, and then
post-process that to extract the timing data for the various runs.

With regards to written code to study, I of course suggest that you can
examine anything in the BOSL2 library for examples of the pinnacle of
OpenSCAD code quality.  :)  More seriously, I think we've generally done a
decent job and we've written a lot of code.  The older stuff may not be as
well written as recent stuff...but there's no simple way for me to tell you
what's recent and what's not, nor do I have a notion of anything that's
somehow particularly well written to point to.  I don't have familiarity
with any other code base I can point to, so others will have to make those
suggestions.

On Sun, Feb 9, 2025 at 8:17 PM John David via Discuss <
discuss@lists.openscad.org> wrote:

After the echo, I returned 'a'.  I tried it with a comma, without, and
more.  The question is where can I place an echo to look at the variables.

Adrian, I have never had an issue with using an echo inside a module, or
outside those contexts.  I also knew that there were both function and
method versions of echo.  That said, are you telling me that the function
version of the echo is ALWAYS called when inside a function, even when
there is no return used?  That may be, but I would wonder if that is a bug
in the function parser.  I have not seen any place that every line inside a
let() has to assign a value.  If that is the rule here, then I will adjust
my world view and code accordingly.  Up until last night, I could not
figure out what was happening at all -- because the warning/error is not
descriptive enough for me to have figured it out.

On Sun, Feb 9, 2025 at 7:43 PM Torsten Paul via Discuss <
discuss@lists.openscad.org> wrote:

On 10.02.25 01:36, Adrian Mariano via Discuss wrote:

I would argue that it has everything to do with echo()

function a(x) = x;

function f(x) = let(y = 2 * x, a(2)) y;

a = f(3);

Same scenario, same warning, no echo() anywhere. Case
closed for me at least. Yes, echo() is special but that's
a different story.

ciao,
Torsten.


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

John, the way I use echo is always with a dummy return. So in a let where I want to display a I would do this. let( a = f(x), dummy = echo(a=a) ) If I wanted to display a and b on separate lines, perhaps because they are long lists, I'd write dummy=echo(a=a)echo(b=b). A let statement is defined to be a series of assignments, so yes, every comma separated entry given to let must be an assignment. As I have argued, there is not a function version of echo, but more a function context version of echo which is some different kind of object than a function. Inside a let statement everything is a function context. It makes no sense to expect otherwise, so it's not a bug that echo is always interpreted in a function context inside a let. You can't make geometry there so modules don't make any sense. For automating time tests it might be possible to run OpenSCAD from the command line with varying inputs, capture the console output, and then post-process that to extract the timing data for the various runs. With regards to written code to study, I of course suggest that you can examine anything in the BOSL2 library for examples of the pinnacle of OpenSCAD code quality. :) More seriously, I think we've generally done a decent job and we've written a lot of code. The older stuff may not be as well written as recent stuff...but there's no simple way for me to tell you what's recent and what's not, nor do I have a notion of anything that's somehow particularly well written to point to. I don't have familiarity with any other code base I can point to, so others will have to make those suggestions. On Sun, Feb 9, 2025 at 8:17 PM John David via Discuss < discuss@lists.openscad.org> wrote: > After the echo, I returned 'a'. I tried it with a comma, without, and > more. The question is where can I place an echo to look at the variables. > > Adrian, I have never had an issue with using an echo inside a module, or > outside those contexts. I also knew that there were both function and > method versions of echo. That said, are you telling me that the function > version of the echo is ALWAYS called when inside a function, even when > there is no return used? That may be, but I would wonder if that is a bug > in the function parser. I have not seen any place that every line inside a > let() has to assign a value. If that is the rule here, then I will adjust > my world view and code accordingly. Up until last night, I could not > figure out what was happening at all -- because the warning/error is not > descriptive enough for me to have figured it out. > > On Sun, Feb 9, 2025 at 7:43 PM Torsten Paul via Discuss < > discuss@lists.openscad.org> wrote: > >> On 10.02.25 01:36, Adrian Mariano via Discuss wrote: >> > I would argue that it has everything to do with echo() >> >> function a(x) = x; >> >> function f(x) = let(y = 2 * x, a(2)) y; >> >> a = f(3); >> >> Same scenario, same warning, no echo() anywhere. Case >> closed for me at least. Yes, echo() is special but that's >> a different story. >> >> ciao, >> Torsten. >> _______________________________________________ >> 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 >
JD
John David
Mon, Feb 10, 2025 3:09 AM

Thank you again.  Now, several details of functions and let() make more
sense, and I will plan on using dummy = echo() when I am debugging
functions.

I'll check on running openscad from the command line, but I am also smack
in the middle of building openscade from source so that I can see if I can
hack in a time([previous]).  It turns out that builtin_functions.cc already
call std::time(nullptr) to initialize the rng.  There is another place in
RenderStatistic.cc which utilizes std::chrono::steady_clock::now().  So it
might not be to difficiult or weird to add a new builtin "time()".

On Sun, Feb 9, 2025 at 9:30 PM Adrian Mariano via Discuss <
discuss@lists.openscad.org> wrote:

John,

the way I use echo is always with a dummy return.

So in a let where I want to display a I would do this.

let(
a = f(x),
dummy = echo(a=a)
)

If I wanted to display a and b on separate lines, perhaps because they are
long lists, I'd write dummy=echo(a=a)echo(b=b).

A let statement is defined to be a series of assignments, so yes, every
comma separated entry given to let must be an assignment.  As I have
argued, there is not a function version of echo, but more a function
context version of echo which is some different kind of object than a
function.  Inside a let statement everything is a function context.  It
makes no sense to expect otherwise, so it's not a bug that echo is always
interpreted in a function context inside a let.  You can't make geometry
there so modules don't make any sense.

For automating time tests it might be possible to run OpenSCAD from the
command line with varying inputs, capture the console output, and then
post-process that to extract the timing data for the various runs.

With regards to written code to study, I of course suggest that you can
examine anything in the BOSL2 library for examples of the pinnacle of
OpenSCAD code quality.  :)  More seriously, I think we've generally done a
decent job and we've written a lot of code.  The older stuff may not be as
well written as recent stuff...but there's no simple way for me to tell you
what's recent and what's not, nor do I have a notion of anything that's
somehow particularly well written to point to.  I don't have familiarity
with any other code base I can point to, so others will have to make those
suggestions.

On Sun, Feb 9, 2025 at 8:17 PM John David via Discuss <
discuss@lists.openscad.org> wrote:

After the echo, I returned 'a'.  I tried it with a comma, without, and
more.  The question is where can I place an echo to look at the variables.

Adrian, I have never had an issue with using an echo inside a module, or
outside those contexts.  I also knew that there were both function and
method versions of echo.  That said, are you telling me that the function
version of the echo is ALWAYS called when inside a function, even when
there is no return used?  That may be, but I would wonder if that is a bug
in the function parser.  I have not seen any place that every line inside a
let() has to assign a value.  If that is the rule here, then I will adjust
my world view and code accordingly.  Up until last night, I could not
figure out what was happening at all -- because the warning/error is not
descriptive enough for me to have figured it out.

On Sun, Feb 9, 2025 at 7:43 PM Torsten Paul via Discuss <
discuss@lists.openscad.org> wrote:

On 10.02.25 01:36, Adrian Mariano via Discuss wrote:

I would argue that it has everything to do with echo()

function a(x) = x;

function f(x) = let(y = 2 * x, a(2)) y;

a = f(3);

Same scenario, same warning, no echo() anywhere. Case
closed for me at least. Yes, echo() is special but that's
a different story.

ciao,
Torsten.


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

Thank you again. Now, several details of functions and let() make more sense, and I will plan on using dummy = echo() when I am debugging functions. I'll check on running openscad from the command line, but I am also smack in the middle of building openscade from source so that I can see if I can hack in a time([previous]). It turns out that builtin_functions.cc already call std::time(nullptr) to initialize the rng. There is another place in RenderStatistic.cc which utilizes std::chrono::steady_clock::now(). So it might not be to difficiult or weird to add a new builtin "time()". On Sun, Feb 9, 2025 at 9:30 PM Adrian Mariano via Discuss < discuss@lists.openscad.org> wrote: > John, > > the way I use echo is always with a dummy return. > > So in a let where I want to display a I would do this. > > let( > a = f(x), > dummy = echo(a=a) > ) > > If I wanted to display a and b on separate lines, perhaps because they are > long lists, I'd write dummy=echo(a=a)echo(b=b). > > A let statement is defined to be a series of assignments, so yes, every > comma separated entry given to let must be an assignment. As I have > argued, there is not a function version of echo, but more a function > context version of echo which is some different kind of object than a > function. Inside a let statement everything is a function context. It > makes no sense to expect otherwise, so it's not a bug that echo is always > interpreted in a function context inside a let. You can't make geometry > there so modules don't make any sense. > > For automating time tests it might be possible to run OpenSCAD from the > command line with varying inputs, capture the console output, and then > post-process that to extract the timing data for the various runs. > > With regards to written code to study, I of course suggest that you can > examine anything in the BOSL2 library for examples of the pinnacle of > OpenSCAD code quality. :) More seriously, I think we've generally done a > decent job and we've written a lot of code. The older stuff may not be as > well written as recent stuff...but there's no simple way for me to tell you > what's recent and what's not, nor do I have a notion of anything that's > somehow particularly well written to point to. I don't have familiarity > with any other code base I can point to, so others will have to make those > suggestions. > > > > On Sun, Feb 9, 2025 at 8:17 PM John David via Discuss < > discuss@lists.openscad.org> wrote: > >> After the echo, I returned 'a'. I tried it with a comma, without, and >> more. The question is where can I place an echo to look at the variables. >> >> Adrian, I have never had an issue with using an echo inside a module, or >> outside those contexts. I also knew that there were both function and >> method versions of echo. That said, are you telling me that the function >> version of the echo is ALWAYS called when inside a function, even when >> there is no return used? That may be, but I would wonder if that is a bug >> in the function parser. I have not seen any place that every line inside a >> let() has to assign a value. If that is the rule here, then I will adjust >> my world view and code accordingly. Up until last night, I could not >> figure out what was happening at all -- because the warning/error is not >> descriptive enough for me to have figured it out. >> >> On Sun, Feb 9, 2025 at 7:43 PM Torsten Paul via Discuss < >> discuss@lists.openscad.org> wrote: >> >>> On 10.02.25 01:36, Adrian Mariano via Discuss wrote: >>> > I would argue that it has everything to do with echo() >>> >>> function a(x) = x; >>> >>> function f(x) = let(y = 2 * x, a(2)) y; >>> >>> a = f(3); >>> >>> Same scenario, same warning, no echo() anywhere. Case >>> closed for me at least. Yes, echo() is special but that's >>> a different story. >>> >>> ciao, >>> Torsten. >>> _______________________________________________ >>> 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 >
NH
nop head
Mon, Feb 10, 2025 11:03 AM

The way to avoid assigning dummy variables is to do echo(a) just before you
use it in a subsequent expression. E.g. instead of just b = 2 * a use
b = echo(a)
2 * a. I use my wrapper echoit() so the first use of a would be b = 2 *
echoit(a).

The same applies to assert.

On Mon, 10 Feb 2025 at 03:09, John David via Discuss <
discuss@lists.openscad.org> wrote:

Thank you again.  Now, several details of functions and let() make more
sense, and I will plan on using dummy = echo() when I am debugging
functions.

I'll check on running openscad from the command line, but I am also smack
in the middle of building openscade from source so that I can see if I can
hack in a time([previous]).  It turns out that builtin_functions.cc already
call std::time(nullptr) to initialize the rng.  There is another place in
RenderStatistic.cc which utilizes std::chrono::steady_clock::now().  So it
might not be to difficiult or weird to add a new builtin "time()".

On Sun, Feb 9, 2025 at 9:30 PM Adrian Mariano via Discuss <
discuss@lists.openscad.org> wrote:

John,

the way I use echo is always with a dummy return.

So in a let where I want to display a I would do this.

let(
a = f(x),
dummy = echo(a=a)
)

If I wanted to display a and b on separate lines, perhaps because they
are long lists, I'd write dummy=echo(a=a)echo(b=b).

A let statement is defined to be a series of assignments, so yes, every
comma separated entry given to let must be an assignment.  As I have
argued, there is not a function version of echo, but more a function
context version of echo which is some different kind of object than a
function.  Inside a let statement everything is a function context.  It
makes no sense to expect otherwise, so it's not a bug that echo is always
interpreted in a function context inside a let.  You can't make geometry
there so modules don't make any sense.

For automating time tests it might be possible to run OpenSCAD from the
command line with varying inputs, capture the console output, and then
post-process that to extract the timing data for the various runs.

With regards to written code to study, I of course suggest that you can
examine anything in the BOSL2 library for examples of the pinnacle of
OpenSCAD code quality.  :)  More seriously, I think we've generally done a
decent job and we've written a lot of code.  The older stuff may not be as
well written as recent stuff...but there's no simple way for me to tell you
what's recent and what's not, nor do I have a notion of anything that's
somehow particularly well written to point to.  I don't have familiarity
with any other code base I can point to, so others will have to make those
suggestions.

On Sun, Feb 9, 2025 at 8:17 PM John David via Discuss <
discuss@lists.openscad.org> wrote:

After the echo, I returned 'a'.  I tried it with a comma, without, and
more.  The question is where can I place an echo to look at the variables.

Adrian, I have never had an issue with using an echo inside a module, or
outside those contexts.  I also knew that there were both function and
method versions of echo.  That said, are you telling me that the function
version of the echo is ALWAYS called when inside a function, even when
there is no return used?  That may be, but I would wonder if that is a bug
in the function parser.  I have not seen any place that every line inside a
let() has to assign a value.  If that is the rule here, then I will adjust
my world view and code accordingly.  Up until last night, I could not
figure out what was happening at all -- because the warning/error is not
descriptive enough for me to have figured it out.

On Sun, Feb 9, 2025 at 7:43 PM Torsten Paul via Discuss <
discuss@lists.openscad.org> wrote:

On 10.02.25 01:36, Adrian Mariano via Discuss wrote:

I would argue that it has everything to do with echo()

function a(x) = x;

function f(x) = let(y = 2 * x, a(2)) y;

a = f(3);

Same scenario, same warning, no echo() anywhere. Case
closed for me at least. Yes, echo() is special but that's
a different story.

ciao,
Torsten.


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


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

The way to avoid assigning dummy variables is to do echo(a) just before you use it in a subsequent expression. E.g. instead of just b = 2 * a use b = echo(a) 2 * a. I use my wrapper echoit() so the first use of a would be b = 2 * echoit(a). The same applies to assert. On Mon, 10 Feb 2025 at 03:09, John David via Discuss < discuss@lists.openscad.org> wrote: > Thank you again. Now, several details of functions and let() make more > sense, and I will plan on using dummy = echo() when I am debugging > functions. > > I'll check on running openscad from the command line, but I am also smack > in the middle of building openscade from source so that I can see if I can > hack in a time([previous]). It turns out that builtin_functions.cc already > call std::time(nullptr) to initialize the rng. There is another place in > RenderStatistic.cc which utilizes std::chrono::steady_clock::now(). So it > might not be to difficiult or weird to add a new builtin "time()". > > On Sun, Feb 9, 2025 at 9:30 PM Adrian Mariano via Discuss < > discuss@lists.openscad.org> wrote: > >> John, >> >> the way I use echo is always with a dummy return. >> >> So in a let where I want to display a I would do this. >> >> let( >> a = f(x), >> dummy = echo(a=a) >> ) >> >> If I wanted to display a and b on separate lines, perhaps because they >> are long lists, I'd write dummy=echo(a=a)echo(b=b). >> >> A let statement is defined to be a series of assignments, so yes, every >> comma separated entry given to let must be an assignment. As I have >> argued, there is not a function version of echo, but more a function >> context version of echo which is some different kind of object than a >> function. Inside a let statement everything is a function context. It >> makes no sense to expect otherwise, so it's not a bug that echo is always >> interpreted in a function context inside a let. You can't make geometry >> there so modules don't make any sense. >> >> For automating time tests it might be possible to run OpenSCAD from the >> command line with varying inputs, capture the console output, and then >> post-process that to extract the timing data for the various runs. >> >> With regards to written code to study, I of course suggest that you can >> examine anything in the BOSL2 library for examples of the pinnacle of >> OpenSCAD code quality. :) More seriously, I think we've generally done a >> decent job and we've written a lot of code. The older stuff may not be as >> well written as recent stuff...but there's no simple way for me to tell you >> what's recent and what's not, nor do I have a notion of anything that's >> somehow particularly well written to point to. I don't have familiarity >> with any other code base I can point to, so others will have to make those >> suggestions. >> >> >> >> On Sun, Feb 9, 2025 at 8:17 PM John David via Discuss < >> discuss@lists.openscad.org> wrote: >> >>> After the echo, I returned 'a'. I tried it with a comma, without, and >>> more. The question is where can I place an echo to look at the variables. >>> >>> Adrian, I have never had an issue with using an echo inside a module, or >>> outside those contexts. I also knew that there were both function and >>> method versions of echo. That said, are you telling me that the function >>> version of the echo is ALWAYS called when inside a function, even when >>> there is no return used? That may be, but I would wonder if that is a bug >>> in the function parser. I have not seen any place that every line inside a >>> let() has to assign a value. If that is the rule here, then I will adjust >>> my world view and code accordingly. Up until last night, I could not >>> figure out what was happening at all -- because the warning/error is not >>> descriptive enough for me to have figured it out. >>> >>> On Sun, Feb 9, 2025 at 7:43 PM Torsten Paul via Discuss < >>> discuss@lists.openscad.org> wrote: >>> >>>> On 10.02.25 01:36, Adrian Mariano via Discuss wrote: >>>> > I would argue that it has everything to do with echo() >>>> >>>> function a(x) = x; >>>> >>>> function f(x) = let(y = 2 * x, a(2)) y; >>>> >>>> a = f(3); >>>> >>>> Same scenario, same warning, no echo() anywhere. Case >>>> closed for me at least. Yes, echo() is special but that's >>>> a different story. >>>> >>>> ciao, >>>> Torsten. >>>> _______________________________________________ >>>> 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 >> > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
JB
Jordan Brown
Tue, Feb 11, 2025 2:04 AM

On 2/9/2025 6:29 PM, Adrian Mariano via Discuss wrote:

As I have argued, there is not a function version of echo, but more a
function context version of echo which is some different kind of
object than a function.

Yes.  A bit more correctly, it's an expression-context version of echo. 
There is no requirement that it be used in a function.  Instead, it can
be used anywhere an expression can be used.  To be precise, it, let(),
and assert() are allowed anywhere that the "expr" production is used,
which makes it usable at the start of:

  • a function definition
  • the right-hand-side expression for an assignment
  • the conditional expression for an if().
  • the "then" and "else" clauses of an a?b:c
  • the expression after one of these let(), echo, or assign() thingamabobs
  • the expression in an array lookup (in [])
  • the expression in parentheses
  • any of the two or three expressions in a range
  • the arguments of a list-comprehension C-like "for"
  • the conditional expression of a list-comprehension "if".
  • an element in a vector specification [a,b,c]
  • a function or module default parameter
  • a function or module argument (after the "=", if by name)

Somebody said that if you didn't include a following expression the
result was zero.  No, it's undef.

On 2/9/2025 6:29 PM, Adrian Mariano via Discuss wrote: > As I have argued, there is not a function version of echo, but more a > function context version of echo which is some different kind of > object than a function. Yes.  A bit more correctly, it's an expression-context version of echo.  There is no requirement that it be used in a function.  Instead, it can be used anywhere an expression can be used.  To be precise, it, let(), and assert() are allowed anywhere that the "expr" production is used, which makes it usable at the start of: * a function definition * the right-hand-side expression for an assignment * the conditional expression for an if(). * the "then" and "else" clauses of an a?b:c * the expression after one of these let(), echo, or assign() thingamabobs * the expression in an array lookup (in []) * the expression in parentheses * any of the two or three expressions in a range * the arguments of a list-comprehension C-like "for" * the conditional expression of a list-comprehension "if". * an element in a vector specification [a,b,c] * a function or module default parameter * a function or module argument (after the "=", if by name) Somebody said that if you didn't include a following expression the result was zero.  No, it's undef.