Not quite what you run in your browsers
If anyone has issues understanding syntax, interrupt or ask!
Clearer
Concise
Cleaner to refactor
// Define functions on their own
const addOne = (x) => x + 1
const two = addOne(1)
const someNumbers = [1, 2, 3]
// Pass functions as arguments
const someBiggerNumbers = someNumbers.map(addOne)
// [2, 3, 4]
// Return functions from functions
const createAddFunction = (x) => {
return (y) => y + x
}
const addUno = createAddFunction(1)// Error prone
const badProcessStudents = (students) => {
addExtraCredit(students)
curve(students)
markFailing(students)
return students
}
// Less error prone
const goodProcessStudents = (students) => {
const ecStudents = addExtraCredit(students)
const curvedStudents = curve(ecStudents)
const pfStudents = markFailing(curvedStudents)
return pfStudents
}const badUpdateGrade = (student) => {
student.grade = 10
}
const goodUpdateGrade = (student) => {
return {...student, grade: 10}
}
const badAddStudent = (students, student) => {
students.push(student)
}
const goodAddStudent = (students, student) => {
return [...students, student]
}
// Don't do this!
const curve = 1.10
const badCurve = (students) => {
for (student of students) {
student.grade = student.grade * curve
}
return students
}
// Do this
const goodCurve = (students, curve) => {
students.map(student => {
return {...student, grade: student.grade * curve}
})
}
Immutable.js
Cannot be changed after creation
Frees your mind from worrying about state
Enables lots of optimization techniques
Allows for easy creation of updated objects
Relies on immutable data structures
Is actually fast
Immutable JS objects are both!
import Immutable from require('immutable');
var map1: Immutable.Map<string, number>;
map1 = Immutable.Map({a:1, b:2, c:3});
var map2 = map1.set('b', 50);
map1.get('b'); // 2
map2.get('b'); // 50
// This is potentially faster than the spread operator
// For sure less memory intensiveconst students = [{name: "Kevin"}, {name: "Dan"}]
const gradedStudents = gradeStudents(students)
// What does gradedStudents look like?
// What does students look like?
const { List } = require('immutable')
const students = List([{name: "Kevin"}, {name: "Dan"}])
const gradedStudents = gradeStudents(students)
// What does gradedStudents look like?
// What does students look like?// Some people call this immutable
const students = [{name: "Kevin"}, {name: "Dan"}]
// But you can still do these things
students.push({name: "Cedric"})
students[0]["name"] = "K-Dog"
// You just can't do this
students = []Rambda is better
// Normal JS
const isUngraded = (task) => {
return !task.graded
}
// Normal JS with Rambda
const isRambdaUngraded = R.whereEq({graded: false})
const ungradedTasks = tasks.filter(isUngraded)
const rambdaUngraded = R.filter(isUngraded, tasks)
// Honestly, the benefits aren't really clear... yet// Normal JS
const getUngradedTasks = (tasks) => {
return tasks.filter(isUngraded)
}
// Rambda
const getRambdaUngradedTasks = R.filter(isUngraded)
// No tasks?!?!
// That's currying!const isGraded = R.whereEq({graded: true})
const hasZero = R.whereEq({grade: 0})
const isIncomplete = R.compose(isGraded, hasZero)
const getIncomplete = R.filter(isIncomplete)
const getParentEmail = R.pluck("parentEmail")
const getSadEmails = R.compose(getParentEmail, getIncomplete)const StudentHeader = ({ username }) => {
return <p>The logged in student is: {username}</p>
}
You have to squint a bit and work hard with Ember
Types help you understand transformations
const gradedStudents = gradeStudents(students)
// What does gradedStudents look like?
// What does students look like?
const { List } = require('immutable')
const gradedStudents = gradeStudents(students)
// What does gradedStudents look like?
// What does students look like?interface Student {
name: string;
graded: boolean;
grade: number;
parentEmail: string;
}
const kevin: Student = {
name: "Kevin",
graded: true,
grade: 75,
parentEmail: "kevinsdad@hotmail.com"
}
const gradeStudents: (students: Student[]): Student[] => {
...
}Fantasy Land gives you the tools to effectively describe all sorts of transformations
Text
Lots of options
import Html exposing (beginnerProgram, div, button, text)
import Html.Events exposing (onClick)
main =
beginnerProgram { model = 0, view = view, update = update }
view model =
div []
[ button [ onClick Decrement ] [ text "-" ]
, div [] [ text (toString model) ]
, button [ onClick Increment ] [ text "+" ]
]
type Msg = Increment | Decrement
update msg model =
case msg of
Increment ->
model + 1
Decrement ->
model - 1(ns example
(:require [reagent.core :as r]))
(def click-count (r/atom 0))
(defn counting-component []
[:div
"The atom " [:code "click-count"] " has value: "
@click-count ". "
[:input {:type "button" :value "Click me!"
:on-click #(swap! click-count inc)}]])