Factory - A function which simplifies the construction of some test dependency (arguments, objects, etc.). Fixture - Any form of static test data. Test-Driven Development (TDD) - A programming discipline which emphasises writing tests as a part of code design, as easy of testing is a good indicator of code quality. Behavior-Driven Development (BDD) - A approach to writing tests which focuses on specification and user-facing behavior. Unit/System Under Test (SUT)/Test Subject — The simplest piece of self-contained functionality. It could be as simple as a method, or as complex as a class, but should be isolated sufficiently from collaborators. Test Case - One atomic test (usually implemented as a function) which runs some code and makes assertions about it. Test Double* - A generic term for any kind of pretend object used in place of a real object for testing purposes. Specific examples given below:
// 4! = 4 * 3 * 2 * 1 | |
// 5! = 5 * 4 * 3 * 2 * 1 | |
// 1! = 1 | |
// 0! = 1 | |
const factorial = (num) => { | |
let total = 1; | |
for(let i = 1; i <= num; i++) { | |
total *= i; | |
} |
// Given the linked list implementation below | |
// write a method which reverses the list. | |
function ListNode(data) { | |
this.data = data; | |
this.next = null; | |
} | |
class LinkedList { | |
constructor() { | |
this.head = null; |
const template = document | |
.createElement("template"); | |
template.innerHTML = `<span></span>`; | |
class MyTicker extends HTMLElement { | |
constructor() { | |
super(); | |
this.ticks = 0; | |
this.attachShadow({ mode: "open" }); | |
this.shadowRoot.appendChild( |
Over the last decade, the software industry has slowly been moving away from classical-inheritance in favor of more compositional patterns (mixins in Ruby, traits in Scala, etc.) and its begs the question: what happens to the OOP design patterns we've all come to know and love (or hate 😬) in a post-inheritance world? Additionally, what happens to these patterns when we have the full power of functional programming (first-class functions, partial application, monads, etc.) at our disposal?
These are the questions this article attempts to answer. So let's take another look at how the classical OOP design patterns patterns manifest themselves (if at all) in a functional programming language with support for objects. Although several superior languages fit this bill (OCaml, Lisp, etc.) my code examples are going to be in JavaScript, because of its approachable syntax and large user-base.
In my examples, I'll be using the object creation technique simliar to the one o
function namedCurry(source_fn, arg_order){ | |
function receiver( received_values, n_received, defaults ){ | |
received_values = (received_values || []).slice() | |
n_received = n_received || 0 | |
Object.keys(defaults).forEach(function( input_arg ){ | |
var value = defaults[ input_arg ] | |
var required_index = arg_order.indexOf( input_arg ) | |
var is_known_argument = required_index > -1 |
const Future = require('fluture'); | |
const R = require('ramda'); | |
const {Reader} = require('monet'); | |
const FakeDb = () => { | |
const data = { | |
1: {id: 1, name: 'bob', bff: 2}, | |
2: {id: 2, name: 'alice', bff: 1} | |
}; |
const Future = require('fluture'); | |
const R = require('ramda'); | |
const Reader = require('./monads/reader'); | |
// Setup | |
const FakeDb = () => { | |
const data = { | |
1: {id: 1, name: 'bob', bff: 2}, | |
2: {id: 2, name: 'alice', bff: 1} | |
}; |
module A | |
def msg | |
'hello' | |
end | |
end | |
module B | |
def msg | |
'hi' | |
end |
Level 1 (Loops) - (map
, reduce
, filter
, more).
Level 2 (Callbacks/Async) - Use Promise
s (or better yet, Future
s).*.
Level 3 (Assignment) - pipe
or compose
functions together to avoid unnecessary intermediate variable declarations.
A wild monad appears! Monet Olé!
Level 4 (null
/undefined
) - Use Maybe
monad.*.