External function runtime checks #5985
Replies: 2 comments 7 replies
-
|
I'm a little unclear what this is protecting me from or what problem this is intended to solve. It looks like these runtime checks would only save me in instances where both the following are true:
To take the example already given: // example.gleam
@external(erlang, "wibble", "wobble")
@external(javascript, "wibble", "wobble")
pub thingy(id: Int, name: String, items: List(String)) -> NilThis external function has annotated types – as it must for externals in Gleam. That means I cannot, in my gleam code, call: thing("hello", -123.4, <<>>)So the proposed runtime checks would only help me prevent mistakes when i do something like: // whoopsie.mjs
import { thingy } from './example.mjs'
// proposed runtime checks could catch this.
thing("hello")This seems like an incredibly niche case. I can see a stronger argument for all public functions having these runtime checks in a development mode, but limiting it to just externals seems far too specific to be useful. |
Beta Was this translation helpful? Give feedback.
-
|
One thing I often want to do with a library or application is to benchmark various approaches to see how I can improve performance. I would usually do this by writing some code in a test or dev module. If we always enabled development mode for test and dev, this would lead to misleading benchmarks due to the additional FFI checks. I suppose we would want to have some way to enable production mode for this purpose, to get a more accurate representation of code speed in the production environment. Also you didn't mention this explicitly, but I assume |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
External functions are the main area in Gleam where the compiler is unable to help you catch mistakes; Any time you are writing external functions you just have to make sure that you are using the correct runtime values for the types you have specified the functions takes and receives. This often results in mistakes.
To help with this we when an external function is defined we could generate code that checks they are correct at runtime.
Traversing lists each time they go through FFI would be expensive, so the list is only checked shallowly.
This example uses prelude types, but custom types could be checked too. The depth to which they should be checked I am unsure of. Perhaps it could traverse through any nested custom types with only a single variant, as those values cannot be recursive and so have a constant size.
External types have unknown runtime representation, so it is impossible to generate checks for them.
I thought these checks would be useful for catching mistakes in development and in tests, but wouldn't be desired in production due to their (slight) runtime cost and increase in code size. To control this would could expose the production compile mode in the tooling's public API by adding a
--productionor such flag togleam runandgleam build.gleam exportwould continue to use production mode, andgleam devandgleam testwould continue to use dev mode.What do you think?
Beta Was this translation helpful? Give feedback.
All reactions