First proposal for 2020!

Just like a `struct` is an extension over a `map` with its own dedicated 
syntactic sugar, what prevents to regard a `record` to be an extension over 
a `tuple` with syntactic sugar en par with that of a `struct`?

When we introduce a `struct`:

defmodule A do
 defstruct a: 1
end

Instead of interacting with it like: 
%{__struct__: A, a: i} = a

We can interact with it as:

%A{a: i}= a

and likewise we can pattern match the same on function arguments:

def set(m =%A{},i), do:%{m|a: i}


According to the documentation <https://hexdocs.pm/elixir/Record.html> a 
variety of `macro`s have already been introduced to abstract away from the 
underlying `tuple` as a data structure. 

I am wondering if there would be any merit if a `Record` could be accorded 
with its own special notation that would allow us to pattern match 
accordingly?

Currently the equivalent of the `set`-`method` above is to be written using 
a `guard`, e.g.:
defmodule B do
 import Record
 defrecord(:bb, a: 1)

  def set(record, i) when is_record(record, :bb) do 
    bb(record, a: i)
 end
end


and pattern matching on a specific value can only be done by resorting to 
the underlying tuple implementation:

require B
{:bb, i}= B.bb()


It would be nice if we could introduce a special notation such as:
~bb{a: 1}

So then we could:
def set(record = ~bb{}, i) do 

and:
require B
~B.bb{a: i} = B.bb()



These two aspects are the core aspects of my proposal. In addition to this, 
I would like to highlight that it would be helpful if we could bridge the 
gap even more by being able to do:
defmodule B do
import Record
defrecord(__MODULE__, a: 1)

def set(record = ~__MODULE__{}, i) do
...
which in itself is possible, but at the expense of losing access to the 
underlying macros as enumerated in the documentation <defmodule B do import 
Record defrecord(__MODULE__, a: 1) def set(record = ~bb{}, i) do bb(record, 
a: i) end end>.

You would not be able to do:
require B
# B()
# B.B()

Also it would be nice to be able to update similar to a map:
defmodule B do
import Record
defrecord(__MODULE__, a: 1)

def set(record = ~__MODULE__{}, i) do 
~__MODULE__{record | a: i}
end
end


These last two suggestions are mainly to illustrate how the end result 
could potentially look like if we were to fully bridge the gap so to say, 
but the most essential one is the pattern matching aspect detailed above.

-- 
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/36e4c070-4efc-4641-8341-f3a95c71a905%40googlegroups.com.

Reply via email to