2

In scala, when you write out a string "Hello World" to a file it writes

Hello World

(note: no double quotes).

Lisp has a concept of print and write. One writes without the double quotes, the other includes them to make it easy to write out data structures and read them back later using the standard reader.

Is there anyway to do this in Scala?

With one string it is easy enough to format it - but with many deeply nested structures, it is nearly impossible.

For example, say I have

sealed trait PathSegment
case class P(x:String) extends PathSegment
case class V(x:Int)    extends PathSegment

To create one does:

P("X")

or

V(0)

a list of these PathSegments prints as:

List(P(paths), P(/pets), P(get), P(responses), V(200))

I want this to print out as:

List(P("paths"), P("/pets"), P("get"), P("responses"), V(200))

In other words, I want strings (and characters), no matter where to occur in a structure to print out as "foo" or 'c'

haroldcarr
  • 1,523
  • 15
  • 17

3 Answers3

1

That's what Serialization is about. Also, why JSON is popular.

Daniel C. Sobral
  • 295,120
  • 86
  • 501
  • 681
1

Check out lift-json ( https://github.com/lift/lift/tree/master/framework/lift-base/lift-json/ ) for writing data out that will be parsed and read by another language. JSON is pretty standard in the web services world for request/response serialization and there are JSON libraries in just about every language.

To literally write out a string including double quotes, you can also do something like this:

"""
The word "apple" is in double quotes.
"""

I find a slightly more structured format like JSON more useful, and a library like lift-json does the right thing in terms of quoting Strings and not quoting Ints, etc.

Janx
  • 3,285
  • 3
  • 19
  • 24
1

I think you are looking for something like Javascript's eval() + JSON, and Python's eval(), str() and repr(). Essentially, you want Lispy symmetric meta-circular evaluation. Meaning you can transform data into source code, and evaluating that source code with give you back the same data, right?

AFAIK, there's no equivalent of eval() in Scala. Daniel Spiewak has talked about this here before. However, if you reeeeeealy want to. I suggest the following things:

  1. Every collection object has 3 methods that will allow you to transform its data to a string representation anyway you want. There are mkString, addString and stringPrefix. Do something clever with them (think "decompiling" your in-memory ADTs back to source-code form) and you shall arrive to step 2). Essentially, you can transform a list of integers created by List(1,2,3) back to a string "List(1,2,3)". For more basic literals like a simple string or integer, you'll need to pimp the built-in types using implicits to provide them with these toString (I'm overloading the term here) helper methods.
  2. Now you have your string representation, you can think about how to "interpret" or "evaluate" them. You will need an eval() function that create a new instance of a parser combinator that understands Scala's literals and reassemble the data structure for you.

Implementing this actually sounds fun. Don't forget to post back here if you've successfully implementing it. :)

Community
  • 1
  • 1
Y.H Wong
  • 7,151
  • 3
  • 33
  • 35