Guida Compiler - Was "There are 3 Elm compilers written in Elm"

These 3 all seem to be completely independant efforts to rewrite the Elm compiler in Elm:

Just wondering if anyone has tried them out and any thoughts on stability, speed, compatability, future directions?

For myself, I am interested in doing some Elm compiler hacking. There is a lot of appeal in working in Elm rather than Haskel, but its only one factor amongst a lot of things to weigh up.

9 Likes

I tried Guida and compiled my old Sunny Land project with the new compiler. I’ve found no issues. I even tried to enable source maps and played a bit on Safari debugger. That worked great too. I’m wondering if there’s a way with sourcemaps to separate dependencies modules and user app code, because actually they are all listed together and this confuses things a bit.

AFAIK Guida’s author is currently working on a format tool (equivalent to elm-format). Very impressed by the quality of the project so far!

6 Likes

Did you get an idea what the compile time is like compared with Elm compiler?

Nope, I didn’t do any benchmark on it. :pensive_face:

Tried Guida on a 150K LOC project, with a view to comparing compile times. I guess I will have to try something a bit smaller.

<--- JS stacktrace --->

FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory
 1: 0xb7a940 node::Abort() [/home/rupert/.asdf/installs/nodejs/18.16.1/bin/node]
 2: 0xa8e823  [/home/rupert/.asdf/installs/nodejs/18.16.1/bin/node]
 3: 0xd5c990 v8::Utils::ReportOOMFailure(v8::internal::Isolate*, char const*, bool) [/home/rupert/.asdf/installs/nodejs/18.16.1/bin/node]
 4: 0xd5cd37 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [/home/rupert/.asdf/installs/nodejs/18.16.1/bin/node]
 5: 0xf3a435  [/home/rupert/.asdf/installs/nodejs/18.16.1/bin/node]
 6: 0xf4c91d v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) [/home/rupert/.asdf/installs/nodejs/18.16.1/bin/node]
 7: 0xf2701e v8::internal::HeapAllocator::AllocateRawWithLightRetrySlowPath(int, v8::internal::AllocationType, v8::internal::AllocationOrigin, v8::internal::AllocationAlignment) [/home/rupert/.asdf/installs/nodejs/18.16.1/bin/node]
 8: 0xf283e7 v8::internal::HeapAllocator::AllocateRawWithRetryOrFailSlowPath(int, v8::internal::AllocationType, v8::internal::AllocationOrigin, v8::internal::AllocationAlignment) [/home/rupert/.asdf/installs/nodejs/18.16.1/bin/node]
 9: 0xf095ba v8::internal::Factory::NewFillerObject(int, v8::internal::AllocationAlignment, v8::internal::AllocationType, v8::internal::AllocationOrigin) [/home/rupert/.asdf/installs/nodejs/18.16.1/bin/node]
10: 0x12ce7ff v8::internal::Runtime_AllocateInYoungGeneration(int, unsigned long*, v8::internal::Isolate*) [/home/rupert/.asdf/installs/nodejs/18.16.1/bin/node]
11: 0x16fb6f9  [/home/rupert/.asdf/installs/nodejs/18.16.1/bin/node]
Aborted (core dumped)

Tried it on the-sett/elm-pretty-print which hash about 3K LOC:

rupert@station:~/projects/elm-pretty-printer$ time elm make
Starting downloads...

  ● elm-community/basics-extra 4.1.0

Dependencies ready!         
Success! Compiled 3 modules.

real    0m1.364s
user    0m0.255s
sys     0m0.281s
rupert@station:~/projects/elm-pretty-printer$ time guida make
Dependencies ready!         
Success! Compiled 3 modules.

real    0m1.325s
user    0m1.494s
sys     0m0.154s

A little faster which is impressive!

2 Likes

Out of memory on an 8K LOC project and on a 4K LOC. Both of those were applications not packages.

Results on the-sett/elm-syntax-dsl package which is about 12K LOC.

There may be an issue with applications? Or maybe its just because some of my applications use a lot of packages so the total size of the build is larger.

rupert@station:~/projects/elm-syntax-dsl$ time elm make
Dependencies ready!           
Success! Compiled 6 modules.

real    0m0.884s
user    0m0.203s
sys     0m0.291s
rupert@station:~/projects/elm-syntax-dsl$ time guida make
Dependencies ready!           
Success! Compiled 6 modules.

