Answering the Question Directly
The PureScript compiler turns a row‑polymorphic record field access into a straight JavaScript property read. For a function like:
foo :: forall r. { name :: String | r } -> String
foo rec = rec.name
the generated code is essentially:
function foo(rec) {
return rec.name;
}
—no helper functions, no dictionary lookups, and no runtime cost that grows with the number of extra fields in the record. The compiler inlines the access when the record is passed as a single argument and is not aliased or mutated.
How the Compiler Achieves It
- Row polymorphism is represented by a type variable (e.g.
r) that the compiler tracks at compile time.
- During type checking, the compiler records the exact field name that must exist (e.g.
name) and guarantees that the value is present.
- When emitting JavaScript, the compiler emits a direct property access (
rec.name) instead of a generic lookup helper.
- If the record is immutable and not captured in a closure, the compiler may further merge consecutive accesses, eliminating repeated reads.
Consistent Lookup Overhead?
Because the generated code is a simple property read, the cost is constant regardless of how many additional fields the record contains. The only variance comes from whether the compiler can inline the access:
- Inlined access:
obj.name – constant O(1) cost.
- Non‑inlined (e.g., through a higher‑order function that captures the record): a small function‑call overhead, but still independent of the record’s size.
What to Check in Your Project
- Compile with
purs compile --profile and inspect the emitted .js to confirm that field accesses are direct.
- Run a micro‑benchmark that performs a large number of lookups (e.g., 1,000,000 iterations) and compare the runtime with a version that uses a non‑polymorphic record type.
- Ensure records are not mutated (e.g., via lenses or
Object.assign) and are passed directly to functions that use the fields.
Missing Diagnostic Detail Needed
To give a precise recommendation for your code base, could you confirm whether the record is ever passed through a higher‑order function or mutated after creation? This affects whether the compiler can inline the access.