ilusm.dev

emb

Shallow object merge and method utilities - merge two objects (B's keys overwrite A's), compose a merged object with self/ext references, look up a callable field by name, get a field with a fallback default, fill missing fields from a defaults object, and produce an immutable copy with one field changed.

Load with: use emb

What this module does

emb provides the small object manipulation helpers that are missing from the core language. The most used function is embsh, a shallow merge that combines two objects and returns a new one - equivalent to JavaScript's Object.assign({}, a, b). Keys in b overwrite keys in a.

embco extends this by storing references to both source objects under self and ext - useful for mixin-style composition. embme retrieves a callable field (function or fn-tagged value), which is handy when building dispatch or plugin systems. embde fills in missing keys from a defaults object without overwriting existing ones. embwi returns an immutable copy of an object with one field updated.

Quick example

use emb

a = {x: 1, y: 2}
b = {y: 99, z: 3}

# Shallow merge - b overwrites a
c = embsh(a, b)  # {x:1, y:99, z:3}

# Fill missing keys from defaults
d = embde({name: "alice"}, {name: "anon", role: "user"})
# {name:"alice", role:"user"}

# Immutable field update
e = embwi(a, "x", 42)  # {x:42, y:2}

# Get with default
v = embge(a, "missing", "fallback")  # "fallback"

# Compose (mixin)
m = embco(a, b)  # {x,y,z, self:a, ext:b}

# Retrieve a method
obj = {greet: \(msg) "Hi " + msg}
fn = embme(obj, "greet")
prn(fn("world"))

Functions

Merging

embsh(a, b)

Shallow-merges two objects. Copies all keys from a, then all keys from b (overwriting any shared keys). Returns the new merged object. Errors if either argument is not an object.

embco(base, ext)

Merges base and ext (ext wins) and additionally stores self: base and ext: ext on the result. Useful for mixin/compose patterns where you need access to the original objects.

embde(obj, defaults)

Returns a copy of obj where any key present in defaults but missing from obj is filled in. Existing keys in obj are never overwritten.

Field access

embge(obj, key, default)

Gets field key from obj. If the field is absent or throws, returns default[0] (the first element of the variadic default list) or nil if no default is given.

embme(obj, name)

Looks up field name on obj and returns it if it is callable (a function or a value with type tag "fn"). Errors via eru.bang if the field is missing or not callable.

embwi(obj, key, value)

Returns a shallow copy of obj with key set to value. The original object is not modified.

Notes

  • All merges are shallow - nested objects are copied by reference, not deep-cloned.
  • Requires trl and eru.