Published
Edited
Jan 10, 2020
Insert cell
Insert cell
{
// Define division using recursive subtraction
var div =
count =>
remainder =>
divisor =>
// Should we continue with recursion?
(divisor <= remainder)
// Yup, call div_next with an incremented counter, a new remainder
// (of the divisor subtracted from the old remainder) and the divisor
? div(count + 1)(remainder - divisor)(divisor)

// Nope, we've reached the end so return an object containing the
// the counter (now the quotient) and whatever is left over in the
// remainder
: { quotient : count
, remainder: remainder}

// Return the answers to 10/3, 12/6 and 5/9
return {
"10_divided_by_3" : div(0)(10)(3)
, "12_divided_by_2" : div(0)(12)(6)
, "5_divided_by_9" : div(0)(5)(9)
}
}
Insert cell
Insert cell
{
// Define division using recursive subtraction
var do_div =
count =>
remainder =>
divisor =>
// Should we continue with recursion?
(divisor <= remainder)
// Yup, call div_next with an incremented counter, a new remainder
// (of the divisor subtracted from the old remainder) and the divisor
? do_div(count + 1)(remainder - divisor)(divisor)

// Nope, we've reached the end so return an object containing the
// the counter (now the quotient) and whatever is left over in the
// remainder
: { quotient : count
, remainder: remainder}

// Create a "div" partial function in order to hide the need
// for the user to supply the initial quotient value
var div = do_div(0);
// Return the answers to 10/3, 12/6 and 5/9
return {
"10_divided_by_3" : div(10)(3)
, "12_divided_by_2" : div(12)(6)
, "5_divided_by_9" : div(5)(9)
}
}
Insert cell
Insert cell
// The Universal combinator
U = fn => fn(fn)
Insert cell
// The Y-Combinator
Y = (rec_fn =>
(gen_rec => U(gen_rec))
(gen_rec => rec_fn((n,a,b) => U(gen_rec)(n,a,b)))
)
Insert cell
{
// Use the Y-Combinator to perform recursive subtraction
var do_div =
div_next =>
count =>
remainder =>
divisor =>
// Should we continue with recursion?
(divisor <= remainder)
// Yup, call div_next with an incremented counter, a new remainder
// (of the divisor subtracted from the old remainder) and the divisor
? div_next(count + 1)
(remainder - divisor)
(divisor)
// Nope, we've reached the end so return an object containing the
// the counter (now the quotient) and whatever is left over in the
// remainder
: { quotient : count
, remainder: remainder}
// Now create the "div" function using the Y-Combinator and as we did
// before, also supply the initial quotient value
var div = Y(do_div)(0);
// Return the answers to 10/3, 12/6 and 5/9
return {
"10_divided_by_3" : div(10)(3)
, "12_divided_by_2" : div(12)(6)
, "5_divided_by_9" : div(5)(9)
}
}
Insert cell
Insert cell
{
// Treat parameter count as a quantity function instead of an integer
var do_div =
div_next =>
count =>
remainder =>
divisor =>
// Should we continue with recursion?
(divisor <= remainder)
// Yup, call div_next with an incremented counter, a new remainder
// (of the divisor subtracted from the old remainder) and the divisor
? div_next(lib.SUCC(count))
(remainder - divisor)
(divisor)
// Nope, we've reached the end so return an object containing the
// the counter (now the quotient) and whatever is left over in the
// remainder
: { quotient : lib.to_integer(count)
, remainder: remainder}

// Now that count is an abstract quantity function and not an integer,
// we must pass the quantity function ZERO as the start value for the
// quotient counter instead of integer 0
var DIV = Y(do_div)(lib.ZERO);
// Return the answers to 10/3, 12/6 and 5/9
return {
"10_divided_by_3" : DIV(10)(3)
, "12_divided_by_2" : DIV(12)(6)
, "5_divided_by_9" : DIV(5)(9)
}
}
Insert cell
Insert cell
{
// Treat remainder and divisor as abstract quantity functions instead of JavaScript integers
var do_div =
div_next =>
count =>
remainder =>
divisor =>
// Should we continue with recursion?
lib.to_boolean(lib.IS_LTE(divisor)(remainder))
// Yup, call div_next with an incremented counter, a new remainder
// (of the divisor subtracted from the old remainder) and the divisor
? div_next(lib.SUCC(count))
(lib.SUBTRACT(remainder)(divisor))
(divisor)
// Nope, we've reached the end so return an object containing the
// the counter (now the quotient) and whatever is left over in the
// remainder
: { quotient : lib.to_integer(count)
, remainder: lib.to_integer(remainder)}
}
Insert cell
Insert cell
{
// Convert the abstract Boolean function to a JavaScript Boolean value
var do_div =
div_next =>
count =>
remainder =>
divisor =>
// Should we continue with recursion?
lib.to_boolean(lib.IS_LTE(divisor)(remainder))
// Yup, call div_next with an incremented counter, a new remainder
// (of the divisor subtracted from the old remainder) and the divisor
? div_next(lib.SUCC(count))
(lib.SUBTRACT(remainder)(divisor))
(divisor)
// Nope, we've reached the end so return an object containing the
// the counter (now the quotient) and whatever is left over in the
// remainder
: { quotient : lib.to_integer(count)
, remainder: lib.to_integer(remainder)}
var DIV = val1 => val2 => Y(do_div)(lib.ZERO)(val1)(val2)
// Now we need to combine the two quantity functions into a PAIR
// before passing them to div
return {
"10_divided_by_3" : DIV(lib.TEN)(lib.THREE)
, "12_divided_by_2" : DIV(lib.TWELVE)(lib.SIX)
, "5_divided_by_9" : DIV(lib.FIVE)(lib.NINE)
}
}
Insert cell
Insert cell
{
var do_div =
div_next =>
count =>
remainder =>
divisor =>
// Should we continue with recursion?
lib.to_boolean(lib.IS_LTE(divisor)(remainder))
// Yup, call div_next with an incremented counter, a new remainder
// (of the divisor subtracted from the old remainder) and the divisor
? div_next(lib.SUCC(count))
(lib.SUBTRACT(remainder)(divisor))
(divisor)
// Nope, we've reached the end so return a PAIR formed from the
// the counter (now the quotient) and whatever is left over in the
// remainder
: lib.PAIR(count)(remainder)
var DIV = val1 => val2 => Y(do_div)(lib.ZERO)(val1)(val2)
// Extract the quotiernt and dividend parts of the result pair before converting
// them back to integers
return {
"10_divided_by_3_quotient": lib.to_integer(lib.HEAD(DIV(lib.TEN)(lib.THREE)))
, "10_divided_by_3_dividend": lib.to_integer(lib.TAIL(DIV(lib.TEN)(lib.THREE)))

, "12_divided_by_2_quotient": lib.to_integer(lib.HEAD(DIV(lib.TWELVE)(lib.SIX)))
, "12_divided_by_2_dividend": lib.to_integer(lib.TAIL(DIV(lib.TWELVE)(lib.SIX)))

, "5_divided_by_9_quotient": lib.to_integer(lib.HEAD(DIV(lib.FIVE)(lib.NINE)))
, "5_divided_by_9_dividend": lib.to_integer(lib.TAIL(DIV(lib.FIVE)(lib.NINE)))
}
}
Insert cell
Insert cell
{
// Remove the use of the JavaScript ternary operator
var do_div =
div_next =>
count =>
remainder =>
divisor =>
// Should we continue with recursion?
lib.IS_LTE(divisor)(remainder)
// Yup, call div_next with an incremented counter, a new remainder
// (of the divisor subtracted from the old remainder) and the divisor
(div_next(lib.SUCC(count))
(lib.SUBTRACT(remainder)(divisor))
(divisor))
// Nope, we've reached the end so return a PAIR formed from the
// the counter (now the quotient) and whatever is left over in the
// remainder
(lib.PAIR(count)(remainder))
var DIV = val1 => val2 => Y(do_div)(lib.ZERO)(lib.PAIR(val1)(val2));

// Extract the quotiernt and dividend parts of the result pair before converting
// them back to integers
return {
"10_divided_by_3_quotient": lib.to_integer(lib.HEAD(DIV(lib.TEN)(lib.THREE)))
, "10_divided_by_3_dividend": lib.to_integer(lib.TAIL(DIV(lib.TEN)(lib.THREE)))

, "12_divided_by_2_quotient": lib.to_integer(lib.HEAD(DIV(lib.TWELVE)(lib.SIX)))
, "12_divided_by_2_dividend": lib.to_integer(lib.TAIL(DIV(lib.TWELVE)(lib.SIX)))

, "5_divided_by_9_quotient": lib.to_integer(lib.HEAD(DIV(lib.FIVE)(lib.NINE)))
, "5_divided_by_9_dividend": lib.to_integer(lib.TAIL(DIV(lib.FIVE)(lib.NINE)))
}
}
Insert cell
Insert cell
{
// Remove the use of the JavaScript ternary operator
var do_div =
div_next =>
count =>
remainder =>
divisor =>
// Should we continue with recursion?
lib.IS_LTE(divisor)(remainder)
// Yup, call div_next with an incremented counter, a new remainder
// (of the divisor subtracted from the old remainder) and the divisor
(fn =>
(div_next(lib.SUCC(count))
(lib.SUBTRACT(remainder)(divisor))
(divisor))
(fn))
// Nope, we've reached the end so return a PAIR formed from the
// the counter (now the quotient) and whatever is left over in the
// remainder
(lib.PAIR(count)(remainder))
var DIV = val1 => val2 => Y(do_div)(lib.ZERO)(val1)(val2)

// Extract the quotient and dividend parts of the result pair before converting
// them back to integers
return {
"10_divided_by_3_quotient": lib.to_integer(lib.HEAD(DIV(lib.TEN)(lib.THREE)))
, "10_divided_by_3_dividend": lib.to_integer(lib.TAIL(DIV(lib.TEN)(lib.THREE)))

, "12_divided_by_2_quotient": lib.to_integer(lib.HEAD(DIV(lib.TWELVE)(lib.SIX)))
, "12_divided_by_2_dividend": lib.to_integer(lib.TAIL(DIV(lib.TWELVE)(lib.SIX)))

, "5_divided_by_9_quotient": lib.to_integer(lib.HEAD(DIV(lib.FIVE)(lib.NINE)))
, "5_divided_by_9_dividend": lib.to_integer(lib.TAIL(DIV(lib.FIVE)(lib.NINE)))
}
}
Insert cell
Insert cell
{
// Remove the use of the JavaScript ternary operator
var do_div =
div_next =>
count =>
remainder =>
divisor =>
// Should we continue with recursion?
lib.IS_LTE(divisor)(remainder)
// Yup, call div_next with an incremented counter, a new remainder
// (of the divisor subtracted from the old remainder) and the divisor
(fn =>
(div_next(lib.SUCC(count))
(lib.SUBTRACT(remainder)(divisor))
(divisor))
(fn))
// Nope, we've reached the end so return a PAIR formed from the
// the counter (now the quotient) and whatever is left over in the
// remainder
(lib.PAIR(count)(remainder))
var DIV = val1 => val2 => Y(do_div)(lib.ZERO)(val1)(val2)
var MOD = val1 => val2 => lib.TAIL(Y(do_div)(lib.ZERO)(val1)(val2))

// Reify the quantity function values returned by MOD for (10 mod 3), (12 mod 6) and (5 mod 9)
return {
"10_mod_3" : lib.to_integer(MOD(lib.TEN)(lib.THREE))
, "12_mod_2" : lib.to_integer(MOD(lib.TWELVE)(lib.SIX))
, "5_mod_9" : lib.to_integer(MOD(lib.FIVE)(lib.NINE))
}
}
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more