(Previous discussion continued)
Re: Changes to SRFI 125 taylanbayirli@xxxxxx 12 Sep 2015 08:13 UTC

Re: Changes to SRFI 125 taylanbayirli@xxxxxx 12 Sep 2015 08:13 UTC

John Cowan <xxxxxx@mercury.ccil.org> writes:

> John Cowan scripsit:
>
>> > - hash-table-find
>> > By the way if you make the 'failure' thunk of hash-table-find optional,
>
> What would be the default behavior?  I don't understand this.

The following definition might be a fine one:

  - (hashtable-find proc ht)

  Applies proc to associations in ht until proc returns non-#f and
  returns that value; returns #f if all applications return #f.

It's very simple and maybe fulfills most use-cases.  It's basically
'any' already, and then 'every' just needs negation.

What bothers me it isn't very general.  What if you want the key or
value of the entry that matched?  They might be #f.  In fact I think it
might be more common to want the key and value, than the result of some
computation that proc does.  That would be consistent with typical
'find' semantics as well.  I'm considering defining the following and
letting users define the other in terms of this themselves if they use
it frequently:

  - (hashtable-find proc ht)

  Applies proc to associations in ht until proc returns non-#f, and
  returns 'key', 'value', and 'found?' where the former two are
  undefined if 'found?' is #f.

I can see myself writing the following without feeling too annoyed in
most cases:

    (let-values (((k v found?) (hashtable-find proc ht)))
      (if found?
          (do something)         ;k and v unused
          (do something else)))

(That's 'any'.)

Surely more verbose than

    (if (hashtable-find proc ht)  ;or hashtable-any
        (do something)
        (do something else))

but obviates the need for a separate procedure.  I'll abstract it out
manually if I use it often:

    (define (hashtable-find? proc ht)
      (let-values (((k v found?) (hashtable-find proc ht)))
        found?))

That's a very trivial definition.

What about the non-#f value that proc returns, which might be something
more useful than just #t?  Whatever proc does will be on the key and
value, which are returned, so you can duplicate what proc does.  What if
it's a heavy operation?  So far I think that's probably an obscure
use-case.  If it really comes down to it, use let-escape-continuation.

    (let/ec return
      (hashtable-for-each (lambda (key value)
                            (and=> (heavy-op key value) return))
                          ht))

I might just write a delimited continuations SRFI next.

Taylan