Releases: amuletml/amulet
Amulet 1.0.0.0
Improvements
Compiler
- Improve type class ambiguity check.
- amc now exits with a "1" when compilation fails.
- amc supports allows turning warnings into errors using -Werror (fail on all errors) and -Werror=123 (fail on a specific error code).
- Lex negative numbers.
- When run with --time, amc will produce a timing report detailing how long each stage took.
- Add a "Lua static" backend, which embeds a Lua interpreter in an executable.
- Improve the REPL, adding a
:h[elp]
command (@CrazedProgrammer) - Implement the "static argument transform", lifting functions with constant arguments out.
- Relax the value restriction for constrained values.
Standard library
- Add an
either
type (@davidgarland). - Add
eq
andord
instances for( * )
. - Add library for modifying mutable arrays
Bug fixes
- Fix name resolution issues with neted modules.
- Correctly handle transitive dependencies when loading files in the REPL.
- Fix parsing of aligned prefix operators.
- Fix several lowering issues with patterns.
- Escape Lua variables which could potentially clash with Lua builtins.
- Fix several pattern-matching checker issues.
Language Server Support
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!
- If you're using Emacs, amulet-mode integrates with the fantastic lsp-mode automatically.
- We have a VS Code extension, though this is not currently on the marketplace, so I'm afraid you'll have to build and install it manually.
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.
Amulet 0.7.0.0 "Who's That Pokémon?"
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.
(2a22dd4) -
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.
(9fa3f20) -
Amulet supports proper dependent kinds and dependent pattern matching in type
functions
(52bceeb,
c7088e9) -
Recursive
let
definitions require arec
keyword.
(3b365b2) -
The REPL knows how to autocomplete names from scope when using the
TAB key. Additionally, the vim integration setsomnifunc
to
use Amulet autocompletion.
(2cce4a0,
0e29d80) -
It is now possible to generate Lua modules to be
require
d from other
programs. (9e9ed88) -
( && )
and( || )
are lazy on their right-hand sides
(bdf0045) -
Type errors will mention when type families/functions not being
injective might be the cause of the error
(70f18c1) -
The Amulet compiler can explain print long-form explanations of some
error messages. Furthermore, it'll mention when these explanations are
available.
(a948da8,
2e3269c,
d37c8b9) -
Several bug fixes to the type checker.
(#217, #218, a partial fix to #219, d4d7fa7) -
Added more bugs
Amulet 0.6.0.0 "None : option release_joke"
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 (e87e40a) -
The type checker supports lifted booleans, tuples and lists (shorthand for a series of
Nil
/Cons
applications) (5363e95) -
Type error messages involving type functions will print the reduced type along with the application (6aa99ff)
-
The standard library has list manipulation functions (
amulet/list.ml
), support for enumerations and ranges (data/enumeration.ml
), thefoldable
andtraversable
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 betypeable
with aderiving instance typeable T
declaration. (8d5826f) -
Idiom bracket handling was moved to the type checker, which means
(| x + y |)
is now handled correctly (and(| x |)
became a shorthand forpure x
). (0bba8c3) -
The compiler understands
include
statements as a way toopen
a module while also exposing the contents of the module. (424b24a, #207) -
Added more bugs
The typeable
class
The 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
.
Amulet 0.5.0.0 "Death By A Thousand Lint Errors"
This boring release is just a bug hunt, actually.
Changes since last release:
- Fixed a bug where equality evidence with superclasses was being used without
consideration for the superclasses; This allowedunsafe_coerce
to be
written. (45c6e4b) - Fixed a solver bug where the type of the selected instance head was not being
unified with the actual wanted constraint, leading to well-typed programs
rejected by Core Lint (d6f68d8) - The Quick Look algorithm considers applications to be simple terms, which
leads to improved type inference in cases like
(fun x -> x) :: (fun x -> x) :: Nil
(80461c9) - Built-in variables with quantified type variables now have their
forall
s
marked Spec, so they can be visibly applied to type arguments.
(f23910d)
You can get this release here or through the usual means.
Amulet 0.4.2.0 "<!-- Squid: fill in this joke -->"
Changes since last release:
- Check for orphan instances, closing a soundness hole #191
- “Quick Look” impredicative polymorphism, #203
The new thing: QL Impredicativity
"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.
Amulet 0.4.1.0 "FIXME Please"
This is a small bug fix release, to resolve several latent issues in the compiler.
Changes in this release:
- Add
negate
andnegatef
to the prelude. - Check arity of arguments when using associated type families.
- Numerous bug fixes with lowering to Core.
Releases are now signed with GPG (key 0E843EFDBA828772). This can also be found on @zardyh's personal and ahti.space websites.
Amulet 0.4.0.0 "Open Import Tariffs.ml"
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 alet
(similarly forfunction
/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 topure f <*> x <*> y <*> z
, using whateverpure
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)
Amulet's New Module System
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 withinlet 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.
Amulet 0.3.0.0 "Feeds a Type Family of 10"
An introductory tutorial to the Amulet programming language is available
here.
Changes since the last release:
- Possible non-termination in associated type instances is an error, not
a warning - Associated type families are only legal when there's an instance for
the type class they're associated with in scope. See the note at the
end of the changelog for details. - An upper bound on solving runtime was established by adding a limit of
20 reductions to type functions. (Yell if this breaks anything) - When a variable with type
ref _
is bound at top-level, a warning is
emitted. - Conversion functions were added between integers and floating-point
numbers (#179)
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
Amulet 0.2.0.0 "Sorry for the Ping"
Changelog since last version:
- Better support for associated type functions
- Unification isn't hopelessly broken when types are applied to ≥3
arguments on the lhs of a unification problem
Amulet 0.1.0.0 "Probably Unsound"
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.