A general trick for optional values with match is something like (or
pat (app (λ _ default-value) pat)). But that doesn't work for
hash-table which uses [pat path] for each mapping. (At least I
couldn't see how.)

Here's _a_ way you could write this as a match pattern:

(define ((hash-has-keys? keys) ht)
  (for/and ([key (in-list keys)])
    (hash-has-key? ht key)))

(match (hash 'a 0 'b 1)
  [(? (hash-has-keys? '(a b))
      (app (λ (ht)
             (values (hash-ref ht 'a)
                     (hash-ref ht 'b)
                     (hash-ref ht 'c 'c-default)))
           a b c))
   (list a b c)])

[I really don't like the hash-has-keys? business, and the resulting
double lookups. But (=> id) is available only to bodies, and
`failure-cont` didn't work for me. So I don't know how else to handle
the case where it should _not_ match.]

Obviously the above is tedious. But, it works solely in term of match
patterns, and it could be the kind of syntax that a
define-match-expander emits for some nicer surface syntax. Where each
mapping is either required [k v], or, optional and you must supply a
default [k v d].  It might also be nice to have syntax like id, no
brackets, meaning the hash key is 'id and the pattern id is #'id.


How Clojure handles destructuring maps, IIRC, is to supply defaults as
`:or {k v ...}` separate from the main matching map. (I don't love
that separation).  If you don't supply a default, it does the typical
Clojure thing where a missing value isn't an error it is nil. (I also
don't love that.)

Clojure does however have the nice thing where :key is bound to a key
identifer (like that 3rd variation with no brackets I just mentioned)
to avoid repetition.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to