Skip to content

Releases: purescript/purescript

v0.13.8

23 May 20:31
Compare
Choose a tag to compare

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, and depends, 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

  • Declare explicit upper bounds on Cabal and haskeline rather than relying on
    stack's pvp-bounds (#3777, @coot)

v0.13.7

23 May 19:49
896228b
Compare
Choose a tag to compare

release withdrawn due to CI mishap

v0.13.6

17 Jan 01:28
4dd32c4
Compare
Choose a tag to compare

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

13 Nov 22:28
Compare
Choose a tag to compare

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

20 Oct 21:03
Compare
Choose a tag to compare

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 declaration C is actually redundant. The warning now would be The 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 an UnusedImport instead of an UnusedExplicitImport 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 error

    No 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 by purs 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 to exports.bar, if foo 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

v0.13.3

18 Aug 13:10
Compare
Choose a tag to compare

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 inserting undefined 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

v0.13.2

05 Jul 13:11
Compare
Choose a tag to compare

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

Other

v0.13.1

04 Jul 21:37
Compare
Choose a tag to compare

Notice: This release has been unpublished due to an error in the package tarball.

v0.13.0

30 May 00:12
738aaa2
Compare
Choose a tag to compare

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 be a@(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 for let (it does not introduce bindings over guards), but it is now usable in case 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 to purs 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 for purs compile where documentation is persisted as a docs.json file in the output directory.

Internal

v0.12.5

15 Apr 01:58
Compare
Choose a tag to compare

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)