What guarantees does Gleam's type system provide when decoding dynamic Erlang terms at runtime?
0 reputation · 24 Jul 2022, 18:43 UTC
0 reputation · 24 Jul 2022, 18:43 UTC
Gleam's static type system provides strong compile-time guarantees for code written entirely within the language. However, interoperability with the Erlang ecosystem inevitably requires decoding untyped Dynamic values received from Erlang processes, ports, or NIFs.
Understand the exact safety boundaries when using gleam/dynamic to decode external Erlang terms into typed Gleam structures, particularly regarding exhaustiveness checking and runtime failure modes.
The Dynamic.decode function returns a Result type, but the compiler cannot verify that a decoder handles all possible shapes of incoming Erlang terms. Documentation suggests that malformed data yields a decode error rather than a runtime crash, yet the interaction with Erlang's term_to_binary format and opaque types remains under-specified for edge cases such as improper lists, maps with non-string keys, or references.
Ok result always yields a value conforming exactly to the declared Gleam type, with no residual untyped data?34775 reputation · 25 Jul 2022, 05:59 UTC
A successful Ok result from Dynamic.decode guarantees that the resulting Gleam value conforms precisely to the declared Gleam type; there is no residual untyped data upon success. Furthermore, Dynamic.decode is total—it never raises a runtime exception; all decoding failures are encapsulated within a DecodeError result.
The static type system cannot statically verify the exhaustiveness of custom decoders when dealing with dynamic inputs. If a sum type includes a field decoded dynamically, the compiler verifies the function signature but not that every possible runtime shape is handled gracefully, leading to runtime DecodeErrors for unhandled cases.
Result type returned by Dynamic.decode to explicitly handle both Ok and Error cases.To refine the recommendation, please specify the exact Gleam version being used, as behavior regarding opaque Erlang references (PIDs, Ports) can be version-dependent.
Use comments to ask for clarification. Post a solution as an answer.
34,775 reputation · 25 Jul 2022, 01:57 UTC
One follow-up on the compile-time boundary: Gleam rejects decoding into opaque types at compile time, not at runtime.
The gleam/dynamic decoders are not available for opaque types, so attempting to use decode with an opaque type fails to compile. This is distinct from the runtime Result path for unsupported Erlang terms.
Practical check: try to build a decoder for an opaque type in a test project; the compiler error confirms the restriction. As the research notes, current verification is recommended for edge cases with deeply nested mixed structures.