discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

debug print in openscad functions

JD
John Danskin
Thu, Jan 14, 2016 5:33 PM

I just discovered that you can do this.

function debugprint(s) = search(s, []);
function f(x) = [debugprint(str("f(", x, ")")), 2 * x][1];
t = f(3);

And get this output:

WARNING: search term not found: "f"

WARNING: search term not found: "("

WARNING: search term not found: "3"

WARNING: search term not found: ")"

ECHO: t = 6

Which is hacky but way better than a poke in the eye with a sharp stick if
you are desperately trying to debug something. I still wish there was a
function with an echo side-effect. It could return undef. If I can already
use search for this, the functionality is in there somewhere.

Anyway, hope this technique helps someone.

I just discovered that you can do this. function debugprint(s) = search(s, []); function f(x) = [debugprint(str("f(", x, ")")), 2 * x][1]; t = f(3); And get this output: WARNING: search term not found: "f" WARNING: search term not found: "(" WARNING: search term not found: "3" WARNING: search term not found: ")" ECHO: t = 6 Which is hacky but way better than a poke in the eye with a sharp stick if you are desperately trying to debug something. I still wish there was a function with an echo side-effect. It could return undef. If I can already use search for this, the functionality is in there somewhere. Anyway, hope this technique helps someone.
M
MichaelAtOz
Thu, Jan 14, 2016 10:19 PM

Thanks. Nice use of a "side-effect" which I thought we didn't allow?
Seems to be the main argument against  echof()
https://github.com/openscad/openscad/issues/741


Newly minted Admin - PM me if you need anything, or if I've done something stupid...

Unless specifically shown otherwise above, my contribution is in the Public Domain; to the extent possible under law, I have waived all copyright and related or neighbouring rights to this work. Obviously inclusion of works of previous authors is not included in the above.

The TPP is no simple “trade agreement.”  Fight it! http://www.ourfairdeal.org/  time is running out!

View this message in context: http://forum.openscad.org/debug-print-in-openscad-functions-tp15683p15685.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

Thanks. Nice use of a "side-effect" which I thought we didn't allow? Seems to be the main argument against echof() <https://github.com/openscad/openscad/issues/741> ----- Newly minted Admin - PM me if you need anything, or if I've done something stupid... Unless specifically shown otherwise above, my contribution is in the Public Domain; to the extent possible under law, I have waived all copyright and related or neighbouring rights to this work. Obviously inclusion of works of previous authors is not included in the above. The TPP is no simple “trade agreement.” Fight it! http://www.ourfairdeal.org/ time is running out! -- View this message in context: http://forum.openscad.org/debug-print-in-openscad-functions-tp15683p15685.html Sent from the OpenSCAD mailing list archive at Nabble.com.
NH
nop head
Fri, Jan 15, 2016 8:47 AM

If you accept that functions can return a debug string as well as a value
then it is no longer a side effect. If you cache the value of the function
for optimisation then you also have to cache the string and emit it
whenever you use the cached value. The same with echo in modules and
geometry.

On 14 January 2016 at 22:19, MichaelAtOz oz.at.michael@gmail.com wrote:

Thanks. Nice use of a "side-effect" which I thought we didn't allow?
Seems to be the main argument against  echof()
https://github.com/openscad/openscad/issues/741


Newly minted Admin - PM me if you need anything, or if I've done something
stupid...

Unless specifically shown otherwise above, my contribution is in the
Public Domain; to the extent possible under law, I have waived all
copyright and related or neighbouring rights to this work. Obviously
inclusion of works of previous authors is not included in the above.

The TPP is no simple “trade agreement.”  Fight it!
http://www.ourfairdeal.org/  time is running out!

View this message in context:
http://forum.openscad.org/debug-print-in-openscad-functions-tp15683p15685.html
Sent from the OpenSCAD mailing list archive at Nabble.com.


OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

If you accept that functions can return a debug string as well as a value then it is no longer a side effect. If you cache the value of the function for optimisation then you also have to cache the string and emit it whenever you use the cached value. The same with echo in modules and geometry. On 14 January 2016 at 22:19, MichaelAtOz <oz.at.michael@gmail.com> wrote: > Thanks. Nice use of a "side-effect" which I thought we didn't allow? > Seems to be the main argument against echof() > <https://github.com/openscad/openscad/issues/741> > > > > ----- > Newly minted Admin - PM me if you need anything, or if I've done something > stupid... > > Unless specifically shown otherwise above, my contribution is in the > Public Domain; to the extent possible under law, I have waived all > copyright and related or neighbouring rights to this work. Obviously > inclusion of works of previous authors is not included in the above. > > The TPP is no simple “trade agreement.” Fight it! > http://www.ourfairdeal.org/ time is running out! > -- > View this message in context: > http://forum.openscad.org/debug-print-in-openscad-functions-tp15683p15685.html > Sent from the OpenSCAD mailing list archive at Nabble.com. > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >
DM
doug moen
Fri, Jan 15, 2016 4:17 PM

The "search" function is badly designed. It prints those warning messages
because
search("large", [["large",42], ["medium",17], ["small",5]])
does not do what it should do.

We should deprecate "search" and replace it with something simpler and
better behaved. A lot of people who need this functionality have already
done this, by writing their own function. My preferred interface looks like
this:
lookup(key, [[key1,value1], [key2,value2], ...])
returns the value associated with the key argument, or returns undef if
there is no match. Works with any type of key for which equality is
defined, including strings and lists.

There is nothing wrong with adding an "echof" function as an aid in
debugging functions. It's no worse than "echo". This is needed as a debug
feature, since OpenSCAD doesn't have proper debug facilities. But we should
be aiming higher, at providing a proper debugger UI in a future release. If
you could use a debugger to set "watchpoints" that print a trace message to
the console each time a particular expression is evaluated, then you could
debug a program without cluttering up the source code with echo statements.

OpenSCAD is a declarative language. Ideally, it has no side effects, and it
has no defined evaluation order, which gives the implementation maximum
flexibility to compile scripts into a form that execute quickly. For
example,

  • Suppose that an expensive-to-compute subexpression occurs inside a for
    loop, but doesn't depend on the iteration variable. An optimizing compiler
    can lift that subexpression outside of the loop, and only evaluate it once.
  • If the same subexpression occurs multiple times, the compiler can
    recognize this and arrange to only evaluate the expression once, caching
    the result for later use.
  • Declarative programs can be automatically parallelized, so that
    multiple cores are used to simultaneously evaluate different parts of the
    program.

Debugging tools expose the evaluation order. That's inevitable. A problem
with 'echo' and 'echof' is that they are part of the language, and users
might come to rely on a particular script producing echo output in a
particular order. I think we should make it clear that 'echo' is only a
debug feature, that there is no defined evaluation order, and that the
evaluation order can change across releases, or vary depending on the
hardware and operating system. With multi-core evaluation, the evaluation
order can change from one run to the next.

I know that people use 'echo' to generate a bill of materials. We should
provide a more declarative way to do this. In OpenSCAD2, I've provided a
mechanism for attaching user-defined metadata to geometric shapes, and I
also explain how to use this to generate a BOM declaratively, without using
echo.

Remember that in a declarative language, the evaluation order is something
internal to the implementation, it does not (should not) affect the final
result. Otherwise it's a bug. In OpenSCAD, the final result is usually the
geometry, but in the above example it's the BOM, if the BOM is defined
declaratively using metadata.

On 15 January 2016 at 03:47, nop head nop.head@gmail.com wrote:

If you accept that functions can return a debug string as well as a value
then it is no longer a side effect. If you cache the value of the function
for optimisation then you also have to cache the string and emit it
whenever you use the cached value. The same with echo in modules and
geometry.

On 14 January 2016 at 22:19, MichaelAtOz oz.at.michael@gmail.com wrote:

Thanks. Nice use of a "side-effect" which I thought we didn't allow?
Seems to be the main argument against  echof()
https://github.com/openscad/openscad/issues/741


Newly minted Admin - PM me if you need anything, or if I've done
something stupid...

