Eigenstate: myrddin-dev mailing list

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Closures work.


You can now capture environments. Fixing this has been a
long time coming. It should make things like std.sort
more useful, and simplify writing code that fills the
same niche as C++'s std::algorithm


Example below:

    use std

    const main = {
        var x, y, yp, fn

        x = 123
        y = 234
        yp = &y

        fn = {
            std.put("closure/pre:\tx={}, y={}, yp#={}\n", x, y, yp#)
            x = 555
            yp# = 666
            std.put("closure/post:\tx={}, y={}, yp#={}\n", x, y, yp#)
        }
        std.put("outer/pre:\tx={}, y={}, yp#={}\n", x, y, yp#)
        fn()
        fn()
        std.put("outer/post:\tx={}, y={}, yp#={}\n", x, y, yp#)
    }

You can build and run, and get this output:

    $ mbld -b t t.myr
    t...
        6m -I /home/ori/bin/lib/myr t.myr 
        ld -o t /home/ori/bin/lib/myr/_myrrt.o t.o -L/home/ori/bin/lib/myr -lstd -lsys 
    $ ./t
    outer/pre:	  x=123, y=234, yp#=234
    closure/pre:  x=123, y=234, yp#=234
    closure/post: x=555, y=234, yp#=666
    closure/pre:  x=555, y=234, yp#=666
    closure/post: x=555, y=234, yp#=666
    outer/post:	  x=123, y=666, yp#=666

Note, this demonstrates a couple of interesting things:

    1) The outer variables are not modified.
    2) We can get pointers to the outer environment if we need to mutate it.
    3) The captured variables keep their values between invocations of the
       closure

The last point can maybe be used towards implementing generators. Or maybe I should
make captures just be const.

ABI-wise, this makes function pointers fat -- they have both an env pointer
and a code pointer.

-- 
    Ori Bernstein

Follow-Ups:
Re: Closures work.Ryan Gonzalez <rymg19@xxxxxxxxx>