github purescript/purescript v0.11.0

latest releases: v0.15.16-1, v0.15.16-0, v0.15.15...
7 years ago

This release includes several breaking changes, in preparation for the 1.0 release, as well as many enhancements and bug fixes.

Most users will probably want to wait until all aspects of the release have been finalized. Progress on libraries and tools is being tracked here.

Many thanks to the contributors who helped with this release!

Breaking Changes

(@garyb, @paf31)

=> now acts like a binary type operator

It was previously possible to specify many constraints in the same context by
separating them with commas inside parentheses on the left of the =>:

runFreeT ::  m f. (Functor f, Monad m) => ...

This is no longer allowed. Instead, => now acts like a binary operator, with a
constraint on the left and a type on the right. Multiple constraints must be
introduced using currying, as with regular function arguments:

runFreeT ::  m f. Functor f => Monad m => ...

This is in preparation for adding constraint kinds, at which point => will become
an actual binary type operator, defined in Prim.

* and ! kinds have been removed

The kind symbols * (for the kind of types) and ! (for the kind of effects) have been
removed from the parser. Instead of *, use Type, which is defined in Prim.
Instead of !, use Effect, which can now be imported from Control.Monad.Eff.

The # symbol, which is used to construct a row kind, is still supported. We cannot move this kind into Prim (because it is polykinded, and we do not support kind polymorphism).

One single consolidated executable

The various psc-* executables have been replaced with a single executable called purs.
The various subcommands are documented on the --help page:

bundle     Bundle compiled PureScript modules for the browser
compile    Compile PureScript source files
docs       Generate Markdown documentation from PureScript source files
hierarchy  Generate a GraphViz directed graph of PureScript type classes
ide        Start or query an IDE server process
publish    Generates documentation packages for upload to Pursuit
repl       Enter the interactive mode (PSCi)

Wrapper scripts will be provided in the binary distribution.

psc-package was removed

psc-package has been removed from the main compiler distribution. It will still
be maintained along with the package sets repo, but will not be bundled with the compiler.

A binary distribution which is compatible with this release is available.

Implicitly discarded values in do blocks now raise errors

Code which discards the result of a computation in a do block:

duplicate :: Array a -> Array a
duplicate xs = do
  x <- xs
  [true, false] -- the result here is discarded
  pure x

will now raise an error. The compiler allows values of certain types to be discarded,
based on the Discard class in Control.Bind. The only type which can be discarded is
Unit, but the feature was implemented using a type class to enable support for
alternative preludes.

No more dependency on the Bower executable

In addition to removing psc-package from the compiler distribution, we have also
removed any explicit dependency on the Bower executable. The compiler will not assume
use of any particular package manager, but will aim to provide generic support for
package managers generally, via command line options and hooks.

purs publish will continue to use the Bower JSON formats. The bower.json format
is now referred to as the "manifest file", while the output of bower list --json,
which is used by purs publish internally, is referred to as the "resolutions file".

Enhancements

Pattern Guards

(@alexbiehl)

In addition to regular guards:

foo x | condition x = ...

the compiler now supports pattern guards, which let the user simultaneously
test a value against a pattern, and bind names to values.

For example, we can apply a function fn to an argument x, succeeding only if
fn returns Just y for some y, binding y at the same time:

bar x | Just y <- fn x = ... -- x and y are both in scope here

Pattern guards can be very useful for expressing certain types of control flow when
using algebraic data types.

HTML Documentation

(@hdgarrood)

The --format html option has been added to purs docs. The HTML format uses
the Pursuit template, and is very useful for rendering documentation for offline
use.

Here is an example of the generated HTML.

Duplicate Labels

(@paf31)

Row types now support duplicate labels, which can be useful when using the Eff
monad. For example, we could not previously use the catchException function if
the resulting action also required the EXCEPTION effect, since otherwise the
type of the inner action would contain a duplicate label.

Rows are now unordered collections (of labels and types) with duplicates. However,
the collection of types for a specific label within a row is ordered.
Conceptually, a row can be thought of as a type-level Map Label (NonEmptyList Type).

A type constructor (such as Record) which takes a row of types as an argument should
define what its meaning is on each row. The meaning of a value of type Record r
is a JavaScript object where the type of the value associated with each label is given
by the head element of the non-empty list of types for that label.

Row Constraints

(@doolse, @paf31)

