Skip to content

Commit b51f25e

Browse files
committed
unsupplied parameters stay bound in deffn
1 parent 72bb624 commit b51f25e

2 files changed

Lines changed: 32 additions & 1 deletion

File tree

effectful/ops/syntax.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -681,7 +681,14 @@ def __call__(
681681
},
682682
}
683683
with handler(subs):
684-
return evaluate(body)
684+
new_body = evaluate(body)
685+
686+
# support partial application: keep any unsupplied parameters bound
687+
remaining_argvars = argvars[len(args) :]
688+
remaining_kwvars = {k: v for k, v in kwvars.items() if k not in kwargs}
689+
if remaining_argvars or remaining_kwvars:
690+
return deffn(new_body, *remaining_argvars, **remaining_kwvars)
691+
return new_body
685692
elif not fvsof((self, args, kwargs)):
686693
return self(*args, **kwargs)
687694
else:

tests/test_ops_syntax.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,30 @@ def test_deffn_keyword_args():
231231
assert isinstance(result2, Term)
232232

233233

234+
def test_deffn_partial_application():
235+
x, y = defop(int, name="x"), defop(int, name="y")
236+
term = deffn(x() + y(), x, y)
237+
238+
# supplying fewer positional args keeps the remaining parameters bound
239+
partial = term(0)
240+
assert isinstance(partial, Term)
241+
assert partial.op is deffn
242+
243+
# the partially applied function can still be fully applied
244+
assert partial(1) == 1
245+
assert term(0)(1) == 1
246+
247+
# partial application via keyword arguments, in either direction
248+
kwterm = deffn(2 * x() + y(), x, y=y)
249+
partial_x = kwterm(3)
250+
assert isinstance(partial_x, Term) and partial_x.op is deffn
251+
assert partial_x(y=4) == 10
252+
253+
partial_y = kwterm(y=4)
254+
assert isinstance(partial_y, Term) and partial_y.op is deffn
255+
assert partial_y(3) == 10
256+
257+
234258
def test_defdata_renaming():
235259
@defop
236260
def Let[S, T, A, B](

0 commit comments

Comments
 (0)