[OpenSCAD] Openscad Indirect Functions

doug moen doug at moens.org
Fri Oct 14 09:46:27 EDT 2016


Bananapeel wrote:

> IMO, there's just one "proper" syntax for this. And that is, that the name
> without () acts as a variable, and () means call. And function becomes just
> another type, like string and int. This means functions and variables must
> occupy the same namespace. This syntax can also work for modules, however,
> this means variables, functions and modules all share the same namespace,
> which currently isn't the case.
>

I agree with this.

If we implement function values without uniting the namespaces, we have to
use ugly, nonstandard syntax for things like: calling a function stored in
a variable, or passing a named function as an argument. This leads to
complicated rules and ugly syntax, worse than function calls in any modern
programming language. And that's not in the spirit of OpenSCAD, which aims
to be simpler than a general purpose programming language.

Thought experiment: what happens if we change OpenSCAD to use 1 namespace
in the next release? Answer: we'd break some existing code, and that
happens in two ways:

   1. If you define a function and a variable with the same name X, in the
   same scope, then the code no longer works. We should report an error
   (duplicate definition of X).
   2. Currently, a variable defined in an inner scope cannot  shadow a
   variable defined in an outer scope, and vice versa. Once we unify the
   namespaces, the scoping rules change, and this sort of shadowing will
   occur. And this could be a silent error?

So maybe we should make this change in two phases, first deprecating the 3
namespaces, then uniting them in a subsequent release?

   1. In release N, we'll deprecate the 3 namespaces. You'll get a warning
   for duplicate definitions in the same scope, and a warning for objects with
   different kinds but the same name shadowing each other in nested scopes.
   2. In release N+1, these warnings turn into errors. We won't silently
   change the meaning of old code: instead, we'll detect the old incompatible
   code, report an error and force you to fix it. In this release, we can also
   make functions into first class values, and introduce a syntax for
   anonymous functions. Although the namespaces are now unified, modules won't
   necessarily be first class values (that's harder to do, and I won't discuss
   the details here).

Even with the deprecation release, this is a disruptive change that breaks
existing code. It's more work, but we could mitigate the problem by
providing an upgrade tool that automatically renames objects to avoid
conflicts. (For example, the tool could append a V, F or M to the names of
variables, functions and modules that conflict with one another.) If the
upgrade tool is painless enough to use, maybe we don't need the deprecation
phase?

This is the simplest path I can think of that leads to function values with
a unified namespace. The backwards compatibility scheme I described in the
OpenSCAD2 proposal is much harder to implement.

Doug Moen.

On 10 October 2016 at 15:15, Bananapeel <lunatica.xiaoyu at gmail.com> wrote:

> I don't know why this thread is inside the thread "Convert from object to
> polygon/polyhedron." Anyways, regarding passing functions as arguments:
>
> IMO, there's just one "proper" syntax for this. And that is, that the name
> without () acts as a variable, and () means call. And function becomes just
> another type, like string and int. This means functions and variables must
> occupy the same namespace. This syntax can also work for modules, however,
> this means variables, functions and modules all share the same namespace,
> which currently isn't the case.
>
> Using () on a variable that isn't of type function or module would give a
> runtime error.
>
> Example:
>
> //Preferred usage//
> function xsq(x) = x*x;
> function recip(x)=1/x;
> vec1=[1, 2, 3];
> vec2=[0.1, 0.7];
>
> function map(func,vec) = [for (i=vec) func(i)];
> echo(map(xsq,vec1));
> echo(map(xsq,vec2));
> echo(map(recip,vec1));
> echo(map(recip,vec2));
>
> //Other crazy usage//
> function div3(x)=x/3;
> indirect = div3;
> echo(map(indirect,vec2));
>
>
>
>
> --
> View this message in context: http://forum.openscad.org/
> Convert-from-object-to-polygon-polyhedron-tp18522p18659.html
> Sent from the OpenSCAD mailing list archive at Nabble.com.
>
> _______________________________________________
> OpenSCAD mailing list
> Discuss at lists.openscad.org
> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openscad.org/pipermail/discuss_lists.openscad.org/attachments/20161014/5f3edfe0/attachment-0002.html>


More information about the Discuss mailing list