PureScript & Pux 
					
						bit.ly/purescript-pux-talk 
					
					
						bit.ly/purescript-pux-repo 
					
         
				
					
						Typed
					 
					
						Pure
					 
					
						Functional
					 
					
						
							PureScript is a typed, pure, functional programming language that
							compiles to JavaScript. It's inspired by Haskell, so if you're
							familiar with Haskell, or Elm it will look familiar.
						
					 
				 
				
					Typed 
					
						Types are known at compile time; they're static
					
					
						Types can be inferred by the compiler
					
					
						
							In PureScript, types are known at compile time. The developer can
							include type signatures, but isn't required to because the
							compiler can infer them. However, in practice they are almost never omitted.
						
					 
				 
				
					Pure 
					
						inputs -> outputs
					
					
						No side-effects
					
					
						
							All functions in PureScript are pure, which means they just map
							inputs to outputs and no matter how many times you call a function
							with the same input you'll get the same output.
						
						
							Pure functions are referentially transparent, which means you can
							replace the functional call with it's return value and there is
							no change to your program.
						
						
							Pure functions can't have side effects. No logging to the console,
							no Date/Time, no HTTP requests, and no DOM. These functions are
							not referentially transparent.
						
					 
				 
				
					Effects As Data 
					
						
Eff (Effect) Result
						
					 
					
						
f :: Eff (dom :: DOM) Location
g :: Eff (now :: NOW) Instant
h :: UserId -> Aff (ajax :: AJAX) User
						
					 
					
						
							So what good is a language that is made up of functions that can't
							do anything? I mean, eventually you're going to want to render
							something to the DOM, or get some data from a server, right?
						
						
							In pure languages, side-effects are encoded into types. PureScript
							uses the Eff type to wrap up all of the effects our program has.
						
						
							The type tells you the type of effect and the type of result
						
						
							Here are a few examples.
						
						
							Don't worry if this code makes no sense right now, what's
							important is that in PureScript we can look at the type and know
							whether or not it creates a side effect. What's more, we can know,
							just from the type, exactly what type of effect it is.
						
					 
				 
				
				Functional 
					
						Literally just programming with functions.
					
					
						
							A lot of time and effort has gone in to giving functional programming
							very involved definitions, but that's really all it is.
						
						
							You can program with functions in a lot of languages; JavaScript,
							Ruby, Scala, but they also allow you to program in other styles.
							PureScript, on the other hand, does not.
						
					 
				 
				
				
					Functions 
					
						
add :: Number -> Number -> Number
add x y = x + y
						
					 
					
						
add 10 11
						
					 
					
						
arrayMap :: (a -> b) -> [a] -> [b]
arrayMap = map
						
					 
					
						
							This is how a function is defined in PureScript. The first line
							is the type. It says "the function add takes two numbers and returns
							another number". The "::" separates the name from the type. The parameters
							are separated by "->" and the last item in the type is the return type.
						
						
							And this is how you call a function: the name of the function
							followed by the arguments, separated by spaces.
						
						
							Functions can also be polymorphic. The type of "arrayMap" says it takes
							a function from some type "a" to some type "b" and a list of "a's",
							and it will return a list of "b's". "a" and "b" are type variables.
							So this function works with any "a" and any "b", and it's important to
							note that "a" and "b" don't have to be different, but they can be.
						
					 
				 
				
					Data Types 
					
						
data RGB = Red | Green | Blue
						
					 
					
						
data Action = AddUser User | UpdateName String
						
					 
					
						
data User = User String Number
						
					 
					
						
							There are a couple of different ways to define data types in
							PureScript.
						
						
							Here we defined a type called RGB, with three possible values:
							"Red", "Green", or "Blue". The | in between each value means "or".
							This is called a sum, or union type. It's similar to an enum, but
							more powerful.
						
						
							This next example creates an "Action" type, with two possible
							values: "AddUser" or "UpdateName". This is another example of a
							sum type, but each of these comes with some extra information.
							"AddUser" comes with a "User" and "UpdateName" inlcudes a "String".
						
						
							In this final example, we have a data type for a "User" and in order
							to have a "User" it must have a "String" and a "Number". Unfortunately,
							we have no keys, so it's not clear what the String & Number are
							used for.
						
					 
				 
				
					Records 
					
						
