What is the difference between multiple dispatch and method overloading? - oop

In languages like Scala, one can have multiple definitions for one method name by changing the number of parameters and/or the type of the parameters of the method. This is called method overloading.
How is that different from multiple dispatch?
Thank you

Method overloading is resolved at compile time.
Multiple dispatch is resolved at runtime.
When using double dispatch the called method depends on the actual type of receiver and arguments. Method overloading however, only allows the called method to depend on the declared type of the parameters. Why? Java binds method calls at compile time with their full signature (early binding). The full signature includes all parameter types, hence when the actual type of an argument differs at runtime (polymoprhism), overloading does not work as you might expect!
void add(Foo o) { ... }
void add(Bar o) { ... }
void client() {
Foo o = new Bar();
add(o); // calls add(Foo) not add(Bar)!
}
using multiple dispatch however
void add(Foo o) { o.dispatch(this); }
void add(Bar o) { o.dispatch(this); }
void client() {
Foo o = new Bar();
add(o); // calls #dispatch as defined in Bar!
}
Things might slightly differ in Scala, though the general distinction should be the same as presented here in all programming languages.

Related

Overriding parameter types?

I would like to override the parameter type of a method in its subclasses, I thought generics could be used for this but that does not seem to work (at least not the way I am doing it).
abstract class A {
bool someMethod<T>(T x);
}
Then override it like so:
class B extends A {
bool someMethod<bool>(bool x) {
// error: isn't a valid override
}
}
I have had to default to using type dynamic x for the parameter type, but that forfeits runtime safety checks and means a lot of type checking whenever the method is implemented.
Is this type of extension possible?
It's possible, but not the way you do it.
What you declare is a generic method, where each invocation gets to pass the type argument to the function.
What you probably want is:
abstract class A<T> {
bool someMethod(T x);
}
class B extends A<bool> {
bool someMethod(bool x) {
return true;
}
}
That makes the type a parameter of the subclass, not the method, so each subclass can define its own type.
(Here you get into problems with Dart's covariant generics, because you can write:
A<Object> a = B();
a.someMethod("a"); // run-time error.
Your type variable occurs only in places where a value of that type is needed, not where one is provided, so casting to the superclass A<Object> make the method more permissive than it can support. The compiler inserts a run-time type check on the argument, which is what the example code here hits.)

Kotlin - Void vs. Unit vs. Nothing

