previous post <->
next post
I accidentally started playing SimCity3000 and it ate big amount of my time..
return
https://github.com/ujihisa/jinaw/commit/2dbc9ed0b3240d9081932c5a519a9767a3763ee4
return
is the only one feature to cancel executing the rest of statements, since there's no try/catch exception handling in this subset. Since the run-
function to sequentially execute statements isn't something like a loop but an explicit recursion, to implement return
, just simply don't recur.
(run '[(var f (function []
[(fcall 'console.log [1])
(return 9)
(fcall 'console.log [2])]))
(fcall 'console.log [(fcall 'f [])])])
This outputs 1 and 9 but not 2.
typeof
https://github.com/ujihisa/jinaw/commit/c499b1bc23a11799ffe119d8a974729c6936c4ad
JavaScript has a unary operator typeof
to tell the type of a value/variable-name.
> typeof 1
"number"
> var x = 1
> typeof x
"number"
> typeof y
"undefined"
Since typeof
isn't a function it has more power than functions; it also accepts undefined variables without throwing ReferenceError
.
(run '[(fcall 'console.log [(typeof 1)]);=> "number"
(var x 1)
(fcall 'console.log [(typeof x)]);=> "number"
(fcall 'console.log [(typeof y)]);=> "undefined"
(fcall 'console.log [(typeof (fcall '+ ['x 2]))])]);=> "number"
==
==
is one of the most difficult aspect of JavaScript. The behavior is too tricky to understand.
> 1 == ['1']
true
> [] == []
false
> [] == ''
true
> 1 == true
true
> 1 == 'true'
false
> '1' == true
true
According to specification, the definition of ==
is
If the two operands are not of the same type, JavaScript converts the operands then applies strict comparison. If either operand is a number or a boolean, the operands are converted to numbers if possible; else if either operand is a string, the other operand is converted to a string if possible. If both operands are objects, then JavaScript compares internal references which are equal when operands refer to the same object in memory.
Well, I couldn't clearly understand it. What if one operand is a number and the other is a boolean? What is an operand is a number but the other operand isn't possible to be converted? They aren't written.
I gave up and made one that works fine for now..
(run '[(fcall 'console.log [(fcall '== [1 1])]);=> true
(fcall 'console.log [(fcall '== [1 2])]);=> false
(fcall 'console.log [(fcall '== ["1" 1])]);=> true
(fcall 'console.log [(fcall '== ["1" 2])]);=> false
(fcall 'console.log [(fcall '== ["1" "1"])]);=> true
(fcall 'console.log [(fcall '== ["1" "2"])]);=> false
(fcall 'console.log [(fcall '== ["aaa" "aab"])])]);=> false
[]
https://github.com/ujihisa/jinaw/commit/8878e40f5a21f8a79067aa822d088db12cb87029
[]
is a unary operator for objects. Note that "object" is a hash-map or an array in JavaScript terminology. I named it as aref
borrowed from Ruby's parser which means array ref, since Clojure doesn't recognize '[]
as Symbol but as vector. To distinguish it with user-defined something which name is aref
, I named it as -aref
.
(run '[(fcall 'console.log [(fcall '-aref [{"0" "a" "1" "b" "2" "c"} 0])])]);=> "a"
(run '[(fcall 'console.log [(fcall '-aref [{"0" "a" "1" "b" "2" "c"} "1"])])]);=> "b"
(run '[(fcall 'console.log [(fcall '-aref [{"0" "a" "1" "b" "2" "c"} 3])])]);=> "undefined"
(run '[(fcall 'console.log [(fcall '-aref [{"0" "a" "1" "b" "2" "c"} "4"])])]); => "undefined"