#Elfu - hosti lammen
Elfu is highly experimental symbolic language. UNICODE contains thousands and thousands of symbols, why not use them?
- Elfu stands for elvish functional language or elvish numeric gongfu.
- Elfu in elvish is called hosti lammen, or computing language.
- Elfu is Javascript compatible, you mix Javascript and Elfu in Elfu file.
- Elfu file extension is .yy (this is elvish)
- Elfu is written in Javascript itself.
- To type symbols we use TAB completion feature of the editor.
- Most of symbols are just replaced with their Javascript counterparts.
- Some symbols are parsed in a special way, like
➮
or⬌
. - Editors known to be Elfu-friendly are Sublime Text, Geany, Deodar.
- If your computer does not show all symbols, there is a font file [elfu.ttf][100].
- Elfu only uses Unicode standard symbols.
- Elfu is mostly reversable, in other words you can convert
.yy->.js
and.js->.yy
. Mostly. - Read this document in better font here. [100]: http://exebook.github.io/fonts/elfu.ttf
Contents
- Screenshot
- Syntax
- function definition
➮
- return statement
$
- while and for statements
⧖
and⧗
- break and continue statements
@
- each looping
⬌
,'►' and⬍
- console.log
ロ
- if, else, elseif
⌥
⎇
⥹
- var and def
∇
∆
≜
- stack operations
⬊
⬈
⬋
⬉
- superscript indexing
Xⁱ
- this and undefined are
⚫
⚪
∅
- comparison operators
≟
and≠
- clean and visible semicolon
⦙
- delete and new are
⏀
and⟡
- length of an array or a string
↥
- require directive
≣
- Math functions
⍽
⬠
⚂
- infinite loop
∞
- time operations
⌛
⌚
⚡
- node.js fs functions
⛁
,⛃
- str serialization with
⌶
⫴
≂
- booleans
⦿
and⦾
- last item of a string or an array
ꕉ
↟
- finding occurence in a string or array with
≀
≀≀
- array utilities
⋃
⨄
ꔬ
⧉
ꗚ
❄
, string and character utilities△
◬
⩪
- symbolic variables
- is defined
⟑
- multi line strings with
'''
- tuples with
ꔪ
- object keys as an array with
⚷
- namespace utility with
➮|
- new syntax for branching with
❰
❱
◇
⁋
- Usage
- Dotcall syntax
- Feedback
/* TODO: ∼◬ String.fromCharCode() - auto arg ꘉ bind - auto arg - mini functions f = ➮ a + b ⦙ ロ f(2, 3)
*/
#Screenshot Here is how Elfu looks in author's editor:
#Syntax
#####function definition ➮
-
typed as
fu|TAB
. -
Elfu translator will replace
➮
withfunction
. -
you can avoid
(
,)
and,
in argument declaration. -
if you omit any arguments, arguments
a
b
c
are default. -
use
➮f(){}
or➮{}
syntax to declare an anomymous function without arguments. -
➮ {}
is a lambda with default arguments a, b, c. -
➮ a + b ;
becomes((➮ { $a+b }).bind(this))
- aka "arrow function" -
anonymous function with arguments
a,b
:➮ - a b {}
➮ compare (a, b) { console.log(a == b) }
➮ compare a b { console.log(a == b) }
➮ compare { console.log(a == b) }
[1,2,3].forEach(➮ { console.log(a) })
n = 2
a ∆ [1,2,3,4,5] ꔬ ➮ a > n ; // 'this' is bound to a caller
ロ a // prints [3,4,5]
Math.sum = ➮ - x y {
$ x+y
}
$
return statement -
$
is replaced withreturn
.
➮ four { $ 2 + 2 }
⧖
and ⧗
while and for statements -
⧖
is replaced withwhile
. -
⧗
is replaced withfor
. - typed as
wh|TAB
,fo|TAB
. - parens () can be avoided if you have braces {}
⧖ (true) step()
⧗ (var i = 0; i < 3; i++) step()
@
break and continue statements -
@
is replaced withbreak
. -
♻
is replaced withcontinue
.
⧖ (true) {
step()
if (again()) ♻
if (finished()) @
}
n ∆ 5
⧖ n > 0 { // parens, ( and ) are not needed
ロ n--
}
⬌
and ⬍
each looping -
⬌
typed asea|TAB
. - compiles to
for (var i = 0; i < obj.length; i++)
. - just type
i ⬌ obj
, it converts to the above. -
►
(iterator) typed asit|TAB
. - ► is similar to ⬌, but the 'i' is an array item rather than an index.
-
⬍
typed asfe|TAB
.` - simply converts to
.forEach
.
var a = [1,2,3]
i ⬌ a { console.log(a[i]) }
a ∆ [1,2,3]
i ⬌ a ロ aⁱ
a ∆ [1,2,3]
i ► a ロ i
// index still can be accessed with `_` + name, in this case `_i`.
The `i` will be replaced with `a[i]`. Operator `►` either requires `{}` or the expression must be on a single line. (Otherwise Elfu would need to use the full blown expression parser, which is beyond the scope of the current version).
A ∆ [1,2,3,4]
A ⬍ (➮ { ロ a ; })
ロ
console.log - typed as
lo|TAB
-
ロ
is Chinese/Japanese character for mouth. - tired typing console.log hundreds times a day?
-
ロ
takes everything until the end of line or;
as arguments. - make sure you add ';' if your code continues on this line.
ロ 'hello world!'
ロ 'numbers are:', 1, 2, 3
if (true) ロ 'here'
➮ compare { ロ a == b; }
Automatic +
insertion. You can avoid +
for brevity, because inside ロ
all string literals can be automatically glued to identifiers and some obvious expressions with '+'.
x ∆ 12345
a ∆ [1,2,3]
ロ 'x = ' x
ロ 'four means ' (2+2)
ロ 'a = ' a ' and length is ' a↥
Elfu allows you to mix with ${}
style of strings.
a ∆ 5678
ロ `a = ${a}`
if, else, elseif ⌥ ⎇ ⥹
- typed as
if|TAB
,el|TAB
,ei|TAB
. -
⌥
is replaced withif
. -
⎇
is replaced withelse
. -
⥹
is replaced withelse if
. - if the conditional statement is enclosed in
{}
, then()
are optional -
()
are optional when the conditional statement starts with one of@
,$
,♻
,ロ
,⧖
,⧗
, '∞', ';', '⌥'.
⌥ (x == 1) ロ 'GREAT'
⥹ (x == 2) ロ 'OK'
⎇ ロ 'WRONG'
⌥ x == 2 { ロ 'x equals to two' ⦙ }
var and def ∇ ∆ ≜
- typed as
va|TAB
,de|TAB
,df|TAB
. -
∇
is replaced withvar
. -
x ∆
is translated tovar x =
. -
∆
reads as is defined as or just define. -
∆
used to be delta, but in fact it is a simplified form of a math symbol≜
-- definition or is defined as. -
x ≜ y
is replaced withif (typeof x == 'undefined') x = y
.
x ∆ 100
⧗ (∇ i = 0; i < x; i++)
a ∆ 1 b ∆ 'string' c ∆ {} d ∆ []
➮ countIt {
a.count ≜ 0
a.count++
}
state ∆ {}
countIt(state)
countIt(state)
ロ state
⬊
⬈
⬋
⬉
stack operations -
⬊
⬈
are typed aspu|TAB
andpo|TAB
. -
⬊
is for.push
and⬈
is for.pop
. - you can omit
(
and)
. -
⬋
⬉
are typed asPu|TAB
andPo|TAB
. -
⬋
is for.shift
and⬉
is for.unshift
. - mnemonically
shift()
ispop()
from the other side. - mnemonically
unshift()
ispush()
from the other side. - add
(
and)
if you push an expression.
A ∆ []
A ⬊ 1
A ⬊ (2 + 2)
// A = [1, 4]
ロ A ⬈ ; // 4
Xⁱ
superscript indexing -
aⁱ
translates toa[i]
. -
a⁰
translates toa[0]
. -
aⁱ⁰
translates toa[i][0]
. - typed as
.i|TAB
or.1|TAB
. - super-script index can only be single character.
- supported are all lowercase latin characters and digits
0
-9
. - do not try to use UPPERCASE characters.
- do not try to use multicharacter variables like
count
.
A = [1,2,3]
i ⬌ A ロ Aⁱ
B = [[1,111],[2,222],[3,333]]
i ⬌ B ロ Bⁱ¹
this
and undefined
are ⚫
⚪
∅
-
⚫
is translated tothis.
. -
⚪
is translated tothis
. -
∅
is translated toundefined
. -
⚫
typed asth|TAB
. -
⚪
typed asthis|TAB
. -
∅
typed asun|TAB
.
➮ f {
⌥ (⚫name == ∅) ロ 'no name'
⎇ ロ ⚫name
}
f()
⚫name = 'f1'
f.bind(⚪)()
≟
and ≠
comparison operators - typed as
eq|TAB
andne|TAB
. -
≟
converts to==
. -
≠
converts to!=
.
⌥ (x ≟ 2) ロ 'two'
⌥ (x ≠ 2) ロ 'not two'
⦙
clean and visible semicolon - since elfu code is so condensed, many expressions fit on the same line, to improve readability of such dense code, cleaner version of semicolon
⦙
was introduced. - typed as
sc|TAB
. -
⦙
and;
both can be used.
ロ 2+2 ⦙ ロ 3+3 ⦙ ロ 4+4 ; ロ 5+5
delete
and new
are ⏀
and ⟡
-
⏀
typed asdl|TAB
. -
⟡
typed asnew|TAB
.
➮ f { ⚫name = 'f1' }
a ∆ ⟡ f
ロ 'name =', a.name
⏀ a ⦙ a = ∅
↥
length of an array or a string - typed as
.le|TAB
. -
↥
is translated to.length
. - do not type '.' before
↥
, it is implied.
A ∆ [1,2,3]
s ∆ 'hello'
ロ s↥, A↥
x ∆ 0
⧖ (x < s↥) { ロ sˣ ⦙ x++ }
require directive ≣
- typed as
re|TAB
. -
≣
is replaced withrequire
. - you can use
(
and)
or avoid them.
fs ∆ ≣ 'fs'
spawn ∆ ≣ ('child_process').spawn
#####Math functions ⍽
⬠
⚂
-
⚂
is typed asra|TAB
. -
⚂
is converted toMath.random()
-
⬠
is typed asro|TAB
. -
⬠
is converted toMath.round()
-
⍽
is typed asfl|TAB
. -
⍽
is converted toMath.floor()
-
⬠
and⍽
can omit(
and)
for simple expressions.
⧗ (i ∆ 0 ⦙ i < 20; i++) ロ ⬠ (⚂ * 1000000)
∇ a = 0.5
ロ ⬠ a, ⍽ a
∞
infinite loop - typed as
in|TAB
. - '∞' is replaced with
while(true)
. - sometimes you just need an infinite loop.
- or you need a loop whose logic is more complex than
for
orwhile
.
∞ step() // infinite
x ∆ 0
∞ {
x += ⚂ * 2
⌥ (x ≟ 5) @
⌥ (x ≟ 7) @
⌥ (x > 10) @
ロ x
}
⌛
⌚
⚡
time operations -
⌛
is converted tosetTimeout
. -
⌚
is converted tosetInterval
. -
⌿⌛
is converted toclearTimeout
. -
⌿⌚
is converted toclearInterval
. -
⚡
is converted to(new Date().getTime())
. -
⚡
gives you millisecond tick. -
⌛
is typed asst|TAB
. -
⌚
is typed assi|TAB
. -
⚡
is typed astt|TAB
(mnemonic: time tick). -
⌿⌛
is typed asct|TAB
. -
⌿⌚
is typed asci|TAB
.
ロ 'please wait two seconds'
⌛(➮ {ロ 'ready';}, 2000)
T ∆ ⚡ ⦙ s ∆ ''
⧖ (s↥ < 1000000) s += 'a'
ロ 'benchmark: ', ⚡ - T, 'ms'
fs
functions ⛁
, ⛃
node.js -
⛁
is replaced withfs.readFileSync
. -
⛃
is replaced withfs.writeFileSync
. -
⛁
is typedfsrs|TAB
. -
⛃
is typedfsws|TAB
. - you can omit
(
and)
for ⛁ with a single argument.
fs ∆ ≣ 'fs'
A ∆ ⛁'readme.txt' ≂ ⌶ '\n'
ロ A ↥, 'lines loaded'
⌶
⫴
≂
.
str serialization with -
⌶
is typed assp|TAB
. -
⫴
is typed asjo|TAB
. -
≂
is typed asts|TAB
. -
⌶
is compiled as.split
-
⫴
is compiled as.join
- you can omit
(
and)
for simple expressions with⌶
,⫴
and≂
. -
≂
is converted to.toString
// replace all occurences of "-" with "+"
ロ '1-2-3-4-5' ⌶ '-' ⫴ '+'
// same with ( and )
s ∆ '-+'
ロ '1-2-3-4-5' ⌶ (s⁰) ⫴ (s¹)
x ∆ 123.456
ロ 'length of string representation of number', x, 'is', x≂↥
fs ∆ ≣ 'fs'
ロ 'Readme contains: ' + ⛁ ('README.md') ≂ ⌶ '\n' ↥ + ' lines'
⦿
and ⦾
booleans -
⦿
is replaced withtrue
. -
⦾
is replaced withfalse
. -
⦿
is typed astr|TAB
. -
⦾
is typed asfa|TAB
.
a ∆ ⦿
⌥ (a) a = ⦾
b ∆ { initialized: ⦾ }
ꕉ
↟
last item of a string or an array -
ꕉ
is typed as.la|TAB
. -
↟
is typed as.lx|TAB
. -
ꕉ
is used to access the last item of an array or a string. -
ꕉ
is compiled to[x.length - 1]
, soxꕉ
becomesx[x.length - 1]
. -
x↟
is compiled to(x.length - 1)
.
A ∆ ['X','Y']
➮ appendAndReturnIndex { A ⬊ a ⦙ $ A↟ }
z ∆ appendAndReturnIndex('Z')
ロ 'inserted', Aᶻ, 'at:', z
A ∆ ['hey', 'there', '.', '.', 'how', 'are', 'are', 'you', '.']
➮ removeDoubles {
R ∆ []
i ⬌ a {
⌥ (aⁱ ≟ Rꕉ) ♻
R ⬊ (aⁱ)
}
$ R
}
ロ removeDoubles(A) ⫴ ' '
// hey there . how are you .
≀
≀≀
finding occurence in a string or array with -
≀
is typed asio|TAB
. -
≀≀
is typed aslio|TAB
orio|TABio|TAB
. -
≀
is replaced with.indexOf
. -
≀≀
is replaced with.lastIndexOf
. -
(
and)
can be used or omited.
s ∆ 'hello world!'
ロ s ≀ 'world', s ≀ ('o'), s ≀≀ 'o'
// 6 4 7
⋃
⨄
ꔬ
⧉
ꗚ
❄
, string and character utilities △
◬
⩪
array utilities -
⋃
is typed assl|TAB
. -
⨄
is typed aspl|TAB
. -
ꔬ
is typed asfi|TAB
. -
⧉
is typed asma|TAB
. -
ꗚ
is typed asaa|TAB
. -
❄
is typed asso|TAB
. -
⋃
is replaced with.slice
. -
⨄
is replaced with.splice
. -
ꔬ
is replaced with.filter
. -
⧉
is replaced with.map
. -
ꗚ
is replaced with.concat
. -
❄
is replaced with.sort
. -
◬
is typed ascc|TAB
. -
△
is typed asca|TAB
. -
⩪
is typed assu|TAB
. -
◬
is replaced with.charCodeAt
. -
△
is replaced with.charAt
. -
⩪
is replaced with.substr
.
➮ numbersOnly { $ a ⌶ '' ꔬ (➮ { $ a◬(0) <= 57 }) }
ロ numbersOnly('a1b2c4d8q11')
// same as above. but sorted
➮ numbersOnly { $ a ⌶ '' ꔬ (➮ { $ a◬(0) <= 57 }) }
ロ numbersOnly('a1b2c4d8q11')❄ (➮ { $a - b })
symbolic variables
- there are three types of symbolic variables.
- the goal is to provide more condense, formula-like notation.
-
α
γ
β
...ζ
are greek letters. - Javascript supports greek letters, no translation is needed.
- Typing in greek: alf=α bet=β gam=γ del=δ eps=ε zet=ζ eta=η tet=θ iot=ι kap=κ lam=λ muu=μ nuu=ν xii=ξ pii=π roo=ρ sig=σ tau=τ ups=υ fii=φ chi=χ psi=ψ ome=ω.
∇ α = 10, δ = 5
α += δ
ロ 'alfa plus delta is:', α
-
ⓐ
ⓑ
ⓒ
...ⓩ
are encircled letters. - encircled letters are typed
ooa|TAB
,oob|TAB
,ooz|TAB
etc. - they are useful if you are out of latin letters.
- internally they are represented as
_oo_0
to_oo_26
.
∇ ⓐ = 0, ⓩ = 26
ロ ⓐ, ⓩ
-
❶
❷
①
②
aretags
orlabels
, they have special syntax. -
❶
is a label definition,❶ 5
equals to;var var0 = 5
. -
①
is a label reference, or usage,ロ ①
will convert toconsole.log(var0)
.
❶ 'hello' ❷ 'world'
ロ ①, ②
is defined
-
⟑
is typed asid|TAB
. -
⟑ <expr>
is replaced with(typeof <expr> != undefined)
.
s ∆ {x:123}
⌥ (⟑s.x) ロ 's.x is not undefined'
multi line strings
Elfu supports multi line strings enclosed with opening '''\n
and closing '''
.
console.log('''
Hello, multi line
strings world
''')
str ∆ '''
Hello, multi line
strings world'''
(GitHub markdown does highlight with red background for some reason.)
tuples
-
ꔪ
is typed astu|TAB
. -
a,b ꔪ <expr>
is replaced withtmp=<expr>;a=tmp[0],b=tmp[1]
.
➮ repl { $a.replace(b, c) }
➮ half {
$[a, a/2]
}
A ∆ {whole:∅, part:∅}
☛ A { whole, part ꔪ half(200) }
∇ a,b,c ꔪ [33,44,55]
ロ A,a,b,c
//{ whole: 200, part: 100 } 33 44 55
TODO: add support for simple name matching with ꔪ, like this:
obj ∆ { a:1, b:2 }
b,a ꔪ obj
//b = obj['b'], a = obj['a']
ロ a, b
// 1, 2
object keys as an array with '⚷'
obj ∆ {a:1, b:2, c:3}
ロ ⚷ obj // ['a', 'b', 'c']
➮|
and ➮]
namespace utility with If your elfu source file has ➮]
anywhere in it, then all top level declared functions of this file will be automatically exported to module.exports
. If you use ➮|
, the functions will be exported as global variables.
######main.yy
➮|
≣'lib'
➮ load {
ロ 'loaded...'
}
scan()
######lib.yy
➮ scan {
load()
ロ 'processing...'
}
➮|
❰
❱
◇
⁋
]232
new syntax for branching with -
❰
is typed asq|TAB
or[|TAB
. -
❱
is typed asw|TAB
or]|TAB
. -
◇
is typed ase|TAB
. - replace '❱' with ')', or '){' when the next token is on the same line.
- replace '◇' with: a. '} else if(' if followed by the next non-space character '❰'; b. '} else {' if the next token is on the same line; c. 'else'. -- not possible, ◇ cannot be used with the oneliners.
- replace '⁋' with '}'.
- replace '❰' with 'if ('.
There is no if
keyword or it's analog if you use this notation, the test condition is enclosed in ❰
and ❱
. The conditional statement is a one liner if it goes on the same line, otherwise end it with the ⁋
. Same is true with else
which is ◇
.
This syntax does not replace original JavaScript or original Elfu if
else
and ⌥
⎇
, but coexist.
/*
Nested conditional expressions.
You cannot use ◇ with one-liners. But ◇ itself could have a oneliner expression.
*/
❰1❱
❰2❱
b = 3
◇
b = 4
⁋
◇
❰5❱
b = 6
◇
b = 7
⁋
⁋
❰a ≟ 5❱ a = c
◇ b = 1
❰a == 5❱ b = 4
❰a == 5❱
b = 4
◇
b = 6
⁋
❰a == 5❱ b = 4 ◇ b = 6
❰a == 5❱ b = 4 ◇ ❰a == 5❱ b = 6
❰a == 5❱ b = 4 ◇ ❰a == 5❱
b = 6
⁋
You can combine syntaxes like this:
❰1❱
{ 2 }
⎇ { 3 }
...or like this:
❰1❱
{ 2 }
else
{ 3 }
#####String array literals
ロ [@ dormouse hare hatter]
// [ 'dormouse', 'hare', 'hatter']
extras
`__arrarr` - get the function arguments as an array.
`__elfuver` - return a string specifying current elfu version. This is read from `package.json`.
#Usage
- install with npm,
[sudo] npm i -g elfu
. -
yy <program>
run the.yy
program. -
yyj program.yy
convertprogram.yy
to Javascript. Data is written to standart outout. -
jyy program.js
convert Javascript to Elfu. -
require('elfu'); require('example.yy')
you can require modules written in Elfu.
#Dotcall syntax
- Elfu supports dotcall syntax.
- dotcall is callback hell remedy.
- read dotcall README for details.
#Feedback
- post your ideas and other feedback in issues on github page.
- Github page is https://github.com/exebook/elfu.
- author's email:
exebook gmail com
- author's VK page: http://vk.com/chucknorrisgriboedov