I believe this is the best proposal on the topic so far. I agree with trade-offs too (disclaimer: we have talked about those trade-offs privately before). I would suggest two amendments:
1. Limit multi-letter sigils only to uppercase sigils for now 2. Include "only: :sigils" as part of the initial implementation On Sat, Feb 15, 2020 at 2:52 PM Wojtek Mach <[email protected]> wrote: > 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 [email protected]. > To view this discussion on the web visit > https://groups.google.com/d/msgid/elixir-lang-core/E4F9858D-7019-4E2E-A463-9FEDAFA52B0E%40wojtekmach.pl > . > -- 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 [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4%2B8fjp8Y%2Bubx5vcq5m-Qwg3DgBsYp_ijqCsVB9vfP58tg%40mail.gmail.com.
