[OpenSCAD] Openscad Indirect Functions

doug moen doug at moens.org
Mon Oct 17 10:53:44 EDT 2016

The @ syntax doesn't work for me, because it only works for functions, not
for modules.

There's been a long history of people asking for operations that take
shapes as arguments, and return values. For example, there's a very recent
forum thread asking for an operation that tests if two shapes intersect,
returning a boolean.

if (intersects(cube(v), children(0)) ...

We can't implement these operations because there's no reasonable syntax
for it, but there would be no problem if we had a unified namespace.

There are 4 solutions to this problem.

1. The simplest solution, as I said before, is to deprecate the 3
namespaces, and then finally unify the namespaces in a future release. It's
simple because no new syntax is required. There is a backward compatibility
issue, because a small percentage of old scripts (the ones that take
advantage of the 3 namespaces by defining the same name twice) would have
to be upgraded to use distinct names.

The other 3 solutions provide better backward compatibility.

2. We can introduce some new syntax: namespace qualifiers, which decorate
an identifier and specify which namespace it belongs to. It's inherently
confusing and ugly, no matter what decorator syntax we choose, but it's one
way to support backward compatibility. This approach, by itself, does *not*
let people write code where all names are in a single unified namespace,
and that's what I really want. If we provide namespace qualifiers in
conjunction with some other solution that lets me write scripts where all
names are in a single namespace, then I don't object to them.

Here is the syntax I've been playing with. There are 3 namespace prefixes:
v$ f$ m$. For example:

  // define a function, in the function namespace, by computing it.
  f$foo = some_expression_that_computes_a_function_value();

  // pass a function as an argument to another function
  map(f$foo, list)

  // call a variable as a function
  function map(f, list) = [ for (x = list) v$f(x) ];

  // call a module in an expression context
  if (intersects(m$cube(v), m$children(0)) ...

3. Introduce a "pragma" statement that you write as the first line of a
script, specifying whether all identifiers are in a single namespace, or in
3 namespaces. This provides pretty good backwards compatibility. If the
default is the single namespace, then that's the best solution going
forward for new code (a single namespace is simpler and easier to
understand), but some old scripts will need to be modified to add the

4. The OpenSCAD2 solution that I proposed last year. Old scripts that use 3
namespaces continue to work, without modification. There is a new syntax
for function and module definitions. If you use the new definition syntax,
the script is interpreted in single-namespace mode. If you use the old
definition syntax, the script is interpreted in 3-namespace mode. No pragma
is required. This provides backwards compatibility, and supports both
styles of coding: the 3-namespace style, and the 1-namespace style.

On 17 October 2016 at 07:58, Richard Urwin <soronlin+openscad at googlemail.com
> wrote:

> ottojas wrote
> > Here is an example of openScad code using the new syntax.
> >
> > function reduce(func,vec) =
> >      len(vec)==2 ? @func(vec[0],vec[1]) : @func(vec[0],reduce(func,[for
> > (i=[1:len(vec)-1]) vec[i]]));
> >
> > echo(reduce(@(x,y:x+y),[1,2,3,4,5]));
> > echo(reduce(@(x,y:x*y),[1,2,3,4,5]));
> >
> > cossin=@(x,y:sin(x)-cos(y));
> > echo(reduce(cossin,[1,2,3,4,5]));
> >
> > /**************************
> >      RESULT
> > ECHO: 15
> > ECHO: 120
> > ECHO: -0.982406
> > **************************/
> The @ in the indirect call is required for backwards compatibility but
> every
> other use of @ could be replaced by "function", making your code:
> function reduce(func,vec) =
>      len(vec)==2 ? @func(vec[0],vec[1]) : @func(vec[0],reduce(@func,[for
> (i=[1:len(vec)-1]) vec[i]]));
> echo(reduce(function(x,y:x+y),[1,2,3,4,5]));
> echo(reduce(function(x,y:x*y),[1,2,3,4,5]));
> cossin=function(x,y:sin(x)-cos(y));
> echo(reduce(cossin,[1,2,3,4,5]));
> To my mind, that is more readable.
> Then, if eventually the namespaces are merged, the @ could be deprecated
> and
> phased out.
> --
> View this message in context: http://forum.openscad.org/
> Convert-from-object-to-polygon-polyhedron-tp18522p18752.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/20161017/a2dc08dd/attachment-0002.html>

More information about the Discuss mailing list