Method-Based LAMBDA UDTs

This post details the first LAMBDA UDT scheme. This version is no longer best practice due to inefficient field access that counted against the calculation limits. However, I've opted to archive the old article as a blog post. See the main LAMBDA UDT page for up-to-date information.

LAMBDA UDTs use LAMBDA to define a custom data type. They emulate the object-oriented programming paradigm, where UDTs consist of fields and methods. These types take the form:

lambda(m,m(a,b...))

Data is encapsulated inside a number of user-defined fields, listed as a,b... in the expression above. These fields can contain any data types, including ranges, arrays, and lambda terms.
In other words, they allow the user to define collections of different kinds of data that can be used as both input and output for user-defined functions.

UDTs must be instantiated and provided data for each field to be operated on. LAMBDA UDTs can be instantiated manually or via constructor:

=let(
udt,lambda(a,b...,
lambda(m,m(a,b...))
),
udt(a,b...)
)

Note that the above formula only shows instantiation. The output will be a lambda term which cannot be output to a cell.

To access data stored within a LAMBDA UDT, you must define lambda terms, or lambda functions, to interface with it. These terms, known as methods, take each field of the UDT as arguments. All fields of a LAMBDA UDT are private and must be accessed through methods. For example, if we want to implement a pair structure, where the UDT stores two associated fields of any type, we could implement methods to access the first and second elements like so:

=let(
pair,lambda(a,b,
lambda(m,m(a,b))
),
first,lambda(a,b,a),
second,lambda(a,b,b),
pair("foo","bar")(first)
)

This formula works by accepting a LAMBDA function, known as the method, as input. The method then accesses the data within the UDT. Note that all methods must be lambda terms that accept all fields of the UDT as arguments. Performing the β-reduction for this formula, we start by resolving the pair instantiation:


lambda(m,m("foo","bar"))(first)

Then, we resolve the m term:

first("foo","bar")

Which then resolves to "foo".

Calculation limits represent a major limitation to LAMBDA UDTs, as they are heavily LAMBDA-intensive in nature and can quickly hit the recursion limit. LAMBDA UDTs also require user-defined interfaces in order to work properly.