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.

Reply via email to