Skip to content
This repository has been archived by the owner on Feb 20, 2019. It is now read-only.

Commit

Permalink
Merge pull request #287 from scala/topic/notes
Browse files Browse the repository at this point in the history
(wip) Release note for 0.10.0
  • Loading branch information
havocp committed Feb 6, 2015
2 parents 26bb7c1 + f23ed33 commit 085f466
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 26 deletions.
73 changes: 47 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,28 @@ scala/pickling

**Scala Pickling** is an automatic serialization framework made for Scala. It's fast, boilerplate-free, and allows users to easily swap in/out different serialization formats (such as binary, or JSON), or even to provide their own custom serialization format.

### Basic usage (0.9.0)
### Defaults mode (0.10.0)

```scala
import scala.pickling._, json._
scala> import scala.pickling.Defaults._, scala.pickling.json._
scala> case class Person(name: String, age: Int)

val pckl = List(1, 2, 3, 4).pickle
val lst = pckl.unpickle[List[Int]]
scala> val pkl = Person("foo", 20).pickle
pkl: pickling.json.pickleFormat.PickleType =
JSONPickle({
"$type": "Person",
"name": "foo",
"age": 20
})

scala> val person = pkl.unpickle[Person]
person: Person = Person(foo,20)
```

### Basic usage (0.10.0)
### Basic usage (0.9.0)

```scala
import scala.pickling._, scala.pickling.Defaults._, scala.pickling.json._
import scala.pickling._, json._

val pckl = List(1, 2, 3, 4).pickle
val lst = pckl.unpickle[List[Int]]
Expand Down Expand Up @@ -114,30 +123,42 @@ If you're a library author, you can provide the convenience object as your proto
- format

```scala
scala> case class Pumpkin(kind: String)
defined class Pumpkin

scala> val pumpkinJsonProtocol = new scala.pickling.pickler.PrimitivePicklers with
| scala.pickling.json.JsonFormats with scala.pickling.Ops {
| import scala.pickling.{ Pickler, Unpickler }
| implicit val pumpkinPickler = Pickler.generate[Pumpkin]
| implicit val pumpkinUnpickler = Unpickler.generate[Pumpkin]
| }
pumpkinJsonProtocol: scala.pickling.pickler.PrimitivePicklers with scala.pickling.json.JsonFormats with scala.pickling.Ops{implicit val pumpkinPickler: scala.pickling.Pickler[Pumpkin] with scala.pickling.Generated; implicit val pumpkinUnpickler: scala.pickling.Unpickler[Pumpkin] with scala.pickling.Generated} = $anon$1@500cd8e3
scala> case class Apple(kind: String)
defined class Apple

scala> val appleProtocol = {
| import scala.pickling._
| new pickler.PrimitivePicklers with pickler.RefPicklers
| with json.JsonFormats {
| // Manually generate pickler for Apple
| implicit val applePickler = PicklerUnpickler.generate[Apple]
| // Don't fall back to runtime picklers
| implicit val so = static.StaticOnly
| // Provide custom functions
| def toJsonString[A: Pickler](a: A): String =
| functions.pickle(a).value
| def fromJsonString[A: Unpickler](s: String): A =
| functions.unpickle[A](json.JSONPickle(s))
| }
| }
appleProtocol: scala.pickling.pickler.PrimitivePicklers with scala.pickling.pickler.RefPicklers with scala.pickling.json.JsonFormats{implicit val applePickler: scala.pickling.Pickler[Apple] with scala.pickling.Unpickler[Apple] with scala.pickling.Generated; implicit val so: scala.pickling.static.StaticOnly.type; def toJsonString[A](a: A)(implicit evidence$1: scala.pickling.Pickler[A]): String; def fromJsonString[A](s: String)(implicit evidence$2: scala.pickling.Unpickler[A]): A} = $anon$1@2b033c35
```

Now your library user can import `pumpkinJsonProtocol` as follows:
Now your library user can import `appleProtocol` as follows:

```
scala> import pumpkinJsonProtocol._
import pumpkinJsonProtocol._
scala> Pumpkin("kabocha").pickle
res0: pumpkinJsonProtocol.pickleFormat.PickleType =
JSONPickle({
"tpe": "Pumpkin",
"kind": "kabocha"
})
scala> import appleProtocol._
import appleProtocol._
scala> toJsonString(Apple("honeycrisp"))
res0: String =
{
"$type": "Apple",
"kind": "honeycrisp"
}
scala> fromJsonString(res0)
res1: Apple = Apple(honeycrisp)
```

<!-- This project aims to turn [a custom build of macro paradise](https://github.com/heathermiller/scala-pickling/tree/topic/scala-pickling) that we used in
Expand Down
74 changes: 74 additions & 0 deletions notes/0.10.0.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
This is the first stable release of Scala Pickling, an automatic serialization framework made for Scala.
It's fast, boilerplate-free, and allows users to easily swap in/out different serialization formats (such as binary, or JSON). We will retain binary compatibility throughout the 0.10.x series. We'll also keep format compatibility during 0.10.x.

## Pickling in a nutshell

To pickle a value, let's say `Person("foo", 20)`, you need two things.
A [pickler combinator][Kennedy] for the given type `Person`, and a pickle format.
The `Pickler[A]` is responsible for breaking `A` down to abstract *entries*, *fields*, and *collections*.
It's called a combinator, because complex pickler combinators can be composed from primitive picklers.
The `PickleFormat` turns the abstract notions like *fields* into binary or text representation.

## Defaults mode

Here's a basic usage using `Defaults` mode.

scala> import scala.pickling.Defaults._, scala.pickling.json._
scala> case class Person(name: String, age: Int)

scala> val pkl = Person("foo", 20).pickle
pkl: pickling.json.pickleFormat.PickleType =
JSONPickle({
"$type": "Person",
"name": "foo",
"age": 20
})

scala> val person = pkl.unpickle[Person]
person: Person = Person(foo,20)

The `Defaults` mode automatically derives `Pickler[Person]` from the primitive picklers at compile-time!
Because the code is statically generated, we can inline the string manipulations and make it fast.
([Faster than Java serialization or Kryo][Miller], which also does not require schema)

Note, because `Pickler[A]` is a typeclass, Pickling can be retrofitted to `Person`
without modifying the class to inherit [Serializable][1] or something like that.

## DIY protocol stack

Pickling 0.10.0 offers picklers, ops, and formats as traits, which can be
stacked together, so third-party libraries can provide custom modes.
Suppose you only want to pickle primitive types and `Apple`, and don't want to automatically
derive pickler combinators. Here's a custom mode:

scala> case class Apple(kind: String)
scala> val appleProtocol = {
import scala.pickling._
new pickler.PrimitivePicklers with pickler.RefPicklers
with json.JsonFormats {
// Manually generate pickler for Apple
implicit val applePickler = PicklerUnpickler.generate[Apple]
// Don't fall back to runtime picklers
implicit val so = static.StaticOnly
// Provide custom functions
def toJsonString[A: Pickler](a: A): String =
functions.pickle(a).value
def fromJsonString[A: Unpickler](s: String): A =
functions.unpickle[A](json.JSONPickle(s))
}
}
scala> import appleProtocol._

scala> toJsonString(Apple("honeycrisp"))
res0: String =
{
"$type": "Apple",
"kind": "honeycrisp"
}

For more details see [Pickling][Pickling].

[Kennedy]: http://research.microsoft.com/pubs/64036/picklercombinators.pdf
[Miller]: http://infoscience.epfl.ch/record/187787/files/oopsla-pickling_1.pdf
[Pickling]: https://github.com/scala/pickling
[1]: http://docs.oracle.com/javase/7/docs/api/java/io/Serializable.html
1 change: 1 addition & 0 deletions notes/about.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[Scala Pickling](https://github.com/scala/pickling) is an automatic serialization framework made for Scala.

0 comments on commit 085f466

Please sign in to comment.