How are Kotlin value classes different from inline classes? - kotlin

What's the difference between an inline class and a value class? I understand that a value class is an inline class when it is annotated as #JvmInline value class but this only applies when targeting the JVM. So on other platforms, are all value classes implicitly inline classes? What exactly is a non-inline value class, and is what is the use of defining a value class without #JvmInline on the JVM?

If you want to understand in more details, you can take a look at the corresponding KEEP.
What's the difference between an inline class and a value class?
You can see value classes as a more general declaration from the developer, while "inline" is more an implementation detail of how this is compiled.
When you declare a value class, you essentially give up on the identity of instances of this class. This means you cannot distinguish between identical references and equal values of that class. This is mostly why other restrictions follow from this declaration (like no var properties or === operator).
A good example to keep in mind is Int. You cannot distinguish between x and y if they are defined like this: val x = 42 and val y = 41 + 1. They are equal in every way because it doesn't make sense to talk about references here. This is why === is prohibited on primitive classes like this (and thus on value classes).
Giving up identity is what opens the door for inlining or other optimizations, but value classes don't have to be implemented this way. In fact, even experimental inline classes were not always "inlined", there are cases where they have to be boxed just like Int (e.g. when used as a generic type parameter, or as a parent type).
So on other platforms, are all value classes implicitly inline classes?
From the explanation above, it might be a bit clearer that inlining is only one possible way of implementing such classes. Actually, it shouldn't really matter to the developer what the compiler uses behind the scenes on different platforms (it's just optimizations). But yeah, on Native and JS it's easier for the compiler to inline stuff. Take a look at this section of the KEEP for more info on platform specifics.
What exactly is a non-inline value class, and is what is the use of defining a value class without #JvmInline on the JVM?
These are not supported at the moment (you have to specify #JvmInline in Kotlin 1.5). Only the "inline" implementation strategy is used in 1.5. However, the Kotlin team wants to be able to later adopt potential other implementation strategies, like making use of Project Valhalla's new kinds of types. To do so in a backwards compatible way, it helps to have this annotation right now and allow to not specify it later. From the KEEP:
The #JvmInline annotation makes it explicit that something special with this class is going on in JVM, and it enables us to support non-annotated value class in the future Valhalla JVM by compiling them using the capabilities of the Project Valhalla.

Related

What is the purpose or possible usages of value class in Kotlin

I found the new value class been
I found the purpose is like :
value class adds attribute to a variable and constraint it’s usage.
I was wondering what is some practical usage of value class.
Well, as stated in the documentation Kotlin Inline classes
Sometimes it is necessary for business logic to create a wrapper around some type. However, it introduces runtime overhead due to additional heap allocations. Moreover, if the wrapped type is primitive, the performance hit is terrible, because primitive types are usually heavily optimized by the runtime, while their wrappers don't get any special treatment.
To solve such issues, Kotlin introduces a special kind of class called an inline class. Inline classes are a subset of value-based classes. They don't have an identity and can only hold values.
A value class can be helpful when, for example, you want to be clear about what unit a certain value uses: does a function expect me to pass my value in meters per second or kilometers per hour? What about miles per hour? You could add documentation on what unit the function expects, but that still would be error-prone. Value classes force developers to use the correct units.
You can also use value classes to provide clear means for other devs on your project on doing operations with your data, for example converting from one unit to another.
Value classes also are not assignment-compatible, so they are treated like actual new class declarations: When a function expects a value class of an integer, you still have to pass an instance of your value class - an integer won't work. With type aliases, you could still accidentally use the underlying type, and thus introduce expensive errors.
In other words, if you simply want things to be easier to read, you can just use type aliases. If you need things to be strict and safe in some way, you probably want to use value classes instead.

Decoupling a class which is used by the lots of subclasses

Hi I have a situation like that;
I have different items in my design and all these items has some specific effect on the Character. There is an apply function in every item so it can use Character object and change its functionalities. But what if I change the Character function, I would have to change all the Item classes in accordance to that.
How can I decouple Item and Character efficiently?
The language I am going to use is C++ and I don't know the other variables and functions inside the Item and Character classes. I just want to decouple them.
You could introduce an interface (abstract class in C++) that Character would inherit. Let's call it ItemUser. The Item#apply signature would be changed so that it would take an object of ItemUser instead of Character. Now you are able to change the implementation of Character freely as long as it respects the ItemUser contract.
Check Decorator design pattern, it seems that this design pattern is what you are looking for. Link :Decorator design pattern
As per what I have understood from reading your question is : You have multiple Item classes each having a effect associated. Effect corressponding to the type of Item object is applied on another entity which is Character. Now your issue is whenever there is a change in Character class your Item classes also needs to change and you want a cleaner way to avoid this.
A good way to handle change is to define the well defined Contract which is less prone to change. For example if we have a functionality to add two integers and later we may have the changes such that we require to add two floating point numbers and later we may need to replace add operation with multiplication. In such a case you can define an abstraction Compute (INum num1, INum num2) : INum as return type. Here INum is an abstraction for type and Compute is abstraction for behaviour of function. Actual implementation defines INum and Compute. Now code using our code only depends on the abstractions and we can freely modify the operation and actual type without affecting the user code.
While implementing the contract you can modify the internal implementation without affecting the outside code using the contract.
You can define an abstract class ICharacter. For certain attributes whose type can change in future you can use Templates and generics or simply create interface for the attribute type as well and let the concrete type implement the interfaces. Refer all your fields with interfaces. Let ICharacter define public abstract methods with parameters of type Interfaces and return type also as Interfaces.
Let Item class use ICharacter and When you need to apply effect as per item class just use the constant abstract functions defined. Your Character internal modifications now can change without affecting the Item class.

Why wouldn't I make every eligable Kotlin class a data class?

I'm of course excluding any reasons that involve violating the rules for what can be a data class. So if you know you won't need to inherit from it for example (although it's my understanding that rule is going away in Kotlin 1.1).
Are there any disadvantages to making a class a data class?
Why don't all eligible classes provide the functionality of a data class as long as they remain eligible? This should all be detectable by the compiler without needing a special keyword. Of course the answer to this might be obvious depending on the answer to question 1.
Is there any reason for me not to mark all of my eligible classes as data classes?
data modifier makes Kotlin generate common methods like toString, hashCode, equals for the most commons (%80) scenarios based on the primary constructor.
This shows 3 reasons why only few classes should be data:
Most non-data classes have a mix of properties defined in the primary constructor and in the body of the class. Also the primary constructor often has parameter that are not fields (but help initialise more complex fields in the body). In other words, data has very restrictive requirements which are rarely met by regular classes.
In addition to point 1, making a class data may hurt its extensibility. Even if the layout of the class in question conforms to the rules of data classes, later someone may want to add another property in the body of the class. In that case he will have to manually override hashCode because it may be used somewhere.
Marking a class data sends a message to the one who reads the code that you intend to use this class as a data career. Marking other classes will be misleading.
because of one the fundament pinciple of OO programming: encapsulation.
by design we deliberately limit ways in which other code can interact with out modules. this gives us maintainability (more powerful refactoring) and readablity

Kotlin: Interface whereby the implementor must be a data class?

Is there an Interface that I can extend or some other way to create an Interface whereby the implementing class must be a data class? It would be useful to have access to the data class API methods such as copy().
No, copy method have unique number of parameters for every data class, so it's useless to have such interface. If all your data classes have same field - just create and implement common interface.
So I'm going to preface my answer by saying I don't have experience with Kotlin, but I have plenty of Java experience which as I understand it is similar, so unless Kotlin has a feature that helps do what you want that Java doesn't, my answer might still apply.
If I understand correctly, basically what you're trying to do is enforce that whatever class implements your interface X, must also be a subtype of Y.
My first question would be Why would you want to do this? Enforcing that X only be implemented by subtypes of Y is mixing interface and implementation, which the exact opposite of what interfaces are for.
To even enforce this, you would have to have X extend the interface of Y, either implicitly or explicitly. Since in Java (and presumably Kotlin), interfaces cannot extend objects, you have two options:
1) extend the INTERFACE of data, if it exists (which I don't think it does given what I've been reading about data classes. It sounds more like a baked in language feature than just a helpful code object)
2) Add to your interface the exact method signatures of the methods you want out of data classes. BY doing this, you've gained two things: First, you get your convenience methods whenever a data class implements your interface, and second, you still have the flexibility that interfaces are meant to provide, because now even non-data classes can implement your interface if you need them to, they just have to be sure to define the data classes interface methods manually.

