Currently sigils are single letter which means there can be only 2 x 26 of them and some of them are already taken by the standard library. As mentioned in [1] it's not clear if there should be for example a `~P` and if so, whether it should be for PID or Port. Similarly, there couldn't be an `~R` sigil for Reference given the symbol is already taken by Regex.
I'd like to propose to extend sigils to support multiple letters. For example, to define a `~Port` sigil we'd write a `sigil_Port` function/macro and to use it it would have to be either local to the module or be imported. After the first letter, we could only use US-ASCII letters (a-z, A-Z). If a sigil starts with a lower-case letter it's interpolated, otherwise it is not. As part of this proposal I'd like to introduce the following sigils to the Kernel module: - `~Port<0.6>` - `~PID<0.108.0>` - `~Reference<0.2489367154.3551002625.84263>` - `~Version<1.0.0>` - `~URI<https://elixir-lang.org>` But worth mentioning that the primary goal of this proposal is allow the community to build sigils like these: - `~Decimal<3.14>` - `~Complex<0+1i>` - `~Ratio<1/3>` - `~Money<100 USD>` - `~Geo<SRID=4326;POINT(30 -90)>` etc basically whenever there's some piece of structured data with compact string representation it'd be a good candidate for a sigil. Notice, I have chosen the same delimiter, `<`, for all proposed sigils. Different ones for different sigils could be of course chosen as the "cannonical" (returned from the Inspect implementation.) Below I'd like to discuss some limitations of this proposal. Given we already have sigils that correspond to structs like `~D`, `~T`, `~N`, `~U`, `~R`, should we deprecate them in favour of `~Date`, `~Time`, `~NaiveDateTime`, `~DateTime`, `~Regex`? I'd arbitrarily say we **should not** and instead keep them as is. (Personally I wouldn't mind using all of these except for maybe `~NaiveDateTime` which is rather long.) The longest possible sigil name would be 249 letters (which along with 6 letters in `sigil_` make 255 characters which is the atom length limit). A shorter maximum name length could be chosen. As mentioned in [2], we run into technical limitations when implementing a ~MapSet sigil, given sigils work on string and not the AST. This could be emulated with some caveats [3]. I'd argue that given single letter sigils have exactly the same problem, perhaps it's not a deal-breaker, just one of consequence of the original design. Given multi-letter sigils may (but of course don't have to) correspond to module names, what about modules with dots like `Date.Range` and `Version.Requirement`? This is especially relevant for user provided sigils, e.g. `~MyApp.Money`. Turns out it's very easy to support these too, instead of `def sigil_Date.Range` which would be a syntax error, we would do `def unquote(:"sigil_Date.Range")`. But then the other parts of the system don't quite work either, e.g. instead of `iex> h sigil_Date.Range` currently we would have to do `iex> h Kernel."sigil_Date.Range"`. For what it's worth it's not very different than the `./2` macro [4] which has similar caveats. In any case, as much as I'd personally like to see `~Date.Range` in particular, I concede we probably should stick to just supporting letters for now. Worth mentioning that sigils need to be manually imported into the current scope (unless they are already there by default, like the ones on Kernel). Thus, to use ~Decimal, users would have to do: `import Decimal, only: [sigil_Decimal: 2]`. A convenience like `import Decimal, only: :sigils` could be added in the future but it's not the topic of this proposal. Limitations aside, here's a proof-of-concept! https://github.com/elixir-lang/elixir/compare/master...wojtekmach:wm-long-sigil - [1] https://groups.google.com/forum/#!topic/elixir-lang-core/C7-QgKKu1Mw, - [2] https://github.com/elixir-lang/elixir/pull/9640#issuecomment-564022856 - [3] https://gist.github.com/wojtekmach/7d4b5dc2f45a4708ce04d19e7c381360 - [4] https://github.com/elixir-lang/elixir/blob/v1.10.1/lib/elixir/lib/kernel/special_forms.ex#L492 -- 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-core+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/E4F9858D-7019-4E2E-A463-9FEDAFA52B0E%40wojtekmach.pl.