Syntax Reference
Records and Patterns
Eve represents data as attribute-value pairs called records. They can have many attributes and attributes can have many values. |
```
commit
[tag: "person" age: 30, name: "Jeff"]
[tag: "boat" tag: "expensive" type: "yacht"]
```
|
The tag attribute is used to indicate the type of a record. #foo is short for tag: "foo" . |
```
search
[#person] = [tag: "person"]
```
|
You can alias an attribute to a different name like age: person-age . Without an alias, the name of the attribute is bound to its value. |
```
search
// These do the same thing.
person-age = 20
[#person age: person-age]
age = 20
[#person age]
```
|
Records can be nested to find or create relationships.
Note: All records in Eve are global. The Ryan record can still be matched on its own. |
```
commit
[#person name: "Chris" brother:
[#person name: "Ryan"]
[#person name: "Jeff" age: 20]]
```
|
Attributes can also be accessed using dot notation. |
```
search
person = [#person]
person.brother = [name: "Ryan"]
```
|
You can search for records by pattern. Eve will match records based on the pattern of attributes you provide. Any attributes you don’t provide a value for will be filled in from the matches. |
```
search
me = [#person brother]
bind
[#my-family me relative: brother]
```
|
Program Structure: Search, Bind, and Commit
Eve programs are markdown documents, with code blocks fenced between three grave (` ) or tilde (~ ) characters. In each block you (optionally) search for patterns, then either bind or commit new or updated records for each match found.
Note: With no search, the records are automatically added once. |
# An example Eve program
```
search // Find something interesting
[#person name]
bind // Do something with it
[#ui/text text: name]
```
|
The search section finds records matching its patterns, staying up to date as data changes.If there aren’t any matches, the bind or commit will do nothing. |
```
search
person = [#person name: "Jeff"]
person.age = 20
```
|
The bind section creates or updated records from your pattern. Since this is a bind , when the search stops matching, those records or updates disappear. |
```
search
person = [#person name: "Jeff" age]
bind
[#my-age age]
```
|
Like bind , the commit section creates or updates records. Unlike bind , it does so permanently.If the search stops matching, the records will remain. |
```
search
[#html/event/click element]
commit
[#ui/text text: "You clicked on {{element}}!"]
```
|
Equivalence and Filtering
Eve has equivalence instead of assignment. Instead of setting Jeff’s age to 20, equivalence causes us to only find the people whose age is 20. |
```
search
// Filter for people named "Jeff" who are 20 years old.
person = [#person name: "Jeff" age]
age = 20
```
|
Nothing can be equivalent to two different values at once. |
```
search
// Something that always fails.
x = 10
x = 100
```
|
Using the same variable in two patterns will find pairs where the value is the same. |
```
search
// pairs of boats and people with the same age.
person = [#person age]
boat = [#boat age]
bind
[#ui/text text: "{{person.name}} has an old boat"]
```
|
You can also filter using inequalities. |
```
search
// Filter within an attribute.
cube = [#rectangle width > 30 height]
height > 30 // Filter a variable.
cube.depth > 30 // Filter with dot notation.
```
|
Not
You can check for the absence of any matching record for a search by wrapping it in not() . |
```
search
// People who are not employees.
person = [#person]
not(person = [#employee])
```
|
If…Then and If…Else
If
lets your block try multiple branches for a variable. If every branch has no matches, the block fails.
If … else lets you express ordered choice. Only the first branch with matches will contribute values to the variable. |
```
search
[#todo filter]
switch = if filter = "completed" then 1
else if filter = "active" then 2
else if filter = "all" then 3
```
|
Multiple If statements without else let each branch contribute to a variable (equivalent to union). |
```
search
// All my friends and their spouses are party guests.
guest = if f = [#friend] then f
if [#friend spouse] then spouse
```
|
If can return multiple values each.
Note: Each branch must return the same number! |
```
search
(pts, pass) = if score > 90 then (3, "true")
if score > 70 then (1, "true")
else (0, "false")
```
|
Functions and Aggregates
Functions are record-like constructs that return values. |
```
search
// The sin function with input in degrees.
x = sin[degrees: 30]
// …or radians
x = sin[radians: 3 * π / 180]
```
|
Aggregates return a value (or value per group) for all matches of your search (akin to reduce() in other languages). Eve will set collapse inputs to an aggregate. That is, if you have 5 unique salary levels for 100 employees, Eve would add each unique salary once. To adjust this, specify the actual identity (employee) you care about with for . To get a value per group, specify the grouping variables with per . |
```
search
// *for* specifies the matches to count.
total-employees = gather/count[for: employee]
// *value* is the number to add to the sum
// *per* specifies the groups to sum the matches in.
budgets = gather/sum[value: employee.salary,
for: employee,
per: employee.department]
```
|
Update Operators
Besides creating new records, Eve has four operators to modify existing records in bind
or commit
.
(+= ) Add value to attribute. |
```
search
chris = [#chris]
commit
chris.likes += "pizza"
```
|
(-= ) Remove value of attribute.
Note: An attribute with no values ceases to exist. |
```
search
chris = [#chris]
commit
chris.likes -= "eggplant"
```
|
(:= ) Set value of attribute.
Set is the same as removing the current value(s) and adding the new value(s). |
```
search
chris = [#chris]
commit
chris.age := 30
```
|
(<- ) Merge pattern into record.
Attributes from the pattern on the right overwrite those of the record on the left. |
```
search
chris = [#chris]
commit
chris <- [eye-color: "green", hair-color: "brown"]
```
|
The set operator with the special value none deletes entire attributes and records.
Note: This should usually be done in commits. |
```
search
chris = [#chris]
commit
chris.likes := none
chris := none
```
|