Definition
A ColdFusion function is a reusable block of CFML (ColdFusion Markup Language) code that performs a specific task and can return a value. Functions in Adobe ColdFusion and Lucee let you encapsulate logic—such as calculations, formatting, validation, or data transformation—so you can call it from multiple places without duplicating code. You can use both built-in functions (like dateFormat, arrayLen, and reReplace) and user-defined functions (UDFs) that you create yourself, either in standalone CFScript or inside a ColdFusion Component (CFC).
—
How a ColdFusion Function Works
- You define a function with a name, an optional return type, and a list of parameters (arguments).
- The function body contains the logic to run when it’s called.
- It can access local variables and the special arguments scope.
- It can return a value using return (CFScript) or
(tag-based CFML). - You call the function by its name, passing required and optional arguments.
Function Syntax (CFScript vs. Tag-Based)
CFScript (typical for Modern CFML):
/ Standalone UDF /
numeric function add(required numeric a, required numeric b) {
return a + b;
}
writeOutput( add(2, 3) ); // 5
Tag-based CFML:
Key points:
- The arguments scope is an implicit struct containing passed parameters.
- The local scope (often referenced via local or with var-scoped variables) avoids leaking variables outside the function.
- output=”false” (or avoiding direct output in functions) keeps functions pure and easier to test.
—
Types of ColdFusion functions
Built-in Functions
ColdFusion ships with hundreds of built-in functions for strings, arrays, structs, dates, encryption, regex, and more. Examples:
- String: ucase(), trim(), replace(), reReplace()
- Date/Time: dateFormat(), now(), dateDiff()
- Array/Struct: arrayLen(), arrayMap(), structKeyExists()
- Security/Hashing: hash(), encrypt(), isValid()
User-Defined Functions (UDFs)
Your own functions, created to encapsulate Business logic or utilities. They can live:
- Inline in a CFML page (quick helpers)
- In components (CFCs) as methods—recommended for organization and reuse
- In shared libraries or modules across an application
Component Methods (CFC Methods)
Functions inside CFCs can have access modifiers (public, private, package, remote) and can be exposed as API endpoints (remote) if needed.
Example (CFC method in CFScript):
component displayname=”MathService” output=”false” hint=”Math utilities” {
public numeric function add(required numeric a, required numeric b) {
return a + b;
}
}
—
Parameters, Return Types, and Scoping
Parameters and Type Checking
You can declare parameter types to catch errors earlier and improve readability.
- Positional arguments: add(1, 2)
- Named arguments: add(a=1, b=2)
- Defaults: function greet(string name=”Guest”) { … }
- Required: required keyword (CFScript) or required=”true” (
)
Return Types
Declaring a return type (numeric, string, struct, array, query, any) provides validation and documentation.
Example:
public string function formatPrice(required numeric amount) {
return “$” & numberFormat(amount, “9,999.99”);
}
Scopes Inside Functions
- local: Variables defined in a function should be local or var-scoped to prevent scope leakage.
- arguments: Parameters arrive here as a struct.
- variables/this: In CFCs, variables is private to the component; this exposes public members. Inside functions, prefer local and arguments for clarity.
—
Real-World Use Case: Order Total Calculator
Suppose you run an E-commerce site and need a consistent way to compute order totals including taxes and optional discounts. A CFC method keeps this logic centralized.
component displayname=”OrderService” output=”false” hint=”Order-related utilities” {
/**
* Calculates the order total.
* @cart An array of structs: each item has price and quantity.
* @taxRate A decimal like 0.07 for 7%.
* @coupon Optional struct with type and value (e.g., {type="percent", value=10}).
*/
public numeric function calculateOrderTotal(
required array cart,
required numeric taxRate,
struct coupon
) output=false {
// Ensure local scoping for safety
var subtotal = 0.0;
var item = {};
var discount = 0.0;
var taxed = 0.0;
// Sum line items
for (item in arguments.cart) {
// Expecting item = {price=..., quantity=...}
subtotal += (item.price * item.quantity);
}
// Apply coupon if provided
if (structKeyExists(arguments, "coupon") and isStruct(arguments.coupon)) {
if (arguments.coupon.type EQ "percent") {
discount = subtotal * (arguments.coupon.value / 100);
} else if (arguments.coupon.type EQ "amount") {
discount = arguments.coupon.value;
}
}
// Do not go negative
subtotal = max(0, subtotal - discount);
// Apply tax
taxed = subtotal + (subtotal * arguments.taxRate);
// Round to two decimals
return inputBaseN( round(taxed * 100), 10 ) / 100;
}
}
Usage:
orderService = new path.to.OrderService();
cart = [
{price=29.99, quantity=2},
{price=15.00, quantity=1}
];
coupon = {type=”percent”, value=10}; // 10% off
total = orderService.calculateOrderTotal(cart=cart, taxRate=0.07, coupon=coupon);
writeOutput( “Order total: ” & total );
Benefits:
- Single source of truth for pricing logic.
- Easy to test and update.
- Reusable in pages, Scheduled tasks, or remote APIs.
—
Advanced Concepts
Closures and Higher-Order Functions
Modern ColdFusion (Adobe CF 11+ and Lucee) supports closures (anonymous functions), allowing arrayMap, arrayFilter, etc.
numbers = [1,2,3,4];
squares = arrayMap(numbers, function(n){ return n*n; });
This makes UDFs even more flexible and promotes Functional programming patterns.
Remote Functions (API Endpoints)
By marking a CFC method as remote, you can invoke it over HTTP/SOAP/AMF (depending on Configuration), enabling lightweight APIs.
remote struct function ping() returnformat=”json” {
return {status=”ok”, ts=now()};
}
Note: Secure such methods with Authentication and input validation.
—
Common Use Cases for ColdFusion functions
- Data formatting: dates, prices, strings, and localization
- Validation: email addresses, phone numbers, business rules
- Transformations: mapping arrays, merging structs, parsing JSON/XML
- Database helpers: query sanitation, record transformations
- API integrations: signing requests, building payloads
- Utility libraries: logging, Configuration loaders, caching helpers
—
Best practices
- Use CFScript for new code: It’s concise and familiar to many developers, while tag-based style remains fully supported.
- Prefer CFC methods for organization: Group related functions in components (e.g., UserService, OrderService).
- Declare types and required parameters: Improves reliability and self-documentation.
- Keep functions small and focused: Each function should do one thing well.
- Return values, avoid side effects: Functions that write output or touch global scopes are harder to test.
- Scope variables locally: Use local or var to prevent scope bleed.
- Handle errors with try/catch: Add helpful messages and rethrow as needed.
- Document with hint and comments: Clarify intent, parameters, and return values.
- Test and log: Build simple unit tests for complex functions; use logging for Troubleshooting.
- Use named arguments for clarity: Especially with many optional parameters.
—
Pros and cons
Pros:
- Reusability and maintainability
- Consistent input validation and output formatting
- Easy testing and Refactoring
- Strong standard library of built-in functions
Cons:
- Overly complex functions become hard to maintain
- Scope mismanagement can cause subtle bugs
- Excessive I/O or output inside functions hurts testability and Performance
—
Key Points
- A ColdFusion function is a reusable, self-contained CFML routine that can accept arguments and return a value.
- Use built-in functions for common tasks; write UDFs for domain-specific logic.
- Organize functions in CFCs with appropriate access modifiers for Encapsulation.
- Leverage types, required flags, and named arguments to make contracts explicit.
- Keep functions pure when possible—no unintended output or global state changes.
—
Syntax Quick reference
CFScript UDF
returnType function name([modifiers] [required] type param = default, …) [attributes] {
// use local/var-scoped variables
return value;
}
Example:
public string function greet(string name=”Guest”) output=false {
return “Hello, ” & name & “!”;
}
Tag-Based
—
Performance and Memory Tips
- Avoid heavy string concatenation in loops; consider StringBuilder patterns or list functions where appropriate.
- Cache results for expensive, repeatable computations when feasible.
- Prefer local variables over global scope access; it’s faster and safer.
- Validate inputs early to fail fast and avoid unnecessary work.
—
Interoperability: Adobe ColdFusion and Lucee
- Most function syntax is compatible between Adobe ColdFusion and Lucee CFML engines.
- Some built-in functions and attributes may differ slightly. Check engine-specific docs when using advanced Features.
- Closures, array/struct higher-order functions, and JSON handling are widely supported, but verify versions.
—
Security Considerations
- Validate and sanitize inputs inside functions that process user data.
- Avoid dynamic evaluation of strings unless absolutely necessary.
- When exposing remote functions, enforce Authentication and authorization.
- Use isValid(), ESAPI libraries, and built-in encoders (encodeForHTML, encodeForURL) as appropriate.
—
FAQ
What’s the difference between a UDF and a CFC method?
A UDF is a user-defined function that can exist standalone in a CFML page or script file. A CFC method is a function defined inside a ColdFusion Component, enabling Encapsulation, access control (public/private/package/remote), and easier reuse across your application.
Should I use CFScript or tag-based syntax for functions?
Both are valid. CFScript is concise and familiar to many developers, and it tends to be preferred for new code. Tag-based syntax is still supported and can be helpful in teams with a history of tag-style CFML. You can mix styles as needed.
How do I prevent variable scope leakage in my functions?
Declare local variables with var (in older code) or use the local scope explicitly. In modern CF, variables declared inside a function are local by default, but using var or local helps clarity and Backward compatibility.
Can ColdFusion functions be passed as arguments (closures)?
Yes. Modern CFML supports closures and higher-order functions. You can pass anonymous functions to arrayMap, arrayFilter, and similar functions, or store function references and invoke them later.
How do I expose a function as a web API?
Define the function inside a CFC with access=”remote” (or remote in CFScript). Optionally set returnformat=”json” and ensure security (authentication/authorization). Then invoke it over HTTP according to your server’s configuration.
