Amuletml Amulet Versions Save

An ML-like functional programming language

1.0.0.0

4 years ago

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 and ord 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.

0.7.0.0

4 years ago

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 required 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

0.6.0.0

4 years ago

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

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_reps, 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.

0.5.0.0

4 years ago

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 allowed unsafe_coerce to be written. (45c6e4b0fee9df3069924b036bb04ca77d5e9bcc)
  • 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 (d6f68d809281205a3985fbde7942f3c75694b09)
  • 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 (80461c9d87af1bf8a7101aa4647ec74b7294e8e8)
  • Built-in variables with quantified type variables now have their foralls marked Spec, so they can be visibly applied to type arguments. (f23910d0e0e8b74da6f403d7b0fc77ca3e412bb2)

You can get this release here or through the usual means.

04.2.0

4 years ago

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.

0.4.1.0

4 years ago

This is a small bug fix release, to resolve several latent issues in the compiler.

Changes in this release:

  • Add negate and negatef 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.

0.4.0.0

4 years ago

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)

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 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.

0.3.0.0

4 years ago

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

0.2.0.0

4 years ago

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

0.1.0.0

4 years ago

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.