Methods and member functions in Kotlin - 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.

Related

Is it correct to say that objects can display polymorphism

https://www.tutorialspoint.com/java/java_polymorphism.htm#:~:text=Polymorphism%20is%20the%20ability%20of,is%20considered%20to%20be%20polymorphic.
As per the link above, in which they say:
Polymorphism is the ability of an object to take on many forms.
I'm having trouble figuring out whether to take this literally or not.
From my knowledge of polymorphism, classes are polymorphic when they can have multiple children, each implementing a parent class method in a different way.
A function can be polymorphic as we can overload and override them so functions can display different behaviors.
I was told and taught that another form of polymorphism applies to objects that inherit from multiple parent classes.
In C++ for example an object may behave differently depending on its reference type if its methods aren't virtual.
Another example that comes to mind is in Java with multiple interfaces, I can look at an object as different types causing different expected behaviors.
Are these examples really considered polymorphism at play or is this just inheritance and Polymorphism best defines the first two examples (classes and methods)
Thanks
The literal meaning of the word "polymorphism" is what the tutorial says. However it makes very little sense to use the literal meaning of a technical term. In OOP, "polymorphism" means subtyping. There are other ways the term "polymorphism" is used in programming (ad-hoc and parametric polymorphism) but they are not related to OOP specifically.
"Polymorphic object" is not a standard term across the OOP literature. It has a very specific meaning in C++, and it's not "an object with several base classes". It is simply an object with at least one virtual function. From the OOP perspective, a C++ "polymorphic object" is just an object.
Deriving from more than one base classes is called multiple inheritance. I have never heard anyone using the term "polymorphism" for this.

Functional style OOP?

What if I make member variables as const as possible and treat frequently changing data as input argument to the interface method.
So instead of data owning methods that operates on itself, methods owns parameters(const members) and operates on data.
Is this kind of style functional or functional-style, or just call it "stateless OOP"?
Is there any reason to encourage or discourage it?
I wouldn't call it functional, as functional tends to imply that your program is made of composable functions (pure functions ideally). However, the "tenets" of functional programming seem to be there- immutability, referential transparency. The only thing you are (potentially) lacking is functions as first class objects. To truly be considered functional programming you really need to have functions that are treated as first class objects- they can be assigned, passed as arguments, and returned from other functions. So I think this would be considered OOP with functional elements.
Someone who is more well-versed in programming language design feel free to modify or refute this answer!

Why avoid subtyping?

I have seen many people in the Scala community advise on avoiding subtyping "like a plague". What are the various reasons against the use of subtyping? What are the alternatives?
Types determine the granularity of composition, i.e. of extensibility.
For example, an interface, e.g. Comparable, that combines (thus conflates) equality and relational operators. Thus it is impossible to compose on just one of the equality or relational interface.
In general, the substitution principle of inheritance is undecidable. Russell's paradox implies that any set that is extensible (i.e. does not enumerate the type of every possible member or subtype), can include itself, i.e. is a subtype of itself. But in order to identify (decide) what is a subtype and not itself, the invariants of itself must be completely enumerated, thus it is no longer extensible. This is the paradox that subtyped extensibility makes inheritance undecidable. This paradox must exist, else knowledge would be static and thus knowledge formation wouldn't exist.
Function composition is the surjective substitution of subtyping, because the input of a function can be substituted for its output, i.e. any where the output type is expected, the input type can be substituted, by wrapping it in the function call. But composition does not make the bijective contract of subtyping-- accessing the interface of the output of a function, does not access the input instance of the function.
Thus composition does not have to maintain the future (i.e. unbounded) invariants and thus can be both extensible and decidable. Subtyping can be MUCH more powerful where it is provably decidable, because it maintains this bijective contract, e.g. a function that sorts a immutable list of the supertype, can operate on the immutable list of the subtype.
So the conclusion is to enumerate all the invariants of each type (i.e. of its interfaces), make these types orthogonal (maximize granularity of composition), and then use function composition to accomplish extension where those invariants would not be orthogonal. Thus a subtype is appropriate only where it provably models the invariants of the supertype interface, and the additional interface(s) of the subtype are provably orthogonal to the invariants of the supertype interface. Thus the invariants of interfaces should be orthogonal.
Category theory provides rules for the model of the invariants of each subtype, i.e. of Functor, Applicative, and Monad, which preserve function composition on lifted types, i.e. see the aforementioned example of the power of subtyping for lists.
One reason is that equals() is very hard to get right when sub-typing is involved. See How to Write an Equality Method in Java. Specifically "Pitfall #4: Failing to define equals as an equivalence relation". In essence: to get equality right under sub-typing, you need a double dispatch.
I think the general context is for the lanaguage to be as "pure" as possible (ie using as much as possible pure functions), and comes from the comparison with Haskell.
From "Ruminations of a Programmer"
Scala, being a hybrid OO-FP language has to take care of issues like subtyping (which Haskell does not have).
As mentioned in this PSE answer:
no way to restrict a subtype so that it can't do more than the type it inherits from.
For example, if the base class is immutable and defines a pure method foo(...), derived classes must not be mutable or override foo() with a function that is not pure
But the actual recommendation would be to use the best solution adapted to the program you are currently developing.
Focusing on subtyping, ignoring the issues related to classes, inheritance, OOP, etc.. We have the idea subtyping represents a isa relation between types. For example, types A and B have different operations but if A isa B we then can use any of B's operations on an A.
OTOH, using another traditional relation, if C hasa B then we can reuse any of B's operations on a C. Usually languages let you write one with a nicer syntax, a.opOnB instead of a.super.opOnB as it would be in the case of composition, c.b.opOnB
The problem is that in many cases there's more than one way to relate two types. For example Real can be embedded in Complex assuming 0 on the imaginary part, but Complex can be embedded in Real by ignoring the imaginary part, so both can be seen as subtypes of the other and subtyping forces one relation to be viewed as preferred. Also, there are more possible relations (e.g. view Complex as a Real using theta component of polar representation).
In formal terminology we usually say morphism to such relations between types and there are special kinds of morphisms for relations with different properties (e.g. isomorphism, homomorphism).
In a language with subtyping usually there's much more sugar on isa relations and given many possible embeddings we tend to see unnecessary friction whenever we're using the unpreferred relation. If we bring inheritance, classes and OOP to the mix the problem becomes much more visible and messy.
My answer does not answer why it is avoided but tries to give another hint at why it can be avoided.
Using "type classes" you can add an abstraction over existing types/classes without modifying them. Inheritance is used to express that some classes are specializations of a more abstract class. But with type classes you can take any existing classes and express that they all share a common property, for example they are Comparable. And as long as you are not concerned with them being Comparable you don't even notice it. The classes don't inherit any methods from some abstract Comparable type as long as you don't use them. It's a bit like programming in dynamic languages.
Further reads:
http://blog.tmorris.net/the-power-of-type-classes-with-scala-implicit-defs/
http://debasishg.blogspot.com/2010/07/refactoring-into-scala-type-classes.html
I don't know Scala, but I think the mantra 'prefer composition over inheritance' applies for Scala exactly the way it does for every other OO programming language (and subtyping is often used with the same meaning as 'inheritance'). Here
Prefer composition over inheritance?
you will find some more information.
I think lots of Scala programmers are former Java programmers. They are used to think in term of Object Oriented subtyping and they should be able to easily find OO-like solution for most problems. But Functional Programing is a new paradigm to discover, so people ask for a different kind of solutions.
This is the best paper I have found on the subject. A motivating quote from the paper –
We argue that while some of the simpler aspects of object-oriented languages are
compatible with ML, adding a full-fledged class-based object system to ML leads to an excessively complex
type system and relatively little expressive gain

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.

Object-oriented programming in a purely functional programming context?

