Cannot access nested type through typealias - kotlin

I have a Quantity/Units library in Kotlin which has classes like Weight, Distance, Force. These classes inherit from a Quantity class and each contain a nested enum class Unit with information about the respective units for each type of quantity.
As a kind of physical oddity, the consumption of an electric car (e.g. kWh/100km) is technically the same dimension as a force, so the Force.Unit class contains both NEWTON and KILOWATTHOUR_PER_100_KILOMETERS.
Of course, we use FuelConsumption for combustion cars and the quantity for electric cars should look similar, so I have created a typealias ElectricConsumption = Force.
For some reason, I can't access the inner class ElectricConsumption.Unit through that typealias. This is extremely inconvenient. Is this by design? Why? Is there a workaround?
class A {
enum class B { X }
}
typealias AA = A
fun main() {
print(A.B.X) // prints X
print(AA.B.X) // Unresolved reference: B
}
https://pl.kotl.in/wTuDs3Hgh

Given that the Kotlin Language Specification says "Type alias introduces an alternative name for the specified type", you would reasonably expect to be able to use the typealias name wherever you can use the original type name. This is not the case in your example, and I suspect that this is a bug (KT-34281) as it obviously doesn't conform to the official description of typealias.
You might be able to work around this issue by using import as instead of typealias:
import A as AA
class A {
enum class B { X }
}
fun main() {
print(A.B.X)
print(AA.B.X)
}
See it working at https://pl.kotl.in/1JUSVZtCL

Related

Generic variance type parameter(Kotlin)

I do not fully understand how variance in Generics work. In the code below the classes are as follows Any -> Mammals -> Cats. Any is the supertype, there is a parameter called from in the copy function
From what I understand about the out and in keywords, out allows reference to any of it's subtype, can only be produced not consumed.
in allows reference to any of it's supertype, can only be consumed not produced.
However in the copytest function we are instantiating the function copy. I gave it a catlist1 argument in the from parameter. Since the parameter has an out keyword wouldn't it mean that we can only input parameters that are a subtype of catlist2?
To top of my confusion I have seen many conflicting definitions, for instance , In Kotlin, we can use the out keyword on the generic type which means we can assign this reference to any of its supertypes.
Now I am really confused could anybody guide me on how all of these works? Preferably from scratch, thanks!
class list2<ITEM>{
val data = mutableListOf<ITEM>()
fun get(n:Int):ITEM = data[n]
fun add(Item:ITEM){data.add(Item)}
}
fun <T> Copy(from: list2<out T>, to:list2<T>){
}
fun copytest(){
val catlist1 = list2<Cat>()
val catlist2 = list2<Cat>()
val mammallist = list2<Mammal>()
Copy(catlist1,mammallist)
}
I think maybe you're mixing up class-declaration-site generics and use-site generics.
Class-declaration-site generics
Defined at the class declaration site with covariant out, it is true you cannot use the generic type as the type of a function parameter for any functions in the class.
class MyList<out T>(
private val items: Array<T>
) {
fun pullRandomItem(): T { // allowed
return items.random()
}
fun addItem(item: T) { // Not allowed by compiler!
// ...
}
}
// Reason:
val cowList = MyList<Cow>(arrayOf(Cow()))
// The declaration site out covariance allows us to up-cast to a more general type.
// It makes logical sense, any cow you pull out of the original list qualifies as an animal.
val animalList: MyList<Animal> = cowList
// If it let us put an item in, though:
animalList.addItem(Horse())
// Now there's a horse in the cow list. That doesn't make logical sense
cowList.pullRandomItem() // Might return a Horse, impossible!
It is not logical to say, "I'm going to put a horse in a list that may have the requirement that all items retrieved from it must be cows."
Use-site generics
This has nothing to do with the class level restriction. It's only describing what kind of input the function gets. It is perfectly logical to say, "my function does something with a container that I'm going to pull something out of".
// Given a class with no declaration-site covariance of contravariance:
class Bag<T: Any>(var contents: T?)
// This function will take any bag of food as a parameter. Inside the function, it will
// only get things out of the bag. It won't put things in it. This makes it possible
// to pass a Bag of Chips or a Bag of Pretzels
fun eatBagContents(bagOfAnything: Bag<out Food>) {
eat(bagOfAnything.contents) // we know the contents are food so this is OK
bagOfAnything.contents = myChips // Not allowed! we don't know what kind of stuff
// this bag is permitted to contain
}
// If we didn't define the function with "out"
fun eatBagContentsAndPutInSomething(bagOfAnything: Bag<Food>) {
eat(bagOfAnything.contents) // this is fine, we know it's food
bagOfAnything.contents = myChips // this is fine, the bag can hold any kind of Food
}
// but now you cannot do this
val myBagOfPretzels: Bag<Pretzels> = Bag(somePretzels)
eatBagContentsAndPutInSomething(myBagOfPretzels) // Not allowed! This function would
// try to put chips in this pretzels-only bag.
Combining both
What could be confusing to you is if you saw an example that combines both of the above. You can have a class where T is a declaration site type, but the class has functions where there are input parameters where T is part of the definition of what parameters the function can take. For example:
abstract class ComplicatedCopier<T> {
abstract fun createCopy(item: T): T
fun createCopiesFromBagToAnother(copyFrom: Bag<out T>, copyTo: Bag<in T>) {
val originalItem = copyFrom.contents
val copiedItem = createCopy(originalItem)
copyTo.contents = copiedItem
}
}
This logically makes sense since the class generic type has no variance restriction at the declaration site. This function has one bag that it's allowed to take items out of, and one bag that it's allowed to put items into. These in and out keywords make it more permissive of what types of bags you can pass to it, but it limits what you're allowed to do with each of those bags inside the function.

