What is the relationship of TypeMirrors and Elements in the lang model? - annotation-processing

(While this question is tagged with annotation-processing I'm actually asking questions about the type model exposed by javax.lang.model whether or not annotation processing is involved.)
In javax.lang.model, there are two fundamental constructs: Elements and TypeMirrors.
Every Element is backed by a TypeMirror. However only certain TypeMirror subtypes, namely DeclaredType and TypeVariable, have Elements associated with them via DeclaredType#asElement() and TypeVariable#asElement() respectively.
(It follows that all Elements "have" TypeMirrors, but not all TypeMirrors "have" Elements.)
Speaking loosely and intuitively, this makes sense: you declare types by chanting certain Java spells: the spells themselves are the (declared) elements; the things they bring into being are the types that back them. I've programmed in Java for decades and have a good working familiarity with oddities like Foo implements Comparable<Foo>. I'm trying to get more rigorous here.
With all that in mind, and considering the following snippet, how are the javax.lang.model types and elements manifested?
// (Defined by the JDK itself of course.)
public interface Comparable<T> ...
// (My class.)
public class Frob implements Comparable<Frob> ...
I see the following "things", working from "top" to "bottom" with less and less certainty as I go along:
a TypeParameterElement whose affiliated Name is equal to "T"
The return value of its asType() method will be a (definitionally nameless) TypeVariable whose asElement() method will return the TypeParameterElement currently being discussed.
The return value of its getGenericElement() method (and its getEnclosingElement() method) will be the Element we'll talk about next ("Comparable").
a TypeElement whose affiliated Name is equal to "Comparable"
The return value of its asType() method will be a (definitionally nameless) DeclaredType whose asElement() method will return the TypeElement currently being discussed
The DeclaredType so returned will have exactly one type argument which will be the (definitionally nameless) TypeVariable discussed above whose asElement() method will return the TypeParameterElement discussed above ("T")
The return value of its getTypeParameters() method will consist solely of the TypeParameterElement discussed earlier.
a TypeElement whose affiliated Name is equal to "Frob".
(This TypeElement is brought into being with the Java syntax public class Frob ....)
The return value of its asType() method will be a (definitionally nameless) DeclaredType whose asElement() method will return the TypeElement currently being discussed.
The return value of its getInterfaces() method will be discussed in a moment.
an Element of some variety loosely described by "Comparable<Frob>".
I say "of some variety" because as written it itself does not have, say, an explicit or implicit extends or implements clause, or other markers I would expect to see of, say, a TypeElement. Nevertheless I'm not sure that it could be any other kind of Element other than a TypeElement. Maybe it is a TypeElement equal to that denoted by "Comparable<T>", but with its various TypeMirror-returning or -referencing methods using the type denoted by Frob?
The return value of its asType() method will be a (definitionally nameless) TypeMirror of some variety (almost certainly a DeclaredType) whose asElement() method will return the Element currently being discussed (this corresponds somewhat to java.lang.reflect.ParameterizedType in the runtime/reflection model)
The TypeMirror so returned will have exactly one type argument which will be the (definitionally nameless) DeclaredType returned by the asType() method of the TypeElement whose Name is equal to "Frob" described above
The TypeMirror so returned will be the sole member of the return value of the getInterfaces() method when invoked on the TypeElement whose Name is equal to "Frob" described above
Do I have this right as far as it goes?

Your question seems well-reasoned, and I can't find anything specifically wrong with it to point out to you, but it is missing the one vital truth of where Elements and TypeMirrors differ.
Elements represent nodes in the Java type AST that reside "on disk" - the code at rest, either in .java or .class files. Any class/interface/enum/record/annotation that exists on disk in this form is in some way discoverable by this. To get a bit further, these cover the entire API of any of those types above - any members (fields/constructors/methods or nested types, then also the params of those methods/ctors) and packages too are described by elements. But the Element hierarchy only covers the types on disk - to use a concrete example from your question, Comparable<T> and its Comparable<T>.compareTo(T) member, and that method's parameter are covered in this way. And yes, lest I omit the type parameter, both the class and the method have a type param embedded in their respective element - as an element.
On the other hand, TypeMirrors represent those elements "in use" - you can't really reason about Comparable<T> in your code, but instead will either use it raw (please don't), or will parameterize it in some specific way (such as Comparable<Frob>, Comparable<?>, or possibly Comparable<T> where T is the type param of an enclosing element such as the current method or class). This means that T is not the same TypeElement as above - it isn't the value of the TypeElement that was on disk, but is something more specific.
You'll find TypeMirrors in Elements (for example "what is the return type of the method that appears in this class?"), and all Elements can be converted to some form of TypeMirror. On the other hand, not all TypeMirrors can be converted to some Element (such as a primitive), or if they can, that conversion may be "lossy" (for example converting a TypeMirror of List<String> to an Element would give you only List<T> itself).

Related

Should I mark all method parameters as final and specify type

Effective dart specifies that top-level variables should be final when applicable:
https://dart-lang.github.io/linter/lints/prefer_final_fields.html
However, I could not find any information about method parameters.
Flutter repo's code functions are mostly ones with parameters not marked final, that includes all the overridden build methods I've seen.
Which of the following is better in terms of performance and app weight:
#override build(context)
#override build(BuildContext context)
#override build(final BuildContext context)
Perhaps overridden functions should be defined the same way as the super function? Is there any difference between overridden functions like build above which can infer the type, and other named/unnamed functions (other than not setting the type makes the variable dynamic), which Flutter repo also writes this way:
static double _flingDistancePenetration(double t) { // t is not final, although treated as immutable
return (1.2 * t * t * t) - (3.27 * t * t) + (_initialVelocityPenetration * t);
}
I've seen this question about Java: Why would one mark local variables and method parameters as "final" in Java?, and, while I agree with the top answer, I'm completely in the dark about why does Flutter repo not do that.
Regarding parameter types: yes, always include them. Otherwise your parameter is likely to be dynamic1, which incurs runtime overhead and no type safety. You also want your API to clearly specify what argument types it expects.
Regarding final: That is an opinion-based question, and my opinion is that while I agree with the prefer_final_fields lint, I disagree with the prefer_final_locals lint. I think that adding final for local variables (including function/method parameters) is pointless.
Contrary to what the top-voted answer to the related Java question says, any half-decent compiler should be able to easily determine whether a local variable is reassigned. If there's any optimization opportunity there, the compiler should be able to do it for you.
In languages such as Dart where implementation usually is inline with the interface (as opposed to languages such as C or C++, which have separate header files to declare interfaces), adding final to parameters is visual noise. It provides no useful information to callers.
You shouldn't unilaterally mark all function/method parameters as final anyway. Sometimes reassigning parameters is appropriate. For example, if your function needs to perform some sort of normalization on its arguments:
void foo(File file) {
file = file.absolute;
...
}
in such a case, using a final File file would mean you'd need a separate local variable for the normalized version, and now the code would be error-prone since it could accidentally use the original variable.
final for a field is an important part of an API. It tells callers that the field will not be reassigned; the object referred to by the field will always be the same object. final for local variables and for function/method parameters affects only the person implementing the function. If the implementor doesn't want to reassign a variable, they can choose to simply not reassign it.
Some people will claim that having final local variables helps code readability since they know that the variable will not be reassigned. However, I instead think that final can be misleading since it says only that a variable cannot be reassigned, not that it won't be mutated, and knowing the latter is much more important.
1 For overridden methods, parameter types are constrained by the corresponding parameter types declared by the base class. Therefore omitting a parameter type in an overridden method will use the parameter type from the base class.
Answer to the author of the question.
You should not mark all method parameters as final
You should specify the type
Examples:
foo(Baz baz)
void main(List<String> args)
An exception to these rules.
You can omit the type indication if the type is dynamic
You can don't specify type if the type can be inferred automatically by the compiler, in the case of using an function-expression.
foo(Baz baz, bar)
list.sort((x, y) => x.compareTo(y))
Some useful information:
From Dart specification:
Dart Programming Language Specification
5th edition draft
Version 2.2
A final variable is a variable whose binding is fixed upon initialization; a final variable v will always refer to the same object after v has been initialized. A variable is final iff its declaration includes the modifier final or the modifier const. A mutable variable is a variable which is not final.
Variable immutability does not make an object immutable in Dart.
This is a very common misconception when variable immutability is confused with object immutability.
P.S.
A common misconception is that Dart users get the impression that function parameters in Dart are passed by reference.
This is not true.
Parameters are passed by value (not by reference).
But due to the fact that (as indicated in the specification) any variable already contains a reference (refers) to the object (but not the object itself), in fact, this reference is passed, by value (as normal value).
That is, a value is passed, but the value itself is of the Referernce type, which is indicated in the language specification.
From Dart specification:
a final variable v will always refer to the same object
That is, the variable stores the reference, but not the value itself.
It is this reference that is passed by value, because there is no reason to pass this reference by reference.

Element vs. Generic Type <T>

I wonder why Swift uses Element rather than Generic <T> in the following example.
What is the difference between Element vs T
From Generics:
Type Parameters
Type parameters specify and name a placeholder type, and are written immediately after the function’s name, between a pair of matching angle brackets (such as <T>).
Naming Type Parameters
In most cases, type parameters have descriptive names, such as Key and Value in Dictionary<Key, Value> and Element in Array<Element>, which tells the reader about the relationship between the type parameter and the generic type or function it’s used in. However, when there isn’t a meaningful relationship between them, it’s traditional to name them using single letters such as T, U, and V, such as T in the swapTwoValues(_:_:) function above.
So
func createArray<Element>(element: Element) -> [Element] { ... }
func createArray<T>(element: T) -> [T] { ... }
func createArray<Rumpelstilzchen>(element: Rumpelstilzchen) -> [Rumpelstilzchen] { ... }
are identical functions. Here the placeholder type is the element type of the returned array, therefore Element is a suitable “descriptive name.”
But it makes no difference otherwise, is it up to you to choose a name for the placeholder, balancing between readability and conciseness.
T is not particularly traditional. In FP, Backus uses T, but ML, from around the same time, uses a. Haskell uses a, Scala uses A. There's a mix of choices.
Swift, however, has strong reasons to use descriptive names. First, it's a quite descriptive language. Types are named with fully spelled-out words. Methods typically are literate in construction. Variables and properties are rarely abbreviated. There's no reason that type parameters should be uniquely obscure.
It also matches well with associated types which are quite naturally verbose. What would you call Collection's index type besides Index? Why should its "element" type be specially abbreviated? And if Array implements Collection, why should it create a distinct name (T) that it would then have to associate with Collection's Element? Why would you special-case all this just to make the type name unintuitive?
The deeper question would be, why wouldn't Array's element be called Element?

How do I subtract an RDD[(Key,Object)] from another one?

I want to change the format of my data, from RDD(Label:String,(ID:String,Data:Array[Double])) to an RDD Object with the label, id and data as components.
But when I print my RDD consecutively twice, the references of objects change :
class Data_Object(private val id:String, private var vector:Vector) extends Serializable {
var label = ""
...
}
First print
(1,ms3.Data_Object#35062c11)
(2,ms3.Data_Object#25789aa9)
Second print
(2,ms3.Data_Object#6bf5d886)
(1,ms3.Data_Object#a4eb65)
I think that explains why the subtract method doesn't work. So can I use subtract with objects as values, or do I return to my classic model ?
Unless you specify otherwise, objects in Scala (and Java) are compared using reference equality (i.e. their memory address). They are also printed out according to this address, hence the Data_Object#6bf5d886 and so on.
Using reference equality means that two Data_Object instances with identical properties will NOT compare as equal unless they are exactly the same object. Also, their references will change from one run to the next.
Particularly in a distributed system like Spark, this is no good - we need to be able to tell whether two objects in two different JVMs are the same or not, according to their properties. Until this is fixed, RDD operations like subtract will not give the results you expect.
Fortunately, this is usually easy to fix in Scala/Spark - define your class as a case class. This automatically generates equals and hashcode and toString methods derived from all of the properties of the class. For example:
case class Data_Object(id:String, label:String, vector:Vector)
If you want to compare your objects according to only some of the properties, you'll have to define your own equals and hashcode methods, though. See Programming in Scala, for example.

Is IEnumerable<object> the proper container for generic data sets?

Using Entity Framework, is IEnumerable the correct container to use to send back a generic data set? I.e. when I do not want to send back a list of the object, but just a generic a result set.
public IEnumerable<object> SelectPlayerFirstAndLastNameList()
{
return (from p in rlpEntities.Players select new { p.PlayerFirstName, p.PlayerLastName });
}
Thanks.
Here is the reference article, which talks about IList(inherits ICollection( and IEnumerable(Base Generic Interface for IQueryable,ICollection,List).
Here are the links which states generics & it's differences & it's usages,
Difference among IEnumerable , IQueryable, ICollection,IList, List
IEnumerable vs. ICollection vs. IQueryable vs. IList
Looking at your linq, it's about specific object & can be extended further in future. IQueryable is right fit for such scenario, as it gives client to iterate/add/remove items.
Check this link out Why use ICollection and not IEnumerable or List<T> on many-many/one-many relationships?.
It really depends on your scenario, but IEnumerable<> would be used when you need to iterate, and List<> when you need to iterate and modify or sort the data.
IEnunerable<> - http://msdn.microsoft.com/en-us/library/system.collections.ienumerable.aspx
List<> - http://msdn.microsoft.com/en-us/library/6sh2ey19.aspx
You can also use generics, to pass on whatever types you are querying against, like for instance
public IEnumerable<T> SelectPlayerFirstAndLastNameList<T>()
{
return (IEnumerable<T>)(from p in rlpEntities.Players);
}
So you can pass either object, or a known defined type. To call this you would do
var x = SelectPlayerFirstAndLastNameList<YourClassHere>();
I think what you have is correct but decide for yourself whether you should use it.
From MSDN: Anonymous Types in the Remarks section:
Anonymous types are class types that derive directly from object, and
that cannot be cast to any type except object.
and
To pass an anonymous type, or a collection that contains anonymous
types, as an argument to a method, you can declare the parameter as
type object. However, doing this defeats the purpose of strong typing.
If you must store query results or pass them outside the method
boundary, consider using an ordinary named struct or class instead of
an anonymous type.

What is exactly the point of auto-generating getters/setters for object fields in Scala?

As we know, Scala generates getters and setters automatically for any public field and make the actual field variable private. Why is it better than just making the field public ?
For one this allows swapping a public var/val with a (couple of) def(s) and still maintain binary compatibility. Secondly it allows overriding a var/val in derived classes.
First, keeping the field public allows a client to read and write the field. Since it's beneficial to have immutable objects, I'd recommend to make the field read only (which you can achieve in Scala by declaring it as "val" rather than "var").
Now back to your actual question. Scala allows you to define your own setters and getters if you need more than the trivial versions. This is useful to maintain invariants. For setters you might want to check the value the field is set to. If you keep the field itself public, you have no chance to do so.
This is also useful for fields declared as "val". Assume you have a field of type Array[X] to represent the internal state of your class. A client could now get a reference to this array and modify it--again you have no chance to ensure the invariant is maintained. But since you can define your own getter you can return a copy of the actual array.
The same argument applies when you make a field of a reference type "final public" in Java--clients can't reset the reference but still modify the object the reference points to.
On a related note: accessing a field via getters in Scala looks like accessing the field directly. The nice thing about this is that it allows to make accessing a field and calling a method without parameters on the object look like the same thing. So if you decide you don't want to store a value in a field anymore but calculate it on the fly, the client does not have to care because it looks like the same thing to him--this is known as the Uniform Access Principle
In short: the Uniform Access Principle.
You can use a val to implement an abstract method from a superclass. Imagine the following definition from some imaginary graphics package:
abstract class circle {
def bounds: Rectangle
def centre: Point
def radius: Double
}
There are two possible subclasses, one where the circle is defined in terms of a bounding box, and one where it's defined in terms of the centre and radius. Thanks to the UAP, details of the implementation can be completely abstracted away, and easily changed.
There's also a third possibility: lazy vals. These would be very useful to avoid recalculating the bounds of our circle again and again, but it's hard to imagine how lazy vals could be implemented without the uniform access principle.