Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions src/lib/indexExamples.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,24 @@ def main(): Unit \\ IO =
resume(dt.getHour())
}`;

export const libraryEffectsExample = `use Fs.FileRead
use Sys.Env
use Time.Clock
use Time.TimeUnit

/// The \`Clock\`, \`Env\`, \`FileRead\`, and \`Logger\`
/// effects all have default handlers, hence \`main\`
/// requires no explicit handlers.
def main(): Unit \\ { Clock, Env, FileRead, Logger } =
let ts = Clock.currentTime(TimeUnit.Milliseconds);
let os = Env.getOsName();
Logger.info("Timestamp: \${ts}");
Logger.info("Operating System: \${os}");
match FileRead.read("data.txt") {
case Ok(content) => Logger.info("Read: \${content}")
case Err(err) => Logger.warn("Error: \${err}")
}`;

export const regionExample = `///
/// We can implement a *pure* \`sort\` function which
/// internally converts an immutable list to an array,
Expand All @@ -125,6 +143,25 @@ def toString(l: List[a]): String with ToString[a] =
StringBuilder.toString(sb)
}`;

export const structsExample = `struct Person[r] {
name: String,
mut age: Int32
}

mod Person {
/// Creates a fresh \`Person\` in the region \`rc\`.
pub def mkPerson(name: String, rc: Region[r]): Person[r] \\ r =
new Person @ rc { name = name, age = 0 }

/// Increments the age of the given person \`p\`.
pub def birthday(p: Person[r]): Unit \\ r =
p->age = p->age + 1

/// Returns a description of the given person \`p\`.
pub def describe(p: Person[r]): String \\ r =
"\${p->name} is \${p->age} years old"
}`;

export const purityReflectionExample = `///
/// We can inspect the purity of a function argument.
///
Expand Down Expand Up @@ -264,6 +301,19 @@ def main(): Unit \\ IO =
println("Unable to write file")
}`;

export const terminationExample = `enum Tree[a] {
case Leaf(a)
case Node(Tree[a], Tree[a])
}