Extend calculator with complex and rational module(using dynamic binding)

I already made calculator that can compute with integers and real numbers(i made it with go).
Then I want to make it possible to calculate complex and rational numbers by adding those modules.
(it can also calculate when types are mixed)
It can be easy if I check types of operands every time(runtime) and take care of each case, but I want to solve it with dynamic binding. Guys can you tell me the idea of how to solve this problem
I think by dynamic typing, you're probably referring to how in eg C++ and Java, dynamic binding is essentially having reference to a base class that can point to a derived class (because the derived class "is a" base class).
One might say that the base class defines the interface behind which derived classes morph. If the derived classes replace methods of the base class, a reference to the base class can still access those methods in the derived class.
Base class can define some methods to provide some "base" functionality to its derived classes. If those classes don't redefine the method, the base class's method can be called.
In go, both these concepts exist, but they're quite different.
Go has an explicit interface keyword that defines method signatures but no methods. Any value implicitly satisfies that interface if it has methods of the same name with the same signature.
type LivingBeing interface {
TakeInEnergy()
ExpelWaste()
}
The interface type becomes a valid type in the code. We can pass an interface to a function, and without knowing the type satisfying that interface, can call its methods:
func DoLife(being LivingBeing) {
being.TakeInEnergy()
being.ExpelWaste()
}
This is valid code, but not complete code. Unlike with base classes in other languages, interfaces cannot define functions, only their signatures. It is purely and only an interface definition. We have to define the types that satisfy the interface separately from the interface itself.
type Organism struct{}
func (o *Organism) TakeInEnergy() {}
func (o *Organism) ExpelWaste() {}
We now have a type organism that satisfies LivingBeing. It is something like a base class, but if we wanted to build on it, we can't use subclassing because Go doesn't implement it. But Go does provide something similar called embedding types.
In this example I'll define a new organism, Animal, that draws ExpelWaste() from LivingBeing, but defines its own TakeInEnergy():
type Animal struct {
Organism // the syntax for an embedded type: type but no field name
}
func (a *Animal) TakeInEnergy() {
fmt.Printf("I am an animal")
}
What isn't obvious from that code is that because Animal's Organism is not a named field, its fields and methods are accessible directly from Animal. It's almost as if Animal "is an" organism.
However it is *not * an organism. It is a different type, and it would be more accurate to think of object embedding as syntactic sugar to automatically promote Organism's fields and methods to Animal.
Since go is statically and explicitly typed, DoLife cannot take an Organism and then be passed an Animal: it doesn't have the same type:
/* This does not work. Animal embeds organism, but *is not* an organism */
func DoLife(being *Organism) {
being.TakeInEnergy()
being.ExpelWaste()
}
func main() {
var a = &Animal{Organism{}}
DoLife(&Animal{})
}
cannot use &Animal{} (type *Animal) as type *Organism in argument to DoLife
That's why interface exists - so that both Organism and Animal (and indeed, even Plant or ChemotrophBacteria) can be passed as a LivingBeing.
Putting it all together, here's the code I've been working from:
package main
import "fmt"
type LivingBeing interface {
TakeInEnergy()
ExpelWaste()
}
type Organism struct{}
func (o *Organism) TakeInEnergy() {
}
func (o *Organism) ExpelWaste() {}
type Animal struct {
Organism
}
func DoLife(being LivingBeing) {
being.TakeInEnergy()
being.ExpelWaste()
}
func (a *Animal) TakeInEnergy() {
fmt.Printf("I am an animal")
}
func main() {
var a = &Animal{Organism{}}
DoLife(a)
}
There are a few caveats:
Syntactically, If you want to declare an embedded literal you must explicitly provide its type. In my example Organism has no fields so there's nothing to declare, but I still left the explicit type in there to point you in the right direction.
DoLife can call the right TakeInEnergy on a LivingBeing, but Organism's methods cannot. They see only the embedded Organism.
func (o *Organism) ExpelWaste() {
o.getWaste() //this will always be Organism's getWaste, never Animal's
}
func (o *Organism)getWaste() {}
func (a *Animal)getWaste() {
fmt.Println("Animal waste")
}
Simlarly if you pass only the embedded part, then it's going to call its own TakeInEnergy(), not that of Animal; there's no Animal left!
func main() {
var a = &Animal{Organism{}}
DoLife(&a.Organism)
}
In summary,
Define explict interface and use that type wherever you want "polymorphic" behavior
Define base types and embed them in other types to share base functionality.
Don't expect the "base" type to ever "bind" to functions from the "derived" type.

How do I define and instantiate a single instance of an anonymous inner class in a single expression

In Kotlin, I want to add a "namespace" to a class that has a set of related functions. Clients of my class will use that namespace to help classify what type of operation they want to do. (I know you're thinking the functions should be in different classes, problem solved. But for other reasons, it's convenient to house all the functions in a single class).
So, I might have a class Uber that contains fooInsert fooOpen fooDispose along with barInsert barTerminate and barHop. As you can see there's no common interface. Just a bunch of functions that for some reason belong in the same class. Some have an affinity with others (i.e. the fooXXX functions "belong" together, as do the "barYYY" functions).
What I've come up with is:
class Uber {
inner class FooNamespace {
fun insert(): Unit {}
fun open(): Unit {}
fun dispose(): Unit {}
}
val foo = FooNamespace()
inner class BarNamespace {
fun insert(): Unit {}
fun terminate(): Unit {}
fun hop(): Unit {}
}
val bar = BarNamespace()
}
Users of the class can do something like this:
val uber = Uber()
uber.foo.insert()
uber.bar.hop()
What I'd like is something that combines the inner class ... and val xxx = XxxNamespace() into one expression. Something like:
// This doesn't actually compile
val foo = object: inner class {
fun insert(): Unit {}
fun open(): Unit {}
fun dispose(): Unit {}
}
The problem here is that you need a properly defined type if you to want to access these members publicly.
For private properties, the syntax val foo = object { ... } is sufficient, but for publicly exposed properties these are inferred as Any and it makes them unusable.
One option is obviously to define an interface for these types, but it's even more boilerplate than what you came up with already, so I am pretty sure this won't suit your needs:
interface FooNamespace {
fun insert()
fun open()
fun dispose()
}
class Uber {
val foo = object : FooNamespace {
override fun insert(): Unit {}
override fun open(): Unit {}
override fun dispose(): Unit {}
}
}
I know you're thinking the functions should be in different classes, problem solved. But for other reasons, it's convenient to house all of the functions in a single class
I'm indeed really thinking that, and would love to hear more about what makes it so convenient to put everything in the same class :) Since the classes are inner classes, I'm assuming this has to do with accessing private state from Uber, but that could also be done by wrapping this private state into another class that's passed to foo and bar.
I believe this is not possible, at least for now.
The main technical problem here is that uber.foo.insert() is really interpreted as chaining uber.foo and then .insert(). So for this to work, uber.foo needs to have an explicitly defined type. It can't be anonymous class/object, because then there is no way to describe what is the type of uber.foo.
That being said, I've always wondered why Kotlin does not support this syntax:
val foo = object Foo {}
This is consistent with the object declaration where the name of the singleton is at the same time the name of the class. And the compiler even understands this above syntax, because it throws the error: "An object expression cannot bind a name". So Kotlin authors seem to intentionally disallow such use.
I found an issue in the YouTrack, so we can at least upvote it: https://youtrack.jetbrains.com/issue/KT-21329

