elfu v0.0.40
#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.
- 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.
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 }
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 ≜ 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
superscript indexing Xⁱ
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(⚪)()
comparison operators ≟
and ≠
- 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'
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:', 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
array 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|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']
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|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
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago