System
module System
The running process and the machine under it: exiting, and asking what platform this is.
System.OS # => :macos
System.posix? # => true
System.exit(1) # ends the program with status 1
exit
exit(code: Integer) -> Void
Ends the process immediately with exit status code.
The invoking shell receives the code, so this is how a command-line tool reports success or failure to whatever ran it: 0 means success, anything else means failure.
Nothing after the call runs, and no cleanup happens: close what needs closing first.
Parameters
code- the exit status
Examples
Failing with a message
IO.printError("config not found")
System.exit(1)
Reporting a test run's result
System.exit(failures.empty? then 0 else 1)
OS constant
OS : OperatingSystem
The operating system family this program is running on.
Both backends answer with the same atom for the same machine. Prefer the macOS? / linux? / windows? / posix? predicates below when you are asking one yes-or-no question; use OS when you need to branch several ways.
Examples
System.OS # => :macos
Choosing a config location per platform
match System.OS do
:macos => "~/Library/Application Support/app"
:linux => "~/.config/app"
_ => "."
end
BITWIDTH constant
BITWIDTH : Integer
The machine's pointer width in bits: 64 on anything current, 32 on a small target.
Reported by the emulator on BEAM and by the pointer size in the tree walker, so both agree for one machine.
Examples
System.BITWIDTH # => 64
macOS? constant
macOS? : Bool
Returns true when running on macOS.
Examples
let opener = System.macOS? then "open" else "xdg-open"
linux? constant
linux? : Bool
Returns true when running on Linux.
Examples
if System.linux?
IO.printLine("using /proc")
end
windows? constant
windows? : Bool
Returns true when running on Windows.
Examples
let separator = System.windows? then "\\" else "/"
posix? constant
posix? : Bool
Returns true when the platform follows POSIX conventions for paths, separators and shell behaviour.
Everything the toolchain runs on except Windows behaves POSIX-ly enough for paths, separators and shell conventions. An unknown system is NOT assumed to be POSIX.
Examples
System.posix? # => true on macOS and Linux
Refusing to guess on an unrecognised platform
if !System.posix?
IO.printError("this tool assumes POSIX paths")
System.exit(1)
end
type OperatingSystem
The operating system families a program may be running on.
A union of atoms rather than an ADT: these are plain tags, and a match over them is still exhaustive. Anything unmodelled is :unknown: the union is closed, so callers can cover it.
Examples
Branching on the platform
match System.OS do
:windows => "\\"
:unknown => die("unsupported platform")
_ => "/"
end
function die
die : Never
die(message: String) -> Never
Ends the program with a fatal error message.
message goes to stderr behind a "fatal: " prefix and the exit status is 1. This is an abort, not an exception, so trying / rescue cannot catch it. Use it only where there is no recoverable answer. The prelude uses it for a negative repeat count, for instance.
Its result type is Never, the bottom type: die does not return, so a branch that dies takes the other branch's type, and if b == 0 then die("divide by zero") else a end is an Integer.
die is declared bare, like assert, so it is always in scope.
Parameters
message- the fatal message; omitted for a generic one
Returns never returns
Examples
die("unreachable state") # stderr: fatal: unreachable state
Using it in a branch that must produce a value
let denominator = if divisor == 0 then die("divide by zero") else divisor end