Skip to content

Instantly share code, notes, and snippets.

CAP Twelve Years Later: How the "Rules" Have Changed

  • CAP prohibits only a tiny part of the design space: perfect availability and consistency in the presence of partitions, which are rare.
  • The modern CAP goal should be to maximize combinations of consistency and availability that make sense for the specific application.

ACID, BASE and CAP

  • In ACID, the C means that a transaction preserves all the database rules, such as unique keys. In contrast, the C in CAP refers only to single‐copy consistency, a strict subset of ACID consistency. ACID consistency also cannot be maintained across partitions—partition recovery will need to restore ACID consistency.
  • Isolation (I). Isolation is at the core of the CAP theorem: if the system requires ACID isolation, it can operate on at most one side during a partition. Serializability requires communication in general and thus fails across partitions. Weaker definitions of correctness are viable across partitions via compensation during partition recovery.
class LikeADuck {
def bark: String = "woof!"
def quack: String = "quack!"
}
object DuckTypeTest {
type QuacksLikeADuck = {
def quack : String
}
val likeADuck = new LikeADuck

Keybase proof

I hereby claim:

  • I am miguel-vila on github.
  • I am miguel (https://keybase.io/miguel) on keybase.
  • I have a public key whose fingerprint is E277 3F1D 8B4A 7227 7A1A 73DF 4E0C DBF3 4810 3B2F

To claim this, I am signing this object:

@miguel-vila
miguel-vila / shapeless-scalaz.sbt
Last active August 29, 2015 14:00
Shapeless and Scalaz console sandbox sbt commands
set scalaVersion := "2.11.0"
set libraryDependencies += "org.scalaz" %% "scalaz-core" % "7.1.0"
set initialCommands += "import scalaz._, Scalaz._"
session save
console
//Shapeless:
/*
set libraryDependencies += "com.chuusai" %% "shapeless" % "2.0.0"
set initialCommands += "import shapeless._"
import AssemblyKeys._
assemblySettings
name := "scala-test"
version := "0.0.1"
scalaVersion := "2.10.3"
// a #:: f(a) #:: f(f(a)) #:: f(f(f(a))) #:: ...
def repeat[A](f: A => A)(a: => A): Stream[A] = a #:: repeat(f)(f(a))
def next(n: Double)(x: Double): Double = (x + n/x)/2.0
def within(eps: Double)(s: Stream[Double]): Double = s match {
case a #:: b #:: rest => if(Math.abs(a-b)<=eps) b else within(eps)(rest)
case _ => throw new Exception("El stream debería tener por lo menos dos elementos")
}
def fa[A0,A1](a: A0): A1 = ???
def head[A](l: List[A]): A = l.head
def fmap[A,B](f: A => B)(l: List[A]): List[B] = l.map(f)
"head and then map is the same as map and then head" {
fa[A0,A1] compose head[A0] == head[A1] compose fmap[A0,A1](fa)
}
def tail[A](l: List[A]): List[A] = l.tail
"tail and then map is the same as map and then tail" {

ScalaCheck The Definitive Guide

Chapter 1

  • A specification is a definition of a program’s behavior in the general case. Preferably, a specification should not deal with concrete examples of program functionality. Instead it should provide an abstract description of the behavior, that you can use both when implementing the program and when verifying it.

  • Specifications, on the other hand, give us a more complete picture of the program but they are often informal and difficult to verify formally. Instead, tests are used to verify specific cases of a specification.

  • Tests as specification is a concept that is gaining popularity in many test-driven software development processes.

def makeFigure(size: Int, spaces: Int, characters: Int, spacesModifier: Int, charactersModifier: Int): String = {
val charsValsStream = Stream.iterate(characters, size)(chars => chars + charactersModifier)
val spacesValsStream = Stream.iterate(spaces, size)(spaces => spaces + spacesModifier)
(charsValsStream zip spacesValsStream).foldLeft(new StringBuilder) { case (builder,(characters,spaces)) =>
builder append (" " * spaces) append ("*" * characters) append "%n".format()
}.toString()
}