According to the Kotlin docs on destructuring declarations, the declared components should match the number of components on the right side:
Anything can be on the right-hand side of a destructuring declaration, as long as the required number of component functions can be called on it.
However, I discovered that this works even if the left hand side doesn't have the same number of components as on the right side of the assignment statement.
fun main() {
val (firstOnly) = Pair("key", "value")
println("firstOnly=${firstOnly}")
}
Is this legal Kotlin or is this is a bug? If it's legal, is there a reference?
If it's legal, is there a reference?
The Kotlin Language Specification says:
A special case of definition by convention is the destructuring declaration of properties [...]
This convention allows to introduce a number (one or more) of properties in the place of one by immediately destructuring the property during construction.
It says "one or more", so yes, declaring a single property by destructuring is allowed.
Also note that "required number of component functions can be called on it" doesn't mean the number of component functions has to equal to number of properties being declared. Let's put it this way: if I have 2 apples, and 1 apple is required. Do I have the "required number of apples"? Clearly the answer is yes.
If you still find it unclear, I think the spec says it better:
For each identifier the corresponding operator function componentK with
K being equal to the position of the placeholder in the declaration (starting from 1) is called without arguments.
which implies that those functions calls need to be valid. Whether or not other component functions exist is not relevant.
From the document you linked to:
Anything can be on the right-hand side of a destructuring declaration, as long as the required number of component functions can be called on it.
It doesn't say it has to match the number of variables declared on the left, only that it has the required number.
In fact, this is very useful when destructuring a List:
val (first, second) = listOf(1, 2, 3, 4, 5)
The documentation for List<T>.component1():
Throws an IndexOutOfBoundsException if the size of this list is less than 1.
Again, it doesn't restrict the list to being of size 1.
Related
So I'm trying to define a method like this
fun <R,F> myFunction(prop: KProperty1<R, F>, value:F) {}
// so that the compiler only allows me to invoke it like
myFunction(User::name, "Alejandro")
// and stops developers from doing illegal things like
myFunction(User::name, 123)
//However, compiler doesn't complain if I do that... it widens the type to Any
How can I achieve that?
Kotlin is "widening" the type here because the value type parameter (i.e. the second type parameter) of KProperty1 is defined with keyword out which makes that parameter covariant.
This means that for instance KProperty1<User, String> is a subtype of KProperty1<User, Any>, and hence User::name which is presumably a KProperty1<User, String>, can also be seen as a special case of KProperty<User, Any>. Therefore, it is totally legal to call myFunction<User,Any>(User::name, 123).
The logic behind this can be derived from the name of the out keyword: It is expected that the typed parameter is only used in "out position" of any function call. In the case of KProperty1 this makes sense, because it is the type of the return value of the property. When you get a value from a KProperty1<K, V>, that value is of type V and thus it can be used anywhere where it is okay to have some supertype of V.
This should only be a problem, if you want to use the value in the "in position" of some function, for instance, if you want to write a function that takes a value of type V and store it in a KProperty1<K, V>.
If this is what you want, you are lucky, because you can and should just use KMutableProperty1<K,V> where the value parameter does not have an out keyword which means that it is invariant. Also, that interface allows you to put the value into the property.
Changing your function definition to
fun <R,F> myFunction(prop: KMutableProperty1<R, F>, value:F) {}
makes that the compiler allows myFunction(User::name, "Alejandro"), but it complains on myFunction(User::name, 123).
See also: Kotlin documentation on Variance
Sorry for the terrible title, but I can't seem to find an allowable way to ask this question, because I don't know how to refer to the code constructs I am looking at.
Looking at this file: https://github.com/Hexworks/caves-of-zircon-tutorial/blob/master/src/main/kotlin/org/hexworks/cavesofzircon/systems/InputReceiver.kt
I don't understand what is going on here:
override fun update(entity: GameEntity<out EntityType>, context: GameContext): Boolean {
val (_, _, uiEvent, player) = context
I can understand some things.
We are overriding the update function, which is defined in the Behavior class, which is a superclass of this class.
The update function accepts two parameters. A GameEntity named entity, and a GameContext called context.
The function returns a Boolean result.
However, I do not understand the next line at all. Just open and close parentheses, two underscores as the first two parameters, and then an assignment to the context argument. What is it we are assigning the value of context to?
Based on IDE behavior, apparently the open-close parentheses are related to the constructor for GameContext. But I would not know that otherwise. I also don't understand what the meaning is of the underscores in the argument list.
And finally, I have read about the declaration-site variance keyword "out", but I don't really understand what it means here. We have GameEntity<out EntityType>. So as I understand it, that means this method produces EntityType, but does not consume it. How is that demonstrated in this code?
val (_, _, uiEvent, player) = context
You are extracting the 3rd and 4th value from the context and ignoring the first two.
Compare https://kotlinlang.org/docs/reference/multi-declarations.html .
About out: i don't see it being used in the code snippet you're showing. You might want to show the full method.
Also, maybe it is there only for the purpose of overriding the method, to match the signature of the function.
To cover the little bit that Incubbus's otherwise-great answer missed:
In the declaration
override fun update(entity: GameEntity<out EntityType>, // …
the out means that you could call the function and pass a GameEntity<SubclassOfEntityType> (or even a SubclassOfGameEntity<SubclassOfEntityType>).
With no out, you'd have to pass a GameEntity<EntityType> (or a SubclassOfGameEntity<EntityType>).
I guess that's inherited from the superclass method that you're overriding. After all, if the superclass method could be called with a GameEntity<SubclassOfEntityType>, then your override will need to handle that too. (The Liskov substitution principle in action!)
In this simple code example...
fun testLocalFunctions() {
aLocalFun() //compiler error: unresolved reference at aLocalFun
fun aLocalFun() {}
aLocalFun() //no error
}
Elsewhere in the language, using a function before definition is allowed. But for local functions, that does not appear to be the case. Refering to the Kotlin Language Specification, the section on Local Functions is still marked "TODO".
Since this sort of constraint does not hold for other types of functions (top-level and member functions), is this a bug?
(Granted, local variable declarations must occur before use, so the same constraint on local functions is not unreasonable. Is there a definitive, preferably authoritative source document that discusses this behavior?)
It's not a bug, it is the designed behavior.
When you use a symbol (variable, type or function name) in an expression, the symbol is resolved against some scope. If we simplify the scheme, the scope is formed by the package, the imports, the outer declarations (e.g. other members of the type) and, if the expression is placed inside a function, the scope also includes the local declarations that precede the expression.
So, you can't use a local function until it's declared just like you cannot use a local variable that is not declared up to that point: it's just out of scope.
I am trying to design a data structure composed of objects which contain, as instance variables, objects of another type.
I'd like to be able to do something like this:
CALL type1_object%get_nested_type2_object()%some_type2_method()
Notice I am trying to immediately use the getter, get_nested_type2_object() and then act on its return value to call a method in the returned type2 object.
As it stands, gfortran v4.8.2 does not accept this syntax and thinks get_nested_type2_object() is an array reference, not a function call. Is there any syntax that I can use to clarify this or does the standard not allow this?
To give a more concrete example, here is some code illustrating this:
furniture_class.F95:
MODULE furniture_class
IMPLICIT NONE
TYPE furniture_object
INTEGER :: length
INTEGER :: width
INTEGER :: height
CONTAINS
PROCEDURE :: get_length
END TYPE furniture_object
CONTAINS
FUNCTION get_length(self)
IMPLICIT NONE
CLASS(furniture_object) :: self
INTEGER :: get_length
get_length = self%length
END FUNCTION
END MODULE furniture_class
Now a room object may contain one or more furniture objects.
room_class.F95:
MODULE room_class
USE furniture_class
IMPLICIT NONE
TYPE :: room_object
CLASS(furniture_object), POINTER :: furniture
CONTAINS
PROCEDURE :: get_furniture
END TYPE room_object
CONTAINS
FUNCTION get_furniture(self)
USE furniture_class
IMPLICIT NONE
CLASS(room_object) :: self
CLASS(furniture_object), POINTER :: get_furniture
get_furniture => self%furniture
END FUNCTION get_furniture
END MODULE room_class
Finally, here is a program where I attempt to access the furniture object inside the room (but the compiler won't let me):
room_test.F95
PROGRAM room_test
USE room_class
USE furniture_class
IMPLICIT NONE
CLASS(room_object), POINTER :: room_pointer
CLASS(furniture_object), POINTER :: furniture_pointer
ALLOCATE(room_pointer)
ALLOCATE(furniture_pointer)
room_pointer%furniture => furniture_pointer
furniture_pointer%length = 10
! WRITE(*,*) 'The length of furniture in the room is', room_pointer%furniture%get_length() - This works.
WRITE(*,*) 'The length of furniture in the room is', room_pointer%get_furniture()%get_length() ! This line fails to compile
END PROGRAM room_test
I can of course directly access the furniture object if I don't use a getter to return the nested object, but this ruins the encapsulation and can become problematic in production code that is much more complex than what I show here.
Is what I am trying to do not supported by the Fortran standard or do I just need a more compliant compiler?
What you want to do is not supported by the syntax of the standard language.
(Variations on the general syntax (not necessarily this specific case) that might apply for "dereferencing" a function result could be ambiguous - consider things like substrings, whole array references, array sections, etc.)
Typically you [pointer] assign the result of the first function call to a [pointer] variable of the appropriate type, and then apply the binding for the second function to that variable.
Alternatively, if you want to apply an operation to a primary in an expression (such as a function reference) to give another value, then you could use an operator.
Some, perhaps rather subjective, comments:
Your room object doesn't really contain a furniture object - it holds a reference to a furniture object. Perhaps you use that reference in a manner that implies the parent object "containing" it, but that's not what the component definition naturally suggests.
(Use of a pointer component suggests that you want the room to point at (i.e. reference) some furniture. In terms of the language, the object referenced by a pointer component is not usually considered part of the value of the parent object of the component - consider how intrinsic assignment works, restrictions around modifying INTENT(IN) arguments, etc.
A non-pointer component suggests to me that the furniture is part of the room. In a Fortran language sense an object that is a non-pointer component it is always part of the value of the parent object of the component.
To highlight - pointer components in different rooms could potentially point at the same piece of furniture; a non-pointer furniture object is only ever directly part of one room.)
You need to be very careful using functions with pointer results. In the general case, is it:
p = some_ptr_function(args)
(and perhaps I accidentally leak memory) or
p => some_ptr_function(args)
Only one little character difference, both valid syntax, quite different semantics. If the second case is what is intended, then why not just pass the pointer back via a subroutine argument? An inconsequential difference in typing and it is much safer.
A general reminder applicable to some of the above - in the context of an expression, evaluation of a function reference yields a value. Values are not variables and hence you are not permitted to vary [modify] them.
In programming (and math) there are variables and constants. Is there a name to describe both of them?
I was thinking value, but that's not it. A value is what variables/constants contain, not what they are.
I would call it a symbol. From google:
sym·bol/ˈsimbəl/Noun
1. A thing that represents or stands for something else,
esp. a material object representing something abstract.
...
From what I know Its called a field
How about:
maths and logic: term
programming: l-value and r-value.
There are a few different terms I use, depending on context. I'll give you a list of the terms I (might) use - sometimes I'll just default to calling everything 'variables'.
Field - a variable or constant that's declared as part of the class definition.
Parameter - one of the inputs specified when defining a method in a class.
Argument - the actual value that you provide for a parameter when calling a method.
Method variable - a variable declared inside a method.
Method constant - a constant declared inside a method.
In OOP, the attribute can be both a variable and a constant.
Identifiers
In computer languages, identifiers are tokens (also called symbols) which name language entities. Some of the kinds of entities an identifier might denote include variables, types, labels, subroutines, and packages.
Symbols are super set of Identifiers
https://en.wikipedia.org/wiki/Identifier#In_computer_languages
How about "data item"?
One definition: https://www.yourdictionary.com/data-item
Example showing it can be used for local variables/constants as well (unlike "field" or "attribute"): https://www.microfocus.com/documentation/visual-cobol/VC222/EclWin/GUID-A3B817EE-1D63-4F67-A62C-61DE681C6719.html