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 {}
➮ { console }➮ compare a b console ➮ compare console 123
n = 2a ∆ 12345 ꔬ ➮ a > n ; // 'this' is bound to a callerロ a // prints [3,4,5]
Mathsum = ➮ - 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 ⧗ var i = 0; i < 3; i++
@
break and continue statements @
is replaced withbreak
.♻
is replaced withcontinue
.
⧖ true if ♻ if @
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 = 123i ⬌ a console
a ∆ 123i ⬌ a ロ aⁱ
a ∆ 123i ► 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 ∆ 1234A ⬍ ➮ ロ 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 3if 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 ∆ 12345a ∆ 123 ロ 'x = ' xロ 'four means ' 2+2ロ 'a = ' a ' and length is ' a↥
Elfu allows you to mix with ${}
style of strings.
a ∆ 5678ロ `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 acount ≜ 0 acount++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 ⬊ 1A ⬊ 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 = 123i ⬌ A ロ Aⁱ
B = 111122223333i ⬌ 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⚫name = 'f1'f
≟
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 =' aname⏀ 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 ∆ 123s ∆ '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 = 05ロ ⬠ 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
.
∞ // 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 ∆ 123456ロ '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 ∆ ロ 'inserted' Aᶻ 'at:' z
A ∆ 'hey' 'there' '.' '.' 'how' 'are' 'are' 'you' '.'➮ removeDoubles R ∆ i ⬌ a ⌥ aⁱ ≟ Rꕉ ♻ R ⬊ aⁱ $ Rロ ⫴ ' '// 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 ロ
// same as above. but sorted➮ numbersOnly $ a ⌶ '' ꔬ ➮ $ a◬0 <= 57 ロ ❄ ➮ $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⌥ ⟑sx ロ 's.x is not undefined'
multi line strings
Elfu supports multi line strings enclosed with opening '''\n
and closing '''
.
console 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 ➮ half $a a/2 A ∆ whole:∅ part:∅ ☛ A whole part ꔪ ∇ abc ꔪ 334455 ロ Aabc//{ whole: 200, part: 100 } 33 44 55
TODO: add support for simple name matching with ꔪ, like this:
obj ∆ a:1 b:2 ba ꔪ 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...'
lib.yy
➮ scan ロ '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