From: Stormcoder
Subject: a predicate builder
Date: 
Message-ID: <1146858499.463647.213780@j73g2000cwa.googlegroups.com>
I find myself wanting to search a list of strings a lot so I thought I
would create a predicate builder instead of writing out a new lambda
each time. This is what I initially tried:

(defun string-member-predicate-builder (target-str)
  "returns a predicate for use with higher order functions."
  (lambda (x)
    (string= target-str x)))

I had intended it to be used like so

(find-if #'(string-member-predicate-builder "string")
'("some" "string" "list"))

Obviously it doesn't work. I am not sure why it doesn't work, though.
Would someone enlighten me? What would be a workable solution to do
this? Am I doing things the stupid way? (The approach is wrong.)

What I wound up doing was this:

(defun string-member-of (target string-list)
(member-if #'(lambda (x) (string= x target)) string-list))

Being able to generate a predicate would be more flexible.

From: Zach Beane
Subject: Re: a predicate builder
Date: 
Message-ID: <m364kkgrzx.fsf@unnamed.xach.com>
"Stormcoder" <·········@gmail.com> writes:

> I find myself wanting to search a list of strings a lot so I thought I
> would create a predicate builder instead of writing out a new lambda
> each time. This is what I initially tried:
> 
> (defun string-member-predicate-builder (target-str)
>   "returns a predicate for use with higher order functions."
>   (lambda (x)
>     (string= target-str x)))
> 
> I had intended it to be used like so
> 
> (find-if #'(string-member-predicate-builder "string")
> '("some" "string" "list"))
> 
> Obviously it doesn't work.

Your sharpquote is misplaced. This should work:

   (find-if (string-member-predicate-builder "string") ...)

Also:

   (find "string" list :test #'string=)

> Being able to generate a predicate would be more flexible.

I would tend to use FIND with :test for simple examples like this.

Zach
From: Larry Clapp
Subject: Re: a predicate builder
Date: 
Message-ID: <slrne5ne1n.7sc.larry@theclapp.ddts.net>
On 2006-05-05, Stormcoder <·········@gmail.com> wrote:
> I find myself wanting to search a list of strings a lot so I thought
> I would create a predicate builder instead of writing out a new
> lambda each time. This is what I initially tried:
>
> (defun string-member-predicate-builder (target-str)
>   "returns a predicate for use with higher order functions."
>   (lambda (x)
>     (string= target-str x)))
>
> I had intended it to be used like so
>
> (find-if #'(string-member-predicate-builder "string")
> '("some" "string" "list"))

I think you mean

  (find-if (string-member-predicate-builder "string")
    '("some" "string" "list"))

Test:

  ecl-repl.vim (re)loaded at Fri May  5 16:36:26 2006
  COMMON-LISP-USER> (defun string-member-predicate-builder (target-str)
		      "returns a predicate for use with higher order functions."
		      (lambda (x)
			(string= target-str x)))
  STRING-MEMBER-PREDICATE-BUILDER
  COMMON-LISP-USER> (find-if (string-member-predicate-builder "string")
		      '("some" "string" "list"))
  "string"
  COMMON-LISP-USER> 

-- Larry
From: Pascal Bourguignon
Subject: Re: a predicate builder
Date: 
Message-ID: <87irokxm8b.fsf@thalassa.informatimago.com>
"Stormcoder" <·········@gmail.com> writes:

> I find myself wanting to search a list of strings a lot so I thought I
> would create a predicate builder instead of writing out a new lambda
> each time. This is what I initially tried:
>
> (defun string-member-predicate-builder (target-str)
>   "returns a predicate for use with higher order functions."
>   (lambda (x)
>     (string= target-str x)))
>
> I had intended it to be used like so
>
> (find-if #'(string-member-predicate-builder "string")
> '("some" "string" "list"))
>
> Obviously it doesn't work. I am not sure why it doesn't work, though.
> Would someone enlighten me? What would be a workable solution to do
> this? Am I doing things the stupid way? (The approach is wrong.)

Yes.   The stupid thing to do is to write #'.  Really guys, stop it!  
It's dumb.  


> What I wound up doing was this:
>
> (defun string-member-of (target string-list)
> (member-if #'(lambda (x) (string= x target)) string-list))
>
> Being able to generate a predicate would be more flexible.

  (find-if (string-member-predicate-builder "string") '("some" "string" "list"))

and:

  (member-if (lambda (x) (string= x target)) string-list)

work perfectly well.



In your case, what's wrong with:

  (find "string" '("some" "string" "list") :test (function string=))

?



-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

READ THIS BEFORE OPENING PACKAGE: According to certain suggested
versions of the Grand Unified Theory, the primary particles
constituting this product may decay to nothingness within the next
four hundred million years.
From: Stormcoder
Subject: Re: a predicate builder
Date: 
Message-ID: <1146860656.347871.252460@j33g2000cwa.googlegroups.com>
Ignorance. I'm still trying to figure out the best way to do things.
Understanding the details of all the libraries takes some time and
experience. That is why I was asking all the questions.
From: Pascal Bourguignon
Subject: Re: a predicate builder
Date: 
Message-ID: <87ejz8xl8n.fsf@thalassa.informatimago.com>
"Stormcoder" <·········@gmail.com> writes:
> Ignorance. I'm still trying to figure out the best way to do things.
> Understanding the details of all the libraries takes some time and
> experience. That is why I was asking all the questions.

I have not been too explicit because it's one of my usual rants, but

#'x is read as (function x), and I prefer to write (function x) than #'x.

(lambda (x) (* x x)) when evaluated, returns (function (lambda (x) (* x x)))
so there is no point in writing (function (lambda (x) (* x x)))
and no point in writing #'(lambda (x) (* x x))

Using #' seems to make the writer believe that he is manipulating code.
This is wrong:

(type-of (quote #'(lambda (x) (* x x)))) --> cons
(type-of (lambda (x) (* x x))) --> function

The code vs. data aspect doesn't depend on #' (or FUNCTION), but on QUOTE !



It wouldn't have come to your mind to write:

 (find-if (function (string-member-predicate-builder "string"))
          '("some" "string" "list"))

But since you've seen people using this #' uselessly, you've written
something that read exactly like that.



-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

WARNING: This product warps space and time in its vicinity.
From: Frank Buss
Subject: Re: a predicate builder
Date: 
Message-ID: <o8t1mkklmpjz.fqsl85n4qen2$.dlg@40tude.net>
Pascal Bourguignon wrote:

> (lambda (x) (* x x)) when evaluated, returns (function (lambda (x) (* x x)))
> so there is no point in writing (function (lambda (x) (* x x)))
> and no point in writing #'(lambda (x) (* x x))

Maybe the reason is that it is used in CLHS, e.g.:

http://www.lisp.org/HyperSpec/Body/fun_map.html

and people use examples, which are written in specifications, even if this
makes no sense for some examples of the CLHS.

-- 
Frank Buss, ··@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de
From: Stormcoder
Subject: Re: a predicate builder
Date: 
Message-ID: <1146864105.732513.163960@i40g2000cwc.googlegroups.com>
That is exactly right. When writing CL code I have the hyperspec up and
am looking at function specs and examples from there. I have been
considering the hyperspec as the definitive source. I believe PCL also
has examples that do the same thing.
From: Pascal Bourguignon
Subject: Re: a predicate builder
Date: 
Message-ID: <87zmhww1sn.fsf@thalassa.informatimago.com>
"Stormcoder" <·········@gmail.com> writes:

> That is exactly right. When writing CL code I have the hyperspec up and
> am looking at function specs and examples from there. I have been
> considering the hyperspec as the definitive source. I believe PCL also
> has examples that do the same thing.

All I'm saying is that I've never seen anybody coming here and asking why:

(mapcar (function (get-some-function some-parameter)) some-list)

doesn't work, but we regularly see newbies puzzled over #'.
This is merely too much syntactic suggar for their own good!

That's the difference between names and syntax.



(And ' is suggary too, (QUOTE x) is less unconspicuous than 'x)

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

There is no worse tyranny than to force a man to pay for what he does not
want merely because you think it would be good for him. -- Robert Heinlein
From: Peter Seibel
Subject: Re: a predicate builder
Date: 
Message-ID: <m2fyj7v1wk.fsf@gigamonkeys.com>
"Stormcoder" <·········@gmail.com> writes:

> That is exactly right. When writing CL code I have the hyperspec up and
> am looking at function specs and examples from there. I have been
> considering the hyperspec as the definitive source. I believe PCL also
> has examples that do the same thing.

Yes, because I don't subscribe to Pascal's philosophy about the use of
#'. My point of view is that a lambda expression is a kind of function
name and thus just the way I say:

  (mapcar #'some-function some-list)

I say:

  (mapcar #'(lambda (x) (whatever x)) some-list)

The LAMBDA macro that turns (lambda (...) ...) in a value position
into (function (lambda (...) ...)) is a hack that was put in to the
language to enable an ISLISP compatibility layer to be written in pure
Common Lisp. But I'm not saying Pascal is crazy--just that we take a
different point of view on this.

-Peter

-- 
Peter Seibel           * ·····@gigamonkeys.com
Gigamonkeys Consulting * http://www.gigamonkeys.com/
Practical Common Lisp  * http://www.gigamonkeys.com/book/
From: Thomas A. Russ
Subject: Re: a predicate builder
Date: 
Message-ID: <ymipsioqqhh.fsf@sevak.isi.edu>
"Stormcoder" <·········@gmail.com> writes:

> I find myself wanting to search a list of strings a lot so I thought I
> would create a predicate builder instead of writing out a new lambda
> each time. This is what I initially tried:
> 
> (defun string-member-predicate-builder (target-str)
>   "returns a predicate for use with higher order functions."
>   (lambda (x)
>     (string= target-str x)))

Unless this is used to generate one-time throwaway functions, then you
may want to consider returning a compiled function instead:

  (defun string-member-compiled-predicate-builder (target-str)
     "returns a predicate for use with higher order functions."
     (compile nil `(lambda (x)
                      (string= ,target-str x))))


The other questions were beaten to death already...

-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: Pascal Bourguignon
Subject: Re: a predicate builder
Date: 
Message-ID: <877j4ws2do.fsf@thalassa.informatimago.com>
···@sevak.isi.edu (Thomas A. Russ) writes:

> "Stormcoder" <·········@gmail.com> writes:
>
>> I find myself wanting to search a list of strings a lot so I thought I
>> would create a predicate builder instead of writing out a new lambda
>> each time. This is what I initially tried:
>> 
>> (defun string-member-predicate-builder (target-str)
>>   "returns a predicate for use with higher order functions."
>>   (lambda (x)
>>     (string= target-str x)))
>
> Unless this is used to generate one-time throwaway functions, then you
> may want to consider returning a compiled function instead:
>
>   (defun string-member-compiled-predicate-builder (target-str)
>      "returns a predicate for use with higher order functions."
>      (compile nil `(lambda (x)
>                       (string= ,target-str x))))

You're surprizing me, and clisp implementors...

[444]> (defun string-member-predicate-builder (target-str)
   "returns a predicate for use with higher order functions."
   (lambda (x)
     (string= target-str x)))
STRING-MEMBER-PREDICATE-BUILDER
[445]> (STRING-MEMBER-PREDICATE-BUILDER "hello")
#<FUNCTION :LAMBDA (X) (STRING= TARGET-STR X)>
[446]> (compile 'STRING-MEMBER-PREDICATE-BUILDER)
STRING-MEMBER-PREDICATE-BUILDER ;
NIL ;
NIL
[447]> (STRING-MEMBER-PREDICATE-BUILDER "hello")
#<COMPILED-FUNCTION STRING-MEMBER-PREDICATE-BUILDER-1>
[448]> 

Is there any implementation that won't return a compiled closure from
a compiled function?

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

WARNING: This product warps space and time in its vicinity.