FormuIas - Is it possible to call a user-defined function recursively in Power Apps?

When building user-defined functions, an interesting snippet that's highlighted in the Power Apps blog is the ability to call user-defined functions recursively.


The example shown runs in the Power FX console. It shows a list of employees with their managers. By calling a user-defined function recursively, it's possible to count the number of employees who are hierarchically beneath each employee.


The ability to call user-defined functions recursively is great for these use case scenarios where we want traverse tree structures or scenarios where we need to generate sequences based on computations.    
 
Now that user-defined functions have entered the experimental phase, is it possible to recreate this example in Power Apps? This post finds out.

Building a data source for the recursive user-defined function demonstration
The Power FX example is based on a named formula that returns a table of employees (shown below). Note that in practice, this could be a collection or a live data source.

// table of employees with manager (Named Formula) 
Employees =
Table(
{ Employee: "Charles" },
{ Employee: "Sandra", Manager: "Charles" },
{ Employee: "John", Manager: "Sandra" },
{ Employee: "Tina", Manager: "Sandra" },
{ Employee: "Julia", Manager: "Charles" },
{ Employee: "Fred", Manager: "Julia" },
{ Employee: "Kim", Manager: "Sandra" },
{ Employee: "Jane", Manager: "Fred" }
);

To make more sense of this, the chart below illustrates how this data structure looks hierarchically.



Theory - How to build a recursive user-defined function

In the Power FX demo, the user-defined function that counts the employees beneath a specific employee looks like this:

// user defined function (UDF) to recursively walk the organization and tally reports 
TotalReports(ThisEmployee: String): Number =
Sum(Filter(Employees,
Manager = ThisEmployee
),
1 + TotalReports(Employee)
);

This function takes the name of an employee as an input parameter. It filters the Employees table to return only those records where the manager matches the name that's been passed to the function. It then counts the employee and adds a recursive call to the function to add the number of child reports for the employee.

To clarify this a little further, the pertinent logic exists in the call to Sum.
Sum(Filter(Employees, 
Manager = ThisEmployee
),
1 + TotalReports(Employee)
);
The Sum function takes the filtered table as an input. For each row in the input table, the function adds 1 and adds the number of child reports by calling the TotalReports function again.

Attempting to build a recursive user-defined function in Power Apps

Let's now try to implement this recursive function in Power Apps. To do this, we navigate to the 'Formulas' section in the App node and enter the formula. 

Unfortunately, we very soon see that the Power Apps implementation of user-defined functions doesn't support recursion. When we attempt to create our user-defined function, we receive the error "This rule creates a circular reference between properties, which is not allowed. A property cannot reference itself or other properties affected by its value.".


Therefore, this error stops our experiment and we cannot continue further with this.

However if this worked, we could theoretically define a named formula that returns the Employee table and adds a "Total Reports" column.  

// evaluate UDF for each employee and add a new column to the table 
EmployeesWithReports =
AddColumns(Employees,
"Total Reports",
TotalReports(Employee)
);

Conclusion

According to the Power FX spec, it should be possible to call user-defined functions recursively. If we attempt to do this with the recent experimental implementation of user-defined functions in Power Apps, we receive a circular reference error. Hopefully, the ability to call user-defined functions recursively will be added in a future update.

Related posts

Formulas - A beginners guide on how to create and call user-defined functions (UDFs)
January 28, 2024
Formula - How to add a button that converts degrees Centigrade to Fahrenheit and vice versa
May 08, 2023
Formula - How to convert a single delimited string to rows and columns
April 05, 2023
Data - How to group data in a gallery and calculate sums
January 20, 2023
Formula - How to calculate compound interest
November 24, 2022
Utilities - The best way to peform OCR on images of Power Apps Formulas
October 11, 2022
Example - How to use a drop down control to convert currencies
September 27, 2022
Formula - How to parse JSON in Power Apps- 4 examples
September 15, 2022
Data - How to get a row by ordinal number
April 28, 2022
Formula - What to do when the If statement doesn't work?
December 17, 2021
Formula - Boolean And / Or operators - What is the order of precedence?
December 16, 2021
Controls - How to set the data source of a Combo Box to a comma separated string
November 16, 2021
Numbers - 10 examples of how to round numbers
August 18, 2021
Formula - Difference between round, square, and curly brackets
July 20, 2021
Top 3 highlights of upcoming enhancements to the Power Apps language (Power FX)
May 26, 2021
Email - Sending email attachments with the Office 365 Outlook connector
March 30, 2021
Formula - What to try when numbers don't format correctly
March 24, 2021
Controls - How to convert HTML to Text
March 23, 2021
Formulas - how to return all days between two dates
March 15, 2021
Formula - How to create comma separated (CSV) list of items
February 25, 2021
Formula - How to use the IF and Switch functions - 3 common examples
February 12, 2021
Location - Finding the closest location and and sorting records by distance, based on the current location of the user
January 24, 2021
Formulas - How to cope with weekends and public holidays in date calculations
January 21, 2021