Inspection
Five builtins for asking values about themselves. len counts, type labels, keys and values unpack objects, has checks membership. They work uniformly on strings, arrays, and objects — the same call gives the right answer regardless of shape.
len — count anything countable
Strings, arrays, objects all work
len(value) returns the size. For strings it's the byte length, for arrays the element count, for objects the key count. Calling it on a number, bool, or null is an error — use the value directly if that's what you want.
<p> [len('abc')]
<p> [len(items)]
<p> [len(person)] string: 3
array: 3
object: 2
type — the runtime kind
One of: null, bool, int, float, string, array, object, function
type(value) returns the kind as a string. Useful for branching on shape in a function that accepts a few possibilities. Note int and float are distinct — the server tier preserves the distinction even though they're both number in the browser.
<p> [type('hi')]
<p> [type(42)]
<p> [type(3.14)]
<p> [type(true)]
<p> [type(items)]
<p> [type(person)]
<p> [type(null)] 'hi' → string
42 → int
3.14 → float
true → bool
items → array
person → object
null → null
keys — list the field names
Insertion order, as written in the source
keys(obj) returns the field names in the order they were declared. Pair with in keys(obj) to iterate. Calling it on an array returns the integer indices as strings.
<p> [keys(person)]
<ul>
[k] in keys(person)
<li> [k] [first, last]
- first
- last
values — list the field values
Same order as keys; pairs by index
values(obj) returns the values in the same order keys would. Zip them together when you need [k, v] pairs.
<p> [values(person)] [Grace, Hopper]
has — membership test
true / false; works on objects, arrays, strings
has(obj, name) returns whether the key exists on the object. On arrays it tests element membership; on strings it tests substring presence. contains is its alias for arrays and strings — use whichever reads better in context.
<p> [has(person, 'first')]
<p> [has(person, 'age')]
<p> [has(items, 'pears')]
<p> [has('hello world', 'lo wo')] person.first exists? true
person.age exists? false
items has 'pears'? false
'hello world' has 'lo wo'? false
Putting them together
A generic dispatch table by type
Combine type with a guard chain to render different markup per kind. The same trick works for sanitising user input or normalising heterogenous data into a uniform shape before storage.
> render_value[v]
(type(v) == 'array')
<ul>
[x] in v
<li> [x]
(type(v) == 'object')
<dl>
[k] in keys(v)
<dt> [k]
<dd> [v[k]]
(else)
<p> [v] Next: Strings — case, trim, split, join, replace, padding, and friends.