type User =
  { name :: String
  , age :: Number
  }
						
					 
					
						
							Which brings us to records, which are like object literals
							in JavaScript; just simple key/value pairs. This version of User
							is essentially the same as the previous one, except we now have
							some context for those values.
						
						
							Here we are creating a type alias for a record. We're not
							introducing a new data type, instead what this says is, "We're
							going to call records that have a 'name' that is a String and an
							'age' that is a Number, a User".
						
						
							An important note with aliases is that they only provide a new way
							to talk about existing types, but no additional compile time
							benefits. If I create an alias for String and call it Name, it's
							still just a string. Functions that take a Name as an argument can
							still be called with any String.
						
					 
				 
				
					Newtype 
					
						
newtype Name = Name String
newtype Age = Age Number
newtype User = User { name :: Name
                    , age :: Age
                    }
						
					 
					
						
							A newtype is a way to wrap up an existing type. Like aliases, they
							give us a different way to talk about existing types, newtypes give
							us compile time benefits that aliases don't.
						
						
							One benefit of newtypes is that they come with no overheard. What
							that means is that the runtime representation is exactly the same
							as the existing type, but they are distinct from the point of view
							of the type system.
						
						
							newtypes allow us to write new typeclass instances for existing
							types. We'll touch on typeclasses in a moment, but this means that
							the newtype "Name" will be a string at runtime, but can have
							different behavior than a normal string; for example,
							in how we compare for equality.
						
					 
				 
				
					Pattern Matching 
					
						
							Pattern matching allows us to write function definitions based
							on the value of the input. It's very similar to a "switch" block.
						
					 
				 
				
					
						
royGeeBiv :: RGB -> String
royGeeBiv R = "Roy"
royGeeBiv G = "Gee"
royGeeBiv B = "Biv"
						
					 
					
						
							In this example, we provide a definition for each value of the "RGB"
							data type we defined earlier, and return a string.
						
					 
				 
				
					
						
data UserAccount =
    Guest
  | Authenticated { name :: String }
greetUser :: UserAccount -> String
greetUser Guest = "Wanna create an account"
greetUser (Authenticated { name }) = "Welcome back " <> name
						
					 
					
						
							Here we create a UserAccount type that is either a Guest,
							which has no additional data, or an Autheticated user with a name.
							We provide a definition for each and in the the Authenticated
							case we pull the name out and append it to the "Welcome back "
							message.
						
					 
				 
				
					
						
isItOne :: Int -> Boolean
isItOne 1 = true
isItOne _ = false
						
					 
					
						
							Pattern matches must be exhaustive, or your function must be
							explicitly marked as Partial, meaning it doesn't handle all inputs.
							You can exhaust all patterns either by handling each possible
							input or by using a catchall.
						
						
							Here we match the literal value 1, but it wouldn't be
							possible to match every possible Int value. Instead we use an
							underscore which matches any value. Patterns are checked
							in order, so they should be defined from most specific to least.
						
					 
				 
				
					Fancy Types 
					
						Monoid
					
					
						Functor
					
					
						Monad
					
					
						
class Eq a where
eq :: a -> a -> Boolean
						
					 
					
						
							Fancy types. If you're familiar with Elm, you might have heard this
							term used to describe some of the types in languages like Haskell
							or PureScript. Things like Monoid, Functor and Monad. Most of the
							time what people are talking about are typeclasses; which Elm
							doesn't have. Monoid, Functor & Monad are all typeclasses.
						
						
							A typeclass is just a way to abstract out common functionality. If
							you're familiar with interfaces in C# or Java, or templates in C++,
							it's the same idea.
						
						
							The reason they have a reputation for being "fancy" or "scary", in
							my opinion, is because things like Functor or Monad are more abstract
							that what most of use are used to.
						
						
							The "Eq" typeclass, for example, is much more concrete. It lets us
							define how equality works for our types. To make a data type an instance
							of this type class, or in C#/Java, to implement this interface, we
							need to write an eq function that can look at two values of our type
							and check for equality.
						
					 
				 
				
					Pux 
					
						Pux is a PureScript interface to React, similar to the Elm app
						It is a simple pattern for modular, nested components
						that are easy to test, refactor, and debug...
					 
					
						http://www.alexmingoia.com/purescript-pux/
					 
					
						
							Alright. On to Pux.
						
						
							Pux is a PureScript interface to React, similar to the Elm app
							architecture. It is a simple pattern for modular, nested components
							that are easy to test, refactor, and debug - making it simple and
							straightforward to build complex web applications.
						
						
							So what is the Elm Architecture?
						
					 
				 
				
					The Elm Architecture? 
					
						The Elm Architecture is a simple pattern for architecting webapps.
						It is great for modularity, code reuse, and testing.
					 
					
						https://guide.elm-lang.org/architecture/
					 
					
						
							The Elm Architecture is a simple pattern for architecting webapps.
							It is great for modularity, code reuse, and testing.
						
						
							The pattern breaks modules into three pieces. The "State", which
							represents the state of your application or component. An "Update"
							function which transforms your state based on "Action"s. And a "View"
							function that renders the "State".
						
						
							Users of Redux may recognize this pattern as it was the inspiration
							for the library.
						
					 
				 
				
					An Example 
					
						
							We're going to take a look at a counter app. Press a
							plus button and the count goes up. Press and minus button and it
							goes down.
						
					 
				 
				
					
						