/// The compiler verifies that \`size\` is structurally
/// recursive and hence terminates on all inputs.
@Terminates
def size(t: Tree[Int32]): Int32 = match t {
case Tree.Leaf(_) => 1
case Tree.Node(l, r) => size(l) + size(r)
}`;

export const datalogExample = `def reachable(g: List[(String, Int32, String)], minSpeed: Int32): List[(String, String)] =
let facts = inject g into Road/3;
let rules = #{
Expand Down
126 changes: 111 additions & 15 deletions src/pages/index.astro
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ import {
purityExample,
polyEffectsExample,
effectsExample,
libraryEffectsExample,
regionExample,
structsExample,
purityReflectionExample,
parallelismExample,
concurrencyExample,
Expand All @@ -20,6 +22,7 @@ import {
monadicForExample,
applicativeForExample,
javaInteropExample,
terminationExample,
datalogExample,
latticeExample,
} from "../lib/indexExamples.js";
Expand Down Expand Up @@ -87,6 +90,9 @@ const vscodeSlides = [
<hr class="mb-3" />

<div class="row mb-4">
<div class="col-md-6">
<CodeSnippet code={adtExample} />
</div>
<div class="col-md-6">
<div class="card border-0">
<div class="card-body">
Expand All @@ -101,15 +107,9 @@ const vscodeSlides = [
</div>
</div>
</div>
<div class="col-md-6">
<CodeSnippet code={adtExample} />
</div>
</div>

<div class="row mb-4">
<div class="col-md-6">
<CodeSnippet code={recordExample} />
</div>
<div class="col-md-6">
<div class="card border-0">
<div class="card-body">
Expand All @@ -119,9 +119,15 @@ const vscodeSlides = [
</div>
</div>
</div>
<div class="col-md-6">
<CodeSnippet code={recordExample} />
</div>
</div>

<div class="row mb-4">
<div class="col-md-6">
<CodeSnippet code={purityExample} />
</div>
<div class="col-md-6">
<div class="card border-0">
<div class="card-body">
Expand All @@ -137,15 +143,9 @@ const vscodeSlides = [
</div>
</div>
</div>
<div class="col-md-6">
<CodeSnippet code={purityExample} />
</div>
</div>

<div class="row mb-4">
<div class="col-md-6">
<CodeSnippet code={polyEffectsExample} />
</div>
<div class="col-md-6">
<div class="card border-0">
<div class="card-body">
Expand All @@ -161,9 +161,15 @@ const vscodeSlides = [
</div>
</div>
</div>
<div class="col-md-6">
<CodeSnippet code={polyEffectsExample} />
</div>
</div>

<div class="row mb-4">
<div class="col-md-6">
<CodeSnippet code={effectsExample} />
</div>
<div class="col-md-6">
<div class="card border-0">
<div class="card-body">
Expand All @@ -178,7 +184,7 @@ const vscodeSlides = [
handlers enable program reasoning, modularity, and testability.
</p>
<p>
For example, the program on the right expresses a <code
For example, the program on the left expresses a <code
>greeting</code
> function that is pure modulo the current time of the day. In <code
>main</code
Expand All @@ -190,12 +196,42 @@ const vscodeSlides = [
</div>
</div>
</div>
</div>

<div class="row mb-4">
<div class="col-md-6">
<CodeSnippet code={effectsExample} />
<div class="card border-0">
<div class="card-body">
<div class="card-title"><h4>Library Effects</h4></div>
<p>
The Flix Standard Library comes with a rich collection of
built-in effects, including <code>Clock</code>, <code>Console</code
>, <code>Env</code>, <code>FileSystem</code>, <code>Http</code>, <code
>Logger</code
>, <code>Process</code>, and <code>Random</code>.
</p>
<p>
Every library effect has a default handler, hence programs can
use them without any handler boilerplate.
</p>
<p>
Library effects support composable middleware: HTTP requests can
be configured with retries and circuit breakers, and the
filesystem can be sandboxed, made read-only, or replaced with an
in-memory implementation, e.g. for testing.
</p>
</div>
</div>
</div>
<div class="col-md-6">
<CodeSnippet code={libraryEffectsExample} />
</div>
</div>

<div class="row mb-4">
<div class="col-md-6">
<CodeSnippet code={regionExample} />
</div>
<div class="col-md-6">
<div class="card border-0">
<div class="card-body">
Expand All @@ -219,8 +255,34 @@ const vscodeSlides = [
</div>
</div>
</div>
</div>

<div class="row mb-4">
<div class="col-md-6">
<CodeSnippet code={regionExample} />
<div class="card border-0">
<div class="card-body">
<div class="card-title"><h4>Mutable Structs</h4></div>
<p>
Flix supports mutable structs. Fields are immutable by
default, but can be marked with the <code>mut</code> modifier.
Like all mutable memory in Flix, every struct belongs to a
region.
</p>
<p>
Struct fields are unboxed, i.e. primitive fields do not require
indirection. This makes structs a memory efficient building
block for higher-level data structures, e.g. mutable lists,
stacks, and queues.
</p>
<p>
The fields of a struct are only visible from within its
companion module, providing compiler-enforced encapsulation.
</p>
</div>
</div>
</div>
<div class="col-md-6">
<CodeSnippet code={structsExample} />
</div>
</div>

Expand Down Expand Up @@ -465,6 +527,31 @@ const vscodeSlides = [
</div>
</div>

<div class="row mb-4">
<div class="col-md-6">
<CodeSnippet code={terminationExample} />
</div>
<div class="col-md-6">
<div class="card border-0">
<div class="card-body">
<div class="card-title"><h4>Termination Checking</h4></div>
<p>
Flix supports the <code>@Terminates</code> annotation, which
asks the compiler to verify that a function is structurally
recursive &mdash; and hence guaranteed to terminate on all
inputs.
</p>
<p>
The compiler checks that every recursive call is on a strict
substructure of a formal parameter. The check supports tree
recursion, functions with multiple parameters, local
definitions, and higher-order functions.
</p>
</div>
</div>
</div>
</div>

<div class="row mb-4">
<div class="col-md-12">
<div class="card border-0">
Expand Down Expand Up @@ -541,13 +628,15 @@ const vscodeSlides = [
<li>extensible records</li>
<li>parametric polymorphism</li>
<li>traits (i.e. type classes)</li>
<li>automatic trait derivation</li>
<li>higher-kinded types</li>
<li>associated types and effects</li>
</ul>
</div>
<div class="col-md-4">
<ul>
<li>effect polymorphism + subeffecting</li>
<li>default effect handlers</li>
<li>purity reflection</li>
<li>CSP-style concurrency</li>
<li>buffered &amp; unbuffered channels</li>
Expand All @@ -561,6 +650,7 @@ const vscodeSlides = [
<ul>
<li>monadic forM expressions</li>
<li>applicative forA expressions</li>
<li>string interpolation</li>
<li>expression holes</li>
<li>compilation to JVM bytecode</li>
<li>full tail call elimination</li>
Expand Down Expand Up @@ -850,6 +940,12 @@ const vscodeSlides = [
<td>utop</td>
<td>ghci</td>
</tr>
<tr>
<td>Test Framework</td>
<td>flix</td>
<td>OUnit, alcotest</td>
<td>HUnit, tasty</td>
</tr>
<tr>
<td>Build Tool</td>
<td>flix</td>
Expand Down