> Couldn't you define a method like __record_keys__/0 on the atom in the 
defrecord call?

Yes. To be concrete, this is how it could work:

```
defmodule Records do
  import Record
  defrecord :a, [:x, :y]
  defrecord :b, [:x, :y]
end

iex> Records.__records__()
[
  a: [:x, :y],
  b: [:x, :y]
]
```

Alternatively, this could become `Records.__info__(:records)`. In either 
case, to make this work I think we'd need `use Record`. Or, we'd have a new 
`defrecords/1` that defines both multiple records as well as this 
reflection function.

> Unlike structs there's no guarantee that two records won't be defined 
with the same name, they are scoped within modules.

That's a good point. That's something I was aware of but I guess I haven't 
thought through the consequences which I think are: if by doing `defrecord` 
we'd store the fields somewhere (like the :persistent_term solution 
mentioned) we'll need to handle duplicates by erroring or at least warning.

For this reason, perhaps the other, "stateless", approach mentioned above 
is more suitable? Users will opt-in to use records so they'll handle 
conflicts themselves.

I mentioned we can configure inspect behaviour with `IEx.configure`; the 
`ExUnit.configure(inspect: ...) is not possible (I honestly thought it is) 
so in order to format records in ExUnit diffs we'd need that.
Even if we configure both IEx and ExUnit to use record definitions, anytime 
we do `IO.inspect(record)` we'd get non-formatted records output and so to 
format it we'd have to keep inspect record options everywhere. To take 
advantage of this feature we'd have to configure it in IEx, ExUnit and all 
IO.inspect calls; that's explicit but doesn't sound practical.

The only solutions I can think of at the moment are:
1. Going back to magically keeping record fields
2. Currently, we have essentially `Kernel.inspect(term, opts \\ [])`, 
`IO.inspect(term, opts \\ [])`; if we change it something along the lines 
of `Kernel.inspect(term, opts \\ default_opts())` and make these defaults 
configurable we could configure our records just once. So we're back to 
global state after all.

Neither option is perfect. I'll continue experimenting with this as a 
standalone library but it seems less likely it could be part of Elixir. 
What do you think?

On Sunday, December 16, 2018 at 3:47:57 PM UTC+1, Louis Pop wrote:
>
> Hey
>
> Unlike structs there's no guarantee that two records won't be defined with 
> the same name, they are scoped within modules.
>
> Cheers,
> Louis
>
> On Sun, 16 Dec 2018 at 13:55 Allen Madsen <[email protected] 
> <javascript:>> wrote:
>
>> Couldn't you define a method like __record_keys__/0 on the atom in the 
>> defrecord call?
>>
>> Allen Madsen
>> http://www.allenmadsen.com
>>
>>
>> On Sat, Dec 15, 2018 at 11:49 AM <[email protected] 
>> <javascript:>> wrote:
>>
>>> One way to avoid issues with state is to avoid... state. Maybe we'd 
>>> configure it like this:
>>>
>>> records = [
>>>   # explicit
>>>   {:column_definition, [:name, :type]},
>>>
>>>   # grabs record fields from record macro in that module, e.g: 
>>> resultset(resultset()) |> Keyword.keys()
>>>   {Records, :resultset}
>>> ]
>>>
>>> IEx.configure(inspect: [records: records])
>>> ExUnit.configure(inspect: [records: records])
>>>
>>> This is less convenient, but I guess sometimes we may prefer the "tuple" 
>>> representation so by making this opt-in we cater to that use case as well.
>>>
>>> On Saturday, December 15, 2018 at 5:08:13 PM UTC+1, 
>>> [email protected] wrote:
>>>>
>>>> Hello,
>>>> I'd like to discuss support for Inspect protocol for records. I created 
>>>> a proof-of-concept here: https://github.com/wojtekmach/record_inspect
>>>>
>>>> Basically, for these records:
>>>>
>>>> defrecord :resultset [
>>>>   :column_count,
>>>>   :column_definitions,
>>>>   :row_count,
>>>>   :rows,
>>>>   :warning_count,
>>>>   :status_flags
>>>> ]
>>>>
>>>> defrecord :column_definition41, [:name, :type]
>>>>
>>>> Instead of:
>>>>
>>>> {:resultset, 2,
>>>>  [{:column_definition41, "2*3", 8}, {:column_definition41, "4*5", 8}], 
>>>> 1,
>>>>  [[6, 20]], 0, 2}
>>>>
>>>> We could get this:
>>>>
>>>> #resultset([
>>>>   column_count: 2,
>>>>   column_definitions: [
>>>>     #column_definition41([name: "2*3", type: 8]),
>>>>     #column_definition41([name: "4*5", type: 8])
>>>>   ],
>>>>   row_count: 1,
>>>>   rows: [[6, 20]],
>>>>   warning_count: 0,
>>>>   status_flags: 2
>>>> ])
>>>>
>>>> My proof-of-concept uses the new `:persistent_term` facility in OTP 
>>>> 21.2 just to get something working. Managing the state is challenging for 
>>>> potentially including this in Elixir.
>>>>
>>>> Feedback appreciated!
>>>>
>>> -- 
>>> 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] <javascript:>.
>>> To view this discussion on the web visit 
>>> https://groups.google.com/d/msgid/elixir-lang-core/8e936469-e806-46f9-b4a4-3aa3c577d205%40googlegroups.com
>>>  
>>> <https://groups.google.com/d/msgid/elixir-lang-core/8e936469-e806-46f9-b4a4-3aa3c577d205%40googlegroups.com?utm_medium=email&utm_source=footer>
>>> .
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>> -- 
>> 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] <javascript:>.
>> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/elixir-lang-core/CAK-y3Ct-2iFCY12qQD07GurkkRepiN3vqaDVgML_7WpHctqLuA%40mail.gmail.com
>>  
>> <https://groups.google.com/d/msgid/elixir-lang-core/CAK-y3Ct-2iFCY12qQD07GurkkRepiN3vqaDVgML_7WpHctqLuA%40mail.gmail.com?utm_medium=email&utm_source=footer>
>> .
>> For more options, visit https://groups.google.com/d/optout.
>>
>

-- 
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/ac5197ed-aadf-4b2c-b9bd-743eb14fe6d2%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to