From 4e2a28c9c67244cbdd9aa3ab096ce7dc1a5abb09 Mon Sep 17 00:00:00 2001 From: Juha Jeronen Date: Sat, 6 Oct 2018 00:33:00 +0300 Subject: [PATCH] =?UTF-8?q?tentative:=20allow=20default=20values=20for=20a?= =?UTF-8?q?rguments=20in=20=CE=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- macro_extras/main.py | 6 ++++++ unpythonic/syntax.py | 18 +++++++++++++----- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/macro_extras/main.py b/macro_extras/main.py index fb5f6e34..007598d5 100644 --- a/macro_extras/main.py +++ b/macro_extras/main.py @@ -264,6 +264,12 @@ def g(*args): z = echo("hi there") assert z == "hi there" + echo = λ(myarg="hello")[print(myarg), myarg] + result = echo() + assert result == "hello" + result = echo(3) + assert result == 3 + myadd = λ(x, y)[print("myadding", x, y), x + y] assert myadd(2, 3) == 5 diff --git a/unpythonic/syntax.py b/unpythonic/syntax.py index 079b96db..f90aac39 100644 --- a/unpythonic/syntax.py +++ b/unpythonic/syntax.py @@ -526,9 +526,8 @@ def _monadify(value, unpack=True): # ----------------------------------------------------------------------------- -# TODO: support default values for arguments. Requires support in MacroPy for named arguments. @macros.expr -def λ(tree, args, **kw): +def λ(tree, args, kwargs, **kw): """[syntax, expr] Rackety lambda with implicit begin. (Actually, implicit ``do``, because that gives an internal definition @@ -543,12 +542,21 @@ def λ(tree, args, **kw): Limitations: - No *args or **kwargs. - - No default values for arguments. """ - names = [k.id for k in args] + invalids = [x for x in args if type(x) is not Name] + if invalids: + assert False, "arguments to λ must be name or name=default_value" + # To make defaults possible, we abuse the fact that args with defaults + # are always declared after args with no defaults. There is fortunately + # a similar rule that in a call, arguments passed by name come after + # arguments passed by position. Combine these and OrderedDict, and bingo. + names = [k.id for k in args] + [k for k in kwargs] + if len(set(names)) < len(names): # may happen if both bare and with-default. + assert False, "argument names must be unique in the same λ" newtree = do.transform(tree) lam = q[lambda: ast_literal[newtree]] - lam.args.args = [arg(arg=x) for x in names] # inject args + lam.args.args = [arg(arg=x) for x in names] + lam.args.defaults = [kwargs[k] for k in kwargs] # for the last n args return lam # -----------------------------------------------------------------------------