Unless specifically shown otherwise above, my contribution is in the
Public Domain; to the extent possible under law, I have waived all
copyright and related or neighbouring rights to this work. Obviously
inclusion of works of previous authors is not included in the above.

The TPP is no simple “trade agreement.”  Fight it!
http://www.ourfairdeal.org/  time is running out!

View this message in context:
http://forum.openscad.org/debug-print-in-openscad-functions-tp15683p15685.html
Sent from the OpenSCAD mailing list archive at Nabble.com.


OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

The "search" function is badly designed. It prints those warning messages because search("large", [["large",42], ["medium",17], ["small",5]]) does not do what it should do. We should deprecate "search" and replace it with something simpler and better behaved. A lot of people who need this functionality have already done this, by writing their own function. My preferred interface looks like this: lookup(key, [[key1,value1], [key2,value2], ...]) returns the value associated with the key argument, or returns undef if there is no match. Works with any type of key for which equality is defined, including strings and lists. There is nothing wrong with adding an "echof" function as an aid in debugging functions. It's no worse than "echo". This is needed as a debug feature, since OpenSCAD doesn't have proper debug facilities. But we should be aiming higher, at providing a proper debugger UI in a future release. If you could use a debugger to set "watchpoints" that print a trace message to the console each time a particular expression is evaluated, then you could debug a program without cluttering up the source code with echo statements. OpenSCAD is a declarative language. Ideally, it has no side effects, and it has no defined evaluation order, which gives the implementation maximum flexibility to compile scripts into a form that execute quickly. For example, - Suppose that an expensive-to-compute subexpression occurs inside a for loop, but doesn't depend on the iteration variable. An optimizing compiler can lift that subexpression outside of the loop, and only evaluate it once. - If the same subexpression occurs multiple times, the compiler can recognize this and arrange to only evaluate the expression once, caching the result for later use. - Declarative programs can be automatically parallelized, so that multiple cores are used to simultaneously evaluate different parts of the program. Debugging tools expose the evaluation order. That's inevitable. A problem with 'echo' and 'echof' is that they are part of the language, and users might come to rely on a particular script producing echo output in a particular order. I think we should make it clear that 'echo' is only a debug feature, that there is no defined evaluation order, and that the evaluation order can change across releases, or vary depending on the hardware and operating system. With multi-core evaluation, the evaluation order can change from one run to the next. I know that people use 'echo' to generate a bill of materials. We should provide a more declarative way to do this. In OpenSCAD2, I've provided a mechanism for attaching user-defined metadata to geometric shapes, and I also explain how to use this to generate a BOM declaratively, without using echo. Remember that in a declarative language, the evaluation order is something internal to the implementation, it does not (should not) affect the final result. Otherwise it's a bug. In OpenSCAD, the final result is usually the geometry, but in the above example it's the BOM, if the BOM is defined declaratively using metadata. On 15 January 2016 at 03:47, nop head <nop.head@gmail.com> wrote: > If you accept that functions can return a debug string as well as a value > then it is no longer a side effect. If you cache the value of the function > for optimisation then you also have to cache the string and emit it > whenever you use the cached value. The same with echo in modules and > geometry. > > On 14 January 2016 at 22:19, MichaelAtOz <oz.at.michael@gmail.com> wrote: > >> Thanks. Nice use of a "side-effect" which I thought we didn't allow? >> Seems to be the main argument against echof() >> <https://github.com/openscad/openscad/issues/741> >> >> >> >> ----- >> Newly minted Admin - PM me if you need anything, or if I've done >> something stupid... >> >> Unless specifically shown otherwise above, my contribution is in the >> Public Domain; to the extent possible under law, I have waived all >> copyright and related or neighbouring rights to this work. Obviously >> inclusion of works of previous authors is not included in the above. >> >> The TPP is no simple “trade agreement.” Fight it! >> http://www.ourfairdeal.org/ time is running out! >> -- >> View this message in context: >> http://forum.openscad.org/debug-print-in-openscad-functions-tp15683p15685.html >> Sent from the OpenSCAD mailing list archive at Nabble.com. >> >> _______________________________________________ >> 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 > >
NH
nop head
Fri, Jan 15, 2016 5:05 PM

Well actually I think echo is run while the CSG tree is being made from the
AST tree, which is a serial process and unlikely to be the bit paralleled
for speed, which would be evaluating the CSG tree to create geometry.

As I said before if you consider the console text as part of the result it
is no longer a side effect any more than creating geometry and rendering it
on the screen is. It doesn't create any side effect type problems like
mutable variables do because its effect is external to the program.

If any debug information needs to be output during the geometry creation it
isn't a problem either. Any parallel execution has to evaluate the children
of a node before it can use the results to do its operation. As long as the
text from echo is returned as part of the value of the child node instead
of being immediately printed the tree can be used to render it in the
console in the correct order. I.e. each node evaluates it children
(potentially in parallel) and returns the geometry to is parent. I can all
receive debug strings from its children, concatenate them and return them
to its parent. The text will still be in the same order regardless of
parallelism. Also any optimisation that caches geometry has to cache the
string as well.

Echo in expressions can be handled exactly the same way and produce
deterministic results despite parallelism and caching, just the same as the
expression value is deterministic.

If you can get a deterministic result from attaching metadata then you can
also make echo work as you can consider it a special case of metadata.

On 15 January 2016 at 16:17, doug moen doug@moens.org wrote:

The "search" function is badly designed. It prints those warning messages
because
search("large", [["large",42], ["medium",17], ["small",5]])
does not do what it should do.

We should deprecate "search" and replace it with something simpler and
better behaved. A lot of people who need this functionality have already
done this, by writing their own function. My preferred interface looks like
this:
lookup(key, [[key1,value1], [key2,value2], ...])
returns the value associated with the key argument, or returns undef if
there is no match. Works with any type of key for which equality is
defined, including strings and lists.

There is nothing wrong with adding an "echof" function as an aid in
debugging functions. It's no worse than "echo". This is needed as a debug
feature, since OpenSCAD doesn't have proper debug facilities. But we should
be aiming higher, at providing a proper debugger UI in a future release. If
you could use a debugger to set "watchpoints" that print a trace message to
the console each time a particular expression is evaluated, then you could
debug a program without cluttering up the source code with echo statements.

OpenSCAD is a declarative language. Ideally, it has no side effects, and
it has no defined evaluation order, which gives the implementation maximum
flexibility to compile scripts into a form that execute quickly. For
example,

- Suppose that an expensive-to-compute subexpression occurs inside a
for loop, but doesn't depend on the iteration variable. An optimizing
compiler can lift that subexpression outside of the loop, and only evaluate
it once.
- If the same subexpression occurs multiple times, the compiler can
recognize this and arrange to only evaluate the expression once, caching
the result for later use.
- Declarative programs can be automatically parallelized, so that
multiple cores are used to simultaneously evaluate different parts of the
program.

Debugging tools expose the evaluation order. That's inevitable. A problem
with 'echo' and 'echof' is that they are part of the language, and users
might come to rely on a particular script producing echo output in a
particular order. I think we should make it clear that 'echo' is only a
debug feature, that there is no defined evaluation order, and that the
evaluation order can change across releases, or vary depending on the
hardware and operating system. With multi-core evaluation, the evaluation
order can change from one run to the next.

I know that people use 'echo' to generate a bill of materials. We should
provide a more declarative way to do this. In OpenSCAD2, I've provided a
mechanism for attaching user-defined metadata to geometric shapes, and I
also explain how to use this to generate a BOM declaratively, without using
echo.

Remember that in a declarative language, the evaluation order is something
internal to the implementation, it does not (should not) affect the final
result. Otherwise it's a bug. In OpenSCAD, the final result is usually the
geometry, but in the above example it's the BOM, if the BOM is defined
declaratively using metadata.

On 15 January 2016 at 03:47, nop head nop.head@gmail.com wrote:

If you accept that functions can return a debug string as well as a value
then it is no longer a side effect. If you cache the value of the function
for optimisation then you also have to cache the string and emit it
whenever you use the cached value. The same with echo in modules and
geometry.

On 14 January 2016 at 22:19, MichaelAtOz oz.at.michael@gmail.com wrote:

Thanks. Nice use of a "side-effect" which I thought we didn't allow?
Seems to be the main argument against  echof()
https://github.com/openscad/openscad/issues/741


Newly minted Admin - PM me if you need anything, or if I've done
something stupid...

Unless specifically shown otherwise above, my contribution is in the
Public Domain; to the extent possible under law, I have waived all
copyright and related or neighbouring rights to this work. Obviously
inclusion of works of previous authors is not included in the above.

The TPP is no simple “trade agreement.”  Fight it!
http://www.ourfairdeal.org/  time is running out!

View this message in context:
http://forum.openscad.org/debug-print-in-openscad-functions-tp15683p15685.html
Sent from the OpenSCAD mailing list archive at Nabble.com.


OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

Well actually I think echo is run while the CSG tree is being made from the AST tree, which is a serial process and unlikely to be the bit paralleled for speed, which would be evaluating the CSG tree to create geometry. As I said before if you consider the console text as part of the result it is no longer a side effect any more than creating geometry and rendering it on the screen is. It doesn't create any side effect type problems like mutable variables do because its effect is external to the program. If any debug information needs to be output during the geometry creation it isn't a problem either. Any parallel execution has to evaluate the children of a node before it can use the results to do its operation. As long as the text from echo is returned as part of the value of the child node instead of being immediately printed the tree can be used to render it in the console in the correct order. I.e. each node evaluates it children (potentially in parallel) and returns the geometry to is parent. I can all receive debug strings from its children, concatenate them and return them to its parent. The text will still be in the same order regardless of parallelism. Also any optimisation that caches geometry has to cache the string as well. Echo in expressions can be handled exactly the same way and produce deterministic results despite parallelism and caching, just the same as the expression value is deterministic. If you can get a deterministic result from attaching metadata then you can also make echo work as you can consider it a special case of metadata. On 15 January 2016 at 16:17, doug moen <doug@moens.org> wrote: > The "search" function is badly designed. It prints those warning messages > because > search("large", [["large",42], ["medium",17], ["small",5]]) > does not do what it should do. > > We should deprecate "search" and replace it with something simpler and > better behaved. A lot of people who need this functionality have already > done this, by writing their own function. My preferred interface looks like > this: > lookup(key, [[key1,value1], [key2,value2], ...]) > returns the value associated with the key argument, or returns undef if > there is no match. Works with any type of key for which equality is > defined, including strings and lists. > > There is nothing wrong with adding an "echof" function as an aid in > debugging functions. It's no worse than "echo". This is needed as a debug > feature, since OpenSCAD doesn't have proper debug facilities. But we should > be aiming higher, at providing a proper debugger UI in a future release. If > you could use a debugger to set "watchpoints" that print a trace message to > the console each time a particular expression is evaluated, then you could > debug a program without cluttering up the source code with echo statements. > > OpenSCAD is a declarative language. Ideally, it has no side effects, and > it has no defined evaluation order, which gives the implementation maximum > flexibility to compile scripts into a form that execute quickly. For > example, > > - Suppose that an expensive-to-compute subexpression occurs inside a > for loop, but doesn't depend on the iteration variable. An optimizing > compiler can lift that subexpression outside of the loop, and only evaluate > it once. > - If the same subexpression occurs multiple times, the compiler can > recognize this and arrange to only evaluate the expression once, caching > the result for later use. > - Declarative programs can be automatically parallelized, so that > multiple cores are used to simultaneously evaluate different parts of the > program. > > Debugging tools expose the evaluation order. That's inevitable. A problem > with 'echo' and 'echof' is that they are part of the language, and users > might come to rely on a particular script producing echo output in a > particular order. I think we should make it clear that 'echo' is only a > debug feature, that there is no defined evaluation order, and that the > evaluation order can change across releases, or vary depending on the > hardware and operating system. With multi-core evaluation, the evaluation > order can change from one run to the next. > > I know that people use 'echo' to generate a bill of materials. We should > provide a more declarative way to do this. In OpenSCAD2, I've provided a > mechanism for attaching user-defined metadata to geometric shapes, and I > also explain how to use this to generate a BOM declaratively, without using > echo. > > Remember that in a declarative language, the evaluation order is something > internal to the implementation, it does not (should not) affect the final > result. Otherwise it's a bug. In OpenSCAD, the final result is usually the > geometry, but in the above example it's the BOM, if the BOM is defined > declaratively using metadata. > > > On 15 January 2016 at 03:47, nop head <nop.head@gmail.com> wrote: > >> If you accept that functions can return a debug string as well as a value >> then it is no longer a side effect. If you cache the value of the function >> for optimisation then you also have to cache the string and emit it >> whenever you use the cached value. The same with echo in modules and >> geometry. >> >> On 14 January 2016 at 22:19, MichaelAtOz <oz.at.michael@gmail.com> wrote: >> >>> Thanks. Nice use of a "side-effect" which I thought we didn't allow? >>> Seems to be the main argument against echof() >>> <https://github.com/openscad/openscad/issues/741> >>> >>> >>> >>> ----- >>> Newly minted Admin - PM me if you need anything, or if I've done >>> something stupid... >>> >>> Unless specifically shown otherwise above, my contribution is in the >>> Public Domain; to the extent possible under law, I have waived all >>> copyright and related or neighbouring rights to this work. Obviously >>> inclusion of works of previous authors is not included in the above. >>> >>> The TPP is no simple “trade agreement.” Fight it! >>> http://www.ourfairdeal.org/ time is running out! >>> -- >>> View this message in context: >>> http://forum.openscad.org/debug-print-in-openscad-functions-tp15683p15685.html >>> Sent from the OpenSCAD mailing list archive at Nabble.com. >>> >>> _______________________________________________ >>> OpenSCAD mailing list >>> Discuss@lists.openscad.org >>> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >>> >> >> >> _______________________________________________ >> OpenSCAD mailing list >> Discuss@lists.openscad.org >> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >> >> > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org > >
J
johnmdanskin
Fri, Jan 15, 2016 6:05 PM

I agree that the search function isn't ideal. The only use I can think of for
the current search function is to generate the side effect statements. A
user defined lookup function is only 3ish lines of code (wrote one last
night), so I don't really feel the lack.

As a person trying to debug functions, my most common problem, or at least
the only common problem I actually remember, is infinite recursion. Somehow
I make a mistake, the stupid thing won't stop, and all I get is "Recursion
Detected". If functions returned a debug string, that wouldn't help because
my problem is that the function never returns.  As someone who is just
looking for a freaking debugging clue, any theoretical non-determinism
wouldn't be nearly as irritating as not being able to debug.

I'd be really sad if we couldn't implement echof because really we should
have an IDE.  As a side point, an IDE would also expose execution order and
the presence or absence of caching.

About 100 years ago, I wrote a language that worked a lot like OpenSCAD. I
appreciate the functional issues. I admire the decisions that have been
made. In most ways, OpenSCAD is a thing of  beauty.

Echof is a side-effect, but it doesn't actually influence program execution.
Since it doesn't influence program execution, it shouldn't be a programming
model issue.

--
View this message in context: http://forum.openscad.org/debug-print-in-openscad-functions-tp15683p15707.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

I agree that the search function isn't ideal. The only use I can think of for the current search function is to generate the side effect statements. A user defined lookup function is only 3ish lines of code (wrote one last night), so I don't really feel the lack. As a person trying to debug functions, my most common problem, or at least the only common problem I actually remember, is infinite recursion. Somehow I make a mistake, the stupid thing won't stop, and all I get is "Recursion Detected". If functions returned a debug string, that wouldn't help because my problem is that the function never returns. As someone who is just looking for a freaking debugging clue, any theoretical non-determinism wouldn't be nearly as irritating as not being able to debug. I'd be really sad if we couldn't implement echof because really we should have an IDE. As a side point, an IDE would also expose execution order and the presence or absence of caching. About 100 years ago, I wrote a language that worked a lot like OpenSCAD. I appreciate the functional issues. I admire the decisions that have been made. In most ways, OpenSCAD is a thing of beauty. Echof is a side-effect, but it doesn't actually influence program execution. Since it doesn't influence program execution, it shouldn't be a programming model issue. -- View this message in context: http://forum.openscad.org/debug-print-in-openscad-functions-tp15683p15707.html Sent from the OpenSCAD mailing list archive at Nabble.com.
DM
doug moen
Fri, Jan 15, 2016 7:21 PM

There's a design flaw in our geometry cache, which caches geometry across
different script evaluations. The problem is that CGAL messages which
appear the first time, do not appear during subsequent F5/F6 evaluations.
This is annoying and should be fixed. I agree that the fix will have to
involve caching the CGAL messages together with the cached geometry.

I consider this issue separate from the issue of making the script
evaluator run faster, using the standard techniques that are available to
declarative and functional languages. In the latter case, I am quite sure
that we don't want to prohibit the use of optimizations because somebody
might use echo to debug a script.

Yes, echo and echof produce side effects. Optimizations will often change
those side effects, even though the result is the same:

  • an optimization might avoid evaluating a module or expression multiple
    times, because the result is the same each time. This means the echo
    happens only once instead of multiple times.
  • an optimization can change the order of evaluation. This doesn't
    affect the result, but the echos will now occur in a different order.
  • an optimization can decide not to evaluate a function or module call,
    because the optimizer can prove that the result has no effect on the
    geometric output. This means the echo doesn't occur.

Echo is not the same thing as metadata. These optimizations apply equally
well to geometry nodes that contain metadata.

If we agree that caching evaluation results across different script
evaluations
needs to be treated more carefully, then can we agree that it
is okay to use agressive performance optimizations within a single script
evaluation?

Nop Head said:

Well actually I think echo is run while the CSG tree is being made from

the AST tree, which is a serial process and unlikely to be the bit
paralleled for speed, which would be evaluating the CSG tree to create
geometry.

Historically, it's true that OpenSCAD is designed to have a script
evaluation phase, which isn't performance critical, followed by a geometry
evaluation phase (currently using CGAL) which is very performance
sensitive. But if you look at how the language is being used now, and at
the pull request for 'probe', then that may no longer be an accurate way to
think about performance.

  1. OpenSCAD has poor support for creating curved surfaces, so we now
    have libraries that build curved surfaces using polyhedron(), such as the
    new spline library. This means we are now increasingly doing our geometry
    computations in the OpenSCAD scripting language, instead of in CGAL.
  2. There is a pull request for a 'probe' function, which performs a CGAL
    computation, then makes the results available to the function, expression
    and variable part of the scripting language. One request in that thread is
    to make the vertices and faces available, presumably so they can be
    transformed and fed back into polyhedron using the scripting language. This
    could greatly increase the extent to which CGAL and script evaluation are
    interleaved.

If the scripting language is being called upon to do the heavy lifting of
geometry evaluation, as an adjunct to CGAL, then yes maybe we will need to
consider parallel script evaluation.

On 15 January 2016 at 12:05, nop head nop.head@gmail.com wrote:

Well actually I think echo is run while the CSG tree is being made from
the AST tree, which is a serial process and unlikely to be the bit
paralleled for speed, which would be evaluating the CSG tree to create
geometry.

As I said before if you consider the console text as part of the result it
is no longer a side effect any more than creating geometry and rendering it
on the screen is. It doesn't create any side effect type problems like
mutable variables do because its effect is external to the program.

If any debug information needs to be output during the geometry creation
it isn't a problem either. Any parallel execution has to evaluate the
children of a node before it can use the results to do its operation. As
long as the text from echo is returned as part of the value of the child
node instead of being immediately printed the tree can be used to render it
in the console in the correct order. I.e. each node evaluates it children
(potentially in parallel) and returns the geometry to is parent. I can all
receive debug strings from its children, concatenate them and return them
to its parent. The text will still be in the same order regardless of
parallelism. Also any optimisation that caches geometry has to cache the
string as well.

Echo in expressions can be handled exactly the same way and produce
deterministic results despite parallelism and caching, just the same as the
expression value is deterministic.

If you can get a deterministic result from attaching metadata then you can
also make echo work as you can consider it a special case of metadata.

On 15 January 2016 at 16:17, doug moen doug@moens.org wrote:

The "search" function is badly designed. It prints those warning messages
because
search("large", [["large",42], ["medium",17], ["small",5]])
does not do what it should do.

We should deprecate "search" and replace it with something simpler and
better behaved. A lot of people who need this functionality have already
done this, by writing their own function. My preferred interface looks like
this:
lookup(key, [[key1,value1], [key2,value2], ...])
returns the value associated with the key argument, or returns undef if
there is no match. Works with any type of key for which equality is
defined, including strings and lists.

There is nothing wrong with adding an "echof" function as an aid in
debugging functions. It's no worse than "echo". This is needed as a debug
feature, since OpenSCAD doesn't have proper debug facilities. But we should
be aiming higher, at providing a proper debugger UI in a future release. If
you could use a debugger to set "watchpoints" that print a trace message to
the console each time a particular expression is evaluated, then you could
debug a program without cluttering up the source code with echo statements.

OpenSCAD is a declarative language. Ideally, it has no side effects, and
it has no defined evaluation order, which gives the implementation maximum
flexibility to compile scripts into a form that execute quickly. For
example,

- Suppose that an expensive-to-compute subexpression occurs inside a
for loop, but doesn't depend on the iteration variable. An optimizing
compiler can lift that subexpression outside of the loop, and only evaluate
it once.
- If the same subexpression occurs multiple times, the compiler can
recognize this and arrange to only evaluate the expression once, caching
the result for later use.
- Declarative programs can be automatically parallelized, so that
multiple cores are used to simultaneously evaluate different parts of the
program.

Debugging tools expose the evaluation order. That's inevitable. A problem
with 'echo' and 'echof' is that they are part of the language, and users
might come to rely on a particular script producing echo output in a
particular order. I think we should make it clear that 'echo' is only a
debug feature, that there is no defined evaluation order, and that the
evaluation order can change across releases, or vary depending on the
hardware and operating system. With multi-core evaluation, the evaluation
order can change from one run to the next.

I know that people use 'echo' to generate a bill of materials. We should
provide a more declarative way to do this. In OpenSCAD2, I've provided a
mechanism for attaching user-defined metadata to geometric shapes, and I
also explain how to use this to generate a BOM declaratively, without using
echo.

Remember that in a declarative language, the evaluation order is
something internal to the implementation, it does not (should not) affect
the final result. Otherwise it's a bug. In OpenSCAD, the final result is
usually the geometry, but in the above example it's the BOM, if the BOM is
defined declaratively using metadata.

On 15 January 2016 at 03:47, nop head nop.head@gmail.com wrote:

If you accept that functions can return a debug string as well as a
value then it is no longer a side effect. If you cache the value of the
function for optimisation then you also have to cache the string and emit
it whenever you use the cached value. The same with echo in modules and
geometry.

On 14 January 2016 at 22:19, MichaelAtOz oz.at.michael@gmail.com
wrote:

Thanks. Nice use of a "side-effect" which I thought we didn't allow?
Seems to be the main argument against  echof()
https://github.com/openscad/openscad/issues/741


Newly minted Admin - PM me if you need anything, or if I've done
something stupid...

Unless specifically shown otherwise above, my contribution is in the
Public Domain; to the extent possible under law, I have waived all
copyright and related or neighbouring rights to this work. Obviously
inclusion of works of previous authors is not included in the above.

The TPP is no simple “trade agreement.”  Fight it!
http://www.ourfairdeal.org/  time is running out!

View this message in context:
http://forum.openscad.org/debug-print-in-openscad-functions-tp15683p15685.html
Sent from the OpenSCAD mailing list archive at Nabble.com.


OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

