# Side Effect Analysis on Macros

**URL:** <https://discourse.julialang.org/t/side-effect-analysis-on-macros/106526>\
**Category:** VS Code\
**Tags:** internals\
**Created:** [November 21, 2023, 1:46pm UTC](https://discourse.julialang.org/t/side-effect-analysis-on-macros/106526 "2023-11-21T13:46:23Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![mrufsvold](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mrufsvold/32/31600_2.png) [@mrufsvold](https://discourse.julialang.org/u/mrufsvold)\
**Post date:** [November 21, 2023, 1:46pm UTC](https://discourse.julialang.org/t/side-effect-analysis-on-macros/106526/1 "2023-11-21T13:46:23Z")

</div>

A recurrent challenge for linting Julia is macro mini languages. From chaining with underscores to sum types, there are lots of symbols that get created by macros which are obvious to the human reader but not to LSP. The obvious solution would be to expand macros before analyzing the AST, but since macros can execute arbitrary code, that could be dangerous.

Given that we have side effect analysis for functions now, could that be leveraged to determine whether expanding a macro would do anything other than return AST and only expand macros that are pure? I don’t know if the compiler applies the same effect analysis to macros.

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [November 21, 2023, 2:22pm UTC](https://discourse.julialang.org/t/side-effect-analysis-on-macros/106526/2 "2023-11-21T14:22:01Z")

</div>

Pluto seems to do some macro analysis/expansion, wonder how specifically they do it…

---

<div class="post-metadata">

**Author:** ![pfitzseb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pfitzseb/32/45566_2.png) [@pfitzseb](https://discourse.julialang.org/u/pfitzseb)\
**Post date:** [November 21, 2023, 2:38pm UTC](https://discourse.julialang.org/t/side-effect-analysis-on-macros/106526/3 "2023-11-21T14:38:13Z")

</div>

Pluto has access to a Julia runtime that has the macro and everything it depends on loaded, which is not the case for the VS Code extension.

Generally full static analysis of macros is basically impossible, so an idea is to move to a multi-process approach, where some sandboxed processes are in fact allowed to load packages and expand macros in a module context.

---

<div class="post-metadata">

**Author:** ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)\
**Post date:** [November 21, 2023, 2:42pm UTC](https://discourse.julialang.org/t/side-effect-analysis-on-macros/106526/4 "2023-11-21T14:42:42Z")

</div>

> [@pfitzseb](#):
>
> Generally full static analysis of macros is basically impossible, so an idea is to move to a multi-process approach, where some sandboxed processes are in fact allowed to load packages and expand macros in a module context.

One alternative, (I’m not a fan, but it might work alright) is to have a plugin system so that macro-writers can communicate to the linter what variable names it is creating, and what types it is defining, and other static information the linter might need to know.

---

<div class="post-metadata">

**Author:** ![pfitzseb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pfitzseb/32/45566_2.png) [@pfitzseb](https://discourse.julialang.org/u/pfitzseb)\
**Post date:** [November 21, 2023, 2:46pm UTC](https://discourse.julialang.org/t/side-effect-analysis-on-macros/106526/5 "2023-11-21T14:46:01Z")

</div>

Yes, but it’s also not entirely clear how to best design this plugin system. Either it also requires loading LS-extension-code based on your current environment _or_ is pretty limited in that it can only work declaratively.

---

<div class="post-metadata">

**Author:** ![mrufsvold](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mrufsvold/32/31600_2.png) [@mrufsvold](https://discourse.julialang.org/u/mrufsvold)\
**Post date:** [November 21, 2023, 2:52pm UTC](https://discourse.julialang.org/t/side-effect-analysis-on-macros/106526/6 "2023-11-21T14:52:08Z")

</div>

I know I’ve said it elsewhere to you, @pfitzseb , but could you clarify if there is any possibility of convincing LSP that certain symbols are definitely defined? Like in a list in a Workspace config file? That way, one could white list, say, `_` if they are using Chain.jl.

---

<div class="post-metadata">

**Author:** ![mrufsvold](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mrufsvold/32/31600_2.png) [@mrufsvold](https://discourse.julialang.org/u/mrufsvold)\
**Post date:** [November 21, 2023, 3:06pm UTC](https://discourse.julialang.org/t/side-effect-analysis-on-macros/106526/7 "2023-11-21T15:06:34Z")

</div>

Okay, one more thought, is it possible to use comments to communicate with the language server? Like, could I put `#=expand=# @chain` or something when I’m very confident that I want it expanded? Then package documentation could add notes to their macros about which are safe to notate as such.

---

<div class="post-metadata">

**Author:** ![savq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/savq/32/22063_2.png) [@savq](https://discourse.julialang.org/u/savq)\
**Post date:** [November 21, 2023, 10:23pm UTC](https://discourse.julialang.org/t/side-effect-analysis-on-macros/106526/8 "2023-11-21T22:23:37Z")

</div>

I recently found out that Clojure’s [clj-kondo](https://github.com/clj-kondo/clj-kondo) can be extended with [hooks](https://blog.michielborkent.nl/clj-kondo-hooks.html) written in Clojure (only interpreted, not compiled). I don’t really know how powerful this feature is, but it’s some prior art you could look into.

i like that idea because if you want to grow a language, then you need tooling that grows with it.

---

<div class="post-metadata">

**Author:** ![fredrikekre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fredrikekre/32/1688_2.png) [@fredrikekre](https://discourse.julialang.org/u/fredrikekre)\
**Post date:** [November 21, 2023, 11:57pm UTC](https://discourse.julialang.org/t/side-effect-analysis-on-macros/106526/9 "2023-11-21T23:57:46Z")

</div>

A hacky but very useful trick is to use `local var` before macros that result in new variables etc. For example, all of these annoying warnings:

 ![image](https://global.discourse-cdn.com/julialang/original/3X/c/7/c7bef5ca14721db98ef3abf790e204c414411bfc.png)  
can be silenced with `local` expressions like this:

```julia
using SumTypes

local Either, A, B, Left, Right
@sum_type Either{A, B} begin
    Left{A}(::A)
    Right{B}(::B)
end

function foo() :: Either{Int, Float64}
    # Randomly return either a Left(1) or a Right(2.0)
    rand(Bool) ? Left(1) : Right(2.0)
end

using Symbolics

local x
@variables x

function f()
    local y
    @variables y
    return x + y
end

```

---

<div class="post-metadata">

**Author:** ![Ronis\_BR](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ronis_br/32/50999_2.png) [@Ronis\_BR](https://discourse.julialang.org/u/Ronis_BR)\
**Post date:** [April 24, 2024, 11:26pm UTC](https://discourse.julialang.org/t/side-effect-analysis-on-macros/106526/10 "2024-04-24T23:26:20Z")

</div>

Hi!

Is there any update here? It turns out that the LSP is almost unusable if you use Paramters.jl to define all the custom structures in your package.

---

<div class="post-metadata">

**Author:** ![mrufsvold](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mrufsvold/32/31600_2.png) [@mrufsvold](https://discourse.julialang.org/u/mrufsvold)\
**Post date:** [April 25, 2024, 2:12am UTC](https://discourse.julialang.org/t/side-effect-analysis-on-macros/106526/11 "2024-04-25T02:12:08Z")

</div>

Switching my workflow to use more Pluto is about all the progress I can report unfortunately!
