- purity is a syntactical property of programs, more precisely defined as referential transparency: replacing an expression for its bound value doesn't change meaning (precise definition)
- side effects are things that break referential transparency (precise definition)
- There's no direct connection between the concepts of IO, State and so on, and side effects. Traditionally, these things are side effectful (break referential transparency), but you can have abstractions that are pure (don't break ref.trans.)
- Due to the above, the term purely functional programming is not an oxymoron, it makes perfect sense.
- In haskell style pure FP, type constructors and algebras are used to represent "things that would otherwise traditionally be side effects (break ref.trans.)". We call these F[_]s effects or computational contexts for brevity. You can see for yourself how this cannot be a precise definition (especially because they could also have kind higher than * -> *, even though most famous a
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import cats.Applicative | |
import cats.data.NonEmptyList | |
import cats.effect.Concurrent | |
import cats.effect.concurrent.{Deferred, Ref} | |
import cats.implicits._ | |
import fs2.concurrent.{InspectableQueue, SignallingRef} | |
import fs2.{Chunk, CompositeFailure, Scope, Stream} | |
object StreamPriorityUtils { |
- Install IntelliJ + Scala Plugin
- Don’t do the Coursera courses yet.
- Don’t do the “red book” Functional Programming in Scala yet.
- Do: http://underscore.io/books/
- Essential Scala
- Essential Play
- Essential Slick
- Do Scala for the Impatient: https://www.amazon.com/Scala-Impatient-Cay-S-Horstmann/dp/0321774094
- The Neophyte’s Guide to Scala http://danielwestheide.com/scala/neophytes.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import shapeless.ops.nat.ToInt | |
import shapeless.{Nat, Succ} | |
import scala.concurrent.Promise | |
import scala.util.{Failure, Success} | |
import scala.concurrent.Future | |
import scala.concurrent.ExecutionContext.Implicits._ | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import scala.language.higherKinds | |
package object tag { | |
private def cast[T, U](v: U): T = v.asInstanceOf[T] | |
type Tag[T, +U] = {type Raw = T ; type Gag <: U } | |
type @@[T, +U] = T with Tag[T, U] | |
type Tagged[T, +U] = T with Tag[T, U] | |
def tag[T, U](value:T):T @@ U = cast(value) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import cats.data.{ EitherT, State } | |
import cats.implicits._ | |
import cats.{ Monad, ~> } | |
import io.aecor.liberator.macros.free | |
import io.aecor.liberator.syntax._ | |
import io.aecor.liberator.{ ProductKK, Term } | |
@free | |
trait Api[F[_]] { | |
def doThing(aThing: String, params: Map[String, String]): F[Either[String, String]] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns hello-manifold.core | |
(:require | |
[aleph.http :as http] | |
[byte-streams :as bs] | |
[cheshire.core :as json] | |
[clojure.string :as str] | |
[manifold.deferred :as d] | |
[manifold.executor :as e] | |
[manifold.stream :as s])) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
object StaticFile { | |
// Various necessary imports. Notes: | |
// | |
// 1. fs2 is necessary. See https://github.com/functional-streams-for-scala/fs2 | |
// 2. streamz is necessary. See https://github.com/krasserm/streamz | |
// 3. Apache Tika is used to infer MIME types from file names, because it's more reliable and | |
// fully-featured than using java.nio.file.Files.probeContentType(). | |
// | |
// If using SBT, you'll want these library dependencies and resolvers: |
Miles Sabin recently opened a pull request fixing the infamous SI-2712. First off, this is remarkable and, if merged, will make everyone's life enormously easier. This is a bug that a lot of people hit often without even realizing it, and they just assume that either they did something wrong or the compiler is broken in some weird way. It is especially common for users of scalaz or cats.
But that's not what I wanted to write about. What I want to write about is the exact semantics of Miles's fix, because it does impose some very specific assumptions about the way that type constructors work, and understanding those assumptions is the key to getting the most of it his fix.
For starters, here is the sort of thing that SI-2712 affects:
def foo[F[_], A](fa: F[A]): String = fa.toString
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; boot fmt -f myfile.clj | |
;; boot fmt -f src | |
;; -- it will change files inplace | |
(set-env! :dependencies '[[cljfmt "0.3.0"]]) | |
(require '[cljfmt.core :as fmt] | |
'[clojure.java.io :as io]) | |
(defn fmt-file [f] |
NewerOlder