I just read and enjoyed the Cake pattern article. However, to my mind, one of the key reasons to use dependency injection is that you can vary the components being used by either an XML file or command-line arguments.
How is that aspect of DI handled with the Cake pattern? The examples I've seen all involve mixing traits in statically.
Since mixing in traits is done statically in Scala, if you want to vary the traits mixed in to an object, create different objects based on some condition.
Let's take a canonical cake pattern example. Your modules are defined as traits, and your application is constructed as a simple Object with a bunch of functionality mixed in
val application =
new Object
extends Communications
with Parsing
with Persistence
with Logging
with ProductionDataSource
application.startup
Now all of those modules have nice self-type declarations which define their inter-module dependencies, so that line only compiles if your all inter-module dependencies exist, are unique, and well-typed. In particular, the Persistence module has a self-type which says that anything implementing Persistence must also implement DataSource, an abstract module trait. Since ProductionDataSource inherits from DataSource, everything's great, and that application construction line compiles.
But what if you want to use a different DataSource, pointing at some local database for testing purposes? Assume further that you can't just reuse ProductionDataSource with different configuration parameters, loaded from some properties file. What you would do in that case is define a new trait TestDataSource which extends DataSource, and mix it in instead. You could even do so dynamically based on a command line flag.
val application = if (test)
new Object
extends Communications
with Parsing
with Persistence
with Logging
with TestDataSource
else
new Object
extends Communications
with Parsing
with Persistence
with Logging
with ProductionDataSource
application.startup
Now that looks a bit more verbose than we would like, particularly if your application needs to vary its construction on multiple axes. On the plus side, you usually you only have one chunk of conditional construction logic like that in an application (or at worst once per identifiable component lifecycle), so at least the pain is minimized and fenced off from the rest of your logic.
Scala is also a script language. So your configuration XML can be a Scala script. It is type-safe and not-a-different-language.
Simply look at startup:
scala -cp first.jar:second.jar startupScript.scala
is not so different than:
java -cp first.jar:second.jar com.example.MyMainClass context.xml
You can always use DI, but you have one more tool.
The short answer is that Scala doesn't currently have any built-in support for dynamic mixins.
I am working on the autoproxy-plugin to support this, although it's currently on hold until the 2.9 release, when the compiler will have new features making it a much easier task.
In the meantime, the best way to achieve almost exactly the same functionality is by implementing your dynamically added behavior as a wrapper class, then adding an implicit conversion back to the wrapped member.
Until the AutoProxy plugin becomes available, one way to achieve the effect is to use delegation:
trait Module {
def foo: Int
}
trait DelegatedModule extends Module {
var delegate: Module = _
def foo = delegate.foo
}
class Impl extends Module {
def foo = 1
}
// later
val composed: Module with ... with ... = new DelegatedModule with ... with ...
composed.delegate = choose() // choose is linear in the number of `Module` implementations
But beware, the downside of this is that it's more verbose, and you have to be careful about the initialization order if you use vars inside a trait. Another downside is that if there are path dependent types within Module above, you won't be able to use delegation that easily.
But if there is a large number of different implementations that can be varied, it will probably cost you less code than listing cases with all possible combinations.
Lift has something along those lines built in. It's mostly in scala code, but you have some runtime control. http://www.assembla.com/wiki/show/liftweb/Dependency_Injection
Related
I want to write an arch unit test to assert that a class extends AnyVal type.
val rule = classes().should().beAssignableTo(classOf[AnyVal])
val importedClasses = new ClassFileImporter().importPackages("a.b.c")
isAnyVal.check(importedClasses) // Always returns true
The above code doesn't actually catch anything and passes for classes that don't extend AnyVal also.
classOf[AnyVal] is java.lang.Object, so you are just asking that all classes extend Object, which they do.
From ArchUnit user guide:
It does so by analyzing given Java bytecode, importing all classes into a Java code structure.
I was hoping you'd get Class etc. and could go into Scala reflection from there, even if you wouldn't get the nice DSL, but they use their own API instead.
So to answer Scala-specific questions, it would need to parse #ScalaSignature annotations and that would probably be a very large effort for the developers (not to mention maintenance, or dependence on specific Scala version at least until Scala 3).
For me, I would use an implicit class under the following scenarios:
don't have access to the underlying type to be able to add the method I want.
the method I want doesn't make sense in a "global" sense.
i am splitting the functionality into another library of "extensions"
actually converting to a new type adds semantic/readability value (the new type actually means something)
However, I am fairly new to Scala (<6 months) and I'm noticing the developers around me are using implicit classes when it breaks the scenarios above. When I asked why, the answer was "because that's what I've always done".
So my question is, is there an official recommendation for when one should use an implicit class over a normal function added to the class definition? (I couldn't find anything here: https://docs.scala-lang.org/overviews/core/implicit-classes.html)
As per the SIP,
Motivation for the implicit class was that the popular extension method pattern, sometimes called the Pimp My Library pattern was used in Scala to extend pre-existing classes with new methods, fields, and interfaces.
There was also another common ‘extension’ use case known as type traits or type classes (see scala.math.Numeric). Type classes offered an alternative to pure inheritance hierarchies that was very similar to the extension method pattern.
The main drawback to both of these techniques was that they suffered the creation of an extra object at every invocation to gain the convenient syntax. This made these useful patterns unsuitable for use in performance-critical code. In these situations it was common to remove use of the pattern and resort to using an object with static helper methods.
And implicit class syntax was thus added to solve these issues.
The rock. They allow to make your own DSLs. Take a look to the Spray code, one of our classic and beloved projects:
trait TransformerPipelineSupport {
...
implicit class WithTransformation[A](value: A) {
def ~>[B](f: A ⇒ B): B = f(value)
}
...
}
The ~> allows to compose Spray directives... There are many more examples
What does it mean when it is said that scala provides for first class module support through the object syntax? Nothing in the glossary even mentions the phrase but I've run into it twice now and haven't been able to decipher it. Is was said in this blog post regarding adapters.
A "module" is a pluggable piece of software, also called a "package" sometimes. It provides a functionality through a well-defined set of interfaces, which declare what it provides and what it requires. Finally, it is interchangeable.
There are few languages with direct support for modules, mostly because while support for declaring APIs is common, support for declaring dependencies or requirements is not. Libraries in popular languages will usually interface by relying on types provided by the "standard" library, or requiring initialization with objects implementing APIs they provide.
So, if I want to make a benchmark module, I'll usually resort to clock facilities provided by the standard libraries or, at worse, I'll declare a clock type and request to be initialized with a class implementing it before the module's functionality is ready to be used.
When module support is available, however, I'll not only declare the benchmark interfaces I provide, but I'll also declare that I need a "clock module" -- a module exporting certain interfaces that I need.
A client of my module would not be required to do anything to use my interfaces -- it could just go ahead and use it. Or it could not even declare that my benchmark module would be used and, instead, declare that it has a requirement for a benchmark module.
What will satisfy the requirements is only decided at the "top" level, at the application level (modules are components of applications). At that point it would declare that it would use that client, my benchmark, and a module implementing my clock requirements.
If you know Guice, this might seem familiar. The problems that Guice addresses are in large part caused by the lack of module support in the Java programming language.
So, back to Scala. How does module support work? Well, the interface of my module might look like this:
trait Benchmark extends Clock // What I need {
// What I provide
type ABench <: Bench
trait Bench {
def measure(task: => Unit): Long
}
def aBench: ABench
}
and Clock would be a module definition, such as this:
trait Clock {
// What it provides
type AClock <: Clock
trait Clock {
def now(): Long
}
def aClock: AClock
}
My module itself might look like this:
trait MyModule extends Benchmark {
class ABench extends Bench {
def measure(task: => Unit): Long = {
val measurements = for(_ <- 1 to 10) yield {
val start = aClock.now()
task
val end = aClock.now()
end - start
}
measurements / 10
}
}
object aBench extends ABench
}
The Clock module would be similarly defined. An application could be declared as being a composition of modules:
trait application extends Clock with Benchmark with ...
though, of course, dependencies need not be declared, as they are already provided for. You can then combine modules that provide the requirements to build the application:
object Application extends MyModule with JavaClock with ...
And that would link the requirements of MyModule with the implementation provided by JavaClock. The stuff above still require some shared knowledge, because "Clock" is likely, an API that I provide. One can write a proxy, of course, but it's not plug and play. Scala can go a bit further, if I declared my Benchmark module like this:
trait Benchmark {
type Clock = {
def now(): Long
}
def aClock: Clock
// What I provide
type ABench <: Bench
trait Bench {
def measure(task: => Unit): Long
}
def aBench: ABench
}
Now any class that offers a now(): Long method can be used to satisfy the requirement, without any bridge. Of course, if the name of the methods is "millis(): Long" instead of "now(): Long", I'm still screwed, and that kind of "binding" is something that languages providing module support might address, though not Scala. Also, due to how JVM works, there's a performance penalty there as well.
So, that's the module, and the module support. Finally first class module. First class support for X means X can be manipulated as values. For example, Scala has first class support for functions, which means I can pass a function to a method, store it in a variable, in a map, etc.
The first class support for modules, is basically instantiation, though one can use an "object" to create a singleton of that module, and then pass that around (the advantages of which I discuss further below). So, I can do this:
object myBenchmark extends MyModule with JVMClock
and pass myBenchmark as a parameter to methods that need such a module.
There are two elements in Scala that make all of that work: abstract types and path dependent types.
Abstract types, the "type" declarations, make it possible for a piece of code to declare it will be using a type X, which is not going to be defined by who calls or instantiates it, but, rather, at the moment modules get composed.
Path dependent types make it possible to work with modules without being completely unsafe, but without being so restrictive as to not allow anything. Let's say I do this:
val b: MyModule.Clock = MyModule.aClock
And let's say I have a method on Benchmark that took a Clock as a parameter. I can call that method on MyModule passing b as a parameter, because Scala knows that the Clock of b is the clock bound to MyModule. And if I try to pass b to another module implementing Benchmark, Scala would not let me do that. That is, I can get values out of Benchmark that are specific to abstract types of Benchmark -- unknown to all but the module implementations -- and feed it back to that Benchmark but not other Benchmark implementations.
In groovy one can do:
class Foo {
Integer a,b
}
Map map = [a:1,b:2]
def foo = new Foo(map) // map expanded, object created
I understand that Scala is not in any sense of the word, Groovy, but am wondering if map expansion in this context is supported
Simplistically, I tried and failed with:
case class Foo(a:Int, b:Int)
val map = Map("a"-> 1, "b"-> 2)
Foo(map: _*) // no dice, always applied to first property
A related thread that shows possible solutions to the problem.
Now, from what I've been able to dig up, as of Scala 2.9.1 at least, reflection in regard to case classes is basically a no-op. The net effect then appears to be that one is forced into some form of manual object creation, which, given the power of Scala, is somewhat ironic.
I should mention that the use case involves the servlet request parameters map. Specifically, using Lift, Play, Spray, Scalatra, etc., I would like to take the sanitized params map (filtered via routing layer) and bind it to a target case class instance without needing to manually create the object, nor specify its types. This would require "reliable" reflection and implicits like "str2Date" to handle type conversion errors.
Perhaps in 2.10 with the new reflection library, implementing the above will be cake. Only 2 months into Scala, so just scratching the surface; I do not see any straightforward way to pull this off right now (for seasoned Scala developers, maybe doable)
Well, the good news is that Scala's Product interface, implemented by all case classes, actually doesn't make this very hard to do. I'm the author of a Scala serialization library called Salat that supplies some utilities for using pickled Scala signatures to get typed field information
https://github.com/novus/salat - check out some of the utilities in the salat-util package.
Actually, I think this is something that Salat should do - what a good idea.
Re: D.C. Sobral's point about the impossibility of verifying params at compile time - point taken, but in practice this should work at runtime just like deserializing anything else with no guarantees about structure, like JSON or a Mongo DBObject. Also, Salat has utilities to leverage default args where supplied.
This is not possible, because it is impossible to verify at compile time that all parameters were passed in that map.
I've noticed that the Scala standard library uses two different strategies for organizing classes, traits, and singleton objects.
Using packages whose members are them imported. This is, for example, how you get access to scala.collection.mutable.ListBuffer. This technique is familiar coming from Java, Python, etc.
Using type members of traits. This is, for example, how you get access to the Parser type. You first need to mix in scala.util.parsing.combinator.Parsers. This technique is not familiar coming from Java, Python, etc, and isn't much used in third-party libraries.
I guess one advantage of (2) is that it organizes both methods and types, but in light of Scala 2.8's package objects the same can be done using (1). Why have both these strategies? When should each be used?
The nomenclature of note here is path-dependent types. That's the option number 2 you talk of, and I'll speak only of it. Unless you happen to have a problem solved by it, you should always take option number 1.
What you miss is that the Parser class makes reference to things defined in the Parsers class. In fact, the Parser class itself depends on what input has been defined on Parsers:
abstract class Parser[+T] extends (Input => ParseResult[T])
The type Input is defined like this:
type Input = Reader[Elem]
And Elem is abstract. Consider, for instance, RegexParsers and TokenParsers. The former defines Elem as Char, while the latter defines it as Token. That means the Parser for the each is different. More importantly, because Parser is a subclass of Parsers, the Scala compiler will make sure at compile time you aren't passing the RegexParsers's Parser to TokenParsers or vice versa. As a matter of fact, you won't even be able to pass the Parser of one instance of RegexParsers to another instance of it.
The second is also known as the Cake pattern.
It has the benefit that the code inside the class that has a trait mixed in becomes independent of the particular implementation of the methods and types in that trait. It allows to use the members of the trait without knowing what's their concrete implementation.
trait Logging {
def log(msg: String)
}
trait App extends Logging {
log("My app started.")
}
Above, the Logging trait is the requirement for the App (requirements can also be expressed with self-types). Then, at some point in your application you can decide what the implementation will be and mix the implementation trait into the concrete class.
trait ConsoleLogging extends Logging {
def log(msg: String) = println(msg)
}
object MyApp extends App with ConsoleLogging
This has an advantage over imports, in the sense that the requirements of your piece of code aren't bound to the implementation defined by the import statement. Furthermore, it allows you to build and distribute an API which can be used in a different build somewhere else provided that its requirements are met by mixing in a concrete implementation.
However, there are a few things to be careful with when using this pattern.
All of the classes defined inside the trait will have a reference to the outer class. This can be an issue where performance is concerned, or when you're using serialization (when the outer class is not serializable, or worse, if it is, but you don't want it to be serialized).
If your 'module' gets really large, you will either have a very big trait and a very big source file, or will have to distribute the module trait code across several files. This can lead to some boilerplate.
It can force you to have to write your entire application using this paradigm. Before you know it, every class will have to have its requirements mixed in.
The concrete implementation must be known at compile time, unless you use some sort of hand-written delegation. You cannot mix in an implementation trait dynamically based on a value available at runtime.
I guess the library designers didn't regard any of the above as an issue where Parsers are concerned.