Functions literals / higher order functions

classic Classic list List threaded Threaded
4 messages Options
tp3
Reply | Threaded
Open this post in threaded view
|

Functions literals / higher order functions

tp3
A couple of weeks ago there was a discussion about
function parameters for modules. I linked to the
proposal Doug made some time ago.

I wanted to have that feature for quite some time
so I had a closer look at this. The result is at
https://github.com/openscad/openscad/pull/3077
which is a prototype implementation of function
literals.

This still needs work, specifically verifying that
the parser changes did not break any existing
behavior and verification that the scoping works
as defined.

Anyone interested in helping to get that ready
for merging?

ciao,
  Torsten.


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

function-literals.png (496K) Download Attachment
-- Torsten
Reply | Threaded
Open this post in threaded view
|

Re: Functions literals / higher order functions

caterpillar
It looks nice. This is helpful when developing flexible modules and
functions, such as `sort`, `filter`, etc.



-----
http://openhome.cc
--
Sent from: http://forum.openscad.org/

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
tp3
Reply | Threaded
Open this post in threaded view
|

Re: Functions literals / higher order functions

tp3
So getting the variable scoping working needed a little
bit more work than anticipated, but it should be ok now.
Function literals capture the static scope as proposed
in:
https://github.com/doug-moen/openscad2/blob/master/rfc/Functions.md

Example with a function returning a function object
and using both lexical/static scoping of variable 'a'
and dynamic scoping of variable '$a'.

---------------------------------------

module m2(f1, f2) {
    a = 3;
    $a = 30;
    echo(f1 = f1(0.03), f2 = f2(0.07));
}

module m1(f) {
    a = 2;
    $a = 20;
    add2 = function(x) function(y) x + y + a + $a;
    m2(f, add2(0.2));
}

a = 1;
$a = 10;
add1 = function(x) function(y) x + y + a + $a;
m1(add1(0.1));

// ECHO: f1 = 31.13, f2 = 32.27

---------------------------------------

Or for a more visual example defining a simple plot()
module taking a function.

---------------------------------------

module plot(count, f) {
    for (x = [0 : count - 1]) {
        translate([x, 0, 0]) cube([1, 1, 1 + f(x / count)]);
    }
}

func_sin = function(x) 10 * sin(360 * x) + 10;
func_cos = function(x) 10 * cos(360 * x) + 10;
func_pow = function(x) 10 * pow(abs(4 * (x - 0.5)), 2);

funcs = [
    [func_sin,  0, "red"],
    [func_cos, 20, "green"],
    [func_pow, 40, "yellow"]
];

for (func = funcs)
    color(func[2])
        translate([0, func[1], 0])
            plot(100, func[0]);

---------------------------------------

Binary downloads of the current state of this branch:

Linux: https://app.circleci.com/jobs/github/openscad/openscad/3622/artifacts
Win32: https://app.circleci.com/jobs/github/openscad/openscad/3624/artifacts
Win64: https://app.circleci.com/jobs/github/openscad/openscad/3623/artifacts

ciao,
  Torsten.


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
-- Torsten
Reply | Threaded
Open this post in threaded view
|

Re: Functions literals / higher order functions

RevarBat
Very nice!  This will be helpful with several things.

-Revar

> On Sep 24, 2019, at 5:47 PM, Torsten Paul <[hidden email]> wrote:
>
> ´╗┐So getting the variable scoping working needed a little
> bit more work than anticipated, but it should be ok now.
> Function literals capture the static scope as proposed
> in:
> https://github.com/doug-moen/openscad2/blob/master/rfc/Functions.md
>
> Example with a function returning a function object
> and using both lexical/static scoping of variable 'a'
> and dynamic scoping of variable '$a'.
>
> ---------------------------------------
>
> module m2(f1, f2) {
>    a = 3;
>    $a = 30;
>    echo(f1 = f1(0.03), f2 = f2(0.07));
> }
>
> module m1(f) {
>    a = 2;
>    $a = 20;
>    add2 = function(x) function(y) x + y + a + $a;
>    m2(f, add2(0.2));
> }
>
> a = 1;
> $a = 10;
> add1 = function(x) function(y) x + y + a + $a;
> m1(add1(0.1));
>
> // ECHO: f1 = 31.13, f2 = 32.27
>
> ---------------------------------------
>
> Or for a more visual example defining a simple plot()
> module taking a function.
>
> ---------------------------------------
>
> module plot(count, f) {
>    for (x = [0 : count - 1]) {
>        translate([x, 0, 0]) cube([1, 1, 1 + f(x / count)]);
>    }
> }
>
> func_sin = function(x) 10 * sin(360 * x) + 10;
> func_cos = function(x) 10 * cos(360 * x) + 10;
> func_pow = function(x) 10 * pow(abs(4 * (x - 0.5)), 2);
>
> funcs = [
>    [func_sin,  0, "red"],
>    [func_cos, 20, "green"],
>    [func_pow, 40, "yellow"]
> ];
>
> for (func = funcs)
>    color(func[2])
>        translate([0, func[1], 0])
>            plot(100, func[0]);
>
> ---------------------------------------
>
> Binary downloads of the current state of this branch:
>
> Linux: https://app.circleci.com/jobs/github/openscad/openscad/3622/artifacts
> Win32: https://app.circleci.com/jobs/github/openscad/openscad/3624/artifacts
> Win64: https://app.circleci.com/jobs/github/openscad/openscad/3623/artifacts
>
> ciao,
>  Torsten.
>
>
> _______________________________________________
> OpenSCAD mailing list
> [hidden email]
> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org