Skip to content
Ilya Katun edited this page Jun 13, 2022 · 3 revisions

Welcome to the fundom wiki!

Why fundom?

It stands for "functional domain" as fundom is hugely inspired by series of talk on functional patterns and domain modelling by Scott Wlaschin and also hist book "Domain Modeling Made Functional: Tackle Software Complexity with Domain-Driven Design and F#"

fundom is aimed on providing simple and extensive set of features for developing systems with complex domain with functional programming.

Monads

Monad mainly is a combination of objects - container and binding function.

Container is some wrapper around value which provides some meta-data (or actual additional data).

Binding function is some function that describes rules of applying Container to some function.

pipe and future

Provides functionality for building sync pipelines. It provides 2 operator overloads - << and >> (see proposal) that execute next function based on wrapped into pipe variable. To exit pipe and unpack use pipe.finish method. future doesn't require finish usage as it is unpacked via built-in await statement.

Basically pipe operator just swaps argument on the left with argument on the right. For example in F#:

let (|>) v f = f v

let add a b = a + b

3 |> add 5
// ┌----------┐
// |          |
// |          V
// 3 |> add 5 3

With pipe and future following can be achieved:

result = await (
   pipe(b"http://...")
   << query.take                # from byte representation of route take query part after '?'; returns `Pipe[bytes]`
   << query.bytes_to_dict       # convert byte string to dictionary representation of query; returns `Pipe[dict[str, str]]`
   << query.bind_to(FindUsers)  # insert dictionary values into pydantic model; returns `Pipe[FindUsers]`
   >> database.find             # make async call to database; returns `Future[list[User]]`
)

future is mainly abstraction over asynchronous value. It allows to build async pipelines in sync context.

Maybe

We often have to work with None and perform checks if value is actually some value and not None. Commonly languages provide specific container for handling such values.

Container Meaning
Some Value is actually there, we work with something existing
Nothing Value is not present and the is Nothing to work with
Binding function Meaning
if_some Function will be executed only in case Some is passed
if_none Function will be executed only in case None is passed

⚠️ Important notice

pymon does not provide dedicated Some and Nothing containers, as it makes code more complex and we already have None. It provides only binding functions for existing None value that represents Nothing.

Clone this wiki locally