data Action = Increment | Decrement
						
					 
					
				 
				
					
						
type State = Int
init :: State
init = 0
						
					 
					
						
							Next comes our State, and in this case we just going to use an Int,
							but we've given it an alias to make things easier to follow. We also
							give an initial state for our counter.
						
					 
				 
				
					
						
update :: Action -> State -> State
update Increment state = state + 1
update Decrement state = state - 1
						
					 
					
						
							Next is the Update function which takes an Action, the current state,
							and returns the new state. We pattern match on each type of Action
							and either increment or decrement the counter.
						
					 
				 
				
					
						
view :: State -> Html Action
view state =
  div
    []
    [ h1 [ className "page-title" ] [ text "Counter" ]
    , button [ onClick (const Increment) ] [ text "Increment" ]
    , span [] [ text (show state) ]
    , button [ onClick (const Decrement) ] [ text "Decrement" ]
    ]
						
					 
					
						
							Finally we have the View function which takes the current State
							and returns some Html that can perform the types of Actions we
							described above.
						
						
							Pux provides a DSL for constructing HTML. Each element type has a
							a corresponding function. Each element function takes two arguments,
							a list of attributes, and a list of children.
						
						
							So we have an H1, an increment button, a span that shows the count,
							and a decrement button. When the user clicks a button our Update
							function is called with the correct action, and state. Then the View
							function is called to render the new state.
						
					 
				 
				
				
				
					Why 
					
						
							So why would you want to program like this? Programming with pure
							functions, immutable data, and types puts a lot of restriction on
							the developer, what's the benefit? For me the benefit is in
							testing, reliability, and reasoning.
						
					 
				 
				
					
						Testing
					 
					
						
							When a function just maps inputs to outputs and can have no side
							effects, the testing is far simpler. There is no orchestration,
							mocking, etc. Adding types can completely eliminate entire
							classes of test.There's no need to test what some function, that
							is supposed to accept number, does when you give it a string.
						
					 
				 
				
					
						Reliability
					 
					
						
							A common saying in Haskell/PureScript/Elm languages is, "If it
							compiles, it works." This is mostly a joke, but there putting
							these constraints on your code greatly improves correctness leading
							to fewer Bugs. Richard Feldman of No Red Ink, the largest
							production user of Elm, is fond of saying that their Elm code has
							had zero runtime errors in over a year.
						
					 
				 
				
					
						Reasoning
					 
					
						
update :: Action -> State -> State
						
					 
					
						
							The case of reasoning is best described with an example.
						
						
							What can you tell me about what this function does? It could do a
							lot things really. We don't really know what it does, but we
							absolutely know what it doesn't do: It doesn't use anything other
							than some "Action" & "State", and it cannot have any effects; No
							logging, no HTTP requests, no DOM.
						
						
							But types can tell us a fair bit about what a function actually
							does. The types we use in our function can so limit what a function
							is allowed to do with it's arguments, that we can, in some cases
							be left with only one possible implementation. How that is possible
							is beyond the scope of this talk, unfortunately.
						
						
							By contraining ourselves to pure functions, static types, with
							effects built into the type system, we are able to understand much
							more about our code. Without them, we're left with names, and sifting
							through numerous lines of source code.