Flix Examples ↩
Directory examples\ contains Flix code examples coming from various websites - mostly from the Flix project.
|
We currently support five ways to build/run/test our Flix code examples:
Build tool | Build file | Parent file | Environment(s) |
---|---|---|---|
cmd.exe |
build.bat |
MS Windows | |
sh.exe |
build.sh |
Any a) | |
ant.bat |
build.xml |
Any | |
gradle.exe |
build.gradle |
common.gradle |
Any |
make.exe b) |
Makefile |
Makefile.inc |
Any |
b) Default shell is
/bin/sh
as described in the online document Choosing the Shell.🔎 Command
examples\build.bat
allows us to clean, build and run all projects in directoryexamples\
, for instance before updating our Github repositoryflix-examples
with local changes.
areas
Example ▴
This project has the following directory structure :
> tree /a /f . | findstr /v /b [A-Z] | build.bat | build.gradle (..\common.gradle) | build.sh | build.xml | gradle.properties | Makefile (..\Makefile.inc) | pom.xml \---src +---main | Main.flix \---test TestMain.flix
Command build.bat -verbose run
3 generates the target file areas.jar
from the Flix source file src\main\Main.flix
and executes it :
> build -verbose run Copy 1 Flix source file to directory "target\areas\src\" Compile 1 Flix source file into directory "target\areas\build\" Create archive file "target\areas\artifact\areas.jar" Execute Flix program "target\areas\artifact\areas.jar" 2 :: 6 :: Nil 2 :: 6 :: Nil
During compilation we run the two Flix commands build
1 and build-jar
to successively generate the Java class files in subdirectory target\areas\build\
and the target file target\areas\artifact\areas.jar
:
> tree /a /f areas | findstr /v /b [A-Z] \---areas | .gitignore | areas.jar-test.txt | flix.toml | LICENSE.md | README.md +---artifact | areas.jar +---build | \---class (*.class) +---lib | \---cache +---src | Main.flix \---test TestMain.flix
Command build.bat -verbose test
generates the target file target\areas\areas.jar
from the Flix source files src\main\Main.flix
and src\test\TestMain.flix
and runs the tests:
> build -verbose test Copy 1 Flix source file to directory "target\areas\src\" Copy 1 Flix test source file to directory "target\areas\test\" Compile 1 Flix source file and 1 Flix test source file Create archive file "target\areas\artifact\areas.jar" Execute tests for Flix program "target\areas\artifact\areas.jar" Running 2 tests... PASS test01 415,8us PASS test02 89,5us Passed: 2, Failed: 0. Skipped: 0. Elapsed: 4,0ms.
🔎 We provide other ways to build/run/test our Flix code examples :
- Command
make.exe
reads its configuration from the two configuration filesMakefile
andMakefile.inc
(we can use option--silent
to hide the executed commands):> make run [ -d "target/areas" ] || "C:/opt/Git/usr/bin/mkdir.exe" -p "target/areas" cd "target/areas"; \ [ -d "build" ] || "C:/opt/jdk-temurin-21.0.4_7/bin/java.exe" -jar "C:\opt\flix\flix.jar" init && \ "C:/opt/Git/usr/bin/rm.exe" -f "src/Main.flix" && \ "C:/opt/Git/usr/bin/cp.exe" -r "F:/examples/areas/src/main/." src && \ "C:/opt/jdk-temurin-21.0.4_7/bin/java.exe" -jar "C:\opt\flix\flix.jar" build && \ "C:/opt/jdk-temurin-21.0.4_7/bin/java.exe" -jar "C:\opt\flix\flix.jar" build-jar "C:/opt/jdk-temurin-21.0.4_7/bin/java.exe" -jar "target/areas/artifact/areas.jar" 2 :: 6 :: Nil 2 :: 6 :: Nil > make --silent test Running 2 tests... PASS test01 806,3us PASS test02 115,4us Passed: 2, Failed: 0. Skipped: 0. Elapsed: 6,3ms.- Command
gradle.bat
reads its configuration from the two configuration filesbuild.gradle
andcommon.gradle
:> gradle run > Task :compileFlix > Task :run 2 :: 6 :: Nil 2 :: 6 :: Nil BUILD SUCCESSFUL in 15s 7 actionable tasks: 7 executed- Command
sh.exe
targets a Unix-like environment in the same way asbuild.bat
targets the Windows environment:> sh ./build.sh -verbose run Initialize directory "target/areas" Copy Flix source files to directory "target/areas/src" Copy Flix test source files to directory "target/areas/test" Compile 1 Flix source file to directory "target/areas/build" Create archive file "target/areas/artifact/areas.jar" Execute the JAR file "target/areas/artifact/areas.jar" 2 :: 6 :: Nil 2 :: 6 :: Nil
channels
Example ▴
This project has the following directory structure :
> tree /a /f . | findstr /v /b [A-Z] | build.bat | build.gradle | build.sh | build.xml | gradle.properties | Makefile \---src +---main | Main.flix \---test TestMain.flix
Command build.bat -verbose run
generates the target file target\channels\artifact\channels.jar
from the Flix source file src\main\Main.flix
and executes the target file :
> build -verbose run Copy 1 Flix source file to directory "target\channels\src\" Compile 1 Flix source file to directory "target\channels\build\" Create archive file "target\channels\artifact\channels.jar" Extract Flix runtime from archive file "C:\opt\flix\flix.jar" Add Flix runtime to archive file "target\channels\artifact\channels.jar" Execute Flix program "target\channels\artifact\channels.jar" 1 :: 2 :: 3 :: Nil
Note: The Flix command
build-jar
does not add the Flix runtime to the generated archive filetarget\channels\channels.jar
, so we need to update it with class files extracted fromflix.jar
and belonging to packageca.uwaterloo.flix.runtime
.
Without that additional step we get the following runtime error :> build -verbose run Copy 1 Flix source file to directory "target\channels\src\" Compile 1 Flix source file Create archive file "target\channels\channels.jar" Execute Flix program "target\channels\channels.jar" Exception in thread "main" java.lang.NoClassDefFoundError: ca/uwaterloo/flix/runtime/interpreter/Channel at Def%main%.invoke(Unknown Source) at Cont%Obj.unwind(Cont%Obj) at Ns.m_main%(Unknown Source) at Main.main(Main) Caused by: java.lang.ClassNotFoundException: ca.uwaterloo.flix.runtime.interpreter.Channel at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581) at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522) ... 4 more Error: Failed to execute Flix program "target\channels\artifact\channels.jar"
datalog-constraints
Example▴
This project has the following directory structure :
> tree /f /a . | findstr /v /b [A-Z] | build.bat | build.gradle | build.sh | build.xml | gradle.properties | Makefile \---src +---main | Main.flix \---test TestMain.flix
Command build.bat -verbose run
generates the target file target\datalog-constraints\datalog-constraints.jar
from the Flix source file src\main\Main.flix
and executes the target file :
> build -verbose run Copy 1 Flix source file to directory "target\datalog-constraints\src\" Compile 1 Flix source file into directory "target\datalog-constraints\build\" Create archive file "target\datalog-constraints\datalog-constraints.jar" Execute Flix program "target\datalog-constraints\datalog-constraints.jar" (C++, x86) :: (MiniScala, C++) :: (MiniScala, x86) :: (Scala, C++) :: (Scala, MiniScala) :: (Scala, x86) :: Nil
fibonacci
Example ▴
This example has the following directory structure :
> tree /f /a . | findstr /v /b [A-Z] | build.bat | build.gradle | build.sh | build.xml | gradle.properties | Makefile | pom.xml \---src +---main | Main.flix \---test TestMain.flix
Command build.bat -verbose run
generates the target file target\fibonacci\fibonacci.jar
from the Flix source file src\main\Main.flix
and executes the target file :
> build -verbose run Copy 1 Flix source file to directory "target\fibonacci\src\" Compile 1 Flix source file into directory "target\fibonacci\build\" Create archive file "target\fibonacci\artifact\fibonacci.jar" Execute Flix program "target\fibonacci\artifact\fibonacci.jar" 0 :: 1 :: 1 :: 2 :: 3 :: 5 :: 8 :: 13 :: 21 :: 34 :: Nil
Command build.bat -verbose test
generates the target file target\fibonacci\fibonacci.jar
from the Flix source files src\main\Main.flix
and src\test\TestMain.flix
and runs the tests:
> build -verbose test Copy 1 Flix source file to directory "target\fibonacci\src\" Copy 1 Flix test source file to directory "target\fibonacci\test\" Compile 1 Flix source file and 1 Flix test source file Create archive file "target\fibonacci\artifact\fibonacci.jar" Execute tests for Flix program "target\fibonacci\artifact\fibonacci.jar" Running 1 tests... PASS test01 1,0ms Passed: 1, Failed: 0. Skipped: 0. Elapsed: 5,8ms.
This example is slightly more complex than the others because it contains several source files, including the Scala source file Counter.scala
.
> tree /a /f . | findstr /v /b [A-Z] | build.bat | build.sh | build.gradle (..\common.gradle) | gradle.properties | Makefile (..\Makefile.inc) \---src +---main | Counter.scala | lambda-calculus.flix | Main.flix \---test TestMain.flix
🔎
Counter.scala
implements the stateful objectCounter
with one single methodgetNext()
. In source filelambda-calculus.flix
we callgetNext()
instead of???
(the "unimplemented" function) inside functionfreshVar()
in order to obtain a runnable example :def freshVar(): Int32 = // ??? import static Counter.getNext(): Int32 \ {}; getNext()
Concretely we perform two additional steps before calling the Flix commands build
and build-jar
:
- we compile
Counter.scala
into directorytarget\lambda-calculus\lib\
with the Scala commandscalac.bat
. - we create
target\lambda-calculus\lib\lib-lambda-calculus.jar
with the Java commandjar.exe
.
> build -debug clean run [build] Properties : _PROJECT_NAME=lambda-calculus [build] Options : _NIGHTLY=0 _VERBOSE=0 [build] Subcommands: _COMMANDS= clean compile run [build] Variables : "FLIX_HOME=C:\opt\flix" [build] Variables : "JAVA_HOME=C:\opt\jdk-temurin-21.0.4_7" [build] Variables : "SCALA_HOME=C:\opt\scala-2.13.12" [build] rmdir /s /q "F:\examples\lambda-calculus\target" [build] 00000000000000 Target : 'F:\examples\lambda-calculus\target\lambda-calculus\lambda-calculus.jar' [build] 20220924220123 Sources: 'F:\examples\lambda-calculus\src\main\*.flix' [build] _ACTION_REQUIRED=1 [build] "C:\opt\jdk-temurin-21.0.4_7\bin\java.exe" -jar "C:\opt\flix\flix.jar" init [build] xcopy /s /y "F:\examples\lambda-calculus\src\main" "F:\examples\lambda-calculus\target\lambda-calculus\src\" 1>NUL [build] "C:\opt\scala-2.13.12\bin\scalac.bat" -cp "C:\opt\flix\flix.jar" -d "F:\examples\lambda-calculus\target\lambda-calculus\lib" "F:\examples\lambda-calculus\target\lambda-calculus\src\Counter.scala" [build] "C:\opt\jdk-temurin-21.0.4_7\bin\jar.exe" cf "F:\examples\lambda-calculus\target\lambda-calculus\lib\lib-lambda-calculus.jar" -C "F:\examples\lambda-calculus\target\lambda-calculus\lib" . [build] "C:\opt\jdk-temurin-21.0.4_7\bin\java.exe" -cp "F:\examples\lambda-calculus\target\lambda-calculus\build" -jar "C:\opt\flix\flix.jar" build --explain [build] "C:\opt\jdk-temurin-21.0.4_7\bin\java.exe" -jar "C:\opt\flix\flix.jar" build-jar [build] "C:\opt\jdk-temurin-21.0.4_7\bin\java.exe" "-Xbootclasspath/a:F:\examples\lambda-calculus\target\lambda-calculus\lib\lib-lambda-calculus.jar" -jar "F:\examples\lambda-calculus\target\lambda-calculus\lambda-calculus.jar" Abs(1, Abs(0, Var(0))) [build] _EXITCODE=0
mutability
Example ▴
This example has the following directory structure :
> tree /f /a . | findstr /v /b [A-Z] | build.bat | build.gradle | build.sh | build.xml | gradle.properties | Makefile \---src +---main | Main.flix \---test TestMain.flix
Command build.bat
-debug run
generates the target file target\mutability\mutability.jar
from the Flix source file src\Main.flix
and runs the target file :
> build -debug run [build] Properties : _PROJECT_NAME=mutability [build] Options : _NIGHTLY=0 _VERBOSE=0 [build] Subcommands: _COMMANDS= compile run [build] Variables : "FLIX_HOME=C:\opt\flix" [build] Variables : "JAVA_HOME=C:\opt\jdk-temurin-21.0.4_7" [build] Variables : "SCALA_HOME=C:\opt\scala-2.13.14" [build] 00000000000000 Target : 'F:\examples\mutability\target\mutability\mutability.jar' [build] 20220908185859 Sources: 'F:\examples\mutability\src\*.flix' [build] _ACTION_REQUIRED=1 [build] "C:\opt\jdk-temurin-21.0.4_7\bin\java.exe" -jar "C:\opt\flix\flix.jar" init [build] xcopy /s /y "F:\examples\mutability\src" "F:\examples\mutability\target\mutability\src\" 1>NUL [build] "C:\opt\jdk-temurin-21.0.4_7\bin\java.exe" -jar "C:\opt\flix\flix.jar" build [build] "C:\opt\jdk-temurin-21.0.4_7\bin\java.exe" -jar "C:\opt\flix\flix.jar" build-jar [build] "C:\opt\jdk-temurin-21.0.4_7\bin\java.exe" -jar "F:\examples\mutability\target\mutability\mutability.jar" 1 :: 2 :: 3 :: Nil [build] _EXITCODE=0
named-arguments
Example ▴
Command gradle.bat run
(build.gradle
/common.gradle
) generates the target file target\named-arguments\named-arguments.jar
from the Flix source file src\main\named-arguments.flix
and executes the target file :
> gradle -Dnightly clean run > Configure project : Nightly build 'flix-2024-02-10.jar' was selected > Task :compileFlix > Task :run Player(1, 0) BUILD SUCCESSFUL in 18s 8 actionable tasks: 8 executed
This example has the following directory structure :
> tree /f /a . | findstr /v /b [A-Z] | build.bat | build.gradle | build.sh | build.xml | gradle.properties | Makefile \---src +---main | Main.flix \---test TestMain.flix
Command build.bat run
generates the target file target\primes\primes.jar
from the Flix source file src\main\Main.flix
and executes the target file :
> build run Using 'primes' 2 :: 3 :: 5 :: 7 :: 11 :: 13 :: 17 :: 19 :: 23 :: 29 :: Nil Using 'primes2' 2 :: 3 :: 5 :: 7 :: 11 :: 13 :: 17 :: 19 :: 23 :: 29 :: Nil
Command build.bat -verbose test
generates the target file target\primes\primes.jar
from the Flix source files src\main\Main.flix
and src\test\TestMain.flix
and runs the tests:
> build -verbose test Running 2 tests... PASS test01 892,4us PASS test02 278,4us Passed: 2, Failed: 0. Skipped: 0. Elapsed: 5,7ms.
records
Example ▴
This example has the following directory structure :
> tree /f /a . | findstr /v /b [A-Z] | build.bat | build.gradle | build.sh | build.xml | gradle.properties | Makefile | pom.xml \---src +---main | Main.flix \---test TestMain.flix
Command build.bat run
generates the target file target\records\artifact\records.jar
from the Flix source file src\main\Main.flix
and executes the target file :
> build run r1 = { 1, 2 } r2 = { 1, 2 } r1 == r2: true r3 = { 3, 2 }
Command build.bat run
generates the target file target\trees\artifact\trees.jar
from the Flix source file src\main\Main.flix
and executes the target file :
> build run 10
Command build.bat run
generates the target file target\type-aliases\artifact\type-aliases.jar
from the Flix source file src\main\Main.flix
and executes the target file :
> build run Map#{1 => Hello, 2 => World} Map#{1 => Ok(123), 2 => Err(Hello)}
Footnotes ▴
[1] Flix commands ↩
-
We give option
--help
to display the Flix commands :> "%JAVA_HOME%\bin\java.exe" -jar "%FLIX_HOME%\flix.jar" --help The Flix Programming Language v0.49.0 Usage: flix [init|check|build|build-jar|build-pkg|run ↲
|benchmark|test|repl|install|lsp] [options] <args>... Command: init creates a new project in the current directory. Command: check checks the current project for errors. Command: build builds (i.e. compiles) the current project. Command: build-jar builds a jar-file from the current project. Command: build-pkg builds a fpkg-file from the current project. Command: run runs main for the current project. Command: doc generates API documentation. Command: benchmark runs the benchmarks for the current project. Command: test runs the tests for the current project. Command: repl starts a repl for the current project, or provided Flix source files. Command: lsp port starts the LSP server and listens on the given port. port --args <a1, a2, ...> arguments passed to main. Must be a single quoted string. --entrypoint <value> specifies the main entry point. --explain provides suggestions on how to solve a problem. --github-token <value> API key to use for GitHub dependency resolution. --help prints this usage information. --json enables json output. --listen <port> starts the socket server and listens on the given port. --no-install disables automatic installation of dependencies. --threads <value> number of threads to use for compilation. --yes automatically answer yes to all prompts. --version prints the version number. The following options are experimental: --Xbenchmark-code-size [exp.] benchmarks the size of the generated JVM files. --Xbenchmark-incremental [exp.] benchmarks the performance of each compiler phase in incremental mode. --Xbenchmark-phases [exp.] benchmarks the performance of each compiler phase.. --Xbenchmark-frontend [exp.] benchmarks the performance of the frontend. --Xbenchmark-throughput [exp.] benchmarks the performance of the entire compiler. --Xlib <value> [exp.] controls the amount of std. lib. to include (nix, min, all). --Xno-optimizer [exp.] disables compiler optimizations. --Xprint-phase <value> [exp.] prints the AST(s) after the given phase(s). 'all' prints all ASTs. --Xbdd-threshold <value> [exp.] sets the threshold for when to use BDDs. --Xno-bool-cache [exp.] disables Boolean caches. --Xno-bool-specialcases [exp.] disables hardcoded Boolean unification special cases. --Xno-bool-table [exp.] disables Boolean minimization via tabling. --Xno-bool-unif [exp.] disables Boolean unification. (DO NOT USE). --Xno-qmc [exp.] disables Quine McCluskey when using BDDs. --Xsummary [exp.] prints a summary of the compiled modules. --Xparser [exp.] disables new experimental lexer and parser. <file>... input Flix source code files, Flix packages, and Java archives.
[2] Flix-managed project directory ↩
-
Flix project directories must have a special layout enforced by the Flix command
init
. For instance the documentation filesLICENSE.md
andREADME.md
must exist inside the project directory in order to run the Flix commandsbuild
,build-jar
, etc.> tree /a /f . | tail -n +3 F:\EXAMPLES\SAMPLE | LICENSE.md, README.md +---build +---lib +---src | Main.flix \---test TestMain.flix
[3] Flix nightly builds ↩
-
We can select the latest nightly build of the Flix library instead of the release version to generate the target JAR file for each of the above examples :
build.bat
supports the-nightly
option.make.exe
supports theNIGHTLY=1
property.gradle.bat
supports the-Dnightly
property.
areas
example :> build -verbose -nightly clean run Nightly build "flix-2024-08-16.jar" was selected Delete directory "target" Initialize Flix project directory "target\areas" Copy 1 Flix source file to directory "target\areas\src\" Compile 1 Flix source file into directory "target\areas\build\" Create archive file "target\areas\artifact\areas.jar" Execute Flix program "target\areas\artifact\areas.jar" 2 :: 6 :: Nil 2 :: 6 :: Nil
> make NIGHTLY=1 run [ -d "target/areas" ] || "C:/opt/Git/usr/bin/mkdir.exe" -p "target/areas" cd "target/areas"; \ [ -d "build" ] || "C:/opt/jdk-temurin-21.0.4_7/bin/java.exe" -jar "C:\opt\flix\flix-2024-08-16.jar" init && \ "C:/opt/Git/usr/bin/rm.exe" -f "src/Main.flix" && \ "C:/opt/Git/usr/bin/cp.exe" -r "F:/examples/areas/src/main/." src && \ "C:/opt/jdk-temurin-21.0.4_7/bin/java.exe" -jar "C:\opt\flix\flix-2024-08-16.jar" build && \ "C:/opt/jdk-temurin-21.0.4_7/bin/java.exe" -jar "C:\opt\flix\flix-2024-08-16.jar" build-jar "C:/opt/jdk-temurin-21.0.4_7/bin/java.exe" -jar "target/areas/areas.jar" 2 :: 6 :: Nil 2 :: 6 :: Nil
> gradle -Dnightly run > Configure project : Nightly build 'flix-2024-08-16.jar' was selected &g; Task :compileFlix > Task :run 2 :: 6 :: Nil 2 :: 6 :: Nil BUILD SUCCESSFUL in 15s 7 actionable tasks: 7 executed