Searching inside scala 2.10 ASTs - scala

What's the best way to recursively search for an element in scala 2.10 ASTs?
The trees might be a result of power.trees(code) or mirror.mkToolBox().parseExpr(code)
Edit. In 2.10.0-RC1 parseExpr has been renamed to parse.
The concrete use-case that I have is extracting the code of a method from a given class/object code by method name,
but I assume that the question would be more relevant for others if formulated in a more generic way.

Maybe you should have a look at https://github.com/scala/scala/blob/2.10.x/src/reflect/scala/reflect/api/Trees.scala#L606, especially at the classes Traverser, Transformer and the methods for substitution (Tree.substituteSymbols, Tree.substituteTypes or Tree.substituteThis). If you want to extract a method from a tree, you can use a Traverser and override the traverse method. In the traverse method, you check whether the node matches the method you want. If so, you are done. If not, you call super.traverse.

Related

How can I allow the caller to call method of field of case class?

I am not sure the keywords for this pattern, sorry if the question is not clear.
If you have:
case class MyFancyWrapper(
somethingElse: Any,
heavyComplexObject: CrazyThing
)
val w = MyFancyWrapper(???, complexThing)
I want to be able to call w.method with the method coming from complexThing. I tried to extends CrazyThing but it is a trait and I don't want to implement all the method that would be very tedious. I also don't want to have to do:
def method1 = heavyComplexObject.method1
...
for all of them.
Any solution ?
Thanks.
You can do this with macros but I agree with Luis that this is an overkill. Macros are intended to repetitive boring things, not one time boring things. Also this is not as trivial as it sounds, because you probably don't want to pass through all the methods (you probably still want your own hashCode and equals). Finally macros have bad IDE support so most probably no auto-completion for all those methods. On the other hand if you do use a good IDE (like IDEA) there is most probably an action like "Delegate methods" that will generate most of the code for you. You still will have to change the return type from Unit to MyFancyWrapper and add returning this at the end of each method but this can easily be done with mass replace operations (hint: replace "}" with "this }" and the automatically re-formatting code should do the trick)
Here are some screenshots of the process from JetBrains IDEA:
You can use an implicit conversion to make all the methods of heavyComplexThing directly available on MyFancyWrapper:
implicit def toHeavy(fancy: MyFancyWrapper): CrazyThing = fancy.heavyComplexObject
This needs to be in scope when the method is called.
In the comments you indicate that you want to return this so that you can chain multiple calls on the same object:
w.method1.method2.method3
Don't do this
While this is a common pattern in non-functional languages, it is bad practice is Scala for two reasons:
This pattern inherently relies on side-effects, which is the antithesis of functional programming.
It is confusing, because in Scala chaining calls in this way is used to implement a data pipeline, where the output of one function is passed as the input to the next.
It is much clearer to write separate statements so that it is obvious that the methods are being called on the same object:
w.method1()
w.method2()
w.method3()
(It is also conventional to use () when calling methods with side effects)

Scala equivalent of java.util.Collection?

What is the equivalent of java.util.Collection? I first thought Seq is the way to go, but actually it's an ordered set of elements. I mean we have a numeration of elements.
Collection Hierarcy
Traversable is on top above iterable
The picture above is very good looking, but it is not helpful at all in answering the question. (It may be helpful as general reference for other purposes, but not for this purpose.) It is even missing some very important interfaces. So, here is some good old text to try and clear out the confusion:
The Scala equivalent to java.util.Collection is scala.collection.Iterable, despite the mismatch in the name.
You see, scala.collection.Iterable offers the basic functionality of a Java Collection: it has an iterator and a size.
Apparently, what Java calls Iterable Scala calls it Traversable, and then what Java calls Collection Scala calls it Iterable.

Scala list with stackable modifications example

I have read the following example on stackable modifications in scala: https://www.artima.com/pins1ed/traits.html#12.5
We have an abstract IntQueue whose put method is implemented in BasicQueue. BasicQueue gets modified by some traits that should modify the behavior of put. I don't understand why this works. If I understand linearization correctly, then BasicQueue is the first element in the linearization, therefore queue.put should call BasicQueue.put. I think that the implementation of BasicQueue.put should be in IntQueue.put which is the last method to call since IntQueue is the last element in the linearization. Then of course put shouldn't be implemented in BasicQueue.
Is my argumentation correct or where am I wrong.
ps: I don't have access to a computer with scala at the moment, otherwise I would try it out.

Scala objects masked as methods vs actual method (Stream.cons)

I have been going through the Scala Stream collection API and I have noticed that Stream.cons is implemented as an embedded object. What advantage does this have over implementing it as a function? Under what circumstances should one consider using this technique?
Cheers.
As an object, it defines unapply in addition to apply, which let you pattern match on it.

Common in scala's Array and List

I'm new to scala(just start learning it), but have figured out smth strange for me: there are classes Array and List, they both have such methods/functions as foreach, forall, map etc. But any of these methods aren't inherited from some special class(trait). From java perspective if Array and List provide some contract, that contract have to be declared in interface and partially implemented in abstract classes. Why do in scala each type(Array and List) declares own set of methods? Why do not they have some common type?
But any of these methods aren't inherited from some special class(trait)
That simply not true.
If you open scaladoc and lookup say .map method of Array and List and then click on it you'll see where it is defined:
For list:
For array:
See also info about Traversable and Iterable both of which define most of the contracts in scala collections (but some collections may re-implement methods defined in Traversable/Iterable, e.g. for efficiency).
You may also want to look at relations between collections (scroll to the two diagrams) in general.
I'll extend om-nom-nom answer here.
Scala doesn't have an Array -- that's Java Array, and Java Array doesn't implement any interface. In fact, it isn't even a proper class, if I'm not mistaken, and it certainly is implemented through special mechanisms at the bytecode level.
On Scala, however, everything is a class -- an Int (Java's int) is a class, and so is Array. But in these cases, where the actual class comes from Java, Scala is limited by the type hierarchy provided by Java.
Now, going back to foreach, map, etc, they are not methods present in Java. However, Scala allows one to add implicit conversions from one class to another, and, through that mechanism, add methods. When you call arr.foreach(println), what is really done is Predef.refArrayOps(arr).foreach(println), which means foreach belongs to the ArrayOps class -- as you can see in the scaladoc documentation.