You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
our interpreter currently creates unnecessary closures.
this may or may not be a big deal.
I'd say it seems likely that other issues are more pressing than interpreter performance.
since this is semi-fresh in my mind, I'm recording my thoughts here in case we want to investigate this in the future.
core issue
currently if we have ((lam [x y] (+ x y)) 1 2), we will create 2 closures.
we'll interpret the first lambda to get a VClosure.
then we'll interpret the application of the lambda, do a substitution with 1 for x into the body, then get out another VClosure.
then we will interpret that body with 2 substituted for y, and be done.
so we will do 2 packaging-up-s of closures, and 2 substitutive interpretations.
in this case, no closure is actually needed to evaluate the arguments or the closure body (since 1, 2, and (+ x y) have no free variables - x & y are bound by the lambda).
this seems like a waste, when we could just substitute both at once, and not package up either closure.
IIRC, this is a safe optimization, but I can't remember the name for it...
I think they key is determining whether the arguments to the function applications have any free variables.
and perhaps also determining what variables are returned...
next action
try to find this optimization, perhaps in a textbook about interpreters. seems much easier to find it than to try to reinvent the optimization.
potential approach to testing
generate well-typed Exprs (see #21).
evaluate them to Values, using the unoptimized interpreter and the optimized interpreter.
assert that both versions produce the same output.
derive equality on Value (possible??) in order to decide equality.
this should be doable given the current definition of Value, which would be a strong form of equality (I forget all the names for different equality-s, but this is a very literal form, where we would ideally just derive Eq).
after demonstrating equivalence, using 2 modules, replace the unoptimized module with the optimized one.
OR, hide the optimization behind some feature flag / optimization level.
motivation
our interpreter currently creates unnecessary closures.
this may or may not be a big deal.
I'd say it seems likely that other issues are more pressing than interpreter performance.
since this is semi-fresh in my mind, I'm recording my thoughts here in case we want to investigate this in the future.
core issue
currently if we have
((lam [x y] (+ x y)) 1 2)
, we will create 2 closures.we'll interpret the first lambda to get a
VClosure
.then we'll interpret the application of the lambda, do a substitution with
1
forx
into the body, then get out anotherVClosure
.then we will interpret that body with
2
substituted fory
, and be done.so we will do 2 packaging-up-s of closures, and 2 substitutive interpretations.
in this case, no closure is actually needed to evaluate the arguments or the closure body (since
1
,2
, and(+ x y)
have no free variables -x
&y
are bound by the lambda).this seems like a waste, when we could just substitute both at once, and not package up either closure.
IIRC, this is a safe optimization, but I can't remember the name for it...
I think they key is determining whether the arguments to the function applications have any free variables.
and perhaps also determining what variables are returned...
next action
potential approach to testing
generate well-typed
Expr
s (see #21).evaluate them to Values, using the unoptimized interpreter and the optimized interpreter.
assert that both versions produce the same output.
derive equality on
Value
(possible??) in order to decide equality.this should be doable given the current definition of
Value
, which would be a strong form of equality (I forget all the names for different equality-s, but this is a very literal form, where we would ideally just deriveEq
).after demonstrating equivalence, using 2 modules, replace the unoptimized module with the optimized one.
OR, hide the optimization behind some feature flag / optimization level.
migrated from mhuesch/poly-rs#12.
The text was updated successfully, but these errors were encountered: