Kex
trait Inspectable
Types that can be rendered structurally, for a person reading output.
The rendering shows the value's STRUCTURE — quotes on strings, Just(...) around an optional — which is what makes it right for debugging and wrong for user-facing text. Showable is the other half of that pair.
Every type is inspectable through a structural fallback, so inspected and IO.inspect work on anything; a type that wants a different rendering overrides inspectValue.
[1, 2].inspected # => "[1, 2]"
Just("hi").inspected # => "Just(\"hi\")"
Implemented by Binary, Period, Date, Time, DateTime, URI, URL, Headers.
Provided methods
inspectValue
inspectValue(colors: Bool) -> String
Renders the value structurally, with ANSI colors when colors is true.
inspected and IO.inspect call this for you, passing the console's own color setting — call it directly only when you need to force one.
Parameters
colors- whether to include ANSI color escapes
Returns the rendered value
Examples
[1, 2].inspectValue(false) # => "[1, 2]"
trait Showable
Implemented by Binary, Optional<Showable>, Result<X, E>, Period, Date, Time, DateTime, URI, URL, Queue<A>, Set<A>, UnorderedSet<A>, Stack<A>, Headers.
Provided methods
extends Optional<Showable>
More methods of Optional, added by this module.
Implements Showable.
extends Result<X, E>
More methods of Result, added by this module.
Implements Showable.
The same for Result, with one deliberate asymmetry: SHOWING a result shows what it carries, so Ok(42) reads as 42 rather than leaking the wrapper into text — but an Error keeps its marker. Dropping it made a failure and a success print identically, and unlike None (which shows as "", visibly not a value) there would be nothing left to tell them apart.
The marker is spelled Error(...), matching how the same value renders as an ELEMENT of a collection — [1, Error(Bad(no))]. Elements render structurally rather than through showValue (as in Ruby, where nil.to_s is "" but [nil].to_s is "[nil]"), so this is the one spelling that reads the same at both levels.
What functions RETURN is unchanged: Integer.parse still answers with a Result, IO.inspect still shows Ok(42), and both arms are still matchable.
module Kex
The running toolchain: which backend, which version, which features.
Kex.BACKEND # => Interpreter
Kex.Kernel.VERSION.release # => "0.4.0"
Kex.Feature.has?(Kex.FS) # => true
BACKEND constant
BACKEND : Backend
Which backend is executing this program.
interpreted? and underBeam? below are the readable way to ask.
Examples
Kex.BACKEND # => Interpreter
interpreted? constant
Returns true when running on the tree-walking interpreter.
Examples
Kex.interpreted? # => true under `kex file.kex`
underBeam? constant
Returns true when running on the BEAM.
The backend a program is on decides what is available — processes and the web server need the BEAM (kex -R file.kex).
Examples
Kex.underBeam? # => true under `kex -R file.kex`
type Backend
Which backend is executing the program: the tree-walking Interpreter, or the Beam virtual machine.
Variants
InterpreterBeam
type Feature
An optional capability a build may or may not include. Ask about one with Kex.Feature.has? before relying on it.
Variants
FSProcess
module Kex.Kernel
record Version
The toolchain a program is running on. kex --version and the REPL banner report the same numbers.
revision is the git commit the compiler was built from — None when it was built from a source archive rather than a checkout, which is why it is an Optional rather than a String.
Examples
Kex.Kernel.VERSION.major # => 0
Kex.Kernel.VERSION.revision # => Just("a1b2c3d")
Kex.Kernel.VERSION.to(String) # => "0.3.0 (a1b2c3d)"
Fields
Methods
tuple
tuple : (Integer, Integer, Integer, String?)
The version's four values as a tuple, for destructuring.
A tuple cannot carry accessors of its own — there is no named type for a make block to target — so the record is the value and this is the view.
Returns major, minor, patch, revision
Examples
let (major, minor, patch, revision) = Kex.Kernel.VERSION.tuple
major # => 0
release
release : String
The three numbers, plus the pre-release channel when there is one.
0.4.0, or 0.4.0-rc.1 on a pre-release build. What a version RANGE is matched against, so the channel has to be in it.
Returns the release string
Examples
Kex.Kernel.VERSION.release # => "0.4.0-alpha.2"
number
number : String
The release string with the build revision after it, when there is one.
This is what kex --version and the REPL banner print.
to(String) — the language's conversion protocol, and what this should really be — is deliberately NOT defined here: a second to(String) implementation anywhere in the prelude breaks type-directed to dispatch for every prelude type on BEAM, so adding one here silently broke 3.kilo.watt.to(String). Pinned by spec/prelude_to_string_dispatch.kex; restore this as to(String) once that dispatcher is fixed.
Returns the full version string
Examples
Kex.Kernel.VERSION.number # => "0.4.0-alpha.2 (219e625)"
Reporting the toolchain in a tool's output
IO.printLine("built with Kex ${Kex.Kernel.VERSION.number}")
module Kex.Feature
Which optional capabilities this build includes.
Optional non-network capabilities in this build. Networking has its own granular opt-in Net.Support report.
module Kex.Interface
Reading the typed public surface of a compiled Kex module.
read
read(path: FS.FilePath) -> Any?
Reads the KexI interface chunk of a compiled Kex module — its typed public surface — and answers the decoded term, or None when the file has no such chunk, does not exist, or is not a BEAM artifact.
The term is an ordinary tree of tuples, lists, atoms, integers and strings, so it is walked with normal pattern matching and Tuple.items. This exists so that reading it needs no Erlang.* interop: it is the one intentional entry point rather than a general term decoder.
Parameters
path- the compiled .beam file to read
Returns the decoded interface term, or None
Examples
Kex.Interface.read("build/runtime/beam/kex_prelude.beam")
function inspected
inspected(value: Inspectable) -> String
Returns the pretty-printed representation of any value as a STRING — the same form the REPL echoes. Universal: reachable on every type through UFCS.
Named apart from inspect, which prints and returns its INPUT so it can be dropped into a pipeline. Both spellings used to be called inspect, and which one a call reached depended on whether it was written x.inspect or IO.inspect(x) — so [1, 2].inspect.count answered 24, the length of the rendered string, rather than 2.
Parameters
value- any value
Returns its rendered form
Examples
[1, 2].inspected # => "[1, 2]"
{ a: 1 }.inspected # => "{ a: 1 }"
{ "a": 1 }.inspected # => "{ \"a\": 1 }"
Just("hi").inspected # => "Just(\"hi\")"
Putting a rendering into a message
IO.printError("unexpected value: ${value.inspected}")
function inspect
inspect(value: A) -> A
Prints the pretty-printed form of value to stderr and returns value unchanged, so it can be dropped into any pipeline without changing what flows through it. The same operation as IO.inspect, reachable by UFCS.
Parameters
value- the value to show
Returns the same value, unchanged
Examples
[1, 2, 3, 4].map { |n| n * 3 }.inspect.filter(~even?)
# stderr: [3, 6, 9, 12] : [Int]
# => [6, 12]
Submodules
Kex.ASTParses Kex source code into a structured AST, at run time.