Support keyword arguments in @formula function calls#341
Open
sdwfrost wants to merge 1 commit intoJuliaStats:masterfrom
Open
Support keyword arguments in @formula function calls#341sdwfrost wants to merge 1 commit intoJuliaStats:masterfrom
sdwfrost wants to merge 1 commit intoJuliaStats:masterfrom
Conversation
Add parse! methods for :kw and :parameters Expr nodes so that
keyword arguments in function calls pass through instead of
erroring. This enables syntax like:
@formula(y ~ s(x; k=10, bs=:cr))
@formula(y ~ s(x, k=10, bs=:cr))
Kwargs are preserved in FunctionTerm.exorig and can be extracted
by downstream packages via the new kwarg_exprs() and has_kwargs()
helper functions.
This is fully backward compatible — existing formulas without
kwargs work identically. The 9 pre-existing broken tests are
unchanged.
Motivation: packages like GAM.jl need to pass configuration
options (basis type, dimension, etc.) to smooth term constructors
within formulas. Without this change, they must define custom
formula macros (@gam_formula) instead of using @formula.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Allow keyword arguments in
@formulafunction calls, enabling syntax like:Currently, both forms crash in
parse!because:kwand:parametersAST nodeshit
check_call()which requireshead == :call. This PR adds handling for thesenodes so they pass through as quoted literals in
FunctionTerm.args.Motivation
Downstream packages that extend
@formulawith custom function terms (e.g., GAMsmooth specifications like
s(x; k=10, bs=:cr)) need keyword arguments to configurethose terms. Without this change, users must use a separate macro (
@gam_formula) orencode configuration as positional arguments (
cr(x, 10)), which is less readableand less discoverable.
This is a common need — R's formula interface supports
s(x, k=10, bs="cr")in mgcv,and Julia's native call syntax already supports kwargs. The parser just needs to not
crash on them.
Changes
src/formula.jlparse!handling for:kwand:parametersExpr nodes — quotesthem so they survive as literals in
FunctionTerm.argsparse!(::QuoteNode, ...)method for quoted symbols (e.g.,:cr)src/terms.jlkwarg_exprs(ft::FunctionTerm)— extract keyword argument expressions fromFunctionTerm.exorigfor downstream usehas_kwargs(ft::FunctionTerm)— convenience predicatesrc/StatsModels.jlkwarg_exprs,has_kwargstest/formula.jlsymbol values, numeric values, no-kwargs backward compatibility
Design
The approach is deliberately minimal and backward-compatible:
No struct changes —
FunctionTermalready storesexorig(the original Expr),which naturally contains kwargs. We just need
parse!to not crash beforeFunctionTermis constructed.Kwargs are opaque to StatsModels — they pass through as quoted expressions.
StatsModels does not interpret them. Downstream packages inspect them in their
apply_schemaimplementations viakwarg_exprs(ft).Full backward compatibility — existing formulas produce identical results.
All 965 existing tests pass unchanged.
Test Results
Example Usage (downstream package)