Are there any advantages to using object-oriented programming (OOP) in a functional programming (FP) context?
I have been using F# for some time now, and I noticed that the more my functions are stateless, the less I need to have them as methods of objects. In particular, there are advantages to relying on type inference to have them usable in as wide a number of situations as possible.
This does not preclude the need for namespaces of some form, which is orthogonal to being OOP. Nor is the use of data structures discouraged. In fact, real use of FP languages depend heavily on data structures. If you look at the F# stack implemented in F Sharp Programming/Advanced Data Structures, you will find that it is not object-oriented.
In my mind, OOP is heavily associated with having methods that act on the state of the object mostly to mutate the object. In a pure FP context that is not needed nor desired.
A practical reason may be to be able to interact with OOP code, in much the same way F# works with .NET. Other than that however, are there any reasons? And what is the experience in the Haskell world, where programming is more pure FP?
I will appreciate any references to papers or counterfactual real world examples on the issue.
The disconnect you see is not of FP vs. OOP. It's mostly about immutability and mathematical formalisms vs. mutability and informal approaches.
First, let's dispense with the mutability issue: you can have FP with mutability and OOP with immutability just fine. Even more-functional-than-thou Haskell lets you play with mutable data all you want, you just have to be explicit about what is mutable and the order in which things happen; and efficiency concerns aside, almost any mutable object could construct and return a new, "updated" instance instead of changing its own internal state.
The bigger issue here is mathematical formalisms, in particular heavy use of algebraic data types in a language little removed from lambda calculus. You've tagged this with Haskell and F#, but realize that's only half of the functional programming universe; the Lisp family has a very different, much more freewheeling character compared to ML-style languages. Most OO systems in wide use today are very informal in nature--formalisms do exist for OO but they're not called out explicitly the way FP formalisms are in ML-style languages.
Many of the apparent conflicts simply disappear if you remove the formalism mismatch. Want to build a flexible, dynamic, ad-hoc OO system on top of a Lisp? Go ahead, it'll work just fine. Want to add a formalized, immutable OO system to an ML-style language? No problem, just don't expect it to play nicely with .NET or Java.
Now, you may be wondering, what is an appropriate formalism for OOP? Well, here's the punch line: In many ways, it's more function-centric than ML-style FP! I'll refer back to one of my favorite papers for what seems to be the key distinction: structured data like algebraic data types in ML-style languages provide a concrete representation of the data and the ability to define operations on it; objects provide a black-box abstraction over behavior and the ability to easily replace components.
There's a duality here that goes deeper than just FP vs. OOP: It's closely related to what some programming language theorists call the Expression Problem: With concrete data, you can easily add new operations that work with it, but changing the data's structure is more difficult. With objects you can easily add new data (e.g., new subclasses) but adding new operations is difficult (think adding a new abstract method to a base class with many descendants).
The reason why I say that OOP is more function-centric is that functions themselves represent a form of behavioral abstraction. In fact, you can simulate OO-style structure in something like Haskell by using records holding a bunch of functions as objects, letting the record type be an "interface" or "abstract base class" of sorts, and having functions that create records replace class constructors. So in that sense, OO languages use higher-order functions far, far more often than, say, Haskell would.
For an example of something like this type of design actually put to very nice use in Haskell, read the source for the graphics-drawingcombinators package, in particular the way that it uses an opaque record type containing functions and combines things only in terms of their behavior.
EDIT: A few final things I forgot to mention above.
If OO indeed makes extensive use of higher-order functions, it might at first seem that it should fit very naturally into a functional language such as Haskell. Unfortunately this isn't quite the case. It is true that objects as I described them (cf. the paper mentioned in the LtU link) fit just fine. in fact, the result is a more pure OO style than most OO languages, because "private members" are represented by values hidden by the closure used to construct the "object" and are inaccessible to anything other than the one specific instance itself. You don't get much more private than that!
What doesn't work very well in Haskell is subtyping. And, although I think inheritance and subtyping are all too often misused in OO languages, some form of subtyping is quite useful for being able to combine objects in flexible ways. Haskell lacks an inherent notion of subtyping, and hand-rolled replacements tend to be exceedingly clumsy to work with.
As an aside, most OO languages with static type systems make a complete hash of subtyping as well by being too lax with substitutability and not providing proper support for variance in method signatures. In fact, I think the only full-blown OO language that hasn't screwed it up completely, at least that I know of, is Scala (F# seemed to make too many concessions to .NET, though at least I don't think it makes any new mistakes). I have limited experience with many such languages, though, so I could definitely be wrong here.
On a Haskell-specific note, its "type classes" often look tempting to OO programmers, to which I say: Don't go there. Trying to implement OOP that way will only end in tears. Think of type classes as a replacement for overloaded functions/operators, not OOP.
As for Haskell, classes are less useful there because some OO features are more easily achieved in other ways.
Encapsulation or "data hiding" is frequently done through function closures or existential types, rather than private members. For example, here is a data type of random number generator with encapsulated state. The RNG contains a method to generate values and a seed value. Because the type 'seed' is encapsulated, the only thing you can do with it is pass it to the method.
data RNG a where RNG :: (seed -> (a, seed)) -> seed -> RNG a
Dynamic method dispatch in the context of parametric polymorphism or "generic programming" is provided by type classes (which are not OO classes). A type class is like an OO class's virtual method table. However, there's no data hiding. Type classes do not "belong" to a data type the way that class methods do.
data Coordinate = C Int Int
instance Eq Coordinate where C a b == C d e = a == b && d == e
Dynamic method dispatch in the context of subtyping polymorphism or "subclassing" is almost a translation of the class pattern in Haskell using records and functions.
-- An "abstract base class" with two "virtual methods"
data Object =
Object
{ draw :: Image -> IO ()
, translate :: Coord -> Object
}
-- A "subclass constructor"
circle center radius = Object draw_circle translate_circle
where
-- the "subclass methods"
translate_circle center radius offset = circle (center + offset) radius
draw_circle center radius image = ...
I think that there are several ways of understanding what OOP means. For me, it is not about encapsulating mutable state, but more about organizing and structuring programs. This aspect of OOP can be used perfectly fine in conjunction with FP concepts.
I believe that mixing the two concepts in F# is a very useful approach - you can associate immutable state with operations working on that state. You'll get the nice features of 'dot' completion for identifiers, the ability to easy use F# code from C#, etc., but you can still make your code perfectly functional. For example, you can write something like:
type GameWorld(characters) =
let calculateSomething character =
// ...
member x.Tick() =
let newCharacters = characters |> Seq.map calculateSomething
GameWorld(newCharacters)
In the beginning, people don't usually declare types in F# - you can start just by writing functions and later evolve your code to use them (when you better understand the domain and know what is the best way to structure code). The above example:
Is still purely functional (the state is a list of characters and it is not mutated)
It is object-oriented - the only unusual thing is that all methods return a new instance of "the world"