sydney.lambda
2019-6-27 01:09:46

Has anyone ever come across/experimented with a Lisp/Scheme that has “where” clauses? Something like: (define (foo x) (if (> x 2) (inc y) (dec y)) (where ([y (* x x)] [inc (λ(x)(+ x 1)] [dec (λ(x)(- x 1)])) => (define (foo x) (let ([y (* x x)] [inc (λ(x)(+ x 1)] [dec (λ(x)(- x 1)]) (if (> x 2) (inc y) (dec y)))) I’m curious what pitfalls this has (at the very least I feel like you’d limit it to certain locations as in Haskell’s where), and how it could possibly be implemented. Cheers :slightly_smiling_face:


samth
2019-6-27 01:14:27

it’s pretty easy to implement, here’s an untested version: (define-syntax (where stx) (raise-syntax-error #f stx "used outside of `define/where`")) (define-syntax (define/where stx) (syntax-parse stx #:literals (where) [(_ (f args ...) e0 e ... (where (clauses ...))) #'(define (f args) (let (clauses ...) e0 e ...))]))


sydney.lambda
2019-6-27 01:18:54

Thanks! It makes sense to me reading it, but gives "_ wildcard not allowed as expression" when trying to use it. Really, I should feel ashamed if I can’t work it out myself, now I know it really can just be transformed into a let using a special define/where form.


greg
2019-6-27 01:23:20

If you’re using #lang racket you’ll need to (require (for-syntax syntax/parse)). syntax-parse is not required by default. Also it needs to be required for-syntax. I think approximately 100% of people using syntax/parse get puzzled by this error message.


greg
2019-6-27 01:24:24

After you fix that, you’ll get another error, which is hopefully clearer: ; /tmp/foo.rkt:8:64: syntax: missing ellipsis with pattern variable in template ; at: args ; in: (syntax (define (f args) (let (clauses ...) e0 e ...)))


sydney.lambda
2019-6-27 01:24:56

I added a … after args; hopefully that’s it.


greg
2019-6-27 01:25:05

Bingo.


greg
2019-6-27 01:25:50

At least, that makes the definition of the macro OK. I haven’t tried to use it.


sydney.lambda
2019-6-27 01:27:25

Seems to work great! Thank you both for your help. If I wasn’t already convinced of Lisp/Scheme/Racket’s ease-of-transformation (I was) I sure am now! :wink:


sydney.lambda
2019-6-27 01:28:11

I remember someone mentioning this was removed from OCaml for some reason, but what exactly was said escapes me, sadly.


lexi.lambda
2019-6-27 01:36:07

FWIW, recent Rackets also include this information in the error message: _: wildcard not allowed as an expression after encountering unbound identifiers (which is possibly the real problem): where syntax-parse