Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Embedding XML (and other languages?) in Scala

Tags:

scala

dsl

I'm wondering how the scala.xml library is implemented, to get an Elem-instance out of XML.

So I can write:

val xml = {
  <myxml>
    Some wired text withoud "'s or code like
    import x
    x.func()
    It's like a normal sting in triple-quotes.
  </myxml>
}

xml.text

String = 
 "
    Some text wired withoud "'s or code like
    import x
    x.func()
    It's like a normal sting in triple-quotes.
  "

A look at the source code doesn't gave me the insight, how this is achieved. Is the "XML-detection" a (hard) scala language feature or is it an internal DSL? Because I would like to build my own things like this:

var x = LatexCode {
  \sqrt{\frac{a}{b}}
}

x.toString

"\sqrt{\frac{a}{b}}"

or

var y = PythonCode {
  >>> import something
  >>> something.func()
}

y.toString
"""import something ..."""

y.execute  // e.g. passed to python as python-script

or

object o extends PythonCode {
  import x
  x.y()
}

o.toString

"""import x...."""

I would like to avoid using such things like PythonCode { """import ...""" } as "DSL". And in scala, XML is magically transported to a scala.xml-Class; same with Symbol which I can get with val a = 'symoblname, but in the source code there's no clue how this is implemented.

How can I do something like that on myself, preferably as internal DSL?

like image 592
Themerius Avatar asked Aug 28 '12 12:08

Themerius


2 Answers

XML is a scala language feature (*) - see the SLS, section 1.5.

I think that string interpolation is coming in 2.10, however, which would at least allow you to define your own DSL:

val someLatex = latex"""\sqrt{\frac{a}{b}}}"""

It's an experimental feature explained more fully in the SIP but has been additionally blogged about by the prolific Daniel Sobral. The point of this is (of course) that the correctness of the code in the String can be checked at compile time (well, to the extent possible in an untyped language :-) and your IDE can even help you write it (well, to the extent possible in an untyped language :-( )

(*) - We might expect this to change in the future given the many shortcomings of the implementation. My understanding is that a combination of string interpolation and anti-xml may yet be the one true way.

like image 97
oxbow_lakes Avatar answered Sep 30 '22 19:09

oxbow_lakes


It's an XML literal, just like "foo" is a string literal, 42 is an integer literal, 12.34 is a floating point literal, 'foo is a symbol literal, (foo) => foo + 1 is a function literal and so on.

Scala has fewer literals than other languages (for example, it doesn't have array literals or regexp literals), but it does have XML literals.

Note that in Scala 2.10 string literals become vastly more powerful by allowing you to intercept and re-interpret them using StringContexts. These more powerful string literals would allow you to implement all of your snippets, including XML without separate language support. It is likely that XML literals will be removed in a future version of the language.

like image 26
Jörg W Mittag Avatar answered Sep 30 '22 19:09

Jörg W Mittag