Velocity Reviews > RE: if does not evaluate

RE: if does not evaluate

Jim Newton
Guest
Posts: n/a

 06-11-2004

> (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.
>

Not sure what you mean by "does not translate well?" Although maybe
i misunderstand, but it looks like you are naming the function the
opposite of what it does?

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

Are you really trying to find out whether the condition fails
for every element of the list?

By the way, how do you find out in Python if there is
a member of a list that matches a condition? It is something
i often and never know the best way to do it? I can
use a list compression to find ALL the matches, but what
if i only want to know whether or not there is a match?

-jim

Peter Otten
Guest
Posts: n/a

 06-11-2004
Jim Newton wrote:

> By the way, how do you find out in Python if there is
> a member of a list that matches a condition? It is something
> i often and never know the best way to do it? I can
> use a list compression to find ALL the matches, but what
> if i only want to know whether or not there is a match?

Generator expressions will solve that, I think

"Mary" in (person.name for person in people)

In the meantime:

>>> class Person:

.... def __init__(self, name):
.... self.name = name
....
>>> people = map(Person, "Jim Bob Mary Sue".split())
>>>
>>> def attrgetter(name):

.... return lambda o: getattr(o, name)
....
>>> import itertools
>>> "Mary" in itertools.imap(attrgetter("name"), people)

True

No big deal.

Peter

Jacek Generowicz
Guest
Posts: n/a

 06-11-2004
http://www.velocityreviews.com/forums/(E-Mail Removed) (James Moughan) writes:

> 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))))

