Giter Site home page Giter Site logo

purenix-org / purenix Goto Github PK

View Code? Open in Web Editor NEW
280.0 10.0 7.0 153 KB

Nix backend for PureScript. Transpile PureScript code to Nix.

Home Page: https://hackage.haskell.org/package/purenix

License: BSD 3-Clause "New" or "Revised" License

Nix 10.11% Haskell 84.51% Shell 5.38%
purescript nix transpiler hacktoberfest haskell

purenix's Introduction

PureNix

PureNix is a Nix backend for PureScript.

Sometimes, you find yourself having to write Nix code that's more complicated than what the language was designed for. PureNix allows you to write that code in a fully-featured, strongly-typed language instead, and then compile to Nix. A typical example is parsing of configuration files, like the port of cabal2nix that inspired PureNix.

PureNix has full support for all of PureScript's features, including data types, type classes, and calling back into Nix using the FFI.

On the organization page for PureNix you will find a number of packages intended to be used with PureNix, including ports of libraries like purescript-prelude.

Usage

The easiest way to use PureNix is through Spago. Simply set backend = "purenix", make sure purenix is available in the PATH, and build as normal.

When you run purenix, manually or through Spago, it will look for the Purescript output directory ./output in the current working directory. It then traverses this directory structure, looks for Purescript's intermediate corefn.json files, transpiles the corefn.json files to the equivalent Nix code, and writes the output Nix code to default.nix.

See the Getting Started Guide for more in-depth instructions.

Code sample

PureScript source, Main.purs:

module Main where

import Data.A as A
import Data.B as B

greeting :: String
greeting = "Hello, world!"

data Maybe a = Nothing | Just a

fromMaybe :: forall a. a -> Maybe a -> a
fromMaybe a Nothing = a
fromMaybe _ (Just a) = a

foreign import add :: Int -> Int -> Int

foo :: Int
foo = add A.bar B.baz

Nix FFI file, Main.nix:

{ add = a: b: a + b; }

Generated Nix:

let
  module =
    { "Data.A" = import ../Data.A;
      "Data.B" = import ../Data.B;
    };
  foreign = import ./foreign.nix;
  add = foreign.add;
  Nothing = {__tag = "Nothing";};
  Just = value0:
    { __tag = "Just";
      __field0 = value0;
    };
  greeting = "Hello, world!";
  fromMaybe = v: v1:
    let
      __pattern0 = __fail: if v1.__tag == "Nothing" then let a = v; in a else __fail;
      __pattern1 = __fail: if v1.__tag == "Just" then let a = v1.__field0; in a else __fail;
      __patternFail = builtins.throw "Pattern match failure in src/Main.purs at 11:1 - 11:41";
    in
      __pattern0 (__pattern1 __patternFail);
  foo = add module."Data.A".bar module."Data.B".baz;
in
  {inherit greeting Nothing Just fromMaybe add foo;}

There are a couple things to notice here:

  • PureScript built-in types like String, Int, records, and lists are converted to their corresponding Nix types, as in greeting.
  • Data constructors from sum types are available to easily work with in the output Nix file, like Just and Nothing, although you might want to define named field accessors.
  • Foreign imports are straightforward to define and use, like in add and foo. The FFI file gets copied into the module's output directory as foreign.nix.

Development

You can launch a development shell with the command nix develop (as long as you have flakes support enabled in Nix). This puts you in a Nix shell with cabal-install and GHC setup to compile PureNix, as well as other helpful tools like HLint, HLS, PureScript, Spago, etc. From here you should be able to run commands like cabal build in order to build PureNix.

Warnings

What PureNix is and is not

PureNix allows you to write code in PureScript, and then compile to Nix. The degree to which you can replace existing Nix code depends on how well you can express that code in PureScript. For some things, that's pretty easy, but there are many things in Nix and nixpkgs that are much harder to provide (useful) types for. As such, PureNix is not a complete typed replacement for Nix. The goal for now is simply to allow you to take code that's tricky to write in an untyped language, and write it in a typed language instead.

The ecosystem around PureNix is currently focused on providing PureNix ports of existing PureScript libraries. Over time, we hope to expand in the other direction as well, with libraries that provide typed versions of Nix-only constructs, thereby expanding the amount of Nix you can feasibly replace with PureNix, but there's still a lot to be done. Any help is welcome!

