Proposal: @mark module attribute

62 views
Skip to first unread message

Mark Madsen

unread,
Mar 17, 2025, 4:38:49 PMMar 17
to elixir-lang-core

Has there been any discussion around adding a module attribute @mark to Elixir that would function as a code organization tool similar to Swift's // MARK: or Objective-C's #pragma mark?

-- WHY --
As an example I've found that when developing Phoenix LiveView applications, modules often accumulate numerous handle_event/3 and handle_info/2 callback functions and it would be nice to have a way to organize things.

I understand that right now we can add comments, and we have compiler warnings. But nothing official an editor can support. Given that we want all the handle_event and handle_info functions together this seems like the way.

Clearly it would be optional. But it would be beneficial.

My proposal would:

  1. Introduce @mark as a special module attribute recognized by the Elixir compiler
  2. Enable IDE/editor integration for code navigation and folding based on these marks
  3. Potentially allow documentation tools like ExDoc to use these marks in module documentation

The primary benefit would be improved code organization and readability in larger modules where related functions need to stay together but would benefit from visual separation and navigation support.

Thoughts?

I'm not asking someone to write this for me... but would like to understand if something like this would be accepted before working on it.

Thanks,

Mark

Jean Klingler

unread,
Mar 17, 2025, 7:24:38 PMMar 17
to elixir-l...@googlegroups.com
The ExDoc part of the story is already covered by @doc group I think:
https://hexdocs.pm/ex_doc/Mix.Tasks.Docs.html#module-grouping-functions-types-and-callbacks

Given @doc group matches the idea of indicating the logical grouping of functions, introducing something else for a similar purpose at the language level might be redundant?
I'm not sure if IDEs could leverage them somehow to achieve what you have in mind.

Cheers,
Jean

--
You received this message because you are subscribed to the Google Groups "elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-co...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/elixir-lang-core/ebb12c67-1e90-430b-89c6-c78702e4c1d7n%40googlegroups.com.

Austin Ziegler

unread,
Mar 17, 2025, 7:54:50 PMMar 17
to elixir-l...@googlegroups.com
This definitely isn't a language feature, but an editor feature. The `#pragma mark` is used for Xcode, but Visual Studio uses `#pragma region` and `#pragma endregion` (VS Code may as well) for C/C++ (because of -Wall -Werror, unknown pragmas may be warned and/or errored). C# apparently uses `//#region` and `//#endregion`, but this isn't recognized in VS Code for C/C++.

Not all clients will support it, but the LSP defines a `Folding Range Request` (https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_foldingRange) that could be defined matching either `@doc group: NAME` or `# mark: NAME` or something, so IMO this would be something to propose to the Elixir LS team, because it would provide nice features across all supporting editors.

I don't think that `@doc group: NAME` is the correct choice, because doc sections are folded together for functions of the same name.

-a

Christopher Keele

unread,
Mar 18, 2025, 4:54:31 PMMar 18
to elixir-lang-core
An alternative approach (for the Elixir LS team) would be to recognize body-less clauses as the start of a folding range across all clauses of a function, ex:

v defmodule MyServer do
@doc "handle events"
v def handle_event(event, state)

v def handle_event({:login, session}, state) do
#...
end

> def handle_event({:logout, session}, state) do ...

end

Toggling the second fold would lead to:

v defmodule MyServer do
@doc "handle events"
> def handle_event(event, state) ...
end

Bodyless clauses are already required syntactically to be before all concrete implementations (used to anchor cross-clause concerns like default-args, @doc, and @spec), multi-clause functions are already required syntactically to be clustered, and future type system syntax will likely work with the same conceits.

I like to provide one for most multi-clause function implementations for easy-of-scannability purposes and foldability seems like a related concern. All you'd have to do to organize your code to be foldable is to provide a bodyless clause, which you are likely to do if you care about readability for the arg/doc/spec benefits anyways.

Reply all
Reply to author
Forward
0 new messages