real    0m3.380s
user    0m4.423s
sys     0m0.436s

Big enough to show the difference, but I am still impressed!

1 Like

Hi Rupert, I know almost nothing about the pine-vm, but I’d love to learn more about it.

One important difference between DΓ©cio’s Guida and my port of the Elm compiler is that my port is designed to run in the browser, while Guida runs in Node.js, has write access to your files, and can therefore theoretically be used as a drop-in replacement for the original compiler.

I deliberately didn’t add write access to local files in my port, because that could have quickly pushed it toward becoming an IDE, which wasn’t my goal at all (yet).

In this test, it looks like Elm had to download one dependency, while Guida didn’t. So it’s a bit unfair :slight_smile:

Missed that. I was trying to ensure it did no downloads to make the test fair. I think therefore that one should be ignored, and the later test against the-sett/elm-syntax-dsl taken as a better indication.

Tried Guida on each of 5 subapps of a 200kloc codebase at work.
All of them runs out of memory :frowning:

(sorry, had to edit the post since I’m a new user and can only put 2 links in a post)

hi Rupert, really happy to see the interest in these projects, and in Guida in particular :slight_smile:

I am Decio Ferreira, the creator of the guida-lang project.

thoughts on stability, speed, compatibility, future directions?

With Guida, the intent is to create a new language that is company friendly and builds on top of Elm, having backward compatibility (respecting existing Elm projects, ensuring a frictionless migration), self-hosted environment (allowing more devs to contribute to the language, helping debug any issues they might find, having a better understanding of how it works and a good example of what can be achieved with the language), and finally I intend to evolve the language to integrate new features and improvements (ideally i would love to see the community contribute to having functionally like tests, format, extra-libraries integrating the core of the language). Also, to provide the environment required to use the language, like registry (package-registry) and other tools (eg. vscode-client).

The package registry can run on a local environment, which means private packages are supported. For this we just need use the GUIDA_REGISTRY environment variable to point at it (by default it currently uses elm package)

The language can already compile itself, is backward compatibility with elm 0.19, has a few extra functionalities like --yes flags on commands, uninstall and test commands integrated on the compiler, --package on the init command, and small additions to the language to represent some of the things that I want to do with it going forward (eg. _name (underscore) wildcard pattern, tuple with 3+ elements, or source maps).

Here are some details of self compilation of the project:

compiler % time ./bin/index.js make --optimize src/Terminal/Main.elm
Starting downloads...

  ● Janiczek/elm-vlq 1.0.0
(...)
  ● stil4m/elm-syntax 7.3.8

Dependencies ready!           
Success! Compiled 149 modules.

    Terminal.Main ───> index.html

./bin/index.js make --optimize src/Terminal/Main.elm  58.91s user 2.90s system 122% cpu 50.277 total
compiler % rm -rf guida-stuff 
compiler % time ./bin/index.js make --optimize src/Terminal/Main.elm
Dependencies ready!           
Success! Compiled 149 modules.

    Terminal.Main ───> index.html

./bin/index.js make --optimize src/Terminal/Main.elm  26.46s user 1.27s system 135% cpu 20.527 total

Line count for elm files on the project:

---------------------------------------------------------------------------------------
Language                             files          blank        comment           code
---------------------------------------------------------------------------------------
Elm                                    226          19974           2784          69340
---------------------------------------------------------------------------------------

Guida can already compile code on the browser as well (guida-lang.org/try), and with some extra work, it should also be possible to compile multi-file projects (not done yet).

As @passiomatic said, I am currently working on the format logic, to add it as a command, API, and to introduce it on the vscode-client. The focus is to have the required tools to be able to work on a guida project.

Tried Guida on a 150K LOC project, with a view to comparing compile times. I guess I will have to try something a bit smaller.

I noticed that you were using node v18.16.1, any chance you could try it with v23.10.0? If you still find issues, any chance you could create an issue with your finding? @G4BB3R any details you could share as well? If you have the opportunity to debug it (since this is just a node application, should be fairly simple to do), I would greatly appreciate it.

I would love to get some help on the projects within guida-lang project (bug fixes, new features, help with the documentation page for the website, or just simple bug reports). Feel free to reach out on slack as well.

