#lang racket/base
(module let2 plait
(define-type LAE
[Num (val : Number)]
[Sub (l : LAE) (r : LAE)]
[Id (name : Symbol)]
[Let2 (name1 : Symbol) (val1 : LAE) (name2 : Symbol) (val2 : LAE)
(body : LAE)])
(define-type Env
[Extend (id : Symbol) (val : Number) (rest : Env)]
[EmptyEnv])
(define (lookup id env)
(type-case Env env
[(EmptyEnv) (error 'lookup "unbound")]
[(Extend name val rest)
(if (eq? id name) val (lookup id rest))]))
(define (interp expr env)
(type-case LAE expr
[(Num n) n]
[(Sub l r) (- (interp l env) (interp r env))]
[(Id name) ....]
[(Let2 bound-id1 named-expr1 bound-id2 named-expr2 bound-body) ....]))
(test (interp (Let2 'x (Num 1) 'y (Num 2) (Sub (Id 'x) (Id 'y))) (EmptyEnv))
-1)
(test (interp (Let2 'x (Num 1) 'y (Num 2)
(Let2 'x (Id 'y) 'y (Id 'x)
(Sub (Id 'x) (Id 'y)))) (EmptyEnv))
1)
)
(require (only-in 'let2))
(module odds plait #:untyped
#;(let* ([odds
(lambda (....)
(let ([odds (....)])
(cond
[(empty? lst) lst]
[(odd? (first lst)) (cons (first lst) (odds (rest lst)))]
[else (odds (rest lst))])))]
[odds (....)])
(begin
(test (odds '(1 2 3 4 5 6)) '(1 3 5))
(test (odds '(2 4 6)) '()))))
(require (only-in 'odds))