A new constraint called Union has been added to Prim. Union is a three-way relation between
rows of types, and the compiler will solve it automatically when it is possible to do so.

Union is a left-biased union of rows which takes into account duplicate labels. If the same label appears in rows l and r, and Union l r u holds, then the label will appear twice in u.

Union makes it possible to give a type to the function which merges two records:

merge :: forall r1 r2 r3. Union r1 r2 r3 => Record r1 -> Record r2 -> Record r3

Note that this is a left-biased merge - if the two input record contain a common label, the type of the
label in the result will be taken from the left input.

Patterns in let expressions

(@noraesae)

Let expressions and where clauses can now use binders on the left hand side of
a declaration:

map f xs = 
  let { head, tail } = uncons xs
  in [f head] <> map f tail

Unlike in Haskell, declarations with these patterns cannot appear in dependency cycles, and bound names can only be used in declarations after the one in which they are brought into scope.

Find record accessors in Type Directed Search

(@kritzcreek)

Type-directed search will now include results for record accessors. This can
be very useful when working with extensible records with a type-driven programming
workflow.

Other Enhancements

  • Add basic usability check and error for ambiguously-typed type class members (@LiamGoodacre)
  • Improved skolem escape check (@paf31)
  • Fix links to declarations in Prim (@hdgarrood)
  • Emit _ instead of false case for if then else to improve optimizations (@rightfold)
  • Add InvalidDerivedInstance error to improve errors for derived instances (@paf31)
  • Make generated code for superclass instances less ugly (@paf31)
  • Support polymorphic types in typed binders (@paf31)
  • Make file paths relative in error messages (@paf31)
  • Improve errors from module sorter (@paf31)
  • Improve error for unused type variables (@paf31)
  • Include source span in externs file for error reporting purposes (@paf31)
  • Improve instance arity errors (@mrkgnao)

purs ide

Features

Improve import parsing

  • purs ide now uses a new import parser, which allows purs ide to handle any
    import section that the compiler would accept correctly. (@kritzcreek)
  • Parse imports with hanging right paren (@matthewleon)
  • Reuses lenient import parsing for the list import command (@kritzcreek)

Don't create the output/ directory if it can't be found

(@kritzcreek)

purs ide will now no longer leave empty output/ directories behind when it is
started in a directory that is not a PureScript project.

Collect type class instances

(@kritzcreek)

purs ide collects instances and stores them with their respective type class.
There's no way to retrieve these yet, but we will extend the protocol soon.

Bug Fixes

  • No longer strip trailing dots for Pursuit queries (@kritzcreek)
  • Fix #2537 (psc-ide shouldn't crash when building a non-existent file) (@kritzcreek)
  • Fix #2504 (fix a crash related to prematurely closed handles) (@kritzcreek)
  • Speed up rebuilding by x2, by rebuilding with open exports asynchronously (@kritzcreek)
  • Return operators in purs ide imports list (@nwolverson)
  • Also detect location information for operators (@kritzcreek)

Cleanup

  • Removes unnecessary clause in import pretty printing (@kritzcreek)
  • Removes the deprecated --debug option (@kritzcreek)
  • Restructure testing to avoid running the server (@kritzcreek)

purs repl

  • Add back .purs-repl file support (@paf31)
  • PSCi command changes, add :clear (@noraesae)
  • Declarations no longer require let (@noraesae)
  • Improve CLI error and startup messages (@noraesae)

Bug Fixes

  • Changes to help the tail call optimization fire more consistently (@paf31)
  • Fix everythingWithScope traversal bug #2718 (@paf31)
  • Errors for open rows in derived instances (@paf31)
  • Instantiate types in record literals as necessary (@paf31)
  • Fix Generic deriving with synonyms (@paf31)
  • Rebuild modules if necessary when using --dump-corefn (@paf31)
  • Ensure solved type classes are imported (@LiamGoodacre)
  • Allow for older Git versions in purs publish (@mcoffin)
  • Fix purs publish --dry-run (@hdgarrood)
  • Exported data constructors can now contain quotes (@LiamGoodacre)

Documentation

  • Capitalise *script into *Script (@noraesae)

Performance

  • Optimize keepImp (@paf31)
  • Replace nub with ordNub (@matthewleon)
  • Combine inlining optimizations into a single pass (@paf31)

Other

Don't miss a new purescript release

NewReleases is sending notifications on new releases.