Justin Pombrio

Syntactic Sugar

Here are Some of my favorite examples of simple syntactic sugar.

For Loops

for f(v1 from x1, ..., vn from xn) { body }
==>
f(lam(v1, ..., vn) { body }, x1, ..., xn)

If-let

if let p = x { y } else { z }
==>
match x {
  p => y,
  _ => z
}

Fun

fun f(v1, ..., vn) { body }
==>
rec f = lam(v1, ..., vn) { body }

Do Notation

do x           ==>  x
do x; xs       ==>  x >>= lam(v) { do xs }
do v <- x; xs  ==>  x >>= lam(v) { do xs }

And/Or

x and y        ==>  if x then y else false
x or  y        ==>  if x then true else y

Testing Forms

x is y
==>
try { x }
then(x) { add-test-result(x == y) }
catch(e) { add-test-result(false) } <!-- -->
x raises e
==>
try { x }
then(x) { add-test-result(false) }
catch(err) { add-test-result(err == e) }

Let

let v1 = x1, ..., vn = xn in body
==>
(lam(v1, ..., vn) { body })(x1, ..., xn)

Cases

cases(T) x
  | C1(v11, ..., v1k)  => x1
  | ...
  | Cn(vn1, ..., vnk) => xn
==>
x.matcher({
  C1: lam(v11, ..., v1k) { x1 },
  ...,
  Cn: lam(vn1, ..., vnk) { xn }
})

Typeof

In a typed language, some sugars benefit from being able to take the type of one of their subexpressions:

let v1 = x1, ..., vn = xn in body
==>
(lam(v1 : typof(x1), ..., vn : typeof(xn)) { body })(x1, ..., xn)

Debugging

Some sugars benefit from being able to get source-location information. For example:

debug(msg)
==>
print("On line " + str(SRCLOC.line-number) + ":");
print(msg)

Etc.

More sugars to think about: var-lifting, letrec, cond, circular refs, return, ErrorState, sugars from Cyenne, Pyret.