Exploring Parametric polymorphism

Corollary

Parametric polymorphism will disable require more steps to use automatic type inference in Odin for the procedure that use it.

// We have to pass the type in an explicit way
filtered := filter([]string{"one", "two"}, proc (element: string) -> bool {
    return element == "two"
})

// We can also store it in a typed variable
items := []string{"one", "two"}
filtered := filter(items, proc (element: string) -> bool {
    return element == "two"
})

// This way can be ambiguos using Parapoly
filtered := filter({"one", "two"}, proc (element: string) -> bool {
    return element == "two"
})

Another option is using Procedure Overloading to accept different param types in our procedures.

Example

package Project

import "core:fmt"

import "core:slice"
import "base:runtime"

filter_int :: proc(items : []int, callback: proc(element : int) -> bool, allocator:= context.allocator) -> (res: []int, err: runtime.Allocator_Error) #optional_allocator_error {
    return slice.filter(items, callback, allocator)
}

filter_string :: proc(items : []string, callback: proc(element : string) -> bool, allocator:= context.allocator) -> (res: []string, err: runtime.Allocator_Error) #optional_allocator_error {
    return slice.filter(items, callback, allocator)
}

filter :: proc {
    filter_int,
    filter_string,
    slice.filter,
}

main :: proc() {
    fmt.println(filter([]int{1, 2, 3}, proc( element: int) -> bool {
        return element == 2
    }))
}

When we have a procedure where multiple types can be assigned to a param in the same position in the signature. Ambiguos situations can arise and we have to resort to directly pass the type.