Development

NAVIGATION
CATEGORIES
REFERRENCE
LINKS
  • A critic of Guido's blog on Python's lambda

    6 answers - 4903 bytes - related search similar search Add To My Delicious Add To My Stumble Upon Add To My Google Mark Add To My Facebook Add To My Digg Add To My Reddit

    Steve R. Hastings wrote:
    Fri, 05 May 2006 21:16:50 -0400, Ken Tilton wrote:
    The upshot of
    what he wrote is that it would be really hard to make semantically
    meaningful indentation work with lambda.
    Pretty much correct. The complete thought was that it would be painful
    all out of proportion to the benefit.
    See, you don't need multi-line lambda, because you can do this:
    --
    def make_adder(x):
    def adder_func(y):
    sum = x + y
    return sum
    return adder_func
    Now imagine you had to do this with every object.
    def add_five(x)
    # return x + 5 <-- anonymous integer literal, not allowed!!!
    five = 5 # define it first
    return x + five
    Think about the ramifications of every object having to have a name in
    some environment, so that at the leaves of all expressions, only names
    appear, and literals can only be used in definitions of names.
    Also, what happens in the caller who invokes make_adder? Something like
    this:
    adder = make_adder(42)
    perhaps even something like this
    make_adder(2)(3) 5
    Look, here the function has no name. Why is that allowed? If anonymous
    functions are undesireable, shouldn't there be a requirement that the
    result of make_adder has to be bound to a name, and then the name must
    be used?
    Note that make_adder() doesn't use lambda, and yet it makes a custom
    function with more than one line. Indented, even.
    That function is not exactly custom. What is custom are the environment
    bindings that it captures. The code body comes from the program itself.
    What about actually creating the source code of a function at run-time
    and compiling it?
    (let ((source-code (list 'lambda (list 'x 'y) )))
    (compile nil source-code))
    Here, we are applying the compiler (available at run-time) to syntax
    which represents a function. The compiler analyzes the syntax and
    compiles the function for us, giving us an object that can be called.
    Without that syntax which can represent a function, what do you pass to
    the compiler?
    If we didn't have lambda in Lisp, we could still take advantage of the
    fact that the compiler can also take an interpreted function object and
    compile that, rather than source code. So we could put together an
    expression which looks like this:
    (flet ((some-name (x y) )) #'some-name)
    We could EVAL this expression, which would give us a function object,
    which can then be passed to CMPILE. So we have to involve the
    evaluator in addition to the compiler, and it only works because the
    compiler is flexible enough to accept function objects in addition to
    source code.
    No; lambda is a bit more convenient. But this doesn't seem like a very
    big issue worth a flame war. If GvR says multi-line lambda would make
    the lexer more complicated and he doesn't think it's worth all the effort,
    I don't see any need to argue about it.
    I.e. GvR is the supreme authority. If GvR rationalizes something as
    being good for himself, that's good enough for me and everyone else.
    I won't say more, since Alex Martelli already pointed out that Google is
    doing big things with Python and it seems to scale well for them.
    That's pretty amazing for something that doesn't even have a native
    compiler, and big mutexes in its intepreter core.
    Look at "docs.python.org" in section 8.1 en titled "Thread State and
    the Global Interpreter Lock":
    "The Python interpreter is not fully thread safe. In order to support
    multi-threaded Python programs, there's a global lock that must be held
    by the current thread before it can safely access Python objects.
    Without the lock, even the simplest operations could cause problems in
    a multi-threaded program: for example, when two threads simultaneously
    increment the reference count of the same object, the reference count
    could end up being incremented only once instead of twice. Therefore,
    the rule exists that only the thread that has acquired the global
    interpreter lock may operate on Python objects or call Python/C API
    functions. In order to support multi-threaded Python programs, the
    interpreter regularly releases and reacquires the lock -- by default,
    every 100 bytecode instructions (this can be changed with
    sys.setcheckinterval())."
    That doesn't mean you can't develop scalable solutions to all kinds of
    problems using Python. But it does mean that the scalability of the
    overall solution comes from architectural details that are not related
    to Python itself. Like, say, having lots of machines linked by a fast
    network, working on problems that decompose along those lines quite
    nicely.
  • No.1 | | 1734 bytes | |

    Kaz Kylheku wrote:

    Now imagine you had to do this with every object.

    def add_five(x)
    # return x + 5 <-- anonymous integer literal, not allowed!!!
    five = 5 # define it first
    return x + five

    I mentioned that as Slippery slope fallacious argument in other reply.

    []
    That doesn't mean you can't develop scalable solutions to all kinds of
    problems using Python. But it does mean that the scalability of the
    overall solution comes from architectural details that are not related
    to Python itself. Like, say, having lots of machines linked by a fast
    network, working on problems that decompose along those lines quite
    nicely.

    Is there such language that allow scalability without any need for
    design on the underlying architecture?

    Python doesn't obscure or become obstacle in utilise those
    architecture. Python allow one to design scalable architecture. So
    Python IS scalable, isn't it? when Python prevent the up-scaling
    or Python made scaled up project unmanagable that you can say that
    Python is not scalable.

    In 'Team scalable' axis, Python is easy to learn for average
    programmer. So it is easier for Python to scale up.
    'Data scalable' axis is language neutral, it depends on how you
    architecture your database, etc.

    'User requirement scalable' axis require both infrastructure and
    language to provide:

    No matter how scalable your language is, you cannot make a 100MHz/128MB
    server serve 100,000 client a second over the internet.

    No matter how many server and load balancing you have, you cannot
    practically program gmail using purely MS-DS bat file.
  • No.2 | | 800 bytes | |

    Pisin Bootvong <joesb.coe9 (AT) gmail (DOT) comwrote:
    +
    | No matter how scalable your language is, you cannot make a 100MHz/128MB
    | server serve 100,000 client a second over the internet.
    +

    Sure you can! That's ~1000 CPU cycles/request, which [assuming at least
    a 100BASE-TX NIC] is plenty to service 100K *small* requests/s ;-}

    course, you might have to write it in assembler on bare metal,
    but the good news is that with only a 1000 cycle budget, at least
    the code won't be very large! ;-}

    -Rob [someone who remembers 0.5 MIPS DEC PDP-10s being used
    for >100 simultaneous commercial timesharing users]

    Rob Warnock<rpw3 (AT) rpw3 (DOT) org>
    627 26th Avenue<URL:http://rpw3.org/>
    San Mateo, CA 94403(650)572-2607
  • No.3 | | 1041 bytes | |

    Rob Warnock wrote:
    Pisin Bootvong <joesb.coe9 (AT) gmail (DOT) comwrote:
    +
    | No matter how scalable your language is, you cannot make a 100MHz/128MB
    | server serve 100,000 client a second over the internet.
    +

    Sure you can! That's ~1000 CPU cycles/request, which [assuming at least
    a 100BASE-TX NIC] is plenty to service 100K *small* requests/s ;-}

    course, you might have to write it in assembler on bare metal,
    but the good news is that with only a 1000 cycle budget, at least
    the code won't be very large! ;-}

    Well, I was really asking for a service that really service something
    complicate and useful though :-D

    And donot forget to account for S CPU time (well may be you can write
    your own S for it too :-D )

    -Rob [someone who remembers 0.5 MIPS DEC PDP-10s being used
    for >100 simultaneous commercial timesharing users]

    Rob Warnock<rpw3 (AT) rpw3 (DOT) org>
    627 26th Avenue<URL:http://rpw3.org/>
    San Mateo, CA 94403(650)572-2607
  • No.4 | | 1514 bytes | |

    Pisin Bootvong <joesb.coe9 (AT) gmail (DOT) comwrote:
    +
    | Rob Warnock wrote:
    | | No matter how scalable your language is, you cannot make a
    | | 100MHz/128MB server serve 100,000 client a second over the internet.
    | +
    | >
    | Sure you can! That's ~1000 CPU cycles/request, which [assuming at least
    | a 100BASE-TX NIC] is plenty to service 100K *small* requests/s ;-}
    |
    | Well, I was really asking for a service that really service something
    | complicate and useful though :-D
    +

    If "only" being useful is enough, 100 cycles is enough for a DNS server,
    or an NTP server, or even a stub HTTP server that delivers some small
    piece of real-time data, like a few realtime environmental sensors
    [temperature, voltages, etc.].

    +
    | course, you might have to write it in assembler on bare metal,
    | but the good news is that with only a 1000 cycle budget, at least
    | the code won't be very large! ;-}
    |
    | And donot forget to account for S CPU time (well may be you can write
    | your own S for it too :-D )
    +

    Uh What I meant by "bare metal" is *no* "/S" per se, only a
    simple poll loop servicing the attention flags[1] of the various
    I/ devices -- a common style in lightweight embedded systems.

    -Rob

    [1] a.k.a. "interrupt request" bits, except with interrupts not enabled.

    Rob Warnock<rpw3 (AT) rpw3 (DOT) org>
    627 26th Avenue<URL:http://rpw3.org/>
    San Mateo, CA 94403(650)572-2607
  • No.5 | | 572 bytes | |

    Pisin Bootvong <joesb.coe9 (AT) gmail (DOT) comwrote:

    Is there such language that allow scalability without any need for
    design on the underlying architecture?

    Perhaps Erlang? I have no specific experience with it, but according
    to the rumor mill it forces or cajoles you into an architecture that's
    quite appropriate for scaling -- i.e., sure that architecture needed to
    be designed, but (if I understand Erlang correctly) it's now built into
    the language and you're more or less going to use the right paradigm.

    Alex
  • No.6 | | 1187 bytes | |

    Rob Warnock <rpw3 (AT) rpw3 (DOT) orgwrote:

    If "only" being useful is enough, 100 cycles is enough for a DNS server,
    or an NTP server, or even a stub HTTP server that delivers some small
    piece of real-time data, like a few realtime environmental sensors
    [temperature, voltages, etc.].

    Reminds me of Stuart Cheshire's description of how they managed to
    shoehorn zeroconf (aka bonjour, the artist formerly known as rendezvous)
    into a risible amount of RM (less than 1K byte, if I recall correctly)
    left in an embedded microcontroller (for a video camera, I think).
    Zeroconf is at heart a few clever tricks on top of DNS (plus 169.254.*
    IPs), and in the end they managed by one more clever trick (the thingy
    ignores WHAT the request is for, and just spits out the same response
    each and every time -- pushing the boundaries of DNS but, it seems,
    still technically staying within those boundaries;-).

    Not directly relevant to the scaling debate (the camera's expected to be
    on a LAN, serving a few requests per second at most), but the limit
    being on bits rather than cycles somehow "tastes" similar to me.

    Alex

Re: A critic of Guido's blog on Python's lambda


max 4000 letters.
Your nickname that display:
In order to stop the spam: 7 + 6 =
QUESTION ON "Development"

EMSDN.COM