Why did kotlin creators decide to place <> after a class name but before a function name in kotlin generics? - kotlin

This is not directly related to programming but after some time you need to brush up your generic skill with google searches. This is confusing and irritating. Do you know why the kotlin creators decided to be inconsistent with their square brackets like this?

In Kotlin, the angle brackets (< and >) are used to denote generic types. The placement of the angle brackets in Kotlin's syntax is consistent with the way generics are represented in the Java programming language, from which Kotlin draws much of its inspiration.
When used with a class, the angle brackets are placed after the class name, like this: MyClass<T>. This syntax is used to indicate that the class is a generic class and that it can be parameterized with a type.
When used with a function, the angle brackets are placed before the function name, like this: fun <T> myFunction(). This syntax is used to indicate that the function is a generic function, and that it can be parameterized with a type.
The placement of the angle brackets before the function name is intended to make it clear that the function is a generic function, and that the type parameter is part of the function's signature, rather than part of the function's return type or parameter types.
It's worth noting that the syntax for generics in Kotlin is consistent with Java, and it's designed to be familiar to developers who are already familiar with Java's generics. It also makes it easy for Java developers to learn and use Kotlin.

Related

What is the usage scenario of kotlin overloading the invoke operator?

Why not use top-level functions but overloaded invoke operators?
Is there any advantage to overloading the invoke operator?
class GetFollowableTopicsUseCase #Inject constructor(
private val topicsRepository: TopicsRepository,
private val userDataRepository: UserDataRepository
) {
operator fun invoke(sortBy: TopicSortField = NONE): Flow<List<FollowableTopic>>
...
}
There's an old pair of sayings that floats around programming communities like these.
Closures are a poor man's objects, and objects are a poor man's closures.
The fact of the matter is that, in a sufficiently modern language like Kotlin (or like most languages that we use nowadays), objects and closures are pretty similar. You could replace every class in your Kotlin program with a mess of functions and mutable variables they close over. Likewise, you could replace every function in your program with an object that has an invoke function. But the former would be a constant wrestling match with the type system, and the latter would be absurdly verbose.
So Kotlin lets us do both. Which should you use? The advantage of functions is that they're short and snappy and to-the-point. And, to a functional programmer at least, functions should generally be free of side-effects. Objects, on the other hand, are loud and verbose. That's a bad thing, in that it takes longer to read and comprehend when skimming the code. But it's also a good thing, because it stops you from hiding complexity.
So if your function is simple, use a function. If it's complicated or stateful, use a named object and document it like any public class. As a few examples, here's how I would handle some different situations.
A function to add two numbers together is simple, side-effect-free, and referentially transparent. Use a function.
A function to add a number to a local val is still very simple. It's a closure, but the val is immutable, so the function's behavior is predictable. Using an object would be overkill, so make it a function.
A function that keeps track of how many times it's been called and prints out that number each time has side effects and local state. While it could be written as a fancy closure around a var, it would be better to make this a real object, whose counter variable is a genuine instance variable, so that anyone reading the code can see at a glance what's happening.
In addition to Silvio's general answer, one specific case is for factory methods.
If you define a factory method like this:
class MyClass(…) {
…
companion object {
operator fun invoke(…): MyClass = …
}
}
Then calling the factory method looks exactly like calling a constructor: MyClass(…). This makes factory methods, with all their advantages, easier to use and hence more likely to be adopted.
(Obviously, this only makes sense when the parameter type(s) clearly distinguish the factory method from any public constructors, and also clearly indicate its purpose. In other cases, named factory methods are preferably.)

How are Kotlin value classes different from inline classes?

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.

Methods and member functions in Kotlin

Kotlin Reference section on Functions states that 'A member function is a function that is defined inside a class or object':
I have also seen references to methods in Kotlin. Are methods and member functions the same, different or misuse of terms?
AFAIK yes, same.
Kotlin is a bit different from Java because there are for example top level functions, and functions in companion objects, functions within functions, extension functions, etc. Everything in Kotlin starts with fun is called a (some kind of) function.
In Java, there are less types of functions. There are static (class-level) functions and object-level methods. The latter expression comes from OOP world, and Java is an OOP language, while Kotlin is not just that.
Methods and member functions are synonyms. Much like object attributes are called member fields. Synonyms, however, have often little differences or shades of meanings. For instance, the word old can be expressed with synonyms ancient, venerable, elderly or matured. Each of the words describes the same thing with some different shades of
meanings.
Kotlin is a powerful functional programming language. In functional languages, the term function is very important. Kotlin functions are much powerful than Java or C# methods. If we called them methods, this would imply similar to C# and Java. The term member function reflects the power and flexibility of the Kotlin function better.