5 Likes

I will try that, thanks.

1 Like

Guida seems most committed to breathing new life in to the language - what are likely to be first things that evolve?

1 Like

I tried guida again with node 24.5.0. This project is quite small at 8K LOC, but has a lot of dependencies (probably I don’t need them all). I think still too large?

Great that it can self compile though, and the compiler is 70K LOC which is a fair size. I will try that.

Starting downloads...

  ● elm/virtual-dom 1.0.3
  ● rtfeldman/elm-hex 1.0.0
  ● elm/regex 1.0.0
  ● elm-community/maybe-extra 5.3.0
  ● elm/parser 1.1.0
  ● elm/random 1.0.0
  ● elm/browser 1.0.2
  ● elm/json 1.1.3
  ● ianmackenzie/elm-triangular-mesh 1.1.0
  ● elm-community/easing-functions 2.0.0
  ● ianmackenzie/elm-float-extra 1.1.0
  ● rtfeldman/elm-iso8601-date-strings 1.1.4
  ● avh4/elm-color 1.0.0
  ● ianmackenzie/elm-interval 2.0.0
  ● elm-community/list-extra 8.3.1
  ● ianmackenzie/elm-1d-parameter 1.0.1
  ● folkertdev/elm-deque 3.0.1
  ● hecrj/html-parser 2.4.0
  ● elm/svg 1.0.1
  ● elm/time 1.0.0
  ● j-maas/elm-ordered-containers 1.0.0
  ● elm-community/array-extra 2.6.0
  ● elm/html 1.0.0
  ● ianmackenzie/elm-units-interval 2.3.0
  ● elm/url 1.0.0
  ● elm-community/json-extra 4.3.0
  ● elm/core 1.0.5
  ● the-sett/elm-animate 1.1.0
  ● the-sett/elm-pointer 1.0.1
  ● TSFoster/elm-tuple-extra 2.0.0
  ● ianmackenzie/elm-geometry-svg 3.0.0
  ● pablohirafuji/elm-markdown 2.0.5
  ● the-sett/elm-2d-camera 2.1.0
  ● the-sett/elm-update-helper 2.2.0
  ● elm-community/typed-svg 7.0.0
  ● lattyware/elm-fontawesome 5.0.0
  ● ianmackenzie/elm-units 2.9.0
  ● mweiss/elm-rte-toolkit 1.0.4
  ● rtfeldman/elm-css 16.1.1

<--- Last few GCs --->

[76882:0x1bf6a000]    46539 ms: Scavenge (interleaved) 4045.0 (4062.8) -> 4045.0 (4109.8) MB, pooled: 0 MB, 20.51 / 0.00 ms  (average mu = 0.169, current mu = 0.131) allocation failure; 
[76882:0x1bf6a000]    48714 ms: Mark-Compact (reduce) 4045.4 (4109.8) -> 4045.4 (4048.3) MB, pooled: 0 MB, 1939.10 / 0.00 ms  (+ 12.3 ms in 7 steps since start of marking, biggest step 5.0 ms, walltime since start of marking 1955 ms) (average mu = 0.151, 
FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
----- Native stack trace -----

 1: 0xf41253 node::OOMErrorHandler(char const*, v8::OOMDetails const&) [/home/rupert/.asdf/installs/nodejs/24.5.0/bin/node]
 2: 0x1388b50 v8::Utils::ReportOOMFailure(v8::internal::Isolate*, char const*, v8::OOMDetails const&) [/home/rupert/.asdf/installs/nodejs/24.5.0/bin/node]
 3: 0x1388c3f v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, v8::OOMDetails const&) [/home/rupert/.asdf/installs/nodejs/24.5.0/bin/node]
 4: 0x1621705  [/home/rupert/.asdf/installs/nodejs/24.5.0/bin/node]
 5: 0x1621732  [/home/rupert/.asdf/installs/nodejs/24.5.0/bin/node]
 6: 0x1621a2a v8::internal::Heap::RecomputeLimits(v8::internal::GarbageCollector, v8::base::TimeTicks) [/home/rupert/.asdf/installs/nodejs/24.5.0/bin/node]
 7: 0x1631f4a  [/home/rupert/.asdf/installs/nodejs/24.5.0/bin/node]
 8: 0x16362f0  [/home/rupert/.asdf/installs/nodejs/24.5.0/bin/node]
 9: 0x20c8ff1  [/home/rupert/.asdf/installs/nodejs/24.5.0/bin/node]
