Design Guides behind toString in Scala

Hello,

I’m not sure if it’s the right place to ask this question. I’m currently programming AI bots in Scala. One nice feature I find is that I can use the string representation of a state to re-instantiate that state. For example

If I print this instance of my state class, I can use the output as code to instantiate again the object.

val state = CaribbeanState(
  CaribbeanContext(Map(), Map(2 -> 50, 0 -> 39)),
  Map(0 -> Ship(0, Offset(8, 12), 1, 2, 64, 1)
    , 2 -> Ship(2, Offset(10, 11), 2, 1, 50, 1)
    , 1 -> Ship(1, Offset(20, 10), 4, 2, 67, 0)
    , 3 -> Ship(3, Offset(17, 16), 5, 2, 59, 0)),
  Map(),
  Map(59 -> Ball(59, Offset(12, 14), 3, 1)
    , 60 -> Ball(60, Offset(14, 17), 2, 2)),
  Map(5 -> Mine(5, Offset(14, 12))
    , 29 -> Mine(29, Offset(7, 8))
    , 61 -> Mine(61, Offset(15, 12))
    , 38 -> Mine(38, Offset(4, 10))
    , 7 -> Mine(7, Offset(12, 16))
    , 51 -> Mine(51, Offset(14, 10))
    , 4 -> Mine(4, Offset(14, 8))), 51)

I find this behavior very useful (for debugging). Can someone kindly share more details about this design decision?

Regards,
Hui

I suspect this post might do better on users, but it’s not very clear.

Such behavior is standard for numbers, and functional languages tend to extend that to data structures —both Haskell and Scheme have similar properties.

That’s more helpful with immutable data: If you print out and reenter immutable data you get an equal result. For objects with mutable state getting a clone can be less useful.

Unfortunately, toString doesn’t always guarantee this behavior—it fails on String, because of behavior inherited from Java. Try a case class containing strings to see better what I mean.
A standalone solution is http://www.lihaoyi.com/upickle-pprint/pprint/ — many implementation of Show typeclasses (like the one in Cats, http://eed3si9n.com/herding-cats/Show.html) also provide better guarantees.

1 Like