# Extending @formula syntax is difficult to understand

**URL:** <https://discourse.julialang.org/t/extending-formula-syntax-is-difficult-to-understand/99326>\
**Category:** General Usage\
**Tags:** question, package\
**Created:** [May 24, 2023, 12:50pm UTC](https://discourse.julialang.org/t/extending-formula-syntax-is-difficult-to-understand/99326 "2023-05-24T12:50:34Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![xuanquansheng](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xuanquansheng/32/32400_2.png) [@xuanquansheng](https://discourse.julialang.org/u/xuanquansheng)\
**Post date:** [May 24, 2023, 12:50pm UTC](https://discourse.julialang.org/t/extending-formula-syntax-is-difficult-to-understand/99326/1 "2023-05-24T12:50:34Z")

</div>

Extending [@formula](https://github.com/formula) syntax in [StatsModels.jl](https://github.com/JuliaStats/StatsModels.jl) is difficult to understand.  
I read the examples of `ploy` in the official documentation, but I feel that the comments are not detailed enough, and I still don’t quite understand.  
For example, why define `StatsModels.apply_schema` , and after defining it, how is it called in `f = apply_schema(f, schema(data))` ? Can you give a detailed and clear procedure?

---

<div class="post-metadata">

**Author:** ![dave.f.kleinschmidt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dave.f.kleinschmidt/32/55_2.png) [@dave.f.kleinschmidt](https://discourse.julialang.org/u/dave.f.kleinschmidt)\
**Post date:** [May 24, 2023, 5:07pm UTC](https://discourse.julialang.org/t/extending-formula-syntax-is-difficult-to-understand/99326/2 "2023-05-24T17:07:06Z")

</div>

It’s hard to know where to start without more details about what kind of custom syntax you’re trying to implement and why!

The docs on “lifecycle of a formula” gives a pretty complete explanation of each step from `@formula` to a fitted model; here’s teh section on `apply_schema`: [Internals and extending the @formula · StatsModels.jl](https://juliastats.org/StatsModels.jl/stable/internals/#Semantics-time-(apply_schema))

> why define `StatsModels.apply_schema`

Because that is the mechanism the StatsModels.jl provides for implementing custom syntax. Custom syntax _is_ in some sense a method of `apply_schema(::FunctionTerm{typeof(my_special_syntax_function)}, ...)`.

> how is it called in `f = apply_schema(f, schema(data))`

Like teh docs say, when `apply_schema` is called on a `FormulaTerm` (or generally any other term that has “children”, like an interaction term, “tuple term” as generated by `+`, etc.), the methods for those terms will call `apply_schema` recursively on the children. So if you have a formula like `y ~ my_special_function(x)`, and you call `apply_schema` on that, eventually it will call `apply_schema` on the `my_special_function(x)` bit, which is represented internally as a `FunctionTerm{typeof(my_special_function)}(my_special_function, [Term(:x)], ...)`. So, by defining a method for `apply_schema(::FunctionTerm{typeof(my_special_function)}, ...)`, you can control what happens when that sub-term is processed.

---

<div class="post-metadata">

**Author:** ![Norman](https://avatars.discourse-cdn.com/v4/letter/n/97f17d/32.png) [@Norman](https://discourse.julialang.org/u/Norman)\
**Post date:** [May 24, 2023, 5:22pm UTC](https://discourse.julialang.org/t/extending-formula-syntax-is-difficult-to-understand/99326/3 "2023-05-24T17:22:08Z")

</div>

The internal design of StatsModels.jl is indeed somewhat complicated. Depending on what you are trying to do, it may not be necessary to deal with the `@formula` at all if the benefit is small.

---

<div class="post-metadata">

**Author:** ![xuanquansheng](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xuanquansheng/32/32400_2.png) [@xuanquansheng](https://discourse.julialang.org/u/xuanquansheng)\
**Post date:** [May 25, 2023, 2:27am UTC](https://discourse.julialang.org/t/extending-formula-syntax-is-difficult-to-understand/99326/4 "2023-05-25T02:27:57Z")

</div>

> [@dave.f.kleinschmidt](#):
>
> the methods for those terms will call `apply_schema` recursively

Thank you for your answer. I also guessed that each term of the formula would call `apply_schema`, but I had no basis and could only ask for help on the forum. Later, I may continue to ask questions about some details of the `ploy` example.