1 Like

That all worked nicely!

rupert@hunter:~/sc/github/guida-lang/compiler$ time ./bin/index.js make --optimize src/Terminal/Main.elm 
Dependencies ready!           
Success! Compiled 149 modules.

    Terminal.Main ───> index.html


real    0m23.354s
user    0m34.547s
sys     0m1.219s

1 Like

So I tried to build rtfeldman/elm-css with guida and it OOMed. This one is a package and about 64K LOC in size, so just a little smaller than the compiler.

I am thinking up to 70K LOC is about the maximum size guida can handle currently - although elm-css makes extensive use of phantom types and I wonder if that might be something to do with it?

Since most of my applications use elm-css it explains why even my smallest applications are not building.

guida make
Starting downloads...

  ● robinheghan/murmur3 1.0.0
  ● elm/virtual-dom 1.0.4
  ● elm-explorations/test 1.2.2

Dependencies ready!         
Compiling ...
<--- Last few GCs --->

[87244:0x380a0700]    23927 ms: Mark-sweep 4050.7 (4136.9) -> 4050.7 (4136.9) MB, 1260.9 / 0.0 ms  (average mu = 0.643, current mu = 0.082) allocation failure scavenge might not succeed
[87244:0x380a0700]    26553 ms: Mark-sweep 4066.4 (4136.9) -> 4066.4 (4168.9) MB, 2622.7 / 0.0 ms  (average mu = 0.324, current mu = 0.001) allocation failure scavenge might not succeed


<--- JS stacktrace --->

FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory
 1: 0xb09c10 node::Abort() [/home/rupert/.asdf/installs/nodejs/16.15.1/bin/node]
 2: 0xa1c193 node::FatalError(char const*, char const*) [/home/rupert/.asdf/installs/nodejs/16.15.1/bin/node]
 3: 0xcf8dde v8::Utils::ReportOOMFailure(v8::internal::Isolate*, char const*, bool) [/home/rupert/.asdf/installs/nodejs/16.15.1/bin/node]
 4: 0xcf9157 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [/home/rupert/.asdf/installs/nodejs/16.15.1/bin/node]
 5: 0xeb09f5  [/home/rupert/.asdf/installs/nodejs/16.15.1/bin/node]
 6: 0xec06bd v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) [/home/rupert/.asdf/installs/nodejs/16.15.1/bin/node]
 7: 0xec33be v8::internal::Heap::AllocateRawWithRetryOrFailSlowPath(int, v8::internal::AllocationType, v8::internal::AllocationOrigin, v8::internal::AllocationAlignment) [/home/rupert/.asdf/installs/nodejs/16.15.1/bin/node]
 8: 0xe848fa v8::internal::Factory::NewFillerObject(int, bool, v8::internal::AllocationType, v8::internal::AllocationOrigin) [/home/rupert/.asdf/installs/nodejs/16.15.1/bin/node]
 9: 0x11fd646 v8::internal::Runtime_AllocateInYoungGeneration(int, unsigned long*, v8::internal::Isolate*) [/home/rupert/.asdf/installs/nodejs/16.15.1/bin/node]
10: 0x15f20b9  [/home/rupert/.asdf/installs/nodejs/16.15.1/bin/node]
1 Like

It build elm-goemetry at 160K LOC without issue. That uses phantom types also, but only simple ones, not record phantoms like elm-css does. That might help to narrow down what is going on with elm-css.

1 Like

Thanks! We’ve already made several improvements by converging multiple tools into the compiler itself, making common tasks more convenient. For example:

  • guida init supports setting a package version

  • --yes flag to skip prompts

  • uninstall command for packages

  • guida test is implemented as part of the compiler

The current focus is to make sure we have the essential tools needed to develop in the language β€” that means building:

  • a working VSCode extension

  • which requires a language server

  • which in turn requires a formatting tool

Some related discussions and ideas:

You can find many more in guida/compiler issue tracker. Contributions are very welcome β€” even just surfacing known issues from elm/compiler, elm-format, elm-test, or elm-json that one would like to see addressed in Guida is already a helpful form of contribution.

3 Likes