Kotlin: Omitting enum name when its unambiguous

With Swift enums you can omit the name of the enum in cases where only a value of that type can be used.
So when given the enum (Swift/Kotlin)
enum (class) CompassPoint {
case north
case south
case east
case west
}
Swift only needs the enums name when creating a new variable:
// type unclear, enum name needed
var directionToHead = CompassPoint.west
// type clear, enum name can be dropped
directionToHead = .east
// type clear, enum name can be dropped
switch directionToHead {
case .north:
print("Lots of planets have a north")
case .south:
print("Watch out for penguins")
case .east:
print("Where the sun rises")
case .west:
print("Where the skies are blue")
}
While in Kotlin, for the same situation you'd have to write
// type unclear, enum name needed
var directionToHead = CompassPoint.west
// type clear, enum name still needed
directionToHead = CompassPoint.east
// each case needs the enum name
when(directionToHead) {
CompassPoint.north -> println("Lots of planets have a north")
CompassPoint.south -> println("Watch out for penguins")
CompassPoint.east -> println("Where the sun rises")
CompassPoint.west -> println("Where the skies are blue")
}
Is there a reason for this, and/or are there situations in Kotlin where just .north or north can be used?
Edit: It seems importing the enum 'fixes' this and is necessary even when the enum is defined in the same file as it is used.
While this helped practically, I still don't understand why the import is needed.
Just use import, so you can use enum values without enum name
import CompassPoint.*
Edit: It seems importing the enum 'fixes' this and is necessary even when the enum is defined in the same file as it is used.
While this helped practically, I still don't understand why the import is needed.
Simply because it isn't treated specially. import CompassPoint.* lets you write just <name> for anything you'd write as CompassPoint.<name> without it (if the name doesn't conflict with anything). If you happen to be in the file where CompassName is defined, it works exactly the same.
You can refer to the values as north etc. without imports inside the enum definition, exactly like you can refer to an object's members inside this object:
object Obj {
val v = 0
val v1 = v
}
val v2 = Obj.v
or
import Obj.* // or import Obj.v
val v2 = v
FWIW, the Kotlin team is considering implementing unqualified enum constants when the enum type is unambiguous.
They're currently doing a feature survey to gather feedback, and unqualified enum constants are on there too.

Approaches to testing that a method is not available on a type

Given a type hierarchy for a game which strongly distinguishes whose turn is next:
trait Game
trait BlackToPlay extends Game {
def move(p: BlackPiece, s: Square): Either[FinishedGame, WhiteToPlay]
}
trait WhiteToPlay extends Game {
def move(p: WhitePiece, s: Square): Either[FinishedGame, BlackToPlay]
}
Can I make the following, important assertion without resorting to reflection?
"A game with white to play" should {
"not allow black to play" in {
// an instance of whiteToPlay should not
// have the `move(BlackPiece, Square)` method.
}
}
EDIT: My attempt to implement #Martin's solution doesn't work. Any thoughts on what's wrong here? From the REPL:
scala> class B() {
| def b(s: String) = s
| }
defined class B
scala> val b = new B()
b: B = B#420e44
scala> b.c("")
<console>:8: error: value c is not a member of B
b.c("")
^
scala> b match {
| case _: { def c(s: String) } => false
| case _ => true
| }
warning: there were unchecked warnings; re-run with -unchecked for details
res7: Boolean = false
res7 should have been true, because b should not match on the structural type of { def c(s: String) }
You don't test what the type system already guarantees. In fact, the type system is already a test of certain properties of your program.
You could further on to test that the types you have guarantee a certain property (like no player making a move twice in a row), but this kind of thing is restricted to languages like Agda and Coq, for now.
Assuming BlackPiece is not a subtype of WhitePiece:
WhiteToPlayInstance.move(BlackPiece, s) should not compile - which means you can't write a test for it. The type system ensures that you can't move a BlackPiece on a WhiteToPlay.
EDIT: As Thomas pointed out, the below answer is nonsense since structural types cannot be used in pattern matches in the JVM version of scala.
Under normal cicumstances this doesnt make much sense because scala is statically typed and things like that are taken care of by the compiler but if you do make massive use of reflection or structural typing in your code it might be a good test:
instance match {
case x: { def move(p: BlackPiece, s: Square): Either[FinishedGame, WhiteToPlay] } => // error
case _ => // no error
}
If you really want to test for such things, move the check from type checking to something dynamic. Assume that WhitePiece and BlackPiece share a common supertype Piece:
trait Game {
def move(p : Piece, s : Square) : Either[FinishedGame, WhiteToPlay]
}
trait BlackToPlay extends Game
trait WhiteToPlay extends Game
Then a test could look like this:
val b2p : BlackToPlay = ...
val bp : BlackPiece = ...
val wp : WhitePiece = ...
{a move bp} must not produce [IllegalMoveException]
{a move wp} must produce [IllegalMoveException]
I am not sure this would be good design, but it makes your system explicitly testable.
I know you didn't want a reflection solution, but you could (if scala 2.9 is acceptable) use the new Dynamic trait like this:
class ReflectionDynamic[T <: AnyRef](t: T) extends Dynamic {
def typed[A]: A = sys.error("doh");
def applyDynamic(name: String)(args: Any*) = {
val argRefs = args.map {
case a: AnyRef => a
case _ => sys.error("only AnyRefs")
}
t.getClass.getMethod(name, argRefs.map(_.getClass): _*).invoke(t, argRefs: _*)
}
}
... and that will give this positive test:
val dynamicWhiteToPlay = new ReflectionDynamic(whiteToPlay)
dynamicWhiteToPlay.move(new WhitePiece, new Square) must_== Right(blackToPlay)
... and this for negative:
dynamicWhiteToPlay.move(new BlackPiece, new Square) must throwA[NoSuchMethodException]
The question is akin to asking: Given val f: (Boolean) => Int, how can I test that f("hello world") is rejected by the compiler?
After some brief conversation at the Melbourne Scala User Group my question was validated (yay). After all, the restriction I'm trying to test for is included by design and therefore deserves a test.
Bernie Pope suggested that the mechanism required is Automated Theorem Proving. #daniel-c-sobral was kind enough to mention Agda and Coq in a slightly different context and indeed these are ATP technologies which could prove my application to be correct.
Another suggestion was to execute the offending code as a script and assert that it fails. A poor-mans eval, if you like.