Arguments are how data gets into a function. ColdFusion's argument handling has a few genuinely unusual pieces compared to most languages — the Arguments scope behaves like both an array and a structure at once, and whether a change inside the function affects the caller's original variable depends on the data type being passed.
Learning Objectives
After completing this lesson, you'll be able to:
- Declare arguments with cfargument's type, required, and default attributes.
- Access arguments by position or by name through the Arguments scope.
- Pass a whole struct of named arguments at once with argumentCollection.
- Explain the difference between pass-by-value and pass-by-reference in ColdFusion.
Declaring Arguments
cfargument Attributes
| Attribute | Purpose |
|---|---|
| name | The argument's name — required |
| type | Data type: any, string, numeric, boolean, array, struct, query, date, and more |
| required | Whether the caller must supply this argument |
| default | A fallback value used only when the argument isn't required and wasn't passed |
| hint | A description shown when introspecting the function |
The Arguments Scope: Array and Struct at Once
Inside a function, every argument is also reachable as arguments[1], arguments[2], and so on, in the order they were declared — useful for functions that accept a variable number of values.
isArray(arguments) always returns false even though it can be indexed like one — the Arguments scope is its own special type, not literally an array.
Passing a Struct of Named Arguments: argumentCollection
When the arguments to pass already exist as a struct (built dynamically, or coming from another function), argumentCollection passes them all at once instead of listing each one out.
The struct's keys must match the function's argument names.
Pass-by-Value vs Pass-by-Reference
Simple types — strings, numbers, booleans, dates — are passed by value, so changing the argument inside the function has no effect on the caller's original variable. Structs, queries, and CFC instances are passed by reference, so a change inside the function does change the original.
Arrays are pass-by-value by default too, unless this.passArrayByReference = true is set in Application.cfc (ColdFusion 2021+).
Required Arguments Don't Have to Come First
The common convention is to list required arguments before optional ones — but it's only a convention. Since named-argument calls match by name, not position, a required argument can come after optional ones when it makes the function's signature read more naturally, as long as every call site uses named arguments.
Common Beginner Mistakes
Expecting a number or string argument to change for the caller after the function runs
Simple types are passed by value — the function gets a copy. Only structs, queries, and CFC instances are passed by reference and reflect changes back to the caller.
Passing positional arguments out of order
myFunc(b, a) doesn't magically match by name — positional arguments fill parameters strictly in declaration order. Use named arguments (myFunc(a = a, b = b)) whenever call-site order might get confusing.
Assuming isArray(arguments) is true
It's false — the Arguments scope behaves like an array for indexing purposes, but its actual type is neither an array nor a struct.
Best Practices
- Always declare a type on cfargument / typed CFScript parameters — it documents intent and catches mistakes earlier.
- Use default values for genuinely optional parameters instead of checking structKeyExists(arguments, "x") inside the function body.
- Use named arguments at the call site for functions with more than two or three parameters — it's self-documenting and order-independent.
Interview Questions
What does argumentCollection do?
It passes a whole struct as a function's arguments in one call, matching struct keys to argument names, instead of listing each argument individually.
Which ColdFusion data types are passed by reference?
Structs, queries, and CFC/object instances. Simple types (strings, numbers, booleans, dates) are passed by value, and arrays are pass-by-value by default unless passArrayByReference is enabled.
Do required arguments have to be declared before optional ones?
No — that's just a convention. Since named-argument calls match by name rather than position, a required argument can be declared after optional ones.
Summary
In this lesson, you covered cfargument's attributes, the Arguments scope's dual array/struct behavior, argumentCollection for passing a struct of named arguments at once, and the pass-by-value vs pass-by-reference distinction that trips up almost everyone at least once.
What's Next?
The next lesson covers return values — the return statement, <cfreturn>, returnType, and how to return more than one value from a single function.