Name is TBD; Joss for now.


Codebase Management

Forget about files, modules, all of that garbage. A Joss system is a bag of functions. The end user pulls types and tools out of that bag to use in their programs. The system should recommend these tools to the end user as frequently as possible.

Program Exportation

To export a program from Joss is to provide a single Joss function to export. This creates a program tree and exports a database that contains everything in the program tree. Any functions that aren't used just don't show up in the tree, so there is no notion of codebase bloat.

TODO Version Control

This is a big problem


Projections are mappings from the Joss AST to concrete syntax. A default s-expression based projection is provided. Another name could be `syntax`, but `projection` sounds much cooler.

Once a projection is defined, error messages should print with respect to that projection as well.

TODO Exceptions


Statically typed; makes heavy use of row polymorphism. Supports type inference of course. Users should not have to write types for most things. This gives programmers incredible flexibility while preserving a strong type system.



Support arbitrary precision arithmetic. End-user programmers should not have to worry about numbers at all. Make the number type as flexible as possible.

TODO Strings

I would like to discourage language users from using strings whenever possible; how can this be done while still retaining practicality? Maybe abstracting this idea of custom deserializers to make types look nice can also be leveraged in this way? Or guaranteeing that strings can not be used inline?

TODO Enumerations



Function Types

Syntax is inspired by Racket's contract system

(-> number bool)
(-> (mapping number string) number)

;; named function
(function add-nums (a1     a2) ;; name, arg1, arg2
          (->      number  number number) ;; optional contract
          "Add two numbers together." ;; optional docstring
          (+ a1 a2)) ;; function body

;; having the docstring in the function body gives us lots of information:
;; - we're guaranteed that it's affiliated with the function
;; - can compute edit distance from other purpose statements to identify similar functions

;; alternative for signature
(function ([a1 string] [a2 number])

;; anonymous function
(function (a1 a2)
          (+ a1 a2))

(function get-keys (mp)
          (->      )

;; can add types to functions after the fact in different contexts to 'concretize' them
(: add-nums (-> number number number))

Expressiveness Requirements

Algebraic Data Types

This is syntactic sugar for adding a tag to a union type!

(type Name (name 'a 'b 'c 'd)
  (map 'a 'b
       'c 'd))

Desugared, this looks like

(type (name 'a 'b 'c 'd)
  (map 'a 'b
       'c 'd
       "__type": "Name"))

TODO Flexible Map

(type (map 'a 'b 'c 'd ..)
   (pair 'a 'b)
   (pair 'c 'd)))

TODO Mapping

All keys are of the same type; so are all values.

(type (mapping 'a 'b)


(type (list 'a)
   (OR (pair 'a (list 'a))


(type (array 'a)
  (mapping 'number 'a))


(type bool
  (or #true #false))

TODO Tuple

(type (tuple 'a 'b  'c ...)
  (pair 'a (pair 'b) ...)