fble-0.5 (2025-07-13,fble-0.4-212-ga8f8ad0f)
In this tutorial we'll learn how to write command line programs that interact with the environment.
Until now we've been writing fble programs that use
/Core/Stdio/StringO%.Run to output a string:
String@ output = Str|'hello, world'; /Core/Stdio/StringO%.Run(output);
The /Core/Stdio% library provides a more general interface for writing
fble programs that allows you to access command line arguments, access
standard input, output, and error streams, read and write files, read
environment variables, and return an exit status.
The /Core/Stdio/IO%.Run function takes a Main@ function with the
following type:
<<@>@>@ Main@ = <<@>@ M@>(Stdio@<M@>, Monad@<M@>, List@<String@>) { M@<Bool@>; };
Here is an example hello world program using this more general interface:
# A hello world program using the Stdio@ interface. Main@ Main = <<@>@ M@>(Stdio@<M@> stdio, Monad@<M@> m, List@<String@> _args) { % O = /Core/Stream/OStream%(m); Unit@ _ <- m.do(O.PutLine(stdio.out, Str|'hello, world')); m.return(True); }; /Core/Stdio/IO%.Run(Main);
Let's break this down
<<@>@ M@>The Main@ function is polymorphic, parameterized by type M@. The
first two arguments to the function are stdio and m, which are
interfaces supported by the abstract type M@.
This says your main function can be used with any type M@ that
implements the Stdio@ and Monad@ interfaces. The
/Core/Stdio/IO%.Run function provides a concrete type of M@ for use
with the fble-stdio program.
The reason Main@ is polymorphic instead of hard coding the concrete type
for M@ provided by /Core/Stdio/IO%.Run is to make your main function
more general than just for use with fble-stdio. For example, you can
write test cases for your main function using a simulated environment.
Stdio@<M@> stdioThe Stdio@<M@> interface is defined as follows:
<<@>@>@ Stdio@ = <<@>@ M@> { *( # stdin stream IStream@<M@> in, # stdout stream OStream@<M@> out, # stderr stream OStream@<M@> err, # Open the named file for reading. # Returns an input stream for reading. Nothing if unable to open the file. (String@) { M@<Maybe@<IStream@<M@>>>; } read, # Open the named file for writing. # Returns an output stream for writing. Nothing if unable to open the file. (String@) { M@<Maybe@<OStream@<M@>>>; } write, # Gets an environment variable value. (String@) { M@<Maybe@<String@>>; } getenv ); };
The IStream@ and OStream@ are types for reading a sequence of bytes.
The Stdio@ interface represents bytes using the Int@ type:
<<@>@>@ IStream@ = <<@>@ M@> { M@<Maybe@<Int@>>; }; <<@>@>@ OStream@ = <<@>@ M@>(Int@) { M@<Unit@>; };
The fields in, out, and err let you read and write standard
input and output streams.
The fields read and write let you open files for reading and writing
respectively.
The field getenv lets you access the value of an environment variable.
Monad@<M@> mThe Monad@<M@> interface m provides a way to sequence operations.
This is needed to have a well defined order of operations when interacting
with input and output streams and files.
List@<String@> argsThe args argument is the list of command line arguments passed when
invoking the program. For example, if you ran your program as:
fble-stdio -p core -I . -m /Foo% -- hello there now
Then the value of args would be:
List[Str|'hello', Str|'there', Str|'now']
M@<Bool@>;The result of the Main@ program has type M@<Bool@>. If you return
True using m.return(True), your program will have exit status 0.
Otherwise your program will have exit status 1.
Write an fble program that prints out a sorted list of the command line arguments passed to it.
Write an fble program that outputs the length of a given file. Try passing the file via standard input and as a file path.
Write an fble program that repeatedly prompts the user for a number and outputs the largest number input so far.
This completes this tutorial series on the fble language. You now understand all the fble language features and can write interesting programs that interact with the environment on the command line. Go forth now and program.
Or you can head back to the Tutorials page for links
to debug and profiling guides.