Guided Examples
This chapter is example-first: each section includes complete code you can copy into a .fss file and run directly.
Choose an example
| Start here when you want to… | Example |
|---|---|
| Read inputs and produce a result | Hello with script arguments |
| Learn branching without ceremony | FizzBuzz with for + match |
| Transform real data | Collections and pattern matching |
| Model recursive domain data | Recursive records and traversal |
| Split a script into modules | Imports + exports |
| Call a script from an application | An embedded pricing rule |
1) Hello with script arguments
This first example introduces:
- reading CLI arguments through
Env.Arguments, - pattern matching on lists,
- string interpolation.
let name =
match Env.Arguments with
| head :: _ -> head
| _ -> "Unknown"
Console.writeLine $"Hello {name} !"
Run it:
fscript hello.fss -- Ada
API references used here:
2) FizzBuzz with for + match
This example introduces:
- helper functions,
- modulo checks,
- tuple matching in
match.
let fizz n = n % 3 = 0
let buzz n = n % 5 = 0
for n in [0..20] do
match (fizz n, buzz n) with
| (true, true) -> Console.writeLine "Fizz Buzz"
| (true, _) -> Console.writeLine "Fizz"
| (_, true) -> Console.writeLine "Buzz"
| _ -> Console.writeLine $"{n}"
3) Collections and pattern matching
This example introduces:
List.filter,List.map,List.fold,List.tryHeadand option matching,- head/tail list patterns,
- map-pattern removal with
{ [key] = _; ..rest }.
let values = [1;2;3;4;5;6]
let evens = values |> List.filter (fun n -> n % 2 = 0)
let doubled = evens |> List.map (fun n -> n * 2)
let total = doubled |> List.fold (fun acc -> fun n -> acc + n) 0
Console.writeLine $"evens={evens}"
Console.writeLine $"doubled={doubled}"
Console.writeLine $"total={total}"
let firstEven = evens |> List.tryHead
match firstEven with
| Some x -> Console.writeLine $"first even: {x}"
| None -> Console.writeLine "no even value"
match doubled with
| head :: tail -> Console.writeLine $"head={head} tail={tail}"
| [] -> Console.writeLine "empty"
let scores = { ["a"] = 1; ["b"] = 2 }
let remove k m =
match m with
| { [key] = _; ..rest } when key = k -> rest
| _ -> m
let removedB = remove "b" scores
Console.writeLine $"scores without b = {removedB}"
4) Recursive records and traversal
This example introduces:
- recursive record types (
type rec), - optional child nodes,
- recursive tree traversal.
type rec Node =
{ Value: int
Left: Node option
Right: Node option }
let leaf1 = { Value = 4; Left = None; Right = None }
let leaf2 = { Value = 5; Left = None; Right = None }
let leaf3 = { Value = 6; Left = None; Right = None }
let leaf4 = { Value = 7; Left = None; Right = None }
let n2 = { Value = 2; Left = Some leaf1; Right = Some leaf2 }
let n3 = { Value = 3; Left = Some leaf3; Right = Some leaf4 }
let root = { Value = 1; Left = Some n2; Right = Some n3 }
let rec explore visit (node: Node) =
visit node
let exploreChild child =
match child with
| Some n -> explore visit n
| _ -> ()
exploreChild node.Left
exploreChild node.Right
let displayNode (node: Node) =
Console.writeLine $"{node.Value}"
explore displayNode root
5) Imports + exports (multi-file)
This example introduces:
import "..." as Alias,- top-level
[<export>]bindings, - using imported record types in exported functions.
File: includes/common.fss
type ProjectInfo = { Name: string; Language: string }
let describe_project project =
$"{project.Name} ({project.Language})"
let describe_command cmd =
$"step={cmd}"
let join_with_comma items =
String.concat ", " items
File: imports-and-exports.fss
import "includes/common.fss" as Common
[<export>] let extension_name = "demo"
[<export>] let summary (project: Common.ProjectInfo) =
let steps = [ "build"; "test"; "publish" ] |> List.map Common.describe_command
$"{Common.describe_project project}: {Common.join_with_comma steps}"
let main =
let project = { Name = "Terrabuild"; Language = "F#" }
Console.writeLine (summary project)
Console.writeLine $"Extension: {extension_name}"
main
6) An embedded pricing rule
This example shows the full product-facing loop: keep a business rule in FScript, export one intentional entry point, and invoke it from a JavaScript host.
File: pricing.fss
type Customer =
{ Plan: string
Seats: int }
[<export>] let quote (customer: Customer) =
let pricePerSeat =
match customer.Plan with
| "scale" -> 29
| "team" -> 19
| _ -> 9
pricePerSeat * customer.Seats
File: pricing.mjs
import { readFile } from "node:fs/promises";
import { load, invoke } from "@magnusopera/fscript";
const source = await readFile(new URL("./pricing.fss", import.meta.url), "utf8");
const script = load(source);
const result = invoke(script, "quote", [{ Plan: "scale", Seats: 12 }]);
console.log(result.value); // 348n
Install the package and run the host:
npm install @magnusopera/fscript
node pricing.mjs
The script owns the changeable rule. The host owns loading, input, output, and every external capability. For typed extern functions and production concerns, continue with the Fable and JavaScript host guide.
Suggested order
- Run example 1 and 2 to get comfortable with flow and syntax.
- Run example 3 to practice pattern matching on real data.
- Run example 4 to practice recursion with typed data.
- Run example 5 when you are ready for multi-file scripts and host-facing exports.
- Run example 6 when you are ready to cross the script/host boundary.
- Run the BASIC sample under
samples/basic/when you want to see FScript host a second language withPRINT,INPUT, jumps, and loops.