I'm reading through the Swift documentation about type methods and type properties, and I cannot for the life of me figure out why it says this particular thing (in bold):
Within the body of a type method, the implicit self property refers to
the type itself, rather than an instance of that type. For
structures and enumerations, this means that you can use self to
disambiguate between type properties and type method parameters, just
as you do for instance properties and instance method parameters.
More generally, any unqualified method and property names that you use
within the body of a type method will refer to other type-level
methods and properties. A type method can call another type method
with the other method’s name, without needing to prefix it with the
type name. Similarly, type methods on structures and enumerations
can access type properties by using the type property’s name without a
type name prefix.
So, why is this pointing out structures and enumerations being able to do these things when, as far as I know, you can do these things with any kind of type methods/parameters (i.e. classes as well)? It makes me think I'm missing something.
The page in the documentation I'm looking at is here: https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Methods.html
Apparently I wasn't the only one with this question. I'm not sure how I didn't see this post before: https://softwareengineering.stackexchange.com/questions/276962/static-properties-and-implicit-self-property-in-structures-and-enumerations-vs
Related
In Swift we are able to write following construction:
class SomeClass {}
let metaMetatype: SomeClass.Type.Type = SomeClass.Type.self
Here metaMetatype does not conform to type AnyObject (SomeClass.Type does). Construction can be even longer, as long as we wish:
let uberMetatype: SomeClass.Type.Type.Type.Type.Type.Type.Type.Type.Type.Type = SomeClass.Type.Type.Type.Type.Type.Type.Type.Type.Type.self
Are this constructions have any sense? If SomeClass.Type.Type not an object, what is this, and why we able to declare it?
If SomeClass.Type.Type not an object, what is this and why we able to declare it?
I will try to dissect what you're asking.
SomeClass.Type.Type is a Metatype of a Metatype. Metatypes exist in Swift because Swift has types that are not classes. This is most similar to the Metaclass concept in Objective-C.
Lexicon.rst in the Swift Open Source Repo has a pretty good explanation:
metatype
The type of a value representing a type. Greg Parker has a good
explanation of Objective-C's "metaclasses" because Swift has types
that are not classes, a more general term is used.
We also sometimes refer to a value representing a type as a "metatype
object" or just "metatype", usually within low-level contexts like IRGen
and LLDB. This is technically incorrect (it's just a "type object"), but
the malapropism happened early in the project and has stuck around.
Why are we able to declare a type of a type of a type... and so on? Because it's a feature of the language called type metadata:
type metadata
The runtime representation of a type, and everything you can do with it.
Like a Class in Objective-C, but for any type.
Note that you can't do something like NSObject().class in Swift because class is a reserved keyword for the creation of a class. This is how you would get the type (or class in this case) of an NSObject in Swift:
let nsObj = NSObject()
nsObj.classForCoder // NSObject.Type
nsObj.classForKeyedArchiver // NSObject.Type
nsObj.dynamicType // NSObject.Type
Note that nsObj and nsObj.self are identical and represent the instance of that NSObject.
I don't see where in the Swift module or open source repo where types allow for .Type, but I'm still looking. It might have to do with the inheritance from SwiftObject, the Objective-C object all Swift classes inherit from (at least on Mac).
Type of a class is also represented in memory (it has for example their own methods). It's represented by singleton representing the Type. (It's not an instance of this type - that's something different). If you call self on a Type like this SomeClass.self you will take singleton instance representing the SomeClass Type.
For more info check this answer
The Scala API lists something called Abstract Value Members under some classes and traits. What are these things and how do they differ from what the API lists as Concrete Values Members?
An abstract value has a name and a type but no value. This value has to be provided by a concrete val definition in a subclass. In contrast, concrete value members do have a name, type and value defined. It is as simple as that. Scala' abstraction mechanisms are more general than Java's.
I think it is covered in the link provided by #I.K. http://www.artima.com/pins1ed/abstract-members.html
Abstract Value Members are simple abstract members, i.e. members that don't have a value. Note that they are NOT necessarily vals but defs are included as well.
Is the answer to this :
Instantiation of the object uses 'val' instead of 'var'.
Each member variable of the object being created is also 'val' instead of 'var'. This is to prevent users updating an object value after its set.
An object is immutable if there is no way for the user of that object to mutate it. This means that it must have no public methods that reassign any of its member variables or mutate any objects referred to by those variables. If all the object's members are vals this ensures the former (i.e. they can't be reassigned), but not the latter (i.e. if the objects referred to by those variables are themselves mutable, they can still be mutated by calling mutating methods on them even if they're referred to only by vals).
Also note that even if the members are declared as vars, the object can still be immutable if none of the object's methods actually reassign the variables (or call mutating methods on them) - assuming of course, they're private.
So having only val members is neither necessary nor sufficient for an object being immutable. Whether the object is referred to by a val or a var (or both) makes no difference in that matter.
#sepp2k nicely and correctly explains the criteria for an object being technically immutable. One subtle point missing from his answer is that not all member variables correspond to externally visible state. A member may also be e.g. a cached internal value to store some local, hard to compute data which is not directly visible from outside (thus qualified as private[this] in Scala). An object can have such a var member e.g. to store a computed hash value. It can even be accessible via a public getter - as long as the behaviour of the accessor is purely functional, i.e. it always produces the same value for each invocation on the same object (except that it returns faster when reusing the internally cached value).
The Scala compiler is aware of this distinction so it can help one to implement an immutable class correctly, even when using mutable state internally. This is important when generic type variance comes into play. Namely, the compiler allows a generic type parameter to be covariant even if the class contains reassignable fields of this type - as long as these fields are private[this], ensuring that one cannot have a reference to a containing object that has a statically weaker type than the type the object was defined with (which would be a precondition for variance to cause type errors).
This is explained in more detail, with a code example, in section 19.7 of Programming in Scala.
This came up in another question (kindly answered by meronix) but I curious to learn a little more about what is going on here, is this a LLVM/Clang issue, or are the two statements different in someway.
I know I can fix this by adding (See below), so more curious than anything ...
The two statements are different. A property can only be used if the type of the lvalue declares the property. This is because the getter and setter for the property might be non-obvious (often the case with boolean properties, where the getter is explicitly set to isSomething.) The compiler cannot infer that without strong type info.
The [lvalue message] syntax, however, has no such ambiguity, so the compiler allows it. Since the type of the lvalue is id, any known message can be sent to it without a compiler warning. The compiler will only warn if two signatures correspond to the same selector (for instance, one class has - (UIWindow *)window and another has - (int)window.)
The UIApplicationDelegate protocol defines a window property, so when you explicitly type your object as id <UIApplicationDelegate>, the compiler knows about the property and can use it.
I'm very confused by Scala's HashSet and Set types as they both seem to do the same thing.
What is the difference between them?
Is it the same in Java?
In my reference it says that HashSet is an "explicit set class" (as compared to Set). What does that mean?
Scala's mutable and immutable HashSet implementations are concrete classes which you can instantiate. For example, if you explicitly ask for a new scala.collection.immutable.HashSet, you will always get a set which is implemented by a hash trie. There are other set implementations, such as ListSet, which uses a list.
Set is a trait which all the set implementations extend (whereas in Java, Set is an interface).
Set is also a companion object* with an apply** method. When you call Set(...), you're calling this factory method and getting a return value which is some kind of Set. It might be a HashSet, but could be some other implementation. According to 2, the default implementation for an immutable set has special representation for empty set and sets size up to 4. Immutable sets size 5 and above and mutable sets all use hashSet.
*In Scala, instead of having static class methods, you can create a singleton object with the same name as your class or trait. This is called a companion object, and methods you define on it can be called as ObjectName.method(), similar to how you'd call a static method in Java.
**Set(x) is syntactic sugar for Set.apply(x).