Search code examples
functional-programmingschemelispracketinfix-notation

How to put Lisp/Scheme/Racket symbol at the end?


A form in Lisp/Scheme/Racket has symbol put at first position. This code works in Racket:

(define (? a b) (if a (display b) 0))
(? #t "Hello")

But I want to simulate the a? b:0 statement in C/C++ and the question mark (the symbol) is supposed to be at the end, after a.

How to put ? and a and b in this order?

(define (a ? b) (if a (display b) 0))
(#t ? "Hello")

Do I need to use define-syntax or that kind of thing?


Solution

  • Let me offer an alternative solution via overriding the application syntax #%app. Here's an example of the ternary operator in C-like languages:

    #lang racket
    
    (require syntax/parse/define
             (only-in racket [#%app racket:#%app]))
    
    (define-syntax-parser #%app
      [(_ test-expr {~datum ?} then-expr {~datum :} else-expr)
       #'(if test-expr then-expr else-expr)]
      [(_ xs ...)
       #'(racket:#%app xs ...)])
    
    > ((= 42 42) ? "a" : "b")
    "a"
    > ((= 42 0) ? "a" : "b")
    "b"
    

    Because the application syntax has the lowest priority, other syntax will be considered first:

    > (define-simple-macro (discard-all xs ...) 1)
    > (discard-all ? 42 : 123)
    1
    > (if ? 1 : 2)
    if: bad syntax ;; because if should have exactly three subforms, but the above line has four.
    

    But as Ryan said, this is not a "good" Racket code in a sense that it defies Racket convention and no one (well, probably except you) will be able to understand your code.