Python is Considered Harmful

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • mike420@ziplip.com

    Python is Considered Harmful

    Ladies and Gentlemen,

    I present to you the final and ultimate proof of Python's
    brain-damage:

    As you may remember,

    flist = []

    for i in range(3)
    f = lambda x: x + i
    flist.append(f)

    [f(1) for f in flist]

    produces [3, 3, 3] in Python.

    In Haskell, we would express this as follows:

    map (\f -> f 1) [\x -> x + i | i <- [0..2]]

    This, of course, evaluates to the expected [1, 2, 3]

    As you might have heard, the ever so generous GvR allowed us write
    the same in Python (literal translation, really):

    map(lambda f: f(1), [lambda x: x + 1 for i in range(3)])

    What do you think this evaluates to: also [1, 2, 3] or [3, 3, 3]
    as before?

    Guess again, it's [2, 2, 2] !

    ROTFLMFAO!

    Pythonista, you are all very welcome to learn Haskell.
    You will find the syntax very familiar. Haskell is short
    too (compare one line above that gives the correct
    result to several Python lines that surprise you)

    All this Python bashing is starting to feel like mocking
    a retarded child...

    420
  • Darius

    #2
    Re: Python is Considered Harmful

    On Sun, 26 Oct 2003 22:25:41 -0800 (PST)
    mike420@ziplip. com wrote:

    Ladies and Gentlemen,

    I present to you the final and ultimate proof of mike420's
    brain-damage:

    In Haskell, we would express this as follows:

    map (\f -> f 1) [\x -> x + 1 | i <- [0..2]]

    This, of course, evaluates to the expected [2, 2, 2]

    map(lambda f: f(1), [lambda x: x + 1 for i in range(3)])

    What do you think this evaluates to: also [1, 2, 3] or [3, 3, 3]
    as before?

    It's [2, 2, 2] !

    -

    You are a blatant troll and now a public moron to boot. Will you please
    go away? You may consider coming back when you learn 1+1=2.

    Comment

    • Ville Vainio

      #3
      Re: Python is Considered Harmful

      mike420@ziplip. com writes:
      [color=blue]
      > I present to you the final and ultimate proof of Python's
      > brain-damage:[/color]

      -1, Troll.
      [color=blue]
      > map(lambda f: f(1), [lambda x: x + 1 for i in range(3)])[/color]
      [color=blue]
      > Guess again, it's [2, 2, 2] ![/color]

      Yes, 1+1 == 2 for usual values of 1.
      [color=blue]
      > Pythonista, you are all very welcome to learn Haskell.[/color]

      ...
      [color=blue]
      > All this Python bashing is starting to feel like mocking
      > a retarded child...[/color]

      Well, the Haskell community seems like a friendly bunch, at least.

      --
      Ville Vainio http://www.students.tut.fi/~vainio24

      Comment

      • KefX

        #4
        Re: Python is Considered Harmful

        Hmm...I think the Haskell syntax looks like crap. ;) Seriously, I can't even
        guess how it works without some kind of manual. And of course the Python result
        is only 'surprising' if you don't know the rules of name binding.

        I'm not bashing Haskell, of course. I'm just saying I already don't like it...

        - Kef

        Comment

        • Isaac To

          #5
          Re: Python is Considered Harmful

          >>>>> "mike420" == mike420 <mike420@ziplip .com> writes:

          mike420> As you might have heard, the ever so generous GvR allowed us
          mike420> write the same in Python (literal translation, really):

          mike420> map(lambda f: f(1), [lambda x: x + 1 for i in range(3)])

          mike420> What do you think this evaluates to: also [1, 2, 3] or [3, 3,
          mike420> 3] as before?

          mike420> Guess again, it's [2, 2, 2] !

          Did you really mean

          map(lambda f: f(1), [lambda x: x+i for i in range(3)])

          ? If so, it does return [3, 3, 3]. The only problem here is that Python
          variables are name lookups over dictionaries, and as such the value of "i"
          is not coined into the lambda. Rather it is "external", binded dynamically.
          I believe the behaviour can be fixed rather easily by some directives, say
          making it

          map(lambda f: f(1), [lambda x: x+(*i) for i in range(3)])

          where the * construct would get the reference of i at function definition
          time rather than at function invocation time (anyone can point me to an
          PEP?). On the other hand, I basically never use lambda this way.

          mike420> Pythonista, you are all very welcome to learn Haskell. You
          mike420> will find the syntax very familiar. Haskell is short too
          mike420> (compare one line above that gives the correct result to
          mike420> several Python lines that surprise you)

          Yes, tried. Failed, unluckily. It is clear that I'm not the kind of people
          who will map every programming problem into a mathematical problem and solve
          it that way. So I hate maps and reduces. I hate that I cannot assign a new
          value to an existing value to change its binding. I hate having to remember
          the unintuitive meanings of all the symbols. I hate having to guess when
          variables will get its bindings and when functions will be invoked during
          lazy evaluation. There is no way that anyone can turn me to Haskell.
          Basically every strong point Haskellers talk about turn me off. This is
          very unlucky.

          Regards,
          Isaac.

          Comment

          • Dirk Thierbach

            #6
            Re: Python is Considered Harmful

            Ville Vainio <ville.spammeha rdvainio@spamtu t.fi> wrote:[color=blue]
            > mike420@ziplip. com writes:[/color]
            [color=blue][color=green]
            >> I present to you the final and ultimate proof of Python's
            >> brain-damage:[/color][/color]
            [color=blue]
            > -1, Troll.[/color]
            [...][color=blue]
            > Well, the Haskell community seems like a friendly bunch, at least.[/color]

            You're right, he's a troll. As a user of Haskell, I think such postings
            do an inexcusable amount of damage. Please ignore him, and don't
            judge the Haskell community by people like him.

            - Dirk

            [F'up to poster]

            Comment

            • Martin Franklin

              #7
              Re: Python is Considered Harmful

              On Mon, 2003-10-27 at 07:28, Lulu of the Lotus-Eaters wrote:[color=blue]
              > mike420@ziplip. com wrote previously:
              > |All this Python bashing is starting to feel like mocking
              > |a retarded child...
              >
              > Y'know... a few dozen letters to 'abuse@ziplib.c om' certainly couldn't
              > do any harm in troll management. It might not help... but it might.[/color]

              Perhaps that should read abuse@ziplip.co m


              --
              Martin Franklin <mfranklin1@gat wick.westerngec o.slb.com>


              Comment

              • Alex Martelli

                #8
                Re: Python is Considered Harmful

                Isaac To wrote:
                ...[color=blue]
                > Did you really mean
                >
                > map(lambda f: f(1), [lambda x: x+i for i in range(3)])
                >
                > ? If so, it does return [3, 3, 3]. The only problem here is that Python
                > variables are name lookups over dictionaries, and as such the value of "i"
                > is not coined into the lambda. Rather it is "external", binded
                > dynamically. I believe the behaviour can be fixed rather easily by some
                > directives, say making it
                >
                > map(lambda f: f(1), [lambda x: x+(*i) for i in range(3)])
                >
                > where the * construct would get the reference of i at function definition
                > time rather than at function invocation time (anyone can point me to an
                > PEP?). On the other hand, I basically never use lambda this way.[/color]

                No new "directive" needed: it's easy to get "snap-shots" of current
                values of names into a lambda or other function:

                map(lambda f: f(1), [lambda x, i=i: x+i for i in range(3)])

                The "i=i" gets the (outer) value of i at function-definition time and
                injects it as local variable i in the lambda. You can also rename just
                as easily (and sometimes it's clearer):

                map(lambda f: f(1), [lambda x, k=i: x+k for i in range(3)])



                Alex

                Comment

                • Jeremy Fincher

                  #9
                  Re: Python is Considered Harmful

                  mike420@ziplip. com wrote in message news:<D5ODMGKEL 3JQLZOFIJAGKINU HSIEBVOLPZKLOPN S@ziplip.com>.. .[color=blue]
                  > Ladies and Gentlemen,
                  >
                  > I present to you the final and ultimate proof of Python's
                  > brain-damage:
                  >
                  > As you may remember,
                  >
                  > flist = []
                  >
                  > for i in range(3)
                  > f = lambda x: x + i
                  > flist.append(f)
                  >
                  > [f(1) for f in flist]
                  >
                  > produces [3, 3, 3] in Python.
                  >
                  > In Haskell, we would express this as follows:
                  >
                  > map (\f -> f 1) [\x -> x + i | i <- [0..2]][/color]

                  First, let's remove the list comprehension syntactical sugar. This is
                  actually:

                  map (\f -> f 1) (map (\i -> (\x -> x + i)) [0..2])

                  So, as you can see clearly without the sugar, you're basically
                  creating closures, since a new lexical scope is introduced at function
                  creation.
                  [color=blue]
                  > This, of course, evaluates to the expected [1, 2, 3][/color]

                  Expected by functional programmers who expect new lexical scopes to be
                  created at every block, sure. But Python isn't a functional
                  programming language, and doesn't create a new lexical scope in every
                  block.
                  [color=blue]
                  > As you might have heard, the ever so generous GvR allowed us write
                  > the same in Python (literal translation, really):
                  >
                  > map(lambda f: f(1), [lambda x: x + 1 for i in range(3)[/color]

                  Others have pointed out your typo here; I'll assume you meant "lambda
                  x: x + i" instead of 1.

                  Again, let's remove the syntactical sugar here:

                  L = []
                  for i in range(3):
                  L.append(lambda x: x + i)
                  map(lambda f: f(1), L)

                  The observed result, [3, 3, 3] is perfectly in keeping with the fact
                  that Python does not create a new lexical scope in for suites (or if
                  suites, or any other non-class, non-function suite).
                  [color=blue]
                  > Pythonista, you are all very welcome to learn Haskell.
                  > You will find the syntax very familiar. Haskell is short
                  > too (compare one line above that gives the correct
                  > result to several Python lines that surprise you)[/color]

                  The Python result is only surprising to those who try to impose other
                  languages' semantics on Python.
                  [color=blue]
                  > All this Python bashing is starting to feel like mocking
                  > a retarded child...[/color]

                  You, sir, are a poor representative of the Haskell community.

                  Jeremy

                  Comment

                  • Gonçalo Rodrigues

                    #10
                    Re: Python is Considered Harmful

                    On Sun, 26 Oct 2003 22:25:41 -0800 (PST), mike420@ziplip. com wrote:
                    [color=blue]
                    >Ladies and Gentlemen,
                    >
                    >I present to you the final and ultimate proof of Python's
                    >brain-damage:
                    >[/color]

                    [text snipped]
                    [color=blue]
                    >
                    >ROTFLMFAO!
                    >
                    >Pythonista, you are all very welcome to learn Haskell.
                    >You will find the syntax very familiar. Haskell is short
                    >too (compare one line above that gives the correct
                    >result to several Python lines that surprise you)
                    >
                    >All this Python bashing is starting to feel like mocking
                    >a retarded child...
                    >
                    >420[/color]

                    Trolls are not welcomed, get lost.

                    G. Rodrigues

                    Comment

                    • Marco Antoniotti

                      #11
                      Re: Python is Considered Harmful



                      Bengt Richter wrote:[color=blue]
                      > On Mon, 27 Oct 2003 11:14:52 GMT, Alex Martelli <aleax@aleax.it > wrote:
                      >[/color]
                      ...
                      [color=blue][color=green]
                      >>No new "directive" needed: it's easy to get "snap-shots" of current
                      >>values of names into a lambda or other function:
                      >>
                      >>map(lambda f: f(1), [lambda x, i=i: x+i for i in range(3)])
                      >>
                      >>The "i=i" gets the (outer) value of i at function-definition time and
                      >>injects it as local variable i in the lambda. You can also rename just
                      >>as easily (and sometimes it's clearer):
                      >>
                      >>map(lambda f: f(1), [lambda x, k=i: x+k for i in range(3)])
                      >>[/color]
                      >
                      >
                      > I think it would be nice if we could inject a value as a local variable
                      > without being part of the calling signature for the function. E.g., if
                      > the parameter list had a way to delimit "injected" values so that they
                      > weren't part of the parameter list per se. E.g., using '|' to separate
                      > local-variable presets,
                      >
                      > map(lambda f: f(1), [lambda x|k=i: x+k for i in range(3)])[/color]

                      Well then, AFAIU, the

                      lambda x, k = 1: ...

                      idiom serves to introduce an optional lambda bound variable.
                      I.e. something that in CL has been there since 1984 and earlier. Your
                      suggestion is instead along the lines of the &AUX lambda parameter
                      already present in Common Lisp (another non surprise) since 1984 and before.

                      But this begs the question. The bottom line is that Python needs to get
                      proper lambda expressions. The extra "quote" local "unquote" argument
                      is not what you'd expect.

                      Cheers
                      --
                      Marco Antoniotti

                      Comment

                      • Jegenye 2001 Bt

                        #12
                        Re: Python is Considered Harmful

                        Thank you, Alex, for clarifing this issue for me..

                        So this was actually like the famous equation
                        "9*6=42"
                        :-)
                        It is correct (or incorrect) if you look at it in the right (or wrong) way.

                        Best,
                        Miklós

                        --
                        PRISZNYÁK Miklós
                        ---
                        Jegenye 2001 Bt. ( mailto:jegenye2 001@parkhosting .com )
                        Egyedi szoftverkészíté s, tanácsadás
                        Custom software development, consulting



                        Alex Martelli <aleax@aleax.it > wrote in message
                        news:M67nb.3593 75$R32.11848659 @news2.tin.it.. .[color=blue]
                        > Isaac To wrote:
                        > ...[color=green]
                        > > Did you really mean
                        > >
                        > > map(lambda f: f(1), [lambda x: x+i for i in range(3)])
                        > >
                        > > ? If so, it does return [3, 3, 3]. The only problem here is that[/color][/color]
                        Python[color=blue][color=green]
                        > > variables are name lookups over dictionaries, and as such the value of[/color][/color]
                        "i"[color=blue][color=green]
                        > > is not coined into the lambda. Rather it is "external", binded
                        > > dynamically. I believe the behaviour can be fixed rather easily by some
                        > > directives, say making it
                        > >
                        > > map(lambda f: f(1), [lambda x: x+(*i) for i in range(3)])
                        > >[/color]
                        > No new "directive" needed: it's easy to get "snap-shots" of current
                        > values of names into a lambda or other function:
                        >
                        > map(lambda f: f(1), [lambda x, i=i: x+i for i in range(3)])
                        >
                        > The "i=i" gets the (outer) value of i at function-definition time and
                        > injects it as local variable i in the lambda. You can also rename just
                        > as easily (and sometimes it's clearer):
                        >
                        > map(lambda f: f(1), [lambda x, k=i: x+k for i in range(3)])
                        >
                        >
                        >
                        > Alex
                        >[/color]


                        Comment

                        • Mauro Cicognini

                          #13
                          Re: Python is Considered Harmful

                          Marco Antoniotti wrote:
                          [color=blue]
                          > But this begs the question. The bottom line is that Python needs to get
                          > proper lambda expressions. The extra "quote" local "unquote" argument
                          > is not what you'd expect.[/color]

                          Unfortunately, Guido (van Rossum) has many times over voiced his
                          non-support for functional constructs in Python.
                          In other words, I guess he'd rather pull lambdas from Python than add
                          "proper" support for them.

                          And again, how do you define "proper"?

                          Mauro

                          Comment

                          • KefX

                            #14
                            Re: Python is Considered Harmful

                            >[color=blue]
                            >So this was actually like the famous equation
                            >"9*6=42"
                            >:-)
                            >It is correct (or incorrect) if you look at it in the right (or wrong) way.[/color]

                            Nope, it's flat out wrong. The idea that it was true in a different base didn't
                            even occur to Douglas Adams, if that's what you're suggesting. :) However, the
                            analogy still works if you just pretend otherwise.

                            - Kef

                            Comment

                            • Matthias Felleisen

                              #15
                              Re: Python is Considered Harmful

                              Jeremy Fincher wrote:
                              [color=blue]
                              > Expected by functional programmers who expect new lexical scopes to be
                              > created at every block, sure. But Python isn't a functional
                              > programming language, and doesn't create a new lexical scope in every
                              > block.
                              >
                              > The Python result is only surprising to those who try to impose other
                              > languages' semantics on Python.[/color]

                              Yes, that's true but functional programmers come from a "carry your semantics
                              on your sleave" angle at things. Let's see how we build this in Scheme. If I
                              understand Python's semantics properly, a for-iterator has this semantics:

                              (define-syntax python-for
                              (syntax-rules (in range)
                              [(_ x in (range n) exp ...)
                              (let ([x #f])
                              (for-each (lambda (i) (set! x i) exp ...) (build-list n identity)))]))

                              It sets up an iteration variable and then mutates the iteration variable for
                              each iteration. Then you evaluate the body of the for. A Schemer wouldn't cut
                              the overhead and write/expect something like that:

                              (define-syntax scheme-for
                              (syntax-rules (in range)
                              [(_ x in (range n) exp ...)
                              (for-each (lambda (x) exp ...) (build-list n identity))]))

                              Here we just iterate over the specified variable. (I have the iteration order of
                              the number sequence backwards. That's intended to skip a small bit of syntactic
                              overhead.)

                              Now depending on which of these for's you use you get different results for

                              (define flist '())

                              (define f #f)

                              (for i in (range 3)
                              (set! f (lambda (x) (+ x i)))
                              (set! flist (cons f flist)))

                              (map (lambda (f) (f 1)) flist)

                              Nothing surprising here for someone who studies language semantics. Things are
                              as they are. But to someone who compares these things, I must admit that I am
                              astonished that Python chose the first, complicated (not on your sleave)
                              semantics and rejected the second one.

                              -- Matthias



                              Comment

                              Working...