Skip to content

USER_GUIDE

Michael Hueschen edited this page Oct 14, 2022 · 4 revisions

rep_lang user guide

a brief primer, which will hopefully be developed further, as time allows.

subject to change as rep_lang develops!

key concepts

rep_lang parses programs (text / strings of characters) into an Abstract Syntax Tree (AST). internally, this is referred to as Expr, short for expression.

Exprs can be interpreted to Values.

an example here would be that the string (+ 1 2) parses to an Expr of "the addition operator applied to the literal 1 and the literal 2". that Expr can the be interpreted to the Value of 3.

ideally, the internals of the language will not need to be inspected by users, because the abstractions won't "leak". however, Expr and Value are relatively "public" and there values may be stored outside of the interpreter (which is somewhat uncommon - for a language to expose internal datastructures - but seems necessary for some of our goals related to Holochain interoperation).

concrete syntax

note: unfortunately, I can't give a full specification of the concrete syntax and then generate the parser from that, for various reasons. so what is written here is subject to diverge from the implementation of the parser. this is current as of 2021-11-12.

grammar

e ::= (lam [x ...] e)      ;; lambda, with 1+ arguments
    | (let ([x e] ...) e)  ;; let binding
    | (if e e e)           ;; if (first `e` must have type Bool, and the second
                           ;;     & third must have the same type)
    | (e e ...)            ;; application expression
    | (fix e)              ;; fixpoint operator on `e`
    | var                  ;; variable reference
    | prim
    | lit

primop ::= +
        | -
        | *
        | /
        | ==
        | null
        | pair
        | fst
        | snd
        | cons
        | nil
        | head
        | tail

var ::= sequence of chars matching `^[a-zA-Z_][a-zA-Z0-9_\-]*$`

lit ::= sequence of chars matching `^-?[0-9]+$`
      | bool

bool ::= true
       | false

how to read this grammar

looking at e above, we see (on the right side of the ::= and below it) a number of variants.

some of those variants contain es, which implies that we choose variants of e and fill them in there, ad infinitum.

with primop, by contrast, we see no such recursive occurrences - only a finite number of "flat" variants.

testing in rli

the best way to get a felt sense for rep_lang is to use rli (rep_lang interactive/interpreter). here is an example transcript:

# from the repo root

~/projects/rep_lang » cd rep_lang_runtime
~/projects/rep_lang/rep_lang_runtime » cargo run -q --bin rli

                         __
   ________  ____       / /___ _____  ____ _
  / ___/ _ \/ __ \     / / __ `/ __ \/ __ `/
 / /  /  __/ /_/ /    / / /_/ / / / / /_/ /
/_/   \___/ .___/____/_/\__,_/_/ /_/\__, /
         /_/   /_____/             /____/

welcome 🙂

any expression or definiton will be parsed, typechecked, and evaluated.
quit with `ctrl-d`.

> 1
ast: Lit(LInt(1))

(: 1
   Int
)
> true
ast: Lit(LBool(true))

(: true
   Bool
)
> (+ 1 2)
ast: App(App(Prim(Add), Lit(LInt(1))), Lit(LInt(2)))

(: 3
   Int
)
> ((lam [x] (+ x 1)) 9)
ast: App(Lam(Name("x"), App(App(Prim(Add), Var(Name("x"))), Lit(LInt(1)))), Lit(LInt(9)))

(: 10
   Int
)
> (if (== 1 2) 3 4)
ast: If(App(App(Prim(Eql), Lit(LInt(1))), Lit(LInt(2))), Lit(LInt(3)), Lit(LInt(4)))

(: 4
   Int
)
> (let ([x 1] [y 2]) (* x y))
ast: Let(Name("x"), Lit(LInt(1)), Let(Name("y"), Lit(LInt(2)), App(App(Prim(Mul), Var(Name("x"))), Var(Name("y")))))

(: 2
   Int
)
> (cons 1 nil)
ast: App(App(Prim(Cons), Lit(LInt(1))), Prim(Nil))

(: (cons 1 nil)
   (List Int)
)
> (null nil)
ast: App(Prim(Null), Prim(Nil))

(: true
   Bool
)
> (pair 7 false)
ast: App(App(Prim(Pair), Lit(LInt(7))), Lit(LBool(false)))

(: (7, false)
   (Int, Bool)
)
> (snd (pair 7 false))
ast: App(Prim(Snd), App(App(Prim(Pair), Lit(LInt(7))), Lit(LBool(false))))

(: false
   Bool
)
> (head (cons 7 (cons 8 nil)))
ast: App(Prim(Head), App(App(Prim(Cons), Lit(LInt(7))), App(App(Prim(Cons), Lit(LInt(8))), Prim(Nil))))

(: 7
   Int
)
>

bye!
Clone this wiki locally