Skip to content

Instantly share code, notes, and snippets.

@jpfairbanks
Last active January 3, 2016 14:19
Show Gist options
  • Select an option

  • Save jpfairbanks/8475467 to your computer and use it in GitHub Desktop.

Select an option

Save jpfairbanks/8475467 to your computer and use it in GitHub Desktop.
Closure defining macro for julia
function accumulator()
x=0; (y) -> x+=y
end
acc = accumulator()
z = 0
for i in 1:10
z =acc(1)
end
print(z)
#the desired macro
@closure initial update-rule
#so the above code is abbreviated as
accumulator = @closure x=0 (y)-> x+y
#what would the necessary macro be?
#this defines a macro to make instances of a fixed update rule
macro deffer(initexpr)
:($(esc(:fer))() = begin
eval($initexpr)
foo(x) = begin y = y+x end
end
)
end
#usage @deffer y=0; f = fer(); for val in set; f(val);end
#@closure has almost the desired behavior
#usage: @closure y=0 x->y+=x; acc = clj()
#acc is a (+) accumulator
macro closure(initexpr, update)
:($(esc(:clj))() = begin
eval($initexpr)
eval($update)
end
)
end
macro closure_maker(update)
:($(esc(:clj))(initexpr) = begin
eval(initexpr)
:(eval($update))
end
)
end
##### not working
julia> @closure_maker x->y+=x
julia> f = clj(:(y=0))
(anonymous function)
julia> f(4)
ERROR: y not defined
in anonymous at none:1
@jpfairbanks
Copy link
Author

I think I found the form that I like the most

macro clj(initexpr, update)
    :(() -> begin
        eval($initexpr)
        eval($update)
    end)
end

now acc = (@clj y=0 x->y+=x)() makes the accumulator directly.

Does this have any bad performance concerns?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment