let
statements
(* At top level, you can use `;;` (as if you were in a REPL) to end a `let` statement *)
let x=... and y=...;;code here
(* You can also chain let statements without any `;;` or `in` in between. *)
(* (This is only at top level, you cannot do this in a function, loop, etc.) *)
let x=... let y=...;;code here
(* Sometimes instead of `and` you can use tuples *)
let x=ref 2 and y=ref 3;;
let x,y=ref 2,ref 3;;
Redefining/defining operators
(Pretty much same as F#.) When defining functions, you can use an operator instead of a function name to often save bytes. You can either define a new one if you run out of space (add on another char like *+
), or just redefine an existing one (+
/-
/*
//
/^
/etc). Here's a precedence table.
For unary operators, the only one-byte option I know of is (!)
, but you can also redefine unary plus and minus with (~+)
and (~-)
(you can still call with -
/+
).
let(%)a b=a+b;;
print_int(1%6)
let(!)a=a+1;;
print_int !3
Conditionals
If you are using if
with a side effect, you can usually shorten it with &&
and ||
. Since both sides have to be booleans, you can just compare it with ()
(which is unit
).
if something then print_int 3 else print_string"hello";
something&&print_int 3=()||print_string"hello"=()
if something then a:=2;
something&&(a:=2)=();
Avoid reusing module names
List.length(List.filter(...)a);
List.(length(filter(...)a));
Sometimes it's shorter to use open
instead if using this syntax causes you to need a lot of ;;
s instead of in
or something:
let a=something;;let b=a+2;;Module.func(Module.func b)
Module.(let a=something in let b=a+2 in func(func b))
open Module;let a=something;;let b=a+2;;func(func b)
Printing hardcoded numbers
String.iter(fun x->Printf.printf"%d
"(Char.code x))"byte sequence"
Unfortunately with Unicode, this prints the bytes themselves instead of the codepoints. But it works if it's in ASCII.