[racket] matching behavior in dispatch-rules

From: Jay McCarthy (jay.mccarthy at gmail.com)
Date: Wed Jan 22 15:46:25 EST 2014

On Wed, Jan 22, 2014 at 1:14 PM, Matthew Butterick <mb at mbtype.com> wrote:
> I think I've buried the problem inside an inaccurate analogy.
>
> I'm wondering if there's a generalized idiom for matching an item in a
> dispatch pattern WITHOUT passing it through as one of the arguments.
>
> For instance. Suppose I have a magic.html page that I generate with a route,
> so I set up a dispatch pattern like this:
>
> ;;;;;;;;;;;;;;;;;;;;;;
> #lang racket
> (require web-server/dispatch
> web-server/http/request-structs
> net/url)
>
> (define (url->request u)
> (make-request #"GET" (string->url u) empty
> (delay empty) #f "1.2.3.4" 80 "4.3.2.1"))
>
> (define-values (test-dispatch _)
> (dispatch-rules
> [((string-arg) ... "magic.html") (λ(req . args) (print args))]))
>
> (test-dispatch (url->request "http://host.com/some/path/to/magic.html"))
> ;;;;;;;;;;;;;;;;;;;;;
>
> This dispatch pattern will match the given URL and return as the arguments:
>
> '(("some" "path" "to"))
>
> So far, so good. But suppose I want to put the name of the magic page in a
> variable, magic-page-name, and match on that instead:
>
> (define magic-page-name "magic.html")
>
> So how do I adjust the dispatch pattern? If I do this:
>
> ((string-arg) ... magic-page-name)
>
> It's a syntax error, of course. So instead I change the pattern to:
>
> ((string-arg) ... (? (λ(x)(equal? x magic-page-name))))
>
> This seems to work, except that for arguments, I now get:
>
> '(("some" "path" "to") "magic.html")
>
> What I would prefer is to match on magic-page-name without passing through
> the result as an argument (i.e., get the same behavior as when I was using
> the string literal)

I don't think this is possible. dispatch-rules is much more restricted
than match because it has to be able to go backwards from a call like
(f 1 2 3) into a URL like "/fs/1/blah/2/3".

If you don't need that, maybe you just want to use the request/url and
url/paths match expanders directly and write a usage of "match".

Jay

>
>
>
>
>
> On Jan 21, 2014, at 9:10 AM, Jay McCarthy <jay.mccarthy at gmail.com> wrote:
>
> Hi Matthew,
>
> In your 'match' examples, you are printing out the result of "matched"
> which is bound by (and matched ...) on the outside of the match
> pattern, so it is equivalent to
>
> (define matched (list ....))
> (match matched
> [...inside... ....])
>
> This idiom doesn't really have anything to do with what dispatch-rules
> does, because dispatch-rules doesn't have "and". Instead,
> dispatch-rules behaves more like a normal "match" where only the names
> are bound/passed-to-the-function.
>
> Jay
>
>
> On Sat, Jan 18, 2014 at 9:59 PM, Matthew Butterick <mb at mbtype.com> wrote:
>
> If you run this code:
>
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> #lang racket
> (require web-server/dispatch
> web-server/http/request-structs
> net/url)
>
> (define (url->request u)
> (make-request #"GET" (string->url u) empty
> (delay empty) #f "1.2.3.4" 80 "4.3.2.1"))
>
> (define-values (test-dispatch sum-url)
> (dispatch-rules
> [((? string?) "foo" (? string?)) test-route]
> [((? string?) (? (λ(x) (equal? x "bar"))) (? string?)) test-route]))
>
> (define (test-route req . args)
> (displayln (format "args = ~v" args)))
>
> (test-dispatch (url->request
> "http://url.com/first-string/foo/second-string.html"))
> (test-dispatch (url->request
> "http://url.com/first-string/bar/second-string.html"))
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
>
> You'll get this:
>
> args = '("first-string" "second-string.html")
> args = '("first-string" "bar" "second-string.html")
>
>
> Whereas if you use these patterns with regular match, like so:
>
> (match (list "first-string" "foo" "second-string.html")
> [(and matched (list (? string?) "foo" (? string?))) matched])
>
> (match (list "first-string" "bar" "second-string.html")
> [(and matched (list (? string?) (? (λ(x) (equal? x "bar"))) (? string?)))
> matched])
>
> You'll get:
>
> '("first-string" "foo" "second-string.html")
> '("first-string" "bar" "second-string.html")
>
>
> Thus my question: why doesn't the literal "foo" in the first pattern under
> dispatch-rules become one of the matched items, as it does with regular
> match?
>
>
> ____________________
> Racket Users list:
> http://lists.racket-lang.org/users
>
>
>
>
> --
> Jay McCarthy <jay at cs.byu.edu>
> Assistant Professor / Brigham Young University
> http://faculty.cs.byu.edu/~jay
>
> "The glory of God is Intelligence" - D&C 93
>



-- 
Jay McCarthy <jay at cs.byu.edu>
Assistant Professor / Brigham Young University
http://faculty.cs.byu.edu/~jay

"The glory of God is Intelligence" - D&C 93


Posted on the users mailing list.