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.

Reply via email to