Is it possible to use "s-exp" reader to parse expressions without parens wrapped?

Hi, I'm trying to implement a typed language using Racket's LOP.
since my calculus requires full annotation, it will be ugly to write code like

(λ (x : t1) e t2)

It becomes worser when lambda expression are nested like

(λ (x : t1) (λ (y : t3) e t4) t2)

I decide to adopt typed racket's style, is it possible to use “s-exp” reader to parse code like (if yes, then how?)

(: double-num (-> int int))
(define double-num
  (λ (x)
    (+ x x)))

Macro seems only able to capture expressions wrapped with parens or datums.



I think outmost will need parens around, but inside of it, there has ~seq serves sequence. There have more patterns helpers, you can read them. :slight_smile:

1 Like

This is a large topic, and you could wind up wandering around in it for a long time.

To clarify your question: it doesn't appear to me that you include samples of syntax that you would like to use, only examples of syntax that you don't like. Adding that would help steer a response to your question.

More broadly, the question of what a reader for a non-parenthesized language should look like is an area of very active research, take a look at the "shrubbery" proposals that are currently under consideration. Late for class, no time to look up that URL right now.....

If I read correctly, the syntax that @doublex wants is regular s-expression. It’s simply that the type declaration should be in a separate form. That is, @doublex wants

(: add1 (-> Integer Integer))
(define (add1 x) ...)


(define (add1 [x : Integer]) : Integer ...)


(define (add1 x) (-> Integer Integer) ...)


Note that Typed Racket doesn’t use ~seq. Rather, IIUC, : is a macro that quotes the type annotation and stuff it into the expanded code so that the whole program can be traversed for type checking later. You can find its definition at

The Typed Racket approach is convoluted, but it is extensible in a sense that users can define a macro that expands to annotations / definitions / forms with internal definition context, and Typed Racket will still be able to handle them. Another possible approach is to override #%module-begin and various macros with body so that you can use ~seq to search for annotations and definitions in the body. This could risk false positives and negatives, but might be OK and simpler if your system is sufficiently constrained.


I see that @sorawee read the question more carefully than I did; my mistake. Going "whole-program" with a #%module-begin seems like the right choice to me. More generally, people like @sorawee and @ryanc will know more about this than I do!