I am trying to understand the intended usage of procedures in Odin’s standard library that take predicates as parameters.
In practice, I am running into a limitation where many of these procedures are difficult or impossible to use for common, real-world tasks. This applies in particular to procedures that expect a predicate procedure as an argument.
In the vast majority of cases, such predicates need to rely on dynamic runtime data (for example, user input, runtime state, or configuration values). This is a very common and fairly standard requirement for search, filtering, and matching operations.
As far as I understand, Odin does not support closures, so predicate procedures cannot capture external state. Because of this, I expected the standard library to provide alternative variants of these procedures that allow passing explicit user data or context into the predicate.
For example, consider slice.linear_search_proc. I expected something conceptually like this:
linear_search_proc :: proc(
array : $A/[]$T,
user_data : $U,
f : proc(array_element: T, user_data: U) -> bool
) -> (index: int, found: bool) {
for x, i in array {
if f(x, user_data) {
return i, true
}
}
return -1, false
}
Without closures or an explicit user_data parameter, I do not see how predicates are supposed to be used when the condition depends on runtime data.
I am aware that context.user_ptr can be used as a workaround to pass external state. However, this feels like a rather inelegant and fragile solution for what appears to be a very common and generic problem.
So my questions are:
What is the intended pattern for using these standard library procedures that take predicates when the predicate depends on runtime data?
Am I missing some idiomatic approach or language feature related to this use case?
Is the absence of variants that accept user data a deliberate design decision, or is this part of the core standard library still evolving and expected to be extended?