High order functions in Pascal

Hello. I am Timur. I am machine (hydraulic presses) repairer with some programming skils (basic c++ for the moment).

Does Pascal support higher-order functions? Let’s say I want to change the behavior of a character. in c++, I can pass either a pointer to a function or a lambda or std::function inside a class and thus I pass a new behavior program. I do not know if there is a similar thing in the Pascal language.

There is example on cpp (the one language I more-less know for the moment, but pascal looks interesting).

#include
#include
#include

struct fine_grinder
{
void run(std::string coffee_beans)
{
std::cout << "cool! fine grinder works with " << coffee_beans << std::endl;
}
};

struct bad_grinder
{
void run(std::string coffee_beans)
{
std::cout << "baaad grinder works with " << coffee_beans << std::endl;
}
};

// templated function that will use any grinder
template void grinder_func(std::string coffee_beans)
{
Grinder_type grinder;
grinder.run(coffee_beans);
}

struct Cofemachine
{

void grind_coffee(std::string coffee_beans)
{
    grinder_(coffee_beans);
}

void set_grinder(std::reference_wrapper<void(std::string)> grinder)
{
    grinder_ = grinder;
}

std::reference_wrapper<void(std::string)> grinder_ = grinder_func<bad_grinder>;

};

int main()
{

Cofemachine mycoffemaker;
mycoffemaker.grind_coffee(std::string{"coffee_beans coffee"});

// here we pass into mycoffemaker the grinder_function filled with fine_grinder object
mycoffemaker.set_grinder(grinder_func<fine_grinder>);

mycoffemaker.grind_coffee(std::string{"coffee_beans coffee"});

return EXIT_SUCCESS;

}

Hello! And yes :slight_smile:

  1. The base concept to pass an address of a function (global routine, or a method of some class) is documented as “Callbacks (aka events, aka pointers to functions, aka procedural variables)” on Modern Object Pascal Introduction for Programmers | Castle Game Engine .

    This is supported in both FPC and Delphi since always :slight_smile:

  2. To go one step further, if you’re looking specifically for lambdas / anonymous functions, that is also supported: Anonymous Methods in Delphi - RAD Studio . This is a link to Delphi docs, which supports them out-of-the-box.

    My simplest example code using them is on https://github.com/michaliskambi/modern-pascal-introduction/blob/master/code-samples/anonymous_functions.dpr .

    The FPC (open-source Pascal compiler) also supports them, with compatible syntax, albeit it isn’t available yet in the latest FPC stable release (3.2.2). If you’re interested specifically in the anonymous functions + FPC, you can get latest (unstable) FPC using e.g. fpcupdeluxe ( fpcupdeluxe | Manual | Castle Game Engine ).

  3. Finally, your example in C++ adds a twist to this: The function you pass around is a template.

    FPC does not support it, unfortunately. You cannot take a pointer from a specialization of a generic function, it seems, at least for now. You’d have to wrap each possibility in non-generic function.

    Delphi does support it somewhat. It only supports generic methods (not global routines). And Delphi puts more constraints on what you can do with things inside the generic (FPC is more like C++ “templates”, i.e. the correctness is checked at specialization; Delphi is more like “generics” i.e. the correctness must be already good at generic definition).

    You can see my experiments with comments in https://github.com/michaliskambi/modern-pascal-introduction/blob/master/code-samples/callback_from_generic_function.dpr , https://github.com/michaliskambi/modern-pascal-introduction/blob/master/code-samples/callback_from_generic_method.dpr .