There's a design flaw in our geometry cache, which caches geometry across different script evaluations. The problem is that CGAL messages which appear the first time, do not appear during subsequent F5/F6 evaluations. This is annoying and should be fixed. I agree that the fix will have to involve caching the CGAL messages together with the cached geometry. I consider this issue separate from the issue of making the script evaluator run faster, using the standard techniques that are available to declarative and functional languages. In the latter case, I am quite sure that we don't want to prohibit the use of optimizations because somebody might use echo to debug a script. Yes, echo and echof produce side effects. Optimizations will often change those side effects, even though the result is the same: - an optimization might avoid evaluating a module or expression multiple times, because the result is the same each time. This means the echo happens only once instead of multiple times. - an optimization can change the order of evaluation. This doesn't affect the result, but the echos will now occur in a different order. - an optimization can decide not to evaluate a function or module call, because the optimizer can prove that the result has no effect on the geometric output. This means the echo doesn't occur. Echo is not the same thing as metadata. These optimizations apply equally well to geometry nodes that contain metadata. If we agree that caching evaluation results *across different script evaluations* needs to be treated more carefully, then can we agree that it is okay to use agressive performance optimizations *within* a single script evaluation? Nop Head said: >Well actually I think echo is run while the CSG tree is being made from the AST tree, which is a serial process and unlikely to be the bit paralleled for speed, which would be evaluating the CSG tree to create geometry. Historically, it's true that OpenSCAD is designed to have a script evaluation phase, which isn't performance critical, followed by a geometry evaluation phase (currently using CGAL) which is very performance sensitive. But if you look at how the language is being used now, and at the pull request for 'probe', then that may no longer be an accurate way to think about performance. 1. OpenSCAD has poor support for creating curved surfaces, so we now have libraries that build curved surfaces using polyhedron(), such as the new spline library. This means we are now increasingly doing our geometry computations in the OpenSCAD scripting language, instead of in CGAL. 2. There is a pull request for a 'probe' function, which performs a CGAL computation, then makes the results available to the function, expression and variable part of the scripting language. One request in that thread is to make the vertices and faces available, presumably so they can be transformed and fed back into polyhedron using the scripting language. This could greatly increase the extent to which CGAL and script evaluation are interleaved. If the scripting language is being called upon to do the heavy lifting of geometry evaluation, as an adjunct to CGAL, then yes maybe we will need to consider parallel script evaluation. On 15 January 2016 at 12:05, nop head <nop.head@gmail.com> wrote: > Well actually I think echo is run while the CSG tree is being made from > the AST tree, which is a serial process and unlikely to be the bit > paralleled for speed, which would be evaluating the CSG tree to create > geometry. > > As I said before if you consider the console text as part of the result it > is no longer a side effect any more than creating geometry and rendering it > on the screen is. It doesn't create any side effect type problems like > mutable variables do because its effect is external to the program. > > If any debug information needs to be output during the geometry creation > it isn't a problem either. Any parallel execution has to evaluate the > children of a node before it can use the results to do its operation. As > long as the text from echo is returned as part of the value of the child > node instead of being immediately printed the tree can be used to render it > in the console in the correct order. I.e. each node evaluates it children > (potentially in parallel) and returns the geometry to is parent. I can all > receive debug strings from its children, concatenate them and return them > to its parent. The text will still be in the same order regardless of > parallelism. Also any optimisation that caches geometry has to cache the > string as well. > > Echo in expressions can be handled exactly the same way and produce > deterministic results despite parallelism and caching, just the same as the > expression value is deterministic. > > If you can get a deterministic result from attaching metadata then you can > also make echo work as you can consider it a special case of metadata. > > > > On 15 January 2016 at 16:17, doug moen <doug@moens.org> wrote: > >> The "search" function is badly designed. It prints those warning messages >> because >> search("large", [["large",42], ["medium",17], ["small",5]]) >> does not do what it should do. >> >> We should deprecate "search" and replace it with something simpler and >> better behaved. A lot of people who need this functionality have already >> done this, by writing their own function. My preferred interface looks like >> this: >> lookup(key, [[key1,value1], [key2,value2], ...]) >> returns the value associated with the key argument, or returns undef if >> there is no match. Works with any type of key for which equality is >> defined, including strings and lists. >> >> There is nothing wrong with adding an "echof" function as an aid in >> debugging functions. It's no worse than "echo". This is needed as a debug >> feature, since OpenSCAD doesn't have proper debug facilities. But we should >> be aiming higher, at providing a proper debugger UI in a future release. If >> you could use a debugger to set "watchpoints" that print a trace message to >> the console each time a particular expression is evaluated, then you could >> debug a program without cluttering up the source code with echo statements. >> >> OpenSCAD is a declarative language. Ideally, it has no side effects, and >> it has no defined evaluation order, which gives the implementation maximum >> flexibility to compile scripts into a form that execute quickly. For >> example, >> >> - Suppose that an expensive-to-compute subexpression occurs inside a >> for loop, but doesn't depend on the iteration variable. An optimizing >> compiler can lift that subexpression outside of the loop, and only evaluate >> it once. >> - If the same subexpression occurs multiple times, the compiler can >> recognize this and arrange to only evaluate the expression once, caching >> the result for later use. >> - Declarative programs can be automatically parallelized, so that >> multiple cores are used to simultaneously evaluate different parts of the >> program. >> >> Debugging tools expose the evaluation order. That's inevitable. A problem >> with 'echo' and 'echof' is that they are part of the language, and users >> might come to rely on a particular script producing echo output in a >> particular order. I think we should make it clear that 'echo' is only a >> debug feature, that there is no defined evaluation order, and that the >> evaluation order can change across releases, or vary depending on the >> hardware and operating system. With multi-core evaluation, the evaluation >> order can change from one run to the next. >> >> I know that people use 'echo' to generate a bill of materials. We should >> provide a more declarative way to do this. In OpenSCAD2, I've provided a >> mechanism for attaching user-defined metadata to geometric shapes, and I >> also explain how to use this to generate a BOM declaratively, without using >> echo. >> >> Remember that in a declarative language, the evaluation order is >> something internal to the implementation, it does not (should not) affect >> the final result. Otherwise it's a bug. In OpenSCAD, the final result is >> usually the geometry, but in the above example it's the BOM, if the BOM is >> defined declaratively using metadata. >> >> >> On 15 January 2016 at 03:47, nop head <nop.head@gmail.com> wrote: >> >>> If you accept that functions can return a debug string as well as a >>> value then it is no longer a side effect. If you cache the value of the >>> function for optimisation then you also have to cache the string and emit >>> it whenever you use the cached value. The same with echo in modules and >>> geometry. >>> >>> On 14 January 2016 at 22:19, MichaelAtOz <oz.at.michael@gmail.com> >>> wrote: >>> >>>> Thanks. Nice use of a "side-effect" which I thought we didn't allow? >>>> Seems to be the main argument against echof() >>>> <https://github.com/openscad/openscad/issues/741> >>>> >>>> >>>> >>>> ----- >>>> Newly minted Admin - PM me if you need anything, or if I've done >>>> something stupid... >>>> >>>> Unless specifically shown otherwise above, my contribution is in the >>>> Public Domain; to the extent possible under law, I have waived all >>>> copyright and related or neighbouring rights to this work. Obviously >>>> inclusion of works of previous authors is not included in the above. >>>> >>>> The TPP is no simple “trade agreement.” Fight it! >>>> http://www.ourfairdeal.org/ time is running out! >>>> -- >>>> View this message in context: >>>> http://forum.openscad.org/debug-print-in-openscad-functions-tp15683p15685.html >>>> Sent from the OpenSCAD mailing list archive at Nabble.com. >>>> >>>> _______________________________________________ >>>> OpenSCAD mailing list >>>> Discuss@lists.openscad.org >>>> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >>>> >>> >>> >>> _______________________________________________ >>> OpenSCAD mailing list >>> Discuss@lists.openscad.org >>> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >>> >>> >> >> _______________________________________________ >> OpenSCAD mailing list >> Discuss@lists.openscad.org >> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >> >> > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org > >
DM
doug moen
Fri, Jan 15, 2016 7:40 PM

Yes, I would like us to have echof.

