-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Inference and @batchlens
#27
Comments
OK, this is interesting. Thanks for the analysis. Yes, |
I wanted to implement batch |
Maybe I should bite the bullet and use |
BTW here is the using Kaleido, Setfield, MacroTools
using Setfield: parse_obj_lens
using Setfield: get_update_op
using Setfield: _UpdateOp
struct _Constant{T}
value::T
end
(f::_Constant)(x) = f.value
function compute_f_modify(ex::Expr, val)
@assert ex.head isa Symbol
if ex.head == :(=)
return :($_Constant($val))
else
op = get_update_op(ex.head)
return :($_UpdateOp($op, $val))
end
end
apply(f, arg) = f(arg)
function batchsetmacro(obj, body)
obj = esc(obj)
@assert Meta.isexpr(body, :block)
body = MacroTools.striplines(body)
lenses = map(body.args) do ex
ref, val = ex.args
_, lens = parse_obj_lens(ref)
lens
end
fs = map(body.args) do ex
ref, val = ex.args
compute_f_modify(ex, val)
end
fs = Expr(:tuple, fs...)
quote
lens = $batch($(lenses...))
$modify($obj, lens) do vals
map($apply, $fs, vals)
end
end
# # This macro does not infer well.
# # One reason is, that batchlens has inference problems
# # another reason might be that Setfield.modify
# # causes trouble, since it needs to be passed a closure
# # to circumvent the latter, the code below "inlines" modify
#
# new_vals = map(enumerate(body.args)) do (i,ex)
# ref, val = ex.args
# if ex.head == :(=)
# return val
# else
# op = get_update_op(ex.head)
# return :($op(old[$i], $val))
# end
# end
# new = Expr(:tuple, new_vals...)
# quote
# lens = $(batch)($(lenses...))
# old = $get($obj, lens)
# new = $new
# $set($obj, lens, new)
# end
end
macro batchset(obj, body)
batchsetmacro(obj, body)
end
obj = (a=1, b=(c=1, d=2))
two = 2.0
@batchset obj begin
_.a = two
_.b.c += 19
_.b.d -= 22
end |
does not infer:
Interestingly the more complicated
does infer.
The text was updated successfully, but these errors were encountered: