I notice, when I try to tab-complete in the Scala REPL (2.13.8) to get available methods, that some of the methods are marked (universal). What is this indicating?
For instance if I type 1. and then press the tab key, I see a bunch of methods including hashCode() (universal) and getClass() (unmarked). (I also see some methods marked (deprecated), in a similar way, but that seems pretty self-explanatory).
Related
As we know, it is easy to create an inner class in some methods with scala macro.
But I'd like to know is it possible to generate a top level class/object?
If the answer is yes, then how to avoid generate the same class twice?
my scala version is 2.11
Top-level expansions must retain the number of annottees, their flavors and their names, with the only exception that a class might expand into a same-named class plus a same-named module, in which case they automatically become companions as per previous rule.
https://docs.scala-lang.org/overviews/macros/annotations.html
So you can transform top-level
#annot
class A
into
class A
object A
or
#annot
object A
into
class A
object A
Also there existed c.introduceTopLevel but it was removed.
Context.introduceTopLevel. The Context.introduceTopLevel API, which used to be available in early milestone builds of Scala 2.11.0 as a stepping stone towards type macros, was removed from the final release, because type macros were rejected for including in Scala and discontinued in macro paradise.
https://docs.scala-lang.org/overviews/macros/changelog211.html
Scala Macro: Define Top Level Object
introduceTopLevel has provided a long-requested functionality of generating definitions that can be used outside macro expansions. However, metaprogrammers have
quickly discovered that introduceTopLevel is dangerous. Top-level scope is a resource shared between the typechecker and user metaprograms, so mutating it with
introduceTopLevel can lead to compilation order problems. For example, if one file
in a compilation run relies on definitions created by a macro expansion performed in
another file, compiling the former before the latter may lead to unexpected compilation
errors.
https://infoscience.epfl.ch/record/226166/files/EPFL_TH7159.pdf (section 5.2.3 Conclusion)
If the companion you want to generate already exists then the companion you return in macro annotation's macroTransform will replace the original. You don't need to beware that there will be two "companions", compiler will watch that. But surely normally you match if that's the case (whether there is only annottee or annottee + companion).
Within an annotation Macro, I'm enumerating members of a class and want the types of the methods that I find.
So I happily iterate over the body of the class, and collect all the DefDef members.
... which I can't typecheck.
For each DefDef I've tried wrapping it in an Expr and using actualType. I've tried duplicating the thing and transplanting it into an ad-hoc class (via quasiquotes). I've tried everything else I can think of :)
The best I can get is either NoType or Any, depending on the technique used. The worst I get is to have an exception thrown at me.
These are simple methods, of the form def foo(i: String) = i, so the return type needs to be inferred, but there's no external information required. There are no abstract types, or type params, or other members of the class involved here. I'd like to handle more advanced cases later, but want to have these trivial examples working first.
In a plugin, this would be simple. I'd just typecheck the entire unit with errors suppressed and get at what I want through the symbols, then reset the tree attributes for subsequent processing. As a macro... I'm stumped.
What am I missing?
In a macro it's the same. Instead of typed as in plugins, you call c.typeCheck, but have to be careful not to fall into a trap (https://github.com/scalamacros/paradise/issues/1) that is supposed to be fixed in 2.10.5 and 2.11.0. After a successful return from a c.typeCheck, you can get access to the symbol and do all the usual stuff.
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.
Under Window > Preferences > General > Search, there is the option Ignore potential matches
What does it do? Whether I activate it or not, I never see a difference.
Is it an option that only makes sense for Java development (which I never do, but I do develop in C, Python and PHP using Eclipse)?
See bug 127442 for examples: depending on what you are searching (a class, a method, ...), the Search engine can find instances which could match (but it cannot say for certain).
Those instances are marked "POTENTIAL_MATCH":
A method with different number of parameters is not a potential match.
(see bug 97322 )
A potential match is a match where the resolution failed (e.g. the method binding is null).
If the user searches for "foo(String)" (without qualifying String), then "foo(java.lang.String)" and "foo(p.String)" are both exact matches.
For the .class file case, I think we can only have potential matches in the case of the missing type case (see bug 196200), i.e if the .class file was compiled and some types it references were missing.
A current example of potential match misbehavior is found in bug 382778:
I have a public static void method printIt(String name).
When I open its call hierarchy, some callers are missing.
I am guessing the callers are missing because java search marks them as potential instead of exact matches for the printIt(String) reference.
The following code is sometimes marked as potential, and sometimes exact:
// Listing 1
PublicInterface2 impl2 = new Impl2("Name Broken");
Static.printIt(impl2.getName());
When the search result is marked potential, the caller is missing from the printIt() call hierarchy.
PublicInterface2 is an empty public interface which extends PackageInterface2Getters.
PackageInterface2Getters is an empty default-scoped interface which extends PackageInterface1Getters.
PackageInterface1Getters is a default-scoped interface which declares String getName().
So impl2.getName() above returns a String.
There are some problems reported which I guess make the matches be marked as potential:
...
Filename : \D:\workspace\eclipse\_runtimes\jdt\call-hierarchy-bug\src\main\PublicInterface2.java
COMPILED type(s)
2 PROBLEM(s) detected
- Pb(2) PackageInterface1Getters cannot be resolved to a type
- Pb(327) The hierarchy of the type PublicInterface2 is inconsistent
Turns out that:
The compiler asks the "NameEnvironment" to get the type information of any dependent type.
Search has it's own NameEnvironment implementation in JavaSearchNameEnvironment and it is not looking for secondary types.
This is bad and it is surprising that we haven't run into this problem until now.
In Eclipse Luna (Service Release 1 (4.4.1)) I searched just for references to this Java method:
merge(DashboardConfigurationModel template, DashboardModel custom)
It returns two references. One of these calls to the merge() method passes in a DashboardConfigurationModel and a DashboardModel, as befits the method signature. This is a match all right!
The other reference to a merge() method passes in a String and a Map. It is marked in Eclipse as a "potential match" but in my mind, since the argument types don't match, this has zero potential to be a match.
I then checked Ignore potential matches, did the search again, and this noise went away.
Special means that they give you functionality which is impossible to get otherwise, so they treat by compiler in special way.
Examples: 'DelayedInit' - convert all init code to main methods, 'Dynamic' - proxy of all methods etc
At present, the only special traits I'm aware of are DelayedInit and Dynamic.
Anything inheriting from these traits also gets special treatment by the compiler, as with App, which subclasses DelayedInit.
It's worth noting that any trait could potentially be used as a marker by some library, framework, or compiler plugin to "give you functionality which is impossible to get otherwise". These two are the only traits that are specially recognized by the default compiler though.
As well as marker traits, there are some annotations that get treated specially, the scala.annotation and scala.reflect are good places to find these, there's also the #specialized annotation in the scala package and several in compiler plugins (such as delimited continuations).
There is also scala.Singleton.
It is a final trait and cannot be used normally while writing code, but everyone using some a singleton like object Foo has already used it indirectly.
Singleton is used by the compiler to extend a singleton, therefore:
scala> object Foo
defined module Foo
scala> Foo.isInstanceOf[Singleton]
res0: Boolean = true