diff --git a/404.html b/404.html deleted file mode 100644 index e69de29..0000000 diff --git a/CNAME b/CNAME deleted file mode 100644 index e825467..0000000 --- a/CNAME +++ /dev/null @@ -1 +0,0 @@ -docs.witheve.com \ No newline at end of file diff --git a/README.md b/README.md index 408a316..4399a72 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ +

Eve logo

@@ -8,6 +9,10 @@ You can learn more about Eve here: http://witheve.com/ +You can play with Eve here: http://play.witheve.com + Eve is under active development here: https://github.com/witheve/Eve +## Contributing +There's a lot of work to be done on the documentation, so this is a great place for beginners to get started with Eve. From fixing typos to adding examples, work needs to be done across the board here. Check out the [issues](https://github.com/witheve/docs/issues) for a place to start, as they have been raised already as points of improvement by the community. If someone is already assigned and the issue has been aroud a while, check to see if it's being worked on before starting it yourself. Or, if you find an issue yourself, please report it so others know it exists. Thank you! diff --git a/fonts/icon.eot b/fonts/icon.eot deleted file mode 100644 index 8f81638..0000000 Binary files a/fonts/icon.eot and /dev/null differ diff --git a/fonts/icon.svg b/fonts/icon.svg deleted file mode 100644 index 86250e7..0000000 --- a/fonts/icon.svg +++ /dev/null @@ -1,22 +0,0 @@ - - - -Generated by IcoMoon - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/fonts/icon.ttf b/fonts/icon.ttf deleted file mode 100644 index b5ab560..0000000 Binary files a/fonts/icon.ttf and /dev/null differ diff --git a/fonts/icon.woff b/fonts/icon.woff deleted file mode 100644 index ed0f20d..0000000 Binary files a/fonts/icon.woff and /dev/null differ diff --git a/guides/dsl.md b/guides/dsl.md new file mode 100644 index 0000000..bce34d1 --- /dev/null +++ b/guides/dsl.md @@ -0,0 +1,319 @@ +# Eve JavaScript/TypeScript DSL + +The forthcoming v0.3 release of Eve supports a domain specific language (DSL) that interacts with the Eve runtime, allowing you to intermix Javascript and Eve code. There are several benefits to using the DSL: + +1) The syntax is native Javascript, so if you know JS you can write in the DSL +2) You can interact with Javascript functions and libraries +3) The DSL can be used "a la carte", so you can use as much of Eve as you need to for your project. Thus you can write an entire application in Eve, just use it as a datastore, or anywhere between. This makes it easy to integrate Eve with an existing Javascript application. +4) You can easily import data into Eve. If you can get your data in Javascript, you can use it in Eve. + +This DSL guide is for users who are already familiar with Eve semantics. For those new to Eve, we'll have more fundamental guides released in the near future. + +## Summary of DSL + +| | JavaScript/TypeScript DSL | Eve | +|-----|---------------------------|-----| +| find a record | `find("person", {salary})` | `[#person salary]` | +| bind/commit a record | `record("person", {salary})` | `[#person salary]` | +| not | `not(() => person.salary)` | `not(person.salary)` | +| choose | `choose(() => { person.salary; return 1; }, () => 0)` | `if person.salary then 1 else 0` | +| union | `union(() => person.salary, () => person.wage)` | `if person.salary then person.salary if person.wage then person.wage` | +| Add a value | `person.add("salary", 10)` | `person.salary += 10` | +| Remove a value | `person.remove("salary, 10)` | `person.salary -= 10` | +| Set a value | `person.remove("salary").add("salary", 10)` | `person.salary := 10` | +| Remove an attribute | `person.remove("salary")` | `person.salary := none` | +| Remove a record | `person.remove()` | `person := none` | +| functions | `lib.math.sin(number)` | `sin[degrees: number]` | +| aggregates | `gather(person).per(person.dept).count()` | `count[given: person, per: person.dept]` | + +## Using the DSL + +This guide is written for ES6. For added readability, we make frequent use of [destructuring][1] and [arrow functions][2]. We recommend using TypeScript 2.1.0 or later. + +[1]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment +[2]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions#Arrow_functions + +To use the DSL, import it into your application. + +```javascript +import {Program} from "witheve"; +``` + +Then you instantiate a new Eve program, naming it however you want. + +```javascript +let program = new Program("program name"); +``` + +Writing DSL code is similar to writing native Eve code; you attach blocks to the `program`, which search for records and then return records. Blocks in the DSL operate as a either a `bind` or `commit`. Let's look at the DSL block syntax in the case of `bind`: + +```javascript +program.bind("block description", ({find, record}) => { + // search for records tagged "person" + let person = find("person"); + return [ + // bind a record tagged "greeting" with an attribute "message" + record("greeting", {message: `Hello ${person.name}`}) + ]; +}); +``` + +The equivalent Eve block would be + +```eve +search + person = [#person] + +bind + [#greeting message: "Hello {{person.name}}"] +``` + +The identity of a `record()` is established by everything within the parentheses. Therefore, the record ``record("greeting", {message: `Hello ${person.name}`})`` will create one record for every `person.name`. + +If you would like to commit records instead of binding them, you can use the `commit()` method in place of `bind()`. The implication here is that you can no longer create blocks which both commit and bind records at the same time. + +The DSL supports methods which mirror a couple of the Eve update operators. They are: + +### add() + + Adds attribute/value pairs to a record. These added values do not contribute to the identity of a record, allowing you to add multiple values to a single record. This is equivalent to the Eve `+=` operator. For example: + +```javascript +program.bind("Invite classmates to my party", ({find, record}) => { + // search for records tagged "friend" + let student = find("student"); + return [ + // bind a single record tagged "guest-list", with every student as a guest + record("guest-list").add({guest: student}) + ]; +}); +``` + +### remove() + +Removes attribute/value pairs from a record. This is equivalent to the Eve `-=` operator. Remove should only be used in the context of a `commit` block. For example: + +```javascript +program.commit("blacklisted people cannot come to the party", ({find, record}) => { + let blacklisted = find("blacklisted"); + let guests = find("guest-list") + return [ + // remove anyone blacklisted from the guest list + guests.remove({guest: blacklisted}) + ]; +}); +``` + +You can also use `remove()` to completely delete records or attributes on a record. This is equivalent to `:= none` in Eve. For example: + +```javascript +// completely remove the target record +record.remove() +// remove the attribute on the target record +record.remove("attribute") +``` + +The DSL does not contain an equivalent for the Eve set operator `:=`, but you can mimic its behavior by chaining the `add()` and `remove()` operators. For example: + +```javascript +program.bind("Reassign Artemis' teacher", ({find, record}) => { + let artemis = find("student", {name: "Artemis"}); + let teacher = find("teacher", {name: "Smith"}); + return [ + artemis.remove("teacher").add("teacher", teacher) + ]; +}); +``` + +## Sub-Blocks + +In the DSL `not()`, `union()`, and `choose()` are sub-blocks, which have their own body. Let's look at each of these. + +### not() + +The `not()` sub block works similarly to `not()` from the Eve syntax; it performs an anti-join on the records inside and outside of the `not()`. To use not, include it in the parameter list at the beginning of the block. + +```javascript +program.bind("Tag students without any citations.", ({find, record, not}) => { + let students = find("student"); + not(() => { + find("student", {citation}); + }); + return [ + students.add("tag","good-standing") + ]; +}) +``` + +### choose() + +Choose() and union() expressions are behind the mechanics of the if expression in the Eve syntax. In the DSL, we expose these directly. First, `choose()` takes a list of sub-blocks, which contain any valid Eve code to join, filter, or compute their results. Each sub-block is executed in order until one is found valid. This return value of the first valid sub-block is taken as the return value. + +```javascript +program.commit("Assign a letter grade.", ({find, choose}) => { + let student = find("student"); + let [grade] = choose( + () => { student.grade >= 90; return "A"; }, + () => { student.grade >= 80; return "B"; }, + () => { student.grade >= 70; return "C"; }, + () => { student.grade >= 60; return "D"; }, + () => "F" + ) + return [ + student.add("letter-grade", {grade}), + ]; +}); +``` + +### union() + +Similarly, `union()` takes a body of sub-blocks, but the return for each valid sub-block (instead of just the first as with `choose()`) is taken as the return for the union. One common use of union is to normalize records from different data sources. + +```javascript +program.bind("display the student's full names", ({find, record, union}) => { + let east = find("student", {school: "West HS"}); + let west = find("student", {school: "East HS"}); + let [fullName] = union( + () => { east.name; return east.name}, + () => { west.firstName; return `${{west.firstName}} ${{west.lastName}}`}, + ); + return [ + record("html/element", {tagname: "div", text: fullName}), + ]; +}); +``` + +### Functions + +The standard library in Eve has been redone in the DSL. To use library functions, you must now bring in "lib" explicitly when defining your block. From lib you can access the various standard library functions supported by the runtime so far. + +```javascript +program.bind("display the student's full names", ({find, record, lib}) => { + find("angle" degrees) + let result = lib.math.sin(degrees) + return [ + record("html/element", {tagname: "div", text: result}) + ]; +}); +``` + +for now you can find a list of functions in [src/runtime/stdlib.ts](https://github.com/witheve/Eve/blob/refactor-editor/src/runtime/stdlib.ts) + +The interface for wrapping functions for use within Eve is also revamped for the new runtime. When writing a function wrapper, you must ensure that the function is reverentially transparent, meaning given the same input, the function returns the same output. + +Functions are wrapped using `makeFunction()` e.g.: + +```javascript +makeFunction({ + name: "math/sin", + args: {a: "number"}, + returns: {result: "number"}, + apply: (a:number) => { + return [Math.sin(a/180 * Math.PI)]; + } +}); +``` + +### Aggregates + +Aggregates like `sum()`, `count()`, and `sort()` are accessed through the `gather()` function. This function defines the input set to the aggregate. You can optionally group the input set with the `per()` function. For example, here is `count()` at work: + +```javascript +program.bind("count the number of students in each class", ({find, record, gather}) => { + let student = find("student") + let classSize = gather(student).per(student.teacher).count() + return [ + record("html/element", {tagname: "div", text: `${student.teacher} ${classSize}`}) + ]; +}); +``` + +The input set to the `count()` aggregate is the student records, and they are groups according to their teacher attribute. Then, the size of each group is counted and returned in `classSize`, which has the same number of elements as there are teachers. + +Aggregates can take arguments as well. For instance, `sort()` takes as arguments the direction by which to sort the input set. Here is `sort()` in use: + +```javascript +program.bind("sort the students by last name, then first name per teacher", ({find, record, gather}) => { + let student = find("student") + let ix = gather(student.firstName, student.lastName).per(student.teacher).sort("up", "down") + return [ + record("html/element", {tagname: "div", sort: ix, text: `${student.firstName} ${student.lastName}`}) + ]; +}); +``` + +## Importing and Exporting Records + +### Getting Data Into Eve - `inputEAVs()` + +You can import raw EAVs into Eve with the `inputEAVs()` function. Currently, `inputEAVs()` mut be called at least once to initialize your program, and it can only be used after you define all blocks. These limitations will be lifted in future versions. + +`inputEAVs()` takes as input a list of entity, attribute, value triples. The entity value identifies the record to which the attribute and value belong, so it must be unique to that record. For example: + +```javascript +program.inputEAVs([[0,"tag","person"], [0,"name","Archibald"]]); +``` + +This will create a record tagged "person" with the name attribute "Archibald". + +The `appendAsEAVs()` function allows you to destructure an object into a uniquely identified set of EAVs, which can then be input into Eve: + +```javascript +import {appendAsEAVs} from "witheve"; +let inputs = []; +let archibald = {tag: "person", name: "Archibald"}; +appendAsEAVs(inputs, archibald); +program.inputEAVs(inputs); +``` + +### Getting Records out of Eve - Watchers + +Watchers are a third type of block available in the DSL. These allow you to monitor changes in specific records and react to them with a callback function: + +```javascript +program.watch("Export information about students", ({find, lookup, record}) => { + // search for records tagged student + let student = find("student"); + // lookup attributes and values related to each student + let {attribute, value} = lookup(student); + return [ + // Add these attributes and values to the student, creating a diff to which we can react + student.add(attribute, value) + ]; +}) +// React to each addition or removal +.asDiffs((diff) => { + for(let [e, a, v] of diff.adds) { + // ... do something ... + } + for(let [e, a, v] of diff.removes) { + // ... do something ... + } +}); +``` + +If you care about specific attributes, if may be more convenient to write a watcher with `asObjects()` instead of `asDiffs()`: + +```javascript +program.watch("Export student GPA", ({find, lookup, record}) => { + // search for records tagged student + let student = find("student" {name, GPA}); + return [ + // Add these attributes and values to the student, which creates a diff to which we can react + record("grade", {name, GPA}) + ]; +}) +// Handle adds and removes as objects +.asObjects<{name: string, GPA: RawValue}>(({adds, removes}) => { + for(let id in adds) { + let {name, GPA} = adds[id]; + // ... do something ... + } + for(let id in removes) { + let {name, GPA} = removes[id]; + // ... do something ... + } +}) +``` + +Type annotations (between the angle braces `<>`) are necessary for TypeScript, but they can be omitted when using Javascript. diff --git a/src/guides/for-programmers.md b/guides/for-programmers.md similarity index 100% rename from src/guides/for-programmers.md rename to guides/for-programmers.md diff --git a/guides/for-programmers/index.html b/guides/for-programmers/index.html deleted file mode 100644 index 531c8fb..0000000 --- a/guides/for-programmers/index.html +++ /dev/null @@ -1,424 +0,0 @@ - - - - - - - - - - - - Eve for Programmers - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

Eve for Programmers

- -

As a programmer, you probably find it easy to switch between different programming langauges. If you know Javascript, you probably wouldn’t have a hard time learning similar langauges like C++, Java, or Python. That’s because despite syntactic differences, these languages largely conform to the same programming model. When we program in languages like these, we use similar abstractions between them – loops, functions, and input/output patterns have become a staple of every programmer’s toolbox. When we solve problems, we usually reach a solution in terms of these primitive operations.

- -

Eve is a different kind of programming langauge from Javascript or Python, so programmers new to Eve may feel a little lost at first. How do you get anything done in a language without loops? How do you compose code without functions? The purpose of this guide is to provide a mapping from the common tools you know, to the Eve way of solving problems. We’ll look at some programs written in Javascript, and see how they Eve can solve them.

- -

Functions

- -

Functions are the fundamental unit of code reuse in most conventional programming languages. These langauges typically start from a “main” function, and branch

- -

Looping

- -

Map

- -

Reduce

- -

Recursion

- -

I/O

- - -
-
- -
- diff --git a/guides/index.html b/guides/index.html deleted file mode 100644 index 5625b40..0000000 --- a/guides/index.html +++ /dev/null @@ -1,412 +0,0 @@ - - - - - - - - - - - - Guides - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
- -
-
-

Pages in Guide

- - - -

Eve for Programmers

-
- -
- - -

Style Guide

-
- -
- -
-
-
diff --git a/guides/index.xml b/guides/index.xml deleted file mode 100644 index 78a094b..0000000 --- a/guides/index.xml +++ /dev/null @@ -1,200 +0,0 @@ - - - - Guides on Eve Documentation - https://witheve.github.io/docs/guides/ - Recent content in Guides on Eve Documentation - Hugo -- gohugo.io - en-us - - - - Eve for Programmers - https://witheve.github.io/docs/guides/for-programmers/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://witheve.github.io/docs/guides/for-programmers/ - - -<h1 id="eve-for-programmers">Eve for Programmers</h1> - -<p>As a programmer, you probably find it easy to switch between different programming langauges. If you know Javascript, you probably wouldn&rsquo;t have a hard time learning similar langauges like C++, Java, or Python. That&rsquo;s because despite syntactic differences, these languages largely conform to the same programming model. When we program in languages like these, we use similar abstractions between them &ndash; loops, functions, and input/output patterns have become a staple of every programmer&rsquo;s toolbox. When we solve problems, we usually reach a solution in terms of these primitive operations.</p> - -<p>Eve is a different kind of programming langauge from Javascript or Python, so programmers new to Eve may feel a little lost at first. How do you get anything done in a language without loops? How do you compose code without functions? The purpose of this guide is to provide a mapping from the common tools you know, to the Eve way of solving problems. We&rsquo;ll look at some programs written in Javascript, and see how they Eve can solve them.</p> - -<h2 id="functions">Functions</h2> - -<p>Functions are the fundamental unit of code reuse in most conventional programming languages. These langauges typically start from a &ldquo;main&rdquo; function, and branch</p> - -<h2 id="looping">Looping</h2> - -<h3 id="map">Map</h3> - -<h3 id="reduce">Reduce</h3> - -<h3 id="recursion">Recursion</h3> - -<h2 id="i-o">I/O</h2> - - - - - Style Guide - https://witheve.github.io/docs/guides/style/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://witheve.github.io/docs/guides/style/ - - -<h1 id="eve-style-guide">Eve Style Guide</h1> - -<h2 id="comments">Comments</h2> - -<p>Add a space after the comment marker to make comments more readable</p> -<div class="highlight"><pre><code class="language-eve" data-lang="eve"><span></span><span class="c1">// This is correct</span><span class="w"></span> -<span class="c1">//This is incorrect</span><span class="w"></span> -</code></pre></div> - -<h2 id="naming">Naming</h2> - -<p>As much as possible, don&rsquo;t abbreviate names. The goal in writing an Eve program is to be as readable as possible. An abbreviation that makes sense to you might not make sense to someone else, or even yourself when you revisit the program in a year.</p> - -<p>Multi-word names should be joined by dashes <code>-</code>, not underscores <code>_</code>.</p> - -<h2 id="program-layout">Program layout</h2> - -<p>Blocks should be preceeded by at least a one line comment, indicating the purpose of the block.</p> - -<h2 id="commas">Commas</h2> - -<p>Although Eve treats commas as white-space, they should be used to enhance readability as needed:</p> - -<p>In records, separate attributes with commas after a bind</p> -<div class="highlight"><pre><code class="language-eve" data-lang="eve"><span></span><span class="c1">// More readable</span><span class="w"></span> -<span class="p">[</span><span class="nt">#person</span><span class="w"> </span><span class="x">name</span><span class="w"> </span><span class="x">age</span><span class="nf">:</span><span class="w"> </span><span class="m">30</span><span class="p">,</span><span class="w"> </span><span class="x">height</span><span class="nf">:</span><span class="w"> </span><span class="m">5</span><span class="p">,</span><span class="w"> </span><span class="x">hair</span><span class="nf">-</span><span class="x">color</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;brown&quot;</span><span class="p">]</span><span class="w"></span> - -<span class="c1">// Less readable</span><span class="w"></span> -<span class="p">[</span><span class="nt">#person</span><span class="w"> </span><span class="x">name</span><span class="w"> </span><span class="x">age</span><span class="nf">:</span><span class="w"> </span><span class="m">30</span><span class="w"> </span><span class="x">height</span><span class="nf">:</span><span class="w"> </span><span class="m">5</span><span class="w"> </span><span class="x">hair</span><span class="nf">-</span><span class="x">color</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;brown&quot;</span><span class="p">]</span><span class="w"></span> -</code></pre></div> - -<p>Commas should also be used to separate items contained in parenthesis, such as in a multiple return.</p> -<div class="highlight"><pre><code class="language-eve" data-lang="eve"><span></span><span class="c1">// More readable</span><span class="w"></span> -<span class="p">(</span><span class="x">val</span><span class="m">1</span><span class="p">,</span><span class="w"> </span><span class="x">val</span><span class="m">2</span><span class="p">)</span><span class="w"> </span><span class="nf">=</span><span class="w"> </span><span class="kr">if</span><span class="w"> </span><span class="p">[</span><span class="nt">#tag1</span><span class="p">]</span><span class="w"> </span><span class="kr">then</span><span class="w"> </span><span class="p">(</span><span class="m">1</span><span class="p">,</span><span class="w"> </span><span class="l">false</span><span class="p">)</span><span class="w"></span> -<span class="w"> </span><span class="kr">else</span><span class="w"> </span><span class="p">(</span><span class="m">0</span><span class="p">,</span><span class="w"> </span><span class="l">true</span><span class="p">)</span><span class="w"></span> -<span class="x">total</span><span class="w"> </span><span class="nf">=</span><span class="w"> </span><span class="x">count</span><span class="p">[</span><span class="x">given</span><span class="nf">:</span><span class="w"> </span><span class="x">attr</span><span class="m">1</span><span class="p">,</span><span class="w"> </span><span class="x">per</span><span class="nf">:</span><span class="w"> </span><span class="p">(</span><span class="x">attr</span><span class="m">2</span><span class="p">,</span><span class="w"> </span><span class="x">attr</span><span class="m">3</span><span class="p">)]</span><span class="w"></span> - -<span class="c1">// Less readable</span><span class="w"></span> -<span class="p">(</span><span class="x">val</span><span class="m">1</span><span class="w"> </span><span class="x">val</span><span class="m">2</span><span class="p">)</span><span class="w"> </span><span class="nf">=</span><span class="w"> </span><span class="kr">if</span><span class="w"> </span><span class="p">[</span><span class="nt">#tag1</span><span class="p">]</span><span class="w"> </span><span class="kr">then</span><span class="w"> </span><span class="p">(</span><span class="m">1</span><span class="w"> </span><span class="l">false</span><span class="p">)</span><span class="w"></span> -<span class="w"> </span><span class="kr">else</span><span class="w"> </span><span class="p">(</span><span class="m">0</span><span class="w"> </span><span class="l">true</span><span class="p">)</span><span class="w"></span> -<span class="x">total</span><span class="w"> </span><span class="nf">=</span><span class="w"> </span><span class="x">count</span><span class="p">[</span><span class="x">given</span><span class="nf">:</span><span class="w"> </span><span class="x">attr</span><span class="m">1</span><span class="w"> </span><span class="x">per</span><span class="nf">:</span><span class="w"> </span><span class="p">(</span><span class="x">attr</span><span class="m">2</span><span class="w"> </span><span class="x">attr</span><span class="m">3</span><span class="p">)]</span><span class="w"></span> -</code></pre></div> - -<h2 id="indention">Indention</h2> - -<p>Eve does not enforce indention, but it is important for readability</p> - -<h3 id="blocks">Blocks</h3> - -<p><code>search</code>. <code>commit</code>, and <code>bind</code> should be the only lines at zero indention. Everything else should be indented.</p> -<div class="highlight"><pre><code class="language-eve" data-lang="eve"><span></span><span class="c1">// Good</span><span class="w"></span> -<span class="x">match</span><span class="w"></span> -<span class="w"> </span><span class="p">[</span><span class="x">...</span><span class="p">]</span><span class="w"></span> - -<span class="kr">bind</span><span class="w"></span> -<span class="w"> </span><span class="p">[</span><span class="x">...</span><span class="p">]</span><span class="w"></span> -</code></pre></div> - -<p>But not this:</p> -<div class="highlight"><pre><code class="language-eve" data-lang="eve"><span></span><span class="c1">// Bad</span><span class="w"></span> -<span class="x">match</span><span class="w"></span> -<span class="p">[</span><span class="x">...</span><span class="p">]</span><span class="w"></span> - -<span class="kr">bind</span><span class="w"></span> -<span class="p">[</span><span class="x">...</span><span class="p">]</span><span class="w"></span> -</code></pre></div> - -<h3 id="if-then">If-Then</h3> - -<p>Each arm of an <code>if-then</code> statement should be at the same indention level. The <code>then</code> portion of the statement can be on a new line if the <code>if</code> portion is exceptionally long, but it should be indented once.</p> -<div class="highlight"><pre><code class="language-eve" data-lang="eve"><span></span><span class="c1">// Good if layout</span><span class="w"></span> -<span class="x">value</span><span class="w"> </span><span class="nf">=</span><span class="w"> </span><span class="kr">if</span><span class="w"> </span><span class="x">bar</span><span class="w"> </span><span class="kr">then</span><span class="w"> </span><span class="x">baz</span><span class="w"></span> -<span class="w"> </span><span class="kr">if</span><span class="w"> </span><span class="x">bar</span><span class="m">2</span><span class="w"> </span><span class="kr">then</span><span class="w"> </span><span class="x">baz</span><span class="m">2</span><span class="w"></span> -<span class="w"> </span><span class="kr">else</span><span class="w"> </span><span class="x">baz</span><span class="m">3</span><span class="w"></span> - -<span class="c1">// Okay, especially if the branch is long</span><span class="w"></span> -<span class="x">value</span><span class="w"> </span><span class="nf">=</span><span class="w"> </span><span class="kr">if</span><span class="w"> </span><span class="p">[</span><span class="nt">#long-record</span><span class="w"> </span><span class="x">attr</span><span class="m">1</span><span class="w"> </span><span class="x">attr</span><span class="m">2</span><span class="w"> </span><span class="x">attr</span><span class="m">3</span><span class="p">]</span><span class="w"> </span> -<span class="w"> </span><span class="kr">then</span><span class="w"> </span><span class="x">baz</span><span class="w"></span> -<span class="w"> </span><span class="kr">if</span><span class="w"> </span><span class="p">[</span><span class="nt">#long-record2</span><span class="w"> </span><span class="x">attr</span><span class="m">1</span><span class="w"> </span><span class="x">attr</span><span class="m">2</span><span class="w"> </span><span class="x">attr</span><span class="m">3</span><span class="p">]</span><span class="w"> </span> -<span class="w"> </span><span class="kr">then</span><span class="w"> </span><span class="x">baz</span><span class="m">2</span><span class="w"></span> -<span class="w"> </span><span class="kr">else</span><span class="w"> </span><span class="x">baz</span><span class="m">3</span><span class="w"></span> - -<span class="c1">// Bad if layout</span><span class="w"></span> -<span class="x">value</span><span class="w"> </span><span class="nf">=</span><span class="w"> </span><span class="kr">if</span><span class="w"> </span><span class="x">bar</span><span class="w"> </span><span class="kr">then</span><span class="w"> </span><span class="x">baz</span><span class="w"></span> -<span class="kr">if</span><span class="w"> </span><span class="x">bar</span><span class="m">2</span><span class="w"> </span><span class="kr">then</span><span class="w"> </span><span class="x">baz</span><span class="m">2</span><span class="w"></span> -<span class="kr">else</span><span class="w"> </span><span class="x">baz</span><span class="m">3</span><span class="w"></span> - -<span class="c1">// Also a bad if layout</span><span class="w"></span> -<span class="x">value</span><span class="w"> </span><span class="nf">=</span><span class="w"> </span><span class="kr">if</span><span class="w"> </span><span class="x">bar</span><span class="w"> </span><span class="kr">then</span><span class="w"> </span><span class="x">baz</span><span class="w"> </span><span class="kr">if</span><span class="w"> </span><span class="x">bar</span><span class="m">2</span><span class="w"> </span><span class="kr">then</span><span class="w"> </span><span class="x">baz</span><span class="m">2</span><span class="w"> </span><span class="kr">else</span><span class="w"> </span><span class="x">baz</span><span class="m">3</span><span class="w"></span> -</code></pre></div> - -<h3 id="nested-records">Nested records</h3> - -<p>When nested records are placed on a new line, they should be indented once past the parent record. Where possible, nested records should be the final attribute in the parent record.</p> - -<p>Nested records should appear on their own line if you are nesting more than one.</p> -<div class="highlight"><pre><code class="language-eve" data-lang="eve"><span></span><span class="c1">// Okay, but only do this for one level of nesting</span><span class="w"></span> -<span class="p">[</span><span class="nt">#div</span><span class="w"> </span><span class="x">text</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;hello&quot;</span><span class="p">,</span><span class="w"> </span><span class="x">children</span><span class="nf">:</span><span class="w"> </span><span class="p">[</span><span class="nt">#div</span><span class="w"> </span><span class="x">text</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;world&quot;</span><span class="p">]]</span><span class="w"></span> - -<span class="c1">// More readable</span><span class="w"></span> -<span class="p">[</span><span class="nt">#div</span><span class="w"> </span><span class="x">text</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;hello&quot;</span><span class="p">,</span><span class="w"> </span><span class="x">children</span><span class="nf">:</span><span class="w"> </span> -<span class="w"> </span><span class="p">[</span><span class="nt">#div</span><span class="w"> </span><span class="x">text</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;world&quot;</span><span class="p">]]</span><span class="w"></span> - -<span class="c1">// Also good</span><span class="w"></span> -<span class="p">[</span><span class="nt">#div</span><span class="w"> </span><span class="x">children</span><span class="nf">:</span><span class="w"> </span> -<span class="w"> </span><span class="p">[</span><span class="nt">#div</span><span class="w"> </span><span class="x">text</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;div1&quot;</span><span class="p">]</span><span class="w"></span> -<span class="w"> </span><span class="p">[</span><span class="nt">#div</span><span class="w"> </span><span class="x">text</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;div2&quot;</span><span class="w"> </span><span class="x">children</span><span class="nf">:</span><span class="w"></span> -<span class="w"> </span><span class="p">[</span><span class="nt">#div</span><span class="w"> </span><span class="x">text</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;div3&quot;</span><span class="p">]]]</span><span class="w"> </span> - -<span class="c1">// Not good</span><span class="w"></span> -<span class="p">[</span><span class="nt">#div</span><span class="w"> </span><span class="x">children</span><span class="nf">:</span><span class="w"> </span><span class="p">[</span><span class="nt">#div</span><span class="w"> </span><span class="x">text</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;div2&quot;</span><span class="p">]</span><span class="w"> </span><span class="p">[</span><span class="nt">#div</span><span class="w"> </span><span class="x">text</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;div2&quot;</span><span class="p">]]</span><span class="w"></span> - -<span class="c1">// Also not good</span><span class="w"></span> -<span class="p">[</span><span class="nt">#div</span><span class="w"> </span><span class="x">children</span><span class="nf">:</span><span class="w"> </span> -<span class="w"> </span><span class="p">[</span><span class="nt">#div</span><span class="w"> </span><span class="x">text</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;world&quot;</span><span class="p">],</span><span class="w"> </span><span class="x">text</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;hello&quot;</span><span class="p">]</span><span class="w"></span> -</code></pre></div> - -<h2 id="newlines">Newlines</h2> - -<p>Newlines should preceed and follow every code block.</p> - -<p>Within code blocks, a newline should be added between every action. This enhances readability, especially in the case where multiple actions are needed. For instance, the following code block:</p> -<div class="highlight"><pre><code class="language-eve" data-lang="eve"><span></span><span class="kr">search</span><span class="w"> </span><span class="nt">@studentDB</span><span class="w"></span> -<span class="w"> </span><span class="x">students</span><span class="w"> </span><span class="nf">=</span><span class="w"> </span><span class="p">[</span><span class="nt">#students</span><span class="p">]</span><span class="w"></span> - -<span class="kr">search</span><span class="w"> </span><span class="nt">@schoolDB</span><span class="w"></span> -<span class="w"> </span><span class="x">schools</span><span class="w"> </span><span class="nf">=</span><span class="w"> </span><span class="p">[</span><span class="nt">#school</span><span class="p">]</span><span class="w"></span> -<span class="w"> </span><span class="x">schools.name</span><span class="w"> </span><span class="nf">=</span><span class="w"> </span><span class="x">student.school</span><span class="w"></span> - -<span class="kr">bind</span><span class="w"> </span><span class="nt">@browser</span><span class="w"></span> -<span class="w"> </span><span class="p">[</span><span class="nt">#div</span><span class="w"> </span><span class="x">text</span><span class="nf">:</span><span class="w"> </span><span class="x">students.name</span><span class="p">]</span><span class="w"> </span> - -<span class="kr">commit</span><span class="w"></span> -<span class="w"> </span><span class="p">[</span><span class="nt">#new-record</span><span class="p">]</span><span class="w"></span> -</code></pre></div> - -<p>is more readable than this code block:</p> -<div class="highlight"><pre><code class="language-eve" data-lang="eve"><span></span><span class="kr">search</span><span class="w"> </span><span class="nt">@studentDB</span><span class="w"></span> -<span class="w"> </span><span class="x">students</span><span class="w"> </span><span class="nf">=</span><span class="w"> </span><span class="p">[</span><span class="nt">#students</span><span class="p">]</span><span class="w"></span> -<span class="kr">search</span><span class="w"> </span><span class="nt">@schoolDB</span><span class="w"></span> -<span class="w"> </span><span class="x">schools</span><span class="w"> </span><span class="nf">=</span><span class="w"> </span><span class="p">[</span><span class="nt">#school</span><span class="p">]</span><span class="w"></span> -<span class="w"> </span><span class="x">schools.name</span><span class="w"> </span><span class="nf">=</span><span class="w"> </span><span class="x">student.school</span><span class="w"></span> -<span class="kr">bind</span><span class="w"> </span><span class="nt">@browser</span><span class="w"></span> -<span class="w"> </span><span class="p">[</span><span class="nt">#div</span><span class="w"> </span><span class="x">text</span><span class="nf">:</span><span class="w"> </span><span class="x">students.name</span><span class="p">]</span><span class="w"> </span> -<span class="kr">commit</span><span class="w"></span> -<span class="w"> </span><span class="p">[</span><span class="nt">#new-record</span><span class="p">]</span><span class="w"></span> -</code></pre></div> - - - - - \ No newline at end of file diff --git a/src/guides/style.md b/guides/style.md similarity index 87% rename from src/guides/style.md rename to guides/style.md index 548204e..a0e105b 100644 --- a/src/guides/style.md +++ b/guides/style.md @@ -25,7 +25,7 @@ Multi-word names should be joined by dashes `-`, not underscores `_`. ## Program layout -Blocks should be preceeded by at least a one line comment, indicating the purpose of the block. +Blocks should be preceded by at least a one line comment, indicating the purpose of the block. ## Commas @@ -65,7 +65,7 @@ Eve does not enforce indention, but it is important for readability ```eve // Good -match +search [...] bind @@ -75,8 +75,8 @@ bind But not this: ```eve -// Bad -match +// Not good +search [...] bind @@ -94,18 +94,18 @@ value = if bar then baz else baz3 // Okay, especially if the branch is long -value = if [#long-record attr1 attr2 attr3] +value = if [#long-record attr1 attr2 attr3] then baz - if [#long-record2 attr1 attr2 attr3] + if [#long-record2 attr1 attr2 attr3] then baz2 else baz3 -// Bad if layout +// Less readable "if" formatting value = if bar then baz if bar2 then baz2 else baz3 -// Also a bad if layout +// Less readable "if" formatting value = if bar then baz if bar2 then baz2 else baz3 ``` @@ -116,31 +116,30 @@ When nested records are placed on a new line, they should be indented once past Nested records should appear on their own line if you are nesting more than one. ```eve - // Okay, but only do this for one level of nesting [#div text: "hello", children: [#div text: "world"]] // More readable -[#div text: "hello", children: +[#div text: "hello", children: [#div text: "world"]] // Also good -[#div children: +[#div children: [#div text: "div1"] [#div text: "div2" children: - [#div text: "div3"]]] + [#div text: "div3"]]] // Not good [#div children: [#div text: "div2"] [#div text: "div2"]] // Also not good -[#div children: +[#div children: [#div text: "world"], text: "hello"] ``` ## Newlines -Newlines should preceed and follow every code block. +Newlines should precede and follow every code block. Within code blocks, a newline should be added between every action. This enhances readability, especially in the case where multiple actions are needed. For instance, the following code block: @@ -153,7 +152,7 @@ search @schoolDB schools.name = student.school bind @browser - [#div text: students.name] + [#div text: students.name] commit [#new-record] @@ -168,7 +167,7 @@ search @schoolDB schools = [#school] schools.name = student.school bind @browser - [#div text: students.name] + [#div text: students.name] commit [#new-record] -``` \ No newline at end of file +``` diff --git a/guides/style/index.html b/guides/style/index.html deleted file mode 100644 index d453be0..0000000 --- a/guides/style/index.html +++ /dev/null @@ -1,552 +0,0 @@ - - - - - - - - - - - - Style Guide - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

Eve Style Guide

- -

Comments

- -

Add a space after the comment marker to make comments more readable

-
// This is correct
-//This is incorrect
-
- -

Naming

- -

As much as possible, don’t abbreviate names. The goal in writing an Eve program is to be as readable as possible. An abbreviation that makes sense to you might not make sense to someone else, or even yourself when you revisit the program in a year.

- -

Multi-word names should be joined by dashes -, not underscores _.

- -

Program layout

- -

Blocks should be preceeded by at least a one line comment, indicating the purpose of the block.

- -

Commas

- -

Although Eve treats commas as white-space, they should be used to enhance readability as needed:

- -

In records, separate attributes with commas after a bind

-
// More readable
-[#person name age: 30, height: 5, hair-color: "brown"]
-
-// Less readable
-[#person name age: 30 height: 5 hair-color: "brown"]
-
- -

Commas should also be used to separate items contained in parenthesis, such as in a multiple return.

-
// More readable
-(val1, val2) = if [#tag1] then (1, false)
-               else (0, true)
-total = count[given: attr1, per: (attr2, attr3)]
-
-// Less readable
-(val1 val2) = if [#tag1] then (1 false)
-               else (0 true)
-total = count[given: attr1 per: (attr2 attr3)]
-
- -

Indention

- -

Eve does not enforce indention, but it is important for readability

- -

Blocks

- -

search. commit, and bind should be the only lines at zero indention. Everything else should be indented.

-
// Good
-match
-  [...]
-
-bind
-  [...]
-
- -

But not this:

-
// Bad
-match
-[...]
-
-bind
-[...]
-
- -

If-Then

- -

Each arm of an if-then statement should be at the same indention level. The then portion of the statement can be on a new line if the if portion is exceptionally long, but it should be indented once.

-
// Good if layout
-value = if bar then baz
-        if bar2 then baz2
-        else baz3
-
-// Okay, especially if the branch is long
-value = if [#long-record attr1 attr2 attr3] 
-          then baz
-        if [#long-record2 attr1 attr2 attr3] 
-          then baz2
-        else baz3
-
-// Bad if layout
-value = if bar then baz
-if bar2 then baz2
-else baz3
-
-// Also a bad if layout
-value = if bar then baz if bar2 then baz2 else baz3
-
- -

Nested records

- -

When nested records are placed on a new line, they should be indented once past the parent record. Where possible, nested records should be the final attribute in the parent record.

- -

Nested records should appear on their own line if you are nesting more than one.

-
// Okay, but only do this for one level of nesting
-[#div text: "hello", children: [#div text: "world"]]
-
-// More readable
-[#div text: "hello", children: 
-  [#div text: "world"]]
-
-// Also good
-[#div children: 
-  [#div text: "div1"]
-  [#div text: "div2" children:
-    [#div text: "div3"]]]  
-
-// Not good
-[#div children: [#div text: "div2"] [#div text: "div2"]]
-
-// Also not good
-[#div children: 
-  [#div text: "world"], text: "hello"]
-
- -

Newlines

- -

Newlines should preceed and follow every code block.

- -

Within code blocks, a newline should be added between every action. This enhances readability, especially in the case where multiple actions are needed. For instance, the following code block:

-
search @studentDB
-  students = [#students]
-
-search @schoolDB
-  schools = [#school]
-  schools.name = student.school
-
-bind @browser
-  [#div text: students.name] 
-
-commit
-  [#new-record]
-
- -

is more readable than this code block:

-
search @studentDB
-  students = [#students]
-search @schoolDB
-  schools = [#school]
-  schools.name = student.school
-bind @browser
-  [#div text: students.name] 
-commit
-  [#new-record]
-
- - -
-
- -
- diff --git a/src/handbook/actions.md b/handbook/actions.md similarity index 100% rename from src/handbook/actions.md rename to handbook/actions.md diff --git a/handbook/actions/index.html b/handbook/actions/index.html deleted file mode 100644 index d42b6b5..0000000 --- a/handbook/actions/index.html +++ /dev/null @@ -1,428 +0,0 @@ - - - - - - - - - - - - Actions - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

Actions

- -

Description

- -

There are three actions in Eve: search, bind, and commit.

- -

search is used when you want to gather records from one or more databases. These records are called “supporting records”, because they are used as a basis for bound or committed records.

- -

bind and commit actions are used when you want to update records in one or more databases, but they differ in the way the updates are performed.

- -
    -
  • bound records last only as long as their supporting records. When supporting records changes, then bound records changes accordingly, replacing any previously bound records.

  • - -
  • committed records persist past the lifetime of their supporting records. When supporting records change, then a new record is committed, leaving any previously committed records still intact.

  • -
- -

Examples

-

-
- -

See Also

- -

search | bind | commit

- - -
-
- -
- diff --git a/src/handbook/add.md b/handbook/add.md similarity index 96% rename from src/handbook/add.md rename to handbook/add.md index adc42c1..500e7a2 100644 --- a/src/handbook/add.md +++ b/handbook/add.md @@ -22,7 +22,7 @@ record += #tag ## Description -`record.attribute += value` adds `value` to `attribute`. If `record` already has an attribute with a value, then `value` will be added to the set. Otherwise, if `record` doesn't have an attribute with this name already, then `:=` will create the attribute and set it to `value`. As Eve variables are sets, if the value already exists on the attribute, the value cannot be added again. +`record.attribute += value` adds `value` to `attribute`. If `record` already has an attribute with a value, then `value` will be added to the set. Otherwise, if `record` doesn't have an attribute with this name already, then `+=` will create the attribute and set it to `value`. As Eve variables are sets, if the value already exists on the attribute, the value cannot be added again. `attribute` can be an attribute already on the record, or it can be a new attribute. diff --git a/handbook/add/index.html b/handbook/add/index.html deleted file mode 100644 index 650fe50..0000000 --- a/handbook/add/index.html +++ /dev/null @@ -1,462 +0,0 @@ - - - - - - - - - - - - Add: += - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

Add Operator

- -

adds a value to an attribute on a record

- -

Syntax

-
// Add a value to an attribute
-record.attribute += value
-
-// Add a tag to a record
-record += #tag
-
- -

Description

- -

record.attribute += value adds value to attribute. If record already has an attribute with a value, then value will be added to the set. Otherwise, if record doesn’t have an attribute with this name already, then := will create the attribute and set it to value. As Eve variables are sets, if the value already exists on the attribute, the value cannot be added again.

- -

attribute can be an attribute already on the record, or it can be a new attribute.

- -

value can be a string or number literal, a variable bound to one of these, or a record.

- -

record += #tag adds #tag to record. This is shorthand for record.tag += "tag".

- -

Examples

- -

Add the current second to a record. Since Eve works in sets, time-history can only ever hold then numbers 0 through 60. This means after one minute passes, no new elements will be added to tracker.time-history.

-
search
-  tracker = [#seconds-tracker]
-  [#time seconds]
-
-commit
-  tracker.time-history += seconds
-
- -

We can get around this by adding a record:

-
search
-  tracker = [#seconds-tracker]
-  [#time seconds]
-
-commit
-  tracker.time-history += [seconds]
-
- -

Now, instead of adding numbers to time-history we are adding records, which are associated with a unique ID. So after the first minute passes, time-history will contain duplicate seconds, but the record ID will ensure each one is unique.

- -
- -

Add the #honor-student tag to any #student with a GPA greater than 3.75:

-
search
-  student = [#student gpa > 3.75]
-  
-bind
-  student += #honor-student
-
- -

See Also

- -

set operator | remove operator | merge operator | bind | commit

- - -
-
- -
- diff --git a/src/handbook/aggregates.md b/handbook/aggregates.md similarity index 100% rename from src/handbook/aggregates.md rename to handbook/aggregates.md diff --git a/handbook/aggregates/index.html b/handbook/aggregates/index.html deleted file mode 100644 index ac8c219..0000000 --- a/handbook/aggregates/index.html +++ /dev/null @@ -1,430 +0,0 @@ - - - - - - - - - - - - Aggregates - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

Aggregates

- -

aggregates reduce a set of values to a single value

- -

Description

- -

Aggregates are functions that take an input set and produce an output set, typically with a different cardinality than the input set. Examples of aggregates include sum, count, and average. Each of these takes a set of numbers as an input, and typically produces a single number as output.

- -

Aggregates are called just like other functions in Eve. For instance, the count aggregate is called like so:

-
employee-count = count[given: employees]
-
- -

Aggregates don’t always produce a single output value. In some instances, you may want to group your input according to a desired dimension (department, grade, state, country, zip code, etc.) and then aggregate based on those groupings. Extending the example above, we could count the employees in each department:

-
employee-count = count[given: employees, per: department]
-
- -

Now, employee-count will have a count for each department, instead of a single count over all departments. For more complete examples, see the doc files for specific aggregates.

- -

Tip

- -

Aggregates have similar behavior to the reduce() function in many other langauges.

- -

See Also

- -

count

- - -
-
- -
- diff --git a/src/handbook/bind.md b/handbook/bind.md similarity index 99% rename from src/handbook/bind.md rename to handbook/bind.md index b59581b..f83ca7a 100644 --- a/src/handbook/bind.md +++ b/handbook/bind.md @@ -247,11 +247,11 @@ When searching for an event like a `#click`, a commit is usually more appropriat Display a formatted time: ```eve -match +search [#time hours minutes seconds] (am/pm, adjusted-hours) = if hours >= 12 then ("PM", hours - 12) else if hours = 0 then ("AM", 12) - else ("AM", hours) + else ("AM", hours) bind @browser [#div text: "The current time is {{adjusted-hours}}:{{minutes}}:{{seconds}} {{am/pm}}"] ``` diff --git a/handbook/bind/index.html b/handbook/bind/index.html deleted file mode 100644 index dae7b47..0000000 --- a/handbook/bind/index.html +++ /dev/null @@ -1,648 +0,0 @@ - - - - - - - - - - - - bind - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

bind

- -

updates or creates records, syncing them with matched records

- -

Syntax

-
bind
-
-bind @database1, ..., @databaseN
-
- -

Description

- -

bind updates or creates new records with a lifetime equal to matched records within the block. Matched records are any records found in a search action. If matched records change during program execution, all bound records change accordingly. If any matched records are removed (i.e. they no longer match the search), bound records and updates are removed as well.

- -

By default, bound records are directed to a default local database.

- -

bind @database1, ..., @databaseN directs bound records to one or more databases.

- -

Bind vs. Commit

- -

While bind and commit both update records in a database, they do so with slightly different behavior; a bound record has the same lifetime as its supporting records, whereas a committed record exists in the database until it is removed intentionally. Let’s take a closer look at this distinction and what the implications are.

- -

Consider the following block that reads the current time, and prints it to the screen:

-
search
-  [#time seconds]
-
-bind @browser
-  [#div text: seconds]
-
- -

In this block we search for the current time and bind it to a message that displays it. The message exists as long as the current time stays the same (1 second obviously). When the time changes, the current message disappears and is replaced with a new message, displaying the new time. This is the behavior of bind; bound records persist only as long as their matching records.

- -

Now let’s look at what commit does in contrast:

-
search
-  [#time seconds]
-
-commit @browser
-  [#div text: seconds]
-
- -

Compared to the previous block, we only changed bind to commit. When you run this block, at first you’ll see a single message like before. However, you’ll notice that messages begin to accumulate every second. Unlike with bind, committed records persist in the database until they are intentionally removed.

- -

To make things very concrete, we can actually mimic the behavior of a bind using two blocks that commit. We’ve already got the first one (the one just above), that commits messages to @browser. Now all we need is a second block, one that removes old committed messages from @browser:

-
search 
-  [#time seconds]
-
-search @browser
-  s = seconds - 1
-  // Do some math to handle the roll over at 60 seconds
-  last-time = s - 60 * floor[value: s / 60]
-  msg = [#div text: last-time]
-  
-commit @browser
-  msg := none
-
- -

This block searches for the message that was displayed during the previous second, and sets it to none, thereby removing it from @browser. Therefore, only the message bound to the the current time is displayed on the screen. This behavior is identical to that of the block that binds these messages instead of committing them!

- -

An Execution Perspective

- -

Another way to understand bind vs. commit is by looking at how the databases change over each tick of the Eve evaluator. We’ll consider the same program as before, looking at how its state changes over time. First, consider the bind case. When the program starts, there’s nothing in any databases; the program is a blank slate. At t1 the first #time is added to @session. This addition is bound to a #div, which is added to @browser. These changes are summarized in the first column of the table below.

- -

At t2, a new #time is added to @session, and the one from t1 is removed. Since we used a bind, this causes the existing #div to be removed from @browser, but it is replaced with a new #div reflecting the current time. At t3, the same operations takes place, and this process continues until the program is terminated.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - -t0 - -t1 - -t2 - -t3 -
-delta - - - -+ [#time seconds: 39] -+ [#div text: "39"] - -+ [#time seconds: 40] -- [#time seconds: 39] -+ [#div text: "40"] -- [#div text: "39"] - -+ [#time seconds: 41] -- [#time seconds: 40] -+ [#div text: "41"] -- [#div text: "40"] -
-@session - -[ ] - -[[#time seconds: 39]] - -[[#time seconds: 40]] - -[[#time seconds: 41]] -
-@browser - -[ ] - -[[#div text: 39]] - -[[#div text: 40]] - -[[#div text: 41]] -
- -

Let’s perform the same analysis in the commit case. In this program, things start off the same; initially the database is empty, and at t1 a #time and a #div are added to their respective databases. At t2, things get more interesting. While the old #time is still replaced, the #div displaying the old time is not replaced since we committed it to @browser. Indeed, in subsequent rounds of execution, the contents of @browser keeps growing.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - -t0 - -t1 - -t2 - -t3 -
-delta - - -+ [#time seconds: 39] -+ [#div text: "39"] - -+ [#time seconds: 40] -- [#time seconds: 39] -+ [#div text: "40"] - -+ [#time seconds: 41] -- [#time seconds: 40] -+ [#div text: "41"] -
-@session - -[ ] - -[[#time seconds: 39]] - -[[#time seconds: 40]] - -[[#time seconds: 41]] -
-@browser - -[ ] - -[[#div text: 39]] - -[[#div text: 39], - [#div text: 40]] - -[[#div text: 39], - [#div text: 40], - [#div text: 41]] -
- -

Tips

- -

When you want to display data in an interface element like a #div, a bind is usually the more appropriate choice compared to a commit. A bind will keep the interface element always up-to-date, whereas a commit will leave lingering elements that no longer reflect the current state of the program.

- -

When searching for an event like a #click, a commit is usually more appropriate than bind. When an event occurs, a record representing the event is added to a database. That record exists for exactly one “instant”, and then it is removed from the database. During that “instant”, any block searching for that event will be satisfied and can execute a bind or commit action. If you bind on the event, then the result will disappear as soon as the event does. However, if you commit on the event, then that result will persist after the event has been removed.

- -

Examples

- -

Display a formatted time:

-
match
-  [#time hours minutes seconds]
-  (am/pm, adjusted-hours) = if hours >= 12 then ("PM", hours - 12)
-                            else if hours = 0 then ("AM", 12)
-                                            else ("AM", hours)
-bind @browser
-  [#div text: "The current time is {{adjusted-hours}}:{{minutes}}:{{seconds}} {{am/pm}}"]
-
- -

See Also

- -

commit | databases | search

- - -
-
- -
- diff --git a/src/handbook/blocks.md b/handbook/blocks.md similarity index 62% rename from src/handbook/blocks.md rename to handbook/blocks.md index 22bf3bb..47ad679 100644 --- a/src/handbook/blocks.md +++ b/handbook/blocks.md @@ -13,8 +13,8 @@ blocks compose Eve programs ## Syntax ~~~eve +// Blocks contain Eve code and can execute actions ``` -// A block with all three actions search ..... @@ -25,8 +25,21 @@ commit ..... ``` +// Blocks that are disabled are not executed +```eve disabled +search + .... +``` + +// Non-Eve blocks are not parsed or executed +```javascript +function() { + ... +} ``` + // Blocks that omit the search action are satisfied by default +``` bind ..... ``` @@ -41,8 +54,8 @@ commit A `block` is the fundamental unit of Eve code. Eve programs are made up of a series of blocks, each of which can perform actions: -1. A block `search`es one or more databases for records. -2. A block `bind`s or `commit`s new records in one or more databases. +1. A block searches one or more databases for records. +2. A block binds or commits new records in one or more databases. Blocks execute when the records they search for exist or change. If a block doesn't search for any records, then the block executes by default, but it can never update bound or committed records. @@ -50,11 +63,42 @@ Blocks can have any number of `search`, `commit`, and `bind` actions, each of wh Blocks automatically keep bound and committed records up-to-date with matched records. When a record matching a search changes, those changes are reflected automatically in bound and committed records within that block. +## Specifying a Block + +Blocks are specified using two fences to delineate the beginning and end of the block. Code fences are matching pairs of either three consecutive ticks (```) or tildes (~~~). This style of code block is the same as supported by [CommonMark](http://spec.commonmark.org/0.26/#fenced-code-blocks). However, we don't currently support specifying code blocks via indentation. + +## Info Strings + +You can specify the type of code within a block with an info string, written directly after the block's opening code fence. By default, any block without an info string are assumed to contain Eve code. + +~~~ +``` +// An implicit block of Eve code. This block is parsed and executed + ... +``` + +```eve +// An explicit block of Eve code. This block is parsed and executed + ... +``` + +```eve disabled +// An explicit block of Eve code. This block is parsed, but not executed + ... +``` + +```javascript +// An explicit block of Javascript code. This block is ignored +// by the Eve compiler entirely + ... +``` +~~~ + ## Tips -Although they are similar, it's important not to think of blocks like functions in other languages. Blocks don't have a name, and you don't "call" them like you do functions. Instead, you "use" a block by creating the records for which it searches. +Although they are similar, it's important not to think of blocks like functions in other languages. Blocks don't have a name, and you don't "call" them like you do functions. Instead, you "use" a block by searching for the records it creates. -Likewise, there is no "main" block. Since Eve is declarative and there is no order, there is no particular starting point for a program. As a close analog, any block that does not search for records will execute when the program starts. For instance: +Likewise, there is no "main" block. Since Eve is declarative and there is no order, there is no particular starting point for a program. As a close analog, any block that does not search for records will be the first to execute when the program starts. For instance: ```eve commit @@ -62,7 +106,7 @@ commit [#student name: "Ingrid"] ``` -This block has no `search` action, so it doesn't depend on any other records. Thus, it can be viewed as a "root" of the program. A program may contain many such roots. +This block has no `search` action, so it doesn't depend on any other records. Thus, it can be viewed as a "root" of the program. A program may contain many such root blocks. ## Examples diff --git a/handbook/blocks/index.html b/handbook/blocks/index.html deleted file mode 100644 index fcae7d6..0000000 --- a/handbook/blocks/index.html +++ /dev/null @@ -1,500 +0,0 @@ - - - - - - - - - - - - Blocks - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

Blocks

- -

blocks compose Eve programs

- -

Syntax

-
```
-// A block with all three actions
-search
-  .....
-
-bind
-  .....
-
-commit
-  .....
-```
-
-```
-// Blocks that omit the search action are satisfied by default
-bind
-  .....
-```
-
-```
-commit
-  .....
-```
-
- -

Description

- -

A block is the fundamental unit of Eve code. Eve programs are made up of a series of blocks, each of which can perform actions:

- -
    -
  1. A block searches one or more databases for records.
  2. -
  3. A block binds or commits new records in one or more databases.
  4. -
- -

Blocks execute when the records they search for exist or change. If a block doesn’t search for any records, then the block executes by default, but it can never update bound or committed records.

- -

Blocks can have any number of search, commit, and bind actions, each of which can reference any number of databases. If a block has multiple search actions, it will only execute if all searches are satisfied.

- -

Blocks automatically keep bound and committed records up-to-date with matched records. When a record matching a search changes, those changes are reflected automatically in bound and committed records within that block.

- -

Tips

- -

Although they are similar, it’s important not to think of blocks like functions in other languages. Blocks don’t have a name, and you don’t “call” them like you do functions. Instead, you “use” a block by creating the records for which it searches.

- -

Likewise, there is no “main” block. Since Eve is declarative and there is no order, there is no particular starting point for a program. As a close analog, any block that does not search for records will execute when the program starts. For instance:

-
commit
-  [#student name: "Sally"]
-  [#student name: "Ingrid"]
-
- -

This block has no search action, so it doesn’t depend on any other records. Thus, it can be viewed as a “root” of the program. A program may contain many such roots.

- -

Examples

- -

A block with search and bind actions. The bind action adds the #div to the @browser database.

-
search
-  [name]
-
-bind @browser
-  [#div text: name]
-
- -

A block with only a commit action:

-
commit
-  [name: "Roger"]
-
- -
- -

Search for a #click in @event, create a #request in @http

-
search @event
-  [#click]
-
-commit @http
-  [#request #google url: "https://jsonplaceholder.typicode.com/posts/"]
-
- -

Search for a #request with a response, display it in the browser

-
search @http
-  [#request #google response: [json]]
-  json = [#array]
-  lookup[record: json, attribute, value: [title body]]
-
-bind @browser
-  [#div text: "{{title}}"]
-  [#div text: "{{body}}"]
-
- -

See Also

- -

search | bind | commit | databases

- - -
-
- -
- diff --git a/handbook/browser/index.md b/handbook/browser/index.md new file mode 100644 index 0000000..aea5e89 --- /dev/null +++ b/handbook/browser/index.md @@ -0,0 +1,10 @@ +--- +menu: + main: + parent: "Databases" +title: "@browser" +weight: 2 +--- + +# @browser + diff --git a/src/handbook/commit.md b/handbook/commit.md similarity index 100% rename from src/handbook/commit.md rename to handbook/commit.md diff --git a/handbook/commit/index.html b/handbook/commit/index.html deleted file mode 100644 index c804452..0000000 --- a/handbook/commit/index.html +++ /dev/null @@ -1,652 +0,0 @@ - - - - - - - - - - - - commit - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

commit

- -

updates or creates records that persist until intentionally removed

- -

Syntax

-
commit
-
-commit @database1, ..., @databaseN
-
- -

Description

- -

commit updates or creates new records that persist in a database until they are intentionally removed. If supporting records change or are removed, the original committed records remain in tact, and can still be searched by other blocks. By default, committed records are directed to a local database.

- -

commit @database1, ..., @databaseN directs committed records one or more databases.

- -

Bind vs. Commit

- -

While bind and commit both update records in a database, they do so with slightly different behavior; a bound record has the same lifetime as its supporting records, whereas a committed record exists in the database until it is removed intentionally. Let’s take a closer look at this distinction and what the implications are.

- -

Consider the following block that reads the current time, and prints it to the screen:

-
search
-  [#time seconds]
-
-bind @browser
-  [#div text: seconds]
-
- -

In this block we search for the current time and bind it to a message that displays it. The message exists as long as the current time stays the same (1 second obviously). When the time changes, the current message disappears and is replaced with a new message, displaying the new time. This is the behavior of bind; bound records persist only as long as their matching records.

- -

Now let’s look at what commit does in contrast:

-
search
-  [#time seconds]
-
-commit @browser
-  [#div text: seconds]
-
- -

Compared to the previous block, we only changed bind to commit. When you run this block, at first you’ll see a single message like before. However, you’ll notice that messages begin to accumulate every second. Unlike with bind, committed records persist in the database until they are intentionally removed.

- -

To make things very concrete, we can actually mimic the behavior of a bind using two blocks that commit. We’ve already got the first one (the one just above), that commits messages to @browser. Now all we need is a second block, one that removes old committed messages from @browser:

-
search 
-  [#time seconds]
-
-search @browser
-  s = seconds - 1
-  // Do some math to handle the roll over at 60 seconds
-  last-time = s - 60 * floor[value: s / 60]
-  msg = [#div text: last-time]
-  
-commit @browser
-  msg := none
-
- -

This block searches for the message that was displayed during the previous second, and sets it to none, thereby removing it from @browser. Therefore, only the message bound to the the current time is displayed on the screen. This behavior is identical to that of the block that binds these messages instead of committing them!

- -

An Execution Perspective

- -

Another way to understand bind vs. commit is by looking at how the databases change over each tick of the Eve evaluator. We’ll consider the same program as before, looking at how its state changes over time. First, consider the bind case. When the program starts, there’s nothing in any databases; the program is a blank slate. At t1 the first #time is added to @session. This addition is bound to a #div, which is added to @browser. These changes are summarized in the first column of the table below.

- -

At t2, a new #time is added to @session, and the one from t1 is removed. Since we used a bind, this causes the existing #div to be removed from @browser, but it is replaced with a new #div reflecting the current time. At t3, the same operations takes place, and this process continues until the program is terminated.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - -t0 - -t1 - -t2 - -t3 -
-delta - - - -+ [#time seconds: 39] -+ [#div text: "39"] - -+ [#time seconds: 40] -- [#time seconds: 39] -+ [#div text: "40"] -- [#div text: "39"] - -+ [#time seconds: 41] -- [#time seconds: 40] -+ [#div text: "41"] -- [#div text: "40"] -
-@session - -[ ] - -[[#time seconds: 39]] - -[[#time seconds: 40]] - -[[#time seconds: 41]] -
-@browser - -[ ] - -[[#div text: 39]] - -[[#div text: 40]] - -[[#div text: 41]] -
- -

Let’s perform the same analysis in the commit case. In this program, things start off the same; initially the database is empty, and at t1 a #time and a #div are added to their respective databases. At t2, things get more interesting. While the old #time is still replaced, the #div displaying the old time is not replaced since we committed it to @browser. Indeed, in subsequent rounds of execution, the contents of @browser keeps growing.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - -t0 - -t1 - -t2 - -t3 -
-delta - - -+ [#time seconds: 39] -+ [#div text: "39"] - -+ [#time seconds: 40] -- [#time seconds: 39] -+ [#div text: "40"] - -+ [#time seconds: 41] -- [#time seconds: 40] -+ [#div text: "41"] -
-@session - -[ ] - -[[#time seconds: 39]] - -[[#time seconds: 40]] - -[[#time seconds: 41]] -
-@browser - -[ ] - -[[#div text: 39]] - -[[#div text: 39], - [#div text: 40]] - -[[#div text: 39], - [#div text: 40], - [#div text: 41]] -
- -

Tips

- -

When you want to display data in an interface element like a #div, a bind is usually the more appropriate choice compared to a commit. A bind will keep the interface element always up-to-date, whereas a commit will leave lingering elements that no longer reflect the current state of the program.

- -

When searching for an event like a #click, a commit is usually more appropriate than bind. When an event occurs, a record representing the event is added to a database. That record exists for exactly one “instant”, and then it is removed from the database. During that “instant”, any block searching for that event will be satisfied and can execute a bind or commit action. If you bind on the event, then the result will disappear as soon as the event does. However, if you commit on the event, then that result will persist after the event has been removed.

- -

Examples

- -

Initialize a counter when a session connects

-
search
-  [#session-connect]
-
-commit
-  [#counter count: 0]
-
- -

Increment a counter when a button is clicked

-
search
-  [#click element: [#count-button diff counter]]
-
-commit
-  counter.count := counter.count + diff
-
- -

See Also

- -

bind | databases | search

- - -
-
- -
- diff --git a/src/handbook/commonmark.md b/handbook/commonmark.md similarity index 100% rename from src/handbook/commonmark.md rename to handbook/commonmark.md diff --git a/handbook/commonmark/index.html b/handbook/commonmark/index.html deleted file mode 100644 index cb3d8fc..0000000 --- a/handbook/commonmark/index.html +++ /dev/null @@ -1,474 +0,0 @@ - - - - - - - - - - - - CommonMark - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

CommonMark

- -

Eve documents are compatible with CommonMark

- -

Syntax

- -

Headings

- -
# heading1
-## heading2
-### heading3
-
- -

Emphasis

- -
*italic*
-_italic_
-**bold**
-__bold__
-
- - - -
[link](address)
-
-[link][ref]
-[ref] : address
-
- -

Lists

- -
- list item
-- list item2
-  - sublist item
-
-* list item
-* list item2
-  * sublist item
-
-1. ordered list1
-2. ordered list2
-
-1) ordered list1
-2) ordered list2
-
- -

Quotes

- -
> blockquote
-
- -

Code

- -
```
-  a block of code
-```
-
-`Inline code` with backticks
-
- -

Description

- -

CommonMark is an effort to standardize and remove ambiguity from the Markdown language. Eve uses CommonMark as the basis for formatting and rendering prose contained in Eve files. Eve code is written as code blocks within a document specified in CommonMark. Code blocks are delinated by code fences, three backtics before and after Eve code. Everything within a code block is treated as Eve code.

- -

Examples

- -

See Also

- -

literate programming | blocks | programming model

- - -
-
- -
- diff --git a/src/handbook/core.md b/handbook/core.md similarity index 100% rename from src/handbook/core.md rename to handbook/core.md diff --git a/handbook/core/index.html b/handbook/core/index.html deleted file mode 100644 index 54e2f13..0000000 --- a/handbook/core/index.html +++ /dev/null @@ -1,410 +0,0 @@ - - - - - - - - - - - - - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

Core Language

- -

See Also

- -

records | equivalence | actions | expressions | update operators | databases

- - -
-
- -
- diff --git a/handbook/databases.md b/handbook/databases.md new file mode 100644 index 0000000..ceb976b --- /dev/null +++ b/handbook/databases.md @@ -0,0 +1,102 @@ +# Databases + +Databases contain records + +## Syntax + +```eve +// search action +search @database1, ..., @databaseN + +// Commit action +commit @database1, ..., @databaseN + +// Bind action +bind @database1, ..., @databaseN +``` + +## Description + +` @database` performs the given action, one of `search`, `bind`, or `commit`, on the union of the provided databases. + +If no database is provided with an action, then that action is performed on the default `@session` database. + +## Creating and Searching Databases + +You can create databases on-demand by simply committing a record to one. e.g. + +``` +commit @my-database + [#my-record] +``` + +This block will create a new database called "my-database", which will contain the newly committed record. You can now search for this record in your new database: + +``` +search @my-database + [#my-record] + +bind @browser + [#div text: "Found a record!"] +``` + +## Special Databases + +Eve has some built-in databases that have meaning to the runtime. + +- [@session](../session) - the default database when no database is specified with an action. +- [@view](../view) - records committed to `@view` are used to visualize data. +- [@event](../event) - contains events originating from the DOM +- [@browser](../browser) - Eve clients running in the browser render applicable records in this `@browser` as HTML elements. +- [@http](../http) - Stores records representing HTTP requests and responses + +## Examples + +Display the element that was clicked in the DOM + +```eve +search @event + [#click #direct-target element] + +commit @browser + [#div text: "{{element}} was clicked."] +``` + +Commit some data in `@session`, and then display it on a button click. + +``` +commit + [#for-display text: "Hello"] +``` + +We are searching over three databases to complete this block. + +- the `#click` is in `@event` +- the `#button` is in `@browser` +- the text for display is in `@session`. This needs to be made explicit; since we are searching in other databases, `@session` is not searched implicitly. + +``` +search @event @browser @session + [#click element: [#button]] + [#for-display text] + +commit @browser + [#div text] +``` + +This block could have been written with two searches for the same effect: + +``` +search @event @browser + [#click element: [#button]] + +search + [#for-display text] + +commit @browser + [#div text] +``` + +## See Also + +[search](../search) | [bind](../bind) | [commit](../commit) \ No newline at end of file diff --git a/handbook/databases/index.html b/handbook/databases/index.html deleted file mode 100644 index dedfc06..0000000 --- a/handbook/databases/index.html +++ /dev/null @@ -1,449 +0,0 @@ - - - - - - - - - - - - Databases - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

Databases

- -

databases contain records

- -

Syntax

-
// search action
-search @database1, ..., @databaseN
-
-// Commit action
-commit @database1, ..., @databaseN
-
-// Bind action
-bind @database1, ..., @databaseN
-
- -

Description

- -

<action> @database performs the given action, one of search, bind, or commit, on the union of the provided databases.

- -

If no database is provided with an action, then that action is performed on the default @session database.

- -

Special Databases

- -
    -
  • @session - the default database, stores any record not associated explicitly with a database

  • - -
  • @event - holds records generated by user events in the DOM

  • - -
  • @browser - records stored in @browser are rendered as HTML by the browser

  • -
- -

Examples

- -

Display a message when the DOM is clicked

-
search @event
-  [#click #direct-target element]
-
-commit @browser
-  [#div text: "{{element}} was clicked."]
-
- -

See Also

- -

search | bind | commit

- - -
-
- -
- diff --git a/handbook/datetime/date/index.html b/handbook/datetime/date/index.html deleted file mode 100644 index 75af999..0000000 --- a/handbook/datetime/date/index.html +++ /dev/null @@ -1,433 +0,0 @@ - - - - - - - - - - - - date - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

date

- -

provides the current date

- -

Syntax

-
[#date day month year]
-
- -

Attributes

- -
    -
  • day - current numeric day
  • -
  • month - current numeric month
  • -
  • year - current numeric year
  • -
- -

Description

- -

Provides the current day as reported by the system clock.

- -

Time updates at the frequency of the smallest selected in the record.

- -

Examples

- -

Prints the current date as a formatted string.

-
search
-  [#date month day year]
-
-bind @browser
-  [#div text: "Today is {{month}}/{{day}}/{{year}}"]
-
- -

See Also

- -

time

- - -
-
- -
- diff --git a/handbook/datetime/index.html b/handbook/datetime/index.html deleted file mode 100644 index 4f70de8..0000000 --- a/handbook/datetime/index.html +++ /dev/null @@ -1,410 +0,0 @@ - - - - - - - - - - - - Date & Time - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

Date & Time

- -
    -
  • time - The current system time
  • -
- - -
-
- -
- diff --git a/src/handbook/datetime/index.md b/handbook/datetime/index.md similarity index 64% rename from src/handbook/datetime/index.md rename to handbook/datetime/index.md index 98e4ca1..7081433 100644 --- a/src/handbook/datetime/index.md +++ b/handbook/datetime/index.md @@ -3,8 +3,9 @@ menu: main: parent: "Standard Library" title: "Date & Time" +weight: 5 --- # Date & Time -- [time](time.md) - The current system time \ No newline at end of file +- [time](time) - The current system time \ No newline at end of file diff --git a/src/handbook/datetime/time.md b/handbook/datetime/time.md similarity index 100% rename from src/handbook/datetime/time.md rename to handbook/datetime/time.md diff --git a/handbook/datetime/time/index.html b/handbook/datetime/time/index.html deleted file mode 100644 index 3029160..0000000 --- a/handbook/datetime/time/index.html +++ /dev/null @@ -1,461 +0,0 @@ - - - - - - - - - - - - time - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

time

- -

provides the current time

- -

Syntax

-
[#time year 
-       month 
-       day 
-       hours 
-       hours-24 
-       minutes 
-       seconds 
-       time-string 
-       time seconds 
-       frames 
-       ampm]
-
- -

Attributes

- -
    -
  • year - the current year
  • -
  • month - the current month from 0 to 11
  • -
  • day - the current day of the month from 1 to 31
  • -
  • hours - current hour from 0 to 11
  • -
  • hours-24 - current hour from 0 to 23
  • -
  • minutes - current minute from 0 to 59
  • -
  • seconds - current second from 0 to 59
  • -
  • time-string - the current time in a string of the form HH:MM AM/PM
  • -
  • timestamp - the number of milliseconds since midnight January 1, 1970
  • -
  • ampm - a string indicating morning or evening
  • -
  • frames - the number of frames elapsed since the program began. This fastest updating attribute on #time, refreshing evey 16 milliseconds.
  • -
- -

Description

- -

Provides the current time as reported by the system clock.

- -

Time updates at the frequency of the smallest unit of time selected in the record.

- -

Examples

- -

Prints the current time as a formatted string.

-
search
-  [#time hours minutes seconds]
-
-bind @browser
-  [#div text: "The time is {{hours}}:{{minutes}}:{{seconds}}"]
-
- -

Example Usage

- - - - -
-
- -
- diff --git a/handbook/docker.md b/handbook/docker.md new file mode 100644 index 0000000..9ccb7a7 --- /dev/null +++ b/handbook/docker.md @@ -0,0 +1,39 @@ +--- +menu: + main: + parent: "Getting Eve" +title: "Docker" +weight: 4 +--- + +# Eve in Docker + +A Docker container for Eve is available on [Docker Hub](https://hub.docker.com/r/witheve/eve/). After [installing Docker](http://www.docker.com/products/docker) for your platform, you can download our container with the following command: + +``` +docker pull witheve/eve +``` + +Windows Users - Docker for Windows requires Microsoft Hyper-V, which requires Windows 10. + +## Examples + +To run the Docker container, execute: + +``` +docker run -p [port]:8080 witheve/eve +``` + +`[port]` is an available port on your local machine. It can be 8080 or any other port you would like. Then direct your browser to `http://localhost:[port]` to access the editor. + +`[eve_file]` is a path to a `*.eve` file you would like to build. The working directory of the container is `eve/build`, so to run a program in the `eve/examples` directory, you need to provide a relative path e.g. + +``` +docker -p 8080:8080 witheve/eve +``` + +To pass Eve files on your local machine into the container, you'll need to mount a [docker volume](https://docs.docker.com/engine/tutorials/dockervolumes/). + +## See also + +[linux](../linux) | [mac](../mac) | [windows](../windows) | [npm](../npm) |[running](../running) \ No newline at end of file diff --git a/src/handbook/ebnf.md b/handbook/ebnf.md similarity index 100% rename from src/handbook/ebnf.md rename to handbook/ebnf.md diff --git a/handbook/ebnf/index.html b/handbook/ebnf/index.html deleted file mode 100644 index 341c341..0000000 --- a/handbook/ebnf/index.html +++ /dev/null @@ -1,503 +0,0 @@ - - - - - - - - - - - - Grammar - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

Eve EBNF grammar

- -

The following specification is expressed in Extended Backus–Naur Form

- -

Basics

-
newline = "\n"
-whitespace =  " " | "\t" | "," | newline;
-unicode = ? all unicode chars - whitespace ?;
-specials = "@" | "#" | "." | "," | "(" | ")" | "[" | "]" | "{" | "}" | "⦑" | "⦒" | ":" | "\"";
-non-special = unicode - specials;
-
- -

Values

-
none = "none";
-boolean = "true" | "false";
-numeric = "0" .. "9";
-number = ["-"] {numeric} ["." {numeric}];
-string-interpolation = "{{" expression "}}";
-string = "\"" {string-interpolation | unicode - "\"" | "\\\"" | whitespace} "\"";
-uuid ="⦑" (unicode - specials)  "⦒"
-
- -

Keywords and Identifiers

-
search = "search";
-action = "bind" | "commit";
-if = "if";
-then = "then";
-else = "else";
-is = "is";
-not = "not";
-none = "none";
-keyword = search | action | if | then | else | boolean | is | not | none
-non-special-non-numeric = non-special - numeric
-identifier = (non-special-non-numeric {non-special}) - keyword - "```";
-
- -

Comparisons

-
equality = ":" | "=";
-comparator = equality | ">" | "<" | ">=" | "<=" | "!=";
-comparison = expression whitespace+ comparator whitespace+ expression;
-
- -

Functions

-
infix-op = "*" | "+" | "-" | "/";
-infix = expression infix-op expression;
-function = identifier "[" [attribute] {whitespace+ attribute} "]";
-
- -

Records and Attributes

-
record = "[" [attribute] {whitespace+ attribute} "]"
-attribute = name | tag | attribute-not | identifier {whitespace+ comparator whitespace+ expression};
-name = "@" (identifier | string);
-tag = "#" (identifier | string);
-attribute-not = not "(" whitespace* identifier [comparator whitespace+ expression] ")";
-attribute-access = identifier whitespace* {"." whitespace* identifier}+
-
- -

Special Forms

-
not-statement = not "(" statement {whitespace+ statement} ")";
-is-expression = is "(" comparison ")";
-
- -

Expression

-
expression = number | identifier | function | infix | record | attribute-access;
-
- -

Statements

-
comment = "//" {unicode | whitespace - newline} newline
-statement = record | function | not-statement | if-statement | comparison | comment
-
- -

Action Statements

-
create-action = (identifier whitespace+ equality whitespace+ record) | record
-merge-action = (identifier | attribute-access) whitespace+ "<-" whitespace+ record
-name-tag-action = (identifier | attribute-access) whitespace+ ("+=" | "-=") whitespace+ (name | tag)
-remove-action = (identifier | attribute-access) whitespace+ ":=" whitespace+ none
-attribute-action = attribute-access whitespace+ (":=" | "+=" | "-=") whitespace+ expression
-action-operation = create-action | merge-action | name-tag-action | remove-action | attribute-action
-
- -

If-Then

-
group = "(" expression {whitespace+ expression} ")"
-binding-group = "(" identifier {whitespace+ identifier} ")"
-if-result = (group | expression);
-if-expression = if whitespace+ {statement whitespace+} then whitespace+ if-result;
-else-if-expression = else whitespace+ if whitespace+ {statement whitespace+} then whitespace+ if-result;
-else-expression = else whitespace+ if-result
-if-statement = (identifier | binding-group) whitespace+ equality whitespace+
-               if-expression
-               {whitespace+ (if-expression | else-if-expression)}
-               [else-expression]
-
- -

Sections

-
database-declaration = name | "(" {name whitespace+} ")"
-match-section = search whitespace+ [database-declaration whitespace+] {statement whitespace}
-action-section = action whitespace+ [database-declaration whitespace+] {action-statement whitespace}
-section = match-sectiong | action-section
-
- -

Program and Blocks

-
fence-symbol = "```"
-start-fence = newline fence-symbol [whitespace* (unicode - newline)] newline
-end-fence = newline fence-symbol newline
-block = start-fence {section} end-fence
-program = {unicode | whitespace | block}
-
- - -
-
- -
- diff --git a/src/handbook/equality.md b/handbook/equality.md similarity index 100% rename from src/handbook/equality.md rename to handbook/equality.md diff --git a/handbook/equality/index.html b/handbook/equality/index.html deleted file mode 100644 index bebfeaf..0000000 --- a/handbook/equality/index.html +++ /dev/null @@ -1,459 +0,0 @@ - - - - - - - - - - - - Equality - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

Equality

- -

= and : assert the equality of two values

- -

Syntax

-
// Use : in a record to bind an attribute to a value
-[attribute: value]
-
-// Use = outside a record to bind an attribute to a value
-[attribute]
-attribute = value
-
- -

Description

- -

[attribute: value] binds value to attribute, so that only records with attributes of the given value are returned. For instance, [name: "John"] selects all records with a name attribute equal to “John”. You can achieve the same effect with the = operator by first searching for a record. For instance:

-
[name]
-name = "John"
-
- -

This example further demonstrates that in Eve, variables with the same name are equivalent. Here, name inside the record and name on the second line are the same. This has particular implications, especially in the context of joining records. For instance:

-
search
-  [#student name school: name]
-  [#school name address]
-
- -

This block searches for #students and #schools with the same name. This means if you have a school named “South High School”, it won’t match unless there is also a student named “South High School”. If you want to use attributes, but don’t want to join on them, you can access them via dot notation.

-
search
-  [#student name school: schools.name]
-  schools = [#school address]
-
- -

This will correctly allow us to relate students and the addresses of the schools they attend.

- -

Tips

- -

Eve has two identical equivalency operators, : and =. They have the same semantic meaning, and could be used interchangeably. However, for readability reasons we encourage you to use : to express equality within records, and = outside of records. For example [attribute: value] is good, while we don’t encourage [attribute = value], even though it is semantically equivalent.

- -

Examples

- -

The following block will never execute the bind action because of a contradiction in the search:

-
search
-  x = 10
-  x = 20
-
-bind @browser
-  [#div text: "This will never display"]
-
- -

The search action says that x = 10 and x = 20, which is never true. Since there is no order or assignment in Eve, this statement does not first set x to 10 and then to 20. To see this more clearly, these two statements could be written as one:x = 10 = 20.

- -

See Also

- -

inequality | joins

- - -
-
- -
- diff --git a/src/handbook/equivalence.md b/handbook/equivalence.md similarity index 100% rename from src/handbook/equivalence.md rename to handbook/equivalence.md diff --git a/handbook/equivalence/index.html b/handbook/equivalence/index.html deleted file mode 100644 index 29ee5f1..0000000 --- a/handbook/equivalence/index.html +++ /dev/null @@ -1,416 +0,0 @@ - - - - - - - - - - - - Equivalence - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

Equivalence

- -
    -
  • Equality - Expresses when two statements are equality
  • -
  • Inequality - Expresses the relationship between two statements when they are not equality
  • -
  • Joins - Relate disjoint records by binding attributes from one with the other.
  • -
- -

See Also

- -

equality | inequality | joins

- - -
-
- -
- diff --git a/handbook/event/change.md b/handbook/event/change.md new file mode 100644 index 0000000..cf7cae0 --- /dev/null +++ b/handbook/event/change.md @@ -0,0 +1,53 @@ +--- +menu: + main: + parent: "@event" +title: "change" +--- + +# change + +change event + +## Syntax + +``` +[#change] +[#change element] +[#change #direct-target element] +``` + +## Attributes + +- `#direct-target` - selects only directly changed elements, as opposed to elements to which the event bubbles. +- `element` - the element that changed. + +## Description + +When an element in the DOM has changed, a `#change` record is created in the `@event` database. + +## Examples + +Initialize the DOM with a `select` element: + +```eve +commit @browser + [#select #countries children: + [#option text: "italy"] + [#option text: "france"] + [#option text: "spain"] + ] +``` + +Listen for `change` event emitted from `select` element when a country has been selected: + +```eve +search @session @browser @event + element = [#change element: [#select #countries]] + +commit @view + [#value | value: "{{element.value}}"] // it will print "italy", "france" or "spain" +``` + +## See Also +[click](../click) diff --git a/src/handbook/events/click.md b/handbook/event/click.md similarity index 52% rename from src/handbook/events/click.md rename to handbook/event/click.md index 8a317ac..021d48b 100644 --- a/src/handbook/events/click.md +++ b/handbook/event/click.md @@ -1,7 +1,7 @@ --- menu: main: - parent: "Events" + parent: "@event" title: "click" --- @@ -28,4 +28,23 @@ When an element in the DOM is clicked, a `#click` record is created in the `@eve ## Examples -## See Also \ No newline at end of file +Initialize the DOM with a `button` element: + +```eve +commit @browser + [#button #btnHello text: "Click Me"] +``` + +Listen for `click` event emitted from `button` element it gets clicked: + +```eve +search @session @browser @event + [#click element: [#button #btnHello]] + +commit @view + [#value | value: "The button has been clicked"] +``` + + +## See Also +[change](../change) diff --git a/handbook/event/index.md b/handbook/event/index.md new file mode 100644 index 0000000..ca0ecde --- /dev/null +++ b/handbook/event/index.md @@ -0,0 +1,17 @@ +--- +menu: + main: + parent: "Databases" +title: "@event" +weight: 3 +--- + +# @event + +[click](click) - a left-button mouse click event + +[change](change) - an element change event + +[keydown](keydown) - a key down event + +[keyup](keyup) - a key up event diff --git a/handbook/event/keydown.md b/handbook/event/keydown.md new file mode 100644 index 0000000..b13a0e0 --- /dev/null +++ b/handbook/event/keydown.md @@ -0,0 +1,38 @@ +--- +menu: + main: + parent: "@event" +title: "keydown" +--- + +# keydown + +key down event + +## Syntax + +``` +[#keydown] +[#keydown element] +``` + +## Attributes + +- `element` - the element on which the key was pressed. + +## Description + +When a key is pressed when an element in the DOM is focused, a `#keydown` record is created in the `@event` database. + +## Examples + +```eve +search @event + event = [#keydown key] + +commit @browser + [#span text: "key pressed: {{key}}" event] +``` + +## See Also +[keyup](../keyup) diff --git a/handbook/event/keyup.md b/handbook/event/keyup.md new file mode 100644 index 0000000..592331c --- /dev/null +++ b/handbook/event/keyup.md @@ -0,0 +1,38 @@ +--- +menu: + main: + parent: "@event" +title: "keyup" +--- + +# keyup + +key up event + +## Syntax + +``` +[#keyup] +[#keyup element] +``` + +## Attributes + +- `element` - the element on which the key was released. + +## Description + +When a key is released when an element in the DOM is focused, a `#keyup` record is created in the `@event` database. + +## Examples + +```eve +search @event + event = [#keyup key] + +commit @browser + [#span text: "key released: {{key}}" event] +``` + +## See Also +[keydown](../keydown) diff --git a/handbook/events/click/index.html b/handbook/events/click/index.html deleted file mode 100644 index 2fe4b6e..0000000 --- a/handbook/events/click/index.html +++ /dev/null @@ -1,430 +0,0 @@ - - - - - - - - - - - - click - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

click

- -

click event

- -

Syntax

- -
[#click]
-[#click element]
-[#click #direct-target element]
-
- -

Attributes

- -
    -
  • #direct-target - selects only directly clicked elements, as opposed to elements to which the event bubbles.
  • -
  • element - the element that was clicked.
  • -
- -

Description

- -

When an element in the DOM is clicked, a #click record is created in the @event database.

- -

Examples

- -

See Also

- - -
-
- -
- diff --git a/handbook/events/index.html b/handbook/events/index.html deleted file mode 100644 index c456992..0000000 --- a/handbook/events/index.html +++ /dev/null @@ -1,408 +0,0 @@ - - - - - - - - - - - - Events - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

Events

- -

click - a left-button mouse click event

- - -
-
- -
- diff --git a/src/handbook/expressions.md b/handbook/expressions.md similarity index 100% rename from src/handbook/expressions.md rename to handbook/expressions.md diff --git a/handbook/expressions/index.html b/handbook/expressions/index.html deleted file mode 100644 index dc546d0..0000000 --- a/handbook/expressions/index.html +++ /dev/null @@ -1,418 +0,0 @@ - - - - - - - - - - - - Expressions - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
- - -
- diff --git a/src/handbook/functions.md b/handbook/functions.md similarity index 70% rename from src/handbook/functions.md rename to handbook/functions.md index 0875e5a..8fd844c 100644 --- a/src/handbook/functions.md +++ b/handbook/functions.md @@ -51,11 +51,11 @@ Let's look at what makes Eve functions different. ## Explicit Arguments -A function's arguments are enclosed in square brackets to draw attention to the fact that functions in Eve are just regular records. Also like records, arguments are stateted explicitly. This has several advantages over typical calling patterns: +A function's arguments are enclosed in square brackets to draw attention to the fact that functions in Eve are just regular records. Also like records, arguments are stated explicitly. This has several advantages over typical calling patterns: - Explicit arguments are self-documenting, so a reader unfamiliar with the function can understand more about the function without looking up exactly how it works. In the case of `sin`, you don't have to know whether the inputs have to be in radians or degrees; the call-site tells you. -- Eve provides alternative calling patterns for functions. Some languages have two `sin` functions, one for angles in randians and another for angles in degrees. By contrast, Eve has a single `sin` function. If your angles are in randians, you call `sin[radians]`, whereas if your angles are in degrees, you call `sin[degrees]`. +- Eve provides alternative calling patterns for functions. Some languages have two `sin` functions, one for angles in radians and another for angles in degrees. By contrast, Eve has a single `sin` function. If your angles are in radians, you call `sin[radians]`, whereas if your angles are in degrees, you call `sin[degrees]`. - Like all records, you can state arguments in any order. This opens up an easy path for optional arguments: include the arguments you want and leave out the ones you don't. @@ -65,29 +65,7 @@ All expressions in Eve are referentially transparent, meaning you can replace th ## Set Semantics -In Eve, functions work over sets, meaning that a function will be applied to all elements of the input sets, resulting in an output that is itself a set. For example, lets say we have some points with x and y coordinates: - -```eve -commit - [#point x: 5, y: 4] - [#point x: 3, y: 7] - [#point x: 1, y: 2] -``` - -We can calculate the distance from each of these points to every other point: - -```eve -search - p1 = [#point x: x1, y: y1] - p2 = [#point x: x2, y: y2] - dx = x1 - x2 - dy = y1 - y2 - -bind @browser - [#div sort: x1, text: "({{x1}}, {{y1}}) - ({{x2}}, {{y2}}) = ({{dx}}, {{dy}})"] - ``` - -In imperative languages, you would need a nested loop to cover all of the combinations. In Eve, functions (and infix operators like `-`, which are just sugar for a function) operate over sets, so this loop is implicitly handled by Eve. +In Eve, functions work over sets, meaning that a function will be applied to all elements of the input sets, resulting in an output that is itself a set. For more, see the document on [set semantics](../sets). ## See Also diff --git a/handbook/functions/index.html b/handbook/functions/index.html deleted file mode 100644 index 25654f0..0000000 --- a/handbook/functions/index.html +++ /dev/null @@ -1,481 +0,0 @@ - - - - - - - - - - - - Functions - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

Functions

- -

Functions map one or more arguments to one or more values.

- -

Syntax

-
// A typical function call
-value = fn[argument]
-
-// A function call with multiple arguments
-value = fn[argument1, ..., argumentN]
-
-// A function call with multiple arguments and multiple return values
-(value1, value2) = fn[argument1, ..., argumentN]
-
-// A desugared function call
-[#fn #function argument1, ... argumentN, value1, ..., valueN]
-
- -

Description

- -

Functions as they exist in other languages are mostly obviated by Eve’s tag semantics. Consider the following function call in a C-family language.

-
// A typical function call
-x = sin(1.5);                              
-
- -

In Eve, we could match a record that operates similarly:

-
[#sin #function radians: 1.5, return: x]
-
- -

These statements accomplish the same objective: store the sine of an angle in a result variable. The Eve syntax is at a disadvantage though, because it cannot be composed into an expression like a typical function. Therefore, specific Eve records can be used as traditional functions:

-
x = sin[radians: 1.5]
-
- -

Let’s look at what makes Eve functions different.

- -

Explicit Arguments

- -

A function’s arguments are enclosed in square brackets to draw attention to the fact that functions in Eve are just regular records. Also like records, arguments are stateted explicitly. This has several advantages over typical calling patterns:

- -
    -
  • Explicit arguments are self-documenting, so a reader unfamiliar with the function can understand more about the function without looking up exactly how it works. In the case of sin, you don’t have to know whether the inputs have to be in radians or degrees; the call-site tells you.

  • - -
  • Eve provides alternative calling patterns for functions. Some languages have two sin functions, one for angles in randians and another for angles in degrees. By contrast, Eve has a single sin function. If your angles are in randians, you call sin[radians], whereas if your angles are in degrees, you call sin[degrees].

  • - -
  • Like all records, you can state arguments in any order. This opens up an easy path for optional arguments: include the arguments you want and leave out the ones you don’t.

  • -
- -

Referential Transparency

- -

All expressions in Eve are referentially transparent, meaning you can replace the expression with its result and the behavior of the program will not change. This in turn means that expressions are side-effect free, and the only thing they depend on is their input arguments. Referential transparency is key to enabling some key features in Eve, like time travel debugging and provenance.

- -

Set Semantics

- -

In Eve, functions work over sets, meaning that a function will be applied to all elements of the input sets, resulting in an output that is itself a set. For example, lets say we have some points with x and y coordinates:

-
commit
-  [#point x: 5, y: 4]
-  [#point x: 3, y: 7]
-  [#point x: 1, y: 2]
-
- -

We can calculate the distance from each of these points to every other point:

-
search
-  p1 = [#point x: x1, y: y1]
-  p2 = [#point x: x2, y: y2]
-  dx = x1 - x2 
-  dy = y1 - y2
-  
-bind @browser
- [#div sort: x1, text: "({{x1}}, {{y1}}) - ({{x2}}, {{y2}}) = ({{dx}}, {{dy}})"]
-
- -

In imperative languages, you would need a nested loop to cover all of the combinations. In Eve, functions (and infix operators like -, which are just sugar for a function) operate over sets, so this loop is implicitly handled by Eve.

- -

See Also

- -

aggregate | set semantics

- - -
-
- -
- diff --git a/handbook/general/index.html b/handbook/general/index.html deleted file mode 100644 index 7793dd1..0000000 --- a/handbook/general/index.html +++ /dev/null @@ -1,410 +0,0 @@ - - - - - - - - - - - - General - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

General

- -
    -
  • sort - Orders elements in a set
  • -
- - -
-
- -
- diff --git a/handbook/general/index.md b/handbook/general/index.md new file mode 100644 index 0000000..f98849f --- /dev/null +++ b/handbook/general/index.md @@ -0,0 +1,11 @@ +--- +menu: + main: + parent: "Standard Library" +title: "General" +weight: 1 +--- + +# General + +- [sort](sort) - Orders elements in a set \ No newline at end of file diff --git a/handbook/general/sort.md b/handbook/general/sort.md new file mode 100644 index 0000000..23bafb1 --- /dev/null +++ b/handbook/general/sort.md @@ -0,0 +1,159 @@ +--- +menu: + main: + parent: "General" +title: "sort" +--- + +# sort + +generates an ordering for a set + +## Syntax + + +```eve +// Sort one or more values +index = sort[value] +index = sort[value: (value1, value2, ...)] + +// Sort one or more values, and specify the direction for each +index = sort[value direction] +index = sort[value: (value1, value2, ...), direction: ("up", "down", ...)] + +// Sort according to some grouping +index = sort[value per] +index = sort[value direction per] +``` + +## Arguments + +- `value` - one or more variables to sort. More than one variable can be provided using a list e.g. `sort[value: (value1, ..., valueN)]`, and they will be sorted in turn. +- `direction - _optional_` - one or more directions by which to sort `value`. If no direction is provided, all variables are sorted from smallest to largest. Possible values are: + - "up" for sorting from smallest to largest. + - "down" for sorting from largest to smallest. +- `per - _optional_` - Instead of sorting the whole set, `per` allows you to divide the set into groups and sort each one. + +The output is a set of indices, each of which maps to an element of the sorted variable. For example, if the value is `("A", "C", "D", "B")`, then index is `(1, 3, 4, 2)`. + +## Description + +Sort generates an index that describes the ordering of an input value. It's important to remember that variables in Eve are sets, and therefore have no ordering. Because of this, `sort` does not reorder value, but it generates a set of indices, each of which maps to an element in value. + +Sort is flexible, and can generate an ordering over multiple dimensions, directions, and groupings. + +`index = sort[value]` generates an ordering of `value` from smallest to largest. + +`index = sort[value direction]` generates an ordering of `value` in a given `direction`. Acceptable values are "up" and "down". + +`index = sort[value: (value1, ... , valueN)]` generates an ordering of a list of values, ordering by `value1` first, then `value2`, and so on. For example, if you have `#person` records with name, age and height attributes, you could sort as follows: + +```eve +search + [#person name age height] + index = sort[value: (age, name, height)] +``` + +This will sort the people first by age, then by name, then by height. + +`index = sort[value: (value1, ... , valueN), direction: (direction1, ... , directionN)]` does the same as above, but you can specify the direction you sort each variable. Acceptable value for direction are "up" and "down". By default, values are sorted in the "up" direction. + +`index = sort[value per]` sorts `value`, grouped by `per`. This divides `value` into groups according to the elements of `per`, and each one is sorted. + +## Examples + +We have #student records with grade (1 - 12), teacher, GPA (0.0 - 4.0) attributes. We can sort the students by grade: + +```eve +search + [#student name grade] + index = sort[value: grade] + +bind @browser + [#div sort: index, text: "{{index}} - {{name}} {{grade}}"] +``` + +The browser handles the task of rendering the divs in the order specified by the `sort`attribute. Taking this further, we can choose the direction of the sortted set, whether "up" or "down". The default direction is "up" when none is specified. + +```eve +search + [#student name grade] + index = sort[value: grade, direction: "down"] + +bind @browser + [#div sort: index, text: "{{index}} - {{name}} {{grade}}"] +``` + +You can also sort across multiple axes of a record. For instance, we can sort grade from 9 to 12, then sort by name from Z - A. + +```eve +search + [#student name grade] + index = sort[value: (grade, name) , direction: ("up","down")] + +bind @browser + [#div sort: index, text: "{{index}} - {{name}} {{grade}}"] +``` + +This can be extended to sort any number of attributes + +```eve +search + [#student name grade teacher GPA] + index = sort[value: (grade, teacher, name, GPA) , direction: ("up", "down", "up", "down")] + +bind @browser + [#div sort: index, text: "{{index}} - {{name}} {{grade}} {{teacher}} {{GPA}}"] +``` + +Finally, we can group sorted attributes with the per argument. Here you can see the difference between sorting by name *then* grade, and sorting by name *per* grade. + +```eve +search + [#student name grade GPA] + index = sort[value: (GPA, name), per: grade] + +bind @browser + [#div sort: index, text: "{{index}} - {{name}} {{grade}}"] +``` + +When you sort per grade, then name is first grouped by grade, and each of those groups is then sorted. This is why index goes from 1-6 instead of 1-20 as in the other examples; Although there are still 20 elements in index, the maximum is 6 because no grade has more than 6 students. You might want to sort data this way in order to display it in a nested structure, such as this: + +```eve +search + [#student name grade teacher] + index = sort[value: name, per: grade] + +bind @browser + [#div grade children: + [#h3 sort: 0, text: "Grade: {{grade}}"] + [#div sort: index, text: "{{index}} {{name}}"]] +``` + +--- + +Commit some test data + +```eve +commit + [#student name: "Mach", grade: 9, teacher: "Mr. Black", GPA: "1.0"] + [#student name: "Pok", grade: 9, teacher: "Mrs. Brown", GPA: "3.4"] + [#student name: "Karima", grade: 9, teacher: "Mr. Black", GPA: "2.4"] + [#student name: "Garth", grade: 9, teacher: "Mrs. Brown", GPA: "2.8"] + [#student name: "Berta", grade: 9, teacher: "Mr. Black", GPA: "2.7"] + [#student name: "Maxine", grade: 10, teacher: "Mr. Red", GPA: "4.0"] + [#student name: "Gwyn", grade: 10, teacher: "Mrs. Blue", GPA: "2.5"] + [#student name: "Ilse", grade: 10, teacher: "Mr. Red", GPA: "3.0"] + [#student name: "Hobert", grade: 11, teacher: "Ms. Green", GPA: "3.2"] + [#student name: "Arlean", grade: 10, teacher: "Mr. Red", GPA: "2.4"] + [#student name: "Ty", grade: 10, teacher: "Mrs. Blue", GPA: "1.7"] + [#student name: "Kermit", grade: 11, teacher: "Ms. Green", GPA: "2.9"] + [#student name: "Cortez", grade: 11, teacher: "Mrs. Orange", GPA: "2.3"] + [#student name: "Polly", grade: 11, teacher: "Ms. Green", GPA: "2.1"] + [#student name: "Damion", grade: 12, teacher: "Mrs. Purple", GPA: "3.8"] + [#student name: "Gretchen", grade: 12, teacher: "Mrs. Yellow", GPA: "2.8"] + [#student name: "Octavio", grade: 12, teacher: "Mrs. Purple", GPA: "3.4"] + [#student name: "Pa", grade: 12, teacher: "Mrs. Yellow", GPA: "3.5"] + [#student name: "Elwanda", grade: 10, teacher: "Mrs. Blue", GPA: "1.3"] + [#student name: "Guadalupe", grade: 11, teacher: "Mrs. Orange", GPA: "3.7"] +``` \ No newline at end of file diff --git a/handbook/general/sort/index.html b/handbook/general/sort/index.html deleted file mode 100644 index 6d74af7..0000000 --- a/handbook/general/sort/index.html +++ /dev/null @@ -1,544 +0,0 @@ - - - - - - - - - - - - sort - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

sort

- -

generates an ordering for a set

- -

Syntax

-
// Sort one or more values
-index = sort[value]
-index = sort[value: (value1, value2, ...)]
-
-// Sort one or more values, and specify the direction for each
-index = sort[value direction]
-index = sort[value: (value1, value2, ...), direction: ("up", "down", ...)]
-
-// Sort according to some grouping
-index = sort[value per]
-index = sort[value direction per]
-
- -

Arguments

- -
    -
  • value - one or more variables to sort. More than one variable can be provided using a list e.g. sort[value: (value1, ..., valueN)], and they will be sorted in turn.
  • -
  • direction - _optional_ - one or more directions by which to sort value. If no direction is provided, all variables are sorted from smallest to largest. Possible values are: - -
      -
    • “up” for sorting from smallest to largest.
    • -
    • “down” for sorting from largest to smallest.
    • -
  • -
  • per - _optional_ - Instead of sorting the whole set, per allows you to divide the set into groups and sort each one.
  • -
- -

The output is a set of indices, each of which maps to an element of the sorted variable. For example, if the value is ("A", "C", "D", "B"), then index is (1, 3, 4, 2).

- -

Description

- -

Sort generates an index that describes the ordering of an input value. It’s important to remember that variables in Eve are sets, and therefore have no ordering. Because of this, sort does not reorder value, but it generates a set of indices, each of which maps to an element in value.

- -

Sort is flexible, and can generate an ordering over multiple dimensions, directions, and groupings.

- -

index = sort[value] generates an ordering of value from smallest to largest.

- -

index = sort[value direction] generates an ordering of value in a given direction. Acceptable values are “up” and “down”.

- -

index = sort[value: (value1, ... , valueN)] generates an ordering of a list of values, ordering by value1 first, then value2, and so on. For example, if you have #person records with name, age and height attributes, you could sort as follows:

- -
search
-  [#person name age height]
-  index = sort[value: (age, name, height)]
-
- -

This will sort the people first by age, then by name, then by height.

- -

index = sort[value: (value1, ... , valueN), direction: (direction1, ... , directionN)] does the same as above, but you can specify the direction you sort each variable. Acceptable value for direction are “up” and “down”. By default, values are sorted in the “up” direction.

- -

index = sort[value per] sorts value, grouped by per. This divides value into groups according to the elements of per, and each one is sorted.

- -

Examples

- -

We have #student records with grade (1 - 12), teacher, GPA (0.0 - 4.0) attributes. We can sort the students by grade:

-
search
-  [#student name grade]
-  index = sort[value: grade]
-
-bind @browser
-  [#div sort: index, text: "{{index}} - {{name}} {{grade}}"]
-
- -

The browser handles the task of rendering the divs in the order specified by the sortattribute. Taking this further, we can choose the direction of the sortted set, whether “up” or “down”. The default direction is “up” when none is specified.

-
search
-  [#student name grade]
-  index = sort[value: grade, direction: "down"]
-  
-bind @browser
-  [#div sort: index, text: "{{index}} - {{name}} {{grade}}"]
-
- -

You can also sort across multiple axes of a record. For instance, we can sort grade from 9 to 12, then sort by name from Z - A.

-
search
-  [#student name grade]
-  index = sort[value: (grade, name) , direction: ("up","down")]
-
-bind @browser
-  [#div sort: index, text: "{{index}} - {{name}} {{grade}}"]
-
- -

This can be extended to sort any number of attributes

-
search
-  [#student name grade teacher GPA]
-  index = sort[value: (grade, teacher, name, GPA) , direction: ("up", "down", "up", "down")]
-
-bind @browser
-  [#div sort: index, text: "{{index}} - {{name}} {{grade}} {{teacher}} {{GPA}}"]
-
- -

Finally, we can group sorted attributes with the per argument. Here you can see the difference between sorting by name then grade, and sorting by name per grade.

-
search
-  [#student name grade GPA]
-  index = sort[value: (GPA, name), per: grade]
-  
-bind @browser
-  [#div sort: index, text: "{{index}} - {{name}} {{grade}}"]
-
- -

When you sort per grade, then name is first grouped by grade, and each of those groups is then sorted. This is why index goes from 1-6 instead of 1-20 as in the other examples; Although there are still 20 elements in index, the maximum is 6 because no grade has more than 6 students. You might want to sort data this way in order to display it in a nested structure, such as this:

-
search
-    [#student name grade teacher]
-  index = sort[value: name, per: grade]
-  
-bind @browser
-  [#div grade children: 
-    [#h3 text: "Grade: {{grade}}"]
-    [#div sort: index, text: "{{index}} {{name}}"]]
-
- -
- -

Commit some test data

-
commit
-  [#student name: "Mach", grade: 9, teacher: "Mr. Black", GPA: "1.0"]
-  [#student name: "Pok", grade: 9, teacher: "Mrs. Brown", GPA: "3.4"]
-  [#student name: "Karima", grade: 9, teacher: "Mr. Black", GPA: "2.4"]
-  [#student name: "Garth", grade: 9, teacher: "Mrs. Brown", GPA: "2.8"]
-  [#student name: "Berta", grade: 9, teacher: "Mr. Black", GPA: "2.7"]
-  [#student name: "Maxine", grade: 10, teacher: "Mr. Red", GPA: "4.0"]
-  [#student name: "Gwyn", grade: 10, teacher: "Mrs. Blue", GPA: "2.5"]
-  [#student name: "Ilse", grade: 10, teacher: "Mr. Red", GPA: "3.0"]
-  [#student name: "Hobert", grade: 11, teacher: "Ms. Green", GPA: "3.2"]
-  [#student name: "Arlean", grade: 10, teacher: "Mr. Red", GPA: "2.4"]
-  [#student name: "Ty", grade: 10, teacher: "Mrs. Blue", GPA: "1.7"]
-  [#student name: "Kermit", grade: 11, teacher: "Ms. Green", GPA: "2.9"]
-  [#student name: "Cortez", grade: 11, teacher: "Mrs. Orange", GPA: "2.3"]
-  [#student name: "Polly", grade: 11, teacher: "Ms. Green", GPA: "2.1"]
-  [#student name: "Damion", grade: 12, teacher: "Mrs. Purple", GPA: "3.8"]
-  [#student name: "Gretchen", grade: 12, teacher: "Mrs. Yellow", GPA: "2.8"]
-  [#student name: "Octavio", grade: 12, teacher: "Mrs. Purple", GPA: "3.4"]
-  [#student name: "Pa", grade: 12, teacher: "Mrs. Yellow", GPA: "3.5"]
-  [#student name: "Elwanda", grade: 10, teacher: "Mrs. Blue", GPA: "1.3"]
-  [#student name: "Guadalupe", grade: 11, teacher: "Mrs. Orange", GPA: "3.7"]
-
- - -
-
- -
- diff --git a/src/handbook/glossary.md b/handbook/glossary.md similarity index 98% rename from src/handbook/glossary.md rename to handbook/glossary.md index 11c188d..5891875 100644 --- a/src/handbook/glossary.md +++ b/handbook/glossary.md @@ -6,7 +6,7 @@ title: "Glossary" weight: 100 --- -# Glosasry +# Glossary ## Cardinality @@ -32,7 +32,7 @@ Provenance is the record and history of data and its place of origin. In Eve, pr Records are composed of facts. In Eve, you select records from the database by supplying a pattern of attributes, and any records matching that pattern are returned to you. For example, a record might be the ages, salaries, and departments of employees. -## Referential Transparentcy +## Referential Transparency An expression is [referentially transparency](https://en.wikipedia.org/wiki/Referential_transparency) if it can be replaced with its result without changing the behavior of the program. Expression that are not referentially transparent tend to have side effects, or rely on state that is not supplied as part of the input arguments, but through a side channel. diff --git a/handbook/glossary/index.html b/handbook/glossary/index.html deleted file mode 100644 index 2541aaa..0000000 --- a/handbook/glossary/index.html +++ /dev/null @@ -1,438 +0,0 @@ - - - - - - - - - - - - Glossary - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

Glosasry

- -

Cardinality

- -

Cardinality is the number of elements in a set. For example, the set (5, 4, 2) contains three elements, so the cardinality of the set is 3.

- -

Cartesian Product

- -

The Cartesian product A × B of two sets A and B is the set of ordered pairs (a,b) where a ∈ A and b ∈ B. For example, if A = (1, 2) and B = ("A", "B"), then A x B = ((1,"A"), (1, "B"), (2, "A"), (2, "B")).

- -

Entity

- -

Entities are unique IDs in the Eve DB. An entity can represent anything - a person, a business, a message, an application, a button, etc.

- -

Fact

- -

Facts describe entities. Each fact is composed of an attribute and a value, and is associated with a specific entity. Facts might be a person’s age, an employee’s salary, a department’s budget, etc.

- -

Provenance

- -

Provenance is the record and history of data and its place of origin. In Eve, provenance tells you how a value is calculated by looking back at the history of its computation. Provenance can be used to precisely identify the cause of unexpected data in your application.

- -

Record

- -

Records are composed of facts. In Eve, you select records from the database by supplying a pattern of attributes, and any records matching that pattern are returned to you. For example, a record might be the ages, salaries, and departments of employees.

- -

Referential Transparentcy

- -

An expression is referentially transparency if it can be replaced with its result without changing the behavior of the program. Expression that are not referentially transparent tend to have side effects, or rely on state that is not supplied as part of the input arguments, but through a side channel.

- -

Set

- -

In mathematics, a set is a collection of elements where each element is unique. Sets have no order, so position in the set does not imply uniqueness. For example (1, 2, 3) is a set, whereas (1, 2, 1, 3) is not a set, because 1 appears twice. Furthermore, this means that (1, 2, 3) is equivalent to (3, 1, 2), (3, 2, 1), and (1, 3, 2) because they have the same elements regardless of order. Elements of a set can be anything, and therefore can be sets themselves. To make the previous collection a set we could do the following: ((1,A), (2,B), (1,C), (3,D)).

- - -
-
- -
- diff --git a/src/handbook/help.md b/handbook/help.md similarity index 100% rename from src/handbook/help.md rename to handbook/help.md diff --git a/handbook/help/index.html b/handbook/help/index.html deleted file mode 100644 index 1cb5873..0000000 --- a/handbook/help/index.html +++ /dev/null @@ -1,435 +0,0 @@ - - - - - - - - - - - - Getting Help - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

Getting Help

- -

If you have any questions or get stuck while you are learning Eve, there are several ways to get help:

- -

Before reaching out, make sure you’ve looked at the following resources:

- -
    -
  • Read the quick start guide. It contains everything you’ll need to build your first Eve program.
  • -
  • Read the syntax reference. It summarizes the syntax of Eve on a single sheet of paper.
  • -
- -

If you’re still stuck, you can get in touch with Eve developers and the community through these channels:

- -
    -
  • Send a message to the mailing list. We generally respond to messages within a day.
  • -
  • Send a tweet to @with_eve.
  • -
  • Submit an issue to our GitHub repository.
  • -
  • Join the Eve Slack channel to talk with Eve developers and the community in real time (coming soon)
  • -
- -

Hare are some more resources to help you learn Eve:

- -
    -
  • Browse our growing catalog of example applications for something similar to what you’re doing.
  • -
  • Read our development blog to learn more about what goes on behind the scenes at Eve.
  • -
- -

See Also

- -

guides | tutorials | mailing list | @with_eve | GitHub

- - -
-
- -
- diff --git a/handbook/http/index.md b/handbook/http/index.md new file mode 100644 index 0000000..bcfb512 --- /dev/null +++ b/handbook/http/index.md @@ -0,0 +1,10 @@ +--- +menu: + main: + parent: "Databases" +title: "@http" +weight: 4 +--- + +# @http + diff --git a/src/handbook/if-then.md b/handbook/if-then.md similarity index 100% rename from src/handbook/if-then.md rename to handbook/if-then.md diff --git a/handbook/if-then/index.html b/handbook/if-then/index.html deleted file mode 100644 index 27a53c7..0000000 --- a/handbook/if-then/index.html +++ /dev/null @@ -1,482 +0,0 @@ - - - - - - - - - - - - if-then - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

If-Then

- -

Conditional equivalence

- -

Syntax

-
result = if record then value
-  
-result = if record then value
-         else value
-
-result = if record then value
-         if record then value
-
-result = if record then value
-         else if record then value
-
-result = if record then value
-         else if record then value
-         else value
-
-(result1, ..., resultN) = if record then (value, ..., valueN)
-
-(result1, ..., resultN) = if record then (value, ..., valueN)
-                          else (value, ..., valueN)
-
-(result1, ..., resultN) = if record1 then (value, ..., valueN)
-                          if record2 then (value, ..., valueN)
-
-(result1, ..., resultN) = if record1 then (value, ..., valueN)
-                          else if record2 then (value, ..., valueN)
-
-(result1, ..., resultN) = if record1 then (value, ..., valueN)
-                          else if record2 then (value, ..., valueN)
-                          else (value, ..., valueN)                                          
-
- -

Description

- -

If allows conditional equivalence, and works a lot like if in other languages. Our if has two components: The keyword if followed by a conditional; and the keyword then followed by one or more return objects. An optional else keyword indicates the default value:

- -

This block is used to switch between the singular and plural for displaying the number of burgers each guest is eating. If statements can be composed, permitting the creation of complex conditional statements. For instance, instead of inviting friends and their spouses in two blocks (the first two blocks in the example program), I could have done it in a single block using an if statement:

- -

This is equivalent to a union/and operator, which combines elements from disparate sets into the same set. The second way to use if is in conjunction with the else keyword:

- -

This is equivalent to a choose/or operator, selecting only the first branch with a non-empty body. A bug in this program is that if some guest is tagged both #hungry and #vegetarian, that guest will actually receive two burgers. Therefore, while order of statements usually does not matter in Eve, if statements are one area where it does.

- -

A final feature of the if statement is multiple returns. For instance, we could have done this:

- -

Examples

- -

Basic usage

-
burger-switch = if guest.burgers = 1 then "burger"
-                else "burgers"
-
-
[@"my party" date]
-friend = [#friend busy-dates != date]
-guest = if friend then friend
-        if friend.spouse then friend.spouse
-
- -

Using else if

-
burgers = if guest = [@Arthur] then 3
-          else if guest = [#hungry] then 2
-          else if guest = [#vegetarian] then 0
-          else 1
-
- -

Multiple returns

-
(burgers, status) = if guest = [@Arthur] then (3, #fed)
-                    else if guest = [#hungry] then (2, #fed)
-                    else if guest = [#vegetarian] then (0, #needsfood)
-                    else (1, #fed)
-
- -

See Also

- -

expressions | records | functions

- - -
-
- -
- diff --git a/handbook/index.html b/handbook/index.html deleted file mode 100644 index cd85d0f..0000000 --- a/handbook/index.html +++ /dev/null @@ -1,784 +0,0 @@ - - - - - - - - - - - - Handbooks - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
- -
- -
-
diff --git a/handbook/index.xml b/handbook/index.xml deleted file mode 100644 index 92d5077..0000000 --- a/handbook/index.xml +++ /dev/null @@ -1,411 +0,0 @@ - - - - Handbooks on Eve Documentation - https://witheve.github.io/docs/handbook/ - Recent content in Handbooks on Eve Documentation - Hugo -- gohugo.io - en-us - - - - - https://witheve.github.io/docs/handbook/core/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://witheve.github.io/docs/handbook/core/ - - -<h1 id="core-language">Core Language</h1> - -<h2 id="see-also">See Also</h2> - -<p><a href="../records">records</a> | <a href="../equivalence">equivalence</a> | <a href="../actions">actions</a> | <a href="../expressions">expressions</a> | <a href="../update-operators">update operators</a> | <a href="../databases">databases</a></p> - - - - - - https://witheve.github.io/docs/handbook/intro/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://witheve.github.io/docs/handbook/intro/ - - -<h1 id="introduction">Introduction</h1> - -<h2 id="notable-features">Notable Features</h2> - -<ul> -<li><p>Eve programs aren&rsquo;t talking to a database, they <em>are</em> the database. That means no plumbing, no impedance mismatch, and no extra infrastructure is needed.</p></li> - -<li><p>Everything is data. The file system, http requests, the DOM&hellip; That means everything can be queried and everything can be reacted to.</p></li> - -<li><p>Eve&rsquo;s semantics were built for concurrency, asynchrony, and distribution. There are no promises, or thread synchronizations, or borrows.</p></li> - -<li><p>Eve programs practice literate programming, since there&rsquo;s no incidental ordering imposed by the language.</p></li> - -<li><p>Another result of a lack of ordering is that programs grow very organically through composition.</p></li> - -<li><p>Eve programs are naturally tiny.</p></li> - -<li><p>Correctness can be defined globally through integrity constraints, allowing people to safely contribute to an application without worrying about checking every possible invariant locally.</p></li> -</ul> - -<h2 id="see-also">See Also</h2> - -<p><a href="../installation">getting eve</a> | <a href="../running">running eve</a> | <a href="../programs">eve programs</a> | <a href="../core-language">core language</a></p> - - - - - - https://witheve.github.io/docs/handbook/programs/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://witheve.github.io/docs/handbook/programs/ - - -<h1 id="eve-programs">Eve Programs</h1> - -<p>Coming soon&hellip;</p> - -<h2 id="see-also">See Also</h2> - -<p><a href="../model">programming model</a> | <a href="../literate-programming">literate programming</a> | <a href="../blocks">blocks</a></p> - - - - - - https://witheve.github.io/docs/handbook/standard-library/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://witheve.github.io/docs/handbook/standard-library/ - - -<h1 id="standard-library">Standard Library</h1> - -<h2 id="description">Description</h2> - -<ul> -<li><a href="../math">math</a> - General mathematical and trigonometric functions</li> -<li><a href="../strings">strings</a> - Functions that manipulate strings</li> -<li><a href="../statistics">statistics</a> - Functions that calculate statistical measures on values</li> -<li><a href="../datetime">date &amp; time</a> - Functions that get and manipulate date and time</li> -</ul> - - - - - Date & Time - https://witheve.github.io/docs/handbook/datetime/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://witheve.github.io/docs/handbook/datetime/ - - -<h1 id="date-time">Date &amp; Time</h1> - -<ul> -<li><a href="time.md">time</a> - The current system time</li> -</ul> - - - - - Events - https://witheve.github.io/docs/handbook/events/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://witheve.github.io/docs/handbook/events/ - - -<h1 id="events">Events</h1> - -<p><a href="click">click</a> - a left-button mouse click event</p> - - - - - General - https://witheve.github.io/docs/handbook/general/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://witheve.github.io/docs/handbook/general/ - - -<h1 id="general">General</h1> - -<ul> -<li><a href="sort">sort</a> - Orders elements in a set</li> -</ul> - - - - - Linux - https://witheve.github.io/docs/handbook/linux/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://witheve.github.io/docs/handbook/linux/ - - -<h1 id="installing-eve-on-linux">Installing Eve on Linux</h1> - -<p>First, <a href="https://github.com/witheve/Eve/archive/master.zip">download</a> the Eve source. You&rsquo;ll need a recent <a href="https://nodejs.org">node.js</a> and then and then in the extracted Eve directory:</p> - -<pre><code>npm install -npm start -</code></pre> - -<p>Then open <code>http://localhost:8080/</code> in your browser.</p> - -<h2 id="see-also">See also</h2> - -<p><a href="../mac">mac</a> | <a href="../windows">windows</a> | <a href="../running">running</a></p> - - - - - Mac - https://witheve.github.io/docs/handbook/mac/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://witheve.github.io/docs/handbook/mac/ - - -<h1 id="installing-eve-on-mac">Installing Eve on Mac</h1> - -<p>First, <a href="https://github.com/witheve/Eve/archive/master.zip">download</a> the Eve source. You&rsquo;ll need a recent <a href="https://nodejs.org">node.js</a> and then and then in the extracted Eve directory:</p> - -<pre><code>npm install -npm start -</code></pre> - -<p>Then open <code>http://localhost:8080/</code> in your browser.</p> - -<h2 id="see-also">See also</h2> - -<p><a href="../linux">linux</a> | <a href="../windows">windows</a> | <a href="../running">running</a></p> - - - - - Math - https://witheve.github.io/docs/handbook/math/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://witheve.github.io/docs/handbook/math/ - - -<h1 id="math">Math</h1> - -<h2 id="arithemtic">Arithemtic</h2> - -<ul> -<li>plus ( <code>+</code> ) - Add two numbers</li> -<li>minus ( <code>-</code> ) - Subtract two numbers</li> -<li>times ( <code>*</code> ) - Multiply two numbers</li> -<li>divide ( <code>/</code> ) - Divide two numbers</li> -</ul> - -<h2 id="general-math">General Math</h2> - -<ul> -<li><a href="abs">abs</a> - Absolute value</li> -<li><a href="ceil">ceil</a> - Round a number up</li> -<li><a href="floor">floor</a> - Round a number down</li> -<li><a href="round">round</a> - Round a number</li> -<li><a href="mod">mod</a> - Modulo division</li> -<li>exp - The number <code>e</code> raised to a power</li> -<li>log - Calculate the logarithm of a number</li> -</ul> - -<h2 id="trigonometric-functions">Trigonometric Functions</h2> - -<ul> -<li><a href="sin">sin</a> - Sine of an angle</li> -<li><a href="cos">cos</a> - Cosine of an angle</li> -<li><a href="tan">tan</a> - Tangent of an angle</li> -<li>asin - Arc sine of an angle</li> -<li>acos - Arc cosine of an angle</li> -<li>atan - Arc tangent of an angle</li> -<li>atan2 - Arc tangent using sign to determine quadrant</li> -</ul> - -<h2 id="hyperbolic-functions">Hyperbolic Functions</h2> - -<ul> -<li>sinh - Hyperbolic sine of an angle</li> -<li>cosh - Hyperbolic cosine of an angle</li> -<li>tanh - Hyperbolic tangent of an angle</li> -<li>asinh - Hyperbolic arc sine of an angle</li> -<li>acosh - Hyperbolic arc cosine of an angle</li> -<li>atanh - Hyperbolic arc tangent of an angle</li> -</ul> - -<h2 id="other-functions">Other Functions</h2> - -<ul> -<li><a href="range">range</a> - Generates a range of numbers</li> -</ul> - - - - - Statistics - https://witheve.github.io/docs/handbook/statistics/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://witheve.github.io/docs/handbook/statistics/ - - -<h1 id="statistics">Statistics</h1> - -<ul> -<li><a href="count">count</a> - counts the number of elements in a set</li> -</ul> - -<h2 id="random-functions">Random Functions</h2> - -<ul> -<li><a href="random">random</a> - Generates a random number between <code>0</code> and <code>1</code></li> -</ul> - - - - - Strings - https://witheve.github.io/docs/handbook/strings/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://witheve.github.io/docs/handbook/strings/ - - -<h1 id="strings">Strings</h1> - -<ul> -<li><a href="length">length</a></li> -<li><a href="concat">concatenate</a></li> -<li><a href="replace">replace</a></li> -<li><a href="split">split</a></li> -<li><a href="join">join</a></li> -</ul> - - - - - Windows - https://witheve.github.io/docs/handbook/windows/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://witheve.github.io/docs/handbook/windows/ - - -<h1 id="installing-eve-on-windows">Installing Eve on Windows</h1> - -<p>First, <a href="https://github.com/witheve/Eve/archive/master.zip">download</a> the Eve source. You&rsquo;ll need a recent <a href="https://nodejs.org">node.js</a> and then and then in the extracted Eve directory:</p> - -<pre><code>npm install -npm start -</code></pre> - -<p>Then open <code>http://localhost:8080/</code> in your browser.</p> - -<h2 id="see-also">See also</h2> - -<p><a href="../linux">linux</a> | <a href="../mac">mac</a> | | <a href="../running">running</a></p> - - - - - abs - https://witheve.github.io/docs/handbook/math/abs/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://witheve.github.io/docs/handbook/math/abs/ - - -<h1 id="abs">abs</h1> - -<p>The absolute value of a number</p> - -<h2 id="syntax">Syntax</h2> -<div class="highlight"><pre><code class="language-eve" data-lang="eve"><span></span><span class="x">y</span><span class="w"> </span><span class="nf">=</span><span class="w"> </span><span class="x">abs</span><span class="p">[</span><span class="x">value</span><span class="p">]</span><span class="w"></span> -</code></pre></div> - -<h2 id="attributes">Attributes</h2> - -<ul> -<li><code>value</code> - a set of numbers</li> -</ul> - -<h2 id="description">Description</h2> - -<p><code>y = abs[value]</code> returns the absolute value of the elements in <code>value</code>. Every positive number is kept positive, but every negative number is made positive.</p> - -<h2 id="examples">Examples</h2> - -<p>Get the absolute value of a number</p> -<div class="highlight"><pre><code class="language-eve" data-lang="eve"><span></span><span class="kr">search</span><span class="w"></span> -<span class="w"> </span><span class="x">y</span><span class="w"> </span><span class="nf">=</span><span class="w"> </span><span class="x">abs</span><span class="p">[</span><span class="x">value</span><span class="nf">:</span><span class="w"> </span><span class="nf">-</span><span class="m">3</span><span class="p">]</span><span class="w"></span> -<span class="w"> </span> -<span class="kr">bind</span><span class="w"> </span><span class="nt">@browser</span><span class="w"></span> -<span class="w"> </span><span class="p">[</span><span class="nt">#div</span><span class="w"> </span><span class="x">text</span><span class="nf">:</span><span class="w"> </span><span class="x">y</span><span class="p">]</span><span class="w"></span> -</code></pre></div> - -<p>Displays the number <code>3</code>.</p> - -<h2 id="see-also">See Also</h2> - -<p><a href="../sign">sign</a></p> - - - - - ceil - https://witheve.github.io/docs/handbook/math/ceil/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://witheve.github.io/docs/handbook/math/ceil/ - - -<h1 id="ceil">ceil</h1> - -<p>Round a number up to the nearest integer.</p> - -<h2 id="syntax">Syntax</h2> -<div class="highlight"><pre><code class="language-eve" data-lang="eve"><span></span><span class="x">y</span><span class="w"> </span><span class="nf">=</span><span class="w"> </span><span class="x">ceil</span><span class="p">[</span><span class="x">value</span><span class="p">]</span><span class="w"></span> -</code></pre></div> - -<h2 id="attributes">Attributes</h2> - -<ul> -<li><code>value</code> - a set of numbers</li> -</ul> - -<h2 id="description">Description</h2> - -<p><code>y = ceil[value]</code> rounds the elements of <code>value</code> up to the nearest integers.</p> - -<h2 id="examples">Examples</h2> - -<p>Calculate the ceiling of <code>34.2</code></p> -<div class="highlight"><pre><code class="language-eve" data-lang="eve"><span></span><span class="kr">search</span><span class="w"></span> -<span class="w"> </span><span class="x">y</span><span class="w"> </span><span class="nf">=</span><span class="w"> </span><span class="x">ceil</span><span class="p">[</span><span class="x">value</span><span class="nf">:</span><span class="w"> </span><span class="m">34</span><span class="x">.</span><span class="m">2</span><span class="p">]</span><span class="w"></span> -<span class="w"> </span> -<span class="kr">bind</span><span class="w"> </span><span class="nt">@browser</span><span class="w"></span> -<span class="w"> </span><span class="p">[</span><span class="nt">#div</span><span class="w"> </span><span class="x">text</span><span class="nf">:</span><span class="w"> </span><span class="x">y</span><span class="p">]</span><span class="w"></span> -</code></pre></div> - -<p>The result is <code>35</code>.</p> - -<h2 id="see-also">See Also</h2> - -<p><a href="../floor">floor</a> | <a href="../fix">fix</a> | <a href="../round">round</a></p> - - - - - \ No newline at end of file diff --git a/src/handbook/inequality.md b/handbook/inequality.md similarity index 100% rename from src/handbook/inequality.md rename to handbook/inequality.md diff --git a/handbook/inequality/index.html b/handbook/inequality/index.html deleted file mode 100644 index e16ff01..0000000 --- a/handbook/inequality/index.html +++ /dev/null @@ -1,467 +0,0 @@ - - - - - - - - - - - - Inequality - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

Inequality

- -

inequality operators filter records

- -

Syntax

-
// Inequality Operators
->, >=, <, <=, !=
-
-// Inside of records
-[attribute >= value]
-[attribute >= variable]
-
-// Outside of records
-variable >= value
-variable >= variable
-
-// Satisfy multiple constraints in a single line
-value <= variable <= value   
-variable <= variable <= variable
-
- -

Description

- -

Attributes can be filtered using inequality operators, including >, >=, <, <= and !=.

- -

>, >=, <, <= can only filter using values that can be sorted. For instance, you can use these operators to filter numbers, but you cannot filter records this way.

- -

!= tests only for inequality, and doesn’t compare whether an attribute is greater or less than a particular value. Therefore, != can be used to filter any value.

- -

You can use inequality operators inside records or outside of them. Inside of records, you can filter an attribute on a single value. Outside of records, you have more freedom to filter on multiple values. For instance, if you want only records with an attribute between a maximum and minimum value, you can write something like min-value < variable < max-value.

- -

Examples

- -

Select students with a low GPA

-
search @test-data
-  [#student name GPA < 2.0]
-
-bind @browser
-  [#div text: "{{name}} needs a tutor."]
-
- -

Select students with a GPA over 2.0 but less than 3.0

-
search @test-data
-  [#student name GPA]
-  2.0 <= GPA < 3.0
-
-bind @browser
-  [#div text: "{{name}} is doing fine"]
-
- -

You can be very specific with filters. Select students named “John” in 11th or 12th grade with a GPA between 2.0 and 3.0, and who don’t attend “West” high school.

-
search @test-data
-  students = [#student name: "John", grade >= 11, school != "West" ]
-  2.0 <= students.GPA < 3.0
-
-bind @browser
-  [#div text: "{{name}} is doing fine"]  
-
- -

See Also

- -

equality | joins | equivalence

- - -
-
- -
- diff --git a/handbook/installation.md b/handbook/installation.md new file mode 100644 index 0000000..770c315 --- /dev/null +++ b/handbook/installation.md @@ -0,0 +1,20 @@ +--- +menu: + main: + parent: "Introduction" +title: "Getting Eve" +weight: 1 +--- + +# Getting Eve + +There are four ways to get Eve: + +1. Try Eve online, in your browser at [play.witheve.com](play.witheve.com). +2. Download the Eve package through [npm](../npm). +3. Download the Eve [Docker container](../docker). +4. Download and run Eve from source. We have instructions available for [linux](../linux), [mac](../mac), and [windows](../windows). + +## See Also + +[linux](../linux) | [mac](../mac) | [windows](../windows) | [docker](../docker) | [npm](../npm) | [running](../running) diff --git a/handbook/installation/index.html b/handbook/installation/index.html deleted file mode 100644 index 23b3a1f..0000000 --- a/handbook/installation/index.html +++ /dev/null @@ -1,408 +0,0 @@ - - - - - - - - - - - - Getting Eve - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
- - -
- diff --git a/src/handbook/intro.md b/handbook/intro.md similarity index 94% rename from src/handbook/intro.md rename to handbook/intro.md index 4b21742..2b8c765 100644 --- a/src/handbook/intro.md +++ b/handbook/intro.md @@ -18,4 +18,4 @@ ## See Also -[getting eve](../installation) | [running eve](../running) | [eve programs](../programs) | [core language](../core-language) \ No newline at end of file +[getting eve](../installation) | [running eve](../running) | [eve programs](../programs) | [core language](../core) \ No newline at end of file diff --git a/handbook/intro/index.html b/handbook/intro/index.html deleted file mode 100644 index 6dfc36d..0000000 --- a/handbook/intro/index.html +++ /dev/null @@ -1,428 +0,0 @@ - - - - - - - - - - - - - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

Introduction

- -

Notable Features

- -
    -
  • Eve programs aren’t talking to a database, they are the database. That means no plumbing, no impedance mismatch, and no extra infrastructure is needed.

  • - -
  • Everything is data. The file system, http requests, the DOM… That means everything can be queried and everything can be reacted to.

  • - -
  • Eve’s semantics were built for concurrency, asynchrony, and distribution. There are no promises, or thread synchronizations, or borrows.

  • - -
  • Eve programs practice literate programming, since there’s no incidental ordering imposed by the language.

  • - -
  • Another result of a lack of ordering is that programs grow very organically through composition.

  • - -
  • Eve programs are naturally tiny.

  • - -
  • Correctness can be defined globally through integrity constraints, allowing people to safely contribute to an application without worrying about checking every possible invariant locally.

  • -
- -

See Also

- -

getting eve | running eve | eve programs | core language

- - -
-
- -
- diff --git a/src/handbook/is.md b/handbook/is.md similarity index 96% rename from src/handbook/is.md rename to handbook/is.md index 3d38811..1afa4c3 100644 --- a/src/handbook/is.md +++ b/handbook/is.md @@ -30,7 +30,7 @@ search bind @browser [#div text: "y is {{y}}"] - [#div text: "z is {{x}}"] + [#div text: "z is {{z}}"] ``` The output shows that y is `false` while z is `true`. diff --git a/handbook/is/index.html b/handbook/is/index.html deleted file mode 100644 index d9d63df..0000000 --- a/handbook/is/index.html +++ /dev/null @@ -1,439 +0,0 @@ - - - - - - - - - - - - is - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

is

- -

Tests the truth of a statement

- -

Syntax

-
y = is( ... )
-
- -

Description

- -

y = is( ... ) tests the truth of the statement contained in the parentheses. If the statement is true, then is returns the value true, otherwise it returns false.

- -

Examples

-
search
-  x = 10
-  y = is(20 = x)
-  z = is(20 = x * 2)
-
-bind @browser
-  [#div text: "y is {{y}}"]
-  [#div text: "z is {{x}}"]
-
- -

The output shows that y is false while z is true.

- -

Example Usage

- - - -

See Also

- -

not | records | expressions

- - -
-
- -
- diff --git a/src/handbook/joins.md b/handbook/joins.md similarity index 91% rename from src/handbook/joins.md rename to handbook/joins.md index b675f68..3061213 100644 --- a/src/handbook/joins.md +++ b/handbook/joins.md @@ -8,7 +8,7 @@ weight: 3 # Joins -joins allow you to relate to records +joins allow you to relate two records ## Syntax diff --git a/handbook/joins/index.html b/handbook/joins/index.html deleted file mode 100644 index 81649ec..0000000 --- a/handbook/joins/index.html +++ /dev/null @@ -1,426 +0,0 @@ - - - - - - - - - - - - Joins - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

Joins

- -

joins allow you to relate to records

- -

Syntax

-
// Join two records using a bind
-[#record1 attribute1]
-[#record2 attribute2: attribute1]
-
-// Join two records using a name
-[#record1 attribute]
-[#record2 attribute]
-
- -

Description

- -

Examples

- -

See Also

- -

equality | inequality | records

- - -
-
- -
- diff --git a/handbook/linux.md b/handbook/linux.md new file mode 100644 index 0000000..fd3f48b --- /dev/null +++ b/handbook/linux.md @@ -0,0 +1,31 @@ +--- +menu: + main: + parent: "Getting Eve" +title: "Linux" +--- + +# Installing Eve on Linux + +First, [download](https://github.com/witheve/Eve/archive/master.zip) the Eve source. You'll need a recent [node.js](https://nodejs.org) and then in the extracted Eve directory: + +``` +npm install +npm start +``` + +Then open `http://localhost:8080/` in your browser. + +## Tips + +Some distributions (most notably Ubuntu) have renamed `node` to `nodejs`. If this is the case, you'll need to create a symlink that remaps nodejs back to node. e.g. + +``` +ln -s /usr/bin/nodejs /usr/bin/node +``` + +Then proceed with the installation as usual + +## See also + +[mac](../mac) | [windows](../windows) | [docker](../docker) | [running](../running) \ No newline at end of file diff --git a/handbook/linux/index.html b/handbook/linux/index.html deleted file mode 100644 index 7156378..0000000 --- a/handbook/linux/index.html +++ /dev/null @@ -1,418 +0,0 @@ - - - - - - - - - - - - Linux - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

Installing Eve on Linux

- -

First, download the Eve source. You’ll need a recent node.js and then and then in the extracted Eve directory:

- -
npm install
-npm start
-
- -

Then open http://localhost:8080/ in your browser.

- -

See also

- -

mac | windows | running

- - -
-
- -
- diff --git a/src/handbook/literate-programming.md b/handbook/literate-programming.md similarity index 89% rename from src/handbook/literate-programming.md rename to handbook/literate-programming.md index 7766fa1..08be91f 100644 --- a/src/handbook/literate-programming.md +++ b/handbook/literate-programming.md @@ -20,7 +20,7 @@ Writing code this way has several properties that result in higher quality progr - **The human brain is wired to engage with and remember stories.** Think back to a book you read (or maybe a show you watched) last year. You probably remember in great detail all of the characters and their personalities, the pivotal moments of the plot, the descriptions of the various settings, etc. But how much can you remember of a piece of code you haven't looked at for a year? Literate programming adds another dimension to your code that will help you keep more of your program in working memory. -- **Since Eve code blocks can be arranged in any order, literate programming encourages the programmer to arrange them in an way that makes narrative sense.** Code can have a beginning, middle, and end just like a short story. Or like an epic novel, code can have many interwoven storylines. Either way, the structure of the code should follow an order imposed by a narrative, not one imposed by the compiler. +- **Since Eve code blocks can be arranged in any order, literate programming encourages the programmer to arrange them in a way that makes narrative sense.** Code can have a beginning, middle, and end just like a short story. Or like an epic novel, code can have many interwoven storylines. Either way, the structure of the code should follow an order imposed by a narrative, not one imposed by the compiler. - **Literate programming can help you think about your program more thoroughly.** Through practicing literate programming, you can reveal edge cases, incorrect assumptions, gaps in understanding the problem domain, and shaky implementation details before any code is even written. @@ -40,4 +40,4 @@ Eve is [CommonMark][1] compatible. [blocks](../blocks) | [programming model](../model) | [CommonMark](../commonmark) [0]: http://www.literateprogramming.com/knuthweb.pdf -[1]: http://commonmark.org/ \ No newline at end of file +[1]: http://commonmark.org/ diff --git a/handbook/literate-programming/index.html b/handbook/literate-programming/index.html deleted file mode 100644 index 230ead6..0000000 --- a/handbook/literate-programming/index.html +++ /dev/null @@ -1,443 +0,0 @@ - - - - - - - - - - - - Literate Programming - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

Literate Programming

- -

In the spirit of literate programming, Eve programs are primarily prose, interleaved with Eve code. Donald Knuth explains literate programming in his influential paper:

- -
-

The practitioner of literate programming can be regarded as an essayist, whose main concern is with exposition and excellence of style. Such an author … strives for a program that is comprehensible because its concepts have been introduced in an order that is best for human understanding, using a mixture of formal and informal methods that reinforce each other.

-
- -

This description fits with the ethos of Eve - that programming is primarily meant to communicate with other humans, not the computer. You’ll notice the above Eve program is actually written in two languages: Markdown, used to format the prose; and Eve, which is delineated by standard Markdown code blocks. Only the content within a block is compiled, while everything else is disregarded as a comment.

- -

Writing code this way has several properties that result in higher quality programs:

- -
    -
  • Literate programming forces you to consider a human audience. While this is usually the first step in writing any document, in programming the audience is typically a machine. For an Eve program, the audience might be your collaborators, your boss, or even your future self when revisiting the program in a year. By considering the audience of your program source, you create an anchor from which the narrative of your program flows, leading to a more coherent document.

  • - -
  • The human brain is wired to engage with and remember stories. Think back to a book you read (or maybe a show you watched) last year. You probably remember in great detail all of the characters and their personalities, the pivotal moments of the plot, the descriptions of the various settings, etc. But how much can you remember of a piece of code you haven’t looked at for a year? Literate programming adds another dimension to your code that will help you keep more of your program in working memory.

  • - -
  • Since Eve code blocks can be arranged in any order, literate programming encourages the programmer to arrange them in an way that makes narrative sense. Code can have a beginning, middle, and end just like a short story. Or like an epic novel, code can have many interwoven storylines. Either way, the structure of the code should follow an order imposed by a narrative, not one imposed by the compiler.

  • - -
  • Literate programming can help you think about your program more thoroughly. Through practicing literate programming, you can reveal edge cases, incorrect assumptions, gaps in understanding the problem domain, and shaky implementation details before any code is even written.

  • -
- -

Literate programming is a first-class design concept in Eve. We will be writing all of our programs in this manner, and will encourage others to do the same for the reasons above. That said, there is nothing in the syntax that specifically requires literate programming; you can write your program as a series of code blocks without any prose, and it will be perfectly valid.

- -

CommonMark

- -

Eve is CommonMark compatible.

- -

Examples

- - - -

See Also

- -

blocks | programming model | CommonMark

- - -
-
- -
- diff --git a/src/handbook/mac.md b/handbook/mac.md similarity index 67% rename from src/handbook/mac.md rename to handbook/mac.md index 214785c..3fbdecd 100644 --- a/src/handbook/mac.md +++ b/handbook/mac.md @@ -7,7 +7,7 @@ title: "Mac" # Installing Eve on Mac -First, [download](https://github.com/witheve/Eve/archive/master.zip) the Eve source. You'll need a recent [node.js](https://nodejs.org) and then and then in the extracted Eve directory: +First, [download](https://github.com/witheve/Eve/archive/master.zip) the Eve source. You'll need a recent [node.js](https://nodejs.org) and then in the extracted Eve directory: ``` npm install @@ -18,4 +18,4 @@ Then open `http://localhost:8080/` in your browser. ## See also -[linux](../linux) | [windows](../windows) | [running](../running) \ No newline at end of file +[linux](../linux) | [windows](../windows) | [docker](../docker) | [npm](../npm) | [running](../running) \ No newline at end of file diff --git a/handbook/mac/index.html b/handbook/mac/index.html deleted file mode 100644 index a810145..0000000 --- a/handbook/mac/index.html +++ /dev/null @@ -1,418 +0,0 @@ - - - - - - - - - - - - Mac - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

Installing Eve on Mac

- -

First, download the Eve source. You’ll need a recent node.js and then and then in the extracted Eve directory:

- -
npm install
-npm start
-
- -

Then open http://localhost:8080/ in your browser.

- -

See also

- -

linux | windows | running

- - -
-
- -
- diff --git a/src/handbook/math/abs.md b/handbook/math/abs.md similarity index 100% rename from src/handbook/math/abs.md rename to handbook/math/abs.md diff --git a/handbook/math/abs/index.html b/handbook/math/abs/index.html deleted file mode 100644 index 3b3e3ca..0000000 --- a/handbook/math/abs/index.html +++ /dev/null @@ -1,438 +0,0 @@ - - - - - - - - - - - - abs - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

abs

- -

The absolute value of a number

- -

Syntax

-
y = abs[value]
-
- -

Attributes

- -
    -
  • value - a set of numbers
  • -
- -

Description

- -

y = abs[value] returns the absolute value of the elements in value. Every positive number is kept positive, but every negative number is made positive.

- -

Examples

- -

Get the absolute value of a number

-
search
-  y = abs[value: -3]
-  
-bind @browser
-  [#div text: y]
-
- -

Displays the number 3.

- -

See Also

- -

sign

- - -
-
- -
- diff --git a/src/handbook/math/ceil.md b/handbook/math/ceil.md similarity index 59% rename from src/handbook/math/ceil.md rename to handbook/math/ceil.md index 5874aca..9c53060 100644 --- a/src/handbook/math/ceil.md +++ b/handbook/math/ceil.md @@ -2,17 +2,17 @@ menu: main: parent: "Math" -title: "ceil" +title: "ceiling" --- -# ceil +# ceiling Round a number up to the nearest integer. ## Syntax ```eve -y = ceil[value] +y = ceiling[value] ``` ## Attributes @@ -21,7 +21,7 @@ y = ceil[value] ## Description -`y = ceil[value]` rounds the elements of `value` up to the nearest integers. +`y = ceiling[value]` rounds the elements of `value` up to the nearest integers. ## Examples @@ -29,7 +29,7 @@ Calculate the ceiling of `34.2` ```eve search - y = ceil[value: 34.2] + y = ceiling[value: 34.2] bind @browser [#div text: y] @@ -39,4 +39,4 @@ The result is `35`. ## See Also -[floor](../floor) | [fix](../fix) | [round](../round) \ No newline at end of file +[floor](../floor) | [fix](../fix) | [round](../round) diff --git a/handbook/math/ceil/index.html b/handbook/math/ceil/index.html deleted file mode 100644 index de5714e..0000000 --- a/handbook/math/ceil/index.html +++ /dev/null @@ -1,438 +0,0 @@ - - - - - - - - - - - - ceil - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

ceil

- -

Round a number up to the nearest integer.

- -

Syntax

-
y = ceil[value]
-
- -

Attributes

- -
    -
  • value - a set of numbers
  • -
- -

Description

- -

y = ceil[value] rounds the elements of value up to the nearest integers.

- -

Examples

- -

Calculate the ceiling of 34.2

-
search
-  y = ceil[value: 34.2]
-  
-bind @browser
-  [#div text: y]
-
- -

The result is 35.

- -

See Also

- -

floor | fix | round

- - -
-
- -
- diff --git a/src/handbook/math/cos.md b/handbook/math/cos.md similarity index 100% rename from src/handbook/math/cos.md rename to handbook/math/cos.md diff --git a/handbook/math/cos/index.html b/handbook/math/cos/index.html deleted file mode 100644 index 4be961a..0000000 --- a/handbook/math/cos/index.html +++ /dev/null @@ -1,442 +0,0 @@ - - - - - - - - - - - - cos - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

cos

- -

Calculate the cosine of an angle

- -

Syntax

-
y = cos[radians]
-y = cos[degrees]
-
- -

Attributes

- -
    -
  • radians - the angle in radians
  • -
  • degrees - the angle in degrees
  • -
- -

Description

- -

y = cos[degrees] calculates the cosine of an input in degrees.

- -

y = cos[radians] calculates the cosine of an input in radians.

- -

cos operates element-wise on its inputs.

- -

Examples

- -

Calculate the cosine of 90 degrees

-
search
-  y = cos[degrees: 90]
-  
-bind @browser
-  [#div text: y]
-
- -

See Also

- -

sin | tan

- - -
-
- -
- diff --git a/src/handbook/math/fix.md b/handbook/math/fix.md similarity index 100% rename from src/handbook/math/fix.md rename to handbook/math/fix.md diff --git a/handbook/math/fix/index.html b/handbook/math/fix/index.html deleted file mode 100644 index 31f4e2d..0000000 --- a/handbook/math/fix/index.html +++ /dev/null @@ -1,450 +0,0 @@ - - - - - - - - - - - - fix - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

fix

- -

Round a number toward zero.

- -

Syntax

-
y = fix[value]
-
- -

Attributes

- -
    -
  • value - a set of numbers
  • -
- -

Description

- -

y = fix[value] rounds the elements of value toward zero. This means that negative numbers will be rounded up to the nearest integer, while positive numbers will be rounded down.

- -

Examples

- -

Calculate the fix of 34.7 and -34.7

-
search
-  y = fix[value: 34.7]
-  z = fix[value: -34.7]
-
-bind @browser
-  [#div text: "The fix of 34.7 is {{y}}"]
-  [#div text: "The fix of -34.7 is {{z}}"]
-
- -

We see that the fix of 34.7 is 34, while the fix of -34.7 is -34. Compare this to rounding the numbers:

-
search
-  y = round[value: 34.7]
-  z = round[value: -34.7]
-
-bind @browser
-  [#div text: "The round of 34.7 is {{y}}"]
-  [#div text: "The round of -34.7 is {{z}}"]
-
- -

We see that the round of 34.7 is 35, while the round of -34.7 is -35.

- -

See Also

- -

floor | ceil | round

- - -
-
- -
- diff --git a/src/handbook/math/floor.md b/handbook/math/floor.md similarity index 95% rename from src/handbook/math/floor.md rename to handbook/math/floor.md index 841b5fc..baf870c 100644 --- a/src/handbook/math/floor.md +++ b/handbook/math/floor.md @@ -32,7 +32,7 @@ search y = floor[value: 34.2] bind @browser - [#div text: value] + [#div text: y] ``` The result is `34`. diff --git a/handbook/math/floor/index.html b/handbook/math/floor/index.html deleted file mode 100644 index db7d868..0000000 --- a/handbook/math/floor/index.html +++ /dev/null @@ -1,438 +0,0 @@ - - - - - - - - - - - - floor - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

floor

- -

Round a number down to the nearest integer.

- -

Syntax

-
y = floor[value]
-
- -

Attributes

- -
    -
  • value - a set of numbers
  • -
- -

Description

- -

y = floor[value] rounds the elements of value down to the nearest integers.

- -

Examples

- -

Calculate the floor of 34.2

-
search
-  y = floor[value: 34.2]
-
-bind @browser
-  [#div text: value]
-
- -

The result is 34.

- -

See Also

- -

ceil | fix | round

- - -
-
- -
- diff --git a/handbook/math/index.html b/handbook/math/index.html deleted file mode 100644 index 7c4f6cb..0000000 --- a/handbook/math/index.html +++ /dev/null @@ -1,456 +0,0 @@ - - - - - - - - - - - - Math - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

Math

- -

Arithemtic

- -
    -
  • plus ( + ) - Add two numbers
  • -
  • minus ( - ) - Subtract two numbers
  • -
  • times ( * ) - Multiply two numbers
  • -
  • divide ( / ) - Divide two numbers
  • -
- -

General Math

- -
    -
  • abs - Absolute value
  • -
  • ceil - Round a number up
  • -
  • floor - Round a number down
  • -
  • round - Round a number
  • -
  • mod - Modulo division
  • -
  • exp - The number e raised to a power
  • -
  • log - Calculate the logarithm of a number
  • -
- -

Trigonometric Functions

- -
    -
  • sin - Sine of an angle
  • -
  • cos - Cosine of an angle
  • -
  • tan - Tangent of an angle
  • -
  • asin - Arc sine of an angle
  • -
  • acos - Arc cosine of an angle
  • -
  • atan - Arc tangent of an angle
  • -
  • atan2 - Arc tangent using sign to determine quadrant
  • -
- -

Hyperbolic Functions

- -
    -
  • sinh - Hyperbolic sine of an angle
  • -
  • cosh - Hyperbolic cosine of an angle
  • -
  • tanh - Hyperbolic tangent of an angle
  • -
  • asinh - Hyperbolic arc sine of an angle
  • -
  • acosh - Hyperbolic arc cosine of an angle
  • -
  • atanh - Hyperbolic arc tangent of an angle
  • -
- -

Other Functions

- -
    -
  • range - Generates a range of numbers
  • -
- - -
-
- -
- diff --git a/src/handbook/math/index.md b/handbook/math/index.md similarity index 90% rename from src/handbook/math/index.md rename to handbook/math/index.md index 8931eef..9324df6 100644 --- a/src/handbook/math/index.md +++ b/handbook/math/index.md @@ -3,11 +3,12 @@ menu: main: parent: "Standard Library" title: "Math" +weight: 2 --- # Math -## Arithemtic +## Arithmetic - plus ( `+` ) - Add two numbers - minus ( `-` ) - Subtract two numbers @@ -17,9 +18,10 @@ title: "Math" ## General Math - [abs](abs) - Absolute value -- [ceil](ceil) - Round a number up +- [ceiling](ceiling) - Round a number up - [floor](floor) - Round a number down - [round](round) - Round a number +- [fix](fix) - Calculate the fix of a number - [mod](mod) - Modulo division - exp - The number `e` raised to a power - log - Calculate the logarithm of a number diff --git a/src/handbook/math/mod.md b/handbook/math/mod.md similarity index 71% rename from src/handbook/math/mod.md rename to handbook/math/mod.md index d81a765..1e43917 100644 --- a/src/handbook/math/mod.md +++ b/handbook/math/mod.md @@ -30,16 +30,15 @@ Keeps the value of an angle between the range [π, -π]: ```eve search - [#angle value] - pi = 3.141592654 - angle = mod[value, by: 2 * pi] - pi2pi = if angle > pi then angle - 2 * pi - if angle < pi * -1 then angle + 2 * pi - else angle + value = 30 + angle = mod[value, by: 2 * pi[]] + pi2pi = if angle > pi[] then angle - 2 * pi[] + if angle < pi[] * -1 then angle + 2 * pi[] + else angle -bind @browser - [#div text: "{{value}} -> {{pi2pi}}"] -``` +bind @view + [#value | value: "{{value}} -> {{pi2pi}}"] +``` ## See Also diff --git a/handbook/math/mod/index.html b/handbook/math/mod/index.html deleted file mode 100644 index 4ef357a..0000000 --- a/handbook/math/mod/index.html +++ /dev/null @@ -1,442 +0,0 @@ - - - - - - - - - - - - mod - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

mod

- -

Return the modulus after division

- -

Syntax

-
y = mod[value, by]
-
- -

Attributes

- -
    -
  • value - the number to be divided
  • -
  • by - the number by which to divide value
  • -
- -

Description

- -

Modulo division calculates the modulus (the remainder) after dividing value by by. If value is a set of size N, then by can either be a scalar or another set of size N.

- -

Examples

- -

Keeps the value of an angle between the range [π, -π]:

-
search
-  [#angle value]
-  pi = 3.141592654
-  angle = mod[value, by: 2 * pi]
-  pi2pi = if angle > pi then angle - 2 * pi
-        if angle < pi * -1 then angle + 2 * pi
-        else angle
-        
-bind @browser
-  [#div text: "{{value}} -> {{pi2pi}}"]
-
- -

See Also

- -

ceil | floor | round

- - -
-
- -
- diff --git a/src/handbook/math/range.md b/handbook/math/range.md similarity index 94% rename from src/handbook/math/range.md rename to handbook/math/range.md index 726eecf..ec81be8 100644 --- a/src/handbook/math/range.md +++ b/handbook/math/range.md @@ -30,7 +30,7 @@ y = range[from, to, increment] ## Examples -Generate and display the integers between 1 and 10. In this example, `y = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}`: +Generate and display the integers between 1 and 10. In this example, `y = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)`: ```eve search @@ -40,7 +40,7 @@ bind @browser [#div sort: y, text: y] ``` -Generate and display the odd integers between 1 and 10. In this example, `y = {1, 3, 5, 6, 9}`. Notice the set does not include `10` in this case. +Generate and display the odd integers between 1 and 10. In this example, `y = (1, 3, 5, 7, 9)`. Notice the set does not include `10` in this case. ```eve search diff --git a/handbook/math/range/index.html b/handbook/math/range/index.html deleted file mode 100644 index ab8f14d..0000000 --- a/handbook/math/range/index.html +++ /dev/null @@ -1,473 +0,0 @@ - - - - - - - - - - - - range - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

range

- -

Generates a set of numbers between two values

- -

Syntax

-
y = range[from, to]
-y = range[from, to, increment]
-
- -

Attributes

- -
    -
  • from - the start of the range. Does not need to be an integer.
  • -
  • to - the end of the range. Does not need to be an integer.
  • -
  • increment - specifies the increment by which the elements are separated. By default, this value is 1.
  • -
- -

Description

- -

y = range[from, to] generates a set of numbers starting at from and ending at to, in increments of 1. The range generated includes from and to.

- -

y = range[from, to, increment] generates a set of numbers starting at from and ending at to inclusive, at a specified increment. The range generated will start at from and include as many elements as possible until the next element exceeds to. Depending on the chosen increment, this could potentially exclude to from the generated range.

- -

Examples

- -

Generate and display the integers between 1 and 10. In this example, y = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}:

-
search
-  y = range[from: 1, to: 10]
-
-bind @browser
-  [#div sort: y, text: y]
-
- -

Generate and display the odd integers between 1 and 10. In this example, y = {1, 3, 5, 6, 9}. Notice the set does not include 10 in this case.

-
search
-  y = range[from: 1, to: 10, increment: 2]
-
-bind @browser
-  [#div sort: y, text: y]
-
- -

We can use range and Eve’s join semantics to generate indicies for a grid of cells.

-
search
-  i = range[from: 1 to: 5]
-  j = range[from: 1 to: 5]
-  coordinate = "({{i}}, {{j}})"
-
-bind @browser
-  [#div sort: coordinate, text: coordinate]
-
- -

Will display:

- -
(1, 1)
-(1, 2)
-(1, 3)
-...
-(5, 4)
-(5, 5)
-
- -

Example Usage

- - - -

See Also

- - -
-
- -
- diff --git a/src/handbook/math/round.md b/handbook/math/round.md similarity index 100% rename from src/handbook/math/round.md rename to handbook/math/round.md diff --git a/handbook/math/round/index.html b/handbook/math/round/index.html deleted file mode 100644 index e9426b8..0000000 --- a/handbook/math/round/index.html +++ /dev/null @@ -1,441 +0,0 @@ - - - - - - - - - - - - round - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

round

- -

Round a number to the nearest integer

- -

Syntax

-
y = round[value]
-
- -

Attributes

- -
    -
  • value - a set of numbers
  • -
- -

Description

- -

y = round[value] rounds the elements of value toward the nearest integers.

- -
    -
  • For positive numbers - if the fractional part of the number is greater than or equal to 0.5, then the number is rounded up. Otherwise, it is rounded down.
  • -
  • For negative numbers - if the fractional part of the number is greater than or equal to -0.5, then the number is rounded down to the nearest negative integer. Otherwise, it is rounded up.
  • -
- -

Examples

-
search
-  y = round[value: 34.5]
-  z = round[value: 34.4]
-  
-bind @browser
-  [#div text: "The round of 34.5 is {{y}}"]
-  [#div text: "The round of 34.4 is {{z}}"]
-
- -

See Also

- -

floor | ceil | fix

- - -
-
- -
- diff --git a/src/handbook/math/sin.md b/handbook/math/sin.md similarity index 100% rename from src/handbook/math/sin.md rename to handbook/math/sin.md diff --git a/handbook/math/sin/index.html b/handbook/math/sin/index.html deleted file mode 100644 index bc6fa58..0000000 --- a/handbook/math/sin/index.html +++ /dev/null @@ -1,442 +0,0 @@ - - - - - - - - - - - - sin - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

sin

- -

Calculate the sine of an angle

- -

Syntax

-
y = sin[radians]
-y = sin[degrees]
-
- -

Attributes

- -
    -
  • radians - the angle in radians
  • -
  • degrees - the angle in degrees
  • -
- -

Description

- -

y = sin[degrees] calculates the sine of an input in degrees.

- -

y = sin[radians] calculates the sine of an input in radians.

- -

sin operates element-wise on its inputs.

- -

Examples

-
search
-  y = sin[degrees: 90]
-  x = sin[radians: 3.14 / 2]
-  
-bind @browser
-  [#div text: y]
-  [#div text: x]
-
- -

See Also

- -

cos | tan

- - -
-
- -
- diff --git a/handbook/math/sum.md b/handbook/math/sum.md new file mode 100644 index 0000000..1cd8d19 --- /dev/null +++ b/handbook/math/sum.md @@ -0,0 +1,61 @@ +--- +menu: + main: + parent: "Math" +title: "sum" +--- + +# sum + +Sum the elements in a set + +## Syntax + +```eve +y = sum[value, given] +y = sum[value, given, per] +``` + +## Arguments + +- `value` - the variable or attribute to be summed +- `given` - the record from which the value can be accessed +- `per` - _optional_ - specifies the set over which you are summing + +## Description + +`y = sum[value, given]` returns the sum of elements in a set. The set must be entirely numeric or a runtime-error occurs. + +## Examples + +Context data: +```eve +commit + [#employee salary: 100, department: "hunting"] + [#employee salary: 200, department: "hunting"] + [#employee salary: 300, department: "gathering"] +``` + +Get sum of all matching records: +```eve +search + employee = [#employee salary department] + total-salary = sum[value:salary, given: employee] + +bind @browser + [#div text: "Total: {{ total-salary }}" ] +``` + +Get sum of matching records grouped by department: +```eve +search + employee = [#employee salary department] + total-salary = sum[value:salary, given: employee, per: department] + +bind @browser + [#div text: "{{department}} : {{ total-salary }}" ] +``` + +## See Also + +[count](../../statistics/count) | [aggregates](../../aggregates) \ No newline at end of file diff --git a/handbook/math/sum/index.html b/handbook/math/sum/index.html deleted file mode 100644 index 7b737f8..0000000 --- a/handbook/math/sum/index.html +++ /dev/null @@ -1,437 +0,0 @@ - - - - - - - - - - - - sum - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

sum

- -

Sum the elements in a set

- -

Syntax

-
y = sum[given]
-y = sum[given, per]
-
- -

Arguments

- -
    -
  • given - the variable to be summed
  • -
  • per - optional - specifies the set over which you are summing
  • -
- -

Description

- -

y = sum[given] returns the sum of elements in a set. The set must be entirely numeric or a runtime-error occurs.

- -

Examples

-
search @test-data
-  [#employee salary department]
-  department-salary-budgets = sum[given: salary, per: department]
-
-bind @browser
-  [#div text: "{{ department }}: {{ department-salary-budgets }}"]
-
- -

See Also

- -

count | aggregates

- - -
-
- -
- diff --git a/src/handbook/math/tan.md b/handbook/math/tan.md similarity index 100% rename from src/handbook/math/tan.md rename to handbook/math/tan.md diff --git a/handbook/math/tan/index.html b/handbook/math/tan/index.html deleted file mode 100644 index 3371ec4..0000000 --- a/handbook/math/tan/index.html +++ /dev/null @@ -1,439 +0,0 @@ - - - - - - - - - - - - tan - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

tan

- -

Calculate the tangent of an angle

- -

Syntax

-
y = tan[radians]
-y = tan[degrees]
-
- -

Attributes

- -
    -
  • radians - the angle in radians
  • -
  • degrees - the angle in degrees
  • -
- -

Description

- -

y = tan[degrees] calculates the tangent of an input in degrees.

- -

y = tan[radians] calculates the tangent of an input in radians.

- -

tan operates element-wise on its inputs.

- -

Examples

-
match
-  y = tan[degrees: 90]
-bind @browser
-  [#div text: y]
-
- -

See Also

- -

cos | sin

- - -
-
- -
- diff --git a/src/handbook/merge.md b/handbook/merge.md similarity index 100% rename from src/handbook/merge.md rename to handbook/merge.md diff --git a/handbook/merge/index.html b/handbook/merge/index.html deleted file mode 100644 index 6b2830f..0000000 --- a/handbook/merge/index.html +++ /dev/null @@ -1,430 +0,0 @@ - - - - - - - - - - - - Merge <- - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

Merge Operator

- -

Merges one record into another

- -

Syntax

-
record <- [attribute: value, ... ]
-
- -

Description

- -

record <- [attribute: value, ... ] merges the anonymous record [attribute: value, ... ] into the record bound to record. Merge is useful for setting multiple attributes on a record at once.

- -

Examples

- -

Search for a record and merge another record into it.

-
search
-  celia = [#Celia]
-
-bind
-  celia <- [#student grade: 10, school: "East"]
-
- -

See Also

- -

set operator | add operator | remove operator | action phase

- - -
-
- -
- diff --git a/src/handbook/model.md b/handbook/model.md similarity index 100% rename from src/handbook/model.md rename to handbook/model.md diff --git a/handbook/model/index.html b/handbook/model/index.html deleted file mode 100644 index 10f235c..0000000 --- a/handbook/model/index.html +++ /dev/null @@ -1,425 +0,0 @@ - - - - - - - - - - - - Programming Model - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

Programming Model

- -

At its core, Eve only responds to two commands:

- -
    -
  1. What facts do you know about this “record”?
  2. -
  3. Remember a new fact about this “record”.
  4. -
- -

Communication with Eve happens through “records”, which are key-value pairs attached to a unique ID.

- -

Computation occurs as a result of relationships between records. For example, I might model myself as a record with an age and a birth-year. There might also be a record representing the current-year. Then I could compute my age as my birth-year subtracted from the current-year.

- -

A key concept here is that age is a derived fact, supported by two other facts: birth-year and current-year. If either of those supporting facts are removed from Eve, then age can no longer be computed. For intuition, think about modeling this calculation in a spreadsheet using three cells.

- -

One last thing to note about control flow is that we have no concept of a loop in Eve. Recursion is one way to recover looping, but set semantics and aggregates often removes the need for recursion. In Eve, every value is actually a set. With operators defined over sets (think map()) and aggregation (think reduce()) we can actually do away with most cases where we would be tempted to use a loop.

- -

See also

- -

blocks | literate programming | sets | records

- - -
-
- -
- diff --git a/src/handbook/not.md b/handbook/not.md similarity index 68% rename from src/handbook/not.md rename to handbook/not.md index cc5c316..fcb4713 100644 --- a/src/handbook/not.md +++ b/handbook/not.md @@ -21,13 +21,17 @@ not([ ... ]) Not is an anti-join operator, which takes a body of records. For example, we can get a list of people who are not invited to the party: ```eve -friends not invited to the party +// friends not invited to the party +search friends = [#friend] not(friends = [#invited]) + +bind @view + [#value | value: "{{friends.name}} wasn't invited to the party"] ``` ## Examples ## See Also -[is](../is) | [records](../records) | [match](,,/match) \ No newline at end of file +[is](../is) | [records](../records) | [match](../search) diff --git a/handbook/not/index.html b/handbook/not/index.html deleted file mode 100644 index 5b91bd3..0000000 --- a/handbook/not/index.html +++ /dev/null @@ -1,426 +0,0 @@ - - - - - - - - - - - - not - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

not

- -

excludes records from the results

- -

Syntax

-
not([ ... ])
-
- -

Description

- -

Not is an anti-join operator, which takes a body of records. For example, we can get a list of people who are not invited to the party:

-
friends not invited to the party
-  friends = [#friend]
-  not(friends = [#invited])
-
- -

Examples

- -

See Also

- -

is | records | match

- - -
-
- -
- diff --git a/handbook/npm.md b/handbook/npm.md new file mode 100644 index 0000000..254683c --- /dev/null +++ b/handbook/npm.md @@ -0,0 +1,21 @@ +--- +menu: + main: + parent: "Getting Eve" +title: "npm" +weight: 5 +--- + +# Eve on npm + +A package for Eve is available on [npm](https://www.npmjs.com/package/witheve). After [installing npm](https://nodejs.org/en/download/) for your platform, you can download our package with the following command: + +``` +npm install -g witheve +``` + +This will give you a global Eve installation that you can invoke with the command `eve` from any folder. Doing so will launch an Eve server at `http://localhost:8080`. + +## See also + +[linux](../linux) | [mac](../mac) | [windows](../windows) | [docker](../docker) | [running](../running) \ No newline at end of file diff --git a/src/handbook/programs.md b/handbook/programs.md similarity index 100% rename from src/handbook/programs.md rename to handbook/programs.md diff --git a/handbook/programs/index.html b/handbook/programs/index.html deleted file mode 100644 index 9de3051..0000000 --- a/handbook/programs/index.html +++ /dev/null @@ -1,412 +0,0 @@ - - - - - - - - - - - - - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
- - -
- diff --git a/src/handbook/records.md b/handbook/records.md similarity index 65% rename from src/handbook/records.md rename to handbook/records.md index f1e0e01..5816213 100644 --- a/src/handbook/records.md +++ b/handbook/records.md @@ -38,13 +38,17 @@ r.attribute ## Description -Records are the predominate datatype in Eve. Records are used in two ways: +Records are the predominant datatype in Eve. Records are used in two ways: 1. In a `search` you supply a pattern of attributes to match records in a supplied database. 2. In a `bind` or `commit`, you supply a pattern of attributes to insert into a database. `[attribute]` matches all records with the given attribute. +`[attribute1 ... attributeN]` matches all records with the given attributes. + +`[attribute1: variable1, ... , attributeN: variableN]` the expanded form of the above pattern. If the variable assignment is omitted, then the attribute values are assigned to variables equaling their name. If the variable assignment is included, the variables can be used to access their respective attributes instead of the attributes' names. + `[attribute: value]` matches all records with the given attribute bound to specified value. `[attribute > value]` matches all records with the given attribute bound filtered on a value. The inequality `>` can be one of the inequality operators. @@ -74,12 +78,12 @@ Records can have multiple attributes ```eve search [#student name grade school] - + bind @browser [#div text: "{{name}} is in {{grade}}th grade at {{school}}"] ``` -Join records by binding attributes from one record into another record. Equate records with variables. Access record attributes using dot notation. +Join records by binding attributes from one record into another record. Equate records with variables. Access record attributes using dot notation. ```eve search @@ -94,19 +98,42 @@ Records can be nested. ```eve commit - [name: "Jeremey" spouse: [name: "Wendy"]] + [name: "Jeremy" spouse: [name: "Wendy"]] ``` Dot notation can be composed for deep access to records ```eve search - jeremy = [name: "Jeremy"] + Jeremy = [name: "Jeremy"] bind @browser - [#div text: "{{jeremy.name}} is married to {{jeremy.spouse.name}}"] + [#div text: "{{Jeremy.name}} is married to {{Jeremy.spouse.name}}"] ``` +Using dot notation to access record attributes means conditioning the block to have those attributes available. +These two following blocks point to the same results: + +**without dot notation** +```eve +search + [#student name grade school] + +bind @browser + [#div text: "{{name}} is in {{grade}}th grade at {{school}}"] +``` + +**with dot notation** +```eve +search + [#student] + +bind @browser + [#div text: "{{student.name}} is in {{student.grade}}th grade at {{student.school}}"] +``` + +They get executed only if there's at least one student with a name, a grade and a school attribute. + ## See Also -[search](../search) | [bind](../bind) | [commit](../commit) | [tags](../tags) | [databases](../databases) | [equality](../equality) | [inequality](../inequality) | [joins](../joins) \ No newline at end of file +[search](../search) | [bind](../bind) | [commit](../commit) | [tags](../tags) | [databases](../databases) | [equality](../equality) | [inequality](../inequality) | [joins](../joins) diff --git a/handbook/records/index.html b/handbook/records/index.html deleted file mode 100644 index 51595a7..0000000 --- a/handbook/records/index.html +++ /dev/null @@ -1,499 +0,0 @@ - - - - - - - - - - - - Records - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

Records

- -

Records are attribute: value pairs associated to a unique ID

- -

Syntax

-
// A record with an attribute
-[attribute]
-
-// A record with an attribute of given value
-[attribute: value]
-
-// A record with N attributes of given values
-[attribute1: value1, ... , attributeN: valueN]
-
-// A record nested within another record
-[attribute1: [attribute2: value]]
-
-// Equates a record and a variable
-r = [attribute ...]
-
-// Accessing an attribute on a record
-r.attribute
-
-// Join two records
-[attribute1: attribute2]
-[attribute2]
-
- -

Description

- -

Records are the predominate datatype in Eve. Records are used in two ways:

- -
    -
  1. In a search you supply a pattern of attributes to match records in a supplied database.
  2. -
  3. In a bind or commit, you supply a pattern of attributes to insert into a database.
  4. -
- -

[attribute] matches all records with the given attribute.

- -

[attribute: value] matches all records with the given attribute bound to specified value.

- -

[attribute > value] matches all records with the given attribute bound filtered on a value. The inequality > can be one of the inequality operators.

- -

[attribute1: value1, ... , attributeN: valueN] is the general case for records. This matches all records with all of the given attributes filtered on the given values.

- -

[attribute1: [attribute2: value]] nests a record within another record.

- -

r = [attribute ...] equates a record to a variable r.

- -

r.attribute accesses the value of attribute on variable r.

- -

Examples

- -

Match all records with a name, and bind a #div for each one.

-
search
-  [name]
-
-bind @browser
-  [#div text: name]
-
- -

Records can have multiple attributes

-
search
-  [#student name grade school]
-  
-bind @browser
-  [#div text: "{{name}} is in {{grade}}th grade at {{school}}"]
-
- -

Join records by binding attributes from one record into another record. Equate records with variables. Access record attributes using dot notation.

-
search
-  school = [#school name address]
-  student = [#student school: name]
-
-bind @browser
-  [#div text: "{{student.name}} attends {{school.name}} at {{address}}"]
-
- -

Records can be nested.

-
commit
-  [name: "Jeremey" spouse: [name: "Wendy"]]
-
- -

Dot notation can be composed for deep access to records

-
search
-  jeremy = [name: "Jeremy"]
-
-bind @browser
-  [#div text: "{{jeremy.name}} is married to {{jeremy.spouse.name}}"]
-
- -

See Also

- -

search | bind | commit | tags | databases | equality | inequality | joins

- - -
-
- -
- diff --git a/src/handbook/remove.md b/handbook/remove.md similarity index 100% rename from src/handbook/remove.md rename to handbook/remove.md diff --git a/handbook/remove/index.html b/handbook/remove/index.html deleted file mode 100644 index ddb2929..0000000 --- a/handbook/remove/index.html +++ /dev/null @@ -1,423 +0,0 @@ - - - - - - - - - - - - Remove: -= - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
- - -
- diff --git a/handbook/running.md b/handbook/running.md new file mode 100644 index 0000000..58e559f --- /dev/null +++ b/handbook/running.md @@ -0,0 +1,72 @@ +--- +menu: + main: + parent: "Introduction" +title: "Running Eve" +weight: 2 +--- + +# Running Eve + +If you've downloaded and installed Eve via [npm](../npm), you can launch Eve with the `eve` command. + +``` +eve +``` + +This launches an Eve server running in the Eve root directory at `http://localhost:8080`. From here, you'll be directed to `quickstart.eve`, and have access to the Eve examples directory from within the editor. + +## Running an Eve File + +If you want to run a specific Eve program, you can provide its path after the `eve` command: + +``` +eve ~/myDir/myEveFile.eve +``` + +Then you navigate to Eve in your browser to access the specified program. If you like, you can also recover the editor with a flag: + +``` +eve ~/myEveDir/myEveFile.eve --editor +``` + +This will run the supplied Eve program with the editor visible + +## Running Eve in Server mode + +Eve can be started in server mode using the `--server` flag: + +``` +eve --server +``` + +Without this flag, execution of Eve programs happens within the browser, with the Eve server acting only as a file server between the browser and your local system. In server mode, Eve will instead execute your program on the server. Currently written programs will operate exactly as before, but this is a preliminary step in order to get networked Eve applications going (like a chat server or a multiplayer game). There is still work needed to be done there + + +## Eve Workspaces + +You can run Eve in a custom workspace. To create a new Eve workspace, create a folder with an empty file named `package.json`, then start Eve from within this folder. Eve recognizes that it is starting an Eve workspace, and will serve `*.eve` files from within this directory instead of the Eve examples folder. Furthermore, you can serve various assets, like images or CSS, by placing them in an "assets" sub-folder. + +## Flags + +- server - run Eve in server execution mode. +- editor - run Eve with the editor visible. This defaults to false, except when Eve is started in an Eve project folder. +- port - specify the port on which to run the Eve server. Alternatively, the running port can be specified with the `PORT` environment variable, which takes precedence over the `port` flag. + +## Running Eve from Source + +To run Eve from source, you invoke the following command in the extracted Eve folder: + +``` +npm start +``` + +You can apply the above flags to this command, but you'll need an extra `--` to do so. e.g. + +``` +npm start -- --port 1234 +``` + +## See Also + +[linux](../linux) | [mac](../mac) | [windows](../windows) | [docker](../docker) | [npm](../npm) \ No newline at end of file diff --git a/handbook/running/index.html b/handbook/running/index.html deleted file mode 100644 index c61f3aa..0000000 --- a/handbook/running/index.html +++ /dev/null @@ -1,417 +0,0 @@ - - - - - - - - - - - - Running Eve - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

Running Eve

- -

In the extract Eve directory, Running

- -
npm start
-
- -

Then direct your browser to http://localhost:8080

- -

See Also

- -

linux | mac | windows | docker

- - -
-
- -
- diff --git a/src/handbook/search.md b/handbook/search.md similarity index 100% rename from src/handbook/search.md rename to handbook/search.md diff --git a/handbook/search/index.html b/handbook/search/index.html deleted file mode 100644 index 01bbdf3..0000000 --- a/handbook/search/index.html +++ /dev/null @@ -1,439 +0,0 @@ - - - - - - - - - - - - search - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

search

- -

signifies the beginning of the search phase

- -

Syntax

-
search
-
-search @database1, ..., @databaseN
-
- -

Description

- -

search signifies the beginning of the search phase of a block. By default, searched records are drawn from a default local database.

- -

search @database1, ... @databaseN draws searched records from one or more databases.

- -

Examples

- -

search a record

-
search
-  [name]
-  
-bind
-  [#div text: name]  
-
- -

Omit the search phase

-
bind
-  [#div text: "Hello, world"]
-
- -

See Also

- -

bind | commit | databases | records

- - -
-
- -
- diff --git a/handbook/session/index.md b/handbook/session/index.md new file mode 100644 index 0000000..2e85bca --- /dev/null +++ b/handbook/session/index.md @@ -0,0 +1,10 @@ +--- +menu: + main: + parent: "Databases" +title: "@session" +weight: 1 +--- + +# @session + diff --git a/src/handbook/set.md b/handbook/set.md similarity index 100% rename from src/handbook/set.md rename to handbook/set.md diff --git a/handbook/set/index.html b/handbook/set/index.html deleted file mode 100644 index d16ab19..0000000 --- a/handbook/set/index.html +++ /dev/null @@ -1,442 +0,0 @@ - - - - - - - - - - - - Set: := - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

Set Operator

- -

Sets the value of an attribute on a record

- -

Syntax

-
// Set attribute to value
-record.attribute := value
-
-// Remove attribute
-record.attribute := none
-
- -

Description

- -

record.attribute := value sets attribute to value. If record already has an attribute with a value, then this will overwrite it. Otherwise, if record doesn’t have an attribute with this name already, then := will create the attribute and set it to value.

- -

attribute can be an attribute already on the record, or it can be a new attribute.

- -

value can be a string or number literal, a record, or a variable bound to one of these.

- -

record.attribute := none sets the value of attribute to the special value none, which is the empty set (a set with no elements).

- -

Examples

- -

Set the age of #students that don’t already have an age.

-
search
-  student = [#student]
-  age = if student.age then student.age
-        else if student.grade then student.grade + 6
-        
-bind
-  student.age := age
-
- -

See Also

- -

add operator | remove operator | merge operator

- - -
-
- -
- diff --git a/src/handbook/sets.md b/handbook/sets.md similarity index 57% rename from src/handbook/sets.md rename to handbook/sets.md index fc1d749..012cd91 100644 --- a/src/handbook/sets.md +++ b/handbook/sets.md @@ -12,7 +12,7 @@ Expressions and actions in Eve work over sets. ## Description -[Sets](https://en.wikipedia.org/wiki/Set_(mathematics)) are unordered collections where every element of the collection is unique. For example, `("a", "b", "c")` is a set, while `("a", "a", "b", "c")` is not. Furthermoer, `("a", "b", "c")` and `("c", "b", "a")` are equivalent sets, even though the order of elements is different. +[Sets](https://en.wikipedia.org/wiki/Set_(mathematics)) are unordered collections where every element of the collection is unique. For example, `("a", "b", "c")` is a set, while `("a", "a", "b", "c")` is not. Furthermore, `("a", "b", "c")` and `("c", "b", "a")` are equivalent sets, even though the order of elements is different. ## Examples @@ -24,6 +24,30 @@ Expressions and actions in Eve work over sets. (("a", 1), ("a", 2), ("a", 3)) // Sets within sets can be used to repeat values ``` +### Set Example in Eve + +```eve +commit + [#point x: 5, y: 4] + [#point x: 3, y: 7] + [#point x: 1, y: 2] +``` + +We can calculate the distance from each of these points to every other point: + +```eve +search + p1 = [#point x: x1, y: y1] + p2 = [#point x: x2, y: y2] + dx = x1 - x2 + dy = y1 - y2 + +bind @browser + [#div sort: x1, text: "({{x1}}, {{y1}}) - ({{x2}}, {{y2}}) = ({{dx}}, {{dy}})"] + ``` + +In imperative languages, you would need a nested loop to cover all of the combinations. In Eve, functions (and infix operators like `+`, which are just sugar for a function) operate over sets, so this loop is implicitly handled by Eve. + ## See Also -[programming model](../model) | [functions](../functions) | [aggregates](../aggregates) | [cartesian product](../glossary/#cartesian-product) \ No newline at end of file +[programming model](../model) | [functions](../functions) | [aggregates](../aggregates) | [cartesian product](../glossary/#cartesian-product) diff --git a/handbook/sets/index.html b/handbook/sets/index.html deleted file mode 100644 index 32a212e..0000000 --- a/handbook/sets/index.html +++ /dev/null @@ -1,425 +0,0 @@ - - - - - - - - - - - - Sets - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

Set Semantics

- -

Expressions and actions in Eve work over sets.

- -

Description

- -

Sets are unordered collections where every element of the collection is unique. For example, ("a", "b", "c") is a set, while ("a", "a", "b", "c") is not. Furthermoer, ("a", "b", "c") and ("c", "b", "a") are equivalent sets, even though the order of elements is different.

- -

Examples

- -
(1, 2, 3, 4) // Every element is unique           
-(1, 2, 3, 1) // One is repeated twice, so this is not a set
-(4, 3, 2, 1) // This set is the same as the first, despite the order of elements
-("Steve", 1, (1, 2)) // Elements can be nonhomogeneous, as long as each one is unique
-(("a", 1), ("a", 2), ("a", 3)) // Sets within sets can be used to repeat values
-
- -

See Also

- -

programming model | functions | aggregates | cartesian product

- - -
-
- -
- diff --git a/src/handbook/standard-library.md b/handbook/standard-library.md similarity index 55% rename from src/handbook/standard-library.md rename to handbook/standard-library.md index 474bf21..a935ad5 100644 --- a/src/handbook/standard-library.md +++ b/handbook/standard-library.md @@ -1,7 +1,18 @@ +--- +menu: + main: + parent: "Databases" +title: "Standard Library" +weight: 0 +--- + # Standard Library +The Eve standard library of functions is globally available, meaning you don't have to reference a specific database to use these functions. + ## Description +- [general](../general) - General functions - [math](../math) - General mathematical and trigonometric functions - [strings](../strings) - Functions that manipulate strings - [statistics](../statistics) - Functions that calculate statistical measures on values diff --git a/handbook/standard-library/index.html b/handbook/standard-library/index.html deleted file mode 100644 index c3ba25e..0000000 --- a/handbook/standard-library/index.html +++ /dev/null @@ -1,415 +0,0 @@ - - - - - - - - - - - - - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

Standard Library

- -

Description

- -
    -
  • math - General mathematical and trigonometric functions
  • -
  • strings - Functions that manipulate strings
  • -
  • statistics - Functions that calculate statistical measures on values
  • -
  • date & time - Functions that get and manipulate date and time
  • -
- - -
-
- -
- diff --git a/src/handbook/statistics/count.md b/handbook/statistics/count.md similarity index 67% rename from src/handbook/statistics/count.md rename to handbook/statistics/count.md index 8c3f6f0..c355f53 100644 --- a/src/handbook/statistics/count.md +++ b/handbook/statistics/count.md @@ -12,24 +12,46 @@ Returns the number of elements in a set ## Syntax ```eve +// Counts the elements in given y = count[given] + +// Counts the elements established by the set (var1, ... , varN) +y = count[given: (var1, ... , varN)] + +// Group given by the values in per, and count each group y = count[given, per] ``` ## Attributes -- `given` - the set to count over +- `given` - establishes the set to count over. - `per` - _optional_ - one or more attributes by which to group `given`. ## Description `y = count[given]` counts the number of elements in `given`. -`y = count[given, per]` counts the number of elements in `given`, grouped by the attribute(s) provided in `per`. For instance, `class-size = count[given: students, per: grade]` would count the number of students in each grade. You can group along multiple axes; the pervious example could be extended to work across multiple schools by doing `class-size = count[given: students, per: (grade, school)]`. See the examples section to see these in action. +`y = count[given: ()]` counts the number of elements in `given`. + +`y = count[given, per]` counts the number of elements in `given`, grouped by the attribute(s) provided in `per`. For instance, `class-size = count[given: students, per: grade]` would count the number of students in each grade. You can group along multiple axes; the previous example could be extended to work across multiple schools by doing `class-size = count[given: students, per: (grade, school)]`. See the examples section to see these in action. + +## Counting Zero + +Eve's semantics prevent count from ever returning 0; For `count[]` to run, a search must match at least one record. If a search doesn't match any records, then the entire block will not execute. In order to actually get a 0 result, you have to condition the count with an if expression: + +```eve +search + total-items = if c = count[given: [#item]] then c +                else 0 +bind @view + [#value | value: "total items: {{total-items}}"] +``` + +This block searches for `[#item]` records. If any are found, then `count[]` is able to proceed. If none are found, then the if expression allows the block to execute nonetheless, so the total items is correctly reported as 0. ## Examples -Before we get to the `count` examples, let's add some students. Each `#student` has a `grade` and a `school`. Grades are one of 10, 11, or 12. Schools are one of "West" and "East". +Before we get to the `count[]` examples, let's add some students. Each `#student` has a `grade` and a `school`. Grades are one of 10, 11, or 12. Schools are one of "West" and "East". ```eve commit diff --git a/handbook/statistics/count/index.html b/handbook/statistics/count/index.html deleted file mode 100644 index 22b122f..0000000 --- a/handbook/statistics/count/index.html +++ /dev/null @@ -1,489 +0,0 @@ - - - - - - - - - - - - count - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

count

- -

Returns the number of elements in a set

- -

Syntax

-
y = count[given]
-y = count[given, per]
-
- -

Attributes

- -
    -
  • given - the set to count over
  • -
  • per - optional - one or more attributes by which to group given.
  • -
- -

Description

- -

y = count[given] counts the number of elements in given.

- -

y = count[given, per] counts the number of elements in given, grouped by the attribute(s) provided in per. For instance, class-size = count[given: students, per: grade] would count the number of students in each grade. You can group along multiple axes; the pervious example could be extended to work across multiple schools by doing class-size = count[given: students, per: (grade, school)]. See the examples section to see these in action.

- -

Examples

- -

Before we get to the count examples, let’s add some students. Each #student has a grade and a school. Grades are one of 10, 11, or 12. Schools are one of “West” and “East”.

-
commit
-  [#student name: "Diedra" grade: 10 school: "West"]
-  [#student name: "Celia" grade: 10 school: "West"]
-  [#student name: "Michaela" grade: 11 school: "West"]
-  [#student name: "Jermaine" grade: 11 school: "West"]
-  [#student name: "Issac" grade: 12 school: "West"]
-  [#student name: "Jamar" grade: 12 school: "West"]
-  [#student name: "Yee" grade: 10 school: "East"]
-  [#student name: "Johanne" grade: 10 school: "East"]
-  [#student name: "Mertie" grade: 10 school: "East"]
-  [#student name: "Elmira" grade: 11 school: "East"]
-
- -

First let’s count the total number of students in the school district.

-
search
-  students = [#student]
-  enrollment = count[given: students]
-
-bind @view
-  [#value | value: "There are {{enrollment}} students in the district"]
-
- -

Now let’s count the number of students in each school.

-
search
-  students = [#student school]
-  school-enrollment = count[given: students, per: school]
-
-bind @view
-  [#value | value: "{{school-enrollment}} attend {{school}}"]
-
- -

We could have similarly counted the number of students in each grade across the district.

-
search
-  students = [#student grade]
-  grade-enrollment = count[given: students, per: grade]
-
-bind @view
-  [#value | value: "{{grade-enrollment}} students are in {{grade}}th grade"]
-
- -

Finally, we can count the number of students per grade, per school.

-
search
-  students = [#student grade school]
-  grade-school-enrollment = count[given: students, per: (grade, school)]
-
-bind @view
-  [#value | value: "{{grade-school-enrollment}} students are in {{grade}}th grade at {{school}}"]
-
- -

Example Usage

- - - -

See Also

- -

sum | aggregates

- - -
-
- -
- diff --git a/handbook/statistics/index.html b/handbook/statistics/index.html deleted file mode 100644 index 8b66eaf..0000000 --- a/handbook/statistics/index.html +++ /dev/null @@ -1,416 +0,0 @@ - - - - - - - - - - - - Statistics - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

Statistics

- -
    -
  • count - counts the number of elements in a set
  • -
- -

Random Functions

- -
    -
  • random - Generates a random number between 0 and 1
  • -
- - -
-
- -
- diff --git a/src/handbook/statistics/index.md b/handbook/statistics/index.md similarity index 95% rename from src/handbook/statistics/index.md rename to handbook/statistics/index.md index 082017d..7e29a44 100644 --- a/src/handbook/statistics/index.md +++ b/handbook/statistics/index.md @@ -3,6 +3,7 @@ menu: main: parent: "Standard Library" title: "Statistics" +weight: 4 --- # Statistics diff --git a/src/handbook/statistics/random.md b/handbook/statistics/random.md similarity index 55% rename from src/handbook/statistics/random.md rename to handbook/statistics/random.md index 5f140cd..3faf06f 100644 --- a/src/handbook/statistics/random.md +++ b/handbook/statistics/random.md @@ -7,7 +7,7 @@ title: "random" # random -Generates a random number between 0 and 1 +generates a random number between 0 and 1 ## Syntax @@ -21,7 +21,8 @@ y = random[seed] ## Description -`y = random[seed]` generates a pseudorandom number drawn from the [standard uniform distribution][1], meaning the generated number is restricted to be between 0 and 1. To generate a number between a custom range, see the examples. +`y = random[seed]` generates a pseudorandom number drawn from the [standard uniform distribution][1], meaning the generated number is restricted to be between 0 and 1. To generate a number between a custom range, see the examples. +`random` requires a seed as an argument because there is no such thing as a truely random number generator. Instead, "random number generators" are equations that produce results (based on original numbers) that are unpredicatble to humans, but repeatable. For instance, `7 * i % 11` is a simple pseudorandom number generator: the numbers it produces seem to have no relation at all with `i` itself. Therefore it is functionally random to humans, but with the same value for `i`, the same output is produced. In this example, `i` is the seed. A good value to use as a seed is the time in milliseconds, since it is always changing, insuring that you will almost never get the same seed twice (this does not mean you will always get a different number, however). [1]: https://en.wikipedia.org/wiki/Uniform_distribution_(continuous)#Standard_uniform @@ -34,7 +35,7 @@ search [#time minutes seconds] x = random[seed: seconds] -commit +commit @browser [#div time: "{{minutes}}{{seconds}}" text: x] ``` @@ -46,7 +47,7 @@ search max = 10 x = random[seed: 1] * (max - min) + min -bind +bind @browser [#div text: x] ``` @@ -57,7 +58,7 @@ search i = range[from: 1, to: 10] x = random[seed: i] -bind +bind @browser [#div text: x] ``` @@ -65,4 +66,6 @@ bind - [Flappy Bird](https://github.com/witheve/Eve/blob/master/examples/flappy.eve) -## See Also \ No newline at end of file +## See Also + +[gaussian][../gaussian] diff --git a/handbook/statistics/random/index.html b/handbook/statistics/random/index.html deleted file mode 100644 index b8648cc..0000000 --- a/handbook/statistics/random/index.html +++ /dev/null @@ -1,460 +0,0 @@ - - - - - - - - - - - - random - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

random

- -

Generates a random number between 0 and 1

- -

Syntax

-
y = random[seed]
-
- -

Attributes

- -
    -
  • seed - initializes the random number generator. The seed itself does not need to be random.
  • -
- -

Description

- -

y = random[seed] generates a pseudorandom number drawn from the standard uniform distribution, meaning the generated number is restricted to be between 0 and 1. To generate a number between a custom range, see the examples.

- -

Examples

- -

Prints a random number every second. The time attribute in #div is used to make each generated number unique for display purposes.

-
search 
-  [#time minutes seconds]
-  x = random[seed: seconds]
-
-commit
-  [#div time: "{{minutes}}{{seconds}}"  text: x]
-
- -

Generate a random number between min and max

-
search
-  min = 5
-  max = 10
-  x = random[seed: 1] * (max - min) + min
-
-bind
-  [#div text: x]
-
- -

Generate 10 random numbers

-
search
-  i = range[from: 1, to: 10]
-  x = random[seed: i]
-
-bind
-  [#div text: x]
-
- -

Example Usage

- - - -

See Also

- - -
-
- -
- diff --git a/src/handbook/string-interpolation.md b/handbook/string-interpolation.md similarity index 85% rename from src/handbook/string-interpolation.md rename to handbook/string-interpolation.md index 26d2aff..bd66d50 100644 --- a/src/handbook/string-interpolation.md +++ b/handbook/string-interpolation.md @@ -22,7 +22,7 @@ injects the value of an attribute or variable into a string String interpolation works element-wise on its input. This means the string will be repeated for every unique value in `variable`. -Multiple variables can be interpolated into strings. If the variables have no relation to eacother (i.e. they are not joined or part of the same record), then string interpolation is applied to the cartesian product of the sets. +Multiple variables can be interpolated into strings. If the variables have no relation to each other (i.e. they are not joined or part of the same record), then string interpolation is applied to the cartesian product of the sets. ## Examples diff --git a/handbook/string-interpolation/index.html b/handbook/string-interpolation/index.html deleted file mode 100644 index 190aacf..0000000 --- a/handbook/string-interpolation/index.html +++ /dev/null @@ -1,443 +0,0 @@ - - - - - - - - - - - - String Interpolation - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

String Interpolation

- -

injects the value of an attribute or variable into a string

- -

Syntax

-
"{{ variable }}"
-
- -

Description

- -

"{{ variable }}" embeds the value of variable within a string. Variable should be an attribute on a record or the result of an expression.

- -

String interpolation works element-wise on its input. This means the string will be repeated for every unique value in variable.

- -

Multiple variables can be interpolated into strings. If the variables have no relation to eacother (i.e. they are not joined or part of the same record), then string interpolation is applied to the cartesian product of the sets.

- -

Examples

- -

Display student name, grade and school:

-
search
-  [#student name grade school]
-
-bind @browser
-  [#div text: "{{name}} is a {{grade}}th grade student at {{school}}."]
-
- -

Use string interpolation to display pairs of numbers:

-
search 
-  i = range[from: 1, to: 10]
-  j = range[from: 1, to: 10]
-
-bind @browser
-  [#div text: "({{ i }}, {{ j }})"]
-
- -

See Also

- -

strings | expressions

- - -
-
- -
- diff --git a/handbook/strings/convert.md b/handbook/strings/convert.md new file mode 100644 index 0000000..a8b1e8b --- /dev/null +++ b/handbook/strings/convert.md @@ -0,0 +1,54 @@ +--- +menu: + main: + parent: "Strings" +title: "convert" +--- + +# convert + +converts a number into a string or vice versa. + +## Syntax + +```eve +converted = convert[value, to] +``` + +## Attributes + +- `converted` - the resulting converted value +- `value` - the value to be converted +- `to` - a string that specifies the target value type, either "number" or "string" + +## Description + +`converted = convert[value, to]` converts `value` from a number to a string if `to` is set to `"string"`, or if `to` is set to `"number"` converts `value` from a string to a number. + +## Examples + +Convert a string to a number, multiplies it + +```eve +search + x = convert[value: "1", to: "number"] + y = x * 2 + +bind @browser + [#div text: y] +``` + +Convert a number to a string, gets its length + +```eve +search + str = convert[value: "42", to: "number"] + c = length[str] + +bind @browser + [#div text: c] +``` + +## See Also + +[concat](../concat) | [join](../join) | [char-at](../char-at) | [substring](../substring) | [length](../length) | [replace](../replace) | [split](../split) diff --git a/handbook/strings/find.md b/handbook/strings/find.md new file mode 100644 index 0000000..86bfd56 --- /dev/null +++ b/handbook/strings/find.md @@ -0,0 +1,67 @@ +--- +menu: + main: + parent: "Strings" +title: "find" +--- + +# find + +finds a string within a larger string (optinally case-sensitive), starting from the starting index (which defaults to 1). + +## Syntax + +```eve +(string-position, result-index) = find[text, subtext, case-sensitive, from] +``` + +## Attributes + +- `text` - the larger text to be searched within +- `subtext` - the string to find in `text` +- `case-sensitive` - the recovered tokens after the split +- `string-position` - the positions of the occurences of `subtext` in the original text +- `result-index` - the index of this occurence in all occurences of `subtext` in `text` + +## Description + +`(string-position, result-index) = find[text, subtext, case-sensitive, from]` finds all the occurences of `subtext` in `text`, by default case-insensitively. For each match, it returns the position in the string (index starting at one) and the number of the match (for instance, the first match is one, the second match is two). If `from` is specified, it starts the search at that index, inclusively. + +## Examples + +Find all occurences of the string "hello" in `str` (case-insensitive, starting at the first index) + +```eve +search + str = "ahellobhellochello" + (a, b) = find[text: str, subtext: "hello"] + +bind @browser + [#div text: "{{a}}, {{b}}"] +``` + +Find all occurences of a capital 'X' in a string + +```eve +search + str = "xxxXxxXxXXX" + (a, b) = find[text: str, subtext: "X", case-sensitive: true] + +bind @browser + [#div text: "{{a}}, {{b}}"] +``` + +Find occurences of 'X' after the first one + +```eve +search + str = "xxxXxxXxXXX" + (a, b) = find[text: str, subtext: "X", case-sensitive: true, from: 5] + +bind @browser + [#div text: "{{a}}, {{b}}"] +``` + +## See Also + +[concat](../concat) | [join](../join) | [char-at](../char-at) | [substring](../substring) | [length](../length) | [replace](../replace) | [split](../split) diff --git a/handbook/strings/index.html b/handbook/strings/index.html deleted file mode 100644 index e01be24..0000000 --- a/handbook/strings/index.html +++ /dev/null @@ -1,414 +0,0 @@ - - - - - - - - - - - - Strings - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
- - -
- diff --git a/handbook/strings/index.md b/handbook/strings/index.md new file mode 100644 index 0000000..bfbacf8 --- /dev/null +++ b/handbook/strings/index.md @@ -0,0 +1,16 @@ +--- +menu: + main: + parent: "Standard Library" +title: "Strings" +weight: 3 +--- + +# Strings + +- [split](split) - split a string into tokens +- [join](join) - join tokens into a string +- [length](length) - return the length of a string +- [substring](substring) - return a substring of another string +- [find](find) - return a substring of another string +- [convert](convert) - return a substring of another string diff --git a/handbook/strings/join.md b/handbook/strings/join.md new file mode 100644 index 0000000..01ce7c3 --- /dev/null +++ b/handbook/strings/join.md @@ -0,0 +1,87 @@ +--- +menu: + main: + parent: "Strings" +title: "join" +--- + +# join + +Joins a set of tokens into one or more contiguous strings + +## Syntax + +```eve +// join tokens into a string +text = join[token, given, index, with] + +// group tokens before joining +text = join[token, given, index, with, per] +``` + +## Attributes + +- `token` - set of strings to be joined +- `given` - establishes the set being joined. If tokens are not unique, you can add attributes here that will make them unique. Must at least provide `token` as part of the given set, or only the first one will be returned. +- `index` - indicates where each `token` is ordered in `text`. +- `with` - inserted between every element in `token`. +- `per` - _optional_ - one or more attributes by which to group `token`. + +## Description + +`text = join[token, given, index, with]` joins elements of `token` in an order specified by `index`, inserting `with` between each token. Returns the joined string. + +`text = join[token, given, index, with, per]` groups `token` according to the values of `per` before joining. + +## Examples + +Split a sentence into tokens, and join the tokens into a sentence again + +```eve +search + // Split the sentence into words + (token, index) = split[text: "the quick brown fox", by: " "] + + // Join the words back into a sentence, but with hyphens instead of spaces + text = join[token given: token, index with: "-"] + +bind @view + [#value | value: text] // Expected "the-quick-brown-fox" +``` + +--- + +Since join is an aggregate, set semantics play an important part here; if we don't specify what makes each token unique, then the results can be surprising. The following example will demonstrate this. + +Let's split the phrase "hello world" into letters: + +```eve +search + //token = (h, e, l, l, o, w, o, r, l, d) + (token, index) = split[text: "hello world", by: ""] + +bind + [#phrase token index] + +bind @view + [#value | value: token] +``` + +Let's join this phrase back together. Like last time, we'll join with a `-`. Notice that some tokens ("l" and "o") should appear multiple times in the phrase. To correctly join them, we add `index` as part of the `given` set: + +```eve +search + [#phrase token index] + // given = (("h", 1), ("e", 2), ("l", 3), ("l", 4) ... ("l", 10), ("d", 11)) + // without including index, the result is "h-e-l-o- -w-r-d". Try it and see! + text = join[token given: (token, index) index with: "-"] + +bind @view + [#value | value: text] +``` + +The result expected result is "h-e-l-l-o- -w-o-r-l-d". + +## See Also + +[split](../split) diff --git a/handbook/strings/join/index.html b/handbook/strings/join/index.html deleted file mode 100644 index a7fb864..0000000 --- a/handbook/strings/join/index.html +++ /dev/null @@ -1,447 +0,0 @@ - - - - - - - - - - - - join - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

join

- -

Joins a set of strings into a single string

- -

Syntax

-
text = join[token, index, with]
-
- -

Attributes

- -
    -
  • token - set of elements to be joined
  • -
  • index - indicates the order of the tokens in the joined string
  • -
  • with - inserted between every element in tokens
  • -
- -

Description

- -

text = join[token, index, with] takes tokens tokens together using with in an order specified by index. Returns the joined string.

- -

Examples

- -

Split a sentence into tokens

-
search
-  (token, index) = split[text: "the quick brown fox", by: " "]
-
-bind
-  [#token token index]
-
- -

Join the tokens into a sentence again, but with hyphens instead of spaces

-
search
-  [#token token index]
-  text = join[token, index, with: " "]
-
-bind
-  [#div text] // Expected "the-quick-brown-fox"
-
- -

See Also

- -

join | split | char-at | find | length | replace

- - -
-
- -
- diff --git a/handbook/strings/length.md b/handbook/strings/length.md new file mode 100644 index 0000000..a123d8b --- /dev/null +++ b/handbook/strings/length.md @@ -0,0 +1,67 @@ +--- +menu: + main: + parent: "Strings" +title: "length" +--- + +# length + +Returns the length of a string + +## Syntax + +```eve +len = length[text] +len = length[text, as] +``` + +## Attributes + +- `text` - set of strings to be joined +- `as` _optional_ - sets the method by which to count characters. Can be one of + - "symbols" (default) - counts the visible symbols in the string. Characters that span multiple bytes (such as Unicode characters) are counted as a single symbol. + - "code-points" - counts the characters as code-points + - "bytes" (not yet implemented) - counts the characters as bytes + +## Description + +`len = length[text]` returns the number of symbols in a string. + +`len = length[text, as]` returns the number of characters in a string, determined by `as`. + +## Examples + +Count the number of characters in a string. We expect a `len` of 5: + +```eve +search + len = length[text: "Hello"] + +bind @view + [#value | value: len] +``` + +This time, let's throw a Unicode snowman in the mix. In symbols, this is counted as a single character. We expect a `len` of 9 here: + +```eve +search + len = length[text: "Poodle: 🐩", as "symbols"] + +bind @view + [#value | value: len] +``` + +But when we count code-points, the poodle is counted as 2. We expect a `len` of 10 here: + +```eve +search + len = length[text: "Poodle: 🐩", as: "code-points"] + +bind @view + [#value | value: len] +``` + +## See Also + +[split](../split) | [split](../join) diff --git a/src/handbook/strings/split.md b/handbook/strings/split.md similarity index 97% rename from src/handbook/strings/split.md rename to handbook/strings/split.md index 7f89eb4..6b27f43 100644 --- a/src/handbook/strings/split.md +++ b/handbook/strings/split.md @@ -17,7 +17,7 @@ splits a string at the given delimiter ## Attributes -- `text` - the text to be split +- `text` - the text to be split - `by` - the delimiter at which to split the text. An empty string will split the text at every character. - `token` - the recovered tokens after the split - `index` - the indices of the tokens in the original text diff --git a/handbook/strings/split/index.html b/handbook/strings/split/index.html deleted file mode 100644 index 8920118..0000000 --- a/handbook/strings/split/index.html +++ /dev/null @@ -1,447 +0,0 @@ - - - - - - - - - - - - split - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

split

- -

splits a string at the given delimiter

- -

Syntax

-
(token, index) = split[text, by]
-
- -

Attributes

- -
    -
  • text - the text to be split
  • -
  • by - the delimiter at which to split the text. An empty string will split the text at every character.
  • -
  • token - the recovered tokens after the split
  • -
  • index - the indices of the tokens in the original text
  • -
- -

Description

- -

(token, index) = split[text, by] splits a text into tokens according to the given delimiter, by. Returns token and index of those tokens in the original string.

- -

Examples

- -

Splits a string at every character

-
search
-  (token, index) = split[text: "hello, world", by: ""]
-  
-bind @browser
-  [#div text: "{{token}} {{index}}"]
-
- -

Split a sentence into words and display them in order

-
search
-  (token, index) = split[text: "the quick brown fox", by: " "]
-  
-bind @browser
-  [#div sort: index, text: token]
-
- -

See Also

- -

concat | join | char-at | find | length | replace

- - -
-
- -
- diff --git a/handbook/strings/substring.md b/handbook/strings/substring.md new file mode 100644 index 0000000..b6b111c --- /dev/null +++ b/handbook/strings/substring.md @@ -0,0 +1,44 @@ +--- +menu: + main: + parent: "Strings" +title: "substring" +--- + +# substring + +gets the substring of the provided string starting at the specified index (or 1 if not specified) and ending at the other specified index (required). + +## Syntax + +```eve +substr = substring[text, from, to] +``` + +## Attributes + +- `text` - the text to substring +- `to` - the maximum index of the substring, inclusive. +- `from` - the starting index of the substring, starting at one, inclusive +- `substr` - the final substring + +## Description + +`substr = substring[text, from, to]` gets a substring of `text` stretching from `from` to `to`, inclusively on both sides: [from, to]. +**Note:** String indexing starts at one. If you are an experienced programmer, this might trip you up. + +## Examples + +Extracts the word "hello" from the string + +```eve +search + greeting = substring[text: "ahellob", from: 2, to: 6] + +bind @browser + [#div text: greeting] +``` + +## See Also + +[concat](../concat) | [join](../join) | [char-at](../char-at) | [find](../find) | [length](../length) | [replace](../replace) | [split](../split) diff --git a/handbook/strings/urlencode.md b/handbook/strings/urlencode.md new file mode 100644 index 0000000..fd4083c --- /dev/null +++ b/handbook/strings/urlencode.md @@ -0,0 +1,41 @@ +--- +menu: + main: + parent: "Strings" +title: "urlencode" +--- + +# urlencode + +the urlencoded, websafe, version of a string. + +## Syntax + +```eve +safe = urlencode[text] +``` + +## Attributes + +- `text` - the string to be encoded +- `safe` - a url-safe, encoded string + +## Description + +`safe = urlencode[text]` converts `text` into a url-safe string (e.g. replacing a space with `%20`), returning it to `safe`. + +## Examples + +Urlencodes a mathematical expression + +```eve +search + z = urlencode[text: "x * 2"] + +bind @browser + [#div text: z] +``` + +## See Also + +[concat](../concat) | [join](../join) | [char-at](../char-at) | [substring](../substring) | [length](../length) | [replace](../replace) | [split](../split) diff --git a/src/handbook/tags.md b/handbook/tags.md similarity index 100% rename from src/handbook/tags.md rename to handbook/tags.md diff --git a/handbook/tags/index.html b/handbook/tags/index.html deleted file mode 100644 index 2e52054..0000000 --- a/handbook/tags/index.html +++ /dev/null @@ -1,463 +0,0 @@ - - - - - - - - - - - - Tags - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

Tag Selector

- -

The tag selector is a shortcut for the tag attribute on records

- -

Syntax

-
#tag
-
-#"tag with spaces"
-
- -

Description

- -

The tag selector # is a shortcut for the tag attribute, e.g. [#person] is a shortcut for [tag: "person"].

- -

The tag selector is useful for selecting a group of similar records.

- -

Tags are useful for making a record unique. For instance, in a single database, many disparate records might have an age attribute. e.g. [age] might select unrelated records if you’re only interested in ages of employees. A more specific record would be [#employee age], which would match only records that are both tagged “employee” and have an age attribute.

- -

Multiple tags can be used to further specify a record. For instance:

-
[#employee wage]
-[#employee #part-time wage]
-
- -

The first record matches all #employees, while the second matches only those who are also #part-time. Any number of tags can be used in this way.

- -

Tips

- -

Tags are useful for creating switches. Add a tag to a record to include it in a set. Then, when you don’t want that record in the set anymore, just remove the tag. The record will no longer match the set.

- -

Examples

- -

Search for students and display their names and the grade they’re in.

-
search
-  [#student name grade]
-
-bind @browser
-  [#div text: "{{name}} is in {{grade}}th grade."]
-
- -

Add students with good marks to the honor roll. When a student’s GPA falls below 3.5, he or she will not make the honor roll because this block will not add the #honor-roll tag.

-
search
-  students = [#student gpa >= 3.5]
-
-bind
-  students += #honor-roll
-
- -

Display the honor roll

-
search
-  [#student #honor-roll name]
-
-bind @browser
-  [#div text: "{{name}} is a smarty pants"]
-
- -

See Also

- -

records | search | sets

- - -
-
- -
- diff --git a/src/handbook/update-operators.md b/handbook/update-operators.md similarity index 100% rename from src/handbook/update-operators.md rename to handbook/update-operators.md diff --git a/handbook/update-operators/index.html b/handbook/update-operators/index.html deleted file mode 100644 index 89ee415..0000000 --- a/handbook/update-operators/index.html +++ /dev/null @@ -1,430 +0,0 @@ - - - - - - - - - - - - Update Operators - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

Update Operators

- -

Update operates are used to modify records

- -

Syntax

-
// Add operator
-record.attribute += value
-
-// Remove operator
-record.attribute -= value
-
-// Set operator
-record.attribute := value
-
-// Merge operator
-record <- [ ... ]
-
- -

Description

- -

Examples

- -

See Also

- -

add | remove | set | merge | bind | commit

- - -
-
- -
- diff --git a/handbook/view/index.md b/handbook/view/index.md new file mode 100644 index 0000000..27cb468 --- /dev/null +++ b/handbook/view/index.md @@ -0,0 +1,10 @@ +--- +menu: + main: + parent: "Databases" +title: "@view" +weight: 5 +--- + +# @view + diff --git a/src/handbook/windows.md b/handbook/windows.md similarity index 69% rename from src/handbook/windows.md rename to handbook/windows.md index 4fd40d9..785f902 100644 --- a/src/handbook/windows.md +++ b/handbook/windows.md @@ -7,7 +7,7 @@ title: "Windows" # Installing Eve on Windows -First, [download](https://github.com/witheve/Eve/archive/master.zip) the Eve source. You'll need a recent [node.js](https://nodejs.org) and then and then in the extracted Eve directory: +First, [download](https://github.com/witheve/Eve/archive/master.zip) the Eve source. You'll need a recent [node.js](https://nodejs.org) and then in the extracted Eve directory: ``` npm install @@ -18,4 +18,4 @@ Then open `http://localhost:8080/` in your browser. ## See also -[linux](../linux) | [mac](../mac) | | [running](../running) \ No newline at end of file +[linux](../linux) | [mac](../mac) | [docker](../docker) | [npm](../npm) | [running](../running) \ No newline at end of file diff --git a/handbook/windows/index.html b/handbook/windows/index.html deleted file mode 100644 index 62c6392..0000000 --- a/handbook/windows/index.html +++ /dev/null @@ -1,418 +0,0 @@ - - - - - - - - - - - - Windows - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

Installing Eve on Windows

- -

First, download the Eve source. You’ll need a recent node.js and then and then in the extracted Eve directory:

- -
npm install
-npm start
-
- -

Then open http://localhost:8080/ in your browser.

- -

See also

- -

linux | mac | | running

- - -
-
- -
- diff --git a/images/favicon.png b/images/favicon.png deleted file mode 100644 index 9954640..0000000 Binary files a/images/favicon.png and /dev/null differ diff --git a/images/logo_only.png b/images/logo_only.png deleted file mode 100644 index 75f9e62..0000000 Binary files a/images/logo_only.png and /dev/null differ diff --git a/index.html b/index.html deleted file mode 100644 index 53fba4a..0000000 --- a/index.html +++ /dev/null @@ -1,418 +0,0 @@ - - - - - - - - - - - - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
- -
-
- -
- - -
\ No newline at end of file diff --git a/src/index.md b/index.md similarity index 100% rename from src/index.md rename to index.md diff --git a/index.xml b/index.xml deleted file mode 100644 index 9acd5db..0000000 --- a/index.xml +++ /dev/null @@ -1,583 +0,0 @@ - - - - Eve Documentation - https://witheve.github.io/docs/ - Recent content on Eve Documentation - Hugo -- gohugo.io - en-us - - - - - https://witheve.github.io/docs/handbook/core/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://witheve.github.io/docs/handbook/core/ - - -<h1 id="core-language">Core Language</h1> - -<h2 id="see-also">See Also</h2> - -<p><a href="../records">records</a> | <a href="../equivalence">equivalence</a> | <a href="../actions">actions</a> | <a href="../expressions">expressions</a> | <a href="../update-operators">update operators</a> | <a href="../databases">databases</a></p> - - - - - - https://witheve.github.io/docs/handbook/intro/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://witheve.github.io/docs/handbook/intro/ - - -<h1 id="introduction">Introduction</h1> - -<h2 id="notable-features">Notable Features</h2> - -<ul> -<li><p>Eve programs aren&rsquo;t talking to a database, they <em>are</em> the database. That means no plumbing, no impedance mismatch, and no extra infrastructure is needed.</p></li> - -<li><p>Everything is data. The file system, http requests, the DOM&hellip; That means everything can be queried and everything can be reacted to.</p></li> - -<li><p>Eve&rsquo;s semantics were built for concurrency, asynchrony, and distribution. There are no promises, or thread synchronizations, or borrows.</p></li> - -<li><p>Eve programs practice literate programming, since there&rsquo;s no incidental ordering imposed by the language.</p></li> - -<li><p>Another result of a lack of ordering is that programs grow very organically through composition.</p></li> - -<li><p>Eve programs are naturally tiny.</p></li> - -<li><p>Correctness can be defined globally through integrity constraints, allowing people to safely contribute to an application without worrying about checking every possible invariant locally.</p></li> -</ul> - -<h2 id="see-also">See Also</h2> - -<p><a href="../installation">getting eve</a> | <a href="../running">running eve</a> | <a href="../programs">eve programs</a> | <a href="../core-language">core language</a></p> - - - - - - https://witheve.github.io/docs/handbook/programs/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://witheve.github.io/docs/handbook/programs/ - - -<h1 id="eve-programs">Eve Programs</h1> - -<p>Coming soon&hellip;</p> - -<h2 id="see-also">See Also</h2> - -<p><a href="../model">programming model</a> | <a href="../literate-programming">literate programming</a> | <a href="../blocks">blocks</a></p> - - - - - - https://witheve.github.io/docs/handbook/standard-library/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://witheve.github.io/docs/handbook/standard-library/ - - -<h1 id="standard-library">Standard Library</h1> - -<h2 id="description">Description</h2> - -<ul> -<li><a href="../math">math</a> - General mathematical and trigonometric functions</li> -<li><a href="../strings">strings</a> - Functions that manipulate strings</li> -<li><a href="../statistics">statistics</a> - Functions that calculate statistical measures on values</li> -<li><a href="../datetime">date &amp; time</a> - Functions that get and manipulate date and time</li> -</ul> - - - - - Date & Time - https://witheve.github.io/docs/handbook/datetime/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://witheve.github.io/docs/handbook/datetime/ - - -<h1 id="date-time">Date &amp; Time</h1> - -<ul> -<li><a href="time.md">time</a> - The current system time</li> -</ul> - - - - - Eve Documentation - https://witheve.github.io/docs/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://witheve.github.io/docs/ - - -<h1 id="eve-programming-language-documentation">Eve Programming Language Documentation</h1> - -<h2 id="guides">Guides</h2> - -<ul> -<li><a href="http://play.witheve.com">Eve Quickstart Guide</a></li> -</ul> - - - - - Eve for Programmers - https://witheve.github.io/docs/guides/for-programmers/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://witheve.github.io/docs/guides/for-programmers/ - - -<h1 id="eve-for-programmers">Eve for Programmers</h1> - -<p>As a programmer, you probably find it easy to switch between different programming langauges. If you know Javascript, you probably wouldn&rsquo;t have a hard time learning similar langauges like C++, Java, or Python. That&rsquo;s because despite syntactic differences, these languages largely conform to the same programming model. When we program in languages like these, we use similar abstractions between them &ndash; loops, functions, and input/output patterns have become a staple of every programmer&rsquo;s toolbox. When we solve problems, we usually reach a solution in terms of these primitive operations.</p> - -<p>Eve is a different kind of programming langauge from Javascript or Python, so programmers new to Eve may feel a little lost at first. How do you get anything done in a language without loops? How do you compose code without functions? The purpose of this guide is to provide a mapping from the common tools you know, to the Eve way of solving problems. We&rsquo;ll look at some programs written in Javascript, and see how they Eve can solve them.</p> - -<h2 id="functions">Functions</h2> - -<p>Functions are the fundamental unit of code reuse in most conventional programming languages. These langauges typically start from a &ldquo;main&rdquo; function, and branch</p> - -<h2 id="looping">Looping</h2> - -<h3 id="map">Map</h3> - -<h3 id="reduce">Reduce</h3> - -<h3 id="recursion">Recursion</h3> - -<h2 id="i-o">I/O</h2> - - - - - Events - https://witheve.github.io/docs/handbook/events/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://witheve.github.io/docs/handbook/events/ - - -<h1 id="events">Events</h1> - -<p><a href="click">click</a> - a left-button mouse click event</p> - - - - - General - https://witheve.github.io/docs/handbook/general/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://witheve.github.io/docs/handbook/general/ - - -<h1 id="general">General</h1> - -<ul> -<li><a href="sort">sort</a> - Orders elements in a set</li> -</ul> - - - - - Linux - https://witheve.github.io/docs/handbook/linux/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://witheve.github.io/docs/handbook/linux/ - - -<h1 id="installing-eve-on-linux">Installing Eve on Linux</h1> - -<p>First, <a href="https://github.com/witheve/Eve/archive/master.zip">download</a> the Eve source. You&rsquo;ll need a recent <a href="https://nodejs.org">node.js</a> and then and then in the extracted Eve directory:</p> - -<pre><code>npm install -npm start -</code></pre> - -<p>Then open <code>http://localhost:8080/</code> in your browser.</p> - -<h2 id="see-also">See also</h2> - -<p><a href="../mac">mac</a> | <a href="../windows">windows</a> | <a href="../running">running</a></p> - - - - - Mac - https://witheve.github.io/docs/handbook/mac/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://witheve.github.io/docs/handbook/mac/ - - -<h1 id="installing-eve-on-mac">Installing Eve on Mac</h1> - -<p>First, <a href="https://github.com/witheve/Eve/archive/master.zip">download</a> the Eve source. You&rsquo;ll need a recent <a href="https://nodejs.org">node.js</a> and then and then in the extracted Eve directory:</p> - -<pre><code>npm install -npm start -</code></pre> - -<p>Then open <code>http://localhost:8080/</code> in your browser.</p> - -<h2 id="see-also">See also</h2> - -<p><a href="../linux">linux</a> | <a href="../windows">windows</a> | <a href="../running">running</a></p> - - - - - Math - https://witheve.github.io/docs/handbook/math/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://witheve.github.io/docs/handbook/math/ - - -<h1 id="math">Math</h1> - -<h2 id="arithemtic">Arithemtic</h2> - -<ul> -<li>plus ( <code>+</code> ) - Add two numbers</li> -<li>minus ( <code>-</code> ) - Subtract two numbers</li> -<li>times ( <code>*</code> ) - Multiply two numbers</li> -<li>divide ( <code>/</code> ) - Divide two numbers</li> -</ul> - -<h2 id="general-math">General Math</h2> - -<ul> -<li><a href="abs">abs</a> - Absolute value</li> -<li><a href="ceil">ceil</a> - Round a number up</li> -<li><a href="floor">floor</a> - Round a number down</li> -<li><a href="round">round</a> - Round a number</li> -<li><a href="mod">mod</a> - Modulo division</li> -<li>exp - The number <code>e</code> raised to a power</li> -<li>log - Calculate the logarithm of a number</li> -</ul> - -<h2 id="trigonometric-functions">Trigonometric Functions</h2> - -<ul> -<li><a href="sin">sin</a> - Sine of an angle</li> -<li><a href="cos">cos</a> - Cosine of an angle</li> -<li><a href="tan">tan</a> - Tangent of an angle</li> -<li>asin - Arc sine of an angle</li> -<li>acos - Arc cosine of an angle</li> -<li>atan - Arc tangent of an angle</li> -<li>atan2 - Arc tangent using sign to determine quadrant</li> -</ul> - -<h2 id="hyperbolic-functions">Hyperbolic Functions</h2> - -<ul> -<li>sinh - Hyperbolic sine of an angle</li> -<li>cosh - Hyperbolic cosine of an angle</li> -<li>tanh - Hyperbolic tangent of an angle</li> -<li>asinh - Hyperbolic arc sine of an angle</li> -<li>acosh - Hyperbolic arc cosine of an angle</li> -<li>atanh - Hyperbolic arc tangent of an angle</li> -</ul> - -<h2 id="other-functions">Other Functions</h2> - -<ul> -<li><a href="range">range</a> - Generates a range of numbers</li> -</ul> - - - - - Quickstart - https://witheve.github.io/docs/tutorials/quickstart/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://witheve.github.io/docs/tutorials/quickstart/ - - -<h1 id="eve-quick-start-tutorial">Eve Quick Start Tutorial</h1> -<div class="highlight"><pre><code class="language-eve" data-lang="eve"><span></span><span class="x">```</span><span class="w"></span> -<span class="kr">bind</span><span class="w"> </span><span class="nt">@browser</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="p">[</span><span class="x">tag</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;div&quot;</span><span class="p">,</span><span class="w"> </span><span class="x">text</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;Hello, world&quot;</span><span class="p">]</span><span class="w"></span> -<span class="x">```</span><span class="w"></span> -</code></pre></div> - -<p>Hello world! At its core, Eve is a pattern matching language. You match patterns of data by searching a database, then update or create new data according to what you&rsquo;ve found. In this example, we created a <a href="https://witheve.github.io/docs/handbook/records/"><code>record</code></a> that has two attributes: a tag attribute with the value <code>&quot;div&quot;</code>, and a text attribute with the value <code>&quot;Hello, world&quot;</code>. We <a href="https://witheve.github.io/docs/handbook/bind/">bound</a> this record to the browser, which is how we displayed our venerable message.</p> - -<p>The three backticks <code>```</code> are called a code fence, and they allow us to denote blocks of code. This gives us the ability to embed Eve code in normal documents written in Markdown. This is how Eve programs are written: everything in a code fence is a <a href="https://witheve.github.io/docs/handbook/blocks/">block</a> of Eve code, while everything outside is prose describing the program. In fact, this quick start tutorial is an example of an executable Eve program! In the subsequent blocks, you won&rsquo;t see any code fences, but they still exist in the <a href="https://raw.githubusercontent.com/witheve/docs/src/guides/quickstart.md">document&rsquo;s source</a>.</p> - -<p>So far we&rsquo;ve created a record that displays “Hello, world!” but as I said, Eve is a pattern matching language. Let&rsquo;s explore that by searching for something:</p> -<div class="highlight"><pre><code class="language-eve" data-lang="eve"><span></span><span class="kr">search</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="p">[</span><span class="x">name</span><span class="p">]</span><span class="w"></span> - -<span class="kr">bind</span><span class="w"> </span><span class="nt">@browser</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="p">[</span><span class="x">tag</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;div&quot;</span><span class="p">,</span><span class="w"> </span><span class="x">text</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;Hello, world&quot;</span><span class="p">]</span><span class="w"></span> -</code></pre></div> - -<p>Our message disappeared! Before, we bound without searching, so the message displayed by default. Now we&rsquo;re binding in the presence of a <a href="https://witheve.github.io/docs/handbook/search/"><code>search</code></a> action, so the bound record only exists if all the searched records are matched. Here, we&rsquo;re searching for all records with a <code>name</code> attribute, but we haven&rsquo;t added any records like that to Eve so none are matched. With no matching records, the <code>bind</code> cannot execute, and the message disappears from the screen.</p> - -<p>This is the flow of an Eve block: you search for records in a database, and if all the records you searched for are matched, you can modify the matched records or create new ones. If any part of your search is not matched, then no records will be created or updated.</p> - -<p>To get our message back, all we need is a record with a name attribute. We can create one permanently with the <a href="https://witheve.github.io/docs/handbook/commit/"><code>commit</code></a> action:</p> -<div class="highlight"><pre><code class="language-eve" data-lang="eve"><span></span><span class="kr">commit</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="p">[</span><span class="x">name</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;Celia&quot;</span><span class="p">]</span><span class="w"></span> -</code></pre></div> - -<p>Hello, world… again! Commit permanently updates or creates a record that will persist even if its matched records (the records matched in a search action) change. Since we aren&rsquo;t searching for anything in this block, the commit executes by default and adds a record with a name attribute of <code>&quot;Celia&quot;</code>. The addition of this new record satisfies the search in the previous block, so “Hello, world!” appears on the screen again.</p> - -<p>But what else can you do with matched records? For starters, we can use them to create new records:</p> -<div class="highlight"><pre><code class="language-eve" data-lang="eve"><span></span><span class="kr">search</span><span class="w"></span> -<span class="w"> </span><span class="p">[</span><span class="x">name</span><span class="p">]</span><span class="w"></span> - -<span class="kr">bind</span><span class="w"> </span><span class="nt">@browser</span><span class="w"></span> -<span class="w"> </span><span class="p">[</span><span class="nt">#div</span><span class="p">,</span><span class="w"> </span><span class="x">text</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;Hello, {{name}}&quot;</span><span class="p">]</span><span class="w"></span> -</code></pre></div> - -<p>Since we matched on a record with a name attribute, we now have a reference to that name, and we can inject it into a string using <a href="https://witheve.github.io/docs/handbook/string-interpolation/"><code>{{ ... }}</code></a> embedding. We can also swap out <code>tag: &quot;div&quot;</code> for the sugared <code>#div</code>. <a href="https://witheve.github.io/docs/handbook/tags/">Tags</a> are used a lot in Eve to talk about collections of related records. For example, we could search for all records with a <code>#student</code> tag, with name, grade, and school attributes.</p> -<div class="highlight"><pre><code class="language-eve" data-lang="eve"><span></span><span class="kr">search</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="p">[</span><span class="nt">#student</span><span class="w"> </span><span class="x">name</span><span class="w"> </span><span class="x">grade</span><span class="w"> </span><span class="x">school</span><span class="p">]</span><span class="w"></span> - -<span class="kr">bind</span><span class="w"> </span><span class="nt">@browser</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="p">[</span><span class="nt">#div</span><span class="w"> </span><span class="x">text</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;{{name}} is a {{grade}}th grade student at {{school}}.&quot;</span><span class="p">]</span><span class="w"></span> -</code></pre></div> - -<p>Since we&rsquo;re matching on more attributes, this block is no longer satisfied by the record we added earlier; we&rsquo;re missing a <code>#student</code> tag, as well as grade and school attributes. Even though these are currently missing, we can still write the code that would display them.</p> - -<p>Let&rsquo;s display this new message by adding the missing attributes to Celia. We could add them to the block where we comitted Celia originally, but we can also do it programatically:</p> -<div class="highlight"><pre><code class="language-eve" data-lang="eve"><span></span><span class="kr">search</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="x">celia</span><span class="w"> </span><span class="nf">=</span><span class="w"> </span><span class="p">[</span><span class="x">name</span><span class="nf">:</span><span class="w"> </span><span class="x">“Celia”</span><span class="p">]</span><span class="w"></span> - -<span class="kr">bind</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="x">celia</span><span class="w"> </span><span class="nf">&lt;-</span><span class="w"> </span><span class="p">[</span><span class="nt">#student</span><span class="w"> </span><span class="x">grade</span><span class="nf">:</span><span class="w"> </span><span class="m">10</span><span class="p">,</span><span class="w"> </span><span class="x">school</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;East&quot;</span><span class="p">,</span><span class="w"> </span><span class="x">age</span><span class="nf">:</span><span class="w"> </span><span class="m">16</span><span class="p">]</span><span class="w"></span> -</code></pre></div> - -<p>You can define variables within blocks, which act as handles on records that allow you to change them. In this case, we&rsquo;re using the <a href="https://witheve.github.io/docs/handbook/merge/">merge operator</a> <code>&lt;-</code> to combine two records. With the addition of this block, the sentence &ldquo;Celia is a 10th grade student at East.&rdquo; appears in the browser.</p> - -<p>Celia is cool and all, but let&rsquo;s add some more students to our database:</p> -<div class="highlight"><pre><code class="language-eve" data-lang="eve"><span></span><span class="kr">commit</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="p">[</span><span class="nt">#student</span><span class="w"> </span><span class="x">name</span><span class="nf">:</span><span class="w"> </span><span class="x">“Diedra”</span><span class="p">,</span><span class="w"> </span><span class="x">grade</span><span class="nf">:</span><span class="w"> </span><span class="m">12</span><span class="p">,</span><span class="w"> </span><span class="x">school</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;West&quot;</span><span class="p">]</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="p">[</span><span class="nt">#student</span><span class="w"> </span><span class="x">name</span><span class="nf">:</span><span class="w"> </span><span class="x">“Michelle”</span><span class="p">,</span><span class="w"> </span><span class="x">grade</span><span class="nf">:</span><span class="w"> </span><span class="m">11</span><span class="p">,</span><span class="w"> </span><span class="x">school</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;West&quot;</span><span class="p">]</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="p">[</span><span class="nt">#student</span><span class="w"> </span><span class="x">name</span><span class="nf">:</span><span class="w"> </span><span class="x">“Jermaine”</span><span class="p">,</span><span class="w"> </span><span class="x">grade</span><span class="nf">:</span><span class="w"> </span><span class="m">9</span><span class="p">]</span><span class="w"></span> -</code></pre></div> - -<p>Three sentences are now printed, one for each student that matches the search. Eve works on <a href="https://witheve.github.io/docs/handbook/sets/">sets</a>, so when we search for <code>[#student name grade school]</code>, we find <em>all</em> records that match the given pattern. This includes Celia, Diedra and Michelle (but not Jermaine, as he has no school in his record). Therefore, when we bind the record <code>[#div text: &quot;{{name}} is a ... &quot;]</code>, we are actually binding three records, one for each matching <code>#student</code>.</p> - -<p>If you re-compile the program a couple times, you&rsquo;ll see the order of sentences may change. This is because <strong>there is no ordering in Eve - blocks are not ordered, statements are not ordered, and results are not ordered</strong>. If you want to order elements, you must impose an ordering yourself. We can ask the browser to draw elements in an order with the &ldquo;sort&rdquo; attribute:</p> -<div class="highlight"><pre><code class="language-eve" data-lang="eve"><span></span><span class="kr">search</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="p">[</span><span class="nt">#student</span><span class="w"> </span><span class="x">name</span><span class="w"> </span><span class="x">grade</span><span class="w"> </span><span class="x">school</span><span class="p">]</span><span class="w"></span> - -<span class="kr">bind</span><span class="w"> </span><span class="nt">@browser</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="p">[</span><span class="nt">#div</span><span class="w"> </span><span class="x">sort</span><span class="nf">:</span><span class="w"> </span><span class="x">name</span><span class="p">,</span><span class="w"> </span><span class="x">text</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;{{name}} is a {{grade}}th grade student at {{school}}.&quot;</span><span class="p">]</span><span class="w"></span> -</code></pre></div> - -<p>This time when you recompile your program, the order will stay fixed, sorted alphabetically by name.</p> - -<p>Let&rsquo;s make things a little more interesting by adding some records about the schools the students attend:</p> -<div class="highlight"><pre><code class="language-eve" data-lang="eve"><span></span><span class="kr">commit</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="p">[</span><span class="nt">#school</span><span class="w"> </span><span class="x">name</span><span class="nf">:</span><span class="w"> </span><span class="x">“West”</span><span class="p">,</span><span class="w"> </span><span class="x">address</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;1234 Main Street&quot;</span><span class="p">]</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="p">[</span><span class="nt">#school</span><span class="w"> </span><span class="x">name</span><span class="nf">:</span><span class="w"> </span><span class="x">“East”</span><span class="p">,</span><span class="w"> </span><span class="x">address</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;5678 Broad Street&quot;</span><span class="p">]</span><span class="w"></span> -</code></pre></div> - -<p>What if we want to display the address of the school each student attends? Although <code>#student</code>s and <code>#school</code>s are in different records, <strong>we can relate two records by associating attributes from one record with attributes from the other.</strong> This is an operation known as <a href="https://witheve.github.io/docs/handbook/joins/">joining</a>. In this case, we want to relate the <code>name</code> attribute on <code>#schools</code> with the <code>school</code> attribute on <code>#students</code>. This compares the values of the attributes between records, and matches up those with the same value. For instance, since Celia&rsquo;s school is &ldquo;East&rdquo;, she can join with the <code>#school</code> named &ldquo;East&rdquo;.</p> - -<p>Our first attempt may come out looking a little something like this:</p> -<div class="highlight"><pre><code class="language-eve" data-lang="eve"><span></span><span class="kr">search</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="x">school</span><span class="w"> </span><span class="nf">=</span><span class="w"> </span><span class="p">[</span><span class="nt">#school</span><span class="w"> </span><span class="x">name</span><span class="w"> </span><span class="x">address</span><span class="p">]</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="x">student</span><span class="w"> </span><span class="nf">=</span><span class="w"> </span><span class="p">[</span><span class="nt">#student</span><span class="w"> </span><span class="x">name</span><span class="w"> </span><span class="x">school</span><span class="nf">:</span><span class="w"> </span><span class="x">name</span><span class="p">]</span><span class="w"> </span> - -<span class="kr">bind</span><span class="w"> </span><span class="nt">@browser</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="p">[</span><span class="nt">#div</span><span class="w"> </span><span class="x">text</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;{{student.name}} attends {{school.name}} at {{address}}&quot;</span><span class="p">]</span><span class="w"></span> -</code></pre></div> - -<p>But that didn&rsquo;t work. How come? In Eve, <strong>things with the same name are <a href="https://witheve.github.io/docs/handbook/equivalence/">equivalent</a></strong>. In this block, we&rsquo;ve used &ldquo;name&rdquo; three times, which says that the school&rsquo;s name, the student&rsquo;s name, and the student&rsquo;s school are all the same. Of course, there is no combination of students and schools that match this search, so nothing is displayed.</p> - -<p>Instead, we can use the dot operator to specifically ask for the name attribute in the <code>#school</code> records, and rename our variables to get a correct block:</p> -<div class="highlight"><pre><code class="language-eve" data-lang="eve"><span></span><span class="kr">search</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="x">schools</span><span class="w"> </span><span class="nf">=</span><span class="w"> </span><span class="p">[</span><span class="nt">#school</span><span class="w"> </span><span class="x">address</span><span class="p">]</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="x">students</span><span class="w"> </span><span class="nf">=</span><span class="w"> </span><span class="p">[</span><span class="nt">#student</span><span class="w"> </span><span class="x">school</span><span class="nf">:</span><span class="w"> </span><span class="x">school.name</span><span class="p">]</span><span class="w"></span> - -<span class="kr">bind</span><span class="w"> </span><span class="nt">@browser</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="p">[</span><span class="nt">#div</span><span class="w"> </span><span class="x">text</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;{{students.name}} attends {{schools.name}} at {{address}}&quot;</span><span class="p">]</span><span class="w"></span> -</code></pre></div> - -<p>This creates an implicit join over the school name without mixing up the names of the students and the names of the schools, giving us our desired output. You can actually bind attributes to any name you want to avoid collisions in a block:</p> -<div class="highlight"><pre><code class="language-eve" data-lang="eve"><span></span><span class="kr">search</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="p">[</span><span class="nt">#school</span><span class="w"> </span><span class="x">name</span><span class="nf">:</span><span class="w"> </span><span class="x">school</span><span class="nf">-</span><span class="x">name</span><span class="w"> </span><span class="x">address</span><span class="p">]</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="p">[</span><span class="nt">#student</span><span class="w"> </span><span class="x">name</span><span class="nf">:</span><span class="w"> </span><span class="x">student</span><span class="nf">-</span><span class="x">name</span><span class="w"> </span><span class="x">school</span><span class="nf">:</span><span class="w"> </span><span class="x">school</span><span class="nf">-</span><span class="x">name</span><span class="p">]</span><span class="w"></span> - -<span class="kr">bind</span><span class="w"> </span><span class="nt">@browser</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="p">[</span><span class="nt">#div</span><span class="w"> </span><span class="x">text</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;{{student-name}} attends {{school-name}} at {{address}}&quot;</span><span class="p">]</span><span class="w"></span> -</code></pre></div> - -<h2 id="advanced-eve">Advanced Eve</h2> - -<p>Recall when we added our students, Celia was the only one we added an <code>age</code> to. Therefore, the following block only displays Celia&rsquo;s age, even though we ask for all the <code>#student</code>s:</p> -<div class="highlight"><pre><code class="language-eve" data-lang="eve"><span></span><span class="kr">search</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="p">[</span><span class="nt">#student</span><span class="w"> </span><span class="x">name</span><span class="w"> </span><span class="x">age</span><span class="p">]</span><span class="w"></span> - -<span class="kr">bind</span><span class="w"> </span><span class="nt">@browser</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="p">[</span><span class="nt">#div</span><span class="w"> </span><span class="x">text</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;{{name}} is {{age}} years old&quot;</span><span class="p">]</span><span class="w"></span> -</code></pre></div> - -<p>Let&rsquo;s pretend that all students enter first grade at six years old. Therefore, if we know a student&rsquo;s grade, we can calculate their age and add it to the student&rsquo;s record:</p> -<div class="highlight"><pre><code class="language-eve" data-lang="eve"><span></span><span class="kr">search</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="x">student</span><span class="w"> </span><span class="nf">=</span><span class="w"> </span><span class="p">[</span><span class="nt">#student</span><span class="p">]</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="x">calculated</span><span class="nf">-</span><span class="x">age</span><span class="w"> </span><span class="nf">=</span><span class="w"> </span><span class="kr">if</span><span class="w"> </span><span class="x">student.age</span><span class="w"> </span><span class="kr">then</span><span class="w"> </span><span class="x">student.age</span><span class="w"></span> -<span class="x">                  </span><span class="w"> </span><span class="kr">else</span><span class="w"> </span><span class="kr">if</span><span class="w"> </span><span class="x">student.grade</span><span class="w"> </span><span class="kr">then</span><span class="w"> </span><span class="x">student.grade</span><span class="w"> </span><span class="nf">+</span><span class="w"> </span><span class="m">5</span><span class="w"></span> - -<span class="kr">bind</span><span class="w"> </span><span class="nt">@browser</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="x">student.age</span><span class="w"> </span><span class="nf">:=</span><span class="w"> </span><span class="x">calculated</span><span class="nf">-</span><span class="x">age</span><span class="w"></span> -</code></pre></div> - -<p>This block selects all students, and uses and <a href="https://witheve.github.io/docs/handbook/if-then/"><code>if-then</code></a> expression to set the student&rsquo;s calculated age. If the student already has an age, we set it to that. Otherwise, if the student has no age, we can calculate it with some arithmetic. The <a href="https://witheve.github.io/docs/handbook/set/">set operator</a> <code>:=</code> sets an attribute to a specified value regardless of what it was before the block executed. That value can be anything, from a number to a string to another record.</p> - -<h3 id="aggregates">Aggregates</h3> - -<p>So far everything we&rsquo;ve done has used one record at a time, but what happens when we want to work over a group of records, such as counting how many students there are? To solve such a problem, we&rsquo;ll need to use an <a href="https://witheve.github.io/docs/handbook/aggregates/">aggregate</a>. Aggregates take a set of values and turn them into a single value, akin to &ldquo;fold&rdquo; or &ldquo;reduce&rdquo; functions in other languages. In this case, we&rsquo;ll use the aggregate <a href="https://witheve.github.io/docs/handbook/statistics/count/"><code>count</code></a> to figure out how many <code>#students</code> are in the school district:  </p> -<div class="highlight"><pre><code class="language-eve" data-lang="eve"><span></span><span class="kr">search</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="x">students</span><span class="w"> </span><span class="nf">=</span><span class="w"> </span><span class="p">[</span><span class="nt">#student</span><span class="p">]</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="x">total</span><span class="nf">-</span><span class="x">students</span><span class="w"> </span><span class="nf">=</span><span class="w"> </span><span class="x">count</span><span class="p">[</span><span class="x">given</span><span class="nf">:</span><span class="w"> </span><span class="x">students</span><span class="p">]</span><span class="w"></span> - -<span class="kr">bind</span><span class="w"> </span> -<span class="x"> </span><span class="w"> </span><span class="p">[</span><span class="nt">#div</span><span class="w"> </span><span class="x">text</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;{{total-students}} are in the school district&quot;</span><span class="p">]</span><span class="w"></span> -</code></pre></div> - -<p>A quick note on the syntax for <code>count</code> - it feels a lot like a function in other languages, since it has a return value and can be used inline in expressions. Under the hood, <a href="https://witheve.github.io/docs/handbook/functions/">functions</a> and aggregates are actually records; <code>total = count[given: students]</code> is shorthand for <code>[#count #function given: students, value: total]</code>. This distinction won&rsquo;t materially change the way you use <code>count</code>, but it goes to show that everything in Eve reduces to working with records.</p> - -<p>While <code>given</code> is a required argument in <code>count</code>, aggregates (and functions in general) can also have optional arguments. Let&rsquo;s say we want to know how many students attend each school. We can use the optional argument <code>per</code> to count students grouped by the school they attend:</p> -<div class="highlight"><pre><code class="language-eve" data-lang="eve"><span></span><span class="kr">search</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="x">students</span><span class="w"> </span><span class="nf">=</span><span class="w"> </span><span class="p">[</span><span class="nt">#student</span><span class="w"> </span><span class="x">school</span><span class="p">]</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="x">students</span><span class="nf">-</span><span class="x">per</span><span class="nf">-</span><span class="x">school</span><span class="w"> </span><span class="nf">=</span><span class="w"> </span><span class="x">count</span><span class="p">[</span><span class="x">given</span><span class="nf">:</span><span class="w"> </span><span class="x">students</span><span class="p">,</span><span class="w"> </span><span class="x">per</span><span class="nf">:</span><span class="w"> </span><span class="x">school</span><span class="p">]</span><span class="w"></span> - -<span class="kr">bind</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="p">[</span><span class="nt">#div</span><span class="w"> </span><span class="x">text</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;{{students-per-school}} attend {{school}}&quot;</span><span class="p">]</span><span class="w"></span> -</code></pre></div> - -<p>All function-like records in Eve specify their arguments as attributes. This means you specify the argument and its value, unlike in other languages, where the order of the values determines the attribute to which they belong. As with everything else in Eve, order doesn&rsquo;t matter.</p> - -<h2 id="extra-credit">Extra Credit</h2> - -<p>At this point, you know everything necessary about Eve to complete this extra credit portion (the only additional knowledge you need is domain knowledge of HTML and forms). Let&rsquo;s review some of the key concepts:</p> - -<ul> -<li>Eve programs are composed of blocks of code that search for and update records.</li> -<li>Records are sets of <code>attribute: value</code> pairs attached to a unique ID.</li> -<li>Eve works with sets, which have no ordering and contain unique elements.</li> -<li>Things with the same name are equivalent.</li> -</ul> - -<p>Your extra credit task is to build a web-based form that allows you to add students to the database. Take a moment to think about how this might be done in Eve, given everything we&rsquo;ve learned so far.</p> - -<p>First, let&rsquo;s make the form. We&rsquo;ve already displayed a <code>#div</code>, and in the same way we can draw <code>#input</code>s and a <code>#button</code>:</p> -<div class="highlight"><pre><code class="language-eve" data-lang="eve"><span></span><span class="kr">bind</span><span class="w"> </span><span class="nt">@browser</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="p">[</span><span class="nt">#div</span><span class="w"> </span><span class="x">children</span><span class="nf">:</span><span class="w"> </span> -<span class="x">   </span><span class="w"> </span><span class="p">[</span><span class="nt">#div</span><span class="w"> </span><span class="x">sort</span><span class="nf">:</span><span class="w"> </span><span class="m">1</span><span class="p">,</span><span class="w"> </span><span class="x">text</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;Name:&quot;</span><span class="p">]</span><span class="w"></span> -<span class="x">   </span><span class="w"> </span><span class="p">[</span><span class="nt">#input</span><span class="w"> </span><span class="nt">#name-input</span><span class="w"> </span><span class="x">sort</span><span class="nf">:</span><span class="w"> </span><span class="m">2</span><span class="p">]</span><span class="w"></span> -<span class="x">   </span><span class="w"> </span><span class="p">[</span><span class="nt">#div</span><span class="w"> </span><span class="x">sort</span><span class="nf">:</span><span class="w"> </span><span class="m">3</span><span class="p">,</span><span class="w"> </span><span class="x">text</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;Grade:&quot;</span><span class="p">]</span><span class="w"></span> -<span class="x">   </span><span class="w"> </span><span class="p">[</span><span class="nt">#input</span><span class="w"> </span><span class="nt">#grade-input</span><span class="w"> </span><span class="x">sort</span><span class="nf">:</span><span class="w"> </span><span class="m">4</span><span class="p">]</span><span class="w"></span> -<span class="x">   </span><span class="w"> </span><span class="p">[</span><span class="nt">#div</span><span class="w"> </span><span class="x">sort</span><span class="nf">:</span><span class="w"> </span><span class="m">5</span><span class="p">,</span><span class="w"> </span><span class="x">text</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;School:&quot;</span><span class="p">]</span><span class="w"></span> -<span class="x">   </span><span class="w"> </span><span class="p">[</span><span class="nt">#input</span><span class="w"> </span><span class="nt">#school-input</span><span class="w"> </span><span class="x">sort</span><span class="nf">:</span><span class="w"> </span><span class="m">6</span><span class="p">]</span><span class="w"></span> -<span class="x">   </span><span class="w"> </span><span class="p">[</span><span class="nt">#button</span><span class="w"> </span><span class="nt">#submit</span><span class="w"> </span><span class="x">sort</span><span class="nf">:</span><span class="w"> </span><span class="m">7</span><span class="w"> </span><span class="x">text</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;submit&quot;</span><span class="p">]]</span><span class="w"></span> -</code></pre></div> - -<p>We&rsquo;ve added some tags to the inputs and the button to distinguish them, so we can easily search for them from other blocks. Now that we have a form, we need to define what happens when the submit button is clicked.</p> - -<p>Remember, everything in Eve is a record, so the <code>#click</code> event is no different. When a user clicks the mouse in the browser, Eve records that click in the database.</p> - -<p>This record exists only for an instant, but we can react to it by searching for <code>[#click element: [#submit]]</code>. This record represents a <code>#click</code> on our <code>#submit</code> button. Then, all we need to do is capture the values of the input boxes and save them as a <code>#student</code> record:</p> -<div class="highlight"><pre><code class="language-eve" data-lang="eve"><span></span><span class="kr">search</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="p">[</span><span class="nt">#click</span><span class="w"> </span><span class="x">element</span><span class="nf">:</span><span class="w"> </span><span class="p">[</span><span class="nt">#submit</span><span class="p">]]</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="x">name</span><span class="w"> </span><span class="nf">=</span><span class="w"> </span><span class="p">[</span><span class="nt">#name-input</span><span class="p">]</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="x">grade</span><span class="w"> </span><span class="nf">=</span><span class="w"> </span><span class="p">[</span><span class="nt">#grade-input</span><span class="p">]</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="x">school</span><span class="w"> </span><span class="nf">=</span><span class="w"> </span><span class="p">[</span><span class="nt">#school-input</span><span class="p">]</span><span class="w"></span> - -<span class="kr">commit</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="c1">// save the new student</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="p">[</span><span class="nt">#student</span><span class="w"> </span><span class="x">name</span><span class="nf">:</span><span class="w"> </span><span class="x">name.value</span><span class="p">,</span><span class="w"> </span><span class="x">grade</span><span class="nf">:</span><span class="w"> </span><span class="x">grade.value</span><span class="p">,</span><span class="w"> </span><span class="x">school</span><span class="nf">:</span><span class="w"> </span><span class="x">school.value</span><span class="p">]</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="c1">// reset the form</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="x">name.value</span><span class="w"> </span><span class="nf">:=</span><span class="w"> </span><span class="s">&quot;&quot;</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="x">grade.value</span><span class="w"> </span><span class="nf">:=</span><span class="w"> </span><span class="s">&quot;&quot;</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="x">school.value</span><span class="w"> </span><span class="nf">:=</span><span class="w"> </span><span class="s">&quot;&quot;</span><span class="w"></span> -</code></pre></div> - -<h2 id="learning-more">Learning more</h2> - -<p>If you want to learn more about Eve, we have some resources to help with that:</p> - -<ul> -<li>Example applications - See some working programs and explore how they work.</li> -<li>Tutorials - Step by step instructions on building Eve applications.</li> -<li><a href="https://witheve.github.io/docs">The Eve Handbook</a> - Everything you need to know about Eve.</li> -<li><a href="https://witheve.github.io/assets/docs/SyntaxReference.pdf">Eve syntax reference</a> - Eve&rsquo;s syntax in one page.</li> -<li>Guides - In-depth documents on topics relating to Eve.</li> -</ul> - -<p>We also invite you to join the Eve community! There are several ways to get involved:</p> - -<ul> -<li>Join our <a href="https://groups.google.com/forum/#!forum/eve-talk">mailing list</a> and get involved with the latest discussions on Eve.</li> -<li>Impact the future of Eve by getting involved with our <a href="https://github.com/witheve/rfcs">Request for Comments</a> process.</li> -<li>Read our <a href="http://incidentalcomplexity.com/">development diary</a> for the latest news and articles on Eve.</li> -<li>Follow us on <a href="https://twitter.com/with_eve">twitter</a>.</li> -</ul> - - - - - Statistics - https://witheve.github.io/docs/handbook/statistics/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://witheve.github.io/docs/handbook/statistics/ - - -<h1 id="statistics">Statistics</h1> - -<ul> -<li><a href="count">count</a> - counts the number of elements in a set</li> -</ul> - -<h2 id="random-functions">Random Functions</h2> - -<ul> -<li><a href="random">random</a> - Generates a random number between <code>0</code> and <code>1</code></li> -</ul> - - - - - Strings - https://witheve.github.io/docs/handbook/strings/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://witheve.github.io/docs/handbook/strings/ - - -<h1 id="strings">Strings</h1> - -<ul> -<li><a href="length">length</a></li> -<li><a href="concat">concatenate</a></li> -<li><a href="replace">replace</a></li> -<li><a href="split">split</a></li> -<li><a href="join">join</a></li> -</ul> - - - - - \ No newline at end of file diff --git a/javascripts/application.js b/javascripts/application.js deleted file mode 100644 index 1199f2e..0000000 --- a/javascripts/application.js +++ /dev/null @@ -1 +0,0 @@ -function pegasus(t,e){return e=new XMLHttpRequest,e.open("GET",t),t=[],e.onreadystatechange=e.then=function(n,o,i,r){if(n&&n.call&&(t=[,n,o]),4==e.readyState&&(i=t[0|e.status/200])){try{r=JSON.parse(e.responseText)}catch(s){r=null}i(r,e)}},e.send(),e}if("document"in self&&("classList"in document.createElement("_")?!function(){"use strict";var t=document.createElement("_");if(t.classList.add("c1","c2"),!t.classList.contains("c2")){var e=function(t){var e=DOMTokenList.prototype[t];DOMTokenList.prototype[t]=function(t){var n,o=arguments.length;for(n=0;o>n;n++)t=arguments[n],e.call(this,t)}};e("add"),e("remove")}if(t.classList.toggle("c3",!1),t.classList.contains("c3")){var n=DOMTokenList.prototype.toggle;DOMTokenList.prototype.toggle=function(t,e){return 1 in arguments&&!this.contains(t)==!e?e:n.call(this,t)}}t=null}():!function(t){"use strict";if("Element"in t){var e="classList",n="prototype",o=t.Element[n],i=Object,r=String[n].trim||function(){return this.replace(/^\s+|\s+$/g,"")},s=Array[n].indexOf||function(t){for(var e=0,n=this.length;n>e;e++)if(e in this&&this[e]===t)return e;return-1},a=function(t,e){this.name=t,this.code=DOMException[t],this.message=e},c=function(t,e){if(""===e)throw new a("SYNTAX_ERR","An invalid or illegal string was specified");if(/\s/.test(e))throw new a("INVALID_CHARACTER_ERR","String contains an invalid character");return s.call(t,e)},l=function(t){for(var e=r.call(t.getAttribute("class")||""),n=e?e.split(/\s+/):[],o=0,i=n.length;i>o;o++)this.push(n[o]);this._updateClassName=function(){t.setAttribute("class",this.toString())}},u=l[n]=[],d=function(){return new l(this)};if(a[n]=Error[n],u.item=function(t){return this[t]||null},u.contains=function(t){return t+="",-1!==c(this,t)},u.add=function(){var t,e=arguments,n=0,o=e.length,i=!1;do t=e[n]+"",-1===c(this,t)&&(this.push(t),i=!0);while(++nc;c++)a[s[c]]=i(a[s[c]],a);n&&(e.addEventListener("mouseover",this.onMouse,!0),e.addEventListener("mousedown",this.onMouse,!0),e.addEventListener("mouseup",this.onMouse,!0)),e.addEventListener("click",this.onClick,!0),e.addEventListener("touchstart",this.onTouchStart,!1),e.addEventListener("touchmove",this.onTouchMove,!1),e.addEventListener("touchend",this.onTouchEnd,!1),e.addEventListener("touchcancel",this.onTouchCancel,!1),Event.prototype.stopImmediatePropagation||(e.removeEventListener=function(t,n,o){var i=Node.prototype.removeEventListener;"click"===t?i.call(e,t,n.hijacked||n,o):i.call(e,t,n,o)},e.addEventListener=function(t,n,o){var i=Node.prototype.addEventListener;"click"===t?i.call(e,t,n.hijacked||(n.hijacked=function(t){t.propagationStopped||n(t)}),o):i.call(e,t,n,o)}),"function"==typeof e.onclick&&(r=e.onclick,e.addEventListener("click",function(t){r(t)},!1),e.onclick=null)}}var e=navigator.userAgent.indexOf("Windows Phone")>=0,n=navigator.userAgent.indexOf("Android")>0&&!e,o=/iP(ad|hone|od)/.test(navigator.userAgent)&&!e,i=o&&/OS 4_\d(_\d)?/.test(navigator.userAgent),r=o&&/OS [6-7]_\d/.test(navigator.userAgent),s=navigator.userAgent.indexOf("BB10")>0;t.prototype.needsClick=function(t){switch(t.nodeName.toLowerCase()){case"button":case"select":case"textarea":if(t.disabled)return!0;break;case"input":if(o&&"file"===t.type||t.disabled)return!0;break;case"label":case"iframe":case"video":return!0}return/\bneedsclick\b/.test(t.className)},t.prototype.needsFocus=function(t){switch(t.nodeName.toLowerCase()){case"textarea":return!0;case"select":return!n;case"input":switch(t.type){case"button":case"checkbox":case"file":case"image":case"radio":case"submit":return!1}return!t.disabled&&!t.readOnly;default:return/\bneedsfocus\b/.test(t.className)}},t.prototype.sendClick=function(t,e){var n,o;document.activeElement&&document.activeElement!==t&&document.activeElement.blur(),o=e.changedTouches[0],n=document.createEvent("MouseEvents"),n.initMouseEvent(this.determineEventType(t),!0,!0,window,1,o.screenX,o.screenY,o.clientX,o.clientY,!1,!1,!1,!1,0,null),n.forwardedTouchEvent=!0,t.dispatchEvent(n)},t.prototype.determineEventType=function(t){return n&&"select"===t.tagName.toLowerCase()?"mousedown":"click"},t.prototype.focus=function(t){var e;o&&t.setSelectionRange&&0!==t.type.indexOf("date")&&"time"!==t.type&&"month"!==t.type?(e=t.value.length,t.setSelectionRange(e,e)):t.focus()},t.prototype.updateScrollParent=function(t){var e,n;if(e=t.fastClickScrollParent,!e||!e.contains(t)){n=t;do{if(n.scrollHeight>n.offsetHeight){e=n,t.fastClickScrollParent=n;break}n=n.parentElement}while(n)}e&&(e.fastClickLastScrollTop=e.scrollTop)},t.prototype.getTargetElementFromEventTarget=function(t){return t.nodeType===Node.TEXT_NODE?t.parentNode:t},t.prototype.onTouchStart=function(t){var e,n,r;if(t.targetTouches.length>1)return!0;if(e=this.getTargetElementFromEventTarget(t.target),n=t.targetTouches[0],o){if(r=window.getSelection(),r.rangeCount&&!r.isCollapsed)return!0;if(!i){if(n.identifier&&n.identifier===this.lastTouchIdentifier)return t.preventDefault(),!1;this.lastTouchIdentifier=n.identifier,this.updateScrollParent(e)}}return this.trackingClick=!0,this.trackingClickStart=t.timeStamp,this.targetElement=e,this.touchStartX=n.pageX,this.touchStartY=n.pageY,t.timeStamp-this.lastClickTimen||Math.abs(e.pageY-this.touchStartY)>n?!0:!1},t.prototype.onTouchMove=function(t){return this.trackingClick?((this.targetElement!==this.getTargetElementFromEventTarget(t.target)||this.touchHasMoved(t))&&(this.trackingClick=!1,this.targetElement=null),!0):!0},t.prototype.findControl=function(t){return void 0!==t.control?t.control:t.htmlFor?document.getElementById(t.htmlFor):t.querySelector("button, input:not([type=hidden]), keygen, meter, output, progress, select, textarea")},t.prototype.onTouchEnd=function(t){var e,s,a,c,l,u=this.targetElement;if(!this.trackingClick)return!0;if(t.timeStamp-this.lastClickTimethis.tapTimeout)return!0;if(this.cancelNextClick=!1,this.lastClickTime=t.timeStamp,s=this.trackingClickStart,this.trackingClick=!1,this.trackingClickStart=0,r&&(l=t.changedTouches[0],u=document.elementFromPoint(l.pageX-window.pageXOffset,l.pageY-window.pageYOffset)||u,u.fastClickScrollParent=this.targetElement.fastClickScrollParent),a=u.tagName.toLowerCase(),"label"===a){if(e=this.findControl(u)){if(this.focus(u),n)return!1;u=e}}else if(this.needsFocus(u))return t.timeStamp-s>100||o&&window.top!==window&&"input"===a?(this.targetElement=null,!1):(this.focus(u),this.sendClick(u,t),o&&"select"===a||(this.targetElement=null,t.preventDefault()),!1);return o&&!i&&(c=u.fastClickScrollParent,c&&c.fastClickLastScrollTop!==c.scrollTop)?!0:(this.needsClick(u)||(t.preventDefault(),this.sendClick(u,t)),!1)},t.prototype.onTouchCancel=function(){this.trackingClick=!1,this.targetElement=null},t.prototype.onMouse=function(t){return this.targetElement?t.forwardedTouchEvent?!0:t.cancelable&&(!this.needsClick(this.targetElement)||this.cancelNextClick)?(t.stopImmediatePropagation?t.stopImmediatePropagation():t.propagationStopped=!0,t.stopPropagation(),t.preventDefault(),!1):!0:!0},t.prototype.onClick=function(t){var e;return this.trackingClick?(this.targetElement=null,this.trackingClick=!1,!0):"submit"===t.target.type&&0===t.detail?!0:(e=this.onMouse(t),e||(this.targetElement=null),e)},t.prototype.destroy=function(){var t=this.layer;n&&(t.removeEventListener("mouseover",this.onMouse,!0),t.removeEventListener("mousedown",this.onMouse,!0),t.removeEventListener("mouseup",this.onMouse,!0)),t.removeEventListener("click",this.onClick,!0),t.removeEventListener("touchstart",this.onTouchStart,!1),t.removeEventListener("touchmove",this.onTouchMove,!1),t.removeEventListener("touchend",this.onTouchEnd,!1),t.removeEventListener("touchcancel",this.onTouchCancel,!1)},t.notNeeded=function(t){var e,o,i,r;if("undefined"==typeof window.ontouchstart)return!0;if(o=+(/Chrome\/([0-9]+)/.exec(navigator.userAgent)||[,0])[1]){if(!n)return!0;if(e=document.querySelector("meta[name=viewport]")){if(-1!==e.content.indexOf("user-scalable=no"))return!0;if(o>31&&document.documentElement.scrollWidth<=window.outerWidth)return!0}}if(s&&(i=navigator.userAgent.match(/Version\/([0-9]*)\.([0-9]*)/),i[1]>=10&&i[2]>=3&&(e=document.querySelector("meta[name=viewport]")))){if(-1!==e.content.indexOf("user-scalable=no"))return!0;if(document.documentElement.scrollWidth<=window.outerWidth)return!0}return"none"===t.style.msTouchAction||"manipulation"===t.style.touchAction?!0:(r=+(/Firefox\/([0-9]+)/.exec(navigator.userAgent)||[,0])[1],r>=27&&(e=document.querySelector("meta[name=viewport]"),e&&(-1!==e.content.indexOf("user-scalable=no")||document.documentElement.scrollWidth<=window.outerWidth))?!0:"none"===t.style.touchAction||"manipulation"===t.style.touchAction?!0:!1)},t.attach=function(e,n){return new t(e,n)},"function"==typeof define&&"object"==typeof define.amd&&define.amd?define(function(){return t}):"undefined"!=typeof module&&module.exports?(module.exports=t.attach,module.exports.FastClick=t):window.FastClick=t}(),function(){var t=function(e){var n=new t.Index;return n.pipeline.add(t.trimmer,t.stopWordFilter,t.stemmer),e&&e.call(n,n),n};t.version="0.6.0",t.utils={},t.utils.warn=function(t){return function(e){t.console&&console.warn&&console.warn(e)}}(this),t.utils.asString=function(t){return void 0===t||null===t?"":t.toString()},t.EventEmitter=function(){this.events={}},t.EventEmitter.prototype.addListener=function(){var t=Array.prototype.slice.call(arguments),e=t.pop(),n=t;if("function"!=typeof e)throw new TypeError("last argument must be a function");n.forEach(function(t){this.hasHandler(t)||(this.events[t]=[]),this.events[t].push(e)},this)},t.EventEmitter.prototype.removeListener=function(t,e){if(this.hasHandler(t)){var n=this.events[t].indexOf(e);this.events[t].splice(n,1),this.events[t].length||delete this.events[t]}},t.EventEmitter.prototype.emit=function(t){if(this.hasHandler(t)){var e=Array.prototype.slice.call(arguments,1);this.events[t].forEach(function(t){t.apply(void 0,e)})}},t.EventEmitter.prototype.hasHandler=function(t){return t in this.events},t.tokenizer=function(e){return arguments.length&&null!=e&&void 0!=e?Array.isArray(e)?e.map(function(e){return t.utils.asString(e).toLowerCase()}):e.toString().trim().toLowerCase().split(t.tokenizer.seperator):[]},t.tokenizer.seperator=/[\s\-]+/,t.Pipeline=function(){this._stack=[]},t.Pipeline.registeredFunctions={},t.Pipeline.registerFunction=function(e,n){n in this.registeredFunctions&&t.utils.warn("Overwriting existing registered function: "+n),e.label=n,t.Pipeline.registeredFunctions[e.label]=e},t.Pipeline.warnIfFunctionNotRegistered=function(e){var n=e.label&&e.label in this.registeredFunctions;n||t.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",e)},t.Pipeline.load=function(e){var n=new t.Pipeline;return e.forEach(function(e){var o=t.Pipeline.registeredFunctions[e];if(!o)throw new Error("Cannot load un-registered function: "+e);n.add(o)}),n},t.Pipeline.prototype.add=function(){var e=Array.prototype.slice.call(arguments);e.forEach(function(e){t.Pipeline.warnIfFunctionNotRegistered(e),this._stack.push(e)},this)},t.Pipeline.prototype.after=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var o=this._stack.indexOf(e);if(-1==o)throw new Error("Cannot find existingFn");o+=1,this._stack.splice(o,0,n)},t.Pipeline.prototype.before=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var o=this._stack.indexOf(e);if(-1==o)throw new Error("Cannot find existingFn");this._stack.splice(o,0,n)},t.Pipeline.prototype.remove=function(t){var e=this._stack.indexOf(t);-1!=e&&this._stack.splice(e,1)},t.Pipeline.prototype.run=function(t){for(var e=[],n=t.length,o=this._stack.length,i=0;n>i;i++){for(var r=t[i],s=0;o>s&&(r=this._stack[s](r,i,t),void 0!==r&&""!==r);s++);void 0!==r&&""!==r&&e.push(r)}return e},t.Pipeline.prototype.reset=function(){this._stack=[]},t.Pipeline.prototype.toJSON=function(){return this._stack.map(function(e){return t.Pipeline.warnIfFunctionNotRegistered(e),e.label})},t.Vector=function(){this._magnitude=null,this.list=void 0,this.length=0},t.Vector.Node=function(t,e,n){this.idx=t,this.val=e,this.next=n},t.Vector.prototype.insert=function(e,n){this._magnitude=void 0;var o=this.list;if(!o)return this.list=new t.Vector.Node(e,n,o),this.length++;if(en.idx?n=n.next:(o+=e.val*n.val,e=e.next,n=n.next);return o},t.Vector.prototype.similarity=function(t){return this.dot(t)/(this.magnitude()*t.magnitude())},t.SortedSet=function(){this.length=0,this.elements=[]},t.SortedSet.load=function(t){var e=new this;return e.elements=t,e.length=t.length,e},t.SortedSet.prototype.add=function(){var t,e;for(t=0;t1;){if(r===t)return i;t>r&&(e=i),r>t&&(n=i),o=n-e,i=e+Math.floor(o/2),r=this.elements[i]}return r===t?i:-1},t.SortedSet.prototype.locationFor=function(t){for(var e=0,n=this.elements.length,o=n-e,i=e+Math.floor(o/2),r=this.elements[i];o>1;)t>r&&(e=i),r>t&&(n=i),o=n-e,i=e+Math.floor(o/2),r=this.elements[i];return r>t?i:t>r?i+1:void 0},t.SortedSet.prototype.intersect=function(e){for(var n=new t.SortedSet,o=0,i=0,r=this.length,s=e.length,a=this.elements,c=e.elements;;){if(o>r-1||i>s-1)break;a[o]!==c[i]?a[o]c[i]&&i++:(n.add(a[o]),o++,i++)}return n},t.SortedSet.prototype.clone=function(){var e=new t.SortedSet;return e.elements=this.toArray(),e.length=e.elements.length,e},t.SortedSet.prototype.union=function(t){var e,n,o;return this.length>=t.length?(e=this,n=t):(e=t,n=this),o=e.clone(),o.add.apply(o,n.toArray()),o},t.SortedSet.prototype.toJSON=function(){return this.toArray()},t.Index=function(){this._fields=[],this._ref="id",this.pipeline=new t.Pipeline,this.documentStore=new t.Store,this.tokenStore=new t.TokenStore,this.corpusTokens=new t.SortedSet,this.eventEmitter=new t.EventEmitter,this._idfCache={},this.on("add","remove","update",function(){this._idfCache={}}.bind(this))},t.Index.prototype.on=function(){var t=Array.prototype.slice.call(arguments);return this.eventEmitter.addListener.apply(this.eventEmitter,t)},t.Index.prototype.off=function(t,e){return this.eventEmitter.removeListener(t,e)},t.Index.load=function(e){e.version!==t.version&&t.utils.warn("version mismatch: current "+t.version+" importing "+e.version);var n=new this;return n._fields=e.fields,n._ref=e.ref,n.documentStore=t.Store.load(e.documentStore),n.tokenStore=t.TokenStore.load(e.tokenStore),n.corpusTokens=t.SortedSet.load(e.corpusTokens),n.pipeline=t.Pipeline.load(e.pipeline),n},t.Index.prototype.field=function(t,e){var e=e||{},n={name:t,boost:e.boost||1};return this._fields.push(n),this},t.Index.prototype.ref=function(t){return this._ref=t,this},t.Index.prototype.add=function(e,n){var o={},i=new t.SortedSet,r=e[this._ref],n=void 0===n?!0:n;this._fields.forEach(function(n){var r=this.pipeline.run(t.tokenizer(e[n.name]));o[n.name]=r,t.SortedSet.prototype.add.apply(i,r)},this),this.documentStore.set(r,i),t.SortedSet.prototype.add.apply(this.corpusTokens,i.toArray());for(var s=0;s0&&(o=1+Math.log(this.documentStore.length/n)),this._idfCache[e]=o},t.Index.prototype.search=function(e){var n=this.pipeline.run(t.tokenizer(e)),o=new t.Vector,i=[],r=this._fields.reduce(function(t,e){return t+e.boost},0),s=n.some(function(t){return this.tokenStore.has(t)},this);if(!s)return[];n.forEach(function(e,n,s){var a=1/s.length*this._fields.length*r,c=this,l=this.tokenStore.expand(e).reduce(function(n,i){var r=c.corpusTokens.indexOf(i),s=c.idf(i),l=1,u=new t.SortedSet;if(i!==e){var d=Math.max(3,i.length-e.length);l=1/Math.log(d)}r>-1&&o.insert(r,a*s*l);for(var h=c.tokenStore.get(i),f=Object.keys(h),p=f.length,m=0;p>m;m++)u.add(h[f[m]].ref);return n.union(u)},new t.SortedSet);i.push(l)},this);var a=i.reduce(function(t,e){return t.intersect(e)});return a.map(function(t){return{ref:t,score:o.similarity(this.documentVector(t))}},this).sort(function(t,e){return e.score-t.score})},t.Index.prototype.documentVector=function(e){for(var n=this.documentStore.get(e),o=n.length,i=new t.Vector,r=0;o>r;r++){var s=n.elements[r],a=this.tokenStore.get(s)[e].tf,c=this.idf(s);i.insert(this.corpusTokens.indexOf(s),a*c)}return i},t.Index.prototype.toJSON=function(){return{version:t.version,fields:this._fields,ref:this._ref,documentStore:this.documentStore.toJSON(),tokenStore:this.tokenStore.toJSON(),corpusTokens:this.corpusTokens.toJSON(),pipeline:this.pipeline.toJSON()}},t.Index.prototype.use=function(t){var e=Array.prototype.slice.call(arguments,1);e.unshift(this),t.apply(this,e)},t.Store=function(){this.store={},this.length=0},t.Store.load=function(e){var n=new this;return n.length=e.length,n.store=Object.keys(e.store).reduce(function(n,o){return n[o]=t.SortedSet.load(e.store[o]),n},{}),n},t.Store.prototype.set=function(t,e){this.has(t)||this.length++,this.store[t]=e},t.Store.prototype.get=function(t){return this.store[t]},t.Store.prototype.has=function(t){return t in this.store},t.Store.prototype.remove=function(t){this.has(t)&&(delete this.store[t],this.length--)},t.Store.prototype.toJSON=function(){return{store:this.store,length:this.length}},t.stemmer=function(){var t={ational:"ate",tional:"tion",enci:"ence",anci:"ance",izer:"ize",bli:"ble",alli:"al",entli:"ent",eli:"e",ousli:"ous",ization:"ize",ation:"ate",ator:"ate",alism:"al",iveness:"ive",fulness:"ful",ousness:"ous",aliti:"al",iviti:"ive",biliti:"ble",logi:"log"},e={icate:"ic",ative:"",alize:"al",iciti:"ic",ical:"ic",ful:"",ness:""},n="[^aeiou]",o="[aeiouy]",i=n+"[^aeiouy]*",r=o+"[aeiou]*",s="^("+i+")?"+r+i,a="^("+i+")?"+r+i+"("+r+")?$",c="^("+i+")?"+r+i+r+i,l="^("+i+")?"+o,u=new RegExp(s),d=new RegExp(c),h=new RegExp(a),f=new RegExp(l),p=/^(.+?)(ss|i)es$/,m=/^(.+?)([^s])s$/,v=/^(.+?)eed$/,g=/^(.+?)(ed|ing)$/,y=/.$/,w=/(at|bl|iz)$/,S=new RegExp("([^aeiouylsz])\\1$"),k=new RegExp("^"+i+o+"[^aeiouwxy]$"),E=/^(.+?[^aeiou])y$/,x=/^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/,b=/^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/,T=/^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/,C=/^(.+?)(s|t)(ion)$/,L=/^(.+?)e$/,_=/ll$/,A=new RegExp("^"+i+o+"[^aeiouwxy]$"),O=function(n){var o,i,r,s,a,c,l;if(n.length<3)return n;if(r=n.substr(0,1),"y"==r&&(n=r.toUpperCase()+n.substr(1)),s=p,a=m,s.test(n)?n=n.replace(s,"$1$2"):a.test(n)&&(n=n.replace(a,"$1$2")),s=v,a=g,s.test(n)){var O=s.exec(n);s=u,s.test(O[1])&&(s=y,n=n.replace(s,""))}else if(a.test(n)){var O=a.exec(n);o=O[1],a=f,a.test(o)&&(n=o,a=w,c=S,l=k,a.test(n)?n+="e":c.test(n)?(s=y,n=n.replace(s,"")):l.test(n)&&(n+="e"))}if(s=E,s.test(n)){var O=s.exec(n);o=O[1],n=o+"i"}if(s=x,s.test(n)){var O=s.exec(n);o=O[1],i=O[2],s=u,s.test(o)&&(n=o+t[i])}if(s=b,s.test(n)){var O=s.exec(n);o=O[1],i=O[2],s=u,s.test(o)&&(n=o+e[i])}if(s=T,a=C,s.test(n)){var O=s.exec(n);o=O[1],s=d,s.test(o)&&(n=o)}else if(a.test(n)){var O=a.exec(n);o=O[1]+O[2],a=d,a.test(o)&&(n=o)}if(s=L,s.test(n)){var O=s.exec(n);o=O[1],s=d,a=h,c=A,(s.test(o)||a.test(o)&&!c.test(o))&&(n=o)}return s=_,a=d,s.test(n)&&a.test(n)&&(s=y,n=n.replace(s,"")),"y"==r&&(n=r.toLowerCase()+n.substr(1)),n};return O}(),t.Pipeline.registerFunction(t.stemmer,"stemmer"),t.generateStopWordFilter=function(t){var e=t.reduce(function(t,e){return t[e]=e,t},{});return function(t){return t&&e[t]!==t?t:void 0}},t.stopWordFilter=t.generateStopWordFilter(["a","able","about","across","after","all","almost","also","am","among","an","and","any","are","as","at","be","because","been","but","by","can","cannot","could","dear","did","do","does","either","else","ever","every","for","from","get","got","had","has","have","he","her","hers","him","his","how","however","i","if","in","into","is","it","its","just","least","let","like","likely","may","me","might","most","must","my","neither","no","nor","not","of","off","often","on","only","or","other","our","own","rather","said","say","says","she","should","since","so","some","than","that","the","their","them","then","there","these","they","this","tis","to","too","twas","us","wants","was","we","were","what","when","where","which","while","who","whom","why","will","with","would","yet","you","your"]),t.Pipeline.registerFunction(t.stopWordFilter,"stopWordFilter"),t.trimmer=function(t){return t.replace(/^\W+/,"").replace(/\W+$/,"")},t.Pipeline.registerFunction(t.trimmer,"trimmer"),t.TokenStore=function(){this.root={docs:{}},this.length=0},t.TokenStore.load=function(t){var e=new this;return e.root=t.root,e.length=t.length,e},t.TokenStore.prototype.add=function(t,e,n){var n=n||this.root,o=t.charAt(0),i=t.slice(1);return o in n||(n[o]={docs:{}}),0===i.length?(n[o].docs[e.ref]=e,void(this.length+=1)):this.add(i,e,n[o])},t.TokenStore.prototype.has=function(t){if(!t)return!1;for(var e=this.root,n=0;nt){for(;" "!=this[t]&&--t>0;);return this.substring(0,t)+"…"}return this},HTMLElement.prototype.wrap=function(t){t.length||(t=[t]);for(var e=t.length-1;e>=0;e--){var n=e>0?this.cloneNode(!0):this,o=t[e],i=o.parentNode,r=o.nextSibling;n.appendChild(o),r?i.insertBefore(n,r):i.appendChild(n)}},document.addEventListener("DOMContentLoaded",function(){"use strict";Modernizr.addTest("ios",function(){return!!navigator.userAgent.match(/(iPad|iPhone|iPod)/g)}),Modernizr.addTest("standalone",function(){return!!navigator.standalone}),FastClick.attach(document.body);var t=document.getElementById("toggle-search"),e=(document.getElementById("reset-search"),document.querySelector(".drawer")),n=document.querySelectorAll(".anchor"),o=document.querySelector(".search .field"),i=document.querySelector(".query"),r=document.querySelector(".results .meta");Array.prototype.forEach.call(n,function(t){t.querySelector("a").addEventListener("click",function(){document.getElementById("toggle-drawer").checked=!1,document.body.classList.remove("toggle-drawer")})});var s=window.pageYOffset,a=function(){var t=window.pageYOffset+window.innerHeight,n=Math.max(0,window.innerHeight-e.offsetHeight);t>document.body.clientHeight-(96-n)?"absolute"!=e.style.position&&(e.style.position="absolute",e.style.top=null,e.style.bottom=0):e.offsetHeighte.offsetTop+e.offsetHeight?(e.style.position="fixed",e.style.top=null,e.style.bottom="-96px"):window.pageYOffsets?e.style.top&&(e.style.position="absolute",e.style.top=Math.max(0,s)+"px",e.style.bottom=null):e.style.bottom&&(e.style.position="absolute",e.style.top=t-e.offsetHeight+"px",e.style.bottom=null),s=Math.max(0,window.pageYOffset)},c=function(){var t=document.querySelector(".main");window.removeEventListener("scroll",a),matchMedia("only screen and (max-width: 959px)").matches?(e.style.position=null,e.style.top=null,e.style.bottom=null):e.offsetHeight+96o;o++)t1e4?n=(n/1e3).toFixed(0)+"k":n>1e3&&(n=(n/1e3).toFixed(1)+"k");var o=document.querySelector(".repo-stars .count");o.innerHTML=n},function(t,e){console.error(t,e.status)})}),"standalone"in window.navigator&&window.navigator.standalone){var node,remotes=!1;document.addEventListener("click",function(t){for(node=t.target;"A"!==node.nodeName&&"HTML"!==node.nodeName;)node=node.parentNode;"href"in node&&-1!==node.href.indexOf("http")&&(-1!==node.href.indexOf(document.location.host)||remotes)&&(t.preventDefault(),document.location.href=node.href)},!1)} \ No newline at end of file diff --git a/javascripts/modernizr.js b/javascripts/modernizr.js deleted file mode 100644 index e82c909..0000000 --- a/javascripts/modernizr.js +++ /dev/null @@ -1 +0,0 @@ -!function(e,t,n){function r(e,t){return typeof e===t}function i(){var e,t,n,i,o,a,s;for(var l in x)if(x.hasOwnProperty(l)){if(e=[],t=x[l],t.name&&(e.push(t.name.toLowerCase()),t.options&&t.options.aliases&&t.options.aliases.length))for(n=0;nf;f++)if(h=e[f],g=_.style[h],l(h,"-")&&(h=m(h)),_.style[h]!==n){if(o||r(i,"undefined"))return a(),"pfx"==t?h:!0;try{_.style[h]=i}catch(y){}if(_.style[h]!=g)return a(),"pfx"==t?h:!0}return a(),!1}function g(e,t,n){var i;for(var o in e)if(e[o]in t)return n===!1?e[o]:(i=t[e[o]],r(i,"function")?s(i,n||t):i);return!1}function v(e,t,n,i,o){var a=e.charAt(0).toUpperCase()+e.slice(1),s=(e+" "+P.join(a+" ")+a).split(" ");return r(t,"string")||r(t,"undefined")?h(s,t,i,o):(s=(e+" "+A.join(a+" ")+a).split(" "),g(s,t,n))}function y(e,t,r){return v(e,n,n,t,r)}var x=[],E={_version:"3.3.1",_config:{classPrefix:"",enableClasses:!0,enableJSClass:!0,usePrefixes:!0},_q:[],on:function(e,t){var n=this;setTimeout(function(){t(n[e])},0)},addTest:function(e,t,n){x.push({name:e,fn:t,options:n})},addAsyncTest:function(e){x.push({name:null,fn:e})}},S=function(){};S.prototype=E,S=new S;var b,w=[],C=t.documentElement,T="svg"===C.nodeName.toLowerCase();!function(){var e={}.hasOwnProperty;b=r(e,"undefined")||r(e.call,"undefined")?function(e,t){return t in e&&r(e.constructor.prototype[t],"undefined")}:function(t,n){return e.call(t,n)}}(),E._l={},E.on=function(e,t){this._l[e]||(this._l[e]=[]),this._l[e].push(t),S.hasOwnProperty(e)&&setTimeout(function(){S._trigger(e,S[e])},0)},E._trigger=function(e,t){if(this._l[e]){var n=this._l[e];setTimeout(function(){var e,r;for(e=0;e",r.insertBefore(n.lastChild,r.firstChild)}function r(){var e=C.elements;return"string"==typeof e?e.split(" "):e}function i(e,t){var n=C.elements;"string"!=typeof n&&(n=n.join(" ")),"string"!=typeof e&&(e=e.join(" ")),C.elements=n+" "+e,u(t)}function o(e){var t=w[e[S]];return t||(t={},b++,e[S]=b,w[b]=t),t}function a(e,n,r){if(n||(n=t),g)return n.createElement(e);r||(r=o(n));var i;return i=r.cache[e]?r.cache[e].cloneNode():E.test(e)?(r.cache[e]=r.createElem(e)).cloneNode():r.createElem(e),!i.canHaveChildren||x.test(e)||i.tagUrn?i:r.frag.appendChild(i)}function s(e,n){if(e||(e=t),g)return e.createDocumentFragment();n=n||o(e);for(var i=n.frag.cloneNode(),a=0,s=r(),l=s.length;l>a;a++)i.createElement(s[a]);return i}function l(e,t){t.cache||(t.cache={},t.createElem=e.createElement,t.createFrag=e.createDocumentFragment,t.frag=t.createFrag()),e.createElement=function(n){return C.shivMethods?a(n,e,t):t.createElem(n)},e.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+r().join().replace(/[\w\-:]+/g,function(e){return t.createElem(e),t.frag.createElement(e),'c("'+e+'")'})+");return n}")(C,t.frag)}function u(e){e||(e=t);var r=o(e);return!C.shivCSS||h||r.hasCSS||(r.hasCSS=!!n(e,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),g||l(e,r),e}function c(e){for(var t,n=e.getElementsByTagName("*"),i=n.length,o=RegExp("^(?:"+r().join("|")+")$","i"),a=[];i--;)t=n[i],o.test(t.nodeName)&&a.push(t.applyElement(f(t)));return a}function f(e){for(var t,n=e.attributes,r=n.length,i=e.ownerDocument.createElement(N+":"+e.nodeName);r--;)t=n[r],t.specified&&i.setAttribute(t.nodeName,t.nodeValue);return i.style.cssText=e.style.cssText,i}function d(e){for(var t,n=e.split("{"),i=n.length,o=RegExp("(^|[\\s,>+~])("+r().join("|")+")(?=[[\\s,>+~#.:]|$)","gi"),a="$1"+N+"\\:$2";i--;)t=n[i]=n[i].split("}"),t[t.length-1]=t[t.length-1].replace(o,a),n[i]=t.join("}");return n.join("{")}function p(e){for(var t=e.length;t--;)e[t].removeNode()}function m(e){function t(){clearTimeout(a._removeSheetTimer),r&&r.removeNode(!0),r=null}var r,i,a=o(e),s=e.namespaces,l=e.parentWindow;return!_||e.printShived?e:("undefined"==typeof s[N]&&s.add(N),l.attachEvent("onbeforeprint",function(){t();for(var o,a,s,l=e.styleSheets,u=[],f=l.length,p=Array(f);f--;)p[f]=l[f];for(;s=p.pop();)if(!s.disabled&&T.test(s.media)){try{o=s.imports,a=o.length}catch(m){a=0}for(f=0;a>f;f++)p.push(o[f]);try{u.push(s.cssText)}catch(m){}}u=d(u.reverse().join("")),i=c(e),r=n(e,u)}),l.attachEvent("onafterprint",function(){p(i),clearTimeout(a._removeSheetTimer),a._removeSheetTimer=setTimeout(t,500)}),e.printShived=!0,e)}var h,g,v="3.7.3",y=e.html5||{},x=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,E=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,S="_html5shiv",b=0,w={};!function(){try{var e=t.createElement("a");e.innerHTML="",h="hidden"in e,g=1==e.childNodes.length||function(){t.createElement("a");var e=t.createDocumentFragment();return"undefined"==typeof e.cloneNode||"undefined"==typeof e.createDocumentFragment||"undefined"==typeof e.createElement}()}catch(n){h=!0,g=!0}}();var C={elements:y.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:v,shivCSS:y.shivCSS!==!1,supportsUnknownElements:g,shivMethods:y.shivMethods!==!1,type:"default",shivDocument:u,createElement:a,createDocumentFragment:s,addElements:i};e.html5=C,u(t);var T=/^$|\b(?:all|print)\b/,N="html5shiv",_=!g&&function(){var n=t.documentElement;return!("undefined"==typeof t.namespaces||"undefined"==typeof t.parentWindow||"undefined"==typeof n.applyElement||"undefined"==typeof n.removeNode||"undefined"==typeof e.attachEvent)}();C.type+=" print",C.shivPrint=m,m(t),"object"==typeof module&&module.exports&&(module.exports=C)}("undefined"!=typeof e?e:this,t);var N={elem:u("modernizr")};S._q.push(function(){delete N.elem});var _={style:N.elem.style};S._q.unshift(function(){delete _.style});var z=(E.testProp=function(e,t,r){return h([e],n,t,r)},function(){function e(e,t){var i;return e?(t&&"string"!=typeof t||(t=u(t||"div")),e="on"+e,i=e in t,!i&&r&&(t.setAttribute||(t=u("div")),t.setAttribute(e,""),i="function"==typeof t[e],t[e]!==n&&(t[e]=n),t.removeAttribute(e)),i):!1}var r=!("onblur"in t.documentElement);return e}());E.hasEvent=z,S.addTest("inputsearchevent",z("search"));var k=E.testStyles=f,$=function(){var e=navigator.userAgent,t=e.match(/applewebkit\/([0-9]+)/gi)&&parseFloat(RegExp.$1),n=e.match(/w(eb)?osbrowser/gi),r=e.match(/windows phone/gi)&&e.match(/iemobile\/([0-9])+/gi)&&parseFloat(RegExp.$1)>=9,i=533>t&&e.match(/android/gi);return n||i||r}();$?S.addTest("fontface",!1):k('@font-face {font-family:"font";src:url("https://")}',function(e,n){var r=t.getElementById("smodernizr"),i=r.sheet||r.styleSheet,o=i?i.cssRules&&i.cssRules[0]?i.cssRules[0].cssText:i.cssText||"":"",a=/src/i.test(o)&&0===o.indexOf(n.split(" ")[0]);S.addTest("fontface",a)});var j="Moz O ms Webkit",P=E._config.usePrefixes?j.split(" "):[];E._cssomPrefixes=P;var A=E._config.usePrefixes?j.toLowerCase().split(" "):[];E._domPrefixes=A,E.testAllProps=v,E.testAllProps=y;var R="CSS"in e&&"supports"in e.CSS,F="supportsCSS"in e;S.addTest("supports",R||F),S.addTest("csstransforms3d",function(){var e=!!y("perspective","1px",!0),t=S._config.usePrefixes;if(e&&(!t||"webkitPerspective"in C.style)){var n,r="#modernizr{width:0;height:0}";S.supports?n="@supports (perspective: 1px)":(n="@media (transform-3d)",t&&(n+=",(-webkit-transform-3d)")),n+="{#modernizr{width:7px;height:18px;margin:0;padding:0;border:0}}",k(r+n,function(t){e=7===t.offsetWidth&&18===t.offsetHeight})}return e}),S.addTest("json","JSON"in e&&"parse"in JSON&&"stringify"in JSON),S.addTest("checked",function(){return k("#modernizr {position:absolute} #modernizr input {margin-left:10px} #modernizr :checked {margin-left:20px;display:block}",function(e){var t=u("input");return t.setAttribute("type","checkbox"),t.setAttribute("checked","checked"),e.appendChild(t),20===t.offsetLeft})}),S.addTest("target",function(){var t=e.document;if(!("querySelectorAll"in t))return!1;try{return t.querySelectorAll(":target"),!0}catch(n){return!1}}),S.addTest("contains",r(String.prototype.contains,"function")),i(),o(w),delete E.addTest,delete E.addAsyncTest;for(var M=0;M #mq-test-1 { width: 42px; }',r.insertBefore(o,i),n=42===a.offsetWidth,r.removeChild(o),{matches:n,media:e}}}(e.document)}(this),function(e){"use strict";function t(){E(!0)}var n={};e.respond=n,n.update=function(){};var r=[],i=function(){var t=!1;try{t=new e.XMLHttpRequest}catch(n){t=new e.ActiveXObject("Microsoft.XMLHTTP")}return function(){return t}}(),o=function(e,t){var n=i();n&&(n.open("GET",e,!0),n.onreadystatechange=function(){4!==n.readyState||200!==n.status&&304!==n.status||t(n.responseText)},4!==n.readyState&&n.send(null))};if(n.ajax=o,n.queue=r,n.regex={media:/@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi,keyframes:/@(?:\-(?:o|moz|webkit)\-)?keyframes[^\{]+\{(?:[^\{\}]*\{[^\}\{]*\})+[^\}]*\}/gi,urls:/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,findStyles:/@media *([^\{]+)\{([\S\s]+?)$/,only:/(only\s+)?([a-zA-Z]+)\s?/,minw:/\([\s]*min\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/,maxw:/\([\s]*max\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/},n.mediaQueriesSupported=e.matchMedia&&null!==e.matchMedia("only all")&&e.matchMedia("only all").matches,!n.mediaQueriesSupported){var a,s,l,u=e.document,c=u.documentElement,f=[],d=[],p=[],m={},h=30,g=u.getElementsByTagName("head")[0]||c,v=u.getElementsByTagName("base")[0],y=g.getElementsByTagName("link"),x=function(){var e,t=u.createElement("div"),n=u.body,r=c.style.fontSize,i=n&&n.style.fontSize,o=!1;return t.style.cssText="position:absolute;font-size:1em;width:1em",n||(n=o=u.createElement("body"),n.style.background="none"),c.style.fontSize="100%",n.style.fontSize="100%",n.appendChild(t),o&&c.insertBefore(n,c.firstChild),e=t.offsetWidth,o?c.removeChild(n):n.removeChild(t),c.style.fontSize=r,i&&(n.style.fontSize=i),e=l=parseFloat(e)},E=function(t){var n="clientWidth",r=c[n],i="CSS1Compat"===u.compatMode&&r||u.body[n]||r,o={},m=y[y.length-1],v=(new Date).getTime();if(t&&a&&h>v-a)return e.clearTimeout(s),void(s=e.setTimeout(E,h));a=v;for(var S in f)if(f.hasOwnProperty(S)){var b=f[S],w=b.minw,C=b.maxw,T=null===w,N=null===C,_="em";w&&(w=parseFloat(w)*(w.indexOf(_)>-1?l||x():1)),C&&(C=parseFloat(C)*(C.indexOf(_)>-1?l||x():1)),b.hasquery&&(T&&N||!(T||i>=w)||!(N||C>=i))||(o[b.media]||(o[b.media]=[]),o[b.media].push(d[b.rules]))}for(var z in p)p.hasOwnProperty(z)&&p[z]&&p[z].parentNode===g&&g.removeChild(p[z]);p.length=0;for(var k in o)if(o.hasOwnProperty(k)){var $=u.createElement("style"),j=o[k].join("\n");$.type="text/css",$.media=k,g.insertBefore($,m.nextSibling),$.styleSheet?$.styleSheet.cssText=j:$.appendChild(u.createTextNode(j)),p.push($)}},S=function(e,t,r){var i=e.replace(n.regex.keyframes,"").match(n.regex.media),o=i&&i.length||0;t=t.substring(0,t.lastIndexOf("/"));var a=function(e){return e.replace(n.regex.urls,"$1"+t+"$2$3")},s=!o&&r;t.length&&(t+="/"),s&&(o=1);for(var l=0;o>l;l++){var u,c,p,m;s?(u=r,d.push(a(e))):(u=i[l].match(n.regex.findStyles)&&RegExp.$1,d.push(RegExp.$2&&a(RegExp.$2))),p=u.split(","),m=p.length;for(var h=0;m>h;h++)c=p[h],f.push({media:c.split("(")[0].match(n.regex.only)&&RegExp.$2||"all",rules:d.length-1,hasquery:c.indexOf("(")>-1,minw:c.match(n.regex.minw)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:c.match(n.regex.maxw)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}E()},b=function(){if(r.length){var t=r.shift();o(t.href,function(n){S(n,t.href,t.media),m[t.href]=!0,e.setTimeout(function(){b()},0)})}},w=function(){for(var t=0;t - - - - https://witheve.github.io/docs/ - - - - https://witheve.github.io/docs/handbook/core/ - - - - https://witheve.github.io/docs/handbook/intro/ - - - - https://witheve.github.io/docs/handbook/programs/ - - - - https://witheve.github.io/docs/handbook/standard-library/ - - - - https://witheve.github.io/docs/handbook/datetime/ - - - - https://witheve.github.io/docs/ - - - - https://witheve.github.io/docs/guides/for-programmers/ - - - - https://witheve.github.io/docs/handbook/events/ - - - - https://witheve.github.io/docs/handbook/general/ - - - - https://witheve.github.io/docs/handbook/linux/ - - - - https://witheve.github.io/docs/handbook/mac/ - - - - https://witheve.github.io/docs/handbook/math/ - - - - https://witheve.github.io/docs/tutorials/quickstart/ - - - - https://witheve.github.io/docs/handbook/statistics/ - - - - https://witheve.github.io/docs/handbook/strings/ - - - - https://witheve.github.io/docs/guides/style/ - - - - https://witheve.github.io/docs/handbook/windows/ - - - - https://witheve.github.io/docs/handbook/math/abs/ - - - - https://witheve.github.io/docs/handbook/math/ceil/ - - - - https://witheve.github.io/docs/handbook/events/click/ - - - - https://witheve.github.io/docs/handbook/math/cos/ - - - - https://witheve.github.io/docs/handbook/statistics/count/ - - - - https://witheve.github.io/docs/handbook/math/fix/ - - - - https://witheve.github.io/docs/handbook/math/floor/ - - - - https://witheve.github.io/docs/handbook/strings/join/ - - - - https://witheve.github.io/docs/handbook/math/mod/ - - - - https://witheve.github.io/docs/handbook/statistics/random/ - - - - https://witheve.github.io/docs/handbook/math/range/ - - - - https://witheve.github.io/docs/handbook/math/round/ - - - - https://witheve.github.io/docs/handbook/math/sin/ - - - - https://witheve.github.io/docs/handbook/general/sort/ - - - - https://witheve.github.io/docs/handbook/strings/split/ - - - - https://witheve.github.io/docs/handbook/math/sum/ - - - - https://witheve.github.io/docs/handbook/math/tan/ - - - - https://witheve.github.io/docs/handbook/datetime/time/ - - - - https://witheve.github.io/docs/handbook/add/ - - - - https://witheve.github.io/docs/handbook/equality/ - - - - https://witheve.github.io/docs/handbook/functions/ - - - - https://witheve.github.io/docs/handbook/installation/ - - - - https://witheve.github.io/docs/handbook/ebnf/ - - - - https://witheve.github.io/docs/handbook/model/ - - - - https://witheve.github.io/docs/handbook/records/ - - - - https://witheve.github.io/docs/handbook/search/ - - - - https://witheve.github.io/docs/handbook/aggregates/ - - - - https://witheve.github.io/docs/handbook/commonmark/ - - - - https://witheve.github.io/docs/handbook/equivalence/ - - - - https://witheve.github.io/docs/handbook/inequality/ - - - - https://witheve.github.io/docs/handbook/running/ - - - - https://witheve.github.io/docs/handbook/set/ - - - - https://witheve.github.io/docs/handbook/sets/ - - - - https://witheve.github.io/docs/handbook/tags/ - - - - https://witheve.github.io/docs/handbook/bind/ - - - - https://witheve.github.io/docs/handbook/actions/ - - - - https://witheve.github.io/docs/handbook/help/ - - - - https://witheve.github.io/docs/handbook/joins/ - - - - https://witheve.github.io/docs/handbook/literate-programming/ - - - - https://witheve.github.io/docs/handbook/remove/ - - - - https://witheve.github.io/docs/handbook/commit/ - - - - https://witheve.github.io/docs/handbook/if-then/ - - - - https://witheve.github.io/docs/handbook/blocks/ - - - - https://witheve.github.io/docs/handbook/expressions/ - - - - https://witheve.github.io/docs/handbook/merge/ - - - - https://witheve.github.io/docs/handbook/is/ - - - - https://witheve.github.io/docs/handbook/not/ - - - - https://witheve.github.io/docs/handbook/string-interpolation/ - - - - https://witheve.github.io/docs/handbook/update-operators/ - - - - https://witheve.github.io/docs/handbook/databases/ - - - - https://witheve.github.io/docs/handbook/glossary/ - - - \ No newline at end of file diff --git a/src/handbook/databases.md b/src/handbook/databases.md deleted file mode 100644 index 9e22be8..0000000 --- a/src/handbook/databases.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -menu: - main: - parent: "Core Language" -title: "Databases" -weight: 6 ---- - -# Databases - -databases contain records - -## Syntax - -```eve -// search action -search @database1, ..., @databaseN - -// Commit action -commit @database1, ..., @databaseN - -// Bind action -bind @database1, ..., @databaseN -``` - -## Description - -` @database` performs the given action, one of `search`, `bind`, or `commit`, on the union of the provided databases. - -If no database is provided with an action, then that action is performed on the default `@session` database. - -## Special Databases - -- `@session` - the default database, stores any record not associated explicitly with a database - -- `@event` - holds records generated by user events in the DOM - -- `@browser` - records stored in `@browser` are rendered as HTML by the browser - -## Examples - -Display a message when the DOM is clicked - -```eve -search @event - [#click #direct-target element] - -commit @browser - [#div text: "{{element}} was clicked."] -``` - -## See Also - -[search](../search) | [bind](../bind) | [commit](../commit) \ No newline at end of file diff --git a/src/handbook/events/index.md b/src/handbook/events/index.md deleted file mode 100644 index 477274f..0000000 --- a/src/handbook/events/index.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -menu: - main: - parent: "Standard Library" -title: "Events" ---- - -# Events - -[click](click) - a left-button mouse click event \ No newline at end of file diff --git a/src/handbook/installation.md b/src/handbook/installation.md deleted file mode 100644 index 8020342..0000000 --- a/src/handbook/installation.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -menu: - main: - parent: "Introduction" -title: "Getting Eve" -weight: 1 ---- - -## See Also - -[linux](../linux) | [mac](../mac) | [windows](../windows) | [running](../running) diff --git a/src/handbook/linux.md b/src/handbook/linux.md deleted file mode 100644 index cada650..0000000 --- a/src/handbook/linux.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -menu: - main: - parent: "Getting Eve" -title: "Linux" ---- - -# Installing Eve on Linux - -First, [download](https://github.com/witheve/Eve/archive/master.zip) the Eve source. You'll need a recent [node.js](https://nodejs.org) and then and then in the extracted Eve directory: - -``` -npm install -npm start -``` - -Then open `http://localhost:8080/` in your browser. - -## See also - -[mac](../mac) | [windows](../windows) | [running](../running) \ No newline at end of file diff --git a/src/handbook/math/sum.md b/src/handbook/math/sum.md deleted file mode 100644 index 9c2d9e7..0000000 --- a/src/handbook/math/sum.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -menu: - main: - parent: "Math" -title: "sum" ---- - -# sum - -Sum the elements in a set - -## Syntax - -```eve -y = sum[given] -y = sum[given, per] -``` - -## Arguments - -- `given` - the variable to be summed -- `per` - _optional_ - specifies the set over which you are summing - -## Description - -`y = sum[given]` returns the sum of elements in a set. The set must be entirely numeric or a runtime-error occurs. - -## Examples - -```eve -search @test-data - [#employee salary department] - department-salary-budgets = sum[given: salary, per: department] - -bind @browser - [#div text: "{{ department }}: {{ department-salary-budgets }}"] -``` - -## See Also - -[count](../../statistics/count) | [aggregates](../../aggregates) \ No newline at end of file diff --git a/src/handbook/running.md b/src/handbook/running.md deleted file mode 100644 index f0c33a0..0000000 --- a/src/handbook/running.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -menu: - main: - parent: "Introduction" -title: "Running Eve" -weight: 2 ---- - -# Running Eve - -In the extract Eve directory, Running - -``` -npm start -``` - -Then direct your browser to `http://localhost:8080` - -## See Also - -[linux](../linux) | [mac](../mac) | [windows](../windows) | [docker](../docker) \ No newline at end of file diff --git a/src/handbook/strings/index.md b/src/handbook/strings/index.md deleted file mode 100644 index 62e0cc9..0000000 --- a/src/handbook/strings/index.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -menu: - main: - parent: "Standard Library" -title: "Strings" ---- - -# Strings - -- [length](length) -- [concatenate](concat) -- [replace](replace) -- [split](split) -- [join](join) \ No newline at end of file diff --git a/src/handbook/strings/join.md b/src/handbook/strings/join.md deleted file mode 100644 index 6db6dc3..0000000 --- a/src/handbook/strings/join.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -menu: - main: - parent: "Strings" -title: "join" ---- - -# join - -Joins a set of strings into a single string - -## Syntax - -```eve -text = join[token, index, with] -``` - -## Attributes - -- `token` - set of elements to be joined -- `index` - indicates the order of the `tokens` in the joined string -- `with` - inserted between every element in `tokens` - -## Description - -`text = join[token, index, with]` takes `tokens` tokens together using `with` in an order specified by `index`. Returns the joined string. - -## Examples - -Split a sentence into tokens - -```eve -search - (token, index) = split[text: "the quick brown fox", by: " "] - -bind - [#token token index] -``` - -Join the tokens into a sentence again, but with hyphens instead of spaces - -```eve -search - [#token token index] - text = join[token, index, with: " "] - -bind - [#div text] // Expected "the-quick-brown-fox" -``` - -## See Also - -[join](../join) | [split](../split) | [char-at](../char-at) | [find](../find) | [length](../length) | [replace](../replace) \ No newline at end of file diff --git a/stylesheets/application.css b/stylesheets/application.css deleted file mode 100644 index 119f9e1..0000000 --- a/stylesheets/application.css +++ /dev/null @@ -1,211 +0,0 @@ -#eve-pallette { - /* Default */ - color: rgb(74,64,136); - color: rgb(91,89,164); - color: rgb(107,103,173); - color: rgb(0,121,177); - color: rgb(0,158,224); - color: rgb(0,184,241); - - /* Style 1 */ - color: rgb(0, 115, 139); - color: rgb(0, 152, 167); - color: rgb(0, 171, 188); - color: rgb(140, 49, 55); - color: rgb(177, 67, 73); - color: rgb(226, 79, 94); - - /* Style 2 */ - color: rgb(85, 138, 126); - color: rgb(113, 177, 162); - color: rgb(128, 198, 182); - color: rgb(153, 114, 45); - color: rgb(198, 154, 63); - color: rgb(246, 192, 78); - - /* Style 3 */ - color: rgb(82, 129, 62); - color: rgb(111, 165, 81); - color: rgb(129, 191, 95); - color: rgb(0, 113, 140); - color: rgb(0, 151, 167); - color: rgb(0, 170, 190); - - /* Style 4 */ - color: rgb(60, 48, 130); - color: rgb(80, 79, 161); - color: rgb(98, 94, 169); - color: rgb(158, 34, 101); - color: rgb(216, 65, 140); - color: rgb(238, 81, 158); - - /* Style 5 */ - color: rgb(185, 73, 21); - color: rgb(216, 99, 27); - color: rgb(244, 119, 33); - color: rgb(197, 114, 21); - color: rgb(248, 158, 36); - color: rgb(251, 176, 49); - - /* Style 6 */ - color: rgb(124, 38, 118); - color: rgb(169, 59, 150); - color: rgb(200, 56, 150); - color: rgb(91, 34, 127); - color: rgb(126, 60, 151); - color: rgb(164, 95, 167); - - /* Style 7 */ - color: rgb(151, 150, 137); - color: rgb(183, 182, 167); - color: rgb(204, 202, 185); - color: rgb(88, 132, 150); - color: rgb(123, 164, 182); - color: rgb(145, 192, 214); -} - -html, body { - font-family: Avenir, "Nelvetica Neue", sans-serif; - height: 100%; - padding: 0px; - margin: 0px; - color: rgb(85,85,85); - font-size: 15px; - background-color: #f5f5f5; -} - -pre { - background-color: rgb(38,38,38); - padding: 20px; - padding-left: 10px; - overflow: auto; -} - -code { - color: rgb(0, 121, 211); -} - -blockquote { - color: rgb(125,125,125); - border-left: 3px solid rgb(200,200,200); - padding-left: 10px; -} - -p { - line-height: 25px; -} - -ul, ol { - line-height: 25px; -} - -h1 { - font-size: 30px; - color: rgb(85, 85, 85); -} - -h2 { - font-size: 25px; - color: rgb(85, 85, 85); - font-weight: bold; - line-height: 25px; -} - -.logo { - width: 30%; - margin-top: 20px; - margin-bottom: 20px; -} - -.main { - display: flex; - align-items: stretch; - min-height: 100%; -} - -.drawer { - background-color: #555; - color: rgb(187,187,187); - width: 280px; - padding-left: 10px; - padding-right: 10px; - padding-bottom: 20px; -} - -.drawer a { - color: rgb(187,187,187); -} - -.article { - max-width: 750px; - padding-left: 60px; - padding-right: 60px; - padding-top: 30px; - background-color: white; -} - -.article a { - color: rgb(0,158,224); -} - -.article a::hover { - color: rgb(91,89,164); -} - -.sidebar-menu { - list-style: none; - margin: 0px; - padding: 0px; -} - -.sidebar-menu a { - text-decoration: none; -} - -.sidebar-menu li { - -} - -.sub { - margin: 0px; - padding: 0px; - padding-left: 20px; -} - -.sub-menu { - margin-top: 20px; -} - -.colored { - color: #eee; -} - -.selected a { - color: rgb(145, 192, 214); -} - -.active { - -} - -.active li { - display: inherit; -} - -.dataTable { - border: 1px solid #000; - border-collapse: collapse; - width: 100%; -} - -.dataTable th { - font-weight: bold; - border: 1px solid #000; -} - -.dataTable td { - border: 1px solid #000; - white-space: pre; - font-family: monospace; - padding: 5px; -} \ No newline at end of file diff --git a/stylesheets/highlight/highlight.css b/stylesheets/highlight/highlight.css deleted file mode 100644 index 7255fa6..0000000 --- a/stylesheets/highlight/highlight.css +++ /dev/null @@ -1,46 +0,0 @@ -.article pre { - color: black; - background-color: #f5f5f5; - border-left: 5px solid rgb(234, 234, 234); - padding-left: 15px; -} - -.kr { - color: black; -} - -.c1 { - color: #747474; -} - -.nt { - color: rgb(0, 118, 206); -} - -.s { - color: rgb(1, 165, 136); -} - -.m { - color: rgb(1, 165, 136); -} - -.l { - color: rgb(1, 165, 136); -} - -.p { - color: gray; -} - -.nf { - color: rgb(128, 128, 128); -} - -.s2 { - color: rgb(1, 165, 136); -} - -.x { - color: rgb(0, 0, 0); -} \ No newline at end of file diff --git a/tutorials/index.html b/tutorials/index.html deleted file mode 100644 index 944f660..0000000 --- a/tutorials/index.html +++ /dev/null @@ -1,406 +0,0 @@ - - - - - - - - - - - - Tutorials - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
- - -
diff --git a/tutorials/index.xml b/tutorials/index.xml deleted file mode 100644 index 6777f33..0000000 --- a/tutorials/index.xml +++ /dev/null @@ -1,248 +0,0 @@ - - - - Tutorials on Eve Documentation - https://witheve.github.io/docs/tutorials/ - Recent content in Tutorials on Eve Documentation - Hugo -- gohugo.io - en-us - - - - Quickstart - https://witheve.github.io/docs/tutorials/quickstart/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://witheve.github.io/docs/tutorials/quickstart/ - - -<h1 id="eve-quick-start-tutorial">Eve Quick Start Tutorial</h1> -<div class="highlight"><pre><code class="language-eve" data-lang="eve"><span></span><span class="x">```</span><span class="w"></span> -<span class="kr">bind</span><span class="w"> </span><span class="nt">@browser</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="p">[</span><span class="x">tag</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;div&quot;</span><span class="p">,</span><span class="w"> </span><span class="x">text</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;Hello, world&quot;</span><span class="p">]</span><span class="w"></span> -<span class="x">```</span><span class="w"></span> -</code></pre></div> - -<p>Hello world! At its core, Eve is a pattern matching language. You match patterns of data by searching a database, then update or create new data according to what you&rsquo;ve found. In this example, we created a <a href="https://witheve.github.io/docs/handbook/records/"><code>record</code></a> that has two attributes: a tag attribute with the value <code>&quot;div&quot;</code>, and a text attribute with the value <code>&quot;Hello, world&quot;</code>. We <a href="https://witheve.github.io/docs/handbook/bind/">bound</a> this record to the browser, which is how we displayed our venerable message.</p> - -<p>The three backticks <code>```</code> are called a code fence, and they allow us to denote blocks of code. This gives us the ability to embed Eve code in normal documents written in Markdown. This is how Eve programs are written: everything in a code fence is a <a href="https://witheve.github.io/docs/handbook/blocks/">block</a> of Eve code, while everything outside is prose describing the program. In fact, this quick start tutorial is an example of an executable Eve program! In the subsequent blocks, you won&rsquo;t see any code fences, but they still exist in the <a href="https://raw.githubusercontent.com/witheve/docs/src/guides/quickstart.md">document&rsquo;s source</a>.</p> - -<p>So far we&rsquo;ve created a record that displays “Hello, world!” but as I said, Eve is a pattern matching language. Let&rsquo;s explore that by searching for something:</p> -<div class="highlight"><pre><code class="language-eve" data-lang="eve"><span></span><span class="kr">search</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="p">[</span><span class="x">name</span><span class="p">]</span><span class="w"></span> - -<span class="kr">bind</span><span class="w"> </span><span class="nt">@browser</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="p">[</span><span class="x">tag</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;div&quot;</span><span class="p">,</span><span class="w"> </span><span class="x">text</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;Hello, world&quot;</span><span class="p">]</span><span class="w"></span> -</code></pre></div> - -<p>Our message disappeared! Before, we bound without searching, so the message displayed by default. Now we&rsquo;re binding in the presence of a <a href="https://witheve.github.io/docs/handbook/search/"><code>search</code></a> action, so the bound record only exists if all the searched records are matched. Here, we&rsquo;re searching for all records with a <code>name</code> attribute, but we haven&rsquo;t added any records like that to Eve so none are matched. With no matching records, the <code>bind</code> cannot execute, and the message disappears from the screen.</p> - -<p>This is the flow of an Eve block: you search for records in a database, and if all the records you searched for are matched, you can modify the matched records or create new ones. If any part of your search is not matched, then no records will be created or updated.</p> - -<p>To get our message back, all we need is a record with a name attribute. We can create one permanently with the <a href="https://witheve.github.io/docs/handbook/commit/"><code>commit</code></a> action:</p> -<div class="highlight"><pre><code class="language-eve" data-lang="eve"><span></span><span class="kr">commit</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="p">[</span><span class="x">name</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;Celia&quot;</span><span class="p">]</span><span class="w"></span> -</code></pre></div> - -<p>Hello, world… again! Commit permanently updates or creates a record that will persist even if its matched records (the records matched in a search action) change. Since we aren&rsquo;t searching for anything in this block, the commit executes by default and adds a record with a name attribute of <code>&quot;Celia&quot;</code>. The addition of this new record satisfies the search in the previous block, so “Hello, world!” appears on the screen again.</p> - -<p>But what else can you do with matched records? For starters, we can use them to create new records:</p> -<div class="highlight"><pre><code class="language-eve" data-lang="eve"><span></span><span class="kr">search</span><span class="w"></span> -<span class="w"> </span><span class="p">[</span><span class="x">name</span><span class="p">]</span><span class="w"></span> - -<span class="kr">bind</span><span class="w"> </span><span class="nt">@browser</span><span class="w"></span> -<span class="w"> </span><span class="p">[</span><span class="nt">#div</span><span class="p">,</span><span class="w"> </span><span class="x">text</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;Hello, {{name}}&quot;</span><span class="p">]</span><span class="w"></span> -</code></pre></div> - -<p>Since we matched on a record with a name attribute, we now have a reference to that name, and we can inject it into a string using <a href="https://witheve.github.io/docs/handbook/string-interpolation/"><code>{{ ... }}</code></a> embedding. We can also swap out <code>tag: &quot;div&quot;</code> for the sugared <code>#div</code>. <a href="https://witheve.github.io/docs/handbook/tags/">Tags</a> are used a lot in Eve to talk about collections of related records. For example, we could search for all records with a <code>#student</code> tag, with name, grade, and school attributes.</p> -<div class="highlight"><pre><code class="language-eve" data-lang="eve"><span></span><span class="kr">search</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="p">[</span><span class="nt">#student</span><span class="w"> </span><span class="x">name</span><span class="w"> </span><span class="x">grade</span><span class="w"> </span><span class="x">school</span><span class="p">]</span><span class="w"></span> - -<span class="kr">bind</span><span class="w"> </span><span class="nt">@browser</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="p">[</span><span class="nt">#div</span><span class="w"> </span><span class="x">text</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;{{name}} is a {{grade}}th grade student at {{school}}.&quot;</span><span class="p">]</span><span class="w"></span> -</code></pre></div> - -<p>Since we&rsquo;re matching on more attributes, this block is no longer satisfied by the record we added earlier; we&rsquo;re missing a <code>#student</code> tag, as well as grade and school attributes. Even though these are currently missing, we can still write the code that would display them.</p> - -<p>Let&rsquo;s display this new message by adding the missing attributes to Celia. We could add them to the block where we comitted Celia originally, but we can also do it programatically:</p> -<div class="highlight"><pre><code class="language-eve" data-lang="eve"><span></span><span class="kr">search</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="x">celia</span><span class="w"> </span><span class="nf">=</span><span class="w"> </span><span class="p">[</span><span class="x">name</span><span class="nf">:</span><span class="w"> </span><span class="x">“Celia”</span><span class="p">]</span><span class="w"></span> - -<span class="kr">bind</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="x">celia</span><span class="w"> </span><span class="nf">&lt;-</span><span class="w"> </span><span class="p">[</span><span class="nt">#student</span><span class="w"> </span><span class="x">grade</span><span class="nf">:</span><span class="w"> </span><span class="m">10</span><span class="p">,</span><span class="w"> </span><span class="x">school</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;East&quot;</span><span class="p">,</span><span class="w"> </span><span class="x">age</span><span class="nf">:</span><span class="w"> </span><span class="m">16</span><span class="p">]</span><span class="w"></span> -</code></pre></div> - -<p>You can define variables within blocks, which act as handles on records that allow you to change them. In this case, we&rsquo;re using the <a href="https://witheve.github.io/docs/handbook/merge/">merge operator</a> <code>&lt;-</code> to combine two records. With the addition of this block, the sentence &ldquo;Celia is a 10th grade student at East.&rdquo; appears in the browser.</p> - -<p>Celia is cool and all, but let&rsquo;s add some more students to our database:</p> -<div class="highlight"><pre><code class="language-eve" data-lang="eve"><span></span><span class="kr">commit</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="p">[</span><span class="nt">#student</span><span class="w"> </span><span class="x">name</span><span class="nf">:</span><span class="w"> </span><span class="x">“Diedra”</span><span class="p">,</span><span class="w"> </span><span class="x">grade</span><span class="nf">:</span><span class="w"> </span><span class="m">12</span><span class="p">,</span><span class="w"> </span><span class="x">school</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;West&quot;</span><span class="p">]</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="p">[</span><span class="nt">#student</span><span class="w"> </span><span class="x">name</span><span class="nf">:</span><span class="w"> </span><span class="x">“Michelle”</span><span class="p">,</span><span class="w"> </span><span class="x">grade</span><span class="nf">:</span><span class="w"> </span><span class="m">11</span><span class="p">,</span><span class="w"> </span><span class="x">school</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;West&quot;</span><span class="p">]</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="p">[</span><span class="nt">#student</span><span class="w"> </span><span class="x">name</span><span class="nf">:</span><span class="w"> </span><span class="x">“Jermaine”</span><span class="p">,</span><span class="w"> </span><span class="x">grade</span><span class="nf">:</span><span class="w"> </span><span class="m">9</span><span class="p">]</span><span class="w"></span> -</code></pre></div> - -<p>Three sentences are now printed, one for each student that matches the search. Eve works on <a href="https://witheve.github.io/docs/handbook/sets/">sets</a>, so when we search for <code>[#student name grade school]</code>, we find <em>all</em> records that match the given pattern. This includes Celia, Diedra and Michelle (but not Jermaine, as he has no school in his record). Therefore, when we bind the record <code>[#div text: &quot;{{name}} is a ... &quot;]</code>, we are actually binding three records, one for each matching <code>#student</code>.</p> - -<p>If you re-compile the program a couple times, you&rsquo;ll see the order of sentences may change. This is because <strong>there is no ordering in Eve - blocks are not ordered, statements are not ordered, and results are not ordered</strong>. If you want to order elements, you must impose an ordering yourself. We can ask the browser to draw elements in an order with the &ldquo;sort&rdquo; attribute:</p> -<div class="highlight"><pre><code class="language-eve" data-lang="eve"><span></span><span class="kr">search</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="p">[</span><span class="nt">#student</span><span class="w"> </span><span class="x">name</span><span class="w"> </span><span class="x">grade</span><span class="w"> </span><span class="x">school</span><span class="p">]</span><span class="w"></span> - -<span class="kr">bind</span><span class="w"> </span><span class="nt">@browser</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="p">[</span><span class="nt">#div</span><span class="w"> </span><span class="x">sort</span><span class="nf">:</span><span class="w"> </span><span class="x">name</span><span class="p">,</span><span class="w"> </span><span class="x">text</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;{{name}} is a {{grade}}th grade student at {{school}}.&quot;</span><span class="p">]</span><span class="w"></span> -</code></pre></div> - -<p>This time when you recompile your program, the order will stay fixed, sorted alphabetically by name.</p> - -<p>Let&rsquo;s make things a little more interesting by adding some records about the schools the students attend:</p> -<div class="highlight"><pre><code class="language-eve" data-lang="eve"><span></span><span class="kr">commit</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="p">[</span><span class="nt">#school</span><span class="w"> </span><span class="x">name</span><span class="nf">:</span><span class="w"> </span><span class="x">“West”</span><span class="p">,</span><span class="w"> </span><span class="x">address</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;1234 Main Street&quot;</span><span class="p">]</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="p">[</span><span class="nt">#school</span><span class="w"> </span><span class="x">name</span><span class="nf">:</span><span class="w"> </span><span class="x">“East”</span><span class="p">,</span><span class="w"> </span><span class="x">address</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;5678 Broad Street&quot;</span><span class="p">]</span><span class="w"></span> -</code></pre></div> - -<p>What if we want to display the address of the school each student attends? Although <code>#student</code>s and <code>#school</code>s are in different records, <strong>we can relate two records by associating attributes from one record with attributes from the other.</strong> This is an operation known as <a href="https://witheve.github.io/docs/handbook/joins/">joining</a>. In this case, we want to relate the <code>name</code> attribute on <code>#schools</code> with the <code>school</code> attribute on <code>#students</code>. This compares the values of the attributes between records, and matches up those with the same value. For instance, since Celia&rsquo;s school is &ldquo;East&rdquo;, she can join with the <code>#school</code> named &ldquo;East&rdquo;.</p> - -<p>Our first attempt may come out looking a little something like this:</p> -<div class="highlight"><pre><code class="language-eve" data-lang="eve"><span></span><span class="kr">search</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="x">school</span><span class="w"> </span><span class="nf">=</span><span class="w"> </span><span class="p">[</span><span class="nt">#school</span><span class="w"> </span><span class="x">name</span><span class="w"> </span><span class="x">address</span><span class="p">]</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="x">student</span><span class="w"> </span><span class="nf">=</span><span class="w"> </span><span class="p">[</span><span class="nt">#student</span><span class="w"> </span><span class="x">name</span><span class="w"> </span><span class="x">school</span><span class="nf">:</span><span class="w"> </span><span class="x">name</span><span class="p">]</span><span class="w"> </span> - -<span class="kr">bind</span><span class="w"> </span><span class="nt">@browser</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="p">[</span><span class="nt">#div</span><span class="w"> </span><span class="x">text</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;{{student.name}} attends {{school.name}} at {{address}}&quot;</span><span class="p">]</span><span class="w"></span> -</code></pre></div> - -<p>But that didn&rsquo;t work. How come? In Eve, <strong>things with the same name are <a href="https://witheve.github.io/docs/handbook/equivalence/">equivalent</a></strong>. In this block, we&rsquo;ve used &ldquo;name&rdquo; three times, which says that the school&rsquo;s name, the student&rsquo;s name, and the student&rsquo;s school are all the same. Of course, there is no combination of students and schools that match this search, so nothing is displayed.</p> - -<p>Instead, we can use the dot operator to specifically ask for the name attribute in the <code>#school</code> records, and rename our variables to get a correct block:</p> -<div class="highlight"><pre><code class="language-eve" data-lang="eve"><span></span><span class="kr">search</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="x">schools</span><span class="w"> </span><span class="nf">=</span><span class="w"> </span><span class="p">[</span><span class="nt">#school</span><span class="w"> </span><span class="x">address</span><span class="p">]</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="x">students</span><span class="w"> </span><span class="nf">=</span><span class="w"> </span><span class="p">[</span><span class="nt">#student</span><span class="w"> </span><span class="x">school</span><span class="nf">:</span><span class="w"> </span><span class="x">school.name</span><span class="p">]</span><span class="w"></span> - -<span class="kr">bind</span><span class="w"> </span><span class="nt">@browser</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="p">[</span><span class="nt">#div</span><span class="w"> </span><span class="x">text</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;{{students.name}} attends {{schools.name}} at {{address}}&quot;</span><span class="p">]</span><span class="w"></span> -</code></pre></div> - -<p>This creates an implicit join over the school name without mixing up the names of the students and the names of the schools, giving us our desired output. You can actually bind attributes to any name you want to avoid collisions in a block:</p> -<div class="highlight"><pre><code class="language-eve" data-lang="eve"><span></span><span class="kr">search</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="p">[</span><span class="nt">#school</span><span class="w"> </span><span class="x">name</span><span class="nf">:</span><span class="w"> </span><span class="x">school</span><span class="nf">-</span><span class="x">name</span><span class="w"> </span><span class="x">address</span><span class="p">]</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="p">[</span><span class="nt">#student</span><span class="w"> </span><span class="x">name</span><span class="nf">:</span><span class="w"> </span><span class="x">student</span><span class="nf">-</span><span class="x">name</span><span class="w"> </span><span class="x">school</span><span class="nf">:</span><span class="w"> </span><span class="x">school</span><span class="nf">-</span><span class="x">name</span><span class="p">]</span><span class="w"></span> - -<span class="kr">bind</span><span class="w"> </span><span class="nt">@browser</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="p">[</span><span class="nt">#div</span><span class="w"> </span><span class="x">text</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;{{student-name}} attends {{school-name}} at {{address}}&quot;</span><span class="p">]</span><span class="w"></span> -</code></pre></div> - -<h2 id="advanced-eve">Advanced Eve</h2> - -<p>Recall when we added our students, Celia was the only one we added an <code>age</code> to. Therefore, the following block only displays Celia&rsquo;s age, even though we ask for all the <code>#student</code>s:</p> -<div class="highlight"><pre><code class="language-eve" data-lang="eve"><span></span><span class="kr">search</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="p">[</span><span class="nt">#student</span><span class="w"> </span><span class="x">name</span><span class="w"> </span><span class="x">age</span><span class="p">]</span><span class="w"></span> - -<span class="kr">bind</span><span class="w"> </span><span class="nt">@browser</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="p">[</span><span class="nt">#div</span><span class="w"> </span><span class="x">text</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;{{name}} is {{age}} years old&quot;</span><span class="p">]</span><span class="w"></span> -</code></pre></div> - -<p>Let&rsquo;s pretend that all students enter first grade at six years old. Therefore, if we know a student&rsquo;s grade, we can calculate their age and add it to the student&rsquo;s record:</p> -<div class="highlight"><pre><code class="language-eve" data-lang="eve"><span></span><span class="kr">search</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="x">student</span><span class="w"> </span><span class="nf">=</span><span class="w"> </span><span class="p">[</span><span class="nt">#student</span><span class="p">]</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="x">calculated</span><span class="nf">-</span><span class="x">age</span><span class="w"> </span><span class="nf">=</span><span class="w"> </span><span class="kr">if</span><span class="w"> </span><span class="x">student.age</span><span class="w"> </span><span class="kr">then</span><span class="w"> </span><span class="x">student.age</span><span class="w"></span> -<span class="x">                  </span><span class="w"> </span><span class="kr">else</span><span class="w"> </span><span class="kr">if</span><span class="w"> </span><span class="x">student.grade</span><span class="w"> </span><span class="kr">then</span><span class="w"> </span><span class="x">student.grade</span><span class="w"> </span><span class="nf">+</span><span class="w"> </span><span class="m">5</span><span class="w"></span> - -<span class="kr">bind</span><span class="w"> </span><span class="nt">@browser</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="x">student.age</span><span class="w"> </span><span class="nf">:=</span><span class="w"> </span><span class="x">calculated</span><span class="nf">-</span><span class="x">age</span><span class="w"></span> -</code></pre></div> - -<p>This block selects all students, and uses and <a href="https://witheve.github.io/docs/handbook/if-then/"><code>if-then</code></a> expression to set the student&rsquo;s calculated age. If the student already has an age, we set it to that. Otherwise, if the student has no age, we can calculate it with some arithmetic. The <a href="https://witheve.github.io/docs/handbook/set/">set operator</a> <code>:=</code> sets an attribute to a specified value regardless of what it was before the block executed. That value can be anything, from a number to a string to another record.</p> - -<h3 id="aggregates">Aggregates</h3> - -<p>So far everything we&rsquo;ve done has used one record at a time, but what happens when we want to work over a group of records, such as counting how many students there are? To solve such a problem, we&rsquo;ll need to use an <a href="https://witheve.github.io/docs/handbook/aggregates/">aggregate</a>. Aggregates take a set of values and turn them into a single value, akin to &ldquo;fold&rdquo; or &ldquo;reduce&rdquo; functions in other languages. In this case, we&rsquo;ll use the aggregate <a href="https://witheve.github.io/docs/handbook/statistics/count/"><code>count</code></a> to figure out how many <code>#students</code> are in the school district:  </p> -<div class="highlight"><pre><code class="language-eve" data-lang="eve"><span></span><span class="kr">search</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="x">students</span><span class="w"> </span><span class="nf">=</span><span class="w"> </span><span class="p">[</span><span class="nt">#student</span><span class="p">]</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="x">total</span><span class="nf">-</span><span class="x">students</span><span class="w"> </span><span class="nf">=</span><span class="w"> </span><span class="x">count</span><span class="p">[</span><span class="x">given</span><span class="nf">:</span><span class="w"> </span><span class="x">students</span><span class="p">]</span><span class="w"></span> - -<span class="kr">bind</span><span class="w"> </span> -<span class="x"> </span><span class="w"> </span><span class="p">[</span><span class="nt">#div</span><span class="w"> </span><span class="x">text</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;{{total-students}} are in the school district&quot;</span><span class="p">]</span><span class="w"></span> -</code></pre></div> - -<p>A quick note on the syntax for <code>count</code> - it feels a lot like a function in other languages, since it has a return value and can be used inline in expressions. Under the hood, <a href="https://witheve.github.io/docs/handbook/functions/">functions</a> and aggregates are actually records; <code>total = count[given: students]</code> is shorthand for <code>[#count #function given: students, value: total]</code>. This distinction won&rsquo;t materially change the way you use <code>count</code>, but it goes to show that everything in Eve reduces to working with records.</p> - -<p>While <code>given</code> is a required argument in <code>count</code>, aggregates (and functions in general) can also have optional arguments. Let&rsquo;s say we want to know how many students attend each school. We can use the optional argument <code>per</code> to count students grouped by the school they attend:</p> -<div class="highlight"><pre><code class="language-eve" data-lang="eve"><span></span><span class="kr">search</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="x">students</span><span class="w"> </span><span class="nf">=</span><span class="w"> </span><span class="p">[</span><span class="nt">#student</span><span class="w"> </span><span class="x">school</span><span class="p">]</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="x">students</span><span class="nf">-</span><span class="x">per</span><span class="nf">-</span><span class="x">school</span><span class="w"> </span><span class="nf">=</span><span class="w"> </span><span class="x">count</span><span class="p">[</span><span class="x">given</span><span class="nf">:</span><span class="w"> </span><span class="x">students</span><span class="p">,</span><span class="w"> </span><span class="x">per</span><span class="nf">:</span><span class="w"> </span><span class="x">school</span><span class="p">]</span><span class="w"></span> - -<span class="kr">bind</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="p">[</span><span class="nt">#div</span><span class="w"> </span><span class="x">text</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;{{students-per-school}} attend {{school}}&quot;</span><span class="p">]</span><span class="w"></span> -</code></pre></div> - -<p>All function-like records in Eve specify their arguments as attributes. This means you specify the argument and its value, unlike in other languages, where the order of the values determines the attribute to which they belong. As with everything else in Eve, order doesn&rsquo;t matter.</p> - -<h2 id="extra-credit">Extra Credit</h2> - -<p>At this point, you know everything necessary about Eve to complete this extra credit portion (the only additional knowledge you need is domain knowledge of HTML and forms). Let&rsquo;s review some of the key concepts:</p> - -<ul> -<li>Eve programs are composed of blocks of code that search for and update records.</li> -<li>Records are sets of <code>attribute: value</code> pairs attached to a unique ID.</li> -<li>Eve works with sets, which have no ordering and contain unique elements.</li> -<li>Things with the same name are equivalent.</li> -</ul> - -<p>Your extra credit task is to build a web-based form that allows you to add students to the database. Take a moment to think about how this might be done in Eve, given everything we&rsquo;ve learned so far.</p> - -<p>First, let&rsquo;s make the form. We&rsquo;ve already displayed a <code>#div</code>, and in the same way we can draw <code>#input</code>s and a <code>#button</code>:</p> -<div class="highlight"><pre><code class="language-eve" data-lang="eve"><span></span><span class="kr">bind</span><span class="w"> </span><span class="nt">@browser</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="p">[</span><span class="nt">#div</span><span class="w"> </span><span class="x">children</span><span class="nf">:</span><span class="w"> </span> -<span class="x">   </span><span class="w"> </span><span class="p">[</span><span class="nt">#div</span><span class="w"> </span><span class="x">sort</span><span class="nf">:</span><span class="w"> </span><span class="m">1</span><span class="p">,</span><span class="w"> </span><span class="x">text</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;Name:&quot;</span><span class="p">]</span><span class="w"></span> -<span class="x">   </span><span class="w"> </span><span class="p">[</span><span class="nt">#input</span><span class="w"> </span><span class="nt">#name-input</span><span class="w"> </span><span class="x">sort</span><span class="nf">:</span><span class="w"> </span><span class="m">2</span><span class="p">]</span><span class="w"></span> -<span class="x">   </span><span class="w"> </span><span class="p">[</span><span class="nt">#div</span><span class="w"> </span><span class="x">sort</span><span class="nf">:</span><span class="w"> </span><span class="m">3</span><span class="p">,</span><span class="w"> </span><span class="x">text</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;Grade:&quot;</span><span class="p">]</span><span class="w"></span> -<span class="x">   </span><span class="w"> </span><span class="p">[</span><span class="nt">#input</span><span class="w"> </span><span class="nt">#grade-input</span><span class="w"> </span><span class="x">sort</span><span class="nf">:</span><span class="w"> </span><span class="m">4</span><span class="p">]</span><span class="w"></span> -<span class="x">   </span><span class="w"> </span><span class="p">[</span><span class="nt">#div</span><span class="w"> </span><span class="x">sort</span><span class="nf">:</span><span class="w"> </span><span class="m">5</span><span class="p">,</span><span class="w"> </span><span class="x">text</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;School:&quot;</span><span class="p">]</span><span class="w"></span> -<span class="x">   </span><span class="w"> </span><span class="p">[</span><span class="nt">#input</span><span class="w"> </span><span class="nt">#school-input</span><span class="w"> </span><span class="x">sort</span><span class="nf">:</span><span class="w"> </span><span class="m">6</span><span class="p">]</span><span class="w"></span> -<span class="x">   </span><span class="w"> </span><span class="p">[</span><span class="nt">#button</span><span class="w"> </span><span class="nt">#submit</span><span class="w"> </span><span class="x">sort</span><span class="nf">:</span><span class="w"> </span><span class="m">7</span><span class="w"> </span><span class="x">text</span><span class="nf">:</span><span class="w"> </span><span class="s">&quot;submit&quot;</span><span class="p">]]</span><span class="w"></span> -</code></pre></div> - -<p>We&rsquo;ve added some tags to the inputs and the button to distinguish them, so we can easily search for them from other blocks. Now that we have a form, we need to define what happens when the submit button is clicked.</p> - -<p>Remember, everything in Eve is a record, so the <code>#click</code> event is no different. When a user clicks the mouse in the browser, Eve records that click in the database.</p> - -<p>This record exists only for an instant, but we can react to it by searching for <code>[#click element: [#submit]]</code>. This record represents a <code>#click</code> on our <code>#submit</code> button. Then, all we need to do is capture the values of the input boxes and save them as a <code>#student</code> record:</p> -<div class="highlight"><pre><code class="language-eve" data-lang="eve"><span></span><span class="kr">search</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="p">[</span><span class="nt">#click</span><span class="w"> </span><span class="x">element</span><span class="nf">:</span><span class="w"> </span><span class="p">[</span><span class="nt">#submit</span><span class="p">]]</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="x">name</span><span class="w"> </span><span class="nf">=</span><span class="w"> </span><span class="p">[</span><span class="nt">#name-input</span><span class="p">]</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="x">grade</span><span class="w"> </span><span class="nf">=</span><span class="w"> </span><span class="p">[</span><span class="nt">#grade-input</span><span class="p">]</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="x">school</span><span class="w"> </span><span class="nf">=</span><span class="w"> </span><span class="p">[</span><span class="nt">#school-input</span><span class="p">]</span><span class="w"></span> - -<span class="kr">commit</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="c1">// save the new student</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="p">[</span><span class="nt">#student</span><span class="w"> </span><span class="x">name</span><span class="nf">:</span><span class="w"> </span><span class="x">name.value</span><span class="p">,</span><span class="w"> </span><span class="x">grade</span><span class="nf">:</span><span class="w"> </span><span class="x">grade.value</span><span class="p">,</span><span class="w"> </span><span class="x">school</span><span class="nf">:</span><span class="w"> </span><span class="x">school.value</span><span class="p">]</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="c1">// reset the form</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="x">name.value</span><span class="w"> </span><span class="nf">:=</span><span class="w"> </span><span class="s">&quot;&quot;</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="x">grade.value</span><span class="w"> </span><span class="nf">:=</span><span class="w"> </span><span class="s">&quot;&quot;</span><span class="w"></span> -<span class="x"> </span><span class="w"> </span><span class="x">school.value</span><span class="w"> </span><span class="nf">:=</span><span class="w"> </span><span class="s">&quot;&quot;</span><span class="w"></span> -</code></pre></div> - -<h2 id="learning-more">Learning more</h2> - -<p>If you want to learn more about Eve, we have some resources to help with that:</p> - -<ul> -<li>Example applications - See some working programs and explore how they work.</li> -<li>Tutorials - Step by step instructions on building Eve applications.</li> -<li><a href="https://witheve.github.io/docs">The Eve Handbook</a> - Everything you need to know about Eve.</li> -<li><a href="https://witheve.github.io/assets/docs/SyntaxReference.pdf">Eve syntax reference</a> - Eve&rsquo;s syntax in one page.</li> -<li>Guides - In-depth documents on topics relating to Eve.</li> -</ul> - -<p>We also invite you to join the Eve community! There are several ways to get involved:</p> - -<ul> -<li>Join our <a href="https://groups.google.com/forum/#!forum/eve-talk">mailing list</a> and get involved with the latest discussions on Eve.</li> -<li>Impact the future of Eve by getting involved with our <a href="https://github.com/witheve/rfcs">Request for Comments</a> process.</li> -<li>Read our <a href="http://incidentalcomplexity.com/">development diary</a> for the latest news and articles on Eve.</li> -<li>Follow us on <a href="https://twitter.com/with_eve">twitter</a>.</li> -</ul> - - - - - \ No newline at end of file diff --git a/src/tutorials/quickstart.md b/tutorials/quickstart.md similarity index 99% rename from src/tutorials/quickstart.md rename to tutorials/quickstart.md index de1cbee..a4c1395 100644 --- a/src/tutorials/quickstart.md +++ b/tutorials/quickstart.md @@ -48,7 +48,7 @@ search [name] bind @browser - [#div, text: "Hello, {{name}}"] + [#div text: "Hello, {{name}}"] ``` Since we matched on a record with a name attribute, we now have a reference to that name, and we can inject it into a string using [`{{ ... }}`][string-interpolation] embedding. We can also swap out `tag: "div"` for the sugared `#div`. [Tags][tags] are used a lot in Eve to talk about collections of related records. For example, we could search for all records with a `#student` tag, with name, grade, and school attributes. diff --git a/tutorials/quickstart/index.html b/tutorials/quickstart/index.html deleted file mode 100644 index 4ad4a4f..0000000 --- a/tutorials/quickstart/index.html +++ /dev/null @@ -1,630 +0,0 @@ - - - - - - - - - - - - Quickstart - Eve Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
- - - -

Eve Quick Start Tutorial

-
```
-bind @browser
-  [tag: "div", text: "Hello, world"]
-```
-
- -

Hello world! At its core, Eve is a pattern matching language. You match patterns of data by searching a database, then update or create new data according to what you’ve found. In this example, we created a record that has two attributes: a tag attribute with the value "div", and a text attribute with the value "Hello, world". We bound this record to the browser, which is how we displayed our venerable message.

- -

The three backticks ``` are called a code fence, and they allow us to denote blocks of code. This gives us the ability to embed Eve code in normal documents written in Markdown. This is how Eve programs are written: everything in a code fence is a block of Eve code, while everything outside is prose describing the program. In fact, this quick start tutorial is an example of an executable Eve program! In the subsequent blocks, you won’t see any code fences, but they still exist in the document’s source.

- -

So far we’ve created a record that displays “Hello, world!” but as I said, Eve is a pattern matching language. Let’s explore that by searching for something:

-
search
-  [name]
-
-bind @browser
-  [tag: "div", text: "Hello, world"]
-
- -

Our message disappeared! Before, we bound without searching, so the message displayed by default. Now we’re binding in the presence of a search action, so the bound record only exists if all the searched records are matched. Here, we’re searching for all records with a name attribute, but we haven’t added any records like that to Eve so none are matched. With no matching records, the bind cannot execute, and the message disappears from the screen.

- -

This is the flow of an Eve block: you search for records in a database, and if all the records you searched for are matched, you can modify the matched records or create new ones. If any part of your search is not matched, then no records will be created or updated.

- -

To get our message back, all we need is a record with a name attribute. We can create one permanently with the commit action:

-
commit
-  [name: "Celia"]
-
- -

Hello, world… again! Commit permanently updates or creates a record that will persist even if its matched records (the records matched in a search action) change. Since we aren’t searching for anything in this block, the commit executes by default and adds a record with a name attribute of "Celia". The addition of this new record satisfies the search in the previous block, so “Hello, world!” appears on the screen again.

- -

But what else can you do with matched records? For starters, we can use them to create new records:

-
search
-  [name]
-
-bind @browser
-  [#div, text: "Hello, {{name}}"]
-
- -

Since we matched on a record with a name attribute, we now have a reference to that name, and we can inject it into a string using {{ ... }} embedding. We can also swap out tag: "div" for the sugared #div. Tags are used a lot in Eve to talk about collections of related records. For example, we could search for all records with a #student tag, with name, grade, and school attributes.

-
search
-  [#student name grade school]
-
-bind @browser
-  [#div text: "{{name}} is a {{grade}}th grade student at {{school}}."]
-
- -

Since we’re matching on more attributes, this block is no longer satisfied by the record we added earlier; we’re missing a #student tag, as well as grade and school attributes. Even though these are currently missing, we can still write the code that would display them.

- -

Let’s display this new message by adding the missing attributes to Celia. We could add them to the block where we comitted Celia originally, but we can also do it programatically:

-
search
-  celia = [name: “Celia”]
-
-bind
-  celia <- [#student grade: 10, school: "East", age: 16]
-
- -

You can define variables within blocks, which act as handles on records that allow you to change them. In this case, we’re using the merge operator <- to combine two records. With the addition of this block, the sentence “Celia is a 10th grade student at East.” appears in the browser.

- -

Celia is cool and all, but let’s add some more students to our database:

-
commit
-  [#student name: “Diedra”, grade: 12, school: "West"]
-  [#student name: “Michelle”, grade: 11, school: "West"]
-  [#student name: “Jermaine”, grade: 9]
-
- -

Three sentences are now printed, one for each student that matches the search. Eve works on sets, so when we search for [#student name grade school], we find all records that match the given pattern. This includes Celia, Diedra and Michelle (but not Jermaine, as he has no school in his record). Therefore, when we bind the record [#div text: "{{name}} is a ... "], we are actually binding three records, one for each matching #student.

- -

If you re-compile the program a couple times, you’ll see the order of sentences may change. This is because there is no ordering in Eve - blocks are not ordered, statements are not ordered, and results are not ordered. If you want to order elements, you must impose an ordering yourself. We can ask the browser to draw elements in an order with the “sort” attribute:

-
search
-  [#student name grade school]
-
-bind @browser
-  [#div sort: name, text: "{{name}} is a {{grade}}th grade student at {{school}}."]
-
- -

This time when you recompile your program, the order will stay fixed, sorted alphabetically by name.

- -

Let’s make things a little more interesting by adding some records about the schools the students attend:

-
commit
-  [#school name: “West”, address: "1234 Main Street"]
-  [#school name: “East”, address: "5678 Broad Street"]
-
- -

What if we want to display the address of the school each student attends? Although #students and #schools are in different records, we can relate two records by associating attributes from one record with attributes from the other. This is an operation known as joining. In this case, we want to relate the name attribute on #schools with the school attribute on #students. This compares the values of the attributes between records, and matches up those with the same value. For instance, since Celia’s school is “East”, she can join with the #school named “East”.

- -

Our first attempt may come out looking a little something like this:

-
search
-  school = [#school name address]
-  student = [#student name school: name] 
-
-bind @browser
-  [#div text: "{{student.name}} attends {{school.name}} at {{address}}"]
-
- -

But that didn’t work. How come? In Eve, things with the same name are equivalent. In this block, we’ve used “name” three times, which says that the school’s name, the student’s name, and the student’s school are all the same. Of course, there is no combination of students and schools that match this search, so nothing is displayed.

- -

Instead, we can use the dot operator to specifically ask for the name attribute in the #school records, and rename our variables to get a correct block:

-
search
-  schools = [#school address]
-  students = [#student school: school.name]
-
-bind @browser
-  [#div text: "{{students.name}} attends {{schools.name}} at {{address}}"]
-
- -

This creates an implicit join over the school name without mixing up the names of the students and the names of the schools, giving us our desired output. You can actually bind attributes to any name you want to avoid collisions in a block:

-
search
-  [#school name: school-name address]
-  [#student name: student-name school: school-name]
-
-bind @browser
-  [#div text: "{{student-name}} attends {{school-name}} at {{address}}"]
-
- -

Advanced Eve

- -

Recall when we added our students, Celia was the only one we added an age to. Therefore, the following block only displays Celia’s age, even though we ask for all the #students:

-
search
-  [#student name age]
-
-bind @browser
-  [#div text: "{{name}} is {{age}} years old"]
-
- -

Let’s pretend that all students enter first grade at six years old. Therefore, if we know a student’s grade, we can calculate their age and add it to the student’s record:

-
search
-  student = [#student]
-  calculated-age = if student.age then student.age
-                   else if student.grade then student.grade + 5
-
-bind @browser
-  student.age := calculated-age
-
- -

This block selects all students, and uses and if-then expression to set the student’s calculated age. If the student already has an age, we set it to that. Otherwise, if the student has no age, we can calculate it with some arithmetic. The set operator := sets an attribute to a specified value regardless of what it was before the block executed. That value can be anything, from a number to a string to another record.

- -

Aggregates

- -

So far everything we’ve done has used one record at a time, but what happens when we want to work over a group of records, such as counting how many students there are? To solve such a problem, we’ll need to use an aggregate. Aggregates take a set of values and turn them into a single value, akin to “fold” or “reduce” functions in other languages. In this case, we’ll use the aggregate count to figure out how many #students are in the school district:  

-
search
-  students = [#student]
-  total-students = count[given: students]
-
-bind 
-  [#div text: "{{total-students}} are in the school district"]
-
- -

A quick note on the syntax for count - it feels a lot like a function in other languages, since it has a return value and can be used inline in expressions. Under the hood, functions and aggregates are actually records; total = count[given: students] is shorthand for [#count #function given: students, value: total]. This distinction won’t materially change the way you use count, but it goes to show that everything in Eve reduces to working with records.

- -

While given is a required argument in count, aggregates (and functions in general) can also have optional arguments. Let’s say we want to know how many students attend each school. We can use the optional argument per to count students grouped by the school they attend:

-
search
-  students = [#student school]
-  students-per-school = count[given: students, per: school]
-
-bind
-  [#div text: "{{students-per-school}} attend {{school}}"]
-
- -

All function-like records in Eve specify their arguments as attributes. This means you specify the argument and its value, unlike in other languages, where the order of the values determines the attribute to which they belong. As with everything else in Eve, order doesn’t matter.

- -

Extra Credit

- -

At this point, you know everything necessary about Eve to complete this extra credit portion (the only additional knowledge you need is domain knowledge of HTML and forms). Let’s review some of the key concepts:

- -
    -
  • Eve programs are composed of blocks of code that search for and update records.
  • -
  • Records are sets of attribute: value pairs attached to a unique ID.
  • -
  • Eve works with sets, which have no ordering and contain unique elements.
  • -
  • Things with the same name are equivalent.
  • -
- -

Your extra credit task is to build a web-based form that allows you to add students to the database. Take a moment to think about how this might be done in Eve, given everything we’ve learned so far.

- -

First, let’s make the form. We’ve already displayed a #div, and in the same way we can draw #inputs and a #button:

-
bind @browser
-  [#div children: 
-    [#div sort: 1, text: "Name:"]
-    [#input #name-input sort: 2]
-    [#div sort: 3, text: "Grade:"]
-    [#input #grade-input sort: 4]
-    [#div sort: 5, text: "School:"]
-    [#input #school-input sort: 6]
-    [#button #submit sort: 7 text: "submit"]]
-
- -

We’ve added some tags to the inputs and the button to distinguish them, so we can easily search for them from other blocks. Now that we have a form, we need to define what happens when the submit button is clicked.

- -

Remember, everything in Eve is a record, so the #click event is no different. When a user clicks the mouse in the browser, Eve records that click in the database.

- -

This record exists only for an instant, but we can react to it by searching for [#click element: [#submit]]. This record represents a #click on our #submit button. Then, all we need to do is capture the values of the input boxes and save them as a #student record:

-
search
-  [#click element: [#submit]]
-  name = [#name-input]
-  grade = [#grade-input]
-  school = [#school-input]
-
-commit
-  // save the new student
-  [#student name: name.value, grade: grade.value, school: school.value]
-  // reset the form
-  name.value := ""
-  grade.value := ""
-  school.value := ""
-
- -

Learning more

- -

If you want to learn more about Eve, we have some resources to help with that:

- -
    -
  • Example applications - See some working programs and explore how they work.
  • -
  • Tutorials - Step by step instructions on building Eve applications.
  • -
  • The Eve Handbook - Everything you need to know about Eve.
  • -
  • Eve syntax reference - Eve’s syntax in one page.
  • -
  • Guides - In-depth documents on topics relating to Eve.
  • -
- -

We also invite you to join the Eve community! There are several ways to get involved:

- - - - -
-
- -
-