polymorphism - pannous/warp GitHub Wiki

The ability to write code that can operate on different types is called polymorphism.

In dynamic languages you often find beasts such as:

function foo(x)
    if x is Integer
        x + x
    elif x is Float
        x / 2.0
    elif x is String
        length(x)
    else
        1
    end
end

This is clearly unidiomatic and should be written as

foo(x:int) := x + x
foo(x:text) := x.length
foo(3)       # 6
foo("abc")   # 3

Each line adds a variant of foo; a call picks the one its argument's type fits.

An untyped foo(x) := 1 next to typed variants is the variant for every other value: foo("abc") takes the text variant, foo(2.5) the fallback.

Functions dispatch on the classes of their arguments (function#Methods): sort(d:Deck) and sort of lists are one function, and collide(a:Ship, b:Rock) picks its method by both arguments. This is called multiple dispatch. Unlike in object orientated languages multiple dispatch functions can "belong" to multiple objects.

For example a generic function slice fruit with tool {...} would live outside the fruit and tool classes and be applicable to both.

One big disadvantage of the functional approach, besides discoverability, is lack of encapsulation and private access. This can be alleviated with modules (in case of Julia)

return type polymorphism

Thanks to return polymorphism, the concepts of arguments, functions and their return type become unified in a general matching framework:

A function can have variants that differ only in what they return; the type the caller expects picks one:

class pdf{body}
class docx{body}
render(t):pdf  := pdf("%PDF " + t)
render(t):docx := docx("<w:t>" + t)
x = (render "hello") as pdf
docx example = render "hello MS"

as pdf, a declared variable type or a parameter's type is the expected type. Without one, warp takes the first variant and warns: "render has variants returning pdf, docx: which does render "hi" mean? (taking pdf); fix: (render "hi") as pdf".

The English definition form names the result type after as:

class pdf{body}
to render text as pdf:
 return pdf("%PDF " + text)
(render "hello") as pdf

Again using types as parameter names. PS: the return statement here is superfluous and just for clarification purposes.

⚠️ **GitHub.com Fallback** ⚠️