Quick tips
- If you need a module more than once, you can bind its atom to a shorter name:
L=lists,L:seq(1,100) - Specific functions can also be bound to shorter names:
L=fun lists:seq/2,L(1,100) - Specific functions with specific inputs can also be bound:
L=lists:seq(1,100),L - The
$syntax can be used for integers.$dinstead of100save 1 byte. But also,$breaks up tokens, so can be useful even if it's not shorter by itself.N rem$drem$instead ofN rem 100 rem 32. Unicode works too for larger integers! - Many Erlang functions that operate on "strings" actually operate on
iodata, which is a list that may contain code points, binary, and other otheriodata. This means that instead of concatenating together strings, you can sometimes put them in a list:"Foo"++"Fizz"++"Buzz"++"Bar"vs["Foo","Fizz","Buzz","Bar"]
Output
Erlang lacks a function that "just prints" a value, with or without a trailing \n. Instead, you have to pick (and possibly combine) cleverly. Also consider whether the text you want to print is the "standard syntax" of a number or atom.
erlang:display/1: This prints a trailing\n, anderlang:display(X)is shorter thanio:read(X),io:nl()(and it attempts to find strings inX).io:format/1/io:fwrite/1: Try usingio:read/1first. If that turns out unreliable, then prefer this overio:put_chars/1if possible due to its shorter name.io:format/2/io:fwrite/2: Formatted output.io:nl/0io:put_chars/1: This is a very "last resort" function. Try usingio:read/1first. If it's unreliable, it may still be shorter to replace~s with~~s (if any) and opt forio:format/1instead.io:read/1: Intended for reading input, but can also display a prompt that goes to stdout. This should be used for string output when you don't need special formatting. (The docs lie--it'll accept any term, not just strings.) Note: This function may be unreliable! Read below if you want to ensure your solution isn't flaky (it's often possible without resorting to longer functions).io:write/1: If possible (and reliable enough), try usingio:read/1first. Doesn't attempt to find strings.
io:read/1: The Last Call
If there are multiple calls to io:read/1, and the last call to io:read/1 is also the last call to any function in io, then this call (the "Last Call") may or may not print its argument, and this behavior can change between runs, seemingly at random.
erlang:display/1 is not an io function, and does not cooperate well with the Last Call; if the Last Call works, and erlang:display/1 is called at least once since then, then the output from the Last Call can appear after the output of any of the erlang:display/1 calls, either after or before the trailing \n, but never before the output of the first erlang:display/1 call.
Working around the Last Call
Remember that a printed "string" can be "deep", hence an expression like [io:read(f(I)) || I <- L] can often be written as io:read([f(I) || I <- L]) instead, to have only one call (the first call can't be the Last Call).
io:nl/0 is an io function, hence if you're using an io:read/1-then-io:nl/0 pattern to print a line, then this io:read/1 call is not the Last Call (as long as io:nl/0 is, in fact, called there).
If there's at most one erlang:display/1 call after the Last Call, and the Last Call's argument only contains whitespace, then, on code.golf, the Last Call will never print the whitespace (and thus consistent output is guaranteed), since trailing whitespace is truncated. This is counterproductive, however, if you do want the whitespace printed before the term.