Hacker News new | ask | show | jobs
by raganwald 5039 days ago
I don't know about those other complaints, I don't personally have any complaints about Python. It doesn't have multi-line lambdas, that's a design trade-off like an iPhone not having a slide-out keyboard. But it does have first-class functions.

https://en.wikipedia.org/wiki/Python_syntax_and_semantics#Fi...

What I was speaking to is the desire to write:

  class SomeExampleModel:
  
    def setHeavyweightProperty:
      triggers('cache:dirty')(
        lambda self, property, value:
          ...something...
My understanding is that Python doesn't like two different things about this. First, the multi-line anonymous lambda being used as the target of the decorator. Second, a function being called with another function as its argument as an expression within an instance method definition.

I'm open to reëducation.

2 comments

> What I was speaking to is the desire to write:

    setHeavyweightProperty = triggers('cache:dirty')(
        lambda self, property, value: 'code')
is the same thing as

    @triggers('cache:dirty')
    def setHeavyweightProperty(self, property, value):
        # code
but with the limitations of lambdas (no statements allowed)

> First, the multi-line anonymous lambda being used as the target of the decorator.

Python has no issue with that, it's just hard to do it because Python's lambdas can only contain expressions which can be rather limited in a statements-heavy language.

> Second, a function being called with another function as its argument as an expression within an instance method definition.

That's because your "instance method definition" is not syntactically correct, the capability itself exists. A "method definition" is nothing more than a function defined within a class scope. In fact you can do things like that:

    >>> def method_outside(self):
    ...     return self.wedding
    ... 
    >>> class SomeType:
    ...     whose = method_outside
    ... 
    >>> s = SomeType()
    >>> s.wedding = "Amanda"
    >>> s.whose()
    'Amanda'
    >>> method_outside(s)
    'Amanda'
    >>> from collections import namedtuple
    >>> o = namedtuple('N', 'wedding')(wedding="Jim")
    >>> method_outside(o)
    'Jim'
    >>>
Can't edit, but "a function defined within a class scope" should actually be "a function assigned within a class scope", where and how the function object was defined does not actually matter (as the example shows), the only thing which matters is that the object is bound to a name in the class scope.
First off, I really like your posts and books. I learned advice / AOP at a previous job and really enjoy using it and applying it to new things. Your writing on the subject is great!

The only thing python does not like is multi-line lambdas. You can target a lambda with decorators, just like you can target any callable. I'm not sure if I correctly parsed what you mean by "a function being called with another function as its argument as an expression within an instance method definition", but I'm pretty sure python can do that. Here is some demonstration code (see RaganwaldWidgetViewThree):

https://gist.github.com/3495990

And finally here is the translation of the before/after/etc. method combinators:

https://gist.github.com/3495985

But I might have misunderstood waitLevel, can you explain what it is for?