Why can I serialize scala.collection.immutable.List ?

1,034 views
Skip to first unread message

Henry Goldwire

unread,
Jan 11, 2012, 5:48:37 PM1/11/12
to scala...@googlegroups.com
The current API does not indicate that scala.collection.immutable.List has the Serializable trait:

bizarrely, this works fine for me:


import java.io._

val il = scala.collection.immutable.List("1","hi","yo")

val store = new ObjectOutputStream(new FileOutputStream("store.dat")) 
store.writeObject(il) 
store.close     


val in = new ObjectInputStream(new FileInputStream("store.dat")) 
val copy = in.readObject() 
println( copy)  
println(copy.getClass)


Shouldn't it give me a java.io.NotSerializableException ?


Thanks,
Henry

Derek Williams

unread,
Jan 11, 2012, 6:02:36 PM1/11/12
to scala...@googlegroups.com
On Wed, Jan 11, 2012 at 3:48 PM, Henry Goldwire <hgol...@manaproducts.com> wrote:
The current API does not indicate that scala.collection.immutable.List has the Serializable trait:


 

√iktor Ҡlang

unread,
Jan 11, 2012, 6:04:35 PM1/11/12
to scala...@googlegroups.com
scala> List(1,2).isInstanceOf[Serializable]
res0: Boolean = true

Cheers,
--
Viktor Klang

Akka Tech Lead
Typesafe - Enterprise-Grade Scala from the Experts

Twitter: @viktorklang

Brian Maso

unread,
Jan 11, 2012, 6:31:17 PM1/11/12
to scala-user
(Forgot to send to scala-user)

---------- Forwarded message ----------
From: Brian Maso <brian....@gmail.com>
Date: 2012/1/11
Subject: Re: [scala-user] Why can I serialize scala.collection.immutable.List ?
To: √iktor Ҡlang <viktor...@gmail.com>




2012/1/11 √iktor Ҡlang <viktor...@gmail.com>

scala> List(1,2).isInstanceOf[Serializable]
res0: Boolean = true


Yes, but

scala> implicitly[List[_] <:< java.io.Serializable]
<console>:8: error: Cannot prove that List[_] <:< java.io.Serializable.
              implicitly[List[_] <:< java.io.Serializable]

Which is odd considering

scala> implicitly[::[_] <:< java.io.Serializable]
res2: <:<[scala.collection.immutable.::[_],java.io.Serializable] = <function1>

I'm wondering why the base type wasn't declared Serializable, but instead the two subsclasses are. Just a little odd. Not a big deal.

Brian Maso
 

Doug Tangren

unread,
Jan 11, 2012, 6:37:57 PM1/11/12
to Brian Maso, scala-user
On Wed, Jan 11, 2012 at 6:31 PM, Brian Maso <brian....@gmail.com> wrote:
(Forgot to send to scala-user)

---------- Forwarded message ----------
From: Brian Maso <brian....@gmail.com>
Date: 2012/1/11
Subject: Re: [scala-user] Why can I serialize scala.collection.immutable.List ?
To: √iktor Ҡlang <viktor...@gmail.com>




2012/1/11 √iktor Ҡlang <viktor...@gmail.com>
scala> List(1,2).isInstanceOf[Serializable]
res0: Boolean = true


Yes, but

scala> implicitly[List[_] <:< java.io.Serializable]
<console>:8: error: Cannot prove that List[_] <:< java.io.Serializable.
              implicitly[List[_] <:< java.io.Serializable]

Which is odd considering

scala> implicitly[::[_] <:< java.io.Serializable]
res2: <:<[scala.collection.immutable.::[_],java.io.Serializable] = <function1>

I'm wondering why the base type wasn't declared Serializable, but instead the two subsclasses are. Just a little odd. Not a big deal.


I'm guessing because List, without known contents, is just a container. A box of Cheerios is edible, but I couldn't prove that if someone handled me a cereal box with mysterious contents, those contents would be edible.

Naftoli Gugenheim

