keyword - pannous/warp GitHub Wiki
A guiding philosophy of warp is to make sigil special chars (!@#$%^&*[}...) completely optional. A guiding principle of warp is to make julia like beautiful math possible.
Keywords are just predefined functors or operators which cannot be redefined, but whose behavior can be _ refined_ β : Most english particles and prepositions act as keyword. Noteworthily in on of to with while it that which
Otherwise they go through the exact same parsing and precedence mechanisms as custom operators and functions.
(Only exception: the 'if' keyword is not implemented as if(condition:block then:block else:block?) functor for
efficiency reasons and to allow syntactic sugar such as if 1:exit.
optional values get denoted via maybe or '?' sigil keyword.
required values get denoted via '!' sigil keyword, or by default.
enum and variant are aliases which are only needed for interop, otherwise all node_pointer are prone to matching
Special care should be given to the and operator, which could in theory reflect much of the natural behavior:
Set union: women and children
Set union: they can read and write
Set intersection: my jeans were creased and dirty
Sequential: he turned round and walked out
Causal: there was a flash flood and by the next morning the town was under waterβ
And, there are many more usages. The technical word linguists use for the role words like "and" play is coordination.
https://en.wikipedia.org/wiki/Coordination_(linguistics)
https://news.ycombinator.com/item?id=25406211
The keywords of warp
Three kinds of words (P165, src/lowering/welcoming/soft_keywords.rs):
- hard keywords are reserved: no program may name anything with them;
- soft keywords mean something, but a local variable, parameter or field may still use the word (you get a "got it" note); only defining one at the top level is an error;
- every other word below is a contextual word: it means something only in its spot (
byaftersort,ofaftereffects) and is an ordinary name everywhere else.
Aliases are other spellings of the same word: they work, and some of them suggest the canonical word in a hint. Each example shows its result after β (warp's probes/keyword_examples.py runs them all; the Sublime plugin's scripts/update_words.py fails when a keyword of warp's sources is missing here).
Hard keywords
| word | aliases | meaning | example |
|---|---|---|---|
| if | condition, also after a statement | if 2 > 1 {'yes'} else {'no'} β "yes"; n = 0; n += 5 if 1 > 2; n β 0 |
|
| then | the branch after a condition | x = 2; if x > 1 then 'big' else 'small' β "big" |
|
| else | the other branch; also the fallback of try |
r = try 1/0 else 0; r β 0 |
|
| while | loop while true, also after a statement | x = 0; while x < 3 { x += 1 }; x β 3; x = 0; x += 1 while x < 3; x β 3 |
|
| for | loop over items | s = 0; for i in 1 to 3 { s += i }; s β 6 |
|
| in | the items of a loop, membership (yes/no) | 2 in [1, 2] β yes |
|
| return | leave a function with a value | def f(x) { return x + 1 }; f(1) β 2 |
|
| break | leave a loop | x = 0; loop { x += 1; if x == 4 { break } }; x β 4 |
|
| continue | next round of a loop | s = 0; for i in 1..4 { if i == 2 { continue }; s += i }; s β 4 |
|
| def | define, function, func | define a function | def f(x) { x * 2 }; f(4) β 8 |
| fun | fn | define a function | fun g(x) = x * 3; g(2) β 6 |
| class | struct | declare a type | class Point { x: int; y: int }; Point(1, 2).y β 2 |
| var | a variable | var x = 1; x = 2; x β 2 |
|
| let | an immutable variable (var changes) | let y = 5; y β 5 |
|
| val | a variable (Kotlin) | val v = 8; v β 8 |
|
| const | constant | a value that never changes | const z = 7; z β 7 |
| global | a module-wide variable | global n = 1; n β 1 |
|
| true | yes, β€, β, β, β , β | truth | x = β
; x and β€ β yes |
| false | no, β₯, β, β | falsehood | not β β yes |
| null | nil, ΓΈ, none, nothing, void, nul, nill, nix, nada | no value | null |
| use | import, require | load a module | use math; sqrt(16) β 4 |
| include | insert a file's code, #include too |
include "helpers.warp" |
f(x) := x * 2 defines a function without any keyword.
Soft keywords
| word | aliases | meaning | example |
|---|---|---|---|
| emit | send; fire, trigger, signal, ask | send an event to its handlers | n=0; on alarm {n+=1}; emit alarm; emit alarm; n β 2 |
| broadcast | send an event to other programs | broadcast {text: 'hi'} on 'room' |
|
| every | repeat on a schedule | on every 1000 ms { print 'tick' } |
|
| whenever | run each time a condition becomes true | x=0; hits=0; whenever x>1 {hits+=1}; x=1; x=2; x=3; x=0; hits β 1 |
|
| init | constructor, initialize | a class's constructor | class P { x=0; init(v) := { x = v * 2 } }; P(3).x β 6 |
| new | make an instance (other languages' spelling) | new Point(1, 2) |
|
| root | the page's root element | root.add(p{'hi'}) |
|
| listeners | the handlers of an event | on alarm {1}; on alarm {2}; count alarm.listeners β 2 |
|
| stored | a variable kept across runs | stored visits default 0; visits += 1 β 1, then 2 on the next run |
|
| stored β¦ : [Class] | a database table of a class's instances, named after the variable, or the table given with in |
stored people: [Person], stored people: [Person] in "people_v2" |
|
| undo | the variable's previous value | x = 1; x = 2; undo x; x β 1 |
|
| redo | take back an undo | x = 1; x = 2; undo x; redo x; x β 2 |
Contextual words
Control flow
| word | aliases | meaning | example |
|---|---|---|---|
| unless | if not, also after a statement |
x = 3; x unless x > 5 β 3 |
|
| until | while not |
x = 0; until x >= 3 { x += 1 }; x β 3 |
|
| elif | elsif, elseif | else if | x = 5; if x < 3 {'a'} elif x < 6 {'b'} else {'c'} β 'b' |
| do | run a block on the spot; do β¦ end blocks |
x = 0; while x < 2 do x += 1 end; x β 2 |
|
| end | closes do / then (Ruby, Lua) |
||
| loop | loop forever | x = 0; loop { x += 1; if x == 4 { break } }; x β 4 |
|
| times | repeat n times | 3 times { print 'hi' } |
|
| switch | match | pick a branch by value | x = 2; switch x { 1: 'one' 2: 'two' default: 'many' } β "two" |
| case | a variant of an enum (Swift) | enum Shape { case circle(radius: int); case square(side: int) }; s = Shape::square(4); s.side β 4 |
|
| default | _, other, else |
the switch branch for every other value | x = 7; match x { 1: 'one' _: 'many' } β "many" |
| try | catch an error; a bare try keeps it as the value |
try { 1/0 } catch { 'caught' } β "caught", r = try 10/0; r failed β yes |
|
| catch | except | handle the error of try |
try { raise 'oops' } catch e { e } β Error("oops") |
| finally | runs after try either way | ||
| raise | throw, fail, panic | make an error | throw 'bad' β Error("bad") |
| warning | warn | report a problem and continue (an error under use strict; levels: warning) |
warn "careful"; 1 β warning: careful, then 1 |
| assert | check | stop when false | assert 1 + 1 == 2 β 1 |
| test | a soft check: only warp test runs it, counts it and goes on |
test 1 + 1 == 2 β under warp test: β 1 test passed |
|
| expect | expect V C is test C == V |
expect 30 10+20 β under warp test: β 1 test passed |
|
| yield | call the block a function was given (Ruby blocks; generators were dropped) | def twice; yield 1; yield 2; end; twice { |x| print x } β prints 1 and 2 |
|
| once | run when a condition first becomes true | x=0; hits=0; once x==5 {hits+=1}; for i in 1..10 { x = i }; hits β 1 |
Declarations
| word | aliases | meaning | example |
|---|---|---|---|
| record | data | a class from its fields | record Pair(a: int, b: int); Pair(1, 2).b β 2 |
| enum | named alternatives | enum Color { red green blue }; Color.green β 1 |
|
| trait | interface, protocol, typeclass, prototype, capability, aspect, feature | what a class promises | trait Shape { area() }; class Square implements Shape { side: int; area() := side * side }; Square(3).area() β 9 |
| extends | inherit from a class | class Shape { name: text }; class Circle extends Shape { r: int }; Circle('c', 2).name β 'c' |
|
| implements | claim a trait | see trait | |
| mixin | fields and methods to mix in | mixin Walker{ steps:int=0; walk() := 'walks' }; class Cat with Walker { name: text }; Cat('tom').walk() β "walks" |
|
| with | mix in; scoped resource | see mixin | |
| get, set | accessors of a field | ||
| operator | define an operator | class V{x:int; operator +(o) := V(x + o.x)}; (V(1) + V(2)).x β 3 |
|
| prefix, infix, suffix | the kind of a new operator | suffix operator βΌ := it*2; 3βΌ β 6 |
|
| above, below | the precedence of a new operator | ||
| lambda | an anonymous function (Python) | f = lambda x: x * 2; f(3) β 6 |
|
| law | a property a function promises | square(x) := x*x; law square(-x) == square(x); square(3) β 9 |
|
| extension | methods added to an existing type |
Modifiers
| word | aliases | meaning | example |
|---|---|---|---|
| export | visible to importers | export f(x) := x; f(1) β 1 |
|
| mutable | mut | may change (after a declaration word) | var x = 1; x = 2; x β 2 (let mut x works as var x, with a note: write var) |
| final | never reassigned | final k = 3; k β 3 |
|
| static | belongs to the class, not its instances | static k = 3; k β 3 |
|
| nonlocal | assign the enclosing function's variable | ||
| shared | one value every task sees | shared n = 0; go { n += 1 }; sleep(50 ms); n β 1 |
|
| linear | an array in linear memory | linear xs = float[8] |
|
| async | accepted, tasks need no marking |
Other languages' modifiers are accepted and skipped with a warning ("public has no meaning in warp"): public, private, protected, internal, fileprivate, open, sealed, abstract, override, virtual, inline, extern, external, local, native, atomic, synchronized, transient, volatile, thread_local, constexpr.
Implicit names
| word | aliases | meaning | example |
|---|---|---|---|
| it | the one parameter of a function or block | square := it*it; square(3) β 9 |
|
| self | this | the instance in its methods | class C { n: int = 1; double() := self.n * 2 }; C().double() β 2 |
| super | the parent class | ||
| result | the value of the statement before | f(x) := x*x; f(3); result β 9 |
|
| event | the event inside its handler | level=0; on alarm {level=event.level}; emit alarm{level:3}; level β 3 |
|
| value, old | previous, was | the new and the old value in a change handler |
Operators as words
| word | aliases | meaning | example |
|---|---|---|---|
| and | β§ | both | true and false β no |
| or | β¨ | either; and= and or= assign |
x = no; x or= yes; x β yes |
| xor | β» | exactly one | 1 xor 0 β 1 |
| not | Β¬ | negation | not true β no |
| nand | βΌ | not both | true nand true β no |
| is | equals | equal, of a type, or fitting a pattern (pattern-matching) | 1 + 1 is 2 β yes |
| is not | not equal | 3 is not 4 β yes |
|
| same | same as, is the same as | identical | x = 1; x same as 1 β yes |
| greater than | is greater than | > |
5 is greater than 3 β yes |
| less than | is less than | < |
|
| at least, at most | >=, <= |
5 is at least 5 β yes |
|
| plus | + |
3 plus 4 β 7 |
|
| minus | - |
9 minus 4 β 5 |
|
| times | * (hint: prefer *) |
||
| divided by | / |
8 divided by 2 β 4 |
|
| mod | modulo | remainder, sign of the divisor | 5 mod 3 β 2 |
| rem | remainder, sign of the dividend | 7 rem 3 β 1 |
|
| div | whole division (note: prefer /!) |
7 div 2 β 3 |
|
| contains | has, includes | membership | [1, 2] contains 2 β yes |
| to | through | inclusive range | 1 to 3 β [1 2 3] |
| upto | exclusive range (warns) | ||
| down to | falling range | 3 down to 1 β [3 2 1] |
|
| circa | approximately, β | equal up to rounding | 0.1 + 0.2 circa 0.3 β yes |
| as | convert | 3 as text β "3" |
|
| interpret | run data as code at run time | y = data 6*7; interpret y β 42 |
|
| a, an | type test article | 3 is an int β yes |
|
| empty | missing, absent, unknown, undefined | test for no value | x = []; x is empty β yes |
| failed | test for an error value: the no-catch way to handle errors (Error) | r = error "neg"; if r failed then 1 else 2 β 1 |
Lists
| word | aliases | meaning | example |
|---|---|---|---|
| where | filter | [1, 2, 3, 4] where it > 2 β [3 4] |
|
| sort_by | sort by a key function | ["bbb", "a", "cc"].sort_by(it => it.length) β ['a' "cc" "bbb"] |
|
| slice | a 0-based, end-exclusive slice | [1, 2, 3, 4].slice(0, 2) β [1 2] |
|
| add β¦ to | append | xs = [1, 2]; add 3 to xs; xs β [1 2 3] |
|
| all | apply to every item | add(a, b) := a + b; add(all [1, 2], 10) β [11 12] |
|
| each | for each | loop over items, each is the item |
s = 0; for each in [1, 2] { s = s + each }; s β 3 |
| even, odd | loop filter of a type word, when no function of that name is defined | s=0; for (even number) in [1,2,3,4] { s += it }; s β 6 |
|
| for β¦ if | comprehension | [x * 2 for x in 1..4 if x > 1] β [4 6] |
Events and signals
| word | aliases | meaning | example |
|---|---|---|---|
| on | handle an event or a change | x = 1; on change x { print 'changed' }; x = 2 |
|
| set, change | changes | the variable events | |
| before, after | run around a function call | log=0; def save(x): x; before save: log=1; save(5); log β 1 |
|
| remove β¦ from listeners | drop a handler | ||
| at | a time of day | on every friday at 17:00 { β¦ } |
|
| weekday, weekend, am, pm | schedule words | ||
| click, key, input | page events | ||
| interrupt, exit | system events |
Tasks
| word | aliases | meaning | example |
|---|---|---|---|
| go | start a task | f(x):=x*2; job = go f(3); await job β 6 |
|
| await | wait for a task; await all, await any |
see go | |
| within | a time limit for await | await job within 100 ms or 0 |
|
| finishes | finished, completes, ends, done | the task event | job = go 3; once job finishes: x = 7; x β 7 |
| stop, pause, cancel, resume | control a task | ||
| sleep | wait | sleep(50 ms) |
Reflection
| word | aliases | meaning | example |
|---|---|---|---|
| effects | effects of | what a function may do | f(x) := x; effects of f β Pure |
| fields | attributes, members | the field names | class P { x:int; y:int }; p = P(1,2); p.fields β ["x" "y"] |
| methods | the method names | class P { x:int; sq() := x*x }; P.methods β ["sq"] |
|
| params | parameters | a function's parameter names | f(a:int, b:int) := a+b; f.params β ["a" "b"] |
| signature | a function's type | f(a:int, b:int) := a+b; f.signature β "(a:int, b:int) -> int" |
|
| type | class | the type of a value | class P { x:int }; p = P(1); p.type β P |
| dir | keys | the names a value or module has | dir {a: 1, b: 2} |
| body, definition, doc | a function's code and its comment | ||
| exports, functions, classes | what a module holds | ||
| meta | @name |
meta information on a value | |
| ref | $name |
a reference to an enclosing node | x = a{ b:2 c{ parent=ref a } }; x.c.parent.b β 2 |
Server and database
| word | aliases | meaning | example |
|---|---|---|---|
| serve | server | run the program as a web server | serve |
| get, post, put, delete, patch | a route of the server | get "/hi" { "hello" } |
|
| request, path | the request inside a route | ||
| route, outlet | client-side page routes | ||
| database | indexedDB | values or tables in a database | database people = [...] |
| local storage, session | where stored keeps a value |
||
| save | write a table row |
Modules
| word | aliases | meaning | example |
|---|---|---|---|
| use | import, require | load a module, #import too |
use math; sqrt(16) β 4 |
| include | insert a file's code | ||
| folder, package, project | the scope of a module search |
Constants
| word | aliases | meaning | example |
|---|---|---|---|
| pi | Ο | pi β Ο |
|
| tau | Ο | 2Ο | tau β 2Ο |
| euler | β― | euler β β― |
|
| β | the imaginary unit | β
* β
β -1 |
|
| Ξ΅, Ο | infinitesimal, infinite | Ξ΅ β Ξ΅ |
|
| β | infinity |
Units
Number words after a literal: 3 m + 20 cm β 320cm, 2 hours + 30 minutes β 2 hours 30 minutes.
Time units: second, minute, hour, day, week, month, year (and plurals); others: m, cm, mm, km, g, kg, mg, ms, s, h,
bytes, characters, codepoints (lib/units.warp has the full table).
Listed but unused
None at the moment: every word above parses. A word that a table in warp's sources lists but no pass gives a meaning belongs here (and on the to-do board), not in the tables above.