[r6rs-discuss] [Formal] FIND delivers an ambiguous value

Eli Barzilay eli at barzilay.org
Wed Nov 1 14:59:31 EST 2006


On Nov  1, Andre van Tonder wrote:
> On Wed, 1 Nov 2006, Shiro Kawai wrote:
> 
> > From: Andre van Tonder <andre at het.brown.edu>
> >>
> >> This is clearly the right way of doing it.  But since then
> >>
> >>    find = memp
> >>
> >> I would argue for dropping find altogether.
> >
> > In my view, 'find' is just a convenience procedure trading
> > accuracy (about #f as element).   Despite of the problem
> > Nils pointed out, I use 'find' a lot more than 'member'-type
> > procedures, because most of the time I know what I'm going
> > to find is not #f.  I think it captures a common use case
> > and worth to have it.
> 
> But in your use case, don't you normally have to check the
> return value anyway?  If so, there very little
> difference between writing:
> 
>    (let ((x (memp p list)))      ; equivalent to suggested modification
>      (if x
>          (do-something (car x))
>          (do-something-else)))
> 
> and
> 
>    (let ((x (find p list)))      ; with existing spec
>      (if x
>          (do-something x)
>          (do-something-else)))   ; fragile
> 
> except that the suggested modification is more reliable in case
> your data is corrupt (exactly this has been known to happen to me).
> 
> Sometimes memp can be more concise.  The following is a very common use case:
> 
>    (cond ((memp p list) => car)  ; equivalent to suggested modification
>          (else 'error))
> 
>    (cond ((find p list) => (lambda (result) result))  ; existing spec
>          (else 'error))                               ; more fragile
> 
> The memp convention is the traditional way of encoding "maybe"
> return values in Scheme.  Find, as currently specified, is in
> contradiction with this old convention.  So is the optional argument
> suggestion.

Two things make `find' more convenient:

1. It is much more convenient to write:

     ... (find p list) ...

   than

     ... (cond [(memp p list) => car] [else #f]) ...

   It's a simple concept that should not worth more than a few
   characters.  (Lame reason, I know, but like he said -- it's just
   convenient.)

2. I think that *very* often you run into situations where the
   fragility of `find' is irrelevant.  A typical example:

     (find (lambda (str) (< 10 (string-length str))) strings)

   Which can never return an ambiguous #f.  I'd even say that uses of
   `find' over lists that contain `#f' are almost always bogus.
   (Except that they are sometimes useful too -- for example, map a
   function that returns #f to mask some items out, then use `find' on
   the result.)

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                  http://www.barzilay.org/                 Maze is Life!



More information about the r6rs-discuss mailing list