Crazy what-if idea for function/method calling syntax

Ô

ÔÆÙÔÆÉÏÕ

Jumping in:

What if a construct

xx(*args1, **kwargs1)yy(*args2, **kwargs2)

was interpreted as

xxyy(*(args1+args2), **(kwargs1+kwargs2))

(Note: with **(kwargs1+kwargs2) I mean “put keyword arguments in the
order given”, since dicts can't be added)

This construct is currently a syntax error. The intent of this idea is
to help improve legibility.

Example:
def place_at(item, x, y): blah blah
could be called as
place(item)_at(x, y)

I believe it makes code more readable; it's also a more terse
alternate to a call like:
place_at(item=item, x=x, y=y)

Another example:
group(iterable)_by(callable)

I can think of some objections myself; the most important is whether
the current parser (with a complexity defined by the wishes of Guido,
which I faintly recall reading about a long time ago) can do that or
not. I also don't know if any other language exists supporting this
construct.

There is also a big window for misuse (i.e. break the function/method
name in illogical places), but I would classify this under “consenting
adults”. It might be suggested as good form that function names break
at underscores, like my examples.

I know it seems extreme. I only posted this idea here because I would
like some input about how feasible it can be and whether people like
it or not. Any input is welcome; however, I kindly request that
negative replies include counter-arguments (an abrupt “no” or “yuck!”
does not help others improve their knowledge of Python or Pythonic-
ness :).

Thanks in advance.
 
T

Thomas Jollans

Jumping in:

What if a construct

xx(*args1, **kwargs1)yy(*args2, **kwargs2)

was interpreted as

xxyy(*(args1+args2), **(kwargs1+kwargs2))

(Note: with **(kwargs1+kwargs2) I mean “put keyword arguments in the
order givenâ€, since dicts can't be added)

This construct is currently a syntax error. The intent of this idea is
to help improve legibility.

Example:
def place_at(item, x, y): blah blah
could be called as
place(item)_at(x, y)

Objective C does something similar. I don't actually know Objective C,
but from what I remember from when I briefly read up on in (somebody
please correct me), that call could, in Objective C, look something like:

[ place:item atPositionX:x Y:y ]

The idiomatic Python way for this is the following:

def place(item, at): pass
place(item, at=(x,y))

Your suggestion would open up an infinite number of different, mostly
unreadable, ways to call a single method. This completely goes against
the principle of encouraging there being only one way to do things.

Multi-part method names (with fixed, non-optional, "split" points, if
you know what I mean) are slightly interesting, but don't fit in, and,
more importantly, don't add anything to the language: all the possible
readability benefits are already provided (and trumped) by keyword
arguments.
 
C

Cameron Simpson

| What if a construct
|
| xx(*args1, **kwargs1)yy(*args2, **kwargs2)
|
| was interpreted as
|
| xxyy(*(args1+args2), **(kwargs1+kwargs2))
|
| (Note: with **(kwargs1+kwargs2) I mean “put keyword arguments in the
| order givenâ€, since dicts can't be added)
|
| This construct is currently a syntax error. The intent of this idea is
| to help improve legibility.
|
| Example:
| def place_at(item, x, y): blah blah
| could be called as
| place(item)_at(x, y)
[...]
| There is also a big window for misuse (i.e. break the function/method
| name in illogical places), but I would classify this under “consenting
| adultsâ€. It might be suggested as good form that function names break
| at underscores, like my examples.

Another problem is the scope for error. I can easily imagine typing:

x=foo(x)bah(y)

when I intended to type:

x=foo(x)+bah(y)

Adding your syntax causes silent breakage later instead of immediate
syntax error now.

Cheers,
--
Cameron Simpson <[email protected]> DoD#743
http://www.cskk.ezoshosting.com/cs/

hybrid rather than pure; compromising rather than clean;
distorted rather than straightforward; ambiguous rather than
articulated; both-and rather than either-or; the difficult
unity of inclusion rather than the easy unity of exclusion.
- Paul Barton-Davis <[email protected]>
 
I

Ian Kelly

2011/7/17 ÔÆÙÔÆÉÏÕ said:
Jumping in:

What if a construct

xx(*args1, **kwargs1)yy(*args2, **kwargs2)

was interpreted as

xxyy(*(args1+args2), **(kwargs1+kwargs2))

(Note: with **(kwargs1+kwargs2) I mean "put keyword arguments in the
order given", since dicts can't be added)

This construct is currently a syntax error. The intent of this idea is
to help improve legibility.

Example:
def place_at(item, x, y): blah blah
could be called as
place(item)_at(x, y)


class place(object):
def __init__(self, item):
self.__item = item
def at(self, x, y):
# place self.__item at (x, y)
pass

Then you can do:

place(item).at(x, y)

No syntax changes required. :)
 
S

Steven D'Aprano

Jumping in:

What if a construct

xx(*args1, **kwargs1)yy(*args2, **kwargs2)

was interpreted as

xxyy(*(args1+args2), **(kwargs1+kwargs2))

(Note: with **(kwargs1+kwargs2) I mean “put keyword arguments in the
order givenâ€, since dicts can't be added)

This construct is currently a syntax error. The intent of this idea is
to help improve legibility.

I don't think it does that. I think it is misleading, as it looks like two
independent function calls. It also makes it hard to search for a function
call -- instead of searching for

do_something\(.*\)

you have to now search for

do_something\(.*\)
do\(.*\)_something\(.*\)
do_\(.*\)something\(.*\)
do_some\(.*\)thing\(.*\)

and so on.


Example:
def place_at(item, x, y): blah blah
could be called as
place(item)_at(x, y)

You would probably like the Xtalk family of languages, starting with
Hypertalk from Apple in the late 80s or early 90s.

There's a neat implementation here: http://code.google.com/p/openxion/


Xtalk includes syntax like this:

put newStr into character 23 to 42 of theStr
put suffix after theStr
delete first char of theStr

although this only applied to built-in functions, not user-functions.
 
P

Pierre Quentel

I don't think it does that. I think it is misleading, as it looks like two
independent function calls. It also makes it hard to search for a function
call -- instead of searching for

do_something\(.*\)

you have to now search for

do_something\(.*\)
do\(.*\)_something\(.*\)
do_\(.*\)something\(.*\)
do_some\(.*\)thing\(.*\)

and so on.


You would probably like the Xtalk family of languages, starting with
Hypertalk from Apple in the late 80s or early 90s.

There's a neat implementation here:http://code.google.com/p/openxion/

Xtalk includes syntax like this:

put newStr into character 23 to 42 of theStr
put suffix after theStr
delete first char of theStr

although this only applied to built-in functions, not user-functions.

If I understand correctly, you propose to translate "do something to X
with arguments a,b,c" to

(1) do_something_to(X)_with_arguments(a,b,c)

instead of

(2) do_something(X,a,b,c)

I agree that the first one is more readable than the second, because
in the arguments list in (2) you mix the object you are working on and
the parameters used. But there is another option :

(3) X.do_something_with_arguments(a,b,c)

which would be in your examples : "item.place_at(x,y)" or
"iterable.group_by(collection)"

It's valid Python code and probably as readable than what you suggest,
with a clear distinction between the object and the arguments

- Pierre
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,982
Messages
2,570,185
Members
46,736
Latest member
AdolphBig6

Latest Threads

Top