Skip to main content

Strings and Text

NumFu treats text as first-class data with powerful string operations. Let's explore how to work with strings in NumFu.


String Literals​

Basic Strings​

Strings are enclosed in double quotes:

"Hello, NumFu!"
"Programming is fun"
"" // Empty string

Escape Sequences​

Use backslash for special characters:

"Line 1\nLine 2"          // Newline
"Tab\tSeparated" // Tab character
"Quote: \"Hello\"" // Escaped quotes
"Backslash: \\" // Escaped backslash
"Unicode: \u03B1" // Unicode (α)

String Operations​

Strings are very similar to lists and share many operations with them. You can think of them as lists of characters.

Concatenation​

Join strings with the + operator:

"Hello" + " " + "World"     // "Hello World"
"NumFu" + "!" // "NumFu!"

// Multi-line concatenation
"This is a very long string " +
"that spans multiple lines"

Repetition​

Repeat strings with the * operator:

3 * "Ho"             // "HoHoHo"
"=" * 20 // "===================="
2* "NumFu " // "NumFu NumFu "

String Access and Properties​

Character Indexing​

Access individual characters with square brackets (just like elements in a list):

"Hello"[0]           // "H" (first character)
"Hello"[4] // "o" (last character)
"NumFu"[2] // "m"

Negative Indexing​

Count from the end with negative indices:

"Hello"[-1]          // "o" (last character)
"Hello"[-2] // "l" (second to last)
"Programming"[-1] // "g"

String Properties & Functions​

All of the functions shown below must be imported from the std standard library module. When running the examples, remember to import it at the top of your file (or in the REPL):

import * from "std"

String Length​

length("Hello")          // 5
length("") // 0
length("NumFu rocks!") // 12

Case Conversion​

toLowerCase("HELLO")     // "hello"
toUpperCase("world") // "WORLD"

String Testing​

contains("hello", "lo")    // true (substring exists)
contains("hello", "xyz") // false

Count Substrings​

count("The math is not mathing.", "math")
// 2 (two occurences of "math")

String Slicing​

Extract substrings using slice(string, start, end):

slice("Hello World", 0, 4)    // "Hello"
slice("Programming", 3, 6) // "gram"
slice("NumFu", 1, -1) // "umF" (from index 1 to end-1)

Splitting Strings​

Split a string into a list of strings by the specified separator: split(string, separator)

let text = "NumFu Programming Language" in
let words = split(text, " ") in
words // ["NumFu", "Programming", "Language"]

Joining Lists​

Join a list of strings with a separator: join(list, separator)

let words = ["NumFu", "Programming", "Language"] in
join(words, "-") // "NumFu-Programming-Language"

Template Strings & Formatting​

The format() function from std allows you to create formatted strings by inserting values into placeholders. It takes a string and the same number of additional arguments as there are placeholders ({}).

import format from "std"
format("Welcome to {}, {}!", "NumFu", "programmer")
// "Welcome to NumFu, programmer!"

format("Result: {} + {} = {}", 2, 3, 5)
// "Result: 2 + 3 = 5"

If you do not supply the correct number of arguments, an IndexError will be raised.

format("{} likes {}", "John")
// IndexError: Incorrect number of placeholders

Escape placeholders​

To escape placeholders and treat them as literal characters, enclose them in curly braces

format("Using placeholders {{}}, you can format {}", "strings")
// "Using placeholders {}, you can format strings"

Examples​

When running the examples below, remember to import the std standard library module at the top of your file (or in the REPL) because it provides essential functions for working with strings.

import * from "std"

Bordered Title​

let border = "=" * 50 in
let title = "NumFu Tutorial" in
let padding = ((50 - length(title)) / 2) in
border + "\n" +
" " * padding + title + "\n" +
border
==================================================
NumFu Tutorial
==================================================

Building Messages​

let name = "Alice" in
let age = 30 in
"Hello, " + name + "! You are " + String(age) + " years old."
// Hello, Alice! You are 30 years old.

String Validation​

let isValidEmail = {email ->
if count(email, "@") != 1 then false else
let splitted = split(email, "@") in
count(splitted[1], ".") > 0
&& splitted[1][-1] != "."
&& splitted[0][0] != "."
}

isValidEmail("user@example.com") // true
isValidEmail("userexample.com") // false
isValidEmail("user@email@example.com") // false
isValidEmail("user@example.com.") // false

String Processing​

Take a list of boolean options to determine whether to trim, lowercase, and replace spaces with underscores in the input text.

// Text processor factory
let makeTextProcessor = {options ->
let shouldTrim = options[0],
shouldLower = options[1],
shouldReplace = options[2] in
{text ->
let step1 = if shouldTrim then trim(text) else text in
let step2 = if shouldLower then toLowerCase(step1) else step1 in
let step3 = if shouldReplace then replace(step2, " ", "_") else step2 in
step3
}
}

let processor = makeTextProcessor([true, true, true]) in
processor(" Hello World ") // "hello_world"