But I want the easy-to-implement version of echof that outputs text to the
console as a side effect, and is used for debugging. With this version,
internal performance optimizations are fully visible via echof. If your
function isn't called at all, or called only once instead of several times,
due to a performance optimization, then you'll see this in the echof
output, and it will help you to understand what's going on during script
evaluation. This is particularly useful if you are debugging a performance
problem.

What I don't want is a denotational semantics for OpenSCAD where echof is
given a declarative semantics, and optimizations need to be suppressed when
echof is used. That increases the complexity of the implementation, and
decreases the utility of echof for debugging.

On 15 January 2016 at 13:05, johnmdanskin johnmdanskin@gmail.com wrote:

I agree that the search function isn't ideal. The only use I can think of
for
the current search function is to generate the side effect statements. A
user defined lookup function is only 3ish lines of code (wrote one last
night), so I don't really feel the lack.

As a person trying to debug functions, my most common problem, or at least
the only common problem I actually remember, is infinite recursion. Somehow
I make a mistake, the stupid thing won't stop, and all I get is "Recursion
Detected". If functions returned a debug string, that wouldn't help because
my problem is that the function never returns.  As someone who is just
looking for a freaking debugging clue, any theoretical non-determinism
wouldn't be nearly as irritating as not being able to debug.

I'd be really sad if we couldn't implement echof because really we should
have an IDE.  As a side point, an IDE would also expose execution order and
the presence or absence of caching.

About 100 years ago, I wrote a language that worked a lot like OpenSCAD. I
appreciate the functional issues. I admire the decisions that have been
made. In most ways, OpenSCAD is a thing of  beauty.

Echof is a side-effect, but it doesn't actually influence program
execution.
Since it doesn't influence program execution, it shouldn't be a programming
model issue.

--
View this message in context:
http://forum.openscad.org/debug-print-in-openscad-functions-tp15683p15707.html
Sent from the OpenSCAD mailing list archive at Nabble.com.


OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

Yes, I would like us to have echof. But I want the easy-to-implement version of echof that outputs text to the console as a side effect, and is used for debugging. With this version, internal performance optimizations are fully visible via echof. If your function isn't called at all, or called only once instead of several times, due to a performance optimization, then you'll see this in the echof output, and it will help you to understand what's going on during script evaluation. This is particularly useful if you are debugging a performance problem. What I don't want is a denotational semantics for OpenSCAD where echof is given a declarative semantics, and optimizations need to be suppressed when echof is used. That increases the complexity of the implementation, and decreases the utility of echof for debugging. On 15 January 2016 at 13:05, johnmdanskin <johnmdanskin@gmail.com> wrote: > I agree that the search function isn't ideal. The only use I can think of > for > the current search function is to generate the side effect statements. A > user defined lookup function is only 3ish lines of code (wrote one last > night), so I don't really feel the lack. > > As a person trying to debug functions, my most common problem, or at least > the only common problem I actually remember, is infinite recursion. Somehow > I make a mistake, the stupid thing won't stop, and all I get is "Recursion > Detected". If functions returned a debug string, that wouldn't help because > my problem is that the function never returns. As someone who is just > looking for a freaking debugging clue, any theoretical non-determinism > wouldn't be nearly as irritating as not being able to debug. > > I'd be really sad if we couldn't implement echof because really we should > have an IDE. As a side point, an IDE would also expose execution order and > the presence or absence of caching. > > About 100 years ago, I wrote a language that worked a lot like OpenSCAD. I > appreciate the functional issues. I admire the decisions that have been > made. In most ways, OpenSCAD is a thing of beauty. > > Echof is a side-effect, but it doesn't actually influence program > execution. > Since it doesn't influence program execution, it shouldn't be a programming > model issue. > > > > > -- > View this message in context: > http://forum.openscad.org/debug-print-in-openscad-functions-tp15683p15707.html > Sent from the OpenSCAD mailing list archive at Nabble.com. > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org > > >
TP
Torsten Paul
Fri, Jan 15, 2016 7:52 PM

On 01/15/2016 08:40 PM, doug moen wrote:

Yes, I would like us to have echof.

Ok then, to make it easier to use, what about:

  • just call it echo() instead of echof()

  • have it declared like echo(result, ...)

    where it returns the value that is either the first positional
    argument or the argument named result (to match the argument
    behavior of module instantiations).

  • all arguments are printed as with the module echo()

  • if the function echo() is called with no argument, it will
    return undef.

ciao,
Torsten.

On 01/15/2016 08:40 PM, doug moen wrote: > Yes, I would like us to have echof. > Ok then, to make it easier to use, what about: - just call it echo() instead of echof() - have it declared like echo(result, ...) where it returns the value that is either the first positional argument or the argument named result (to match the argument behavior of module instantiations). - all arguments are printed as with the module echo() - if the function echo() is called with no argument, it will return undef. ciao, Torsten.
NH
nop head
Fri, Jan 15, 2016 8:14 PM

On 15 January 2016 at 19:21, doug moen doug@moens.org wrote:

There's a design flaw in our geometry cache, which caches geometry across
different script evaluations. The problem is that CGAL messages which
appear the first time, do not appear during subsequent F5/F6 evaluations.
This is annoying and should be fixed. I agree that the fix will have to
involve caching the CGAL messages together with the cached geometry.

Agreed. And the same mechanism can be used for echof in functions if the
functions get memoized.

I consider this issue separate from the issue of making the script
evaluator run faster, using the standard techniques that are available to
declarative and functional languages. In the latter case, I am quite sure
that we don't want to prohibit the use of optimizations because somebody
might use echo to debug a script.

No but you can recognise that the presence of echo locally means you can't
rearrange the code if it would change the text. It is quite normal to
disable optimisations when debugging code. I don't see a need for echof
once the bug is found. I don't think the same applies to echo in modules /
the geometry tree however and the order of evaluation doesn't matter as
long as the strings are combined alongside the geometry results.

Yes, echo and echof produce side effects. Optimizations will often change
those side effects, even though the result is the same:

- an optimization might avoid evaluating a module or expression
multiple times, because the result is the same each time. This means the
echo happens only once instead of multiple times.
- an optimization can change the order of evaluation. This doesn't
affect the result, but the echos will now occur in a different order.
- an optimization can decide not to evaluate a function or module
call, because the optimizer can prove that the result has no effect on the
geometric output. This means the echo doesn't occur.

All these things make debugging totally confusing unless you can disable

them. The last time I used Microsoft Visual Studio debug mode disabled all
optimisations and ran about 10 times slower. It was possible to run the
debugger on release mode code but it was mighty confusing. For example you
could have simple functions in unrelated classes, such as property
accessors, that produce the same machine code but have totally different
names. In release mode they all get combined so you step through one class
and and see it call a completely unrelated one. But if you put printf in,
it still produces the correct results in release mode because the optimiser
knows it can't remove or reorder the code so it prints differently. Nobody
complains their code runs slower due to the presence of debugging code they
put in. It does sometimes create Heisenbugs though.

Echo is not the same thing as metadata. These optimizations apply equally
well to geometry nodes that contain metadata.

I don't understand that. If I make a bom with metadata I want it to be the
same as one I currently create with echo, so if you handle metadata
correctly, so that it is the same, then you can handle echo the same way.

If we agree that caching evaluation results across different script
evaluations
needs to be treated more carefully, then can we agree that it
is okay to use agressive performance optimizations within a single script
evaluation?

Yes but I think echo is not a side effect, just as the geometry is not a
side effect, so you can do whatever optimisations don't affect the geometry
and don't change what is echoed.

Nop Head said:

Well actually I think echo is run while the CSG tree is being made from

the AST tree, which is a serial process and unlikely to be the bit
paralleled for speed, which would be evaluating the CSG tree to create
geometry.

Historically, it's true that OpenSCAD is designed to have a script
evaluation phase, which isn't performance critical, followed by a geometry
evaluation phase (currently using CGAL) which is very performance
sensitive. But if you look at how the language is being used now, and at
the pull request for 'probe', then that may no longer be an accurate way to
think about performance.

