Both selectors and transforms modify the behavior of MSL expressions. The differences between them can be divided into functional and syntactic elements. Working together, they enable many capabilities of MSL in viewer applications.
Selectors are engine functions.
Selectors work at the level of the hybrid database. They determine how values are set and retrieved within each atom's subatomic namespaces. You can think of a selector as looking inside an atom.
Without a selector, an atom always returns its own value.
Transforms are viewer functions.
Transforms happen inside the viewer. They determine how an atom's values are displayed to the user. You can think of a transform as changing the appearance of an atom.
Without a transform, a return value is a plain text value.
The metadata selector is the most common selector. It selects inside the atom using the metadata key. Metadata, like all selectors, can be applied to an atom independently of the atom's value.
(@WALT Walt Disney)
(@WALT :birthday 1901)
(@WALT) ⇒ (@WALT Walt Disney :birthday 1901) ⇒ Walt Disney
(@DONALD Donald :gf (@DAISY Daisy) :nephs (@HUEY Huey) (@DEWEY Dewey) (@LOUIE Louie))
(@DONALD:nephs) ⇒ Huey Dewey Louie
(@HUEY) ⇒ Huey
(@WALT Walter Elias Disney)
(@WALT) ⇒ (@WALT Walter Elias Disney :birthday 1901) ⇒ Walter Elias Disney
(@WALT:birthday) ⇒ 1901
(@HUEY Howard)
(@DONALD:nephs) ⇒ Howard Dewey Louie
Line 3 shows that the definition of (@WALT)
has accumulated the metadata value from line 2.
Line 5 defines the (@DONALD)
atom and two pieces of metadata in the same expression. Line 6 shows that the :nephs
metadata exists in its own namespace. Line 7 shows that the (@HUEY)
atom also exists.
Lines 9 and 10 show that Walt's :birthday
metadata survived the change to his value, which was rewritten in line 9.
Lines 13 and 14 show that Donald's :nephs
metadata is correctly updated with the current value of (@HUEY)
.
Some people when confronted with a problem think, "I know; I'll use regular expressions." Now they have two problems.
—Jamie Zawinski
RegEx selectors or regular expressions can be used to further select inside a particular value from an atom or its metadata, or to quickly generate a short sequence from a long text value. When a regex selector is encountered, the engine returns the result of the regular expression as the value.
RegEx selectors serve several functions in MSL applications:
A regex selector can be used to validate the contents of an atom before further processing by the viewer.
(@no-bees There's bees in here. /(^[^bB]+)$/g) ⇒ NIL
(@no-bees There's none of those in here. /(^[^bB]+)$/g) ⇒ There's none of those in here.
Line 1 will not be processed by a viewer because it returns NIL
from the engine, indicating that the regex expression did not match (and that the supplied value did contain the letter b
or B
.)
A regex selector can be used to extract only the useful parts of a longer atom or metadata value. Once applied to the atom, the regex selector is preserved until the atom's value is changed.
(@CHICAGO Chicago, Illinois USA)
(@CHICAGO /[^,]+/) ⇒ Chicago
(@CHICAGO) ⇒ Chicago
(@CHICAGO Chicago, The Windy Cindy) ⇒ Chicago, The Windy Cindy
Line 2 shows the application of the regex selector, which matches everything before the comma.
Line 3 shows that the regex selector is preserved for later invocations of (@CHICAGO)
.
Line 5 shows that changing the atom's value removes the regex selector.
When followed by a value, a regex selector performs a search and replace function and returns the original value with the match(es) replaced by the value following.
(@old-book Spain's currency, the peseta, is accepted nationwide. /peseta/ euro) ⇒ Spain's currency, the euro, is accepted nationwide.
(@story Mary married Geroge in 2001. Geroge had a son from a previous marriage.)
(@story /Geroge/g George) ⇒ Mary married George in 2001. George had a son from a previous marriage.
Line 1 shows how outdated text can be updated with a regex selector's search and replace. The same regex selector can be applied to a view, stream, world, or machine.
Line 4 shows how a regex selector can record a spelling or typo correction using the /g
global regex-env
or flag.
When two or more regex selectors occur in sequence, their resulting values are curried in a chaining operation. This can serve as a higher level "capture group" in sequencing regular expressions.
(@part-number 747-8i:2707v14r)
(@part-number :aircraft-family (@part-number) /[^:]+]/ /[^-]/) ⇒ 747
(@part-number :revision (@part-number) /:[0-9]{4}/) ⇒ v14r
Regex selectors (and other selectors) can be used to abstract over an embedded atom, meaning that they can apply changes to the current value of the embedded atom.
(msl abstract-over-embed Abstracting a regex selector over an embedded atom)
(@WALT Walt Disney)
(@WALT :birthplace Baton Rouge, LA) --> Baton Rouge, LA
(@WALT :city (@WALT :birthplace) /[^,]+/) --> Baton Rouge
(@WALT :birthplace Chicago, IL) --> Chicago, IL
(@WALT :city) --> Chicago
In line 4, the value of Walt's :city
becomes the current value of his :birthplace
with the regex selector applied. As long as this value assignment doesn't change, the regex is preserved. This allows the regex selector for :city
to abstract over a new value of (@WALT:birthplace)
.
In line 5, Walt is assigned a new :birthplace
. In line 6, his :city
reflects the application of the regex selector to the current value.