if does not evaluate

James Moughan moughanj at tcd.ie
Fri Jun 11 04:36:39 CEST 2004

Jim Newton <jimka at rdrop.com> wrote in message news:<2irotfFqob91U1 at uni-berlin.de>...
> >>Secondly, Lisp's syntax doesn't parse well into the way people
> >>think,
> > 
> > 
> not sure i understand what you mean by "not the way people think",
> but i think i disagree with you.  lisp seems to be very similar
> to the way people think, it is just that programmers have learned
> over the years to think in a algol type way.
> For example, if you have a bag of balls, and you want to find out
> if one of them is red.  The algol type way would be
> for ball in bag-of-balls
>     is ball red?
>        yes ==> set flag true
>        no  ==> keep going
> Is flag true?
>     yes ==> there is a red ball
>     no  ==> there is no red ball
> but that seems like a very different way than people think.
> the lisp way to answer the question is
> is there a ball in the bag that matches condition?
> condition being: is the ball red?
> It seems like a much more natural way to think... at least to me.
> -jim

Undeniably, Lisp has some useful routines.  Especially for LISt
Processing. :)However, let's rewrite this how I might put it in

def has_elem(lis, cond):
    for x in lis:
        if cond(x): 
            return True
    return False

which, to me, says; check each element of the list, if it fulfils the
condition, be true.  If none fulfilled the condition, be false. 
Logical enough.  If I were checking through a deck of cards to see if
there were any Jokers then that's what I'd do.

Now, how to do this in Lisp.  There are several functions for applying
a function to the elements of a list to select them, though AFAIK none
specifically for our purpose.  I may very well be wrong there
o'course.  One way is:

(define has-element (cond list) 
    (equal () (member-if #'cond list))))

Well, it's definitely short.  It doesn't exactly translate well,
though; search the list for a sub-list that starts with an element
which evaluates to true under cond.  Evaluate to the equality of that
list with the null list.  Hmmm.

That's not a great example, although it's probably how I'd write it :)
so let's do a real function:

(defun has-element (pred lis)
    (if (equal lis ())
        (if (funcall pred (car lis))
            (has-element pred (cdr lis)))))

Rough translation; if the list is the null list, return NIL (false). 
Otherwise, if applying pred to the first element of the list is true,
be T (true), otherwise, evaluate to the value of this function applied
to pred and the list excluding the first element.

This isn't really too complex.  However, it's not how most people
*think* about a job like searching a list; mentally, searching is a
single block task, not a recursive function.

There are some other obvious issues with syntax.  The brain wasn't
meant to pick up on structure in arbitrary numbers of parenthesis, and
I wouldn't even try to write Lisp without a highlighting editor.  car
and cdr might as well be in greek. (yes, I know I can redefine them;
first thing I did).  We have to have a rather arbitrary #' funcall and
syntax to stop a function evaluating long enough to shift it to where
it's useful.

None of these are anything like fatal flaws.  When I'm programming in
Python, though, concepts seem to just flow naturally onto the screen. 
I don't think that's entirely 'what I know', either, because it began
happening within a day or two, and my style in Python is quite
different to in most other languages.

Hmm, long answer to a short question.  I hope you see what I mean,
though.  Lisp is a powerful language, but pragmatically, Python lets
me just get on with what I'm doing.

More information about the Python-list mailing list