Re: Lisp mentality vs. Python mentality

Discussion in 'Python' started by Ciprian Dorin, Craciun, Apr 25, 2009.

  1. On Sat, Apr 25, 2009 at 9:06 AM, Carl Banks <> wrote:
    > In answering the recent question by Mark Tarver, I think I finally hit
    > on why Lisp programmers are the way they are (in particular, why they
    > are often so hostile to the "There should only be one obvious way to
    > do it" Zen).
    >
    > Say you put this task to a Lisp and a Python programmer: Come up with
    > a good, generic, reusable way to compare two lists.  What are their
    > respective trains of thought?
    >
    >
    > Lisp programmer:
    >
    > Well, there is a standard function called mismatch that does it, but I
    > can't recommend it.  First of all, you don't know where that
    > function's been.  Anyone and their mother could have worked on it, did
    > they have good, sound programming practice in mind when they wrote
    > it?  Of course not.  Let's be real here, we have to implement this by
    > hand.
    >
    > (defun lists-are-equal (a b)
    >   (or (and (not a) (not b))
    >       (and (= (car a) (car b)) (lists-are-equal (cdr a) (cdr b))))
    >
    > There, much better than the standard function, and better yet, it's in
    > the *absolute minimal form possible*.  There is no way to express list
    > comparison in a more reduced form.  It's almost erotic how awesome it
    > is.  I'm---whoa, ok, I'm getting a little excited now, settle down.
    > Well, come to think of it, that's really not that good.  First of all
    > it's a function.  I mean, it just sits there and does nothing till you
    > call it.  How boring is that?  It can't react to the current
    > situation.  Plus it compares all lists the same way, and that is
    > really inefficient.  Every list compare is a new problem.  Different
    > lists need different comparative strategies.  This function simply
    > won't do.  I need a macro that can intelligently compile the right
    > list compare methodology in.  For instance, if we want to compare two
    > lists that are known at compile time, we don't want to waste time
    > comparing them at runtime.  No, the macro must detect constant
    > arguments and special case them.  Good start.  Now, we have to
    > consider the conditions this comparison is being done under.  If the
    > user is passing the result of a sort to this macro, it's almost
    > certain that they are trying to see whether the lists have the same
    > elements.  We can do that a lot more efficiently with a countset.  So
    > let's have the macro check to see if the forms passed to it are all
    > sort calls.  Better yet, let's check for my own powerful sort macro.
    > Hmm.  Wait... I think my 4600-line sort macro already checks its
    > calling context to see if its results are being fed to a list
    > comparison.  I'll have to refactor that together with this macro.  Ok,
    > good, now I am sure other users will eventually want to customize list
    > comparison for their own use, after all every list comparison is
    > different and I can't possibly anticipate all of them.  A user needs
    > to be able to adapt to the situation, so it's vitally important to
    > create a plug-in infrastructure to give them that flexibility.  Now,
    > what about exceptions, there's a millions ways to deal with that...
    >
    > ...and so on until eyelids can no longer stay open....
    >
    >
    >
    > Python programmer:
    >
    > a == b.  Next question.
    >
    >
    >
    > Carl Banks, who might be exaggerating
    >
    > ...a little.
    > --
    > http://mail.python.org/mailman/listinfo/python-list



    Well, if you opened the Pandora's box, lets see how can we
    implement this both ways...

    The Scheme way (a little more verbose but clearer I would say):
    --------
    (define (compare a b (comp eq?))
    (cond
    ((and (null? a) (null? b) #t))
    ((or (null? a) (null? b) #f))
    ((and (comp (first a) (first b)))
    (compare (rest a) (rest b) comp))
    (else #f)))

    (compare '(1 2 3) '(1 2 3))
    (compare '(1 "a" 3) '(1 "a" 3) equal?)
    (compare '(1 2 3) '(1 2 4) <=)
    ---------

    Python way:
    ---------
    def eq (a, b) :
    return a == b

    def compare (a, b, comp = eq) :
    if len (a) != len (b) :
    return False
    for i in xrange (len (a)) :
    if not comp (a, b) :
    return False
    return True

    compare ([1, 2, 3], [1, 2, 3])
    ---------

    I don't see another way... (Or at least another more different way...)

    Which is best? None:
    * they both work in linear time (except the Python implementation
    checks the length first);
    * they are both compact and readable;
    * they are both expandable;

    Personally I like best the Scheme version, because for example I
    can use it like (compare '(1 2 3) '(1 2 4) <=) to compare for less or
    equal in case of vectors. In the case of Python I would have needed to
    write compare ([1, 2, 3], [1, 2, 4], lambda a, b : a <= b)

    Ciprian Craciun.

    P.S.: I think of this as a challenge for hackers in both languages
    to come up with the most estetic, optimal and useful implementation...
    (My implementations are just toys...)
    Ciprian Dorin, Craciun, Apr 25, 2009
    #1
    1. Advertising

  2. On Sat, Apr 25, 2009 at 10:43 AM, <> wrote:
    > Ciprian Dorin, Craciun:
    >> Python way:
    >> ---------
    >> def eq (a, b) :
    >>     return a == b
    >>
    >> def compare (a, b, comp = eq) :
    >>     if len (a) != len (b) :
    >>         return False
    >>     for i in xrange (len (a)) :
    >>         if not comp (a, b) :
    >>             return False
    >>     return True

    >
    > That's not "pythonic".
    >
    > Bye,
    > bearophile
    > --
    > http://mail.python.org/mailman/listinfo/python-list


    Ok... Then what's pythonic? Please give a pythonic implementation...

    Ciprian Craciun.

    P.S.: Also, I'm tired of hearing about the pythonic way... Where
    do I find a definitive description about the pythonic way? I think
    that this word is used only when someone sees something that he
    doesn't like, he doesn't know what he doesn't like at it, and just
    goes to say its un-pythonic, without saying what would be... Wouldn't
    be just easier to say "I don't know" or "I doesn't feel right to me"?
    Ciprian Dorin, Craciun, Apr 25, 2009
    #2
    1. Advertising

  3. Ciprian Dorin, Craciun

    Paul Rubin Guest

    "Ciprian Dorin, Craciun" <> writes:
    > Ok... Then what's pythonic? Please give a pythonic implementation...


    Use the builtin a==b, similar to (equal a b)
    Paul Rubin, Apr 25, 2009
    #3
  4. On Sat, Apr 25, 2009 at 11:04 AM, Paul Rubin
    <http://> wrote:
    > "Ciprian Dorin, Craciun" <> writes:
    >>     Ok... Then what's pythonic? Please give a pythonic implementation...

    >
    > Use the builtin a==b, similar to (equal a b)


    But how about extensibility?
    Ciprian Dorin, Craciun, Apr 25, 2009
    #4
  5. On Sat, Apr 25, 2009 at 11:30 AM, "Martin v. Löwis" <> wrote:
    >>>>     Ok... Then what's pythonic? Please give a pythonic implementation...
    >>> Use the builtin a==b, similar to (equal a b)

    >>
    >>     But how about extensibility?

    > [...]
    >
    > I see that you allow for a different comparison function. I do wonder
    > what the use case for this is - in what application do you have to
    > compare two lists for equality, and the item's __eq__ is inappropriate?
    > What would break if you fix the item's __eq__, instead of writing
    > your own comparison algorithm?
    >
    > [...]


    A practical example: I have lists that contain strings, but I want
    to compare them in an case-insensitive way... Should I update the
    __eq__ method (for str class) and break almost everything? Can I write
    now a == b? Nop... I need the loop you've just mentioned in all the
    places where the comparison changes just in the operator, not in the
    algorithm... (I would say this is bad coding practice...)
    Ciprian Dorin, Craciun, Apr 25, 2009
    #5
  6. > A practical example: I have lists that contain strings, but I want
    > to compare them in an case-insensitive way...


    I'd claim that this is still theoretical: what are these strings, and
    why do you have lists of them that you want to compare?

    Why don't you try to lower-case the strings in the list as you
    add them?

    Also, are you sure a list is the best data structure for your problem?
    Perhaps using a set would be better?

    > Should I update the
    > __eq__ method (for str class) and break almost everything? Can I write
    > now a == b? Nop... I need the loop you've just mentioned in all the
    > places where the comparison changes just in the operator, not in the
    > algorithm... (I would say this is bad coding practice...)


    If you want to compare the same lists in many places, this is indeed
    bad coding practice. You should try to centralize whatever reasons
    you have for comparing the lists into a few methods of the objects
    holding the lists.

    Regards,
    Martin
    Martin v. Löwis, Apr 25, 2009
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. ekzept
    Replies:
    0
    Views:
    354
    ekzept
    Aug 10, 2007
  2. Carl Banks

    Lisp mentality vs. Python mentality

    Carl Banks, Apr 25, 2009, in forum: Python
    Replies:
    74
    Views:
    1,417
    Vsevolod
    Apr 29, 2009
  3. nanothermite911fbibustards
    Replies:
    0
    Views:
    362
    nanothermite911fbibustards
    Jun 16, 2010
  4. nanothermite911fbibustards
    Replies:
    0
    Views:
    307
    nanothermite911fbibustards
    Jun 16, 2010
  5. Chris Seberino
    Replies:
    8
    Views:
    117
    Chris Seberino
    Jan 4, 2014
Loading...

Share This Page