Tuples aren't Enumerable?

1,335 views
Skip to first unread message

TR NS

unread,
Sep 5, 2013, 12:10:46 PM9/5/13
to elixir-l...@googlegroups.com
I was surprised when I tried to use Enum.member? on a tuple and was told to beat it. What gives? Tuples don't support the Enumerable protocol? They sure seem enumerable when you can ask `elem {:a, :b, :c}, 1` and get `:b`.

Thanks.

Peter Minten

unread,
Sep 5, 2013, 12:25:59 PM9/5/13
to elixir-l...@googlegroups.com
I suspect this has to do with how records are implemented. From the
Record documentation: "A record is a tagged tuple which contains one or
more elements where the first element is an atom.". If there is a
protocol implementation for tuple it would conflict with all records.
Given that custom instances for a protocol virtually always are defined
for records adding a tuple would make the whole Enumerable protocol
rather useless.

Tuples also aren't meant to be iterated over, don't get confused by the
fact that you could using elem/2 and size/1. Tuples are for storing
multiple pieces of information together, which does not imply that they
are intended for storing a collection.

Bruce Williams

unread,
Sep 5, 2013, 12:52:23 PM9/5/13
to elixir-l...@googlegroups.com
The way I'm breaking this down (as I did with Erlang) is that lists are for iteration, tuples are for pattern matching. Generally I don't put a bunch of homogenous items in tuples, but atoms and values for extraction. Wanting the ability to enumerate over a tuple (for me) is usually a sign I'm structuring things incorrectly.

Bruce



--
You received this message because you are subscribed to the Google Groups "elixir-lang-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-talk+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.



Christopher Keele

unread,
Sep 5, 2013, 1:04:37 PM9/5/13
to elixir-l...@googlegroups.com
I'm with Bruce. I wanted tuples to be enumerable at first, and even eventually implemented Enumerable on them, which did not work out.

The way I'm learning to think about it, tuples aren't meant to be viewed as a data structure for general values. They represent highly structured data: every value inside it has meaning because of its position inside the tuple. 

If you find yourself wanting to enumerate over a tuple so you can use each value outside of the context of the tuple, you probably want a list instead.

Tuples are stored consecutively in memory, so they're quick to access and expensive to update (copy). Enumeration like mapping or reducing can be a copy-intensive process.

Alexei Sholik

unread,
Sep 5, 2013, 1:10:03 PM9/5/13
to elixir-l...@googlegroups.com
Another explanation would be that tuples are poor man's records. In other words, a tuple represents a single piece of data, a single value, albeit aggregate. You cannot take away an element from a tuple without changing the semantic meaning of that particular tuple value.

This is contrary to lists and other collections that store many values independent values. Taking a value away from list simply reduces the length of the list. It doesn't affect semantic meaning of anything.


--
You received this message because you are subscribed to the Google Groups "elixir-lang-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-ta...@googlegroups.com.

For more options, visit https://groups.google.com/groups/opt_out.



--
Best regards
Alexei Sholik

Gustavo Brunoro

unread,
Sep 5, 2013, 1:10:29 PM9/5/13
to elixir-l...@googlegroups.com
If you find yourself wanting to enumerate over a tuple so you can use each value outside of the context of the tuple, you probably want a list instead.

That's it. But there are cases where you may need to use the use Enumerable on a tuple (ie.: metaprogramming), and for that you could use the `list_to_tuple/1` and `tuple_to_list/1` functions.


2013/9/5 Christopher Keele <d...@chriskeele.com>

Bruce Williams

unread,
Sep 5, 2013, 1:35:11 PM9/5/13
to elixir-l...@googlegroups.com
Gustavo, agreed. And those functions being "extra work" is probably a Good Thing. They're a nice hint that you're doing something weird and [hopefully] very intentional.

TR NS

unread,
Sep 6, 2013, 6:27:48 PM9/6/13
to elixir-l...@googlegroups.com


I guess Tuples seemed the logical choice because I was storing some constant data. e.g.

    @categorical_positions [
      [ 0, 1, 2],[ 3, 4, 5],[ 6, 7, 8],
      [ 9,10,11],[12,13,14],[15,16,17],
      [18,19,20],[21,22,23],[24,25,26],
      [27,28,29],[30,31,32],[33,34,35],
      [ 0, 9,18,27],[ 1,10,19,28],[ 2,11,20,29],
      [ 3,12,21,30],[ 4,13,22,31],[ 5,14,23,32],
      [ 6,15,24,33],[ 7,16,25,34],[ 8,17,26,35],
      [ 0, 3, 6],[ 1, 4, 7],[ 2, 5, 8],
      [ 9,12,15],[10,13,16],[11,14,17],
      [18,21,24],[19,22,25],[20,23,26],
      [27,30,33],[28,31,34],[29,32,35]
    ]

But as you can see I had to convert them all to lists only because I needed to use Enum.each on them. So I gave up the memory space b/c I didn't want to waste time converting each tuple to a list. I suppose I could have iterated using an index range, now that I think about it some more, but that sure seems afunctional.




 
Reply all
Reply to author
Forward
0 new messages