elfu
v0.0.40
Published
Programming language that elves use
Maintainers
Readme

#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->.jsand.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
abcare 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 }while and for statements ⧖ and ⧗
⧖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--
}
each looping ⬌ and ⬍
⬌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 ≜ yis 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)
ロ statestack operations ⬊ ⬈ ⬋ ⬉
⬊⬈are typed aspu|TABandpo|TAB.⬊is for.pushand⬈is for.pop.- you can omit
(and). ⬋⬉are typed asPu|TABandPo|TAB.⬋is for.shiftand⬉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
superscript indexing Xⁱ
aⁱtranslates toa[i].a⁰translates toa[0].aⁱ⁰translates toa[i][0].- typed as
.i|TABor.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(⚪)()comparison operators ≟ and ≠
- typed as
eq|TABandne|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+5delete 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, ⍽ ainfinite 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
fororwhile.
∞ 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'node.js fs functions ⛁, ⛃
⛁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'booleans ⦿ and ⦾
⦿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:', zA ∆ ['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|TABorio|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 7array utilities ⋃ ⨄ ꔬ ⧉ ꗚ ❄, string and character 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|TABetc. - they are useful if you are out of latin letters.
- internally they are represented as
_oo_0to_oo_26.
∇ ⓐ = 0, ⓩ = 26
ロ ⓐ, ⓩ❶❷①②aretagsorlabels, they have special syntax.❶is a label definition,❶ 5equals 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 55TODO: 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, 2object keys as an array with '⚷'
obj ∆ {a:1, b:2, c:3}
ロ ⚷ obj // ['a', 'b', 'c']namespace utility with ➮| and ➮]
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...'
}
➮|
new syntax for branching with ❰ ❱ ◇ ⁋]232
❰is typed asq|TABor[|TAB.❱is typed asw|TABor]|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.yyprogram.yyj program.yyconvertprogram.yyto Javascript. Data is written to standart outout.jyy program.jsconvert 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
