Repository navigation
Myron grows a macro system, modules, records and error handling, and the executable becomes a script runner as well as a REPL.
Some of the public Swift interface has changed, so a host written against 0.2.0 may need a few updates. See For Swift hosts below.
The language
Macros and templates. defmacro defines a macro, which receives its arguments as code and gives back new code to evaluate in their place. Templates, written with a backtick, build that code: ,x puts a value in and ,@xs splices a list in.
(defmacro (unless test then else) `(if ,test ,else ,then))
(unless false "yes" "no") ; "yes"make-symbol and symbol? let a macro build the names it defines. Macros are not hygienic yet.
Modules. module gathers definitions behind a list of exports. import brings the exports into scope, and a qualified name reaches one without importing anything.
(module geo (area)
(define (area w h) (* w h)))
(geo.area 3 4) ; 12Records. make-record-type and make-record give named, fixed-shape values. get and put work on them as they do on hashmaps. A record type is identified by its name and fields, so two sessions that define point the same way agree on it.
(define point (make-record-type 'point '(x y)))
(get 'x (make-record point 1 2)) ; 1Errors. raise signals an error of your own, and try catches it and hands the message to a handler.
(try (lambda (message) ($ "caught: " message))
((raise "boom"))) ; "caught: boom"Error messages can now end with hints, such as which conversion would let two numbers be compared.
Variadic parameters. A parameter written xs... collects the arguments the others leave over into a list.
(define (sum xs...) (reduce + 0 xs))
(sum 1 2 3) ; 6Strings. string now joins any number of values, and $ is a shorter name for it: ($ "x = " 42) is "x = 42". The release also adds split-all, split-once and find-first.
More of the standard library:
sortandsort-descendingapplyandfoldrzipandzip-allflattenrangeandrange-lentake-lastanddrop-lastintegersandintegers-betweenkind,something?,sortable?andcomparable?- the constants
nanandinfinity
The myron executable
myron-repl is now myron, and it runs programs as well as the REPL:
myron --replstarts the REPL.myron --load one.my --load two.myevaluates files in one environment. A#!/usr/bin/env -S myron --loadline makes a script executable.- A
.mdfile is literate Myron: its fencedlispandmyronblocks are the program. myron --show fileevaluates a file a form at a time and prints each result.- Programs get
print,write,read-line,read-character,read-all,exit,loadandarguments.
For Swift hosts
These changes may need a host written against 0.2.0 to be updated:
MyronSession.set(_:to:)now throws. It rejects a name that Myron source couldn't bind, such as"if","nothing"or"two words", withinvalidName, asdefinealready did. Calls needtry.- New enum cases.
MyronValueandMyronValue.Kindgainrecord,recordType,moduleandmacro.MyronError.Reasongains twelve cases, andMyronHigherOrdergainsfoldrandapply. Aswitchthat covers every case will need the new ones. - Name rules. A special form's name, such as
if, can no longer be bound, and nor cannothing, which is now a literal. A bound name can't end in a dot or contain a". - Error messages.
unexpectedTypemessages now quote the kinds they name. A host that matches on message text will need updating. nanordering.nannow sorts after every other double, so comparisons,sort,minandmaxtreat it consistently.
New in the Swift interface:
MyronRecord,MyronRecordType,MyronModule,MyronMacroandMyronSignaturedefine(_:arity:body:), for primitives that take their arguments as an array- optional signatures on every
define, such as"({integer} {string}[...])" evalEach, which evaluates the top-level forms one at a time
A host primitive can now call eval on its own session. How deeply those calls can nest is bounded by the new maximumEvalDepth.
Fixes
- A host primitive that called
evalused to end the outer program early with the inner result. It now carries on where it left off. - The executable builds for Wasm again. The REPL banner had asked the terminal for its width in a way WASI doesn't support.
Full details are in the CHANGELOG, and every change is in the comparison with 0.2.0.
A few notes:
It’s a summary. The “For Swift hosts” section covers every breaking change the CHANGELOG records, and the CHANGELOG link at the bottom has the full detail.
The two links at the bottom will 404 until the tag exists. They point at the 0.3.0 tag, so push the tag before you publish the release.
No title is included. Put the tag name, 0.3.0, in GitHub’s release title field.