bjomepage/index.sz

82 lines
2.8 KiB
Text

(meta (title "Bjolang")
(listing? #f))
@div["logo"]{@image["/_resources/logo.svg" #:alt "Bjolang"]}
Bjolang is a Lisp for .NET. It has types that are inferred, unions that are
matched exhaustively, traits, hygienic macros, and bjoroutines, and it
compiles to C#. It is a small experiment in what I would like in a programming language, and in api design.
I built it with liberal use of ai, so beware.
@codeblock[#:lang "bjolang"]|{
(type (: Shape (Union (: Circle double)
(: Rect double double))))
(: area (-> Shape double))
(defun (area shape)
(match shape
((Circle r) (* 3.14159 (* r r)))
((Rect w h) (* w h))))
(defun (main args)
(loop (:for s [(Circle 1.0) (Rect 2.0 3.0)])
(:do (println #"area: ${(area s)}")))
0)
}|
@link["manual/"]{Read the manual}, or go straight to the
@link["manual/modules/"]{library reference}.
@section{more examples}
ConcurrentML brings the multithreading story for bjolang into the 1990s. The function within cannot be written in go, because select is a statement.
@codeblock[#:lang "bjolang"]{
(: within (-> int (Event %a) (Event (Option %a))))
(defun (within ms ev)
(choose (wrap ev #(Some &))
(wrap (timeout ms) (fun (u) None))))
(sync (within 20 (chan-recv kitchen))) ;; => None, and nothing is consumed
(sync (within 500 (chan-recv kitchen))) ;; => (Some "dinner")
(sync (within 20 (spawn-evt (count-to 1000)))) ;; works on fibers too
}
This sums every line and every char read from stdin. When the port is closed, the result is printed using the show function from (std fmt).
@codeblock[#:lang "bjolang"]{
(import (only (std ports) port->seq))
(import (std fmt))
(defun (main args)
(def line-seq (port->seq read-line (deref current-input-port)))
(loop (:for line line-seq)
(:acc lines (summing 1))
;; Any :for after a non-:for clause opens a new subloop
;; so this loops over ever char in the line.
(:for ch line)
(:acc chars (summing 1) :when (not (char-whitespace? ch)))
=> (show [(tabular [["Lines:" nl "Chars:" nl]
[lines nl chars nl]])]))
0)
}
Here is a small example showing off bjoroutine use together with process pipelines
@codeblock[#:lang "bjolang"]{
(import (std run))
;; this is an asynchronous filter that suspends if the read-char/opt or
;; write-char has to wait. A filter is a function type declared in (std run)
;; this particular filter upcases every letter.
(: shout Filter)
(defbjo (shout in out)
(loop (:for ch (in-port in read-char/opt))
(:do (write-char out (char-upcase ch)))))
;; the run/xyz functions uses type elaboration to allow for
;; simple DSLs using quoted lists. This runs cat (the linux binary)
;; pipes it's output to the shout method and pipes that to a grep after
;; the word BOMB.
(run/string '(pipe (cat "notes.txt") ,shout (grep "BOMB")))
}