
1. Syntax Differences Between ACF and Standard Custom Functions
In this chapter, we will explore some key syntax differences that are important to be aware of when coding in the ACF language.
1.1. The Use of Commas and Semicolons ↑
In standard custom functions, semicolons are typically used to separate parameters in function calls. However, in ACF, we utilize commas for this purpose. Semicolons, on the other hand, serve as statement terminators. This approach enhances code readability, distinguishing between parameter separators and statement terminators. It's worth noting that either commas or periods can be used as decimal separators for numbers. SQL queries in ACF use periods as decimal separators.
In ACF, each statement must be terminated by a semicolon. Exceptions to this are flow control statements or terminators. Like if
, else
, elseif
, endif
, for
, endfor
, While
, end while
, repeat
, until
, Function
and end
. Look at some of the programming examples to be more familiar with the syntax.
1.2. Conditional expressions ↑
In version 1.7.0.15, we introduced conditional expressions, much like the standard calculations in FileMaker. However, the if
was already used in structural if then else endif
so we had to use something else. Adopting the syntax of conditional expressions in PHP, C, C++ and some other languages was an easy choice. Now this follows this syntax:
variable = <boolean expression> ? <true calculation> : <false calculation> ;
Examples:
int workHours = day >= 6 ? 0.0 : 7.5;
deliveryAddress = orders::deliveryAddress == "" ?
customer::deliveryAddr :
orders::deliveryAddress;
Whether to use conditional expressions or structural if...endif
structures is up to the programmer to decide what fits the actual case. It can be efficient in some cases, but overuse can make the source code less readable.
If the conditional expression is part of another expression, it might be needed to enclose it in parentheses. Like this:
print "WorkHours: " + (day >= 6 ? 0.0 : 7.5) + " hours";
Inline case:
Unlike standard custom functions, ACF does not support inline case
constructs. This design choice aims to improve the legibility of the source code. Instead, we recommend using if-then-elseif-else-endif
or the case...end case
structure, which can be nested to any level. These structures can be combined with loop constructs (for-endfor
, while-endwhile
, repeat-until
). For FileMaker calculations in ACF, you can employ the "@" symbol on each side of the expression. The syntax within these constructs remains consistent with FileMaker calculations.
1.3. Declaration of Variables and Parameters ↑
In standard custom functions and calculations, variables are always auto-declared. An undeclared variable is treated as non-existent, resulting in a return of a blank or zero value if accessed. However, in ACF, both parameters for function definitions and global or local variables must be explicitly declared. Declarations can be integrated into assignments or declared separately before usage. Importantly, declarations should not be placed inside "if-endif" or loop constructs; they must be declared at the function level. Function return values are typically auto-declared based on the type of the returned expression. In some cases, particularly with recursive functions, explicit declaration of the return type is necessary. This is achieved by declaring the function name as if it were a variable. Undeclared variables will trigger a compiler error, while assignments can auto-declare variables but prompt a warning from the compiler.
In FileMaker, data types include Text, Numbers, Dates, TimeStamps, Time, and Containers (field only). ACF introduces String as the text type, and it offers int, long, float, and double as number types. Date, TimeStamp, and Time data types remain consistent with FileMaker. However, Containers are not available in this version of the plugin. Select the data type that aligns with your specific use case: use int or long for whole numbers, and opt for float or double for numbers with decimal values. Strings in ACF can be up to 2GB in length.
In FileMaker, global variables are declared when used with double $
signs (e.g., $$MyVariable
). In ACF, global variables are declared like local variables but are positioned outside functions. Global variables are not initialized with any values, so they must be assigned a value before use. They can be accessed by any other function within the current source file only. Unlike FileMaker, ACF does not have a global level shared across all ACF libraries; for such a purpose, you can use "$$" variables.
Single "$" variables in FileMaker are local to the currently executing script, and they lose their value when the script ends. In ACF, local variables are declared within functions, and they lose their value when the function returns.
1.4. Boolean Operators and Data Types ↑
In standard FileMaker, there isn't an explicit boolean data type. Instead, any data type can be treated as a boolean. This means that a non-zero number or a non-empty text is considered true
, while a zero value or an empty string is considered false
. In ACF, we introduce a dedicated variable type known as bool
. This type can only hold values of true
or false
. You cannot use any other data type as a boolean. For instance, to check if an integer variable i
is true or false in ACF, you would write i != 0
.
In standard FileMaker, the equality operator is represented as =
, whereas in ACF, we use ==
. In standard FileMaker, the "not equal to" operator is ≠
, while in ACF, we support both ≠
and !=
, similar to languages like C, PHP, or JavaScript. In ACF, a single =
is used as an assignment operator, distinct from comparison.
Standard FileMaker utilizes the and
and or
operators in boolean expressions. In ACF, we employ &&
and ||
for the same purpose.
The strict datatype in ACF serves to enhance the compiler's ability to rigorously check expressions. When errors in an expression lead to type mismatches, it is more beneficial to receive an error message than to potentially overlook a flawed expression.
1.5. Function Return Values ↑
In standard custom functions, the value of the calculation is automatically returned. In ACF, it is imperative to explicitly specify what to return using the "return" statement. A function can have multiple "return" statements, indicating that no code beyond the "return" statement will be executed within that function. If no "return" statement is present, an empty value will be returned. When using multiple "return" statements, the type of expression should be consistent across all "return" statements. For example, if one "return" statement returns a string, all other "return" statements in that function should also return strings.
1.6. The Array Type ↑
Standard custom functions in FileMaker lack built-in support for arrays. Repeated fields and variables are the closest alternatives for managing multiple values. In contrast, ACF introduces a comprehensive array type. All data types in ACF can be declared as arrays, utilizing square brackets to specify the array index. If the left side of an assignment includes empty square brackets, a new index is added to the array.
FileMaker supports multiline variables, where each line in the text corresponds to a numbered value. ACF preserves this functionality with the "getValue" function. ACF arrays are effectively employed with functions like "explode" and "implode," facilitating the conversion of CSV-formatted data into arrays and vice versa. This proves particularly useful when handling SQL results and import/export operations.
1.7. Managing Multiple Functions in the Same File ↑
In FileMaker, custom functions can be managed under "Manage/Custom Functions," with each function having its separate editor. ACF adopts a different approach. A "Function" statement marks the start of a function, followed by a list of parameters enclosed in parentheses. Each parameter must be prefixed with its data type. The function concludes with the "end" statement.
The ACF file begins with a "Package" statement that specifies the package name. This step is necessary when working with multiple packages in the plugin to determine which package is replaced when reloaded or recompiled. Although ACF supports functions with the same name across several packages, it's generally not recommended. Having multiple packages implement a function with the same name can make it challenging to identify which version of the function is called from FileMaker.
1.8. Calling functions convention ↑
In Standard custom functions, other functions can be called just by their name. This is also true for ACF function called from inside the functions. From Filemaker calculations, there is two ways to call ACF functions. Either by ACF_Run("FunctionName"; Parameter1;Parameter2;....)
, or if the ACF function is given a unique FunctionID, using the FunctionID statement, they can be called using ACFU_FunctionName(Parameter1; parameter2; ....)
. The Prefix ACFU_
is assigned in order to avoid naming conflicts with other standard functions. From the ACF functions, FileMaker standard custom functions can be called using the @-sign on each side of the function call. Alternatively, using the eval
function. For multiline FileMaker calculations, you can use double @ signs on each side.
We hope this clears up some of the differences between standard custom functions and ACF.