The manual as a site: a landing page, the chapters, and a page per module

index.sz is a landing page pointing to the manual, now manual.sz, and to
modules/, where each library module has a page made by @generate-docs from
the docs it was compiled with. The chapters gain appendices, and part III
links each module to its page. glasnost's page cache is ignored.

🤖 Generated with [ECA](https://eca.dev) (anthropic/claude-opus-5-5)

Co-Authored-By: eca-agent <git@eca.dev>
This commit is contained in:
Linus Björnstam 2026-10-01 18:37:22 +02:00
parent e54bd31d69
commit 27c7d64641
24 changed files with 759 additions and 241 deletions

View file

@ -18,13 +18,13 @@ Bjolang compiles to c#. Many of the design decisions behind bjolang stems from t
This can then be run using @code{bjo run filename}, and it should print @code{Hello, User!}.
What you can see here is that defun is the form for defining a function. main is special, it needs no type declaration. print-hello is a regular unction, and thus has to declare it's type. Everything at toplevel needs to do that. The form is (: name type). A function type is declared as (-> ArgType ... Return-Type). print-hello takes a string argument and returns unit. unit is the name for nothing.
What you can see here is that defun is the form for defining a function. main is special, it needs no type declaration. print-hello is a regular function, and thus has to declare its type. Everything at toplevel needs to do that. The form is (: name type). A function type is declared as (-> ArgType ... Return-Type). print-hello takes a string argument and returns unit. unit is the name for nothing.
@subsection{Declaring types}
For most of your bjolang code, you will only declare types in the top level. Types within functions are inferred, so declaring types there is almost never necessary. A value type is declared just like a function, but without the function type declaration:
@codeblock[#:lang "bjolang"]{
(: usermap (Map Keyword String))
(: usermap (Map Keyword string))
(def usermap #map((:admin "Linus") (:moderator "Sunil") (:janitor "Björnstam")))
}
@ -32,8 +32,8 @@ You can also declare your own types. Either aliases of other types, records of y
@codeblock[#:lang "bjolang"]{
(type
(: Suit (Union Hearts Diamons Clubs Spades))
(: Card (Struct (: rank byte) (: suit Suit))
(: Suit (Union Hearts Diamonds Clubs Spades))
(: Card (Struct (: rank byte) (: suit Suit)))
(: User (Record (: name string)
(: age byte)
(: favourite-playing-card Card)))))
@ -59,11 +59,10 @@ This can then be destructed using pattern matching.
(_ (panic! "This should not happen."))))
}
@subsubsection{Editor support}
Bjolang was written in emacs, and emacs is currently the only editor with limited bjolang support through the file bjomode.el in the main github repository. It lacks any fancy thins, but handles a modicum of indentation and syntax highlighting.
Bjolang was written in emacs, and emacs is currently the only editor with limited bjolang support through the file bjomode.el in the main github repository. It lacks any fancy things, but handles a modicum of indentation and syntax highlighting.
@subsection{Values, types and signatures}
These are the bjolang literals:
@ -182,9 +181,29 @@ Generics can also be constrained to work on Traits. For example this signature,
(: (-> (Tuple %a %b) (Vec %a) bool) (where (Eq %a)))
}
@subsubsection{Local functions}
@subsubsection{Local functions and inline signatures}
A local function looks exactly like a regular functions, but does not need a type signature. In fact, it does not even support (: ...) signatures. When needed you can use inline signatures, which TODO: WRITE INLINE SIGNATURES EXPLANATION.
A local function defined inside another function looks like a top-level @code{defun}, but does not need a separate @code{(: ...)} type signature because local types are inferred automatically with Hindley-Milner type inference. In fact, local functions do not support separate @code{(: ...)} signatures at all.
When you want to document types explicitly or constrain inference, you can write the signature inline directly on the @code{defun} by annotating each parameter with @code{(: param Type)} and following the parameter list with @code{: ReturnType}:
@codeblock[#:lang "bjolang"]{
(defun (process-numbers ls)
(defun (clamp (: n int) (: max int)) : int
(if (> n max) max n))
(list-map #(clamp & 100) ls))
}
Parameters can use any type, including type variables for generic local functions:
@codeblock[#:lang "bjolang"]{
(defun (pair-up val ls)
(defun (wrap (: x %a)) : (Tuple %a %b)
(Tuple x val))
(list-map wrap ls))
}
Note that if you supply an inline signature, all parameters and the return type must be annotated together; partial inline annotations are not permitted. Trait constraints (@code{where} clauses) and keyword argument defaults cannot be written inline and require top-level signatures.
@subsection{Bindings and control flow}