1. OpenSCAD has poor support for creating curved surfaces, so we now
have libraries that build curved surfaces using polyhedron(), such as the
new spline library. This means we are now increasingly doing our geometry
computations in the OpenSCAD scripting language, instead of in CGAL.
2. There is a pull request for a 'probe' function, which performs a
CGAL computation, then makes the results available to the function,
expression and variable part of the scripting language. One request in that
thread is to make the vertices and faces available, presumably so they can
be transformed and fed back into polyhedron using the scripting language.
This could greatly increase the extent to which CGAL and script evaluation
are interleaved.

If the scripting language is being called upon to do the heavy lifting of
geometry evaluation, as an adjunct to CGAL, then yes maybe we will need to
consider parallel script evaluation.

Yes but as I described before, echo in modules does not prevent them being
run in parallel or in any order as long as the text is gathered from the
children and concatenated in the right order and passed up to the parent,
just the same as the geometry.

On 15 January 2016 at 12:05, nop head nop.head@gmail.com wrote:

Well actually I think echo is run while the CSG tree is being made from
the AST tree, which is a serial process and unlikely to be the bit
paralleled for speed, which would be evaluating the CSG tree to create
geometry.

As I said before if you consider the console text as part of the result
it is no longer a side effect any more than creating geometry and rendering
it on the screen is. It doesn't create any side effect type problems like
mutable variables do because its effect is external to the program.

If any debug information needs to be output during the geometry creation
it isn't a problem either. Any parallel execution has to evaluate the
children of a node before it can use the results to do its operation. As
long as the text from echo is returned as part of the value of the child
node instead of being immediately printed the tree can be used to render it
in the console in the correct order. I.e. each node evaluates it children
(potentially in parallel) and returns the geometry to is parent. I can all
receive debug strings from its children, concatenate them and return them
to its parent. The text will still be in the same order regardless of
parallelism. Also any optimisation that caches geometry has to cache the
string as well.

Echo in expressions can be handled exactly the same way and produce
deterministic results despite parallelism and caching, just the same as the
expression value is deterministic.

If you can get a deterministic result from attaching metadata then you
can also make echo work as you can consider it a special case of metadata.

On 15 January 2016 at 16:17, doug moen doug@moens.org wrote:

The "search" function is badly designed. It prints those warning
messages because
search("large", [["large",42], ["medium",17], ["small",5]])
does not do what it should do.

We should deprecate "search" and replace it with something simpler and
better behaved. A lot of people who need this functionality have already
done this, by writing their own function. My preferred interface looks like
this:
lookup(key, [[key1,value1], [key2,value2], ...])
returns the value associated with the key argument, or returns undef if
there is no match. Works with any type of key for which equality is
defined, including strings and lists.

There is nothing wrong with adding an "echof" function as an aid in
debugging functions. It's no worse than "echo". This is needed as a debug
feature, since OpenSCAD doesn't have proper debug facilities. But we should
be aiming higher, at providing a proper debugger UI in a future release. If
you could use a debugger to set "watchpoints" that print a trace message to
the console each time a particular expression is evaluated, then you could
debug a program without cluttering up the source code with echo statements.

OpenSCAD is a declarative language. Ideally, it has no side effects, and
it has no defined evaluation order, which gives the implementation maximum
flexibility to compile scripts into a form that execute quickly. For
example,

- Suppose that an expensive-to-compute subexpression occurs inside a
for loop, but doesn't depend on the iteration variable. An optimizing
compiler can lift that subexpression outside of the loop, and only evaluate
it once.
- If the same subexpression occurs multiple times, the compiler can
recognize this and arrange to only evaluate the expression once, caching
the result for later use.
- Declarative programs can be automatically parallelized, so that
multiple cores are used to simultaneously evaluate different parts of the
program.

Debugging tools expose the evaluation order. That's inevitable. A
problem with 'echo' and 'echof' is that they are part of the language, and
users might come to rely on a particular script producing echo output in a
particular order. I think we should make it clear that 'echo' is only a
debug feature, that there is no defined evaluation order, and that the
evaluation order can change across releases, or vary depending on the
hardware and operating system. With multi-core evaluation, the evaluation
order can change from one run to the next.

I know that people use 'echo' to generate a bill of materials. We should
provide a more declarative way to do this. In OpenSCAD2, I've provided a
mechanism for attaching user-defined metadata to geometric shapes, and I
also explain how to use this to generate a BOM declaratively, without using
echo.

Remember that in a declarative language, the evaluation order is
something internal to the implementation, it does not (should not) affect
the final result. Otherwise it's a bug. In OpenSCAD, the final result is
usually the geometry, but in the above example it's the BOM, if the BOM is
defined declaratively using metadata.

On 15 January 2016 at 03:47, nop head nop.head@gmail.com wrote:

If you accept that functions can return a debug string as well as a
value then it is no longer a side effect. If you cache the value of the
function for optimisation then you also have to cache the string and emit
it whenever you use the cached value. The same with echo in modules and
geometry.

On 14 January 2016 at 22:19, MichaelAtOz oz.at.michael@gmail.com
wrote:

Thanks. Nice use of a "side-effect" which I thought we didn't allow?
Seems to be the main argument against  echof()
https://github.com/openscad/openscad/issues/741


Newly minted Admin - PM me if you need anything, or if I've done
something stupid...

Unless specifically shown otherwise above, my contribution is in the
Public Domain; to the extent possible under law, I have waived all
copyright and related or neighbouring rights to this work. Obviously
inclusion of works of previous authors is not included in the above.

The TPP is no simple “trade agreement.”  Fight it!
http://www.ourfairdeal.org/  time is running out!

View this message in context:
http://forum.openscad.org/debug-print-in-openscad-functions-tp15683p15685.html
Sent from the OpenSCAD mailing list archive at Nabble.com.


OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

