MonkeyTail web is a smart asynchronous programming language, powered by JavaScript.
Make a simple HTML file that includes mt.js
and write your MonkeyTail script in between script
tags with the type set to "text/mt"
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script src="mt.js" defer></script>
<title>MonkeyTail web demo</title>
</head>
<body>
<script type="text/mt">
5 * 8
</script>
</body>
</html>
Look at the console for the output of your scripts.
MonkeyTail web is functional in that every operation is a function. You pass values between functions using the @
symbol like this:
5 @ add 3 @ divide 2
You use the ;
symbol to end the function chain and start a new one:
5 @ add 3 @ divide 2 ; 3 @ add 8 //will return 11
Being functional also means that MonkeyTail has no operators like *
, but converts them to functions. This behavior is named 'shorthand resolving'. The following list describes the meaning of all shorthands:
'+'
: add'-'
: subtract'*'
: multiply'/'
: divide'%'
: modulo'^'
: power'**'
: power'>'
: greater than'<'
: less than'>='
: greater than or equal'<='
: less than or equal'=='
: equal'!='
: not equal'&'
: and'|'
: or'!'
: not'?'
: if (explained below)'<$>'
: set and get a variable'$>'
: only get a variable'>N'
: convert to a number'>S'
: convert to a string'>B'
: convert to a boolean'>L'
: convert to a list'>M'
: convert to a map'>D'
: convert to a date'>R'
: convert to a regex'#'
: get value of index of string, list or map'##'
: slice (get string of list values between indexes)'->'
: execute a lambda
Strings are defined by using <<
and >>
:
<<mt web is great!>> @ print // will print mt web is great!
Code between parentheses ()
is executed first, like in most programming languages. For example:
5 * (3 + 8)
But because all operators are functions, this would produce a mathematically wrong answer:
2 + 3 * 4 // will return 20
You instead have to write this:
2 + (3 * 4) // will return 14
When you set a variable like this:
5 <$> myNumber
it is bound to the current scope. Inner scopes can use them too, but you can also choose which variables an inner scope can access by using []
:
5 <$> myNumber ; [myNumber](myNumber * 3) // will return 15
If you use []
but do not specify variable names, the inner scope will not have access to any outer variable:
5 <$> myNumber ; [](myNumber * 3) // will throw an error
If you do not use []
, inner scopes will have access to all outer variables:
5 <$> myNumber ; (myNumber * 3) // will return 15
Code blocks work like scopes, but are defined using {}
. You can directly execute a code block using the ->
operator, or save it to a variable. Blocks do not automatically have access to outer variables, but you can still import them using []
:
5 <$> myNumber ; [myNumber]{ + myNumber * 3} -> 2
// will return 2 + 5 * 3 = 21 in MonkeyTail
As you can see, you can pass an argument to execute a block. Inside the block, that argument is passed as start of the function chain.
Variables are imported when a block is defined, not when it is executed.
If statements look like this:
5 < 8 ? {3 * 2} {4 + 1}
The boolean result of <
is passed to the ?
operator, the 'if statement' in MonkeyTail. If the boolean is true, then the first code block (the second argument) is executed. If the boolean is false, then the second code block (the third argument) is executed.
The following list contains all shorthands and their equivalent code:
'+': '@ add'
'-': '@ subtract'
'*': '@ multiply'
'/': '@ divide'
'%': '@ modulo'
'^': '@ power'
'**': '@ power'
'>': '@ greater'
'<': '@ less'
'>=': '@ greaterEqual'
'<=': '@ lessEqual'
'==': '@ equal'
'!=': '@ notEqual'
'&': '@ and'
'|': '@ or'
'!': '@ not'
'?': '@ if'
'<$>': '@ variable true'
'$>': '; variable null false'
'>N': '@ convert number'
'>S': '@ convert string'
'>B': '@ convert boolean'
'>L': '@ convert list'
'>M': '@ convert map'
'>D': '@ convert date'
'>R': '@ convert regex'
'#': '@ index'
'##': '@ slice'
'->': '@ execute
These are all functions, with argument types, return type and explanation:
wait any number : any
: wait specified time in milliseconds and return first argumentfetch string : map
: fetch json from uriadd any any : any
: add the two argumentssubtract number number : number
: subtract arg 2 from arg 1multiply number number : number
: multiply the two argumentsdivide number number : number
: divide arg 1 by arg 2modulo number number : number
: modulo arg 1 by arg 2power number number : number
: arg 1 to the power of arg 2sqrt number : number
: square root of argumentabs number : number
: absolute value of argumentfloor number : number
: round argument down to integerceil number : number
: round argument up to integerround number : number
: round argument to nearest integergreater number number : boolean
: is a greater than bless number number : boolean
: is a less than bgreaterEqual number number : boolean
: is a greater than or equal to blessEqual number number : boolean
: is a less than or equal to bequal any any : boolean
: is a equal to bnotEqual any any : boolean
: is a not equal to band : boolean boolean : boolean
: are a and b trueor boolean boolean : boolean
: is a or b truenot boolean : boolean
: is the argument falseif boolean block block : any
: if statement (explained above)type any : string
: type of argumentlength any : number
: length of argument (string or list)print ...any : any
: print all arguments and return first argumentconvert any string : any
: convert argument to typevariable any boolean string
: if boolean is true, set variable to first argument. Return variable with last argument as namelist ...any : list
: convert arguments to listmap ...any : map
: convert argument key value pairs to mapgetIndex any any : any
: get value at indexslice
: get value of index of string, list or mapexecute
: execute a lambda