FAQ
In thinking about PEP 318, I came across an idea that might be worth
pursuing further. It goes deeper than PEP 318, so it would need its own
PEP.

The idea is to make 'def' and 'class' usable within expressions.
Expressions using 'def' or 'class' are followed by a code block. Upon
evaluation of the expression, the 'def' or 'class' symbol evaluates as the
function or class created by the code block. Only one 'def' or 'class' is
allowed per expression.

Some examples follow.


# Define a staticmethod named 'now'.

class datetime:
now = staticmethod(def):
ticks = time.time()
return datetime(ticks)


# Increment a counter, under control of a lock.

def increment():
self.increment_lock.synchronize(def):
self.counter += 1


# Define an interface.

ICustomer = Interface(class):
def get_id():
"""Return the customer ID"""


# Create a singleton object that ignores what you write to it.

dev_null = singleton(class):
def write(self, data):
pass


When an expression uses 'def', the subsequent code block becomes a
function and therefore does not execute unless called by the expression.
When an expression uses 'class', the subsequent code block becomes a class
object and therefore executes before being passed to the expression.

Do you like or dislike it? Why?

Shane

Search Discussions

  • Shane Hathaway at Mar 25, 2004 at 2:41 pm
    Ahem, I was hoping for opinions on this idea, either positive or
    negative. It could make Python better or worse. I need to know whether
    I should flesh out the proposal more.

    I've added some comparisons below. IMHO this syntax is clearer than the
    syntax proposed for PEP 318, and a little more powerful.

    Shane Hathaway wrote:
    In thinking about PEP 318, I came across an idea that might be worth
    pursuing further. It goes deeper than PEP 318, so it would need its own
    PEP.

    The idea is to make 'def' and 'class' usable within expressions.
    Expressions using 'def' or 'class' are followed by a code block. Upon
    evaluation of the expression, the 'def' or 'class' symbol evaluates as the
    function or class created by the code block. Only one 'def' or 'class' is
    allowed per expression.

    Some examples follow.


    # Define a staticmethod named 'now'.

    class datetime:
    now = staticmethod(def):
    ticks = time.time()
    return datetime(ticks)
    Today, this would be written as:

    class datetime:
    def now():
    ticks = time.time()
    return datetime(ticks)
    now = staticmethod(now)

    # Increment a counter, under control of a lock.

    def increment():
    self.increment_lock.synchronize(def):
    self.counter += 1
    Today, this would be written as:

    def increment():
    self.increment_lock.acquire()
    try:
    self.counter += 1
    finally:
    self.increment_lock.release()

    # Define an interface.

    ICustomer = Interface(class):
    def get_id():
    """Return the customer ID"""
    Today, this would be written as:

    class ICustomer:
    def get_id():
    """Return the customer ID"""
    ICustomer = Interface(ICustomer)

    # Create a singleton object that ignores what you write to it.

    dev_null = singleton(class):
    def write(self, data):
    pass
    class dev_null:
    def write(self, data):
    pass
    dev_null = singleton(dev_null)

    When an expression uses 'def', the subsequent code block becomes a
    function and therefore does not execute unless called by the expression.
    When an expression uses 'class', the subsequent code block becomes a class
    object and therefore executes before being passed to the expression.

    Do you like or dislike it? Why?

    Shane
  • Thomas Heller at Mar 25, 2004 at 3:10 pm

    Shane Hathaway <shane at zope.com> writes:

    Ahem, I was hoping for opinions on this idea, either positive or
    negative. It could make Python better or worse. I need to know
    whether I should flesh out the proposal more.

    I've added some comparisons below. IMHO this syntax is clearer than
    the syntax proposed for PEP 318, and a little more powerful.

    Shane Hathaway wrote:
    In thinking about PEP 318, I came across an idea that might be worth
    pursuing further. It goes deeper than PEP 318, so it would need its
    own PEP.
    The idea is to make 'def' and 'class' usable within expressions.
    Expressions using 'def' or 'class' are followed by a code block.
    Upon evaluation of the expression, the 'def' or 'class' symbol
    evaluates as the function or class created by the code block. Only
    one 'def' or 'class' is allowed per expression.
    # Define an interface.
    ICustomer = Interface(class):
    def get_id():
    """Return the customer ID"""
    Today, this would be written as:

    class ICustomer:
    def get_id():
    """Return the customer ID"""
    ICustomer = Interface(ICustomer)
    With PEP 318 in place, it would be written as:

    class ICustomer [Interface]:
    def get_id():
    """Return the customer ID"""

    Hm.

    I like the third way best. Why? The 'Interface(class)' idiom confuses
    me. But maybe I'm infected by the PEP 318 virus.

    Thomas
  • Shane Hathaway at Mar 25, 2004 at 3:19 pm

    Thomas Heller wrote:
    Shane Hathaway <shane at zope.com> writes:
    # Define an interface.
    ICustomer = Interface(class):
    def get_id():
    """Return the customer ID"""
    Today, this would be written as:

    class ICustomer:
    def get_id():
    """Return the customer ID"""
    ICustomer = Interface(ICustomer)

    With PEP 318 in place, it would be written as:

    class ICustomer [Interface]:
    def get_id():
    """Return the customer ID"""

    Hm.

    I like the third way best. Why? The 'Interface(class)' idiom confuses
    me. But maybe I'm infected by the PEP 318 virus.
    What I don't like about the third alternative is the subtle distinction
    between parentheses and square brackets. It seems like newbies would
    have a hard time with it, as would advanced programmers who are looking
    over a new code base.

    Shane
  • Thomas Heller at Mar 25, 2004 at 3:36 pm

    Shane Hathaway <shane at zope.com> writes:

    Thomas Heller wrote:
    Shane Hathaway <shane at zope.com> writes:
    # Define an interface.
    ICustomer = Interface(class):
    def get_id():
    """Return the customer ID"""
    Today, this would be written as:

    class ICustomer:
    def get_id():
    """Return the customer ID"""
    ICustomer = Interface(ICustomer)
    With PEP 318 in place, it would be written as:
    class ICustomer [Interface]:
    def get_id():
    """Return the customer ID"""
    Hm.
    I like the third way best. Why? The 'Interface(class)' idiom
    confuses
    me. But maybe I'm infected by the PEP 318 virus.
    What I don't like about the third alternative is the subtle
    distinction between parentheses and square brackets. It seems like
    newbies would have a hard time with it, as would advanced programmers
    who are looking over a new code base.
    That may be true, especially for classes. But as understand it, the
    main purpose of PEP 318 is for function decorators, not class
    decorators. And for functions it is clearer, since you always have a
    parameter list.

    BTW, how would you specify base classes for ICustomer?

    ICustomer = Interface(class, IBaseInterface):
    def get_id():
    """Return the customer ID"""

    Thomas
  • Skip Montanaro at Mar 25, 2004 at 3:55 pm

    What I don't like about the third alternative is the subtle
    distinction between parentheses and square brackets. It seems like
    newbies would have a hard time with it, as would advanced programmers
    who are looking over a new code base.
    Thomas> That may be true, especially for classes. But as understand it,
    Thomas> the main purpose of PEP 318 is for function decorators, not
    Thomas> class decorators. And for functions it is clearer, since you
    Thomas> always have a parameter list.

    I'm working on changes to PEP 318 which incorporate class decorators.
    Michael Hudson's latest patch supports them.

    Skip
  • Shane Hathaway at Mar 25, 2004 at 3:57 pm

    Thomas Heller wrote:
    Shane Hathaway <shane at zope.com> writes:
    What I don't like about the third alternative is the subtle
    distinction between parentheses and square brackets. It seems like
    newbies would have a hard time with it, as would advanced programmers
    who are looking over a new code base.

    That may be true, especially for classes. But as understand it, the
    main purpose of PEP 318 is for function decorators, not class
    decorators. And for functions it is clearer, since you always have a
    parameter list.
    Guido said that he'd like the "staticmethod" declaration to be closer to
    the first argument, since it changes the meaning of the first argument.
    The syntax I'm proposing lets you do that. (I didn't introduce the
    method of specifying parameters until now, though.)

    foo = staticmethod(def(a, b%)):
    obj = Bar(a, b)
    obj.stuff()
    return obj
    BTW, how would you specify base classes for ICustomer?

    ICustomer = Interface(class, IBaseInterface):
    def get_id():
    """Return the customer ID"""
    That would be the appropriate way to do it, assuming that Interface is
    not a metaclass.

    Shane
  • Joe Mason at Mar 25, 2004 at 7:46 pm

    In article <mailman.405.1080228996.742.python-list at python.org>, Thomas Heller wrote:
    BTW, how would you specify base classes for ICustomer?

    ICustomer = Interface(class, IBaseInterface):
    def get_id():
    """Return the customer ID"""
    Oh, right, that points up another inconsistency in the syntax I wanted
    to point out: it really should be

    ICustomer = Interface(class:
    def get_id():
    """Return the customer ID"""
    pass
    )

    Otherwise, how do we pass multiple to the function?

    PairOfClasses = Interfaces(class: pass, class: pass)

    The PEP318 decorators doesn't support this, of course, but it doesn't
    pretend to. This syntax looks like just a regular function call which
    should allow multiple parameters, though.

    You could say that only the last parameter of a function call can be a
    def or class expression, which then gets bound to the next definiton
    found. But what about

    if (class):

    That's an expression too. Does the : bind to the embedded class or the
    if?

    Can of worms.

    In a C-delimeted language, embedding a large {...} sequence inside a
    function call would be awkward, but not deadly. Here, I think Python's
    delimiting has defeated you.

    Joe
  • John Roth at Mar 25, 2004 at 3:25 pm
    "Shane Hathaway" <shane at zope.com> wrote in message
    news:mailman.373.1080165504.742.python-list at python.org...
    In thinking about PEP 318, I came across an idea that might be worth
    pursuing further. It goes deeper than PEP 318, so it would need its own
    PEP.
    [snip]

    One reason no one has responded is that this (at least
    the def part) is a very old suggestion that most of us are
    bone weary of discussing to death. Also, a lot of the
    usual suspects are away at PyCon.

    I don't believe there is any major resistance to having
    some form of code block to replace the lambda expression.
    The major problem is the syntax; as you can see from the
    discussion of PEP318 (and 308 if you remember back that
    far) having a good syntax is very important to Python
    development.

    If you can make a contribution to a good syntax for
    a code block, I for one would welcome it.

    Just to give you a start: Ruby puts a single code block
    at the end of the parameter list where it's quite obvious
    what it is and where it does not interrupt the flow of reading
    the method call. In python, I'd like to be able to put code
    blocks wherever I can currently put a function / method
    object.

    For example:

    result = map(lambda: ..., list1, list2, list3)

    is readable - barely.

    result = map(def (x, y, z):
    something
    something else
    return
    list1, list2, list3)

    becomes much less readable. This is the problem that
    needs to be solved to make code blocks fly.

    John Roth
  • Shane Hathaway at Mar 25, 2004 at 3:51 pm

    John Roth wrote:
    If you can make a contribution to a good syntax for
    a code block, I for one would welcome it.

    Just to give you a start: Ruby puts a single code block
    at the end of the parameter list where it's quite obvious
    what it is and where it does not interrupt the flow of reading
    the method call. In python, I'd like to be able to put code
    blocks wherever I can currently put a function / method
    object.

    For example:

    result = map(lambda: ..., list1, list2, list3)

    is readable - barely.

    result = map(def (x, y, z):
    something
    something else
    return
    list1, list2, list3)

    becomes much less readable. This is the problem that
    needs to be solved to make code blocks fly.
    That's one of the things I'm trying to achieve, too. Using this syntax,
    I would write it this way:

    result = map(def(x, y, z), list1, list2, list3):
    something
    something else
    return x

    Shane
  • Glenn Andreas at Mar 25, 2004 at 5:19 pm
    In article <mailman.407.1080229887.742.python-list at python.org>,
    Shane Hathaway wrote:
    John Roth wrote:
    If you can make a contribution to a good syntax for
    a code block, I for one would welcome it.

    Just to give you a start: Ruby puts a single code block
    at the end of the parameter list where it's quite obvious
    what it is and where it does not interrupt the flow of reading
    the method call. In python, I'd like to be able to put code
    blocks wherever I can currently put a function / method
    object.

    For example:

    result = map(lambda: ..., list1, list2, list3)

    is readable - barely.

    result = map(def (x, y, z):
    something
    something else
    return
    list1, list2, list3)

    becomes much less readable. This is the problem that
    needs to be solved to make code blocks fly.
    That's one of the things I'm trying to achieve, too. Using this syntax,
    I would write it this way:

    result = map(def(x, y, z), list1, list2, list3):
    something
    something else
    return x

    Shane
    What do you do if the expression is in an "if" statement?


    if map(def(x,y,z),list1,list2,list3):
    # what goes here? The body of the function
    # or the body of the if? And how does the rest of it
    # look?



    Also, limiting to "one per expression" prevents you from doing something
    like:

    myHandlers = {
    "click" : def(x,y):
    print "click at x,y"
    "enter" : def():
    print "mouse entered"
    "exit" : def():
    print "mouse exited"
    }

    (since you'd have to write:

    myHandlers = {
    "click" : def(x,y),
    "enter" : somePreviousFunctionForEnter,
    "exit" : somePreviousFunctionForExit
    } :
    print "click at x,y"

    which, due to the large distance between the "def" and the body is
    terribly hard to figure out)
  • Shane Hathaway at Mar 25, 2004 at 6:13 pm

    Glenn Andreas wrote:
    What do you do if the expression is in an "if" statement?


    if map(def(x,y,z),list1,list2,list3):
    # what goes here? The body of the function
    # or the body of the if? And how does the rest of it
    # look?
    Ah, that's an interesting concern. The same applies to "for" and
    "while" statements. This would have to be a syntax error. Rewriting it
    isn't too difficult, though, if you're willing to create an extra variable.

    condition = map(def(x,y,z),list1,list2,list3):
    function body
    if condition:
    do stuff
    Also, limiting to "one per expression" prevents you from doing something
    like:

    myHandlers = {
    "click" : def(x,y):
    print "click at x,y"
    "enter" : def():
    print "mouse entered"
    "exit" : def():
    print "mouse exited"
    }
    That example reads well, although it's odd that each function can have a
    different set of arguments. I think you'd really want a "case"
    statement instead, but Guido doesn't seem to want that.

    Shane
  • Shane Hathaway at Mar 25, 2004 at 9:11 pm

    Glenn Andreas wrote:
    Also, limiting to "one per expression" prevents you from doing something
    like:

    myHandlers = {
    "click" : def(x,y):
    print "click at x,y"
    "enter" : def():
    print "mouse entered"
    "exit" : def():
    print "mouse exited"
    }
    I just thought of a better way to write this.

    myHandlers = {}
    myHandlers["click"] = def(x,y):
    print "click at x,y"
    myHandlers["enter"] = def():
    print "mouse entered"
    myHandlers["exit"] = def():
    print "mouse exited"

    I think that's pretty nice.

    Shane
  • Ronald Oussoren at Mar 26, 2004 at 7:01 am

    On 25-mrt-04, at 22:11, Shane Hathaway wrote:

    Glenn Andreas wrote:
    Also, limiting to "one per expression" prevents you from doing
    something like:
    myHandlers = {
    "click" : def(x,y):
    print "click at x,y"
    "enter" : def():
    print "mouse entered"
    "exit" : def():
    print "mouse exited"
    }
    I just thought of a better way to write this.

    myHandlers = {}
    myHandlers["click"] = def(x,y):
    print "click at x,y"
    myHandlers["enter"] = def():
    print "mouse entered"
    myHandlers["exit"] = def():
    print "mouse exited"

    I think that's pretty nice.
    And how would you write in-line callbacks for functions that take
    multiple callbacks (such as an on-success and on-error handler)?

    Ronald
  • Shane Hathaway at Mar 26, 2004 at 2:38 pm
    On Fri, 26 Mar 2004, Ronald Oussoren wrote:
    On 25-mrt-04, at 22:11, Shane Hathaway wrote:

    I just thought of a better way to write this.

    myHandlers = {}
    myHandlers["click"] = def(x,y):
    print "click at x,y"
    myHandlers["enter"] = def():
    print "mouse entered"
    myHandlers["exit"] = def():
    print "mouse exited"

    I think that's pretty nice.
    And how would you write in-line callbacks for functions that take
    multiple callbacks (such as an on-success and on-error handler)?
    I would write a class.

    obj.add_listener(class):
    def on_success(self):
    print 'yay!'
    def on_error(self):
    print 'ohh.'

    Shane
  • Shane Hathaway at Mar 26, 2004 at 2:54 pm

    Shane Hathaway wrote:
    On Fri, 26 Mar 2004, Ronald Oussoren wrote:

    On 25-mrt-04, at 22:11, Shane Hathaway wrote:

    I just thought of a better way to write this.

    myHandlers = {}
    myHandlers["click"] = def(x,y):
    print "click at x,y"
    myHandlers["enter"] = def():
    print "mouse entered"
    myHandlers["exit"] = def():
    print "mouse exited"

    I think that's pretty nice.
    And how would you write in-line callbacks for functions that take
    multiple callbacks (such as an on-success and on-error handler)?

    I would write a class.

    obj.add_listener(class):
    def on_success(self):
    print 'yay!'
    def on_error(self):
    print 'ohh.'
    Oops, that's not quite correct. It should pass an instance rather than
    a class.

    obj.add_listener((class)()):
    def on_success(self):
    print 'yay!'
    def on_error(self):
    print 'ohh.'

    That's not pretty. :-(

    Shane
  • Joe Mason at Mar 27, 2004 at 12:58 am

    In article <mailman.449.1080312877.742.python-list at python.org>, Shane Hathaway wrote:
    I would write a class.

    obj.add_listener(class):
    def on_success(self):
    print 'yay!'
    def on_error(self):
    print 'ohh.'
    Oops, that's not quite correct. It should pass an instance rather than
    a class.

    obj.add_listener((class)()):
    def on_success(self):
    print 'yay!'
    def on_error(self):
    print 'ohh.'

    That's not pretty. :-(
    Use Prothon, and that ugliness goes away!

    (Sorry to thread-jack, I just thought that was a good example of where
    prototypes are nice.)

    Joe
  • John Roth at Mar 27, 2004 at 12:43 am
    "Ronald Oussoren" <oussoren at cistron.nl> wrote in message
    news:mailman.439.1080284510.742.python-list at python.org...
    On 25-mrt-04, at 22:11, Shane Hathaway wrote:

    Glenn Andreas wrote:
    Also, limiting to "one per expression" prevents you from doing
    something like:
    myHandlers = {
    "click" : def(x,y):
    print "click at x,y"
    "enter" : def():
    print "mouse entered"
    "exit" : def():
    print "mouse exited"
    }
    I just thought of a better way to write this.

    myHandlers = {}
    myHandlers["click"] = def(x,y):
    print "click at x,y"
    myHandlers["enter"] = def():
    print "mouse entered"
    myHandlers["exit"] = def():
    print "mouse exited"

    I think that's pretty nice.
    And how would you write in-line callbacks for functions that take
    multiple callbacks (such as an on-success and on-error handler)?
    Basically the same way, as far as I can tell. The difficulty is that
    the expression gets broken up the same way Glen Andreas' suggestion
    does above, and you have to be a bit precise about the indentation.


    I like it. By far the most common case is a single def in a statement.
    It solves a problem that I've got with interactive fiction, where I
    want to create a lot of functions on the module level, and then
    stick them into instances (not classes.)

    The uncommon case is uncommon enough (except in very specialized
    environments) that I think we can accept a bit of aparently bizzare
    behavior. At least, I can.

    John Roth
    Ronald
  • Glenn Andreas at Mar 25, 2004 at 9:44 pm
    In article <mailman.416.1080238440.742.python-list at python.org>,
    Shane Hathaway wrote:
    Glenn Andreas wrote:
    What do you do if the expression is in an "if" statement?


    if map(def(x,y,z),list1,list2,list3):
    # what goes here? The body of the function
    # or the body of the if? And how does the rest of it
    # look?
    Ah, that's an interesting concern. The same applies to "for" and
    "while" statements. This would have to be a syntax error. Rewriting it
    isn't too difficult, though, if you're willing to create an extra variable.

    condition = map(def(x,y,z),list1,list2,list3):
    function body
    if condition:
    do stuff
    Wasn't the whole point of the use of "def in expression" to avoid having
    to use an extra variable? After all, you currently can use an extra
    variable and get the exact same result:

    def myMapFunction(x,y,z):
    # body of function
    if map(myMapFunction,list1,list2,list3):
    # body of if

    So basically, at that point, if you want to use def in expressions, for
    control expressions you'd need an extra variable, which is exactly the
    state you've got today (you just move that varible from a function to a
    value from).
    Also, limiting to "one per expression" prevents you from doing something
    like:

    myHandlers = {
    "click" : def(x,y):
    print "click at x,y"
    "enter" : def():
    print "mouse entered"
    "exit" : def():
    print "mouse exited"
    }
    That example reads well, although it's odd that each function can have a
    different set of arguments. I think you'd really want a "case"
    statement instead, but Guido doesn't seem to want that.

    Shane
    I was thinking more the case where you hand that dictionary to something
    like a bridge for an external UI system (in this example it might be to
    handle the various callbacks that might be bound to a button). The
    external (native) system would just know that it has a dictionary with a
    bunch of "handlers" associated with keys.

    Granted, it may be easier to hand the native UI system an object with
    specific methods which it could call (PyObject_CallMethod), but one can
    certainly imagine the system as described being used.


    Personally, I like the idea of anoymous functions, and that:

    x = def(arg):
    print args+1

    and

    def x(arg):
    print arg+1

    are the same doesn't bother me (Lua does this exact same thing - even
    pointing out that the equivalent syntax for the latter form is nothing
    but syntactic sugar for the former (though with the word "function"
    instead of "def")).


    Still, the whole thing comes down to the fact that statements are
    terminated by new-lines & use indentations, and expressions are
    (normally) within a single line (and ignore indentation when they
    aren't). The impediance between the two is pretty high, so trying to
    mix them isn't going to be easy or pretty.
  • Glenn Andreas at Mar 25, 2004 at 10:51 pm
    In article <mailman.429.1080249113.742.python-list at python.org>,
    Shane Hathaway wrote:
    Glenn Andreas wrote:
    Also, limiting to "one per expression" prevents you from doing something
    like:

    myHandlers = {
    "click" : def(x,y):
    print "click at x,y"
    "enter" : def():
    print "mouse entered"
    "exit" : def():
    print "mouse exited"
    }
    I just thought of a better way to write this.

    myHandlers = {}
    myHandlers["click"] = def(x,y):
    print "click at x,y"
    myHandlers["enter"] = def():
    print "mouse entered"
    myHandlers["exit"] = def():
    print "mouse exited"

    I think that's pretty nice.
    That would work, but suddenly we've got a rule that "dictionaries can
    specify all their keys and values, except only one of which can be an
    'inlined' anonymous function, so if you need more, you need to add the
    rest manually".

    Perhaps, if we go with the "foo = def()" being the same as "def foo()":

    myHandlers = {}
    def myHandlers["click"](x,y):
    print "clicked at x,y"

    .. at which point my fingers revolted and refused to type anything
    further example in such stylistic abomination (which is one of the
    reasons I also hate that form of decorators, since it looks like you are
    binding the value of a dictionary).


    OTOH, if you look at NewtonScript (which was prototyped based, BTW) you
    would define the methods for an object exactly like one would create any
    old frame (which is pretty much the same as a dictionary, but is also an
    object - there was no difference between the two):

    anObject := {
    click: func(x,y)
    Print("click at x,y");
    enter: func()
    Print("mouse entered");
    exit: func()
    Print("mouse exitted");
    };

    (and in the above, "click", "enter", "exit" are all symbols, which are
    more like Smalltalk symbols than python strings but it was trivial to
    convert between the two)

    Still, all of that worked because NewtonScript had statements and
    expressions all handled by the same form of delimination. In fact,
    statements were expressions, so you could do "min = if x < y then x else
    y;" which mixes expressions (the RHS of the assignment) with the
    if-statement which has expressions for bodies of then & else clauses
    (instead of more complex statements).
  • John Roth at Mar 25, 2004 at 6:18 pm
    "Shane Hathaway" <shane at zope.com> wrote in message
    news:mailman.407.1080229887.742.python-list at python.org...
    John Roth wrote:
    If you can make a contribution to a good syntax for
    a code block, I for one would welcome it.

    Just to give you a start: Ruby puts a single code block
    at the end of the parameter list where it's quite obvious
    what it is and where it does not interrupt the flow of reading
    the method call. In python, I'd like to be able to put code
    blocks wherever I can currently put a function / method
    object.

    For example:

    result = map(lambda: ..., list1, list2, list3)

    is readable - barely.

    result = map(def (x, y, z):
    something
    something else
    return
    list1, list2, list3)

    becomes much less readable. This is the problem that
    needs to be solved to make code blocks fly.
    That's one of the things I'm trying to achieve, too. Using this syntax,
    I would write it this way:

    result = map(def(x, y, z), list1, list2, list3):
    something
    something else
    return x
    Now, that's got some real possibilities. At least it doesn't
    embed statement indentation problems in the middle of
    expression (lack of) indentation.

    As a couple of other responders have mentioned, it
    doesn't generalize all that well to multiple def's in one
    function call, nor does it generalize all that well to having
    one embedded in a control statement header (like an if
    or for statement).

    I personally don't think restricting those cases would be
    a significant issue, though. At least, it isn't for me, although
    the lack of orthogonality might bother some other people.

    John Roth
    Shane
  • Joe Mason at Mar 25, 2004 at 7:39 pm

    In article <mailman.401.1080225693.742.python-list at python.org>, Shane Hathaway wrote:
    # Define a staticmethod named 'now'.

    class datetime:
    now = staticmethod(def):
    ticks = time.time()
    return datetime(ticks)
    Today, this would be written as:

    class datetime:
    def now():
    ticks = time.time()
    return datetime(ticks)
    now = staticmethod(now)
    Note that it would need to be "now = staticmethod(def()):", I think, to
    allow parameters.

    I like this syntax in general (hence why I hope to have some excuse to
    use Haskell or an ML someday) but it doesn't seem quite Pythonic.
    If "name = def(params): body" and "def name(params): body" are both allowed, we have two
    ways to define functions (plus lambda, although this would make it
    obsolete, I believe).

    So would "now = def then():" be allowed, setting the function name
    attribute to then but making it callable only as now()? Or would this
    not allow naming functions at all? The latter would make the
    multimethods from the other thread hard to implement. (Then again, in
    this view of the world functions don't have names, they just happen to
    be callable by named variables, so multimethods indexed by name wouldn't
    make any sense anyway.)

    Personally, I wouldn't mind at all if this form became the standard, and
    the original form retired. But I think if you don't do both, you'd
    start to get a vaguely schizophrenic language.

    Joe
  • Shane Hathaway at Mar 25, 2004 at 9:08 pm

    Joe Mason wrote:
    In article <mailman.401.1080225693.742.python-list at python.org>, Shane Hathaway wrote:
    # Define a staticmethod named 'now'.

    class datetime:
    now = staticmethod(def):
    ticks = time.time()
    return datetime(ticks)
    Today, this would be written as:

    class datetime:
    def now():
    ticks = time.time()
    return datetime(ticks)
    now = staticmethod(now)

    Note that it would need to be "now = staticmethod(def()):", I think, to
    allow parameters.

    I like this syntax in general (hence why I hope to have some excuse to
    use Haskell or an ML someday) but it doesn't seem quite Pythonic.
    I was amazed to discover that list comprehensions are considered
    Pythonic. They turn two kinds of statements (for and if) into
    expressions and often have to span multiple lines. Also, when read from
    left to right, they set the iteration variable *after* using it. This
    started to open my mind to new possiblities.
    If "name = def(params): body" and "def name(params): body" are both allowed, we have two
    ways to define functions (plus lambda, although this would make it
    obsolete, I believe).
    Yes, although list comprehensions provide a second way to generate a
    list. The difference is procedural vs. functional style. Making Python
    friendlier to the functional style seems valuable, even if it leads to
    two ways to do some things.
    So would "now = def then():" be allowed, setting the function name
    attribute to then but making it callable only as now()? Or would this
    not allow naming functions at all? The latter would make the
    multimethods from the other thread hard to implement. (Then again, in
    this view of the world functions don't have names, they just happen to
    be callable by named variables, so multimethods indexed by name wouldn't
    make any sense anyway.)
    I wouldn't want to allow inline names--they just confuse things.
    Personally, I wouldn't mind at all if this form became the standard, and
    the original form retired. But I think if you don't do both, you'd
    start to get a vaguely schizophrenic language.
    Maybe, but then we'd have to wait for Python 3000 for it to become
    standard. :-)

    Shane

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
grouppython-list @
categoriespython
postedMar 24, '04 at 9:58p
activeMar 27, '04 at 12:58a
posts23
users7
websitepython.org

People

Translate

site design / logo © 2022 Grokbase