3 ms·
I work on Hy, a Lisp that compiles to Python AST, and my intuition tells me that it's a bit of a wart too. Particularly how the syntax for calling is conflated
by agentultra 13y ago
I work on Hy, a Lisp that compiles to Python AST, and my intuition tells me that it's a bit of a wart too. Particularly how the syntax for calling is conflated with the definition and partly in how the arguments are filled in the Call node (basically, left to right). It lets you do things like:
>>> def foo(a, b="Default"):
... print(a, b)
...
>>> foo(1, 2)
(1, 2)
>>> foo(1)
(1, 'Default')
>>> foo(1, b="bar")
(1, 'bar')
>>> def baz(*args, **kwargs):
... print(args, kwargs)
...
>>> args = (1, 2, 3)
>>> kwargs = {'foo': "bar"}
>>> baz(*args, **kwargs)
((1, 2, 3), {'foo': 'bar'})
It's the first example that kind of seems 'off'. It's probably just cross-polination from my CL experience (which seems 'more correct'):
?> (defun foo (a &key (b "Default")) (list a b))
FOO
?> (foo 1 2)
Error: Incorrect keyword arguments
For the most part it hasn't been an issue when I'm writing the code. But when I read code that does this stuff on the call side frequently (or isn't consistent in its use over time) it can be a little frustrating.
- kbd 13y agoIt seems like what you really want is for b to be a keyword-only argument. Python 3 provides this fwiw.
- johnsoft 13y agoPython 3 lets you define functions with keyword-only arguments: >>> def foo(a, *, b="Default"): ... print((a, b)) ... >>> foo(1, b="bar") (1, 'bar') >>> foo(1, 2) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: foo() takes 1 positional argument but 2 were given
- agentultra 13y agoRight, I should've specified the Python version. Python 3's grammar for argument lists changed a bit and added kwonlyargs to the mix. IIRC the call node's arglist isn't just filled in left-to-right and handed names for keyword arguments anymore. Python 3 is definitely a step in the right direction. I wish adoption was a little more rapid.