It's hard to be a cat functional programmer.
Concepts that are common or required in functional languages or functional programming styles. We're talking about this because it's hard to learn functional programming. We'll be going through some basic concepts at a high level. For each term, we'll see the following: * A formal definition * Two code examples (where applicable): * Javascript or Ruby * HaskellSome examples can be better
module Main where beginConceptsOfFP = beginTalk loadConcepts createTalk talkTitle where talkTitle = "Concepts of Functional Programming"
A formal system for expressing computation based on function abstraction and application using variable binding and substitution.
ZERO = -> p { -> x { x } } ONE = -> p { -> x { p[x] } } TWO = -> p { -> x { p[p[x]] } } THREE = -> p { -> x { p[p[p[x]]] } }
Coding With Nothing - Tom Stuart
Unchanging over time or unable to be changed
var mutablePerson = new MutablePerson("Bradley", "Spaulding"); mutablePerson.name; // => "Bradley Spaulding" mutablePerson.firstName = "Charlie"; mutablePerson.name; // => "Charlie Spaulding" var immutablePerson = new ImmutablePerson("Bradley", "Spaulding"); immutablePerson.name; // => "Bradley Spaulding" immutablePerson.firstName = "Charlie"; // => Error!Easier to demonstrate in terms of its opposite. In a dynamically typed language, violating immutability would be a runtime error. In a statically typed language, violating immutability would be a compilation error.
deferring the computation of a value until the value is required by another computation
irb> (1..Float::INFINITY).lazy.map {|n| n * n }.first(10) => [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
ghci> take 10 (map (\n -> n * n) [1..]) [1,4,9,16,25,36,49,64,81,100]
ghci> let fibs = 1 : 1 : zipWith (+) fibs (tail fibs) ghci> take 10 fibs [1,1,2,3,5,8,13,21,34,55]
A function that receives a function as an argument...
var downloadAllCatPhotos = function() { // ... }; document.addEventListener('DOMContentLoaded', downloadAllCatPhotos);
and/or returns a function as its result...
var zero = function(p) { return function(x) { return x; }; } var one = function(p) { return function(x) { return p(x); }; } var two = function(p) { return function(x) { return p(p(x)); }; }
var Y = function(le) { return function(f) { return f(f); }(function(f) { return le( function(x) { return (f(f))(x); } ); }); };We *sort of* do this all the time in ruby when we pass blocks around. We absolutely do this in javascript when we use event handlers.
transforming a function that takes multiple arguments in such a way that it can be called as a chain of functions, each with a single argument
var add = function(a,b) { return a + b; }; add(3,4); // => 7
var curriedAdd = function(a) { return function(b) { return a + b; }; }; curriedAdd(3)(4); // => 7
Prelude> let add a b = a + b Prelude> add 3 4 7 Prelude> :t add add :: Num a => a -> a -> a
the process of fixing, or binding, a number of arguments to a function, producing another function of smaller arity
var add = function(x,y) { return x + y; }; add(1,2); // => 3 var add1 = function(x) { return add(1,x); }; add1(2); // => 3
Prelude> let add a b = a + b Prelude> :t add add :: Num a => a -> a -> a Prelude> let add1 = add 1 Prelude> :t add1 add1 :: Integer -> Integer
checking a perceived sequence of tokens for the presence of the constituents of some pattern
used as a conditional programming construct
length [] = 0 length (head:tail) = 1 + length tail
factorial 0 = 1 factorial n = n * factorial (n - 1)
a type formed by combining other types
data Maybe a = Nothing | Just a
data Tree a = EmptyTree | Node a (Tree a) (Tree a)
A mapping between types.
(1..100).map(&:to_s) # to_s is a functor!
class Functor f where fmap :: (a -> b) -> f a -> f b
data Maybe a = Nothing | Just a
instance Functor Maybe where fmap f (Just x) = Just (f x) fmap f Nothing = Nothing
ghci> fmap (*2) (Just 200) Just 400 ghci> fmap (*2) Nothing NothingComes from category theory in mathematics, where you're mapping values between categories. A common analog in OO might be a constructor function, which creates a new type from other types. Note that in haskell, the typeclass Functor refers also to the thing that can be mapped over. i.e: lists, trees, custom data types, etc. Links: * http://learnyouahaskell.com/making-our-own-types-and-typeclasses#the-functor-typeclass
aka Applicative Functor
a functor that can be applied to a specific data type*
*This is my own definition, because I couldn't find a good one.
instance Applicative Maybe where pure = Just Nothing <*> _ = Nothing (Just f) <*> something = fmap f something
ghci> Just (+3) <*> Just 9 Just 12 ghci> pure (+3) <*> Just 10 Just 13 ghci> pure (+3) <*> Just 9 Just 12 ghci> Just (++"hahah") <*> Nothing Nothing ghci> Nothing <*> Just "woot" NothingA functor is just a function that takes one type and returns another. An applicative functor also specifies how to operate on complex data types. kind of like defining an instance method on a class, only without any concept of a containing state Provides more structure than a Functor, but less than a Monad. There's one more big concept, and it builds on applicatives. With Applicative Functors, we can run computations on generic data types. We can take an arbitrary data type, and an arbitrary computation, and combine them. What we're missing is a structure for composing these operations. Enter the unreasonably scariest word of them all: Monad
a structure that represents computations defined as sequences of steps
3 components:
$('/slow-data.json') .then(filterBySearchParameters({ // some query info ... }); .then(updateView(theView)) .fail(reportError);
main = do json <- getURL '/slow-data.json' data <- parseJSON json filtered <- filterBySearchParameters queryInfo return updateView theView filtered
reactive programs are defined as a series of data transformations operating on streams
user input can be modeled as a data stream!
More to come in a later talk...
Thanks!