(some #'cond list)

> 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.

What on earth are you talking about ?

Jacek Generowicz
Guest
Posts: n/a

 06-11-2004
(E-Mail Removed) (James Moughan) writes:

> Jacek Generowicz <(E-Mail Removed)> wrote in message news:<(E-Mail Removed)>...
> > (E-Mail Removed) (James Moughan) trolls:

> I have no doubt that Lisp can be extremely practical as a language.

Lisp (Common Lisp) is _first and foremost_ an extremely practical
language. It is the product of a couple of decades of smart people
working on a language for solving difficult programming problems in
industry, not in academia.

> I'm expressing a slightly humorous characterization of the attitude of
> parts of the Lisp community, especially in academia.

While there is (used to be) quite a number of Lisp courses around
which should be considered crimes against Lisp and humanity itself
<0.3 wink> (I had the misforture of first encountering Lisp through
one of these myself), that is no good reason to contribute yourself to
perpetuating the myths that such courses help to establish.

> > Maybe Lisp (and therefore Lisp books) are designed for intelligent
> > people who want to solve hard problems, and it is assumed that
> > intelligent people can look up trivia like how to open files in the
> > language standard (); maybe books are considered necessary to teach
> > you the difficult things which you cannot read between the lines of
> > the standard.

[...]

> Strange, I've always worked the other way around. For the extremely
> simple, basic things it seems like *slight* overkill to refer to the
> ansi standard.

What's the point of writing a book telling you how to open files in
CL? This is described in the CLHS, which is available on-line:

http://www.lisp.org/HyperSpec/FrontMatter/index.html

> For complex issues I'd rather have a formal language document that
> tells me exactly what's going on, rather than someone blathering for
> 50 pages.

While the CLHS tells you formally how macros work, it tells you
nothing of the philosophy of using them, it tells you nothing about
best practice, it tells you nothing about the pitfalls, and so on.

Do you really think that you would prefer to try to get an
understanding of what macros are, and how you should use them from
the CLHS (http://www.lisp.org/HyperSpec/FrontMatter/index.html) than
from _On Lisp_ (http://paulgraham.com/paulgraham/onlisp.html) ?

I somehow doubt it.

> In this case, I merely found it particularly striking that a subject
> like file i/o, which would be considered basic and important in most
> languages, seemed to be in many Lispers' 'blind spot'.

Because it's just not interesting. There are so many interesting
things to say and to explain about Lisp. In a language like Java,
opening files is just about as difficult a concept as the programmer
is likely encounter <0.1 wink>, so Java books describe how to do
it. Lisp is by smart people, for smart people who want to solve
difficult problems. Opening files is so trivial that it's just not
worth wasting ink on it.

> Lisp is, without doubt, the most interesting language around in terms
> of pure theory. The corollary to that, I guess, is that it attracts a
> lot of pure theorists.

Common Lisp attracts a lot of people who want to solve difficult
programming problems. Please notice this fact.

> Not really, no. People think about programs tree-style where certain
> control structures occur, and virtually all languages nest at those
> points. However, not in cases like assignment and mathematical
> expressions, where Lisp would still tend to mandate it. That sort of
> deeply nested code is often the most unreadable.

This is your opinion from the perspective of never seriously having
tried to think about programs as trees. We're back to my original
point: don't confuse your opinion formed fromed with lack of
experience and imagination with some universal truth.

> Also Lisp usually nests somewhat uncomfortably, e.g. in an if
> statement
>
> (if (< i 0)
> (* -1 i)
> i)
>
> There's simply no context there for the eye to pick up on.

Of course there is. Indentation. (Shouldn't be too hard a concept for
a c.l.py reader to grasp). Of course, in a trivial example like this,
the indentation level is the same because each of the three
constituent parts fits on one line. Try this:

(if (this that
the other)
(foo bar
(fubar baz))
(fred bob
(bill ben)))

(Yes, there is a lot more to be said about this, but I don't propose
to do this on c.l.PY)

> Nest all of that a couple of layers deeper and it's going to become
> annoying.

Nope, you look at the indentation, just like in Python. Unlike in
Python, my editor is capable of swapping an arbitrarily large
consequent with an abitrarily large bloop, with a single
keystroke. When you catch on to these possibilities, the prodictivity
gaing is huge.

> I am not trolling about Lisp, btw. I'm expressing my experiences of
> playing around with Lisp as a new language. My intention was more in
> the line of amusement.

Unfortunately it's a form of amusement _too often_ chosen by ignorant
people ... which is a pity, because in doing so they help to
perpetuate the myth that what is actually the world's most advanced
and practical programming language, is some sort of joke ... thereby
helping to keep IT in the dark ages. <0.2 wink>

IOW, it's not funny. Pick something else to amuse yourself (like
actually learning Lisp, for example

> And, frankly, if you think that a mildly sarcastic comment about some
> of the learning materials for Lisp, along a bold statement that Lisp
> doesn't have the world's most intuitive syntax is a viscous, trollish
> slur on the language, justifying random personal attacks, then you
> really need to get a freaking life.

Too many ignoramuses making too many of these cheap shots ... yes it
winds me up.

> Lisp pretty much forces you into one way of doing things.

Please get a clue before posting such unfounded misinformation. Common
Lisp natuarally allows you to program in more different styles that
any other language I have come across.

> That's a shortcoming, not a feature.

It would be, if it were true.

> But different problems may - shock - be better expressed through
> different languages, and diferent syntaxes.

Yes, and Common Lisp - shock - allows you to use any syntax you
want. And - shock - even though you can arrange for Lisp to understand
_any_ syntax, people usually decide to base their domain-specific
syntaxes on s-expressions, because an s-expression based one usually
turns out to be the best for the job.

Pertinent piece of history: s-expressions were originally not meant
for human consumption, something called m-expressions, which were to
be the sort of thing that you (and others) claim is the "natural" way
of expressing programs, was planned. Shock: the m-expressions never
caught on because the s-expressions turned out to be such a wonderful
way of writing programs. The programmers didn't want to let go of
their lovely, natural s-expressions.

Jim Newton
Guest
Posts: n/a

 06-11-2004
sorry, i do not understand. The python syntax is a bit
difficult for me.

if i have a list x and a function f how do i know if
there is an element of x on which f returns something
other than False?

-jim

Peter Otten wrote:
> Jim Newton wrote:
>
>
>>By the way, how do you find out in Python if there is
>>a member of a list that matches a condition? It is something
>>i often and never know the best way to do it? I can
>>use a list compression to find ALL the matches, but what
>>if i only want to know whether or not there is a match?

>
>
> Generator expressions will solve that, I think
>
> "Mary" in (person.name for person in people)
>
> In the meantime:
>
>
>>>>class Person:

>
> ... def __init__(self, name):
> ... self.name = name
> ...
>
>>>>people = map(Person, "Jim Bob Mary Sue".split())
>>>>
>>>>def attrgetter(name):

>
> ... return lambda o: getattr(o, name)
> ...
>
>>>>import itertools
>>>>"Mary" in itertools.imap(attrgetter("name"), people)

>
> True
>
> No big deal.
>
> Peter
>

Jim Newton
Guest
Posts: n/a

 06-11-2004
ah so i must encapsulate the predicate function in another named
function which uses yield in order to have the iteration abort
when the target item is reached? can i simply put the predicate
function inside a lambda?

-jim

Peter Otten wrote:
> Jim Newton wrote:
>
>
>>sorry, i do not understand. The python syntax is a bit
>>difficult for me.

>
>
> Maybe I obscured the issue by comparing name attributes to a string instead
> of using a predicate() function.
>
>
>>if i have a list x and a function f how do i know if
>>there is an element of x on which f returns something
>>other than False?

>
>
> Using the above identifiers, let's assume we are looking for a name starting
> with "M":
>
>
>>>>x = ["Peter", "Paul", "Mary", "Jane"]
>>>>def f(o):

>
> ... print "checking", o
> ... return o.startswith("M")
> ...
>
> If we call
>
>
>>>>map(f, x)

>
> checking Peter
> checking Paul
> checking Mary
> checking Jane
> [False, False, True, False]
>
> it invokes f() for every item in x and returns the above list of booleans.
> The equivalent list comprehension would be [f(i) for i in x]. Now
>
>
>>>>True in map(f, x)

>
> checking Peter
> checking Paul
> checking Mary
> checking Jane
> True
>
> gives the correct result but unfortunately does too much work as we don't
> need to calculate f("Jane") when we already know the outcome. Enter
> generator
>
>
>>>>def lazymap(predicate, seq):

>
> ... for item in seq:
> ... yield predicate(item)
> ...
>
> which calulates f(item) as needed. Proof:
>
>
>>>>True in lazymap(f, x)

>
> checking Peter
> checking Paul
> checking Mary
> True
>
>
> itertools.imap() is just the fast C implementation of lazymap().
> The equivalent generator expression (new in Python 2.4) will be
> (f(i) for i in x).
>
> Peter
>

Jim Newton
Guest
Posts: n/a

 06-11-2004
so what i have done in the past is write a generic searching function.

def exists(predicate,seq):
for item in seq:
if( predicate(item)):
return True
return False

then i used that funcion in a test.

x = ["Peter", "Paul", "Mary", "Jane"]

if( exists( lambda y: y.startswith("M"), x)):
...

-jim

> Peter Otten wrote:
>
>> Jim Newton wrote:
>>
>>
>>> sorry, i do not understand. The python syntax is a bit
>>> difficult for me.

>>
>>
>>
>> Maybe I obscured the issue by comparing name attributes to a string
>> instead
>> of using a predicate() function.
>>
>>
>>> if i have a list x and a function f how do i know if
>>> there is an element of x on which f returns something
>>> other than False?

>>
>>
>>
>> Using the above identifiers, let's assume we are looking for a name
>> starting
>> with "M":
>>
>>
>>>>> x = ["Peter", "Paul", "Mary", "Jane"]
>>>>> def f(o):

>>
>>
>> ... print "checking", o
>> ... return o.startswith("M")
>> ...
>>
>> If we call
>>
>>
>>>>> map(f, x)

>>
>>
>> checking Peter
>> checking Paul
>> checking Mary
>> checking Jane
>> [False, False, True, False]
>>
>> it invokes f() for every item in x and returns the above list of
>> booleans.
>> The equivalent list comprehension would be [f(i) for i in x]. Now
>>
>>
>>>>> True in map(f, x)

>>
>>
>> checking Peter
>> checking Paul
>> checking Mary
>> checking Jane
>> True
>>
>> gives the correct result but unfortunately does too much work as we don't
>> need to calculate f("Jane") when we already know the outcome. Enter
>> generator
>>
>>
>>>>> def lazymap(predicate, seq):

>>
>>
>> ... for item in seq:
>> ... yield predicate(item)
>> ...
>>
>> which calulates f(item) as needed. Proof:
>>
>>
>>>>> True in lazymap(f, x)

>>
>>
>> checking Peter
>> checking Paul
>> checking Mary
>> True
>>
>>
>> itertools.imap() is just the fast C implementation of lazymap().
>> The equivalent generator expression (new in Python 2.4) will be (f(i)
>> for i in x).
>>
>> Peter
>>

>

Terry Reedy
Guest
Posts: n/a

 06-11-2004

"Jim Newton" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> if i have a list x and a function f how do i know if
> there is an element of x on which f returns something
> other than False?

If I understand you correctly, you want something like

somexf=False
for i in x:
if f(i):
somexf = True
break

# somexf == <for some item in x f is true>

You are correct, filter() and the equivalent list comp give all items for
which f is true.
They do not break/return on encountering the first one. As a function, the
above is

def some(iterable, f):
for item in iterable:
if f(item): return True
return False

You can easily modify this to instead return item or None.

Terry J. Reedy

Peter Otten
Guest
Posts: n/a

 06-11-2004
Jim Newton wrote:

> sorry, i do not understand. The python syntax is a bit
> difficult for me.

Maybe I obscured the issue by comparing name attributes to a string instead
of using a predicate() function.

> if i have a list x and a function f how do i know if
> there is an element of x on which f returns something
> other than False?

Using the above identifiers, let's assume we are looking for a name starting
with "M":

>>> x = ["Peter", "Paul", "Mary", "Jane"]
>>> def f(o):

.... print "checking", o
.... return o.startswith("M")
....

If we call

>>> map(f, x)

checking Peter
checking Paul
checking Mary
checking Jane
[False, False, True, False]

it invokes f() for every item in x and returns the above list of booleans.
The equivalent list comprehension would be [f(i) for i in x]. Now

>>> True in map(f, x)

checking Peter
checking Paul
checking Mary
checking Jane
True

gives the correct result but unfortunately does too much work as we don't
need to calculate f("Jane") when we already know the outcome. Enter
generator

>>> def lazymap(predicate, seq):

.... for item in seq:
.... yield predicate(item)
....

which calulates f(item) as needed. Proof:

>>> True in lazymap(f, x)

checking Peter
checking Paul
checking Mary
True
>>>

itertools.imap() is just the fast C implementation of lazymap().
The equivalent generator expression (new in Python 2.4) will be
(f(i) for i in x).

Peter

Peter Otten
Guest
Posts: n/a

 06-11-2004
Jim Newton wrote:

> ah so i must encapsulate the predicate function in another named
> function which uses yield in order to have the iteration abort
> when the target item is reached? can i simply put the predicate
> function inside a lambda?

You can always substitute a function identifier with a lambda, e. g

>>> x = ['Peter', 'Paul', 'Mary', 'Jane']
>>> True in itertools.imap(lambda o: o.startswith("M"), x)

True
>>>

Calling a "function containing a yield statement", aka a generator, returns
an iterator object, i. e. an object with a next() method, which, when
called, executes the generator until the next yield statement or raises a
StopIteration exception. All state is kept between invocations of next().

The actual shortcircuiting is done by the "in" operator.

result = value in itertools.imap(predicate, sequence)

under the hood performs then

gen = itertools.imap(predicate, sequence)
try:
while True:
if value == gen.next():
break # found a match, now go on with else: ...
except StopIteration: # no more items in sequence
result = False
else:
result = True

This may look complicated, but you can simplify it yourself, if you know
that the most common case

it = iter(sequence)
try:
while True:
item = it.next()
# do something
except StopIteration:
pass

is actually spelt out as

for item in sequence:
# do something

So in the end we have just a fancy for loop in disguise:

for item in sequence:
if value == predicate(item):
result = True
break
else:
result = False

which I see is how you solved the problem in the past...

Peter

 Thread Tools

 Posting Rules You may not post new threads You may not post replies You may not post attachments You may not edit your posts BB code is On Smilies are On [IMG] code is On HTML code is OffTrackbacks are On Pingbacks are On Refbacks are Off Forum Rules

 Similar Threads Thread Thread Starter Forum Replies Last Post KevinSimonson C++ 6 10-23-2010 08:45 AM Abhi C++ 7 10-06-2005 12:46 AM kushalsoftpro C++ 6 11-04-2004 07:47 AM Jim Newton Python 8 06-08-2004 04:57 PM Rick Osborn Java 10 02-08-2004 02:25 AM

Advertisments