Functions, functums, functanoids and procedures

Quxlang introduces some new concepts called functums and functanoids. These are not entirely new concepts per se, as C++ has similar concepts. Lets start however with some definitions.

A function is the thing you declare in your code. In some sense, the code you write is the function.

If we declare multiple different functions with the same name but which take different arguments, for example, ::sqrt FUNCTION(%val F64):F64 {...} and ::sqrt FUNCTION(%val I64):I64 {...}, these two declarations represent different functions, however, they are both part of the same functum. In C++ terminology, a Quxlang functum would be roughly analogous to a C++ “function overload set”. Formally, a functum is a set of one or more functions which share the same name.

The final introduction in our family of funcs is the functanoid. A functanoid is a function which has become concrete with regard to a specific set of types. More specifically, a single function can have multiple corresponding functanoids depending on how the function is instantiated. For example, given a temploidic function like ::foo FUNCTION(%arg MUT& T(t1)) { arg += 1; }, there are multiple possible functanoids, for example, by passing a 32 or 64 bit integer reference as a parameter, it would generate two functanoids, namely ::foo@[MUT& T(t1)]@(MUT &I64) and ::foo@[MUT& T(t1)]@(MUT &I32). Note that @[...] is used to select a function from a functum, and @(...) is used to instantiate a function with concrete arguments (maybe I will reverse this later, I am still considering this syntax). It is not generally required to perform selection prior to invoking the functum with a call expression, as selection and instantiation are automatic based on the types of the arguments.

A procedure is different from a functanoid. A functanoid operates on the abstract machine, while a procedure is a region of generated machine code. A given functanoid can have multiple associated procedures for a given target. For example, supposing we have a complicated functanoid that adds several members of two arrays together, it might be beneficial to use SSE4 and AVX512 instructions, however not all x64 CPUs support these instructions. The compiler can generate multiple different procedures for the same functanoid, then the Quxlang runtime can link in the fastest procedure which is capable of executing on the CPU at runtime during dynamic loading at program startup for the given functanoid.

Hopefully this clarifies the differences between functions, functums, functanoids, and procedures!

Leave a comment