Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Just a comment on APIs in Scheme...

If you're defining a Web server route handler, it's reasonable to do it as you would in most languages, like this package's example:

    (get "/hello/:who"
      (lambda (rc)
        (format #f "<p>hello ~a</p> " (params rc "who"))))
    
But the following might be easier syntax extension in Scheme, in which each variable URL path element can be mapped for the programmer directly to a Scheme variable binding in the closure:

    (define-http-get-route ("/hello/" who)
      (format #f "<p>hello ~a</p> " who))
(Of course, you'd also have a function to sanitize/escape `who` before injecting it into the HTML.)


Guile's builtin server is similar:

    (define (hello-world-handler request request-body)
      (values '((content-type . (text/plain)))
          "Hello World!"))


IIUC, this is the handler for all requests, not just `GET` with path `/hello/<NAME>`.

It doesn't implement what many Web "backend" developers now call "routing", which means the programmer specifying a rule-based mapping of URL patterns to a set of handlers for different kinds of requests using a simple DSL, and then at run time the library/framework performing the parsing and dispatch based on those rules.

With that stock Guile library only, I think you'd instead have to manually parse the `request` argument, like in this example:

https://www.gnu.org/software/guile/manual/html_node/Web-Exam...


Why not keep the string as normal, but still do as you are suggesting? Shouldn't be too hard to have the macro parse it out so that the following would work, no?

    (define-http-get-route ("/hello/:who")
      (format #f "<p>hello ~a</p> " who))


Yes, with some of the fancier Scheme/Racket syntax transformers, you can do that string parsing at syntax expansion time.

Sometimes it makes sense (e.g., if you want to support chunks of hairy SQL pasted into the code).

I could go either way on how to specify Web server routes, but decided to go with the way I did, for 3 reasons:

1. Looks more familiar to Scheme programmers, without bindings coming out of strings (which I don't think is idiomatic Scheme).

2. Can be implemented more portably, including in Schemes that have only `syntax-rules` as a transformer.

3. If more semantics are added to the route specification later, such as type or validation, you might want want to be doing it in s-expressions rather than in a string.


Fair. I think my ultimate preference would probably be to have the string validated against the parameters. So, something like:

    (define-http-get-route ("/hello/:who" who)
      (format #f "<p>hello ~a</p> " who))
Prevents the confusion of people that remove a parameter from every path it was in, without also removing the parameter it would have bound to. Though, I suppose you would probably need to do a bit more to allow moving from query to path and such?


IMO the whole point is to get rid of the string as normal. The whole "/hello/:who" syntax is weird and arbitrary, it is a different way of declaring a variable which adds an unnecessary extra step to understanding the code.


It matches the Open API specifications, is about the only reason I would try to support it.




Consider applying for YC's Winter 2026 batch! Applications are open till Nov 10

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: