[OpenSCAD] Openscad Indirect Functions

doug moen doug at moens.org
Thu Oct 13 13:27:25 EDT 2016


I've been doing some prototyping work, and after some experiments, my
favourite syntax for anonymous functions is
    (x, y) -> x + y

This syntax is naturally nestable, so it's easy to write a "curried"
function like this:
   x -> y -> x + y
[In my prototype, the parentheses around a parameter list are optional if
the entire parameter list consists of just a single identifier.]

Otto's "map" example would be written
   map(x->x/3, [1,2,3])



On 10 October 2016 at 13:13, otto <otto at 123phase.com> wrote:

> On Mon, 10 Oct 2016 10:44:13 +0100
> nop head <nop.head at gmail.com> wrote:
>
> > So @xsq becomes both a name mangled function and a variable holding
> > its name? That seems like a bit of a kludge to me.
>
> Well its like this, you can pass a function with the name of the
> function in quotes.
>
> function div3(x)=x/3;
> vec = [1,2,3];
>
> function map(func,vec) = [for (i=vec) @func(i)];
> echo(map("div3",vec));
>
> And it works:
>
> Compiling design (CSG Tree generation)...
> ECHO: [0.333333, 0.666667, 1]
>
> Using the construct funcion @xyz .., gives you a way to create a
> function and have the compiler generate a name for the function and put
> it in a variable for you. "@" used in other contexts is simply a
> dereferencing operator.  It does require that the name following the
> "@" is a variable name known by the compiler and not an expression
> returning a string.  "@concat("d","iv3")" will not work.
>
> A syntax that would work nicely (but requires more hacking on my part)
> would be to create true anonymous functions with syntax such as follows.
>
> Abandon the "function @...",
> shorten it to "@(<argument list>,<function,def>)"
> Which returns the created name of the function.  This would allow for
> a more anonymous lambda like usage.
>
> Map could then be invoked, map(@(x,x/3),[1,2,3]), which is more compact
> and would get the right behavior.
>
> Thanks for the questions and idea.  You are helping me think it
> through.  Please try current code.  I think I will try to program
> this capability next week. I am going on a trip this week.
>
> BTW what is best way to pass on this code in github.
>
> Regards
> Otto
>
>
>
>
>
>
> >
> > Defining functions normally and passing them with @name would allow
> > the compiler to check it was a valid function name without having to
> > have specially decorated functions. They could be passed as string
> > equal to their name and then calling @func() could work with any
> > string that equals a function name. Seems less kludgey to me. You
> > only have one type of function rather than ones that have to be
> > called normally and ones that need to be called with @.
> >
> > On 10 October 2016 at 10:19, otto <otto at 123phase.com> wrote:
> >
> > > On Mon, 10 Oct 2016 10:06:50 +0100
> > > nop head <nop.head at gmail.com> wrote:
> > >
> > > The goal was to get what I wanted easily.  The changes are small and
> > > the code seems quite stable.
> > >
> > > In declaring a function with the @ decoration.
> > >
> > > As in function @xsq(x) = x*x
> > > xsq is an ID token and the variable xsq is given a unique function
> > > name as its contents.  The name is a digit followed by a period.
> > > You can see it by echoing xsq.
> > >
> > > You can then pass xsq around and then dereference it with @.
> > > Because we use openscads well designed and consistent
> > > parsing/compiling environment to do all the work, this is fast.  As
> > > designed I hadn't really anticipated the side effect that any
> > > function can be passed as its token name, and dereferenced later.
> > > The great thing about this is that the compiler resolves functions
> > > by there string name and all I needed to do was detect the
> > > decorator in the parser and then do one level of indirection.  The
> > > nice thing is it is safe, it doesn't break other code and it
> > > requires only small changes to the source code and it works now.
> > > Please test the code in the repository if you are inclined or have
> > > the time.
> > >
> > >
> > > Regards
> > > Otto
> > >
> > >
> > > > You don't seem to use the @ sign in the places I would expect. I
> > > > don't see a need for them in the function definition as any
> > > > function should be passable as an argument. I would expect them
> > > > to be needed where a function is called from a string, so:
> > > >
> > > > function xsq(x) = x*x;
> > > > function recip(x)=1/x;
> > > > vec1=[1,2,3];
> > > > vec2=[.1,.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));
> > > >
> > > > The @ sign could also be used to make a function literal instead
> > > > of passing string but that is a bigger change to the language.
> > > > Simply adding @ to take a string and look up function seems like
> > > > a simple mod. Creating a new variable type that is a function
> > > > would have much bigger implications because it could be used in
> > > > any expression. Keeping the name as a string allows all sorts of
> > > > tricks by concatenating suffixes, etc.
> > > >
> > > >
> > > >
> > > > On 10 October 2016 at 09:53, otto <otto at 123phase.com> wrote:
> > > >
> > > > > I have hacked the openscad source code to support function
> > > > > indirection.
> > > > >
> > > > > Here is a sample of how it works.  Function is decorated with
> > > > > the "@" character when it is created and when it is used, but
> > > > > not when it is passed to another function.
> > > > >
> > > > > //Preferred usage//
> > > > > function @xsq(x) = x*x;
> > > > > function @recip(x)=1/x;
> > > > > vec1=[1,2,3];
> > > > > vec2=[.1,.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));
> > > > >
> > > > > Output is:
> > > > >
> > > > > ECHO: [1, 4, 9]
> > > > > ECHO: [0.01, 0.49]
> > > > > ECHO: [1, 0.5, 0.333333]
> > > > > ECHO: [10, 1.42857]
> > > > > ECHO: [0.0333333, 0.233333]
> > > > >
> > > > >
> > > > > Everything is contained in the github repositor:
> > > > > https://github.com/ottojas/openscad-affine
> > > > >
> > > > > There is a pdf file there with some sample 3D and 2D output.  In
> > > > > order to get this capability you need to add about 30 lines of
> > > > > code in changes to five files in the source directory.  These
> > > > > are relatively stable files and you may get away with simply
> > > > > copying them from the ojasSources directory.
> > > > >
> > > > > This is very much a work in progress.  Comments, questions,
> > > > > flames, laughter, mockery etc. all welcome.  If anyone tests
> > > > > this please let me know what your experience is.  Everything is
> > > > > gnu public license as is the source code for openscad.
> > > > >
> > > > > Regards
> > > > > Otto
> > > > >
> > > > >
> > > > >
> > > > >
> > > > >
> > > > > _______________________________________________
> > > > > OpenSCAD mailing list
> > > > > Discuss at lists.openscad.org
> > > > > http://lists.openscad.org/mailman/listinfo/discuss_
> lists.openscad.org
> > > > >
> > >
> > >
> > > _______________________________________________
> > > OpenSCAD mailing list
> > > Discuss at lists.openscad.org
> > > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
> > >
>
>
> _______________________________________________
> 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/20161013/e912fef2/attachment-0002.html>


More information about the Discuss mailing list