merits of Lisp vs Python

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • David Steuber

    #676
    Re: merits of Lisp vs Python

    Steven D'Aprano <steve@REMOVE.T HIS.cybersource .com.auwrites:
    How am I being silly? Do you not believe that people write case blocks
    with fifty tests? Okay, how about twenty? Ten? Eight?
    You should check out generic functions in CLOS. Rather than writing a
    ridiculously long case block, you can use EQL specialized functions.
    It's a great way to do dispatch.

    --
    This post uses 100% post consumer electrons and 100% virgin photons.

    At 2.6 miles per minute, you don't really have time to get bored.
    --- Pete Roehling on rec.motorcycles

    I bump into a lot of veteran riders in my travels.
    --- David Hough: Proficient Motorcycling

    Comment

    • greg

      #677
      Re: merits of Lisp vs Python

      Gabriel Genellina wrote:
      You can even make S = cT (c=ligth of speed in void space).
      The choice of fundamental units is rather arbitrary, and can be reduced
      further to only 1 fundamental unit and even NO fundamental units.
      I once heard mention of a system of units in use at
      one time with the odd feature that capacitance came
      out in units of length.

      Picture the scene: Hobbyist walks into Dick Smith
      store and says "I'd like a 5cm capacitor, please."

      --
      Greg

      Comment

      • greg

        #678
        Re: merits of Lisp vs Python

        Ken Tilton wrote:
        So this:
        (defmethod tf-reverse (id (eql ',sub-id)) resx (drv-opnds tf drv))
        ,@reverser)
        >
        becomes this:
        >
        (defmethod tf-reverse ((id (eql ',sub-id)) tf drv
        &aux (opnds (drv-opnds tf drv)))
        (loop for resx in (results drv)
        ,@reverser))
        I don't see why you can't just write a function that
        loops over the results and calls the user's reversal
        function for each one.

        def reverse_multipl e(skill, resx_list, opnds):
        for resx in rex_list:
        skill.reverse(r esx, opnds)

        There's no need to macro-expand this code into every
        reversal function, when it can be done once as part of
        the framework that calls the reversal functions.

        --
        Greg

        Comment

        • greg

          #679
          Re: merits of Lisp vs Python

          Ken Tilton wrote:
          The reason I post macro expansions along with examples of the macro
          being applied is so that one can see what code would have to be written
          if I did not have the defskill macro to "write" them for me.
          It seems to me your brain is somewhat stuck on the use
          of macros. You're looking at the expansion of your
          macro and assuming that you'd have to write all that
          code by hand if you didn't have macros. You're not
          thinking about alternative approaches, which could
          just as well be used in Lisp as well as Python, that
          are just as compact yet don't make use of macros.

          Unless there's something very subtle that I'm missing
          (I can't claim to follow exactly what all the code
          you posted does in detail) I haven't seen anything
          that couldn't be done quite reasonably with an
          appropriate data structure and ordinary functions
          and methods operating on that data structure.

          --
          Greg

          Comment

          • greg

            #680
            Re: merits of Lisp vs Python

            josephoswaldgg@ hotmail.com wrote:
            Neil Cerutti wrote:
            >
            >>On 2006-12-13, josephoswaldgg@ hotmail.com
            >><josephoswald @gmail.comwrote :
            >>
            >>>Expression s keep the same meaning even if you have to start
            >>>breaking them across lines, etc.
            >>
            >>Yes, it's the same way in Python. Of course, not everything is an
            >>expression in Python, so it's not saying quite as much.
            >
            I fail to see how it is the same in Python.
            Probably what Neil is referring to is the fact that in
            Python, *within an expression*, indentation is not relevant.
            If you put parens around the whole expression, you can split
            it across lines however you like, and indent all the lines
            after the first one however you like, and it makes no
            difference. You could probably even use your Lisp-aware
            auto-indenter on the expression and it would do something
            reasonable.

            It's only *statement* nesting that's determined by relative
            horizontal position (which is a better way of thinking about
            it than "whitespace " -- the whitespace is only there to
            get things into the right position). And statements normally
            occupy one or more entire lines.
            How does a manual correction process come out as simple as "don't
            bother fixing the indentation if you don't care."?
            I think the point is that correcting indentation in Python
            is the equivalent of fixing misplaced parentheses in Lisp,
            and that they're about equally difficult.

            --
            Greg

            Comment

            • greg

              #681
              Re: merits of Lisp vs Python

              josephoswaldgg@ hotmail.com wrote:
              I wrote my first Python in a non-Python-aware editor, and somehow had
              swapped tabs and spaces; when I moved it to IDLE---the indentation
              *looked fine* but was invisibly weird.
              That can admittedly be a problem. It would help if the
              parser complained by default about mixed use of tabs and
              spaces in a single file, instead of silently assuming tab
              stops every 8 spaces (an historical misfeature that we still
              have for the time being). Probably this will change in
              Python 3.0.

              Personally I find Python pleasant enough to work with
              that I'm willing to put up with the odd screwup like that
              happening now and then. And they really don't happen all
              that often -- once you've experienced it a few times,
              you learn how to guard against it and get better at
              fixing it when it does happen.
              I will even admit that white-space significance does not
              materially increase errors among experienced Pythonistas. What it isn't
              is some kind of miraculous invention that saves programmers from ever
              making mistakes that are common in other languages,
              We don't claim that -- only that it's not the unmitigated
              disaster than some people assume it will be without ever
              having tried it.

              --
              Greg

              Comment

              • greg

                #682
                Re: merits of Lisp vs Python

                josephoswaldgg@ hotmail.com wrote:
                Neil Cerutti wrote:
                >
                The parenthesis I added means I don't have
                to use the new-line escape character (\), either.
                >
                Is this so unconscious that you don't recognize you are doing it, even
                though you take a sentence to explain what you had to do to work around
                it?
                Yes, it is pretty unconscious. We all do many things
                unconsciously in everyday life that would take at
                least one sentence to explain to someone else if we
                had to think about it.

                Besides, in many cases the required brackets are
                already there -- e.g. if it's a list, or a function
                call with many arguments -- in which case you don't
                have to add anything at all.
                Adding parentheses ... all this is a
                burden specific to Python.
                As opposed to Lisp, where all you have to do is
                use parentheses... oh, er...
                By the way, you guys seem fixate on the parentheses of Lisp without
                having the experience
                I don't know about the other Pythonistas in this
                discussion, but personally I do have experience with
                Lisp, and I understand what you're saying. I have
                nothing against Lisp parentheses, I just don't agree
                that the Lisp way is superior to the Python way in
                all respects, based on my experience with both.

                --
                Greg

                Comment

                • greg

                  #683
                  Re: merits of Lisp vs Python

                  Ken Tilton wrote:
                  What if it turns into an SQL lookup during refactoring?
                  If the macro can produce SQL code, then whatever interprets the
                  table can produce SQL code as well.

                  If you're thinking of the macro taking apart the user's reverse
                  function (rather than just wrapping it) and somehow translating
                  it into SQL, well... a macro *could* do that, but it would be
                  an awfully hairy thing to do, especially if the user is allowed
                  to write arbitrary Lisp code in the body of his function (as
                  it seems he is, in your example).

                  A better way would be to design an abstract API for the user
                  to use in his reverse functions. Then you can just re-implement
                  the functions making up the API so that they do SQL queries
                  instead of whatever they were doing before. No macro processing
                  needed then.
                  The last example showed the macro inserting code to magically produce a
                  binding inside the reverse function.
                  Are you sure? It looked to me like it was adding code *around*
                  the reverse function, not inside it. I posted a Python function
                  that achieves the same thing by calling the existing reverse
                  function.
                  It would be easier to compare and
                  contrast with the Python equivalent if someone had posted such, but your
                  troops have fallen back to Fort So What? and pulled up the drawbridge.
                  I'm still trying, but some of the code you posted is rather
                  impenetrable without knowing a lot more about the details of
                  your system. I'm doing my best to show some Python demonstrating
                  the gist of what could be done.

                  --
                  Greg

                  Comment

                  • greg

                    #684
                    Re: CLPython (was Re: merits of Lisp vs Python)

                    Willem Broekema wrote:
                    I guess in part it's because there are not that many people really into
                    both Python and Lisp, and those who are might not find this an
                    interesting project because there is nothing "wow" to show, yet.
                    Another reason (or maybe the reason for the reason) is
                    that people are usually interested in Python because it's
                    a relatively simple and lightweight thing.

                    Having to install a complex and heavyweight thing like
                    a Common Lisp system just to be able to program in
                    Python doesn't seem like a good deal.

                    It might become a good deal if you could then compile
                    the Lisp and get a lean, efficient binary executable
                    out of it. But that's going to require much more than
                    just a straightforward translation from Python to Lisp.

                    If CLPython starts to show signs of making progress
                    in that direction, then it could start to get
                    interesting. Although I think I'd rather target Scheme
                    than CL if I were doing it -- cleaner language, small
                    yet still extremely good implementations available.

                    --
                    Greg

                    Comment

                    • Paul Boddie

                      #685
                      Re: CLPython (was Re: merits of Lisp vs Python)

                      greg wrote:
                      Willem Broekema wrote:
                      >
                      I guess in part it's because there are not that many people really into
                      both Python and Lisp, and those who are might not find this an
                      interesting project because there is nothing "wow" to show, yet.
                      >
                      Another reason (or maybe the reason for the reason) is
                      that people are usually interested in Python because it's
                      a relatively simple and lightweight thing.
                      I think it's more likely that the Lisp people wonder why you'd want to
                      write anything other than Lisp (and they're all supposedly too busy
                      doing other things, anyway, like rewriting their own version of
                      reddit.com), whereas the Python people either haven't heard about it,
                      aren't really interested because they believe other projects (eg. PyPy)
                      will deliver the same benefits (which probably won't be the case
                      entirely), or don't have the means to either run and experiment with it
                      or to help out.
                      Having to install a complex and heavyweight thing like
                      a Common Lisp system just to be able to program in
                      Python doesn't seem like a good deal.
                      There seems to be a fairly high intuitive similarity between various
                      Common Lisp concepts and various Python concepts, although one can only
                      make best use out of Common Lisp features (or the features of any
                      particular platform) if the correspondence is sufficiently high. I
                      suppose the argument that one can write extensions in Lisp rather than
                      C may be enticing, but one returns to the "why write anything other
                      than Lisp" argument at this point. There may be an argument for having
                      CLPython as an embedded application scripting language, but again the
                      Lisp camp have often advocated Lisp for that role, too.
                      It might become a good deal if you could then compile
                      the Lisp and get a lean, efficient binary executable
                      out of it. But that's going to require much more than
                      just a straightforward translation from Python to Lisp.
                      Indeed.
                      If CLPython starts to show signs of making progress
                      in that direction, then it could start to get
                      interesting. Although I think I'd rather target Scheme
                      than CL if I were doing it -- cleaner language, small
                      yet still extremely good implementations available.
                      Well, there are some open source Common Lisp implementations around,
                      despite the obvious bias in certain circles to encourage everyone to
                      use the proprietary implementations instead, and things like SBCL are
                      only a simple package manager install away. Meanwhile, there was an
                      implementation of Python for Scheme, but I don't think the developers
                      took the idea much further after presenting it at PyCon a few years
                      ago.

                      Paul

                      Comment

                      • =?ISO-8859-15?Q?Andr=E9_Thieme?=

                        #686
                        Re: merits of Lisp vs Python

                        greg schrieb:
                        Ken Tilton wrote:
                        >
                        >The reason I post macro expansions along with examples of the macro
                        >being applied is so that one can see what code would have to be
                        >written if I did not have the defskill macro to "write" them for me.
                        >
                        It seems to me your brain is somewhat stuck on the use of macros.
                        That you see it this way is normal.
                        A BASIC programmer would tell you the same thing. He can show you
                        solutions that don't use classes, methods or functions.
                        Some sweet gotos and gosubs are enough.
                        The idea is that macros save you tokens and allow you to experess
                        in a clearer way what you want to do. But in no case one "needs"
                        them to solve a programming problem. All what Kenny showed could
                        be done without his macro. It would just be a bit more complicated
                        and the resulting code wouldn't look good.

                        You're looking at the expansion of your
                        macro and assuming that you'd have to write all that
                        code by hand if you didn't have macros. You're not
                        thinking about alternative approaches, which could
                        just as well be used in Lisp as well as Python, that
                        are just as compact yet don't make use of macros.
                        He wouldn't have to write the full expansion. With functional
                        programming he could also solve it, but then he would need
                        a funcall here, a lambda there. And his code would not look
                        so understandable anymore, because it is filled up with some
                        low level details.


                        I will take one of the first macro examples form "On Lisp".
                        Let's say for some reason you want to analyse some numbers
                        and do something depending on their sign. We want a function
                        "numeric if":

                        def nif(num, pos, zero, neg):
                        if num 0:
                        return pos
                        else:
                        if num == 0:
                        return zero
                        else:
                        return neg


                        In Lisp very similar:
                        (defun nif (num pos zero neg)
                        (case (truncate (signum num))
                        (1 pos)
                        (0 zero)
                        (-1 neg)))


                        Now one example Graham gives is:
                        (mapcar #'(lambda (x)
                        (nif x 'p 'z 'n))
                        '(0 2.5 -8))

                        which results in the list (Z P N).
                        You can do the same thing in Python.
                        But it gets hairier if we want to make function calls that
                        have side effects.
                        Let me add these three functions:

                        (defun p ()
                        (print "very positive")
                        "positive")

                        (defun z ()
                        (print "no no")
                        "zero")

                        (defun n ()
                        (print "very negative")
                        "negative")


                        And now see what happens:

                        CL-USER(mapcar #'(lambda (x)
                        (nif x (p) (z) (n)))
                        '(0 2.5 -8))

                        "very positive"
                        "no no"
                        "very negative"
                        "very positive"
                        "no no"
                        "very negative"
                        "very positive"
                        "no no"
                        "very negative"
                        ("zero" "positive" "negative")

                        The messages were printed in each case.
                        To stop that I need lazy evaluation:
                        CL-USER(mapcar #'(lambda (x)
                        (funcall
                        (nif x
                        #'(lambda () (p))
                        #'(lambda () (z))
                        #'(lambda () (n)))))
                        '(0 2.5 -8))

                        "no no"
                        "very positive"
                        "very negative"
                        ("zero" "positive" "negative")


                        I put the calls to the functions p, z and n into a function object.
                        In some languages it would look a bit cleaner, for example Ruby.
                        They have a single name space and don't need funcall and lambda is
                        shorter. But still, we need to add several tokens. Maybe Haskell has
                        built in support for that.


                        Now with nif as a macro:
                        (defmacro nif (expr pos zero neg)
                        `(case (truncate (signum ,expr))
                        (1 ,pos)
                        (0 ,zero)
                        (-1 ,neg)))

                        It is a bit more complex as the function. It has one ` and 4 ,s
                        extra.
                        But now we can express the problem very well:

                        CL-USER(mapcar #'(lambda (x)
                        (nif x (p) (z) (n)))
                        '(0 2.5 -8))

                        "no no"
                        "very positive"
                        "very negative"
                        ("zero" "positive" "negative")

                        And the first example also still works the same way.
                        Now the expansion shows more code than we would have need to
                        write ourself. However, now we can write code that matches
                        much better how we think. No need for "low level" details like
                        embedding the code inside of anon functions.
                        This represents what most macros do. Save one or more lambdas
                        and/or funcalls. One consequence is that development time gets
                        cut down.


                        André
                        --

                        Comment

                        • Ken Tilton

                          #687
                          Re: merits of Lisp vs Python



                          greg wrote:
                          Ken Tilton wrote:
                          >
                          >So this:
                          > (defmethod tf-reverse (id (eql ',sub-id)) resx (drv-opnds tf drv))
                          > ,@reverser)
                          >>
                          >becomes this:
                          >>
                          > (defmethod tf-reverse ((id (eql ',sub-id)) tf drv
                          > &aux (opnds (drv-opnds tf drv)))
                          > (loop for resx in (results drv)
                          > ,@reverser))
                          >
                          >
                          I don't see why you can't just write a function that
                          loops over the results and calls the user's reversal
                          function for each one.
                          That was the original coding, but notice that a derivation (DRV) is an
                          argument to tf-reverse. Can you say "encapsulation" ? :) What if that
                          changes? It did. I used to have just one result per derivation, until a
                          multi-result case came along.

                          Since I will be having many dozens of these I might well try to keep as
                          much code as possible out of them (encapsulation de damned <g>) to
                          minimize the inevitable hit when I refactor, but I have macros so I do
                          not have to.
                          >
                          def reverse_multipl e(skill, resx_list, opnds):
                          for resx in rex_list:
                          skill.reverse(r esx, opnds)
                          >
                          There's no need to macro-expand this code into every
                          reversal function, when it can be done once as part of
                          the framework that calls the reversal functions.
                          Rather than go into "argue mode" before fully understanding the issues,
                          please note that I am just looking to learn (without judgment) what the
                          Python equivalent would be. Things I offer are not "you can't touch
                          this!", they are "what does the Python look like?". Afterwards we can
                          get into a pissing match. :)

                          ken

                          --
                          Algebra: http://www.tilton-technology.com/LispNycAlgebra1.htm

                          "Well, I've wrestled with reality for thirty-five
                          years, Doctor, and I'm happy to state I finally
                          won out over it." -- Elwood P. Dowd

                          "I'll say I'm losing my grip, and it feels terrific."
                          -- Smiling husband to scowling wife, New Yorker cartoon

                          Comment

                          • Ken Tilton

                            #688
                            Re: merits of Lisp vs Python



                            greg wrote:
                            Ken Tilton wrote:
                            >
                            >The reason I post macro expansions along with examples of the macro
                            >being applied is so that one can see what code would have to be
                            >written if I did not have the defskill macro to "write" them for me.
                            >
                            >
                            It seems to me your brain is somewhat stuck on the use
                            of macros. You're looking at the expansion of your
                            macro and assuming that you'd have to write all that
                            code by hand if you didn't have macros. You're not
                            thinking about alternative approaches,...
                            I think your brain is stuck on flaming. I am not thinking about Python
                            approaches, I am sking Pythonistas to do that. After understanding my
                            examples. Unfortunately I do not see the latter really happening, so we
                            are about done here.

                            Unless there's something very subtle that I'm missing
                            (I can't claim to follow exactly what all the code
                            you posted does in detail) I haven't seen anything
                            that couldn't be done quite reasonably with an
                            appropriate data structure and ordinary functions
                            and methods operating on that data structure.
                            I did explain the last little fun bit (where reverse code miraculously
                            got a case-specific "signed-value" parameter bound to exactly the right
                            bit of math structure). This process works only if you then ask
                            specifically about that (if anything was unclear--my guess is you did
                            not try all that hard since you are in argue-mode). The other reason you
                            may not have understodd is that that is waaaaay meta-cool, so meta I do
                            understand if it went over your head and I would (have been) happy to
                            explain had you asked.

                            Time to put the game on, I think. :)

                            ken

                            --
                            Algebra: http://www.tilton-technology.com/LispNycAlgebra1.htm

                            "Well, I've wrestled with reality for thirty-five
                            years, Doctor, and I'm happy to state I finally
                            won out over it." -- Elwood P. Dowd

                            "I'll say I'm losing my grip, and it feels terrific."
                            -- Smiling husband to scowling wife, New Yorker cartoon

                            Comment

                            • Paul Rubin

                              #689
                              Re: merits of Lisp vs Python

                              André Thieme <address.good.u ntil.2006.dec.2 2@justmail.dewr ites:
                              def nif(num, pos, zero, neg):
                              if num 0:
                              return pos
                              else:
                              if num == 0:
                              return zero
                              else:
                              return neg
                              def nif(num, pos, zero, neg):
                              return (neg, zero, pos)[cmp(num, 0)+1]
                              The messages were printed in each case.
                              To stop that I need lazy evaluation:
                              CL-USER(mapcar #'(lambda (x)
                              (funcall
                              (nif x
                              #'(lambda () (p))
                              #'(lambda () (z))
                              #'(lambda () (n)))))
                              '(0 2.5 -8))
                              in Python:

                              def lazy_nif(num, pos, zero, neg):
                              return (neg, zero, pos)[cmp(num, 0)+1]() # the () at the end means funcall

                              map(lambda x: lazy_nif(x, p, z, n), (0, 2.5, -8))

                              "nif" is even cleaner in Haskell, if I have this right:

                              nif x p z n | (x < 0) = n
                              | (x == 0) = z
                              | (x 0) = p

                              All Haskell evaluation is automatically lazy, so no lambdas etc. needed.

                              Comment

                              • Christophe Cavalaria

                                #690
                                Re: merits of Lisp vs Python

                                Paul Rubin wrote:
                                André Thieme <address.good.u ntil.2006.dec.2 2@justmail.dewr ites:
                                >def nif(num, pos, zero, neg):
                                > if num 0:
                                > return pos
                                > else:
                                > if num == 0:
                                > return zero
                                > else:
                                > return neg
                                >
                                def nif(num, pos, zero, neg):
                                return (neg, zero, pos)[cmp(num, 0)+1]
                                Since we are in one liners, let's be even smarter and do it like that :

                                def nif(num, pos, zero, neg):
                                return (zero, pos, neg)[cmp(num, 0)]

                                ;)

                                Comment

                                Working...