Skip to content

Surf and Deep

The .ch files in the lessons use Surf, Chelis's readable source syntax. The compiler can render their structure as Deep, an s-expression syntax with nested parentheses and tagged nodes. Deep files use the .dp extension. You do not need to write Deep to run the lessons.

Save this source as module.ch. It contains the same add_vec definition as lesson 1, now inside a module:

module.ch

module Hello.Basics.HelloTensor
export (add_vec)
def add_vec[n](x: &tensor[n, f32], y: &tensor[n, f32]) -> tensor[n, f32] = add(x, y)

chelis deep module.ch

(module {surf_path: "Hello.Basics.HelloTensor"}
  hello.basics.hellotensor
  (export {} add_vec)
  (defsig {span: "surf:49..133"}
    add_vec
    (n)
    (t-fn {}
      (t-ref {} (t-tensor {} (d-var {} n) (t-prim {} f32)))
      (t-ref {} (t-tensor {} (d-var {} n) (t-prim {} f32)))
      (t-tensor {} (d-var {} n) (t-prim {} f32))))
  (def {span: "surf:49..133"}
    add_vec
    (fn {}
      (params {} (x {type: (t-var {} _)}) (y {type: (t-var {} _)}))
      (app {span: "surf:124..133"}
        (var {span: "surf:124..127"} add)
        (var {span: "surf:128..129"} x)
        (var {span: "surf:131..132"} y)))))

Generate the Deep form yourself:

Terminal window
chelis deep module.ch

Read the generated form alongside the three source lines:

  • module groups the definition under Hello.Basics.HelloTensor.
  • export names the function that other modules can import.
  • defsig records add_vec's signature, including its dimension variable n.
  • t-ref represents &, the read-only borrow in each parameter type.
  • d-var represents the variable introduced by [n].
  • def contains the function body, where app applies add to x and y.

The braces after a tag hold metadata. A span records a source position so tools can relate a generated node to the original Surf file. You can ignore those positions while reading the function's structure.

This module defines and exports add_vec, but never calls it. Evaluating definitions alone does not calculate the sum of two vectors. The first lesson includes x, y, and answer bindings for that purpose.

The hello-chelis repository keeps its examples as modules under src/. The files under tests/ import those modules, call their functions, and assert results. Read a source file and its test together to see both the definition and its use.

Run chelis deep addition.ch on your file from the first lesson. Find the same signature and function body, then look for the top-level bindings that supply the inputs and call add_vec.

To render a saved Deep file back into Surf, use chelis surf file.dp. The compiler's formatting may differ from the source you wrote. The Surf reference explains the source constructs in more detail. The language reference links to the specification for Deep's node forms.