Summary of the thread:

"Hey, here's this thing I'd like to do.  Is there a way to do it?"

T = <a handful of hours>:  "Nope.  Here's some suggestions, though."

T = 22 hours:  "Here, let me add that feature to the language."

Man, I love this community.  Thank you to everyone.


On Fri, Aug 31, 2018 at 5:46 AM, Ryan Culpepper <ry...@ccs.neu.edu> wrote:

> On 8/31/18 4:28 AM, Greg Hendershott wrote:
>
>> 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]. [....]
>>
>
> Here's an implementation:
>
>   (define not-found (gensym 'not-found))
>   (define (not-not-found? x) (not (eq? x not-found)))
>
>   (begin-for-syntax
>     (define-syntax-class kvpat
>       #:description "hash key-value pattern"
>       ;; Note: be careful to evaluate key expr only once!
>       (pattern [key:expr value-pattern]
>                #:with pattern
>                #'(app (lambda (h) (hash-ref h key not-found))
>                       (? not-not-found? value-pattern)))
>       (pattern [key:expr value-pattern default:expr]
>                #:with pattern
>                #'(app (lambda (h) (hash-ref h key (lambda () default)))
>                       value-pattern))))
>
>   (define-match-expander hash-table*
>     (syntax-parser
>       [(_ kv:kvpat ...)
>        #'(? hash? kv.pattern ...)]))
>
>   (match (hash 'a 1 'b 2)
>     [(hash-table* ['a a] ['c c 3])
>      (+ a c)])
>   ;; => 4
>
> Ryan
>

-- 
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 racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to