Scheme

# Scheme and Lisp syntaxes

It is possible to write OCaml programs with Scheme or Lisp syntax. They are close to one another, both using parentheses to identify and separate statements.

## Common

The syntax extension kits are named "`pa_scheme.cmo`" and "`pa_lisp.cmo`". The sources (same names ending with ".ml" in the Camlp5 sources), are written in their own syntax. They are boostrapped thanks to the versions being written in revised syntax and to the Camlp5 pretty printing system.

In the OCaml toplevel, it is possible to use them by loading "`camlp5r.cma`" first, then "`pa_lisp.cmo`" or "`pa_scheme.cmo`" after:

      ocaml -I +camlp5 camlp5r.cma pa_scheme.cmo
              Objective Caml version ...

              Camlp5 Parsing version ...

      # (let ((x 3)) (* 3 x))
      - : int = 9
      # (values 3 4 5)
      - : (int * int * int) = (3, 4, 5)

      ocaml -I +camlp5 camlp5r.cma pa_lisp.cmo
              Objective Caml version ...

              Camlp5 Parsing version ...

      # (let ((x 3)) (* 3 x))
      - : int = 9
      # (, 3 4 5)
      - : (int * int * int) = (3, 4, 5)

The grammar of Scheme and Lisp are relatively simple, just reading s-expressions. The syntax tree nodes are created in the semantic actions. Because of this, these grammars are hardly extensible.

However, the syntax extension EXTEND ("`pa_extend.cmo`" in extensible grammars) works for them: only the semantic actions need be written with the Scheme or Lisp syntax. Stream parsers are also implemented.

Warning: these syntaxes are incomplete, but can be completed, if Camlp5 users are insterested.

## Scheme syntax

Some examples are given to show the principles:

OCaml | Scheme
--- | ---
`let x = 42;;` | `(define x 42)`
`let f x = 0;;` | `(define (f x) 0)`
`let rec f x y = 0;;` | `(definerec (f x y) 0)`
`let x = 42 and y = 27 in x + y;;` | `(let ((x 42) (y 27)) (+ x y))`
`let x = 42 in let y = 27 in x + y;;` | `(let* ((x 42) (y 27)) (+ x y))`
`module M = struct ... end;;` | `(module M (struct ...))`
`type 'a t = A of 'a * int | B` | `(type (t 'a) (sum (A 'a int) (B)))`
`fun x y -> x` | `(lambda (x y) x)`
`x; y; z` | `(begin x y z)`
`f x y` | `(f x y)`
`[1; 2; 3]` | `[1 2 3]`
`x :: y :: z :: t` | `[x y z :: t]`
`a, b, c` | `(values a b c)`
`match x with 'A'..'Z' -> "x"` | `(match x ((range 'A' 'Z') "x")))`
`{x = y; z = t}` | `{(x y) (z t)}`

## Lisp syntax

The same examples:

OCaml | Lisp
--- | ---
`let x = 42;;` | `(value x 42)`
`let f x = 0;;` | `(value f (lambda x 0))`
`let rec f x y = 0;;` | `(value rec f (lambda (x y) 0))`
`let x = 42 and y = 27 in x + y;;` | `(let ((x 42) (y 27)) (+ x y))`
`let x = 42 in let y = 27 in x + y;;` | `(let* ((x 42) (y 27)) (+ x y))`
`module M = struct ... end;;` | `(module M (struct ...))`
`type 'a t = A of 'a * int | B` | `(type (t 'a) (sum (A 'a int) (B)))`
`fun x y -> x` | `(lambda (x y) x)`
`x; y; z` | `(progn x y z)`
`f x y` | `(f x y)`
`[1; 2; 3]` | `(list 1 2 3)`
`x :: y :: z :: t` | `(list x y z :: t)`
`a, b, c` | `(, a b c)`
`match x with 'A'..'Z' -> "x"` | `(match x ((range 'A' 'Z') "x")))`
`{x = y; z = t}` | `({} (x y) (z t))`