An ML-like functional programming language
:h[elp]
command (@CrazedProgrammer)either
type (@davidgarland).eq
and ord
instances for ( * )
.Amulet now comes with an LSP server. This allows us to display diagnoastics and fixes in any editor supporting the protocol, rather than having editor-specific integration!
The editor integration is still relatively simple, missing many key features like auto-complete or go-to-definition, but we hope to expand it in the future.
You can get this release here or through the usual means
Changes since last release:
The Amulet exception library is now less brittle when the stack is unwound because of a Lua error. (2a22dd4c5988e943fc590a04626567f50a315ed6)
Associated type definitions in a class body can now refer to associated types defined previously in the same class. This also goes for type instances. (9fa3f20ab3555ebd3d6ef0de30da8a284683fdde)
Amulet supports proper dependent kinds and dependent pattern matching in type functions (52bceeb5f684c197670fc2627d84f1ef4c03dfaa, c7088e9cb36f3951817cc80a2ad5b4486920e196)
Recursive let
definitions require a rec
keyword.
(3b365b278dc29dc6aaa01cda47825335f5702be6)
The REPL knows how to autocomplete names from scope when using the
TAB key. Additionally, the vim integration sets omnifunc
to
use Amulet autocompletion.
(2cce4a03ea3810c78ab302d8cc7ad24086d64d69,
0e29d80070379f00c63a91f8482fc3ea8239dafe)
It is now possible to generate Lua modules to be require
d from other
programs. (9e9ed889592a62c9efc5fd9f55678831733b88d0)
( && )
and ( || )
are lazy on their right-hand sides
(bdf0045516e71c293b5b5ba5156ea7fec2a84045)
Type errors will mention when type families/functions not being injective might be the cause of the error (70f18c14e350133ff9f5ecf97b14c99bd13e076e)
The Amulet compiler can explain print long-form explanations of some error messages. Furthermore, it'll mention when these explanations are available. (a948da883d5a6ca494718623762bd7cf7d995ae5, 2e3269c8d7a8e49a65cb43991936459bf5a4f1fa, d37c8b991dffabdb209ce2c2fc89a59253020652)
Several bug fixes to the type checker. (#217, #218, a partial fix to #219, d4d7fa7ede85c0c25687fc01ad96f074485acd3a)
Added more bugs
You can get this release here or through the usual means.
Changes since last release:
The REPL will only reload changed files (#211)
--test-tc
dumps the Typed AST and stops before lowering (e87e40af827c76eb0456d4a7264a3ec3f83e7c9d)
The type checker supports lifted booleans, tuples and lists (shorthand for a series of Nil
/Cons
applications) (5363e95d7f8d9320d34a4fba93fa68b58adbb2a0)
Type error messages involving type functions will print the reduced type along with the application (6aa99ff3b7c4c3c1a336f0e67f90a54bb362d923)
The standard library has list manipulation functions (amulet/list.ml
), support for enumerations and ranges (data/enumeration.ml
), the foldable
and traversable
type classes (data/foldable.ml
/data/traversable.ml
resp.), typeable
support functions (data/typeable.ml
), bindings to the Lua I/O facilities (lua/io.ml
), and exception support (amulet/exception.ml
).
The type checker knows of the typeable
class for exposing type information at run-time. This is opt-in: The programmer can ask for their types to be typeable
with a deriving instance typeable T
declaration. (8d5826ff695bcbda6e51bd691e72b14620be8f7b)
Idiom bracket handling was moved to the type checker, which means (| x + y |)
is now handled correctly (and (| x |)
became a shorthand for pure x
). (0bba8c32a3ab4380a0306c27ba13944a1bed2d10)
The compiler understands include
statements as a way to open
a module while also exposing the contents of the module. (424b24a200a658673ab4387965a7fd9670a7ecfa, #207)
Several correctness fixes (#210, 553c36885d39da7882fcf9898e349f9832508927, c72f1515d0ffbe28509ac04ac38cc8e70f3c3930, 27f8bad789f17c794d4b47c3ab050bdcf1a0688d)
Added more bugs
typeable
classThe typeable class is wired-in, and deeply magical. Users are not allowed to define instances of typeable
since that would compromise type safety. It doesn't even get an Amulet definition, but it would be something like this:
(* A representation of 'x *)
type type_rep 'x
class typeable 'x begin
val type_of : 'proxy 'x -> type_rep 'x
end
The compiler also has a wired-in definition for comparing type_rep
s, but using the standard library module amulet/typeable.ml
is recommended:
val is_same_type :
forall 'a 'b.
typeable 'a * typeable 'b =>
proxy 'a -> proxy 'b -> option ('a :~: 'b)
val cast :
forall 'a 'b.
typeable 'a * typeable 'b =>
'a -> option 'b
The amulet/typeable.ml
support module also defines a dynamic
type, for boxing a value along with a type representation for the value.
The typeable support module is exported from the prelude as module Typeable
.
This boring release is just a bug hunt, actually.
Changes since last release:
unsafe_coerce
to be
written. (45c6e4b0fee9df3069924b036bb04ca77d5e9bcc)(fun x -> x) :: (fun x -> x) :: Nil
(80461c9d87af1bf8a7101aa4647ec74b7294e8e8)forall
s
marked Spec, so they can be visibly applied to type arguments.
(f23910d0e0e8b74da6f403d7b0fc77ca3e412bb2)You can get this release here or through the usual means.
Changes since last release:
"Quick Look" impredicativity extends Amulet's support for first-class polymorphism. Like any implementation of this, it's dubiously useful, but does still allow writing some pretty neat snippets, such as constructing a list of identity functions:
let ids : list (forall 'a. 'a -> 'a) =
let empty : list (forall 'a. 'a -> 'a) = []
(fun x -> x) :: empty
You can get this release here or through the usual means.
This is a small bug fix release, to resolve several latent issues in the compiler.
Changes in this release:
negate
and negatef
to the prelude.Releases are now signed with GPG (key 0E843EFDBA828772). This can also be found on @zardyh's personal and ahti.space websites.
Note: Amulet now needs multiple files to work correctly. Please refer to the installation instructions for information on how to set it up.
Changes since the last release:
The note informing the programmer when a match
can be safely converted into a let
(similarly for function
/fun
) is now properly generated.
Breaking: Applications of type functions and polymorphic types are disallowed in instance heads.
There is now built-in syntax for using Applicative functors. The syntax (| f x y z |)
(called an idiom bracket) desugars to pure f <*> x <*> y <*> z
, using whatever pure
and (<*>)
are in scope. See the paper that introduced Applicative for more details.
Amulet has a new module system: see below.
The compiler driver was changed to use sub-commands instead of the mess of flags we had before. See amc --help
for more details.
The compiler driver and the REPL can print their version, including which commit the release was generated from.
Minor changes to the constraint solver should help with type function behaviour in instance definitions.
Some operator precedence issues were fixed in the Lua parser. Moreover, the backend will print if
statements in a single line when possible.
An issue relating to sharing clauses in pattern lowering was fixed, thus generating faster code (at the expense of uglier-looking Lua)
The old module system (which treated modules as extensible namespaces) was completely replaced by a proper, saner module system:
Modules can no longer be extended—redefining a module will shadow it, as with any other definition. As a result, declaring a nested module (i.e. module X.Y = begin .. end
) is no longer valid.
External files can be imported, and treated as another module using the import
construct. This supports both resolution according to a library path (import "my_lib.ml"
), or relative to the current file (import "./my_lib.ml"
).
As the module language is now more unified, import
module terms can also be used within let open
expressions.
Most of the built-ins were axed from the compiler and moved to a ML file, except for those that need special type checker syntax. The prelude
is loaded automatically in the REPL, but needs to be imported explicitly in compiled code: open import "prelude.ml"
results in the old compiler behaviour w.r.t. builtin names.
There are bindings to some Lua libraries under the lua/
directory of the standard library.
The REPL now has a :compile
command for writing the currently-loaded code to a file.
An introductory tutorial to the Amulet programming language is available here.
Changes since the last release:
ref _
is bound at top-level, a warning is
emitted.Note on constrained type families:
The program below is illegal, since there's no assumption of foo 'a
in
the type for MkBox
.
class foo 'a begin
type bar
end
type bar_box 'a =
| MkBox : bar 'a -> bar_box 'a
This, however, fixes it:
- | MkBox : bar 'a -> bar_box 'a
+ | MkBox : foo 'a => bar 'a -> bar_box 'a
Changelog since last version:
The files amc.linked
and amc-prove.linked
are statically-linked executables for x86_64 Linux. Blame GitHub for the dumb file extension, though, not me.