On 15 January 2016 at 19:21, doug moen <doug@moens.org> wrote: > There's a design flaw in our geometry cache, which caches geometry across > different script evaluations. The problem is that CGAL messages which > appear the first time, do not appear during subsequent F5/F6 evaluations. > This is annoying and should be fixed. I agree that the fix will have to > involve caching the CGAL messages together with the cached geometry. > Agreed. And the same mechanism can be used for echof in functions if the functions get memoized. > > I consider this issue separate from the issue of making the script > evaluator run faster, using the standard techniques that are available to > declarative and functional languages. In the latter case, I am quite sure > that we don't want to prohibit the use of optimizations because somebody > might use echo to debug a script. > No but you can recognise that the presence of echo locally means you can't rearrange the code if it would change the text. It is quite normal to disable optimisations when debugging code. I don't see a need for echof once the bug is found. I don't think the same applies to echo in modules / the geometry tree however and the order of evaluation doesn't matter as long as the strings are combined alongside the geometry results. > > Yes, echo and echof produce side effects. Optimizations will often change > those side effects, even though the result is the same: > > - an optimization might avoid evaluating a module or expression > multiple times, because the result is the same each time. This means the > echo happens only once instead of multiple times. > - an optimization can change the order of evaluation. This doesn't > affect the result, but the echos will now occur in a different order. > - an optimization can decide not to evaluate a function or module > call, because the optimizer can prove that the result has no effect on the > geometric output. This means the echo doesn't occur. > > All these things make debugging totally confusing unless you can disable them. The last time I used Microsoft Visual Studio debug mode disabled all optimisations and ran about 10 times slower. It was possible to run the debugger on release mode code but it was mighty confusing. For example you could have simple functions in unrelated classes, such as property accessors, that produce the same machine code but have totally different names. In release mode they all get combined so you step through one class and and see it call a completely unrelated one. But if you put printf in, it still produces the correct results in release mode because the optimiser knows it can't remove or reorder the code so it prints differently. Nobody complains their code runs slower due to the presence of debugging code they put in. It does sometimes create Heisenbugs though. > Echo is not the same thing as metadata. These optimizations apply equally > well to geometry nodes that contain metadata. > I don't understand that. If I make a bom with metadata I want it to be the same as one I currently create with echo, so if you handle metadata correctly, so that it is the same, then you can handle echo the same way. > > If we agree that caching evaluation results *across different script > evaluations* needs to be treated more carefully, then can we agree that it > is okay to use agressive performance optimizations *within* a single script > evaluation? > Yes but I think echo is not a side effect, just as the geometry is not a side effect, so you can do whatever optimisations don't affect the geometry and don't change what is echoed. > Nop Head said: > >Well actually I think echo is run while the CSG tree is being made from > the AST tree, which is a serial process and unlikely to be the bit > paralleled for speed, which would be evaluating the CSG tree to create > geometry. > > Historically, it's true that OpenSCAD is designed to have a script > evaluation phase, which isn't performance critical, followed by a geometry > evaluation phase (currently using CGAL) which is very performance > sensitive. But if you look at how the language is being used now, and at > the pull request for 'probe', then that may no longer be an accurate way to > think about performance. > > 1. OpenSCAD has poor support for creating curved surfaces, so we now > have libraries that build curved surfaces using polyhedron(), such as the > new spline library. This means we are now increasingly doing our geometry > computations in the OpenSCAD scripting language, instead of in CGAL. > 2. There is a pull request for a 'probe' function, which performs a > CGAL computation, then makes the results available to the function, > expression and variable part of the scripting language. One request in that > thread is to make the vertices and faces available, presumably so they can > be transformed and fed back into polyhedron using the scripting language. > This could greatly increase the extent to which CGAL and script evaluation > are interleaved. > > If the scripting language is being called upon to do the heavy lifting of > geometry evaluation, as an adjunct to CGAL, then yes maybe we will need to > consider parallel script evaluation. > Yes but as I described before, echo in modules does not prevent them being run in parallel or in any order as long as the text is gathered from the children and concatenated in the right order and passed up to the parent, just the same as the geometry. > > On 15 January 2016 at 12:05, nop head <nop.head@gmail.com> wrote: > >> Well actually I think echo is run while the CSG tree is being made from >> the AST tree, which is a serial process and unlikely to be the bit >> paralleled for speed, which would be evaluating the CSG tree to create >> geometry. >> >> As I said before if you consider the console text as part of the result >> it is no longer a side effect any more than creating geometry and rendering >> it on the screen is. It doesn't create any side effect type problems like >> mutable variables do because its effect is external to the program. >> >> If any debug information needs to be output during the geometry creation >> it isn't a problem either. Any parallel execution has to evaluate the >> children of a node before it can use the results to do its operation. As >> long as the text from echo is returned as part of the value of the child >> node instead of being immediately printed the tree can be used to render it >> in the console in the correct order. I.e. each node evaluates it children >> (potentially in parallel) and returns the geometry to is parent. I can all >> receive debug strings from its children, concatenate them and return them >> to its parent. The text will still be in the same order regardless of >> parallelism. Also any optimisation that caches geometry has to cache the >> string as well. >> >> Echo in expressions can be handled exactly the same way and produce >> deterministic results despite parallelism and caching, just the same as the >> expression value is deterministic. >> >> If you can get a deterministic result from attaching metadata then you >> can also make echo work as you can consider it a special case of metadata. >> >> >> >> On 15 January 2016 at 16:17, doug moen <doug@moens.org> wrote: >> >>> The "search" function is badly designed. It prints those warning >>> messages because >>> search("large", [["large",42], ["medium",17], ["small",5]]) >>> does not do what it should do. >>> >>> We should deprecate "search" and replace it with something simpler and >>> better behaved. A lot of people who need this functionality have already >>> done this, by writing their own function. My preferred interface looks like >>> this: >>> lookup(key, [[key1,value1], [key2,value2], ...]) >>> returns the value associated with the key argument, or returns undef if >>> there is no match. Works with any type of key for which equality is >>> defined, including strings and lists. >>> >>> There is nothing wrong with adding an "echof" function as an aid in >>> debugging functions. It's no worse than "echo". This is needed as a debug >>> feature, since OpenSCAD doesn't have proper debug facilities. But we should >>> be aiming higher, at providing a proper debugger UI in a future release. If >>> you could use a debugger to set "watchpoints" that print a trace message to >>> the console each time a particular expression is evaluated, then you could >>> debug a program without cluttering up the source code with echo statements. >>> >>> OpenSCAD is a declarative language. Ideally, it has no side effects, and >>> it has no defined evaluation order, which gives the implementation maximum >>> flexibility to compile scripts into a form that execute quickly. For >>> example, >>> >>> - Suppose that an expensive-to-compute subexpression occurs inside a >>> for loop, but doesn't depend on the iteration variable. An optimizing >>> compiler can lift that subexpression outside of the loop, and only evaluate >>> it once. >>> - If the same subexpression occurs multiple times, the compiler can >>> recognize this and arrange to only evaluate the expression once, caching >>> the result for later use. >>> - Declarative programs can be automatically parallelized, so that >>> multiple cores are used to simultaneously evaluate different parts of the >>> program. >>> >>> Debugging tools expose the evaluation order. That's inevitable. A >>> problem with 'echo' and 'echof' is that they are part of the language, and >>> users might come to rely on a particular script producing echo output in a >>> particular order. I think we should make it clear that 'echo' is only a >>> debug feature, that there is no defined evaluation order, and that the >>> evaluation order can change across releases, or vary depending on the >>> hardware and operating system. With multi-core evaluation, the evaluation >>> order can change from one run to the next. >>> >>> I know that people use 'echo' to generate a bill of materials. We should >>> provide a more declarative way to do this. In OpenSCAD2, I've provided a >>> mechanism for attaching user-defined metadata to geometric shapes, and I >>> also explain how to use this to generate a BOM declaratively, without using >>> echo. >>> >>> Remember that in a declarative language, the evaluation order is >>> something internal to the implementation, it does not (should not) affect >>> the final result. Otherwise it's a bug. In OpenSCAD, the final result is >>> usually the geometry, but in the above example it's the BOM, if the BOM is >>> defined declaratively using metadata. >>> >>> >>> On 15 January 2016 at 03:47, nop head <nop.head@gmail.com> wrote: >>> >>>> If you accept that functions can return a debug string as well as a >>>> value then it is no longer a side effect. If you cache the value of the >>>> function for optimisation then you also have to cache the string and emit >>>> it whenever you use the cached value. The same with echo in modules and >>>> geometry. >>>> >>>> On 14 January 2016 at 22:19, MichaelAtOz <oz.at.michael@gmail.com> >>>> wrote: >>>> >>>>> Thanks. Nice use of a "side-effect" which I thought we didn't allow? >>>>> Seems to be the main argument against echof() >>>>> <https://github.com/openscad/openscad/issues/741> >>>>> >>>>> >>>>> >>>>> ----- >>>>> Newly minted Admin - PM me if you need anything, or if I've done >>>>> something stupid... >>>>> >>>>> Unless specifically shown otherwise above, my contribution is in the >>>>> Public Domain; to the extent possible under law, I have waived all >>>>> copyright and related or neighbouring rights to this work. Obviously >>>>> inclusion of works of previous authors is not included in the above. >>>>> >>>>> The TPP is no simple “trade agreement.” Fight it! >>>>> http://www.ourfairdeal.org/ time is running out! >>>>> -- >>>>> View this message in context: >>>>> http://forum.openscad.org/debug-print-in-openscad-functions-tp15683p15685.html >>>>> Sent from the OpenSCAD mailing list archive at Nabble.com. >>>>> >>>>> _______________________________________________ >>>>> OpenSCAD mailing list >>>>> Discuss@lists.openscad.org >>>>> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >>>>> >>>> >>>> >>>> _______________________________________________ >>>> OpenSCAD mailing list >>>> Discuss@lists.openscad.org >>>> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >>>> >>>> >>> >>> _______________________________________________ >>> OpenSCAD mailing list >>> Discuss@lists.openscad.org >>> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >>> >>> >> >> _______________________________________________ >> OpenSCAD mailing list >> Discuss@lists.openscad.org >> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >> >> > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org > >