Haskell and Power Series Brought to Life
- not interested in convergence
- laziness lets you handle infinite series
- head/tail great for describing series
- operator overloading lets you redefine things to work on a power series (list of Nums) as well as Nums
- multiplication complication: can’t multiply power series by a scalar, since they’re not the same type
- could define negation as: negate = map negate
- instead of recursively: negate(x:xs) = negate x : negate xs
- once we define the product of two power series, we get integer powers for free, since it’s defined in terms of the product
- by using haskell’s head-tail notation, we can clear a forest of subscripts from our proofs
- reversion, or functional inversion, can be written as one line in haskell when you take this approach:
- revert (0:fs) = rs where rs = 0 : 1/(fs#rs)
- can define integral and derivative in terms of zipWith over a power series
- once we have integrals and derivatives, we can solve differential equations
- can use to express generating functions, which lets us do things like pascal’s triangle
- can change the default ordering of type use for constants in haskell to get rationals out of the formulas instead of floats
- default (Integer, Rational, Double)
- all formulas can be found on web page: ???
- somewhere on dartmouth’s site
- why not make a data type? why overload lists?
- would have needed to define Input and Ouput for the new data type
- but: for complex numbers, algebraic extensions, would need to define your own types to keep everything straight
- also: looks prettier this way
How to Learn Haskell in Less than 5 Years
- Chris Allen (bitemyapp)
- title derives from how long it took him
- though, he says he’s not particularly smart
- not steady progress; kept skimming off the surface like a stone
- is this talk a waste of time?
- not teaching haskell
- not teaching how to teach haskell
- not convince you to learn haskell
- WILL talk about problems encountered as a learner
- there is a happy ending: uses haskell in production very happily
- eventually made it
- mostly working through exercises and working on own projects
- spent too much time bouncing between different resources
- DOES NOT teach haskell like he learned it
- been teaching haskell for two years now
- was REALLY BAD at it
- started teaching it because knew couldn’t bring work on board unless could train up own coworkers
- irc channel: #haskell-beginners
- the guide: github.com/bitemyapp/learnhaskell
- current recommendations: cis194 (spring ’13) followed by NICTA course
- don’t start with the NICTA course; it’ll drive you to depression
- experienced haskellers often fetishize difficult materials that they didn’t use to learn haskell
- happy and productive user of haskell without understanding category theory
- has no problem understanding advanced talks
- totally not necessary to learn in order to understand haskell
- perhaps for work on the frontiers of haskell
- his materials are optimized around keeping people from dropping out
- steers them away from popular materials because most of them are the worst ways to learn
- “happy to work with any of the authors i’ve critized to help them improve their materials”
- people need multiple examples per concept to really get it, from multiple angles, for both good and bad ways to do things
- doesn’t think haskell is really that difficult, but coming to it from other languages means you have to throw away most of what you already know
- best to write haskell books for non-programmers
- if you come to haskell from js, there’s almost nothing applicable
- i/o and monad in haskell aren’t really related, but they’re often introduced together
- language is still evolving; lots of the materials from 90s are good but leave out a lot of new (and useful!) things
- how to learn: can’t just read, have to work
- writing a book with Julie (?) @argumatronic that will teach haskell to non-programmers, should work for everyone else as well; will be very, very long (longer than Real World Haskell)
- if onboarding new employee, would pair through tutorials for 2 weeks and then cut them loose
- quit clojure because he and 4 other clojurians couldn’t debug a 250 line ns
Production Web App in Elm
- app: web-based doc editor with offline capabilities: DreamWriter
- wrote original version in GIMOJ: giant imperative mess of jquery
- knew was in trouble when he broke paste; could no longer copy/paste text in the doc
- in the midst of going through rewrite hell, saw the simple made easy talk by rich hickey
- “simple is an objective notion” – rich hickey
- measure of how intermingled the parts of a system are
- easy is subjective, by contrast: just nearer to your current skillset
- familiarity grows over time — but complexity is forever
- simpler code is more maintainable
- so how do we do this?
- stateless functions minimize interleaving
- dependencies are clear (so long as no side effects)
- creates chunks of simpleness throughout the program
- easier to keep track of what’s happening in your head
- first rewrite: functional style in an imperative language (coffeescript)
- fewer bugs
- then react.js and flux came out, have a lot of the same principles, was able to use that to offload a lot of his rendering code
- react uses virtual dom that gets passed around so you no longer touch the state of the real dom
- got him curious: how far down the rabbit-hole could he go?
- sometimes still got bugs due to mutated state (whether accidental on his part or from some third-party lib)
- realized: been using discipline to do functional programming, instead of relying on invariants, which would be easier
- over 200 languages compile to js (!)
- how to decide?
- deal-breakers
- slow compiled js
- poor interop with js libs (ex: lunar.js for notes)
- unlikely to develop a community
- js but less painful?
- dart, typescript, coffeescript
- was already using coffeescript, so not compelling
- easily talks to js
- elm, purescript, clojurescript
- ruled out elm almost immediately because of rendering (!)
- cljs
- flourishing community
- mutation allowed
- trivial js interop
- purescript
- 100% immutability + type inference
- js interop: just add type signature
- functions cannot have side effects* (js interop means you can lie)
- so, decision made: rewrite in purescript!
- but: no react or flux equivalents in purescript (sad kitten)
- but then: a new challenger: blazing fast html in eml (blog post)
- react + flux style but even simpler and faster (benchmarked)
- elm js interop: ports
- client/server relationship, they only talk with data
- pub/sub communication system
- so, elm, hmm…
- 100% immutability, type inference
- js interop preserves immutability
- time travelling debugger!!!
- saves user inputs, can replay back and forth, edit the code and then replay with the same inputs, see the results
- decision: rewrite in elm!
- intermediate step of rewriting in functional coffeescript + react and flux was actually really helpful
- could anticipate invariants
- then translate those invariants over to the elm world
- made the transition to elm easier
- open-source: rtfledman/dreamwriter and dreamwriter-coffee on github
- code for sidebar looks like templating language, but is actually real elm (dsl)
- elm programs are built of signals, which are just values that change over time
- only functions that have access to a given signal have any chance of affecting it (or messing things up)
- so how was it?
- SO AWESOME
- ridiculous performance
- since you can depend on the function always giving you the same result for the same arguments, you can CACHE ALL THE THINGS (called lazy in Elm)
- language usability: readable error messages from the compiler (as in, paragraphs of descriptive text)
- refactoring is THE MOST FUN THING
- semantic versioning is guaranteed. for every package. enforced by the compiler. yes, really.
- diff tool for comparing public api for a lib
- no runtime exceptions EVER
- Elm is now his favorite language
- Elm is also the simplest (!)
- elm-lang.org