Laziness and memory management

PureScript generally assumes that its backends perform strict evaluation, and some degree of memory management. Nix is a lazy language however, and is happy to leak memory. For most use cases this doesn't cause any issues, and in fact the laziness allows you to write more Haskell-like code than you usually would in PureScript.

Still, it's good to keep these things in mind:

  • Like in every lazy language, you need to watch out for space leaks caused by accidentally building up large thunks. PureScript does not natively have tools to deal with laziness, like bang patterns or seq, but you can define them yourself by e.g. pulling in builtins.seq through the FFI.

  • Long-running programs may run out of memory due to the lack of garbage collection and tail recursion. If you end up writing long-running programs, like a parser that needs to process very large files, you might have to rewrite it in a way that minimizes recursion and allocation.

purenix's People

Contributors

cdepillabout avatar jonascarpay avatar yvan-sraka avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

purenix's Issues

add binary cache

Just loading the devShell and it needs to build a lot of stuff.
I see there is already a cachix github action but commented out. Maybe consider re-adding it?

Make a release

At some point, we'll have to do a release. Tentative checklist:

README

We need a README.

  • introduction
    • motivation
  • usage
    • spago
    • FFI/prelude
    • notes on laziness
  • generated code samples

create a real package set

In order for PureNix to be widely usable, we need a real package set for people to depend on.

I have a temporary package set that I've been using while doing development on the core libraries: https://github.com/purenix-org/temp-package-set. But this pins all packages to the master branch instead of a release tag.

We need a real package set where everything is correctly pinned to a release tag, like the upstream normal PureScript Package Sets. It would be nice to also have all of their CI automation.

Also, before deciding to copy the PureScript Package Set approach, we should take a look at the PureScript Registry and see if it would be possible to use that, since that is what the PureScript community will use going forward (not the PureScript Package Sets). We need to ask the PureScript Registry maintainers if the registry is directly usable by alternative backends.

If anyone is interested in putting this together, please leave a comment and I can create any repos necessary for you to get started setting this up.

implement bundle command

purs and spago both implement a bundle command.

This command bundles all the output .js files for each PureScript module into a single .js. This single .js file is easy to deploy or copy somewhere else.

It may make sense for us to also implement a bundle command in purenix. This command would output a single .nix for the entire project. This single .nix file would be easy to copy to another project (or possibly even use in a larger repo like Nixpkgs).

We need to investigate exactly how the bundle command works in purs and spago. We need to come up with a good way of including all our output Nix code into a single file.

This was mentioned in #22 (comment).

Quick Start Broken?

Hey, I was trying to follow the Quick Start but couldn't get the example to build. After following the steps, including switching out the package set hash to the latest on master of the temp-package-set repo. Running spago build after that complained that that package set required an older version of purs (0.14.something), but I chose the option to override it in the packages.dhall file..

The result of running spago build was that modules compiled to CoreFn but purenix failed:

[info] Build succeeded.
purenix: impossible
CallStack (from HasCallStack):
  error, called at src/PureNix/Identifiers.hs:63:30 in purenix-1.1-AKRNnyJSalY6yydb60EpDF:PureNix.Identifiers
[error] Backend "purenix" exited with error:1

Are you able to reproduce this? FWIW I also tried to build a custom nix shell using EasyPurescriptNix with the appropriate version of purs that spago wanted for that package set, and I still got errors, albeit a different one. Something about not finding sourcePos.

This is my first rodeo trying to use a different PureScript backend, and I'm not a nix power user so maybe I'm just missing something 🤔

decide what to do about interpolation characters in strings

Right now, we don't check whether PureScript strings have Nix interpolation characters.

For example, this PureScript code:

myTest :: String -> String
myTest hello = "${hello}"

currently becomes:

let
  myIdent = hello: "${hello}";
  ...

We should decide what to do about this.

