Strings
A feature central to C is string constants: you type "abc"
and you can pass it around, read the characters in it, and even do operations on it. Underneath it's really a pointer to a sequence of bytes initialized in memory for you, yet C makes it feel natural.
WebAssembly also gives you the ability to initialize a region of its memory with a string. But it doesn’t let you use the strings directly like C. Instead you must manually allocate memory addresses for each string constant, and then in functions hard-code the addresses, remembering what at what memory offset each string had.
Orb adds a simple string constant system like C’s by letting you use strings directly. At compile-time these strings are substituted by a tuple of their i32
memory address and i32
byte length, represented as the custom type Orb.Str
.
defmodule StaticHTMLPage do
use Orb
defw get_mime_type, Str do
"text/html"
end
defw get_body, Str do
"""
<!doctype html>
<meta charset="utf-8">
<h1>Hello world</h1>
"""
end
end
Building dynamic strings
Dynamic string concatentation is not supported in vanilla Orb as that requires a memory allocator which core WebAssembly doesn’t have. This is one of the batteries that comes with Orb‘s sister standard library SilverOrb.
Here’s an example rendering a dynamic HTML page:
defmodule DynamicHTMLPage do
use Orb
use SilverOrb.StringBuilder
global do
@hour_of_day 8
end
defw set_hour_of_day(hour) do
@hour_of_day = hour
end
defwp daytime?() do
@hour_of_day >= 6 and @hour_of_day <= 19
end
defw text_html, StringBuilder do
StringBuilder.build! do
"""
<!doctype html>
<meta charset="utf-8">
"""
if daytime?() do
"<h1>Hello 🌞 sunny world</h1>"
else
"<h1>Hello 🌛 moonlit world</h1>"
end
end
end
end
In modern web development we have components, and we can create simple components with SilverOrb.StringBuilder
too. Let’s extract the <h1>
rendering into its own component module:
defmodule HelloWorldComponent do
use Orb
use SilverOrb.StringBuilder
defwp daytime?(hour: I32), I32 do
hour >= 6 &&& hour <= 19
end
defw render(hour: I32), StringBuilder do
StringBuilder.build! do
"<h1>"
if daytime?(hour) do
"Hello 🌞 sunny world"
else
"Hello 🌛 moonlit world"
end
"</h1>\n"
end
end
end
defmodule DynamicHTMLPage do
use Orb
use SilverOrb.StringBuilder
Orb.include(HelloWorldComponent)
global do
@hour_of_day 8
end
defw set_hour_of_day(hour: I32) do
@hour_of_day = hour
end
defw text_html(), StringBuilder do
StringBuilder.build! do
"""
<!doctype html>
<meta charset="utf-8">
"""
HelloWorldComponent.render(@hour_of_day)
end
end
end