Releases: purescript/purescript
v0.13.8
Bug Fixes
-
Update incremental build cache information properly on IDE rebuilds (#3789, @kritzcreek)
Fixes a bug where triggering a rebuild via the IDE would not update the
output/cache-db.json
file, which in certain situations could lead to
unnecessary rebuilds, as well as modules not being rebuilt when they should
have been. -
Don't include compiler-internal declarations in IDE completions (#3850, @kritzcreek)
IDE completions would previously include pseudo-declarations such as
RowToList$Dict
which only exist internally, due to how type class
desugaring inside the compiler works. These declarations are now suppressed. -
Fix corefn JSON version parsing (#3877, @paulyoung)
Fixes a bug where the parser for the functional core (or "corefn") JSON
format would ignore all but the first component of the compiler version
stored in the JSON. This does not affect the compiler directly, but will be
useful for other tooling which depends on the corefn JSON parser provided by
the compiler library.
Improvements
-
Add
purs graph
subcommand for graphing module dependencies (#3781, @jmackie, @f-f)This adds a new
graph
subcommand which allows tools to consume information
about which modules depend on which other modules. The format is as follows:{ "Prelude": { "path": "src/Prelude.purs" , "depends": ["Data.Semiring", "Data.Ring", ...] }, "Data.Ring": { "path": "src/Data/Ring.purs" , "depends": [] }, ... }
Each property in the returned object has exactly two properties;
path
,
which is a string containing the file path relative to the directory where
the command was run, anddepends
, which is an array of the names of all
directly imported modules. -
purs ide is better at reloading changes (#3799, @kritzcreek)
The IDE would previously sometimes miss changes that were made outside of the
editor, like building with new dependencies or recompiling larger parts of
the project on the console.The IDE will now notice when this happened on the next command issued to it
and refresh its state before processing that command. This might cause the
first command after an external change to take a long time to execute, but
should increase reliability in general. -
Switch to a binary encoding for externs files (#3841, @kritzcreek)
This change should result in significant performance improvements in both IDE
load times and incremental builds where lots of modules are already built. -
Represent module names as a single Text value internally (#3843, @kritzcreek)
Boosts compiler performance by representing module names as a single Text
value, rather than a list of Text values as it was previously. -
Extract documentation for type classes in purs ide (#3856, @kritzcreek)
This changes makes documentation comments on type classes visible to the IDE.
Other
v0.13.7
v0.13.6
Bug Fixes
-
Reset IDE state before performing a full reload. (#3766, @kritzcreek)
This prevents a space leak in the IDE.
-
Added source spans to ado desugaring. (#3758, @dariooddenino)
Previously errors in ado desugaring might have had no line information.
-
Generate correct arity failure case for some guarded matches. (#3763, @nwolverson)
Specifically when a multi-way case contains a pattern guard or multiple
guard expressions, the desugared case expression could contain a guard with
a different arity to the matched expressions, resulting in an error.
Improvements
-
Improved ambiguous variable check for functional dependencies. (#3721, @MonoidMusician)
Previously the compiler might warn about ambiguous variables that aren't actually ambiguous
due to functional dependencies. This check now fully takes functional dependencies into
consideration. -
Optimize import desugaring for full builds (#3768, @colinwahl)
The compiler was performing redundant work when resolving dependencies for modules resulting
in poor asymptotics. This work is now shared across modules yielding a 30-40% improvement in
build times for full builds. -
Use PureScript escapes in string pretty-printing (#3751, @hdgarrood)
Previously the compiler might print invalid escape sequences when pretty-printing code for
error messages. It now prints correctly escaped code based on PureScript's lexical grammar. -
Optimize away binds to wildcards in do-notation (#3220, @matthewleon, @hdgarrood)
This avoids generating variable assignments if no variables are actually bound in do-notation.
Previously the compiler would emit a unique variable name that went unused. -
Output docs.json files for Prim modules (#3769, @f-f)
This change allows downstream tools such as spago to obtain documentation data for Prim modules.
Please note, however, that the API for the docs.json files is unstable and may change without warning.
Other
v0.13.5
This is a small bugfix release to address some issues which were introduced in 0.13.4.
Bug fixes
-
Fix "too many open files" during compiling (#3743, @hdgarrood)
The compiler would not promptly close files after opening them, which could easily lead to reaching the open file limit, causing the compiler to crash.
-
Fix incorrect unused import warnings when kinds are re-exported (#3744, @hdgarrood)
Fixes a bug in which unused import warnings were generated for kinds which were re-exported (and therefore should have been considered "used").
Other
- Fix Haddock markup error preventing Haddock docs being generated (#3745, @cdepillabout)
- Add upper bound on Protolude to prevent 0.2.4 from being selected (#3752, @hdgarrood)
v0.13.4
Enhancements
-
Use content hashes when determining whether a file needs rebuilding (#3708, @hdgarrood)
We now calculate and store content hashes of input files during compilation. If a file's modification time has changed since the last compile, we compare the hash to the previous hash; if the hash is unchanged, this allows us to skip rebuilding this file, speeding up the build.
-
Include import declaration qualifiers in unused import warnings (#3685, @matthew-hilty)
Previously, warnings didn't distinguish between import declarations from the same module. Code like the following
import A.B (x) -- `x` is used. import A.B (y) as C -- `y` is not used.
would induce a warning like
The import of module A.B is redundant
even though only the qualified import declarationC
is actually redundant. The warning now would beThe import of module A.B (qualified as C) is redundant
. -
Include kind imports when determining unused import warnings (#3685, @matthew-hilty)
Previously, kind imports were ignored. The linter wouldn't emit any warnings for code like the following.
import A.B (kind K) -- `kind K` is not used.
And the linter, disregarding
kind K
, would emit anUnusedImport
instead of anUnusedExplicitImport
for code like the following.import A.B (x, kind K) -- `x` is not used, but `kind K` is.
-
Better reporting of I/O errors (#3730, @hdgarrood)
If an unexpected I/O error occurs during compiling, we now include details in the error message. For example, when trying to write compilation results onto a device which has run out of space, we previously would have received a "CannotWriteFile" error with no further information. Now, we receive the underlying error message too:
I/O error while trying to write JSON file: ./output/cache-db.json ./output/cache-db.json: hClose: resource exhausted (No space left on device)
Bug fixes
-
Improve type class resolution in the presence of constrained higher-order functions (#3558, @matthew-hilty)
This is perhaps best illustrated with an example.
newtype LBox row a = LBox (∀ r. (∀ lbl _1. Row.Cons lbl a _1 row ⇒ IsSymbol lbl ⇒ SProxy lbl → r) → r) unLBox ∷ ∀ row a r. (∀ lbl _1. Row.Cons lbl a _1 row ⇒ IsSymbol lbl ⇒ SProxy lbl → r) → LBox row a → r unLBox g (LBox f) = f g read ∷ ∀ row a. Record row → LBox row a → a read rec = unLBox \lbl → Record.get lbl rec
The
read
function would previously fail with the errorNo type class instance was found for Prim.Row.Cons lbl4 a5 t2 row6
although that dictionary should have been available in the function passed to
unLBox
. Now, it type checks successfully. -
Fix cache invalidation false negatives by storing timestamps (#3705, @hdgarrood)
Previously, an input file would be considered 'modified', and thus requiring rebuilding on a subsequent compile, if its modification time specifies a point in time after any of the modification times of the corresponding output files. This has turned out to be insufficient; files can often change in a way that this algorithm misses, because the input file might still have a timestamp older than the output files. Often this can happen by switching between
git
branches or by updating a dependency.This problem can manifest as compiler errors which don't appear to make sense or correspond to what is inside a source file, and which (until now) would need to be fixed by a clean rebuild (e.g.
rm -r output
).We now make a note of the modification time when we read an input file, and we consider that input file to have changed on a subsequent compile if the modification time is different to what it was before.
The hope with this fix is that it should never be necessary to remove an output directory to get a build to run successfully. If you do run into this problem again, it is a bug: please report it.
-
Fix exports incorrectly being identified as unused in purs bundle (#3727, @rhendric)
References to properties on the
exports
object would previously not be picked up bypurs bundle
as uses of those properties, which could lead to them being incorrectly removed. For example:'use strict'; exports.foo = 1; exports.bar = exports.foo;
would remove the
exports.foo = 1;
statement, breaking the assignment toexports.bar
, iffoo
were not used elsewhere. This statement is now no longer removed. -
Show entire rows in type errors in the presence of the
--verbose-errors
flag (#3722, @Woody88)The row diffing feature, which elides common labels in rows occurring in type errors, did not previously respect the
--verbose-errors
flag, giving the same output regardless of whether it was set or not. Now, if the flag has been supplied, we always show the entire row.
Other
-
Add Makefile command to run license generator (#3718, @hdgarrood)
-
Update language-javascript to 0.7.0.0 (@rhendric, @hdgarrood)
This enables a number of newer JavaScript syntactic constructs to be used in FFI files. Please see the language-javascript release notes for details.
-
Fix for object shorthand syntax in FFI files (#3742, @hdgarrood)
v0.13.3
Enhancements
-
Eliminate empty type class dictionaries in generated code (#2768, @LiamGoodacre)
Empty type class dictionaries — dictionaries which do not contain any type class member implementations at runtime — are often used to provide evidence at compile-time to justify that a particular operation will not fail; for example,
Prim.Row.Cons
can be used to justify that we can expect a record to contain a particular field with a particular type. Unfortunately, constructing empty dictionaries can be costly, especially in more complex scenarios such as type-level programming. This release implements a new optimization which avoids the need to build empty dictionaries at runtime by instead insertingundefined
into the generated code. This optimization can both reduce code size and improve performance in certain contexts. -
Render doc-comments for data constructors and type class members in HTML documentation (#3507, @marcosh)
Documentation comments for data constructors and type class members are now picked up by
purs docs
, and will soon start appearing in Pursuit too. For example:-- | Doc-comments like this one were always rendered in Pursuit data Maybe a = -- | Now this one (for the Just constructor) will be rendered too = Just a -- | And this one (for Nothing) | Nothing -- | Doc-comments like this one were always rendered in Pursuit class Eq a where -- | Now this one (for the `eq` method) will be rendered too eq :: a -> a -> Boolean
-
Show diffs of rows in errors and hints (#3392, @dariooddenino)
In type mismatches between rows, we now elide common labels so that the problem is easier to identify. For example, consider the following code, which has a type error due to the types of the
b
fields in the two records not matching:foo = { a: 1, b: "hi", c: 3, d: 4, e: 5 } bar = { a: 1, b: 2, c: 3, d: 4, e: 5 } baz = [ foo, bar ]
Previously, the type error would include the entirety of each record type:
Could not match type String with type Int while trying to match type ( a :: Int , b :: String , c :: Int , d :: Int , e :: Int ) with type ( a :: Int , b :: Int , c :: Int , d :: Int , e :: Int )
This can become quite difficult to read in the case of large record types. Now, we get this:
Could not match type String with type Int while trying to match type ( b :: String ... ) with type ( b :: Int ... )
Bug fixes
-
Remove more dead code in
purs bundle
(#3551, @rhendric)The dead code elimination in
purs bundle
now no longer incorrectly considers declarations to be used in the presence of local variables which happen to share their names, and is therefore able to remove these declarations when they are unused. -
Fix parsing of comma-separated guards in let statements (#3713, @natefaubion)
The 0.13 parser would previously choke on guards separated by commas in let statements within do/ado blocks, such as
test = ado let foo | bar , baz = 42 | otherwise = 100 in foo
This has now been fixed.
Other
- Add placeholder purs.bin to fix npm installs (#3695, @hdgarrood)
- Refactor and simplify BuildPlan a little (#3699, @hdgarrood)
- Update link to partial type class guide in error message hints (#3717, @alextes)
v0.13.2
Enhancements
-
Add --debug flag to
purs bundle
command (#3666, @rhendric)This flag causes an optimized-for-humans JSON representation of the modules
being bundled to be dumped to stderr, prior to dead code elimination. -
Ignore duplicate file inputs to CLI commands (#3653, @dyerw)
If, after expanding globs, a particular file path appears more than once, the
compiler will now ignore the extra occurrences, instead of emitting a
DuplicateModule
error.
Bug fixes
- Fix printing of tokens with string escapes (#3665, @hdgarrood)
- Fix multiple "let"s in ado before the final "in" (#3675, @natefaubion)
- Throw a parse error (not internal error) when using quoted labels as puns (#3690, @natefaubion)
Other
- Parser: Remove partial type signatures for parameterized productions (#3667, @natefaubion)
- Make git consider *.out files as binary for the golden tests (#3656, @kritzcreek)
- Fix build failures on older GHCs by tightening base lower bound (#3659, @hdgarrood)
- Pin happy version to address build failures when building with Cabal (#3660, @hdgarrood)
- Add upper bounds when producing source distributions (#3661, @hdgarrood)
- Update test dependency on typelevel-prelude (#3649, @hdgarrood)
- Update author and maintainer sections of cabal file (#3663, @hdgarrood)
- Update to GHC 8.6.5, Stackage LTS 13.26 (#3688, @hdgarrood)
- Various CI maintenance (#3687, @hdgarrood)
- Move the "purescript" npm package into the compiler repo (#3691, @hdgarrood)
v0.13.1
v0.13.0
Grammar/Parser Changes
0.13
is a very exciting release for me (@natefaubion). For the past few months I've been working on a complete rewrite of the existing parser. The old parser has served us very well, but it has grown very organically over the years which means it's developed some unsightly limbs! Throughout the process I've tried to iron out a lot of dark corner cases in the language grammar, and I hope this release will set us on a firm foundation so we can start to specify what "PureScript the Language" actually is. This release is definitely breaking, but I think you'll find the changes are modest. I also hope that this release will open up a lot of opportunities for syntactic tooling, both using the existing parser or even using alternative parsers (which are now possible).
Breaking
There are a number of breaking changes, but I think you'll find that most code will continue to parse fine. We've tested the parser against the existing ecosystem and several large production applications at Awake, Lumi, and SlamData. The migration burden was either non-existent or only involved a few changes.
- The only whitespace now allowed in code is ASCII space and line endings. Since you must use indentation to format PureScript code (unlike Haskell), we felt it was best to be more restrictive in what you can write instead of allowing potentially confusing behavior (implicit tab-width, zero-width spaces, etc). You can still use unicode whitespace within string literals.
- The only escapes accepted in string literals are
\n\r\t\'\"\\
,\x[0-9a-fA-F]{1,6}
(unicode hex escape), and\[\r\n ]+\
(gap escapes). We had inherited a vast zoo of escape codes from the Parsec Haskell Language parser. We decided to minimize what we support, and only add things back if there is significant demand. - Octal and binary literals have been removed (hex remains).
\
is no longer a valid operator. It conflicts with lambda syntax.@
is no longer a valid operator. It conflicts with named binder syntax.forall
is no longer a valid identifier for expressions. We wanted a consistent rule for type identifiers and expression identifiers.- Precedence of constructors with arguments in binders (
a@Foo b
must bea@(Foo b)
). - Precedence of kind annotations (
a :: Type -> Type b :: Type
must now be(a :: Type -> Type) (b :: Type)
). - Precedence of type annotations (
::
has lowest precedence, rather than sitting between operators and function application). - Various edge cases with indentation/layout. Again, most code should work fine, but there were some cases where the old parser let you write code that violated the offside rule.
Fixes
- Many fixes around parse error locations. The new parser should yield much more precise error locations, especially for large expressions (like in HTML DSLs).
- Reported source spans no longer include whitespace and comments.
- Reported source span for the last token in a file is now correct.
Enhancements
where
is still only sugar forlet
(it does not introduce bindings over guards), but it is now usable incase
branches in the same manner as declarations._
is now allowed in numeric literals, and is an ignored character (ie.1_000_000 == 1000000
).- Raw string literals (triple quotes) can now contain trailing quotes (ie.
"""hello "world"""" == "hello \"world\""
). - Kind annotations are now allowed in
forall
contexts (#3576 @colinwahl). - The new parser is much faster and can avoid parsing module bodies when initially sorting modules. We also do more work in parallel during the initialization phase of
purs compile
. This means that time to start compiling is faster, and incremental builds are faster. In my testing, a noop call topurs compile
on the Awake codebase went from ~10s to ~3s.
Other Changes
Breaking
- Fix sharing in function composition inlining (#3439 @natefaubion). This is really a bugfix, but it has the potential to break code. Previously, you could write recursive point-free compositions that the compiler inadvertently eta-expanded into working code by eliminating sharing. We've changed the optimization to respect strict evaluation semantics, which can cause existing code to stack overflow. This generally arises in instance definitions. Unfortunately, we don't have a way to disallow the problematic code at this time.
- Fail compilation when a module imports itself (#3586 @hdgarrood).
- Disallow re-exporting class and type with the same name (#3648 @joneshf).
Enhancements
- Better illegal whitespace errors (#3627 @hdgarrood).
- Only display class members that are not exported from the module when throwing a
TransitiveExportError
for a class (#3612 @colinwahl). - Tweaks to type pretty printing (#3610 @garyb).
- Unify matching constraints (#3620 @garyb).
- Improve error message on ModuleNotFound error for Prim modules (#3637 @ealmansi).
Docs
- Make markdown format behave like html. Remove --docgen opt. Separate directories for html and markdown docs (#3641 @ealmansi).
- Make html the default output format (#3643 @ealmansi).
- Write ctags and etags to filesystem instead of stdout (#3644 @ealmansi).
- Add --output option for purs docs (#3647 @hdgarrood).
- Use externs files when producing docs (#3645 @hdgarrood).
docs
is now a codegen target forpurs compile
where documentation is persisted as adocs.json
file in theoutput
directory.
Internal
- Remove failable patterns and
NoMonadFailDesugaring
extension (#3610 @adnelson). - Add tests for grammar fixes addressed by CST (#3629 #3631 @hdgarrood).
- Keep Parser.y ASCII to avoid locale issues with happy (#3640 @jmackie).
- Improve display of internal errors (#3634 @hdgarrood).
v0.12.5
This small release fixes three issues which were introduced in 0.12.4.
Filter out module declarations when suggesting imports (#3591)
When determining candidates for imports, ignore modules. This allows you to easily import types which come from modules of the same name, like Effect
. (@kritzcreek)
Running purs ide server crashes on macOS (#3594)
Running purs ide server
on macOS would immediately crash with the error purs: Network.Socket.listen: unsupported operation (Operation not supported on socket)
; this has now been fixed. (@f-f)
Take qualification into consideration when determining type class cycles (#3595)
When checking for cycles in type classes, the compiler is now able to distinguish classes which have come from different modules, meaning that e.g. class SomeOtherModule.Foo <= Foo
is no longer incorrectly reported as a class having itself as a superclass. (@hdgarrood)