Search code examples
higher-order-functionsrascal

Rascal: Can a Function return a Function


The Rascal documentation has an example of a function that takes a function as an argument:

int f(int x, int (int) multi){ return multi(x); }

Conversely, what is the syntax for a function that returns a function?

I couldn't find an example and tried things along the line:

(int (int)) f() {return (int y) {return y;}}

but got syntax errors in the repl.


Solution

  • Here is an example:

    int two(int n) = 2 * n;
    int(int) g() = two;
    

    Function two multiplies by 2 and g returns the function two. Observe that the return type of g is int(int), a type describing a function which returns an int and has one int argument.

    A similar effect can be achieved by an inline definition:

    int(int) g() = int(int n) { return 2 * n; };
    

    You can also use this same notation inside other functions. For instance, you could create a function which multiplies two numbers:

    int mult(int n, int m) = n * m;
    

    If you use it, you would get what you would expect:

    rascal>mult(3,4);
    int: 12
    

    You can instead return a function that essentially partially applies this function as follows:

    int(int) multBy(int n) { 
        return int(int m) { 
            return mult(n,m); 
        }; 
    }
    int (int) (int)
    

    So, this returns a function that takes an int and returns an int (int), i.e., a function that takes an int and returns an int. You can then use it as so:

    rascal>multBy3 = multBy(3);
    int (int)
    
    rascal>multBy3(4);
    int: 12
    

    You can find more examples in some of our (many) files with tests:

    • lang::rascal::tests::basic::Functions
    • lang::rascal::tests::functionality::FunctionComposition

    Thanks for your question, we have more documentation to do!