guix-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[bug#55030] [PATCH 00/30] gnu: elm: Update to 0.19.1. Add build system &


From: Philip McGrath
Subject: [bug#55030] [PATCH 00/30] gnu: elm: Update to 0.19.1. Add build system & importer.
Date: Sun, 1 May 2022 17:26:17 -0400
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.8.1

Hi,

Hi,

On 5/1/22 16:22, Ludovic Courtès wrote:
Hi Philip,

Philip McGrath <philip@philipmcgrath.com> skribis:

This patch series updates Elm to version 0.9.1, then adds an
'elm-build-system' and a 'guix import elm' command.

Impressive!


Thanks!

To exercise the new features, this patch series then:

   * Build the front-end for the `elm reactor` command (which is written in Elm)
     and adds a variant of Elm to Guix with the command enabled;

   * Builds 'elm-todomvc', an official example of a basic Elm application; and

   * Builds a feature-rich third-party package, "terezka/elm-charts":
     <https://elm-charts.org>.

Woow, neat.

Annoying question that I have to ask: do these packages bundle
JavaScript libraries?  If yes, is it source or is it “minified”?

(My take is that we could tolerate some level of bundling if “doing the
right thing” is impractical, but it’d rather be source.)


Short answer: no, they don't!

Longer answer:

Elm basically takes the view that the existing JavaScript/NPM thicket should be considered harmful. It imposes a lot of very strict requirements on Elm "packages" (vs. "applications") to avoid whole classes of problems. Not all of them are precisely the requirements I would have chosen, but I like them better than the alternative chaos.

(One reason I gave this a try was to get some hands-on experience writing a build system and importer in a simplified context before trying to write `racket-build-system`.)

In particular, allowing arbitrary JavaScript would defeat the strong guarantees Elm wants to offer as a statically-typed, purely-functional language with compiler-enforced semantic versioning (well, for a decidable subset of "semantics") that can make runtime errors vanishingly rare in practice. To that end, Elm requires that "packages"---the things `elm-build-system` knows how to build---be written in pure Elm, with no JavaScript at all. For "applications", interop is limited to asynchronous message passing.[1] The only two "applications" in this series, the `elm reactor` frontend and `elm-todomvc`, don't use any message passing.

Of course, Elm needs some way to implement primitives. These are provided by modules in the `Elm.Kernel.*` namespace, which are written in JavaScript with the undocumented, unsafe conventions expected by the Elm compiler. The Elm compiler only allows kernel modules in packages in the `elm/*` and `elm-explorations/*` namespaces, so users can know that third-party packages won't break Elm's guaranteed, and the compiler is free to change its internal APIs without breaking anything. (This is free software, so you could patch the compiler to do whatever you want: it's just a community norm so strong it's expressed in code.) Even this is all source code with whitespace and comments: it's written in a very stylized way, as an ASM file in another compiler implementation might be, but it isn't generated code.

For people who want to "minify", Elm suggests flags for UglifyJS that can also do otherwise-unsafe whole-program optimization of the compiled "application".[2] (Compiling "packages" emits only an internal representation, not JavaScript.) In my own projects, I've also done other post-processing, like adding LibreJS comments and converting the output to an ES6 module. I haven't tried to make `elm-build-system` do any of those kinds of things for "applications": I think we should find more examples of Elm applications people would want to package for Guix first, rather than trying to guess what they might need.

[1]: https://guide.elm-lang.org/interop/
[2]: https://github.com/elm/compiler/blob/master/hints/optimize.md

-Philip





reply via email to

[Prev in Thread] Current Thread [Next in Thread]