Reason strings are delimited using double quotes (single quotes are reserved for the character type below).
let greeting = "Hello world!";
let multilineGreeting = "Hello
world!";
Special characters in the string need to be escaped:
let oneSlash = "\\";
To concatenate strings, use ^
:
let greetings = "Hello " ^ "world!";
There's a special syntax for string that allows
let greetingAndOneSlash = {|Hello
World
\
Hehe...
|};
Analogically speaking, it's like JavaScript's backtick string interpolation, except without needing to escape special chars, and without built-in interpolation of variables. Though you can trivially restore the latter functionality, as BuckleScript has done:
let world = {js|世界|js}; /* Supports Unicode characters */
let helloWorld = {j|你好,$world|j}; /* Supports Unicode and interpolation variables */
BuckleScript's special pre-processor can then look for such js
and j
markers around the string and transforms it into something else.
More string operations can be found in the standard library. For JS compilation, see the familiar JS.String
API bindings in the BuckleScript API docs. Since a Reason string maps to a JavaScript string, you can mix & match the string operations in both standard libraries.
https://twitter.com/jusrin00/status/875238742621028355
You have an expressive type system now! In an untyped language, you'd often overload the meaning of string by using it as:
var BLUE_COLOR = "blue"
var BLUE = "blue"; var RED = "red"; var colors = [BLUE, RED]
person["age"] = 24
if (audio.canPlayType() === 'probably') {...}
(ಠ_ಠ)The more you overload the poor string type, the less the type system can help you! Reason provides concise, fast and maintainable types & data structures alternatives to the use-cases above (e.g. variants, in a later section).
Under native compilation, Reason strings compile to a simple representation whose performance is straightforward to analyze, at the expense of sometimes requiring manual performance tuning. For example, naively concatenating strings like "hi " ^ "how " ^ "are " ^ "you?"
unnecessarily allocates the intermediate strings "are you?"
and "how are you?"
. In this case, prefer String.concat
. In a way, it's somewhat nice that the traditional runtime analysis we've learned in school can finally be useful again.
Under JavaScript compilation, a Reason string maps to a JavaScript string and vice-versa, so no such above concern or analysis opportunities.
Quoted string's feature of not escaping special characters enables neat DSLs like regular expression:
let r = Str.regexp {|hello \([A-Za-z]+\)|};
as opposed to
let r = Str.regexp "hello \\([A-Za-z]+\\)";
Though for JS compilation, you'd use [%bs.re]
and Js.Re
instead, since Str
is not available.
Reason/OCaml's emphasis on simplicity over cleverness can be seen here through its straightforward native string implementation. An overly sophisticated string implementation can sometimes backfire.
Reason has a type for a string with a single letter:
let firstLetterOfAlphabet = 'a';
Note: Char doesn't support Unicode or UTF-8.
A character compiles to an integer ranging from 0 to 255, for extra speed. You can also pattern-match (covered later) on it:
fun isVowel theChar => switch theChar {
| 'a' | 'e' | 'i' | 'o' | 'u' | 'y' => true
| _ => false
};