14

Is their an equivalent to C#'s Expression API in scala?

For example, I would like to have a lambda like this:

(Foo) => Foo.bar

and be able to access "bar" in the function it is passed to.

user281655
  • 467
  • 1
  • 3
  • 11

4 Answers4

9

This is not supported by Scala. ScalaQL: Language-Integrated Database Queries for Scala describes a LINQ-like functionality in Scala:

While it is possible for Microsoft to simply extend their language with this particular feature, lowly application developers are not so fortunate. For exam- ple, there is no way for anyone (outside of Sun Microsystems) to implement any form of LINQ within Java because of the language modications which would be required. We faced a similar problem attempting to implement LINQ in Scala.

Fortunately, Scala is actually powerful enough in and of itself to implement a form of LINQ even without adding support for expression trees. Through a combination of operator overloading, implicit conversions, and controlled call- by-name semantics, we have been able to achieve the same eect without making any changes to the language itself.

Thomas Jung
  • 32,428
  • 9
  • 84
  • 114
  • 1
    Yes, but the author did not release their source code; moreover, that paper lacks quite a few details needed for a complete implementation - they don't even write the actual interface of their library. Supporting flatMap (which is used in none of the examples) is for instance tricky. – Blaisorblade Oct 08 '11 at 13:18
  • I'm not sure if it implements everything LINQ does, but just wanted to point out that Slick uses the above methods. It implements its own map, filter, groupBy, etc. functions which implicitly cast from regular scala types to a special Rep type. So you can do `coffees.filter(_.price > 8.0).map(_.name)` and it will turn into SQL. [See the docs](http://slick.typesafe.com/doc/2.0.0/introduction.html#lifted-embedding). – ShawnFumo Feb 14 '14 at 19:50
6

There is an experimental scala.reflect.Code.lift which might be of interest, but the short answer is no, Scala does not have access to the AST in any form (expression trees are a subset of C#'s AST).

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

It's not quite clear to me what you want. If you want a function that returns a getter for a field, you can do that quite easily:

class Holder(var s: String) { }
class StringSaver(f: Holder => (() => String), h: Holder) {
  val getter = f(h)
  def lookAtString = getter()
}

val held = new Holder("Hello")
val ss = new StringSaver((h: Holder) => (h.s _) , held)
println(ss.lookAtString)
held.s = "Bye now"
println(ss.lookAtString)

The key is to turn the getter h.s into a function via (h.s _).

Rex Kerr
  • 166,841
  • 26
  • 322
  • 407
  • One way this is used in .NET is in MVC template helpers. The template knows the type of the model, say User (which has a firstName). So you could do `helpers.textBoxFor(m => m.firstName)`. This not only does databinding but uses the name of the property, creating something like ``. This way you get type safety (and refactoring support) with no magic strings needed. – ShawnFumo Feb 14 '14 at 19:30
1

No, to the best of my knowledge.

Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487