Differences between Red's 5 function types, and why does it distinguish them?

In Red, there are functions of datatypes function!, op!, native!, routine! and action!. What are the differences between them? As far as I know function! is used for user-defined functions and op! for infix operators, and routine! for functions defined in Red/System, but why is there a need for the other two?
function!
As you've guessed yourself, function!s are user-defined functions that support refinements and typechecking, and can also contain embedded docstrings.
Typically, function! values are created with func, function, does and has constructors, and utilize so-called spec dialect; but, in theory, nothing stops you from making your own constructors or devising your own spec formats.
It's also worth noting that function!s fully support reflection.
op!
op!s are infix wrappers on top of other 4 types of functions - they take one value on the left and result of an expression on the right, and they also take precedence other functions during evaluation.
op! values are limited to two arguments, don't support refinements, and have a limited support for reflection (e.g. you can't inspect their bodies with body-of).
routine!
routines! exist in both realms of Red and Red/System (low-level dialect on top of which Red runtime is build). Their specs are written in spec dialect, but their bodies contain Red/System code. Oh, and they support reflection.
Usually they are used for library bindings (like the SQL lib you've mentioned), interaction with runtime, or for performance bottlenecks (Red/System is a compiled language, so rewriting perfomance-critial parts of your app as a set of routine!s will give you a significant boost, at the cost of mandatory compilation).
native!
native!s are functions written in Red/System (for perfomance, simplicity or feasibility reasons) and compiled down to native code (hence the name). Not sure what else can be said about them, aside from implementation details. native! aren't very user-facing, so you might want to study Red's source code in case you have any questions left.
action!
action!s are a standardized set of function written in Red/System (just like native!s) that each datatype implements (or inherits) as its "method". action! are polymorphic in a sense that they dispatch on their first argument:
>> add 1 2%
== 1.02
>> add 2% 1
== 102%
>> append [1] "2"
== [1 "2"]
>> append "1" [2]
== "12"
In mainstream languages this typically looks like "1".append([2]) or something like that.
Distinction between action!s and native!s boils down to a design choice:
you can have as many native! as you want, but action!s, for efficiency, have a fixed-size dispatch table (which means that maximum number of action!s per datatype is limited; minimum number is two: make [to create value] and mold [to serialize value to string!]).
logically, action!s are organized around datatype to which they belong, in one file, while native!s aren't really concerned with datatypes, and implement control flow, trigonometric functions, operations on sets, etc.
Coincidentially, just recently we have a similar discussion about action!s and native!s in our community chat, which you might want to read. I can also recommend to skim thru Rudolf Meijer's Red specification draft, and, of course, official reference documentation.
As for "why" in your question - distinction between 5 types is just an implementation detail, inherited from Rebol. Logically, they all implement what you might call a "function" from conceptual standpoint, and fall into any-function! camp.
While to a caller it may seem similar to run a function whose body is a BLOCK! of code to one which is implemented as native instructions...the implementation has to go down a different branch.
I don't know precisely what Red does in the compilation case, the interpreter case for Rebol2 and Red are similar. These different types are effectively part of a big switch() statement. If it looks in the cell describing the "function" and finds TYPE_NATIVE it knows to interpret the cell's contents as containing a native function pointer. If it finds TYPE_FUNCTION, it knows to pick apart the cell as containing a pointer to a block of code to execute:
https://github.com/red/red/blob/cb39b45f90585c8f6392dc4ccfc82ebaa2e312f7/runtime/interpreter.reds#L752
Now I myself would agree with your line of questioning. e.g. is this leaking an implementation detail to the user--who shouldn't be concerned with this facet in the type system?
But for what it is worth, there is a catch-all typeset called ANY-FUNCTION!:
>> any-function!
== make typeset! [native! action! op! function! routine!]
And you might think of that as "anything that obeys a function-like interface for calling". There are some complexities however, as OP! gets its first argument from the left...so that really is a matter of concern from an interface perspective.
Anyway... a NATIVE! (body is built as native code into the executable) vs. a FUNCTION! (body is a block of Red code run by interpretation or compilation) is just one distinction. A ROUTINE! is a facade built to interact with a DLL/library a la FFI that did not have a-priori knowledge of Red. An ACTION! is a very oversimplified attempt at what are called in other languages Generics. An OP! just gets its first argument from the left.
Point being that each of these might feel the same to a caller (except OP!), but the implementation has to do something different. The way it knows to do something different is via a type byte in a value cell. That's how Rebol2 did it--and Red followed Rebol2 fairly closely--so that's how it also does it. It means that any novel concept of what provides the implementation behind a function requires a new datatype, and it's probably not the greatest idea.
Red is based on Rebol an so has the same types.
function! is an user defined function defined in red
native! is an function in machinecode
op! is an infix operator written in machinecode
action! is an polymorphic function in machinecode
routine! is an function in imported from dynamic library

Can Scala be seen as an 'Abstraction Inversion'?

Greetings,
It's a provocative question, aiming to open debate about how abstraction inversion are seen among developer community. I'm really curious to know what you think.
First, here is a quote from the abstraction inversion exemples given by Wikipedia:
http://en.wikipedia.org/wiki/Abstraction_inversion
Creating an object to represent a function is cumbersome in object-oriented languages such as Java and C++, in which functions are not first-class objects. In C++ it is possible to make an object 'callable' by overloading the () operator, but it is still often necessary to implement a new class, such as the Functors in the STL.
For me functions are first-class citizen in Scala, but when we use Scala to generate Java bytecode, Scala create specific class 'on top' of Java to make functional programming possible... can we see this as an abstraction inversion ?
Same can apply to Clojure or any functionnal language for the JVM... or even Apache Collections, for exemple this:
http://commons.apache.org/collections/apidocs/org/apache/commons/collections/Closure.html
BTW, I'm not convinced about the wikipedia article objectivity. For example when speaking about possible abstraction inversion in micro-kernel the article say 'A body of opinion holds the microkernel design to be an abstraction inversion' but no such statement for functional type in OOP
The wiki article is really weak (does it represent an abstraction inversion itself? :), and the very concept is a bit dubious. But the fundamental gist of it seems to be that some basic element is hidden by the abstraction, forcing users of that abstraction to re-implement it.
For instance, from the talk page, comes a much more interesting example. Suppose a CPU had a tan math function, but no sin or cos, and a programming language implemented sin and cos in terms of tan, but did not expose tan itself. A programmer using that language would be forced to implement tan in terms of sin and cos, which, themselves, are implemented in terms of tan, therefore characterizing abstraction inversion.
So, back to Scala. Naturally, a programmer using functions in Scala is not incurring in abstraction inversion, because he is not being forced to re-implement a functionality available as a primitive to Scala.
On the other hand, one might claim that Scala's implementation of functions as class instances is an instance of abstraction inversion. For that to be true, however, two things must also hold true:
There must be a "function" primitive available to JVM.
Such a primitive must have offered an alternative to what Scala is doing.
What, exactly, is a function? What would a function primitive look like? In this context, "function" means data that is capable of being executed. One might say that all assembler code, is, in fact, data that is capable of being executed -- only it is not portable, and, futhermore, not bytecode, therefore failing the design principles.
On the other hand, all methods in Java are referenced by an identifier, through which Java locates the code to be executed for a given object's class hierarchy. This identifier is not exposed, though it can be used indirectly through reflection. If it were exposed, and some functionality offered to say "call this code", then a function could arguably be constructed around that.
So, I think a case could be made for 1 to be true. Let's proceed to the next.
If Java did offer a "method" data type, would Scala functions cease to be instances of a class? No, they would not. One of the fundamental design aspects of Scala is that every element of a running program is an object. The "primitives" that Java already have are presented as if they were normal objects with methods, and if there was a "method" primitive, so would it.
One possible consequence of method primitives would be to elevate methods to first class citizens, but functions, themselves, would hardly change.
Implementing a function via an object is not done simply because that's what's possible on the JVM, it cuts right to the underlying philosophy of Scala.
everything is an object: functions, actors, number literals, etc. It's also possible for any object to be appliable (by defining the apply() method) without actually being a subclass of FunctionN.
This duality is fundamental in the design of many standard library APIs, it allows for e.g. Maps to be viewed as both a function (mapping keys to values) and as a object (a collection of key/value pairs).
Scala is a true object/functional hybrid, with neither paradigm being dominant.
No, it can't be seen as abstraction inversion. The reason is simple: In Scala you have a choice which abstraction level you prefer. Most of the time it's more convenient to write
val f = 2 * (_:Int)
//--> f: (Int) => Int =
f(21)
//--> res5: Int = 42
but it is no problem to do it the "long" way:
val f = new Function1[Int,Int] { def apply(v:Int) = 2*v }
//--> f: java.lang.Object with (Int) => Int =
f(21)
//--> res6: Int = 42
As FunctionN are traits, it's possible to use mix-in inheritance, which allows you to avoid situations like the one for Functors in C++. E.g. you could "retrofit" a Java-Map as a function:
class JavaMap[K,V] extends java.util.HashMap[K,V] with Function1[K,V] {
def apply(k:K) = get(k)
}
val m = new JavaMap[Int, String]
m.put(5,"five")
m(5)
//--> res8: String = five
I believe not. The way first-class functions are implemented in Scala is just that, an implementation detail.