Skip to content

Conversation

@sabiwara
Copy link
Contributor

Close #14648

This is a proposal to address the fact regexes can't be shared across nodes or through config, just by exposing the already existing :export option as a built-in modifier e. No need to fully recompile, we can just re-import (which we're doing already actually).

Maybe we could also have Regex.recompile! strip the :export option to get back, or expose a way to do this?

@sabiwara sabiwara force-pushed the exported-regexes branch 2 times, most recently from 1e87812 to b85fed9 Compare November 13, 2025 00:44
@sabiwara
Copy link
Contributor Author

Sorry still need to handle the OTP27- cases and fix the CI on this better, putting this back to draft but the approach can already be discussed.

@sabiwara sabiwara marked this pull request as draft November 13, 2025 00:51
@josevalim
Copy link
Member

@sabiwara love this. I think this is the way to go. Preferrable we can improve the code in compile.app and when building releases to detect if there is a regex and recommend adding the e flag.

* `:ungreedy` (U) - inverts the "greediness" of the regexp
(the previous `r` option is deprecated in favor of `U`)
* `:export` (e) (from Erlang OTP 28.1 and Elixir 1.20) - uses an exported pattern
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* `:export` (e) (from Erlang OTP 28.1 and Elixir 1.20) - uses an exported pattern
* `:export` (E) (from Erlang OTP 28.1 and Elixir 1.20) - uses an exported pattern

e is already used by Perl/PHP and has another meaning, let's use E to avoid any confusion.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for doing the research, I thought about looking but I forgot.
ef34268

@sabiwara sabiwara changed the title Add 'e' modifier to Regex for :export opt Add 'E' modifier to Regex for :export opt Nov 13, 2025
Comment on lines 6649 to 6650
# We defer to a runtime compilation if using the :export flag on older OTP version
# that don't support it.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think for earlier versions, we should always consider as if export is given, given they can be transmited across nodes and written to config files? So earlier versions don't need to check for it?

Also, why do we want to skip compilation if the "E" flag is given? We can still precompile it, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The thing is that it would make the compilation fail because of the :export flag: https://github.com/sabiwara/elixir/actions/runs/19327180274/job/55281069375

Screenshot 2025-11-13 at 20 36 10

What we could do is make E a non-op on older versions, e.g. just filter out the flag. ~r/foo/E == ~r/foo/.
This way, code written with E would be compatible on both older versions and newer versions.
It might be a bit confusing, but we could document it and it is only a transitional state of things until we drop OTP27-, so LGTM.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What we could do is make E a non-op on older versions

Yes, I'd go this route. We can note that E is a no-op in older versions as all regexes are "exportable" there.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK I think I got it: ddfc080

@sabiwara
Copy link
Contributor Author

referrable we can improve the code in compile.app and when building releases to detect if there is a regex and recommend adding the e flag.

Something like 1b009af?

@josevalim
Copy link
Member

Yes, beautiful. I believe we do similar traversal for releases too... perhaps this could be unified somewhere even.

@sabiwara
Copy link
Contributor Author

I believe we do similar traversal for releases too... perhaps this could be unified somewhere even.

Unifying sounds good indeed. I'm not too familiar with releases, any pointers on where I should look?

@josevalim
Copy link
Member

@sabiwara check Mix.Release.make_sys_config. I think for now, we can simply add the same Regex struct check, and I will try to unify the approaches in another PR (as it will require a bigger change).

@sabiwara sabiwara marked this pull request as ready for review November 13, 2025 12:04
Co-authored-by: José Valim <jose.valim@gmail.com>
@sabiwara
Copy link
Contributor Author

@josevalim the structure is a bit different in releases: we're just validating terms with a bool function and returning terms:

not valid_config?(value),
do: """
Application: #{inspect(app)}
Key: #{inspect(key)}
Value: #{inspect(value)}
"""
message =
case invalid do
[] ->
"Could not read configuration file. Reason: #{inspect(reason)}"
_ ->
"Could not read configuration file. It has invalid configuration terms " <>
"such as functions, references, and pids. Please make sure your configuration " <>
"is made of numbers, atoms, strings, maps, tuples and lists. The following entries " <>
"are wrong:\n#{Enum.join(invalid)}"
. Modifying it to know if it contains a nested regex might be tricky (or maybe just a throw/catch?).

But perhaps the easy way here is to just modify the error message to mention regexes?

Also, I'm wondering. For libraries that want to support various versions of Elixir and Erlang and use regex configs, it might be convenient to automatically export regexes from the config even if they don't have the E modifier? (so we don't get a compile error on Elixir 1.19.2/OTP27 that E doesn't exist).

@josevalim
Copy link
Member

@sabiwara let's skip the config change for now then, we can tackle it later! This is good to go IMO!

@sabiwara sabiwara merged commit b45853f into elixir-lang:main Nov 13, 2025
13 checks passed
@sabiwara sabiwara deleted the exported-regexes branch November 13, 2025 12:37
@sabiwara sabiwara mentioned this pull request Nov 13, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

Regexes cannot be stored in configuration in Erlang/OTP 28

2 participants