Scala: Type safe duck typing
If it walks like a duck and quacks like a duck, I would call it a duck.
Duck typing uses the set of methods and properties of an object, rather than its position in a type hierarchy to decide what you can do with it.
Scala’s structural typing feature provides something close to duck typing in a type safe way. A structural type is close to a .NET anonymous type; a type with a set of methods and properties but with no name. An example in Scala based on one of Wikipedia’s examples of duck typing:
class Duck { def quack = println("Quaaaaaack !") def feathers = println("The duck has white and gray feathers.") } class Person { def quack = println("The person imitates a duck.") def feathers = println("The person takes a feather from the ground and shows it.") } def inTheForest(duck: { def quack; def feathers }) = { duck.quack duck.feathers }
The inTheForest function declares that it will accept any object that has a quack and feathers method, both of which take no parameters and return Unit (like void in Java/C#). When executed, the code works as expected:
scala> inTheForest(new Person) The person imitates a duck. The person takes a feather from the ground and shows it. scala> inTheForest(new Duck) Quaaaaaack ! The duck has white and gray feathers.
To demonstrate the type safety, lets try using a string:
scala> inTheForest("Duck")
:6: error: type mismatch;
found : java.lang.String("Duck")
required: AnyRef{def quack: Unit; def feathers: Unit}
inTheForest("Duck")
^
When is this useful? Mostly in situations where you are consuming classes that follow common conventions but have no shared interface, in this case you can define the parts you are interested in by using the structural type as an implicit interface.
Finally, if you find that you are using a structural type a lot, it can define it in one place:
object UsefulTypes { type Duck = { def quack; def feathers } }
inTheForest can then be declared as:
import UsefulTypes.Duck def inTheForest(duck: Duck) = { duck.quack duck.feathers }
[...] public links >> scala Revised Scala Exercises First saved by netzach2 | 6 days ago Type safe duck typing with Scala First saved by lax | 21 days ago Scala office screens First saved by macaroon02 | 26 days ago [...]
Recent Faves Tagged With "scala" : MyNetFaves
13 Dec 08 at 2:20 am
Nice art.
I see that Scala compared to Ruby (which i currently use) is more type save for the price of writing some additional code, but still in an elegant way.
In Ruby duck typing is comparable. Ruby does not have the obligation and the ability to declare which methods must the method argument have.
Something like this:
def inTheForest(duck: Object) = { /* I mean Object as a wildcard */
duck.quack
duck.feathers
}
will work?
In Ruby it would look like this:
def inTheForest(duck)
duck.quack
duck.feathers
end
Szymon Je?
18 Aug 09 at 6:22 am
[...] Java and I’ve discovered it doesn’t have to. Functions being first class citizens and structural typing (think duck typing on steroids) remove not only a ton of boilerplate but also the need to rely on [...]
Scala: The Million Trait March… « Statically Typed
25 Sep 11 at 5:05 pm
Thanks, pretty clear explanation!
Alex
27 Dec 12 at 4:25 pm
Excellent example. Easy to read and understand.
Lars Støttrup
11 Feb 13 at 10:54 am