Duck typing, must it be dynamic?

Wikipedia used to say* about duck-typing:
In computer programming with
object-oriented programming languages,
duck typing is a style of dynamic
typing in which an object's current
set of methods and properties
determines the valid semantics, rather
than its inheritance from a particular
class or implementation of a specific
interface.
(* Ed. note: Since this question was posted, the Wikipedia article has been edited to remove the word "dynamic".)
It says about structural typing:
A structural type system (or
property-based type system) is a major
class of type system, in which type
compatibility and equivalence are
determined by the type's structure,
and not through explicit declarations.
It contrasts structural subtyping with duck-typing as so:
[Structural systems] contrasts with
... duck typing, in which only the
part of the structure accessed at
runtime is checked for compatibility.
However, the term duck-typing seems to me at least to intuitively subsume structural sub-typing systems. In fact Wikipedia says:
The name of the concept [duck-typing]
refers to the duck test, attributed to
James Whitcomb Riley which may be phrased as
follows: "when I see a bird that walks
like a duck and swims like a duck and
quacks like a duck, I call that bird a
duck."
So my question is: why can't I call structural subtyping duck-typing? Do there even exist dynamically typed languages which can't also be classified as being duck-typed?
Postscript:
As someone named daydreamdrunk on reddit.com so eloquently put-it "If it compiles like a duck and links like a duck ..."
Post-postscript
Many answers seem to be basically just rehashing what I already quoted here, without addressing the deeper question, which is why not use the term duck-typing to cover both dynamic typing and structural sub-typing? If you only want to talk about duck-typing and not structural sub-typing, then just call it what it is: dynamic member lookup. My problem is that nothing about the term duck-typing says to me, this only applies to dynamic languages.
C++ and D templates are a perfect example of duck typing that is not dynamic. It is definitely:
typing in which an
object's current set of methods and
properties determines the valid
semantics, rather than its inheritance
from a particular class or
implementation of a specific
interface.
You don't explicitly specify an interface that your type must inherit from to instantiate the template. It just needs to have all the features that are used inside the template definition. However, everything gets resolved at compile time, and compiled down to raw, inscrutable hexadecimal numbers. I call this "compile time duck typing". I've written entire libraries from this mindset that implicit template instantiation is compile time duck typing and think it's one of the most under-appreciated features out there.
Structural Type System
A structural type system compares one entire type to another entire type to determine whether they are compatible. For two types A and B to be compatible, A and B must have the same structure – that is, every method on A and on B must have the same signature.
Duck Typing
Duck typing considers two types to be equivalent for the task at hand if they can both handle that task. For two types A and B to be equivalent to a piece of code that wants to write to a file, A and B both must implement a write method.
Summary
Structural type systems compare every method signature (entire structure). Duck typing compares the methods that are relevant to a specific task (structure relevant to a task).
Duck typing means If it just fits, it's OK
This applies to both dynamically typed
def foo obj
obj.quak()
end
or statically typed, compiled languages
template <typename T>
void foo(T& obj) {
obj.quak();
}
The point is that in both examples, there has not been any information on the type given. Just when used (either at runtime or compile-time!), the types are checked and if all requirements are fulfilled, the code works. Values don't have an explicit type at their point of declaration.
Structural typing relies on explicitly typing your values, just as usual - The difference is just that the concrete type is not identified by inheritance but by it's structure.
A structurally typed code (Scala-style) for the above example would be
def foo(obj : { def quak() : Unit }) {
obj.quak()
}
Don't confuse this with the fact that some structurally typed languages like OCaml combine this with type inference in order to prevent us from defining the types explicitly.
I'm not sure if it really answers your question, but...
Templated C++ code looks very much like duck-typing, yet is static, compile-time, structural.
template<typename T>
struct Test
{
void op(T& t)
{
t.set(t.get() + t.alpha() - t.omega(t, t.inverse()));
}
};
It's my understanding that structural typing is used by type inferencers and the like to determine type information (think Haskell or OCaml), while duck typing doesn't care about "types" per se, just that the thing can handle a specific method invocation/property access, etc. (think respond_to? in Ruby or capability checking in Javascript).
There are always going to be examples from some programming languages that violate some definitions of various terms. For example, ActionScript supports doing duck-typing style programming on instances that are not technically dynamic.
var x:Object = new SomeClass();
if ("begin" in x) {
x.begin();
}
In this case we tested if the object instance in "x" has a method "begin" before calling it instead of using an interface. This works in ActionScript and is pretty much duck-typing, even though the class SomeClass() may not itself be dynamic.
There are situations in which dynamic duck typing and the similar static-typed code (in i.e. C++) behave differently:
template <typename T>
void foo(T& obj) {
if(obj.isAlive()) {
obj.quak();
}
}
In C++, the object must have both the isAlive and quak methods for the code to compile; for the equivalent code in dynamically typed languages, the object only needs to have the quak method if isAlive() returns true. I interpret this as a difference between structure (structural typing) and behavior (duck typing).
(However, I reached this interpretation by taking Wikipedia's "duck-typing must be dynamic" at face value and trying to make it make sense. The alternate interpretation that implicit structural typing is duck typing is also coherent.)
I see "duck typing" more as a programming style, whereas "structural typing" is a type system feature.
Structural typing refers to the ability of the type system to express types that include all values that have certain structural properties.
Duck typing refers to writing code that just uses the features of values that it is passed that are actually needed for the job at hand, without imposing any other constraints.
So I could use structural types to code in a duck typing style, by formally declaring my "duck types" as structural types. But I could also use structural types without "doing duck typing". For example, if I write interfaces to a bunch of related functions/methods/procedures/predicates/classes/whatever by declaring and naming a common structural type and then using that everywhere, it's very likely that some of the code units don't need all of the features of the structural type, and so I have unnecessarily constrained some of them to reject values on which they could theoretically work correctly.
So while I can see how there is common ground, I don't think duck typing subsumes structural typing. The way I think about them, duck typing isn't even a thing that might have been able to subsume structural typing, because they're not the same kind of thing. Thinking of duck typing in dynamic languages as just "implicit, unchecked structural types" is missing something, IMHO. Duck typing is a coding style you choose to use or not, not just a technical feature of a programming language.
For example, it's possible to use isinstance checks in Python to fake OO-style "class-or-subclass" type constraints. It's also possible to check for particular attributes and methods, to fake structural type constraints (you could even put the checks in an external function, thus effectively getting a named structural type!). I would claim that neither of these options is exemplifying duck typing (unless the structural types are quite fine grained and kept in close sync with the code checking for them).