unread,
Jan 15, 2012, 3:45:50 AM1/15/12
to Doug Tangren, Brian Maso, scala-user
List is sealed. So what would be the harm in marking it as Serializable?

Matthew Pocock

unread,
Jan 16, 2012, 8:16:45 AM1/16/12
to Naftoli Gugenheim, Doug Tangren, Brian Maso, scala-user
There would be no harm that I can see. The utility would be in documenting to people that it is safe to serialize lists.

Matthew
--
Dr Matthew Pocock
Integrative Bioinformatics Group, School of Computing Science, Newcastle University
skype: matthew.pocock
tel: (0191) 2566550

bryan hunt

unread,
Jan 16, 2012, 1:26:45 PM1/16/12
to scala-user
Interesting that:

scala.collection.immutable.List("1", "hi", Seq("dog","cat","frog"))

De-serializes to:

List(1, hi, List(dog, cat, frog))
class scala.collection.immutable.$colon$colon

I'm guessing this is related to Java type-erasure.

rkuhn

unread,
Jan 17, 2012, 8:06:42 AM1/17/12
to scala...@googlegroups.com
Nope, that’s just the actual classes which are created by the List() and Seq() factory methods.

Regards,

Roland

Kevin Wright

unread,
Jan 17, 2012, 8:08:22 AM1/17/12
to bryan hunt, scala-user
Seq is just a trait, the default concrete implementation of that trait is List.
--
Kevin Wright
mail: kevin....@scalatechnology.com
gtalk / msn : kev.lee...@gmail.com
vibe / skype: kev.lee.wright
steam: kev_lee_wright

"My point today is that, if we wish to count lines of code, we should not regard them as "lines produced" but as "lines spent": the current conventional wisdom is so foolish as to book that count on the wrong side of the ledger" ~ Dijkstra

Bryan Hunt

unread,
Jan 17, 2012, 9:42:43 AM1/17/12
to Kevin Wright, scala-user
On Tue, 17 Jan 2012 13:08:22 +0000, Kevin Wright <kev.lee...@gmail.com> wrote:
Non-text part: multipart/alternative

> Seq is just a trait, the default concrete implementation of that trait is
> List.

Thanks Kev, clearest answer of the lot!

Aleksey Nikiforov

unread,
Jan 18, 2012, 9:35:59 AM1/18/12
to Matthew Pocock, Naftoli Gugenheim, Doug Tangren, Brian Maso, scala-user
On Mon, Jan 16, 2012 at 7:16 AM, Matthew Pocock <turingate...@gmail.com> wrote:
There would be no harm that I can see. The utility would be in documenting to people that it is safe to serialize lists.

Matthew


This is precisely why having Serializable trait is a great harm: because it gives an impression that it is safe to serialize instances inheriting from it.

List can contain any members, even the ones that cannot be serialized, resulting in a non-serializable list instance. So not all instances of Serializable are in fact serializable. As a result, relying on Serialializable in method signatures will not save your from Serialization errors.

Serializable trait is Java has more to do with implimintation rather than indicating that an object can be serialized at the type level. I suspect this was one of the reasons Scala used @serializble annotation instead of extending Serializble trait (unfortunately this was changed in 2.9).

Worse, serializable classes can inherit from non-serializable traits. So having signatures like "def foo(s: Serializable)" will force users to cast "foo(x.asInstanceOf[Serializable])" without providing any safety against serialization errors. Instead you will be getting ClassCastException exceptions as well.

The decision to implement Seriazable as an interface in Java has been causing this confusion resulting in libraries that use Serializable in signatures. It is unfortunate that Scala has gave in to the pressure and changed it's serialiazble implementation from annotation to trait. My understanding this was done to be compatible with Java libraries using Serializable in method signatures, further propagating this confusion.

bryan hunt

unread,
Jan 19, 2012, 1:20:48 PM1/19/12
to scala-user
I should probably create a new thread for this question, so sue me...
In Python I can pickle a graph of Objects and just dump them to a file
somewhere for later retrieval.
What is currently considered the best way to do this?
Reply all
Reply to author
Forward
0 new messages