Kotlin has three types that are very similar in nature:
Void
Unit
Nothing
It almost seems like they're making the JavaScript mistake:
null
undefined
void(0)
Assuming that they haven't fallen into the same mistake, what are they all for, and how do they differ?
The Void type is from Java. You generally won't use this from Kotlin unless you're using some Java-library that uses it.
The Unit type is what you return from a function that doesn't return anything of interest. Such a function is usually performing some kind of side effect. The unit type has only one possible value, which is the Unit object. You use Unit as a return type in Kotlin when you would use void (lowercase v) in Java.
The Nothing type has no values. If a function has return type Nothing, then it cannot return normally. It either has to throw an exception, or enter an infinite loop. Code that follows a call to a function with return type Nothing will be marked as unreachable by the Kotlin compiler.
Because Nothing has no values, Nothing? is actually the type that captures only the null value in Kotlin.
Unit
Unit is like void
In Kotlin, when a function does not return any meaningful value, it is declared to return Unit, just like void in Java:
fun greet(): Unit { println("Good day!") }
It's a convention to skip writing Unit when a function returns Unit because Unit is considered the default return type by the compiler:
fun greet() { println("Good day!") }
Unit is a Singleton
The Unit is a class with only a single object (singleton pattern) and that object is the Unit itself. It is declared in the kotlin package using an object declaration as shown below:
public object Unit {
override fun toString() = "kotlin.Unit"
}
Unit in Functional Programming
Kotlin has first-class support for functional programming. It's common to have a Unit in a functional programming language. It makes the function types more readable by enabling all the functions to be declared as having a return value, even when a function does not return a value:
val greet: () -> Unit = { println("Good day!") }
Here, () -> Unit is a function type and the Unit after the -> indicates that this function type does not return any meaningful value. Mentioning the Unit cannot be skipped in function types.
Unit for Extending Generics
Every function has to return a value. Kotlin decided to represent this with a class rather than with a special type void as in Java. The reason for using a class is that the type system can be made more consistent by making it a part of the type hierarchy.
For example, let's say we have a generic interface called Worker<T> that performs some work. The doWork() function of this interface does some work and has to return a value T:
interface Worker<T> {
fun doWork(): T
}
But sometimes, we might want to use this interface for some work where we don't need to return any value, for example, the work of logging, in the LogWorker class shown below that extends the Worker interface:
class LogWorker : Worker<Unit> {
override fun doWork() {
// Do the logging
}
}
This is the magic of Unit where we are able to use the pre-existing interface that was originally designed to return a value. Here we make the doWork() function return the Unit value to serve our purpose in which we don't have anything to return. So, it's useful when you override a function that returns a generic parameter.
Notice that we have also skipped mentioning Unit return type for the doWork() function. There's no need to write a return statement either.
Nothing
Nothing's Value Never Exists
In Kotlin, the class Nothing represents a value that never exists. There can never be any value/object of this class because its constructor is kept private. It's defined in the kotlin package as follows:
public class Nothing private constructor()
Nothing is used for the return type of a function that never returns a value. For example, a function with an infinite loop or a function that always throws an exception. The error() function from Kotlin standard library is an example that always throws an exception and returns Nothing. Here is the code for it:
fun error(message: Any): Nothing = throw IllegalStateException(message.toString())
Nothing is the Bottom Type
In type theory, the type that has no values is called a bottom type and it is a subtype of all other types. So, Nothing is the subtype of all types in Kotlin, just like Any? is the supertype of all types. So, the value(that never exists) of type Nothing is assignable to the variables of all types, for example:
val user: User = request.user ?: error("User not found")
Here, we are calling the error() function that we defined earlier, if the user is null, using the elvis operator(?:). The error() function returns the value of type Nothing but it can be assigned to the variable of type User because Nothing is a subtype of User, just like it is a subtype of any other type. The compiler allows this because it knows that the error() function will never return a value, so there is no harm.
Similarly, you can return Nothing from a function that has any other return type:
fun getUser(request: Request): User {
return request.user ?: error("User not found")
}
Here, even though the getUser() function is declared to return a User, it may return Nothing, if the user is null.
Nothing in Null Object Pattern
Consider the following example of a function that deletes the files given in a list:
fun deleteFiles(files: List<File>? = null) {
if (files != null) files.forEach { it.delete() }
}
The problem with the design of this function is that it doesn't convey whether the List<File> is empty or null or has elements. Also, we need to check whether the list is null before using it.
To solve this problem, we use the null object design pattern. In null object pattern, instead of using a null reference to convey the absence of an object, we use an object which implements the expected interface, but leaves the method body empty.
So, we define the object of the interface List<Nothing>:
// This function is already defined in the Kotlin standard library
fun emptyList() = object : List<Nothing> {
override fun iterator(): Iterator<Nothing> = EmptyIterator
...
}
Now we use this null object in our deleteFiles() function as a default value of our parameter:
fun deleteFiles(files: List<File> = emptyList()) {
files.forEach { it.delete() }
}
This removes the uncertainty of null or empty and makes the intent clearer. It also removes the null checks because the functions on the null object are empty, they will be called but they are no-ops (no operation in them, so they will do nothing).
Nothing for Covariant Generics
In the example above, the compiler allows us to pass List<Nothing> where List<File> is expected. This is because the List interface in Kotlin is covariant since it's defined using the out keyword, that is, List<out T>. And as we learnt, Nothing is a subtype of all types, Nothing is a subtype of File too. And due to covariance, List<Nothing> is a subtype of List<File>, List<Int>, List<User> and so on... List<AllTypes>. This applies to any type with the covariant generics(out), not just List.
Nothing for Better Performance
Just like the function emptyList() used in our example, there are predefined functions like emptyMap(), emptySet(), emptySequence() that return null objects. All these are defined using Nothing. You can define your own objects like this.
The advantage here is that these return singleton objects, for example, you can call the same emptyList() function for getting an empty instance, whether it is for assigning to List<File>, List<Int> and ... List<AllTypes> and in multiple places. Since the same object is returned every time, it saves the cost of object creation and memory allocation.
Void
Void for Extending Generics in Java
The Void class is from the java.lang package while the Unit and Nothing are from the kotlin package. Void is not intended to be used in Kotlin. Kotlin has its own class in the form of Unit.
Void is used in Java for extending generic interfaces like our Worker interface example written for Unit where we have to return a value. So for converting our Kotlin code to Java, we can use Void the same way we have used Unit for our Worker example and rewrite the code in Java as follows:
interface Worker<T> {
T doWork();
}
class LogWorker implements Worker<Void> {
#Override public Void doWork() {
// Do the logging
return null;
}
}
Notice that when using Void, we have to use Void as a return type(can't skip) as well as need to write the return statement whereas for Unit we can skip both. This is another reason to avoid using Void in Kotlin code.
Conclusion
So, Unit and Nothing are not a mistake by Kotlin designers in my opinion and are not as questionable as null, undefined and void(0) in Javascript. Unit and Nothing make the functional programming a breeze while providing other useful features mentioned. They are common in other functional programming languages too.
That's it!
Void is uninstantiable type. It is a plain Java class and has no special meaning in Kotlin.
Unit type has only one value. Replaced Java void (notice: not Void). More info in Kotlin docs.
Nothing has no instances (just like Void). It represents "a value that never exists". In Kotlin if you throw an error it is a Nothing (see Kotlin docs).

How to force invoke method with object type input value without any type casting in a series of overloaded methods?

For example I'm having a class with three overloaded methods like this:
class MyClass
{
int sum(int i)
{
// Method implementation.
}
int sum(string x)
{
// Method implementation.
}
int sum(object o)
{
// Method implementation.
}
}
My question is when I call the sum method of MyClass by passing any value (integer, string or object) it should invoke only third method (with object type input parameter)
class MainClass
{
static void Main(string[] args)
{
MyClass obj = new MyClass();
obj.sum(10);
obj.sum("X")
}
}
You said "without type casting" but you can't, because you need some way to indicate to the compiler which version to call, and the runtime uses the type it sees to do that bit. Boxing the int as an object means the compiler will pick the object version
sum(1);//call int version
sum((object)1); //call object version
sum((string)(object)"1"); //call string version
sum((object)(int)(object)1); //call object version
First of all, let me say that if you sometimes want to call one version of the sum function when working with ints and sometimes want to call another, overloading probably isn't the right tool to use. Overloading works best when you are implementing conceptually the same operation for a number of different types, and you want the compiler to figure out automatically which function is the right one to call for each type; if you need more manual control over which function is called, you're probably better off using different names.
That said, if you're sure that this is what you want to do, you could implement the overloaded version for object in terms of another function in the public interface, as in:
class MyClass
{
int sum(int i)
{
// Method implementation.
}
int sum(string x)
{
// Method implementation.
}
int sum(object o)
{
sum_object(o);
}
int sum_object(object o)
{
// Method implementation for objects
}
}
Then, when you want to apply the object version to int and string objects, you just call sum_object directly instead.

Mockito mocking method with class parameter vs actual object parameter

What is the difference between these two as per Mockito -
Mockito.when(serviceObject.myMethod(Customer.class)).thenThrow(new
RuntimeException());
and
Customer customer = new Customer();
Mockito.when(serviceObject.myMethod(customer)).thenThrow(new
RuntimeException());
And if both serve the same purpose then using which one is considered to be best practice?
There is a misunderstanding on your side - that method specification myMethod(SomeClass.class) is only possible when the signature of that method allows for a class parameter. Like:
Whatever myMethod(Object o) {
or directly
Whatever myMethod(Class<X> clazz) {
In other words: it is not Mockito that does something special about a parameter that happens to be of class Class!
Thus your first option is not something that works "in general". Example: I put down this code in a unit test:
static class Inner {
public int foo(String s) { return 5; }
}
#Test
public void testInner() {
Inner mocked = mock(Inner.class);
when(mocked.foo(Object.class)).thenReturn(4);
System.out.println(mocked.foo(""));
}
And guess what - the above does not compile. Because foo() doesn't allow for a Class parameter. We can rewrite to
static class Inner {
public int foo(Object o) { return 5; }
}
#Test
public void testInner() {
Inner mocked = mock(Inner.class);
when(mocked.foo(Object.class)).thenReturn(4);
System.out.println(mocked.foo(""));
}
And now the above compiles - but prints 0 (zero) when invoked. Because the above would be the same as mocked.foo(eq(Object.class)). In other words: when your method signature allows for passing a Class instance and you then pass a class instance, that is a simple mocking specification for mockito. In my example: when the incoming object would be Object.class - then 4 would be returned. But the incoming object is "" - therefore the Mockito default kicks in and 0 is returned.
I am with the other answer here - I think you are mixing up that older versions of Mockito asked you to write down when(mocked.foo(any(ExpectedClass.class))) - which can nowadays be written as when(mocked.foo(any())). But when(mocked.foo(ExpectedClass.class)) is not a Mockito construct - it is a simple method specification that gives a specific object to "match on" - and that specific object happens to be an instance of class Class.
First one which uses generic Customer class to match type can also be written as:
Mockito.when(serviceObject.myMethod(Mockito.any(Customer.class))).thenThrow(new
RuntimeException());
In case of the second one, you are passing the actual object that will be used in stubbing.
Usage:
If your method myMethod throws the exception based on the state of the Customer object then you can use the latter approach, where you can set the state of the Customer object appropriately.
However If your method myMethod does not depend on the Customer object to throw the exception rather you need it only to pass it as an argument just to invoke the method, then you can take the former approach.

What's the purpose of allowing the declaration of an abstract method in a non-abstract class?

According to this article, it's possible, in Dart, to define a non-abstract class to have an abstract (or not-implemented) method. The abstract method causes a warning, but does not prevent instantiation.
What's the purpose of allowing the declaration of an abstract method in a non-abstract (or concrete) class in Dart? Why was Dart designed to work in this way?
The specification is actually very explicit about declaring abstract methods in a concrete class:
It is a static warning if an abstract member m is declared or inherited in a concrete class
We wish to warn if one declares a concrete class with abstract members.
It is a static warning if a concrete class has an abstract member (declared or inherited).
They don't have any intended purpose for it, which is why they issue warnings. If you're familiar with Java: it's similar to accessing a static member via an object, which is also pointless and triggers a warning.
As for why it passes compilation, Dart uses an optional type system, which means typing concepts should not affect the semantics of the language, and that's simply what Dart is enforcing:
The purpose of an abstract method is to provide a declaration for purposes such as type checking and reflection.
The static checker will report some violations of the type rules, but such violations do not abort compilation or preclude execution.
An abstract method in a concrete class allows you to provide the type signature for a method that is implemented via noSuchMethod() instead. Providing a noSuchMethod() implementation will also silence the warning.
In strong mode, simply having an abstract method in a concrete class will result in an error, unless the class also implements the noSuchMethod() interface.
In short, the purpose of abstract methods in a concrete class is to provide type signatures for noSuchMethod() implementations. This avoids warnings for calling an unknown method and in strong mode (which is the default for dartdevc, and will be first the default and then mandatory for Dart 2.0) these type signatures are necessary for code with noSuchMethod() to even compile, unless the target is of type dynamic.
Example:
class A {
void f();
dynamic noSuchMethod(Invocation inv) => null;
}
void main() {
var a = new A();
a.f();
}
If we replace a.f() with (say) a.f(0), then this will result in an error (in strong mode) for having called the method with the wrong number of parameters. If we omit the void f() declaration, then we'll get an error that A does not have a method f(). If we omit the noSuchMethod() implementation, then the complaint will be that f() lacks a method body, even though A isn't abstract.
The following code provides a more realistic example:
import "dart:mirrors";
class DebugList<T> implements List<T> {
List<T> _delegate;
InstanceMirror _mirror;
DebugList(this._delegate) {
_mirror = reflect(_delegate);
}
dynamic noSuchMethod(Invocation inv) {
print("entering ${inv.memberName}");
var result = _mirror.delegate(inv);
print("leaving ${inv.memberName}");
return result;
}
}
void main() {
List<int> list = new DebugList<int>([1, 2, 3]);
int len = list.length;
for (int i = 0; i < len; i++) print(list[i]);
}
This example creates a debugging decorator for List<T>, showing all method invocations. We use implements List<T> to pull in the entire list interface, inheriting dozens of abstract methods. This would normally result in warnings (or in strong mode, errors) when run through dartanalyzer, as we're missing implementations for all these methods normally provided by List<T>. Providing a noSuchMethod() implementation silences these warnings/errors.
While we could also manually wrap all 50+ methods, this would be a lot of typing. The above approach also will continue to work if new methods are added to the list interface without us having to change our code.
Use cases for explicitly listing methods in a concrete class are less common, but can also occur. An example would be the addition of getters or setters to such a debugging decorator that allows us to inspect or set instance variables of the delegate. We will need to add them to the interface, anyway, to avoid warnings and errors from using them; the noSuchMethod() implementation can then implement them using getField() and setField(). Here's a variant of the previous example, using stacks instead of lists:
// main.dart
import "dart:mirrors";
import "stack.dart";
class DebugStack<T> implements Stack<T> {
Stack<T> _delegate;
InstanceMirror _mirror;
DebugStack(this._delegate) {
_mirror = reflect(_delegate);
}
dynamic _get(Symbol sym) {
// some magic so that we can retrieve private fields
var name = MirrorSystem.getName(sym);
var sym2 = MirrorSystem.getSymbol(name, _mirror.type.owner);
return _mirror.getField(sym2).reflectee;
}
List<T> get _data;
dynamic noSuchMethod(Invocation inv) {
dynamic result;
print("entering ${inv.memberName}");
if (inv.isGetter)
result = _get(inv.memberName);
else
result = _mirror.delegate(inv);
print("leaving ${inv.memberName}");
return result;
}
}
void main() {
var stack = new DebugStack<int>(new Stack<int>.from([1, 2, 3]));
print(stack._data);
while (!stack.isEmpty) {
print(stack.pop());
}
}
// stack.dart
class Stack<T> {
List<T> _data = [];
Stack.empty();
Stack.from(Iterable<T> src) {
_data.addAll(src);
}
void push(T item) => _data.add(item);
T pop() => _data.removeLast();
bool get isEmpty => _data.length == 0;
}
Note that the abstract declaration of the _data getter is crucial for type checking. If we were to remove it, we'd get a warning even without strong mode, and in strong mode (say, with dartdevc or dartanalyzer --strong), it will fail:
$ dartdevc -o main.js main.dart
[error] The getter '_data' isn't defined for the class 'DebugStack<int>' (main.dart, line 36, col 15)
Please fix all errors before compiling (warnings are okay).