41

Besides integration with dynamic languages on the JVM, what are the other powerful uses of a Dynamic type in a statically typed language like Scala?

missingfaktor
  • 90,905
  • 62
  • 285
  • 365
Adam Rabung
  • 5,232
  • 2
  • 27
  • 42
  • 1
    Without language support (e.g. `dynamic` in C#.4), I don't really "see" what's going on with that commit. Would be interesting to see how it fits in. –  Jan 17 '11 at 03:38
  • 1
    Th answers to this question are extremely outdated, for actual answers see: [How does type Dynamic work and how to use it?](http://stackoverflow.com/q/15799811/465304) – kiritsuku Apr 13 '13 at 00:22

3 Answers3

22

I guess a dynamic type could be used to implement several of the features found in JRuby, Groovy or other dynamic JVM languages, like dynamic metaprogramming and method_missing.

For example creating a dynamic query similar to Active Record in Rails, where a method name with parameters is translated to an SQL query in the background. This is using the method_missing functionality in Ruby. Something like this (in theory - have not tried to implement anything like this):

class Person(val id: Int) extends Dynamic {
  def _select_(name: String) = {
    val sql = "select " + name + " from Person where id = " id;
    // run sql and return result
  }

  def _invoke_(name: String)(args: Any*) = {
    val Pattern = "(findBy[a-zA-Z])".r
    val sql = name match {
      case Pattern(col) => "select * from Person where " + col + "='" args(0) + "'"
      case ...
    }
    // run sql and return result
  }
}

Allowing usage like this, where you can call methods 'name' and 'findByName' without having them explicitly defined in the Person class:

val person = new Person(1)

// select name from Person where id = 1
val name = person.name

// select * from Person where name = 'Bob'
val person2 = person.findByName("Bob")

If dynamic metaprogramming was to be added, the Dynamic type would be needed to allow invoking methods that have been added during runtime..

eivindw
  • 1,939
  • 17
  • 13
4

Odersky says the primary motivation was integration with dynamic languages: http://groups.google.com/group/scala-language/msg/884e7f9a5351c549

[edit] Martin further confirms this here

Adam Rabung
  • 5,232
  • 2
  • 27
  • 42
2

You might also use it for syntactic sugar on maps:

class DynamicMap[K, V] extends Dynamic {
  val self = scala.collection.mutable.Map[K, V]()
  def _select_(key: String) = self.apply(key)
  def _invoke_(key: String)(value: Any*) = 
    if (value.nonEmpty) self.update(key, value(0).asInstanceOf[V])
    else throw new IllegalArgumentException
}

val map = new DynamicMap[String, String]()

map.foo("bar")  // adds key "foo" with value "bar"    
map.foo         // returns "bar"

To be honest this only saves you a couple of keystrokes from:

val map = new Map[String, String]()
map("foo") = "bar"
map("foo")
Knut Arne Vedaa
  • 15,372
  • 11
  • 48
  • 59
  • 1
    Note that this example does not quite work for a couple of reasons, but I don't think there's much point in explorering this further before the feature is more stable. – Knut Arne Vedaa Jan 18 '11 at 19:55
  • I made it work here: [http://stackoverflow.com/questions/14876856/simple-scala-macro] – Eric Mariacher Feb 25 '14 at 10:42