I'm reading some code that looks like this:
trait Thingy {
def apply(d: => Unit): Unit
...
}
object Thingy {
def apply(d: => Unit) = {
...
}
}
Where does Odersky in his book edition 3 write about traits and traits having companion objects? His book mostly talks about how classes can have companion objects but not traits. Where is this written?
Also, how would you use thingy? I see that it's use like this:
Thingy {
implicit variable =>
val something = ...
}
What is going on in the above? Odersky doesn't seem to write about how curly braces can be used to call the apply method. Is this what is going on? Where is this written?
In Chapter 9, section 4 "Writing new control structures", Odersky says (all typos are mine):
One way in which you can make the client code look a bit more like a built-in control structure is to use curly braces instead of parentheses to surround the argument list. In any method invocation in Scala in which you're passing in exactly one argument, you can opt to use curly braces to surround the argument instead of parentheses.
In Chapter 3, "Step 7" he also talks about apply:
When you apply parentheses surrounding one or more values to a variable, Scala will transform the code into an invocation of a method named apply on that variable.
Applying these two rules together results in
Thingy { ... }
being rewritten into
Thingy( ... )
and then into
Thingy.apply(...)
It gets even funnier with implicit parameters. For example, for typeclasses it is common to define an apply that looks as follows:
trait MyTypeClass[A]
object MyTypeClass {
def apply[A](implicit inst: MyTypeClass[A]) = inst
}
so that the value-expression MyTypeClass[Int] desugars into MyTypeClass.apply[Int](someImplicitlyInjectedInstance), and thus is a value of type MyTypeClass[Int]. So, both the value MyTypeClass[Int] and the type MyTypeClass[Int] look exactly the same.
On the fact that it is not told explicitly that traits can also have companion objects: there are a lot of things that aren't told explicitly. For example, it was not told explicitly that you can write down type-lambdas in Scala, but it turned out that you actually can.
Related
While reading Functional Programming in Scala by Chiusano and Bjarnason, I encountered the following code in chapter 9, Parser Combinators:
trait Parsers[ParseError, Parser[+_]] { self =>
...
def or[A](s1: Parser[A], s2: Parser[A]): Parser[A]
implicit def string(s: String): Parser[String]
implicit def operators[A](p: Parser[A]) = ParserOps[A](p)
implicit def asStringParser[A](a: A)(implicit f: A => Parser[String]):
ParserOps[String] = ParserOps(f(a))
case class ParserOps[A](p: Parser[A]) {
def |[B>:A](p2: Parser[B]): Parser[B] = self.or(p,p2)
def or[B>:A](p2: => Parser[B]): Parser[B] = self.or(p,p2)
}
}
I understand that if there is a type incompatibility or missing parameters during compilation, the Scala compiler would look for a missing function that converts the non-matching type to the desired type or a variable in scope with the desired type that fits the missing parameter respectively.
If a string occurs in a place that requires a Parser[String], the string function in the above trait should be invoked to convert the string to a Parser[String].
However, I've difficulties understanding the operators and asStringParser functions. These are the questions that I have:
For the implicit operators function, why isn't there a return type?
Why is ParserOps defined as a case class and why can't the | or or function be defined in the Parsers trait itself?
What exactly is the asStringParser trying to accomplish? What is its purpose here?
Why is self needed? The book says, "Use self to explicitly disambiguate reference to the or method on the trait," but what does it mean?
I'm truly enjoying the book but the use of advanced language-specific constructs in this chapter is hindering my progress. It would be of great help if you can explain to me how this code works. I understand that the goal is to make the library "nicer" to use through operators like | and or, but don't understand how this is done.
Every method has a return type. In this case, it's ParserOps[A]. You don't have to write it out explicitly, because in this case it can be inferred automatically.
Probably because of the automatically provided ParserOps.apply-factory method in the companion object. You need fewer vals in the constructor, and you don't need the new keyword to instantiate ParserOps. It is not used in pattern matching though, so, you could do the same thing with an ordinary (non-case) class, wouldn't matter.
It's the "pimp-my-library"-pattern. It attaches methods | and or to Parser, without forcing Parser to inherit from anything. In this way, you can later declare Parser to be something like ParserState => Result[A], but you will still have methods | and or available (even though Function1[ParserState, Result[A]] does not have them).
You could put | and or directly in Parsers, but then you would have to use the syntax
|(a, b)
or(a, b)
instead of the much nicer
a | b
a or b
There are no "real operators" in Scala, everything is a method. If you want to implement a method that behaves as if it were an infix operator, you do exactly what is done in the book.
I have a following function:
def getIntValue(x: Int)(implicit y: Int ) : Int = {x + y}
I see above declaration everywhere. I understand what above function is doing. It is a currying function which takes two arguments. If you omit the second argument, it will invoke implicit definition which returns int instead. So I think it is something very similar to defining a default value for the argument.
implicit val temp = 3
scala> getIntValue(3)
res8: Int = 6
I was wondering what are the benefits of above declaration?
Here's my "pragmatic" answer: you typically use currying as more of a "convention" than anything else meaningful. It comes in really handy when your last parameter happens to be a "call by name" parameter (for example: : => Boolean):
def transaction(conn: Connection)(codeToExecuteInTransaction : => Boolean) = {
conn.startTransaction // start transaction
val booleanResult = codeToExecuteInTransaction //invoke the code block they passed in
//deal with errors and rollback if necessary, or commit
//return connection to connection pool
}
What this is saying is "I have a function called transaction, its first parameter is a Connection and its second parameter will be a code-block".
This allows us to use this method like so (using the "I can use curly brace instead of parenthesis rule"):
transaction(myConn) {
//code to execute in a transaction
//the code block's last executable statement must be a Boolean as per the second
//parameter of the transaction method
}
If you didn't curry that transaction method, it would look pretty unnatural doing this:
transaction(myConn, {
//code block
})
How about implicit? Yes it can seem like a very ambiguous construct, but you get used to it after a while, and the nice thing about implicit functions is they have scoping rules. So this means for production, you might define an implicit function for getting that database connection from the PROD database, but in your integration test you'll define an implicit function that will superscede the PROD version, and it will be used to get a connection from a DEV database instead for use in your test.
As an example, how about we add an implicit parameter to the transaction method?
def transaction(implicit conn: Connection)(codeToExecuteInTransaction : => Boolean) = {
}
Now, assuming I have an implicit function somewhere in my code base that returns a Connection, like so:
def implicit getConnectionFromPool() : Connection = { ...}
I can execute the transaction method like so:
transaction {
//code to execute in transaction
}
and Scala will translate that to:
transaction(getConnectionFromPool) {
//code to execute in transaction
}
In summary, Implicits are a pretty nice way to not have to make the developer provide a value for a required parameter when that parameter is 99% of the time going to be the same everywhere you use the function. In that 1% of the time you need a different Connection, you can provide your own connection by passing in a value instead of letting Scala figure out which implicit function provides the value.
In your specific example there are no practical benefits. In fact using implicits for this task will only obfuscate your code.
The standard use case of implicits is the Type Class Pattern. I'd say that it is the only use case that is practically useful. In all other cases it's better to have things explicit.
Here is an example of a typeclass:
// A typeclass
trait Show[a] {
def show(a: a): String
}
// Some data type
case class Artist(name: String)
// An instance of the `Show` typeclass for that data type
implicit val artistShowInstance =
new Show[Artist] {
def show(a: Artist) = a.name
}
// A function that works for any type `a`, which has an instance of a class `Show`
def showAListOfShowables[a](list: List[a])(implicit showInstance: Show[a]): String =
list.view.map(showInstance.show).mkString(", ")
// The following code outputs `Beatles, Michael Jackson, Rolling Stones`
val list = List(Artist("Beatles"), Artist("Michael Jackson"), Artist("Rolling Stones"))
println(showAListOfShowables(list))
This pattern originates from a functional programming language named Haskell and turned out to be more practical than the standard OO practices for writing a modular and decoupled software. The main benefit of it is it allows you to extend the already existing types with new functionality without changing them.
There's plenty of details unmentioned, like syntactic sugar, def instances and etc. It is a huge subject and fortunately it has a great coverage throughout the web. Just google for "scala type class".
There are many benefits, outside of your example.
I'll give just one; at the same time, this is also a trick that you can use on certain occasions.
Imagine you create a trait that is a generic container for other values, like a list, a set, a tree or something like that.
trait MyContainer[A] {
def containedValue:A
}
Now, at some point, you find it useful to iterate over all elements of the contained value.
Of course, this only makes sense if the contained value is of an iterable type.
But because you want your class to be useful for all types, you don't want to restrict A to be of a Seq type, or Traversable, or anything like that.
Basically, you want a method that says: "I can only be called if A is of a Seq type."
And if someone calls it on, say, MyContainer[Int], that should result in a compile error.
That's possible.
What you need is some evidence that A is of a sequence type.
And you can do that with Scala and implicit arguments:
trait MyContainer[A] {
def containedValue:A
def aggregate[B](f:B=>B)(implicit ev:A=>Seq[B]):B =
ev(containedValue) reduce f
}
So, if you call this method on a MyContainer[Seq[Int]], the compiler will look for an implicit Seq[Int]=>Seq[B].
That's really simple to resolve for the compiler.
Because there is a global implicit function that's called identity, and it is always in scope.
Its type signature is something like: A=>A
It simply returns whatever argument is passed to it.
I don't know how this pattern is called. (Can anyone help out?)
But I think it's a neat trick that comes in handy sometimes.
You can see a good example of that in the Scala library if you look at the method signature of Seq.sum.
In the case of sum, another implicit parameter type is used; in that case, the implicit parameter is evidence that the contained type is numeric, and therefore, a sum can be built out of all contained values.
That's not the only use of implicits, and certainly not the most prominent, but I'd say it's an honorable mention. :-)
Methods are often declared with obvious parameter names, e.g.
def myMethod(s: String, image: BufferedImage, mesh: Mesh) { ... }
Parameter names correspond to parameter types.
1) "s" is often used for String
2) "i" for Int
3) lowercased class name for one word named classes (Mesh -> mesh)
4) lowercased last word from class name for long class names (BufferedImage -> image)
(Of course, it would not be convenient for ALL methods and arguments. Of course, somebody would prefer other rules…)
Scala macros are intended to generate some expressions in code. I would like to write some specific macros to convert to correct Scala expressions something like this:
// "arguments interpolation" style
// like string interpolation
def myMethod s[String, BufferedImage, Mesh]
{ /* code using vars "s", "image", "mesh" */ }
// or even better:
mydef myMethod[String, BufferedImage, Mesh]
{ /* code using vars "s", "image", "mesh" */ }
Is it possible?
Currently it is not possible and probably it will never be. Macros can not introduce their own syntax - they must be represented through valid Scala code (which can be executed at compile time) and, too, they must generate valid Scala code (better say a valid Scala AST).
Both of your shown examples are not valid Scala code, thus Macros can not handle them. Nevertheless, the current nightly build of Macro Paradise includes untyped macros. They allow to write Scala code which is typechecked after they are expanded, this means it is possible to write:
forM({i = 0; i < 10; i += 1}) {
println(i)
}
Notice, that the curly braces inside of the first parameter list are needed because, although the code is not typechecked when one writes it, it must represent a valid Scala AST.
The implementation of this macro looks like this:
def forM(header: _)(body: _) = macro __forM
def __forM(c: Context)(header: c.Tree)(body: c.Tree): c.Tree = {
import c.universe._
header match {
case Block(
List(
Assign(Ident(TermName(name)), Literal(Constant(start))),
Apply(Select(Ident(TermName(name2)), TermName(comparison)), List(Literal(Constant(end))))
),
Apply(Select(Ident(TermName(name3)), TermName(incrementation)), List(Literal(Constant(inc))))
) =>
// here one can generate the behavior of the loop
// but omit full implementation for clarity now ...
}
}
Instead of an already typechecked expression, the macro expects only a tree, that is typechecked after the expansion. The method call itself expects two parameter lists, whose parameter types can be delayed after the expansion phase if one uses an underscore.
Currently there is a little bit of documentation available but because it is extremely beta a lot of things will probably change in future.
With type macros it is possible to write something like this:
object O extends M {
// traverse the body of O to find what you want
}
type M(x: _) = macro __M
def __M(c: Context)(x: c.Tree): c.Tree = {
// omit full implementation for clarity ...
}
This is nice in order to delay the typechecking of the whole body because it allows to to cool things...
Macros that can change Scalas syntax are not planned at the moment and are probably not a good idea. I can't say if they will happen one day only future can tell us this.
Aside from the "why" (no really, why do you want to do that?), the answer is no, because as far as I know macros cannot (in their current state) generate methods or types, only expressions.
I've been working with Scala Macros and have the following code in the macro:
val fieldMemberType = fieldMember.typeSignatureIn(objectType) match {
case NullaryMethodType(tpe) => tpe
case _ => doesntCompile(s"$propertyName isn't a field, it must be another thing")
}
reify{
new TypeBuilder() {
type fieldType = fieldMemberType.type
}
}
As you can see, I've managed to get a c.universe.Type fieldMemberType. This represents the type of certain field in the object. Once I get that, I want to create a new TypeBuilder object in the reify. TypeBuilder is an abstract class with an abstract parameter. This abstract parameter is fieldType. I want this fieldType to be the type that I've found before.
Running the code shown here returns me a fieldMemberType not found. Is there any way that I can get the fieldMemberType to work inside the reify clause?
The problem is that the code you pass to reify is essentially going to be placed verbatim at the point where the macro is being expanded, and fieldMemberType isn't going to mean anything there.
In some cases you can use splice to sneak an expression that you have at macro-expansion time into the code you're reifying. For example, if we were trying to create an instance of this trait:
trait Foo { def i: Int }
And had this variable at macro-expansion time:
val myInt = 10
We could write the following:
reify { new Foo { def i = c.literal(myInt).splice } }
That's not going to work here, which means you're going to have to forget about nice little reify and write out the AST by hand. You'll find this happens a lot, unfortunately. My standard approach is to start a new REPL and type something like this:
import scala.reflect.runtime.universe._
trait TypeBuilder { type fieldType }
showRaw(reify(new TypeBuilder { type fieldType = String }))
This will spit out several lines of AST, which you can then cut and paste into your macro definition as a starting point. Then you fiddle with it, replacing things like this:
Ident(TypeBuilder)
With this:
Ident(newTypeName("TypeBuilder"))
And FINAL with Flag.FINAL, and so on. I wish the toString methods for the AST types corresponded more exactly to the code it takes to build them, but you'll pretty quickly get a sense of what you need to change. You'll end up with something like this:
c.Expr(
Block(
ClassDef(
Modifiers(Flag.FINAL),
anon,
Nil,
Template(
Ident(newTypeName("TypeBuilder")) :: Nil,
emptyValDef,
List(
constructor(c),
TypeDef(
Modifiers(),
newTypeName("fieldType"),
Nil,
TypeTree(fieldMemberType)
)
)
)
),
Apply(Select(New(Ident(anon)), nme.CONSTRUCTOR), Nil)
)
)
Where anon is a type name you've created in advance for your anonymous class, and constructor is a convenience method I use to make this kind of thing a little less hideous (you can find its definition at the end of this complete working example).
Now if we wrap this expression up in something like this, we can write the following:
scala> TypeMemberExample.builderWithType[String]
res0: TypeBuilder{type fieldType = String} = $1$$1#fb3f1f3
So it works. We've taken a c.universe.Type (which I get here from the WeakTypeTag of the type parameter on builderWithType, but it will work in exactly the same way with any old Type) and used it to define the type member of our TypeBuilder trait.
There is a simpler approach than tree writing for your use case. Indeed I use it all the time to keep trees at bay, as it can be really difficult to program with trees. I prefer to compute types and use reify to generate the trees. This makes much more robust and "hygienic" macros and less compile time errors. IMO using trees must be a last resort, only for a few cases, such as tree transforms or generic programming for a family of types such as tuples.
The tip here is to define a function taking as type parameters, the types you want to use in the reify body, with a context bound on a WeakTypeTag. Then you call this function by passing explicitly the WeakTypeTags you can build from universe Types thanks to the context WeakTypeTag method.
So in your case, that would give the following.
val fieldMemberType: Type = fieldMember.typeSignatureIn(objectType) match {
case NullaryMethodType(tpe) => tpe
case _ => doesntCompile(s"$propertyName isn't a field, it must be another thing")
}
def genRes[T: WeakTypeTag] = reify{
new TypeBuilder() {
type fieldType = T
}
}
genRes(c.WeakTypeTag(fieldMemberType))
I understand the difference between zero-parameter and parameterless methods, but what I don't really understand is the language design choice that made parameterless methods necessary.
Disadvantages I can think of:
It's confusing. Every week or two there are questions here or on the Scala mailing list about it.
It's complicated; we also have to distinguish between () => X and => X.
It's ambiguous: does x.toFoo(y) mean what it says, or x.toFoo.apply(y)? (Answer: it depends on what overloads there are x's toFoo method and the overloads on Foo's apply method, but if there's a clash you don't see an error until you try to call it.)
It messes up operator style method calling syntax: there is no symbol to use in place of the arguments, when chaining methods, or at the end to avoid semicolon interference. With zero-arg methods you can use the empty parameter list ().
Currently, you can't have both defined in a class: you get an error saying the method is already defined. They also both convert to a Function0.
Why not just make methods def foo and def foo() exactly the same thing, and allow them to be called with or without parentheses? What are the upsides of how it is?
Currying, That's Why
Daniel did a great job at explaining why parameterless methods are necessary. I'll explain why they are regarded distinctly from zero-parameter methods.
Many people view the distinction between parameterless and zero-parameter functions as some vague form of syntactic sugar. In truth it is purely an artifact of how Scala supports currying (for completeness, see below for a more thorough explanation of what currying is, and why we all like it so much).
Formally, a function may have zero or more parameter lists, with zero or more parameters each.
This means the following are valid: def a, def b(), but also the contrived def c()() and def d(x: Int)()()(y: Int) etc...
A function def foo = ??? has zero parameter lists. A function def bar() = ??? has precisely one parameter list, with zero parameters. Introducing additional rules that conflate the two forms would have undermined currying as a consistent language feature: def a would be equivalent in form to def b() and def c()() both; def d(x: Int)()()(y: Int) would be equivalent to def e()(x: Int)(y: Int)()().
One case where currying is irrelevant is when dealing with Java interop. Java does not support currying, so there's no problem with introducing syntactic sugar for zero-parameter methods like "test".length() (which directly invokes java.lang.String#length()) to also be invoked as "test".length.
A quick explanation of currying
Scala supports a language feature called 'currying', named after mathematician Haskell Curry.
Currying allows you to define functions with several parameter lists, e.g.:
def add(a: Int)(b: Int): Int = a + b
add(2)(3) // 5
This is useful, because you can now define inc in terms of a partial application of add:
def inc: Int => Int = add(1)
inc(2) // 3
Currying is most often seen as a way of introducing control structures via libraries, e.g.:
def repeat(n: Int)(thunk: => Any): Unit = (1 to n) foreach { _ => thunk }
repeat(2) {
println("Hello, world")
}
// Hello, world
// Hello, world
As a recap, see how repeat opens up another opportunity to use currying:
def twice: (=> Any) => Unit = repeat(2)
twice {
println("Hello, world")
}
// ... you get the picture :-)
One nice thing about an issue coming up periodically on the ML is that there are periodic answers.
Who can resist a thread called "What is wrong with us?"
https://groups.google.com/forum/#!topic/scala-debate/h2Rej7LlB2A
From: martin odersky Date: Fri, Mar 2, 2012 at
12:13 PM Subject: Re: [scala-debate] what is wrong with us...
What some people think is "wrong with us" is that we are trying bend
over backwards to make Java idioms work smoothly in Scala. The
principaled thing would have been to say def length() and def length
are different, and, sorry, String is a Java class so you have to write
s.length(), not s.length. We work really hard to paper over it by
admitting automatic conversions from s.length to s.length(). That's
problematic as it is. Generalizing that so that the two are identified
in the type system would be a sure way to doom. How then do you
disambiguate:
type Action = () => () def foo: Action
Is then foo of type Action or ()? What about foo()?
Martin
My favorite bit of paulp fiction from that thread:
On Fri, Mar 2, 2012 at 10:15 AM, Rex Kerr <ich...#gmail.com> wrote:
>This would leave you unable to distinguish between the two with
>structural types, but how often is the case when you desperately
>want to distinguish the two compared to the case where distinguishing
>between the two is a hassle?
/** Note to maintenance programmer: It is important that this method be
* callable by classes which have a 'def foo(): Int' but not by classes which
* merely have a 'def foo: Int'. The correctness of this application depends
* on maintaining this distinction.
*
* Additional note to maintenance programmer: I have moved to zambia.
* There is no forwarding address. You will never find me.
*/
def actOnFoo(...)
So the underlying motivation for the feature is to generate this sort of ML thread.
One more bit of googlology:
On Thu, Apr 1, 2010 at 8:04 PM, Rex Kerr <[hidden email]> wrote: On
Thu, Apr 1, 2010 at 1:00 PM, richard emberson <[hidden email]> wrote:
I assume "def getName: String" is the same as "def getName(): String"
No, actually, they are not. Even though they both call a method
without parameters, one is a "method with zero parameter lists" while
the other is a "method with one empty parameter list". If you want to
be even more perplexed, try def getName()(): String (and create a
class with that signature)!
Scala represents parameters as a list of lists, not just a list, and
List() != List(List())
It's kind of a quirky annoyance, especially since there are so few
distinctions between the two otherwise, and since both can be
automatically turned into the function signature () => String.
True. In fact, any conflation between parameterless methods and
methods with empty parameter lists is entirely due to Java interop.
They should be different but then dealing with Java methods would be
just too painful. Can you imagine having to write str.length() each
time you take the length of a string?
Cheers
First off, () => X and => X has absolutely nothing to do with parameterless methods.
Now, it looks pretty silly to write something like this:
var x() = 5
val y() = 2
x() = x() + y()
Now, if you don't follow what the above has to do with parameterless methods, then you should look up uniform access principle. All of the above are method declarations, and all of them can be replaced by def. That is, assuming you remove their parenthesis.
Besides the convention fact mentioned (side-effect versus non-side-effect), it helps with several cases:
Usefulness of having empty-paren
// short apply syntax
object A {
def apply() = 33
}
object B {
def apply = 33
}
A() // works
B() // does not work
// using in place of a curried function
object C {
def m()() = ()
}
val f: () => () => Unit = C.m
Usefulness of having no-paren
// val <=> def, var <=> two related defs
trait T { def a: Int; def a_=(v: Int): Unit }
trait U { def a(): Int; def a_=(v: Int): Unit }
def tt(t: T): Unit = t.a += 1 // works
def tu(u: U): Unit = u.a += 1 // does not work
// avoiding clutter with apply the other way round
object D {
def a = Vector(1, 2, 3)
def b() = Vector(1, 2, 3)
}
D.a(0) // works
D.b(0) // does not work
// object can stand for no-paren method
trait E
trait F { def f: E }
trait G { def f(): E }
object H extends F {
object f extends E // works
}
object I extends G {
object f extends E // does not work
}
Thus in terms of regularity of the language, it makes sense to have the distinction (especially for the last shown case).
I would say both are possible because you can access mutable state with a parameterless method:
class X(private var x: Int) {
def inc() { x += 1 }
def value = x
}
The method value does not have side effects (it only accesses mutable state). This behavior is explicitly mentioned in Programming in Scala:
Such parameterless methods are quite common in Scala. By contrast, methods defined with empty parentheses, such as def height(): Int, are called empty-paren methods. The recommended convention is to use a parameterless method whenever there are no parameters and the method accesses mutable state only by reading fields of the containing object (in particular, it does not change mutable state).
This convention supports the uniform access principle [...]
To summarize, it is encouraged style in Scala to define methods that take no parameters and have no side effects as parameterless methods, i.e., leaving off the empty parentheses. On the other hand, you should never define a method that has side-effects without parentheses, because then invocations of that method would look like a field selection.