Practical use of the dynamic type in Scala

Besides integrating with dynamic languages ​​in the JVM, what are some other powerful ways to use the dynamic type in a statically typed language like Scala

+41
types scala
Jan 17 '11 at 1:01
source share
3 answers

I suggest that the dynamic type can be used to implement several functions found in JRuby, Groovy, or other dynamic JVM languages, such as dynamic metaprogramming and method_missing.

For example, creating a dynamic query similar to Active Record in Rails, where the name of the method with parameters is translated into the SQL query in the background. Ruby uses the method_missing function. Something like this (theoretically - did not try to implement something 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 use, for example, here, where you can call the "name" and "findByName" methods without explicitly specifying them 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, you will need a dynamic type so that you can call methods that were added at run time.

+21
Jan 17 '11 at 8:30
source share

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

[edit] Martin further confirms this here

+4
Jan 28 2018-11-11T00:
source share

You can 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 will only save you a couple of keystrokes:

 val map = new Map[String, String]() map("foo") = "bar" map("foo") 
+2
Jan 17 2018-11-17T00:
source share



All Articles