/ 4 min read
The 'use' Expression in Gleam
Everybody who knows Python has used the with
statement, most commonly when opening
a file.1
It’s quite powerful!
Gleam is a radically different type of language from Python.
It can be seen as a purely functional version of Rust.
We know that things are rather less obvious in purely functional languages.
So the question here is, how can we emulate the behavior of Python’s with
statement?
Another question is (due to the similarity of Rust and Gleam), how to emulate
Rust’s ?
syntax in Gleam?
‘use’ For Emulating the ‘with’ Statement in Python
In Python, this code
can be rewritten with the with
statement, resulting in a nice, less verbose
piece of code:
Conceptually, the with
statement can be thought of as a higher-order function
(a function that takes other functions) with a callback function as its last parameter.
The block inside the statement (ret = ...
above) is the body of the callback function.
In code, this is:
Assuming the functions open
, close
are available and behaving similarly to the
above, we can rewrite it one-to-one in Gleam.
(The type rtype
below is a generic type.)
What is the Gleam equivalent to the same code, written with the with
statement then?
It is this:
We can think of the first line use retval <- func(args)
as the direct counterpart
of with func(args) as retval
.
Note that all code under use .. <- ..
will be included in the body of callback
.2
If this is an undesirable behavior, we can make the scope similar
to Python’s by simply doing:
(Note that in Gleam, everything is an expression!)
‘use’ For Emulating ’?’ in Rust
Gleam is like a functional (garbage-collected) variant of Rust—they have many
similarities.
One of them is this: errors in Gleam and Rust are return values.
So, there is no throw-try-catch
as in Python or C-inspired languages.
The usual way we handle errors in Rust is by returning the type
Result<return_type, error_type>
.
Then, if we don’t want to do error handling in a function that calls a function
with the Result
type as the return value, we can simply return that error
when it occurs.
In code, this is:
Notice that we must do the pattern matching match
to handle the Result
type.
Notice also that if we don’t want to handle the error here, we have that line
Err(err_val) -> Err(err_val)
which is quite verbose.
In Rust, this can be concisely rewritten with ?
:3
Gleam also has the Result
type and use
can be used to do the same
thing as in Rust.
In Gleam, we can use result.map
to circumvent the need for pattern matching.4
But this is just the higher-order function pattern that we have seen before
in the previous section.
So, we can rewrite it more concisely with use
:
Notice the similarity as the Rust code with ?
!