Polymorphic procedures

Type variables

The dollar sign ($) in Jai indicates a type variable. 1

Type variables allow for defining a generic form of source code that can work for multiple types. Similar to template metaprogramming in C++, but simpler and cleaner and without any header files.

// from https://youtu.be/BwqeFrlSpuI?t=218
print_number :: (number: $T) {
  // pass number as both int and float,
  // one of them will work out..
  printf("print_number: %d %f\n", number, number);
}

n1: int     = 1;
n2: u8      = 2;
n3: s64     = 3;
n4: float32 = 4;
n5: float64 = 5;

print_number(n1); // 1 0.000000
print_number(n2); // 2 0.000000
print_number(n3); // 3 0.000000
print_number(n4); // 0 4.000000
print_number(n5); // 0 5.000000

Authoritative parameters

For procedures with multiple parameters of the same type variable, use only one dollar sign to identify which parameter is authoritative over the error message. 2

add :: (p: $T, q: T) -> T {
  x := p + q; // does not handle overflow
  return x;
}

n1: u8      = 254;
n2: float32 = 7.63;
n3: u8      = 1;

add(n1, n2); // type mismatch error will state second parameter must match first
add(n1, n3); // ok, types match
toggle example
swap.jai
toggle example
find.jai
toggle example
do_three_times.jai

using with type variables

Variable types will work with using: 3

Vector2 :: struct {
  x: float = 2.0;
  y: float = 2.1;
}
Vector3 :: struct {
  z: float = 3.2;
  y: float = 3.1;
  x: float = 3.0;
}

using_test :: (using a: $T) {
  printf("a.x is %f\n", x);
  printf("a.y is %f\n", y);
}

v2: Vector2;
v3: Vector3;

// works with values or pointers
using_test(v2);  // a.x is 2.0; a.y is 2.1
using_test(^v2);

using_test(v3);  // a.x is 3.0; a.y is 3.1
using_test(^v3);

Baking polymorphs

See #bake to precompile a polymorphic procedure for a specific type.

baked3 := #bake using_test(T = Vector3);

Modifying polymorph types

See #modify to inject one or more procedures for inspecting and reacting to type variables being passed to a polymorphic procedure.

toggle example
satisfies_interface.jai

Modifying polymorphic functions

See #body_text to generate a string for use as source code of the polymorphic procedure.

toggle example
length_body_text.jai

Baking values

Use #bake_values to precompile a regular procedure with specific parameter values:

multiplier :: (a: float, b: float) -> float {
  return a * b;
}

printf("multiplier(%f, %f) = %f\n", 3, 5, multiplier(3, 5));
// multiplier(3, 5) = 15

uniplier :: #bake_values multiplier(b = -9);

printf("uniplier(%f) = %f\n", 3, uniplier(3));
printf("uniplier(%f) = %f\n", 5, uniplier(5));
// uniplier(3) = -27
// uniplier(5) = -45

Auto-baking

Use the auto-baking operator ($$) to ask the compiler to bake functions when specific parameters have values known at compile-time.

toggle example
print_names_and_values_autobake.jai

Implementing map

With polymorphic procedures, higher-order functions like map 4 can be implemented, while retaining the speed and type safety of a compiled language.

toggle example
map_test.jai

  1. what the dollar sign indicates is that this is a type variable which means we don’t know what type it is at declaration time. the type of this variable will be determined when the function is called.
    “Polymorphic Procedures, part 1” YouTube, uploaded by Jonathan Blow, Apr 1, 2015, https://youtu.be/BwqeFrlSpuI?t=228 

  2. the reason that we only use the dollar sign once is that the dollar sign tells us which argument is authoritative over what the type should be..
    “Polymorphic Procedures, part 1” YouTube, uploaded by Jonathan Blow, Apr 1, 2015, https://youtu.be/BwqeFrlSpuI?t=360 

  3. here we’ve got a function called using_test, and we’re using the first parameter. Remember that using let’s us refer to these components; it’s like a this pointer.
    “Polymorphic Procedures, part 1” YouTube, uploaded by Jonathan Blow, Apr 1, 2015, https://youtu.be/BwqeFrlSpuI?t=1624 

  4. In many programming languages, map is the name of a higher-order function that applies a given function to each element of a functor, e.g. a list, returning a list of results in the same order.
    Wikipedia contributors. “Map (higher-order function).” Wikipedia, The Free Encyclopedia, 11 Mar. 2019. Web. 31 Jul. 2019., https://en.wikipedia.org/w/index.php?title=Map_(higher-order_function)&oldid=887181717 

jailang 2019 pixeldroid
https://github.com/pixeldroid/jailang
programming pages theme v0.5.21 (https://github.com/pixeldroid/programming-pages)