Profile Lucas Sta Maria

I'm a third-year Computer Science and Mathematics student at Northeastern University interested in programming languages and developer tooling.

(λx.x x) (λx.x x)

ralgo

I am currently working on a Racket package that aims to provide useful data structures, such as options, ordered sets and maps, and more. I aim for these data structures to be functional, but enable mutation if needed.

Options

Options are heavily inspired from the interfaces of Rust.

As written in the documentation:

;; An [Option X] is one of:
;; - None
;; - [Some X]
;; and is used to represent a Maybe value -- a value that may be something or
;; nothing.

We have a function option? for determining if the passed in value is an Option – namely one of the none? or some? structs.

We have a function option-or which takes in two options – if the first is some?, then return that, else return the other option.

There is also option-or-else, which takes in an option and a function. If the option is some?, then return that, else return an option produced by the function. This is helpful since Racket is eagerly-evaluated, and if the backup option we want to return is complex or inefficient to construct, wrapping the computation in a function for later means that computation will only be performed when necessary.

We have several unwrapping functions:

  • option-unwrap which returns the value contained in the some? struct, or errors if none?.
  • option-unwrap-or which returns the value contained in the some? struct, or returns the backup value if none?.
  • option-unwrap-or-else which returns the value contained in the some? struct, or returns the value computed by the lambda if none? (for the same reason as option-or-else).

Here's a rather contrived example:

(define nums '(1 2 3 4 5 6))

(define (num->opt num)
  (if (even? num)
    (some num)
    (none)))

(define nums-opts (map num->opt num))

;; Sums the even numbers
(foldr + 0 (map (lambda (opt) (option-unwrap-or opt 0)) nums-opts))

We can also perform pattern matching on options; here is the implementation of option-unwrap:

;; Unwrap the value contained in the option if it is a `some?`, else surface
;; an error.
(define (option-unwrap opt)
  (option? . -> . any)
  (match opt
    [(some x) x]
    [_ (error 'option-unwrap "unwrapped an empty option")]))