Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Functional Core Imperative Shell
def feeding_time
walruses.each do |walrus| /* we know how to destructure walruses array */
walrus.stomach << Cheese.new /* we know the deep structure of a walrus object */
end
end
def feeding_time
walruses.each do |walrus| /* we still know how to destructure walruses array*/
walrus.eat(Cheese.new) /* but we dont know the deep structure of walrus */
end
end
class Walrus
def eat(food)
@stomach << food
end
end
/* walrus is a primitive, e.g. a struct */
def feeding_time
walruses.map do |walrus| /* map does not mutate walruses array, it creates new array of walruses*/
eat(walrus, "cheese")
end
end
/* this method does not mutate the input walrus, it creates a new walrus*/
def eat(walrus, food)
stomach = walrus.fetch(:stomach) + [food] /* new stomach */
walrus.merge(:stomach => stomach) /*new walrus */
end
def feeding_time
walruses.map do |walrus|
walrus.eat(walrus, "cheese") /* Compared to OO: this eat method returns a new walrus, it does NOT mutate the walrus object */
end
end
/*Compared to Functional: eat method constructs a new object, instead of a primitive */
class Walrus
def eat(food)
Walrus.new(@name, @stomach + [food]) /* returns new walrus instead of mutating @stomach of the current Walrus */
end
end

Functional Core

Functional cores make decisions (many code paths), but has every few dependencies (very well isolated)

Imperative Shell

Compose functional cores (many depencenies), but makes very few decisions (very few code paths).

Notes

  1. Buidling app around concepts of imperative shells and functional cores is like doing OO with Functional computations.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment