7 ms·
One thing I've learned from using immutable, functional languages (Elixir) is: "Don't tell your computer what to do, tell it how to transform data" While it m
by 1_player 11y ago
One thing I've learned from using immutable, functional languages (Elixir) is:
"Don't tell your computer what to do, tell it how to transform data"
While it may seem obvious, it's been a revelation for me and it has totally changed how I write code, and especially how I test it.
In the example they read some command line arguments, read an input file, and process it. The natural instinct it to implement it exactly as it reads.
You can't do that on a functional language, you need to reframe it into:
1) Transform command line arguments to some symbol representing the action to execute.
2) Transform a file name into a string representing the file contents.
3) Transform a string (file contents) into some data structure generated by processing it.
For example, in an Elixir pseudocode:
command = parse_command_line(argv)
case command do
{:process, file} ->
contents = read_file(file)
output = analyze(contents)
_ ->
print_usage()
end
Now each of these functions can be tested by itself and doesn't require mocking. They are just pure functions transforming input arguments into something else.
But there's no error handling: Elixir would solve that very elegantly with both pipelines and pattern matching:
parse_command_line(argv)
|> read_file
|> analyze
|> output_result_or_error
Each of these functions accepts and returns a tuple of {output, error}, and, if "error" is set, we just don't do anything but pass it down the pipeline. Basically the Either monad from Haskell.
Errors-as-values are much better than exceptions for this exact use case. Exceptions are hard to test, to replicate, to inject, while in this example you can just test error handling by.. passing an error value to the function.
- kwhitefoot 11y agoAgreed, but I'd like to point out that you can write in functional style in pretty much any language. Most of my professional life involves VB.net which is mostly object oriented (for some value of object oriented) and procedural but I try to write as much of the code as possible as functions with no side effects. The biggest problem is convincing my colleagues to do the same.