List of all Elm kernerl functions

A list of all Elm kernel functions:

Might be useful as a checklist if anyone was to attempt some porting of the Elm kernel to a different platform for example.

10 Likes

Well done Rupert! There are some other Elm Kernel functions on elm-explorations/* packages:

I always wondered what happens if we upgrade Elm Kernel functionality from ES3/ES5 to ES6! Since ECMAScript 2015 is widely supported in all major browsers, what are the performance and security optimizations this kind of updating Kernel code achieves?

2 Likes

Having worked quite a bit on Elm’s Kernel code, I would say that ES6+ would provide … nothing! Mostly. (I’d love to be proven wrong, though.)

  • Performance: If anything, I’d expect worse performance. ES5 is optimized to oblivion, while ES6+ is still being worked on. The TypeScript compiler switched from let/const back to var for performance: Using `var` in limited contexts to avoid runtime TDZ checks Ā· Issue #52924 Ā· microsoft/TypeScript Ā· GitHub
  • Security: I haven’t heard of or thought of ES6 features in the context of security. Do you have an example in mind?
  • Convenience: Writing a big app in ES5 would be tedious compared to ES6+. But writing a bit of Elm Kernel code in ES5 isn’t that bad.

But there’s at least one feature from ES6+ that Elm could benefit from: Regex unicode mode! I would love to have that available.

Then there’s the Temporal API that I think would be a great fit for Elm. I’m more excited about Elm using new API:s, than new syntax under the hood.

8 Likes

I have added all the elm-explorations ones to the sheet as well - adds another 115. Most of them in elm-explorations/linear-algebra.

Command used to extract all Kernel function calls from Elm code is:

find . -name "*.elm" -exec grep -hoE 'Elm\.Kernel\.[^[:space:]]+' {} + | sort -u
3 Likes

It’s slightly off-topic, but if someone would like to transpile Elm code, I’ve created bytes decoders for elmi/elmo files : GitHub - Warry/elm-stuff: Decode interfaces (.elmi, i.dat) and objects (.elmo, o.dat) from elm-stuff/

I started but never finished a JS generator based on it, but the kernel part was a nightmare and it kind of discouraged me.

edit: published: Warry/elm-stuff/

5 Likes

Warry/elm-stuff/

It’s great!
It worth a dedicated post and also a more detailed example on how to use it.

EDIT: currently, I implemented this, but I’m not sure what to do with the result :slight_smile:

:high_voltage: Performance Considerations

  • Improved Modularity and Tree Shaking: ES6 modules (import/export) enable better bundling and tree shaking, reducing bundle size and improving load times. This leads to faster initial page loads and more efficient caching.

  • Better Memory Management: ES6 features like let and const reduce memory leaks by limiting variable scope compared to ES5’s var.

  • Async/Await Enhancements: Replacing ES5 callbacks with ES6 async/await improves readability and reduces callback hell, which can indirectly enhance performance by simplifying control flow.

:locked_with_key: Security Considerations

  • Strict Mode by Default: ES6 modules enforce strict mode automatically, helping catch common coding errors and preventing unsafe actions like accidental global variable creation.

  • Reduced Global Scope Pollution: ES6 modules encapsulate code, minimizing exposure to global scope and reducing the risk of variable collisions or unintended overrides.

  • Better Encapsulation: Features like closures promote encapsulation, making it harder for malicious code to tamper with internal logic.

These are some basic improvements over ES5 design which I’m pretty sure about. So, it might be more than … Nothing!

Oh, I replied to a bot. Sneaky! Never mind then.

1 Like

You asked for some resolution about my initial question, and after 3 days of basic research and a consice answer, you call me a Bot! That’s not an appropriate behavior in Elm community, Simon …

it opens up meta programming if you’re ambitious. for example, from interfaces you could generate JSON encoders/decoders, or generate typescript type definitions.

Also, I have a problem with a large Elm program which takes a long time and a lot of memory to compile. I think I’ve narrowed the problem down to large .elmi files, which I think is related to the compiler expanding out all record field types. Coincidentally I recently posted about this on my blog: Elm compilation time with large records | Allanderek's blog

So I think I can possibly make use of this package to further inspect the .elmi files and possibly even come up with a plan to reduce the compilation time. I’ve had some success by making some of the record types opaque (because then they are not expanded), but it’s surprisingly difficult to figure out which records would be best to opaquify (if I’m allowed to make up verbs). It feels like there will definitely be some objective criteria (and hence some algorithm) which would report the ā€˜best’ records to opaquify.

All of this is to say this (Warry/elm-stuff) is a cracking package and I agree with setop it deserves a post of its own.

Great post!

Here’s another thread that also talks about using opaque types to improve compilation speed: Improving Compilation time: Insights from Elm Compiler Internals

I talked to someone at Elm Camp 2025, who said that in a project they work on, they have this convention of having Types.elm files which expose everything, which makes the problem worse since basically all record types are exposed then (and end up in .elmi files). And changing a Types.elm file causes a lot of unrelated files to need re-checking. So that could potentially be something to look into, too.

1 Like

Great thanks! I’ll look into both of these, I do not have that Types.elm convention, but nevertheless it might be that I can avoid exporting something that I do (though I use elm-review to avoid that).

About a possible improvement by using es6, my friend who was investigating Closures in recursive calls get shadowed, causing stack overflows Ā· Issue #2017 Ā· elm/compiler Ā· GitHub said that he can fix it cleanly if he can use let.
This bug is kind of patched up on GitHub - Zokka-Dev/zokka-compiler: Fork of compiler for Elm, a functional language for reliable webapps. , but on that implementation, I heard it creates closure on every iteration to hide var from outside of the loop created by tail call optimization, which slows down all the tail calls. So, if we can use let, we can avoid creating closures, which should improve performance significantly compared to the patch.

2 Likes

Against our intuition, the problematic part is encoding type aliases to elmi, so, wrapping the blobbed type in just a sum type instead of opaque type also fixes the problem.

Yes, sorry you’re correct, I used the wrong term, I meant custom type/sum type it doesn’t have to be opaque at all. The distinction is really between structural and nominal types, but in Elm custom types are always nominal and record types are structural. A custom type is never expanded to its variants whether or not its variants are hidden within a module which doesn’t export them. The reason for this is that the application of a variant constructor always produces a single nominal custom type (though it may of course be parameterised). Similarly there is no sub-typing in custom types as there is with record types (extensible records). So when type inference compares (unifies) two custom types it only ever needs to consider their names, not the structure of those types since if the names are same then the structure is the same, but that’s not true for record types.

I think there is an interesting avenue to explore in making both custom types and record types structural by default and nominal when made opaque through a module boundary. I discuss this in this blog post.

3 Likes

Late to the party but I second everything @lydell said.

ES5 remains the best compilation target if you’re not writing the JS.

I will at least give him service and write this for a record.

  • Improved Modularity and Tree Shaking:
    not for elm where code generation does all the possible tree-shaking that could happen while it’s generating JS. Doing any extra pass has cost for no benefit.

  • Better Memory Management
    JS is garbage collected language. Lifetime of a identifier has nothing to do with lifetime of a memory. Further VM optimizations work based on own analysis and can optimize things out of scope (closure) even if semantically they should be availabe but provably they are not used. var was function scoped while const and let are block scoped. In elm you don’t even have blocks only functions so even if there would be some novel runtime implementation taking this to account I don’t see how this could be any benefical for elm.

  • Async/Await Enhancements:
    Async and await are syntax sugar for generators. Elm doesn’t even use generators because it has different concurrency model. But even than generators are just a form of continuations like callbasks are CSP based in the VM. async await is just syntax suggar. So there are no benefits to generating those to be found.

  • Strict Mode by Default
    Elm doesn’t compile to modules - it has own module system

  • Reduced Global Scope Pollution:
    same as above

  • Better Encapsulation:
    closures are in JS since first version and elm uses those to implement lexical scopes.

Computers are not magic. Buzzwords don’t work as magic spells.

The reason why someone does call someone else a ā€œbotā€ perhaps can have something to do with someone using LLMs to generate AI slop and then expect real humans with better things to do to spend their time reacting to it. The problem here is the asymmetry of the effort. People are more than willing to help others but also they have better thing than to argue with text generators.

And for the hot take. I prefer to write ES5 even by hand compare to ES6 which covers every concept by layer of obfuscating syntax sugar.

1 Like