That makes sense to me! I had forgotten Protocol would implicitly imply 
developers should be comfortable knowing these are structs. In fact, I 
never thought about implementing a protocol for Regex at all, which is a 
really cool ability.

I also noticed the commit deprecates exception?/1, which was my only 
follow-up note if we went the other way from what I proposed. :) Thanks for 
talking me through your reasoning!

On Monday, August 17, 2020 at 12:41:29 AM UTC-7 José Valim wrote:

> Hi Chris,
>
> To me the conclusion is exactly the opposite: since we have is_struct/2, 
> there is no need to add a bunch of guards to Kernel. Furthermore, adding 
> such guards to Kernel will only feel natural for Elixir built-types. For 
> everyone else, the usage is more bureaucratic (i.e. import/require a module 
> and then use it). So is_struct/2 is more consistent.
>
> The argument that the Regex struct is an implementation detail does not 
> hold because, given that Elixir has limited built-in types, it has to be a 
> struct by definition. For example, if anyone has ever implemented a 
> protocol for Regex, you are relying on the fact it is a struct - as there 
> is literally no other option.
>
> The MapSet is really an issue with Dialyzer not having a mechanism for us 
> to express the constructs we have in Elixir. As mentioned in the linked 
> issue, it manifests in other occasions too, and I would rather fix 
> Dialyzer. Furthermore, a "is_mapset" guard would have the same warnings as 
> is_struct/2", if any, so it wouldn't really address this problem.
>
> In any case, Regex.regex? does send mixed signals now that we have 
> is_struct/2, so I will schedule it for deprecation in the long run. Thanks!
>
>
> On Mon, Aug 17, 2020 at 2:08 AM Christopher Keele <christ...@gmail.com> 
> wrote:
>
>> With is_struct/2 coming in 1.11, I think it makes sense to add a guard 
>> for regexes at the same time.
>>
>> It is rarely appropriate for Elixir developers to destructure a Regex 
>> struct: its implementation is semi-opaque (partially evidenced by the fact 
>> that it carries a version number 
>> <https://github.com/elixir-lang/elixir/blob/1145dc01680aab7094f8a6dbd38b65185e14adb4/lib/elixir/lib/regex.ex#L146-L148>
>>  
>> with it). The main exception is trying to pattern match on function 
>> parameters to determine if input is a regex versus something else.
>>
>> MapSet is another example of a stdlib struct whose implementation is 
>> versioned 
>> <https://github.com/elixir-lang/elixir/blob/1145dc01680aab7094f8a6dbd38b65185e14adb4/lib/elixir/lib/map_set.ex#L57-L61>,
>>  
>> and might make more sense to have a guard for rather than expecting 
>> developers to pattern match it for typecheck guards. However, since it is 
>> fully opaque, there are other problems implementing a guard for them, as 
>> discussed here already: 
>> https://groups.google.com/g/elixir-lang-core/c/2KnRcKTZvuE/m/229Nfw0oCwAJ
>>
>> The fact that a Regex is a struct is much more of an implementation 
>> detail than some other, raw-data stdlib structs; like Range, Date, Version, 
>> and URI. An is_regex/1 would help make that clearer, and prevent code like 
>> this 
>> <https://github.com/boydm/phoenix_markdown/blob/ef7b5f76f339babec688021080a70708d9ddf1c1/lib/phoenix_markdown/engine.ex#L80-L88>
>>  that 
>> has to choose between not using guards, or reaching into the struct 
>> implementation detail.
>>
>> considerations:
>>
>>    - we'd want to re-implement Regex.regex?/1 in terms of it and 
>>    possibly put that function into a deprecation path.
>>       - we'd need to remove it as an example in the guard Naming 
>>       Convention 
>>       <https://hexdocs.pm/elixir/naming-conventions.html#is_-prefix-is_foo> 
>>       guide.
>>    - could be implemented in either Regex or Kernel. adding to Kernel 
>>    sucks, but I think it would be a stronger commitment to the Regex struct 
>>    implementation being an opaque detail.
>>       - it would make Regexs feel a lot more first-class Elixir 
>>       data-typey, which they already do a lot just by virtue of inspecting 
>> as 
>>       their sigil constructors.
>>    
>> -- 
>> 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-co...@googlegroups.com.
>> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/elixir-lang-core/071f08ea-f4cf-483e-bfe6-29d98af4bef7n%40googlegroups.com
>>  
>> <https://groups.google.com/d/msgid/elixir-lang-core/071f08ea-f4cf-483e-bfe6-29d98af4bef7n%40googlegroups.com?utm_medium=email&utm_source=footer>
>> .
>>
>

-- 
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/f9ffdd9b-e197-4388-aa19-855c9e2d0adcn%40googlegroups.com.

Reply via email to