Our two choices are:

  1. Do nothing and just make sure that users are aware of the need to escape a ${ sequence when writing literal strings.
  2. Actively escape those sequences in strings in purenix. We could possibly add our own newtype StringWithInterp = StringWithInterp String newtype wrapper that purenix is aware of and doesn't do escaping on.

Support running/evaluating built functions

Spago assumes a backed has a --run Module.Name.function flag that will execute the given function. This is also how tests are implemented. I think the following snippet is a reasonable implementation for --run in purenix.

mkdir tmp-nix
export NIX_STORE_PATH=$(pwd)/tmp-nix/store
export NIX_DATA_DIR=$(pwd)/tmp-nix/share
export NIX_LOG_DIR=$(pwd)/tmp-nix/log/nix
export NIX_STATE_DIR=$(pwd)/tmp-nix/log/nix
nix-instantiate --eval --readonly-mode -E "let module = import ./output/Test.Main; in module.main null"

This would of course be implemented within Haskell and the module to import as well as the function to evaluate is defined by the flag.

The snippet runs evaluation against a temporary nix store and in readonly-mode so it should be fine run inside a nix build. I've only tested that it does indeed run in the simplest of scenarios so far.

(Optionally) delete non-nix files

Currently, purenix will only create new files. Maybe it's a good idea to also delete the json files once we're done with them, to leave the directory in as clean a state as possible? AFAICT that's what the JS backend does too.

test suite

It would be nice to have a test-suite for purenix.

The most important tests would be for the Nix.Convert and Nix.Print modules.

We'd also especially like to test that all our identifiers, strings, and attrset keys get escaped correctly.

Places to pull ideas from:

As of this writing, neither purerl nor purescript-native have a test suite.

Implementing the `callPackage` pattern with PureNix

Hello,

Thanks for this great project! I'm looking to better understand what is possible or not to do with Nix PureScrip backend, and mainly how we might replicate the callPackage pattern? I looked a bit over the internet, without success, about how to write a Nix package, a NixOS option or configuration using PureNix, before trying to hack on that myself. Are you aware of existing examples or discussions about this? If not, are there any known challenges or obstacles in doing so?

Thanks!

On a side note: Is there a way to structure PureNix's output, output/Main/default.nix, so that it aligns with the flakes' syntax?

create `purescript-nix-buitins` library

It would be nice to have a library like purescript-nix-builtins that provides FFI for all the different Nix builtins (like builtins.deepSeq, builtins.getEnv, builtins.mapAttrs, etc). This library should also provide FFI data types for types from Nix that are not available from PureScript by default. For instance, a Path type to represent Nix paths.

A couple other points:

don't run purenix for corefn.json files that are older than the output default.nix file

Right now, when you run purenix, it looks for all the output/*/corefn.json files, and transpiles each of them to output/*/default.nix.

It may be possible to instead check if an output/*/default.nix file is newer than output/*/corefn.json, and not regenerate the output/*/default.nix in that case.

We should confirm that purs has similar functionality, and doesn't touch the corefn.json file when it is already newer than the input src/*.purs input file.

There was a little discussion about this in #22 (comment).

"'allow-import-from-derivation' is disabled" error

I'm new to nix, so I don't know if this is an error or intended, but when I try to run nix flake show,
I get the error 'allow-import-from-derivation' is disabled.

$ nix flake show --version
nix (Nix) 2.4
$ nix flake show --show-trace
git+file:///.../github/purenix?ref=main&rev=4dd6ec3913825a66cc2c8a82219428d812c0a203
├───defaultPackage
error: cannot build '/nix/store/vnvd0kq9vphs2b191yh0wk1z7ffffjlq-cabal2nix-purenix.drv' during evaluation because the option 'allow-import-from-derivation' is disabled

       … while importing '/nix/store/ybyh4wwhkwg6fpp2acqd87rkrhj4499r-cabal2nix-purenix'

       at /nix/store/r85b90gdvvpfl04rnn2aisr6jggi2pp0-source/pkgs/development/haskell-modules/make-package-set.nix:87:47:

           86|       # info that callPackage uses to determine the arguments).
           87|       drv = if lib.isFunction fn then fn else import fn;
             |                                               ^
           88|       auto = builtins.intersectAttrs (lib.functionArgs drv) scope;

       … while evaluating 'drvScope'

       at /nix/store/r85b90gdvvpfl04rnn2aisr6jggi2pp0-source/pkgs/development/haskell-modules/make-package-set.nix:91:18:

           90|       # this wraps the `drv` function to add a `overrideScope` function to the result.
           91|       drvScope = allArgs: drv allArgs // {
             |                  ^
           92|         overrideScope = f:

       … from call site

       at /nix/store/r85b90gdvvpfl04rnn2aisr6jggi2pp0-source/lib/customisation.nix:69:16:

           68|     let
           69|       result = f origArgs;
             |                ^
           70|

       … while evaluating 'makeOverridable'

       at /nix/store/r85b90gdvvpfl04rnn2aisr6jggi2pp0-source/lib/customisation.nix:67:24:

           66|   */
           67|   makeOverridable = f: origArgs:
             |                        ^
           68|     let

       … from call site

       at /nix/store/r85b90gdvvpfl04rnn2aisr6jggi2pp0-source/pkgs/development/haskell-modules/make-package-set.nix:101:8:

          100|       };
          101|     in lib.makeOverridable drvScope (auto // manualArgs);
             |        ^
          102|

       … while evaluating 'callPackageWithScope'

       at /nix/store/r85b90gdvvpfl04rnn2aisr6jggi2pp0-source/pkgs/development/haskell-modules/make-package-set.nix:78:37:

           77|   # here `bar` is a manual argument.
           78|   callPackageWithScope = scope: fn: manualArgs:
             |                                     ^
           79|     let

       … from call site

       at /nix/store/r85b90gdvvpfl04rnn2aisr6jggi2pp0-source/pkgs/development/haskell-modules/make-package-set.nix:118:28:

          117|   defaultScope = mkScope self;
          118|   callPackage = drv: args: callPackageWithScope defaultScope drv args;
             |                            ^
          119|

       … while evaluating 'callPackage'

       at /nix/store/r85b90gdvvpfl04rnn2aisr6jggi2pp0-source/pkgs/development/haskell-modules/make-package-set.nix:118:22:

          117|   defaultScope = mkScope self;
          118|   callPackage = drv: args: callPackageWithScope defaultScope drv args;
             |                      ^
          119|

       … from call site

       at /nix/store/r85b90gdvvpfl04rnn2aisr6jggi2pp0-source/pkgs/development/haskell-modules/make-package-set.nix:174:9:

          173|       };
          174|     }) (self.callPackage src args);
             |         ^
          175|

       … while evaluating 'overrideCabal'

       at /nix/store/r85b90gdvvpfl04rnn2aisr6jggi2pp0-source/pkgs/development/haskell-modules/lib/compose.nix:38:22:

           37|    */
           38|   overrideCabal = f: drv: (drv.override (args: args // {
             |                      ^
           39|     mkDerivation = drv: (args.mkDerivation drv).override f;

       … from call site

       at /nix/store/r85b90gdvvpfl04rnn2aisr6jggi2pp0-source/pkgs/development/haskell-modules/make-package-set.nix:162:5:

          161|   callPackageKeepDeriver = src: args:
          162|     overrideCabal (orig: {
             |     ^
          163|       preConfigure = ''

       … while evaluating 'callPackageKeepDeriver'

       at /nix/store/r85b90gdvvpfl04rnn2aisr6jggi2pp0-source/pkgs/development/haskell-modules/make-package-set.nix:161:33:

          160|   # annoyance.
          161|   callPackageKeepDeriver = src: args:
             |                                 ^
          162|     overrideCabal (orig: {

       … from call site

       at /nix/store/r85b90gdvvpfl04rnn2aisr6jggi2pp0-source/pkgs/development/haskell-modules/make-package-set.nix:218:14:

          217|            inherit src;
          218|          }) (callPackageKeepDeriver expr args);
             |              ^
          219|

       … while evaluating 'overrideCabal'

       at /nix/store/r85b90gdvvpfl04rnn2aisr6jggi2pp0-source/pkgs/development/haskell-modules/lib/compose.nix:38:22:

           37|    */
           38|   overrideCabal = f: drv: (drv.override (args: args // {
             |                      ^
           39|     mkDerivation = drv: (args.mkDerivation drv).override f;

       … from call site

       at /nix/store/r85b90gdvvpfl04rnn2aisr6jggi2pp0-source/pkgs/development/haskell-modules/make-package-set.nix:216:10:

          215|         };
          216|       in overrideCabal (orig: {
             |          ^
          217|            inherit src;

       … while evaluating 'callCabal2nixWithOptions'

       at /nix/store/r85b90gdvvpfl04rnn2aisr6jggi2pp0-source/pkgs/development/haskell-modules/make-package-set.nix:205:66:

          204|     # Creates a Haskell package from a source package by calling cabal2nix on the source.
          205|     callCabal2nixWithOptions = name: src: extraCabal2nixOptions: args:
             |                                                                  ^
          206|       let

       … from call site

       at /nix/store/r85b90gdvvpfl04rnn2aisr6jggi2pp0-source/pkgs/development/haskell-modules/make-package-set.nix:220:38:

          219|
          220|     callCabal2nix = name: src: args: self.callCabal2nixWithOptions name src "" args;
             |                                      ^
          221|

       … while evaluating 'callCabal2nix'

       at /nix/store/r85b90gdvvpfl04rnn2aisr6jggi2pp0-source/pkgs/development/haskell-modules/make-package-set.nix:220:32:

          219|
          220|     callCabal2nix = name: src: args: self.callCabal2nixWithOptions name src "" args;
             |                                ^
          221|

       … from call site

       at /nix/store/lgkd30fbvyz9ndyqai6c2cckbfp12bfc-source/nix/overlay.nix:33:11:

           32|           in
           33|           hfinal.callCabal2nix "purenix" src { };
             |           ^
           34|       };

       … while evaluating the attribute 'haskellPackages.purenix'

       at /nix/store/lgkd30fbvyz9ndyqai6c2cckbfp12bfc-source/nix/overlay.nix:5:9:

            4|       prev.haskell.packageOverrides hfinal hprev // {
            5|         purenix =
             |         ^
            6|           let

       … while evaluating 'overrideCabal'

       at /nix/store/r85b90gdvvpfl04rnn2aisr6jggi2pp0-source/pkgs/development/haskell-modules/lib/compose.nix:38:22:

           37|    */
           38|   overrideCabal = f: drv: (drv.override (args: args // {
             |                      ^
           39|     mkDerivation = drv: (args.mkDerivation drv).override f;

       … from call site

       at /nix/store/lgkd30fbvyz9ndyqai6c2cckbfp12bfc-source/nix/overlay.nix:38:5:

           37|   purenix =
           38|     final.haskell.lib.compose.justStaticExecutables final.haskellPackages.purenix;
             |     ^
           39|

       … while evaluating the attribute 'purenix'

       at /nix/store/lgkd30fbvyz9ndyqai6c2cckbfp12bfc-source/nix/overlay.nix:37:3:

           36|
           37|   purenix =
             |   ^
           38|     final.haskell.lib.compose.justStaticExecutables final.haskellPackages.purenix;

       … while evaluating the attribute 'defaultPackage'

       at /nix/store/lgkd30fbvyz9ndyqai6c2cckbfp12bfc-source/flake.nix:15:11:

           14|         {
           15|           defaultPackage = pkgs.purenix;
             |           ^
           16|           packages.purenix = pkgs.purenix;

core library support

This issue is to track which core libraries have been ported to PureNix.

Done

These are libraries that have already been ported.

Todo

These are libraries that still need to be ported.

Won't Do / Can't Do

These are libraries that either can't be ported to PureNix, or don't make sense to port to PureNix.

  • assert

    Nix does have an assert statement, but I'm not sure it would be able to be used with a similar API to purescript-assert. Creating a purescript-nix-assert library would likely be better.

  • console

    Nix doesn't have any way of writing arbitrary text to the console. There is the builtins.trace Nix function, but that could be wrapped up in it's own library.

  • docs-search

    I'm not sure what this is or how it would be related to PureNix.

  • effect

    Nix doesn't have any way of doing arbitrary effects. In theory, we could have an Effect type for compatibility, but in practice we wouldn't be able to do anything interesting with it.

    edit: There was a little discussion in purenix-org/temp-package-set#1 as to whether or not purescript-effect would make sense for PureNix. There are a couple good points in favor of having purescript-effect.

  • exceptions

    Nix doesn't really have exceptions the same way JavaScript does. Nix does have the builtins.abort, assert, and builtins.tryEval functions, which may be able to be wrapped up in a nice library.

  • gen

    See the problem with random.

  • minibench

    I don't think Nix has any way of getting the current time (or at least to any precision that would be necessary for benchmarking).

  • parallel

    Nix doesn't have any built-in way of running computations in parallel. It is possible we could support this same API in PureNix for compatibility, but it is likely we would only be able to run the computations sequentially.

  • quickcheck

    See the problem with random.

  • random

    As far as I know, Nix doesn't have any sort of random number generator. There is no way to generate random numbers.

    edit: Thinking about this a little more, we could have purescript-random be a pseudorandom number generator (PRNG). All the random functions could just take a seed that has to be passed in. The seed would be the initial seed for the PRNG. This could be useful for people that are willing to pass in a random seed when calling nix-build. This seems like a reasonable way to use libraries like purescript-random, purescript-gen, and purescript-quickcheck.

  • refs

    Nix doesn't have any way of mutating values, so refs are not possible.

  • tailrec

    Nix is lazy, so this sort of trampolining isn't necessary.

characters in quotes aren't escaped correctly

It looks like some characters in quotes aren't escaped correctly.

I haven't extensively tested this, but here is one example I've found:

module Main where

example :: String
example = "\""

This compiles to:

let
  module = { };
  example = """;
in
  {inherit example;}

But example should probably be "\"".

make sure that an FFI file exists if a PureScript module has foreign imports

Current in purenix, we copy over an FFI file like Main.nix to output/Main/foreign.nix, but only if Main.nix exists.

We don't have any check for the situation where Main.purs uses FFI functions, but no Main.nix FFI file exists. We should probably add this check, since it can be easy to forget to write an FFI file.

Rename modules

We might want to also change our module Lib to be named something more descriptive.

I guess we could also change modules like Nix.Convert and Nix.Expr to something like PureNix.Convert and PureNix.Expr, but I don't feel as strongly about this.

Originally posted by @cdepillabout in #10 (comment)

add support for running tests with `spago test`

Spago has a test command that makes it easy to run tests. PureNix probably needs something added to be able to work with spago test.

This hasn't really been a problem up until now, since none of the PureNix libraries have tests. But now there is a tasty-like testing framework for PureNix (https://github.com/thought2/purescript-miraculix by @thought2), so it would be really convenient to be able to run tests directly with spago test.

Someone interested in implementing this may want to do the following:

  • Investigate the Spago codebase to find out exactly what it does when running spago test.

    I imagine this function is a good place to start: https://github.com/purescript/spago/blob/aa7c0de6d903262f69452663c09fad9c441af8d3/src/Spago/Build.hs#L241-L256

    Keep in mind that it is quite possible there are two different code-paths here, one for the normal JS backend and one for alternative backends (like PureNix).

    It would be great if you could leave a comment on this issue with exactly what you figured out.

  • Optionally go on the PureScript Discord and ask in #compiler or #purerl how the Erlang backend handles spago test. They may have some good suggestions.

  • Decide on how PureNix should handle spago test, and leave a short comment here with how you see this working.

  • Send a PR implementing whatever is necessary.

Clean up conversion output

I imagine we might want to get rid of this line, since purs doesn't output something like this. Also, for big repos it will sometimes output so many lines that the important Warning lines will be scrolled off the screen.

Originally posted by @cdepillabout in #16 (comment)

laziness

We decided to move forward and make purenix a lazy language.

The big downside of this is that we will have to be careful when copying (JavaScript) PureScript code, since it is strict. Our Prelude and other standard libraries will have to be built from the ground up around laziness.

One concern is whether there is some sort of compilation step in purs before the CoreFn output phase that makes use of PureScript being a strict language. This would cause problems for us. At some point we should probably ask the PureScript developers if they know of anywhere this could bite us.

Naming convention for purenix libraries.

I noticed that the ports of the 'official' PS packages still keep the same names of their origins.

E.g. purescript-nonempty

Would it maybe make sense to name them either purescript-nix-nonempty or even purenix-nonempty. I think the purescript- prefix is a leftover from bower times. It's not mandatory for spago anymore?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.