Why doesn't Elixir have vectors/arrays?

1,878 views
Skip to first unread message

gvim

unread,
Apr 8, 2016, 12:05:19 AM4/8/16
to elixir-l...@googlegroups.com
As far as I'm aware Elixir's data structures are basically Erlang data
structures. That being so, why doesn't Elixir have arrays like Erlang
and nearly every major programming language in use today? It just feels
to me like Elixir's missing piece.

gvim

Stuart Coyle

unread,
Apr 8, 2016, 12:19:06 AM4/8/16
to elixir-l...@googlegroups.com
There is nothing stopping you from calling :array.new/1 in Elixir or any of the other Erlang array functions.

On Fri, Apr 8, 2016 at 2:05 PM, gvim <gvi...@gmail.com> wrote:
As far as I'm aware Elixir's data structures are basically Erlang data structures. That being so, why doesn't Elixir have arrays like Erlang and nearly every major programming language in use today? It just feels to me like Elixir's missing piece.


gvim

--
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.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-talk/57072DF9.1030205%40gmail.com.
For more options, visit https://groups.google.com/d/optout.



--
Stuart Coyle
stuart dot coyle at gmail dot com


gvim

unread,
Apr 8, 2016, 7:04:53 AM4/8/16
to elixir-l...@googlegroups.com
On 08/04/2016 05:19, Stuart Coyle wrote:
> There is nothing stopping you from calling :array.new/1 in Elixir or any
> of the other Erlang array functions.
>

By the same token there is :maps.new/0 but Elixir has map literal syntax
so you haven't really answer my question. Why doesn't Elixir have its
own array literal syntax even if it's only a wrapper around :array.new/1?

gvim

José Valim

unread,
Apr 8, 2016, 7:09:39 AM4/8/16
to elixir-l...@googlegroups.com
We mostly add literal syntax for constructs that could be used in pattern matching. Because we can't leverage such with arrays, be them Erlang or our own, it doesn't make sense to provide a literal syntax.



José Valim
Skype: jv.ptec
Founder and Director of R&D



gvim

--
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.

gvim

unread,
Apr 8, 2016, 7:21:46 AM4/8/16
to elixir-l...@googlegroups.com
On 08/04/2016 12:09, José Valim wrote:
> We mostly add literal syntax for constructs that could be used in
> pattern matching. Because we can't leverage such with arrays, be them
> Erlang or our own, it doesn't make sense to provide a literal syntax.
>

I think the omission takes something away from Elixir having its own
identity. When a new Ruby, Javascript, or Python developer comes to
Elixir they could be forgiven for thinking Elixir has a missing data
structure. Couldn't array literals simply error when used in pattern
matching?

gvim

gvim

unread,
Apr 8, 2016, 7:26:09 AM4/8/16
to elixir-l...@googlegroups.com
On 08/04/2016 12:09, José Valim wrote:
> We mostly add literal syntax for constructs that could be used in
> pattern matching. Because we can't leverage such with arrays, be them
> Erlang or our own, it doesn't make sense to provide a literal syntax.
>

Why can't arrays also be used in pattern matching?

gvim

Chris McCord

unread,
Apr 8, 2016, 7:35:14 AM4/8/16
to elixir-l...@googlegroups.com
> I think the omission takes something away from Elixir having its own identity.

It might be good to search the mailing list history. You'll get a good sense of Elixir's identity and ties with Erlang and why such decisions were made so lets not rehash them in this thread. It has been an intentional effort to lean on Erlang directly and only introduce features on top where it makes sense. `:array` is also very seldom used compared to tuples, lists, and maps. I've never once used it for example, so adding literal syntax, especially one with surprising caveats like no matching makes sense to exclude.
> --
> 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.
> To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-talk/57079446.7030102%40gmail.com.

gvim

unread,
Apr 8, 2016, 7:38:41 AM4/8/16
to elixir-l...@googlegroups.com
On 08/04/2016 12:09, José Valim wrote:
> We mostly add literal syntax for constructs that could be used in
> pattern matching. Because we can't leverage such with arrays, be them
> Erlang or our own, it doesn't make sense to provide a literal syntax.
>
>

It's not just the absence of literal syntax that gives the impression
that arrays are second class citizens in Elixir. We have Dict, HashSet
and HashDict but no Array module and no mention of "array" or "vector"
in the documentation.

gvim

Louis Pilfold

unread,
Apr 8, 2016, 7:55:26 AM4/8/16
to elixir-lang-talk
Well, you technically could, but this would be not very practical
since arrays are a record containing a tuple for the data, and some
extra information about size and default value.

iex(4)> :array.from_list [1,2,3,4,5,6]
{:array, 6, 10, :undefined,
{1, 2, 3, 4, 5, 6, :undefined, :undefined, :undefined, :undefined}}

At best I suppose you could pattern match on the default value or size
of the array, but I can't imagine this ever being useful.

Cheers,
Louis
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/elixir-lang-talk/5707954D.2060602%40gmail.com.

Ben Wilson

unread,
Apr 8, 2016, 7:57:38 AM4/8/16
to elixir-lang-talk
gvim, Have you used elixir much? Many major programming languages also have Objects. Many major programming languages let you mutate a value from inside a loop. Functional programming is different. Some data structures you have never used before are much more common, others you've used a lot before are a lot less common. Cons lists are fundamental to most functional programming languages because prepending is always constant time, and getting the head and tail is always constant time. This makes building and walking through lists in a recursive fashion (remember, recursion is our only looping construct) very easy.

These will replace arrays in a massive number of cases. In fact, it's replaced arrays in every bit of Elixir code I have ever written.

Setting this aside, your choices of other data structures belies an unfamiliarity with both erlang and Elixir. Dict isn't its own datastructure and is deprecated. Hash* are deprecated. They existed because prior to erlang 18 Maps didn't exist. Elixir wanted to provide a key value lookup data structure with O(log(n)) access time and nothing in the erlang library cleanly suited that role.

There are also a surprisingly large number of other "data structures" in the OTP standard library. :digraph, :queue, :array all come to mind.

The primary reasons to include an Array or Queue in the elixir standard library in my opinion is to enable easy interfacing with the Enumerable and Collectable protocols. There are actually libraries on Hex.pm that offer this kind of interface, but they really aren't used all that often either. When people actually start using these more it will enable the core team to evaluate the best way to address those needs in the standard library.

gvim

unread,
Apr 8, 2016, 8:14:59 AM4/8/16
to elixir-l...@googlegroups.com
I've used Elixir for a couple of personal projects, still in
development, and I really like the language. My understanding of it may
be a little naive or "user-level", as I'm no CS major, but I'm not sure
"use x instead" or "I don't use y much" is a good argument for leaving
something out of the language; especially something as basic as arrays.
Isn't it also possible that a robust Array implementation in Elixir
might also help solve another problem - element access in deeply nested
data structures? Clojure's combination of maps and vectors is a joy to
work with yet I get the impression that it's a lot harder in Elixir due
to the second-class treatment of arrays.

gvim




Ben Wilson

unread,
Apr 8, 2016, 8:25:38 AM4/8/16
to elixir-lang-talk
Maybe this could be more productive if you talked more about common use cases you had where the lack of access to arrays turned out to be problematic. Random index based access just isn't a common pattern in functional programming in general, or elixir code specifically.

I continue to be confused by why you think Arrays are "basic". In a language with immutable data, lists are far more commonly the basic way of representing a sequence of things.

While "I" don't use X much isn't a good argument, "almost nobody who uses this language uses x much" turns out to be a rather relevant argument.

gvim

unread,
Apr 8, 2016, 8:36:09 AM4/8/16
to elixir-l...@googlegroups.com
On 08/04/2016 13:25, Ben Wilson wrote:
> Maybe this could be more productive if you talked more about common use
> cases you had where the lack of access to arrays turned out to be
> problematic. Random index based access just isn't a common pattern in
> functional programming in general, or elixir code specifically.
>

I use vectors routinely in Clojure for nested data structures accessed
by index. It's not about me anyway, it's about the language. I don't
agree that the use of arrays/vectors has anything to do with whether a
language is functional or not.

> I continue to be confused by why you think Arrays are "basic". In a
> language with immutable data, lists are far more commonly the basic way
> of representing a sequence of things.
>

Ask Rich Hickey.

gvim

Onorio Catenacci

unread,
Apr 8, 2016, 8:44:07 AM4/8/16
to elixir-lang-talk
So gvim your argument seems to basically be "other languages have their own implementation of array, Elixir should too."  If I've read you wrong I apologize but that's basically what it seems to come down to.  If there's a persuasive use case you can offer that can only be addressed by creating our own implementation of array in Elixir, please do so.  Otherwise, "other languages have it, we should too" isn't really a good argument.  Elixir has some great features that other languages lack--documentation tests for example.  Should we drop those so we're more like other languages?

--
Onorio

José Valim

unread,
Apr 8, 2016, 8:55:27 AM4/8/16
to elixir-l...@googlegroups.com

I think the omission takes something away from Elixir having its own identity. When a new Ruby, Javascript, or Python developer comes to Elixir they could be forgiven for thinking Elixir has a missing data structure. Couldn't array literals simply error when used in pattern matching?

Would such developers then forgive that all literal collections can be pattern matched on except arrays? It is not a "win-win" situation, if it was, this discussion would be much easier. Instead It has pros and cons.

Specially in Elixir where we already have tuples and lists that are used where we would use arrays in other languages. In the rare cases they were not a good fit, I used a map with integer keys (the vector implementation in clojure shares a lot with their associative kv structure with changes to afford efficient push/pop/shift operations). I have never used :array in any of the Elixir or Erlang code I wrote in the last 5 years.

So if you think arrays are important, share use cases. Saying you use a lot in clojure code or that other languages have them is a good indication but it is definitely not enough to warrant their inclusion nor offset the other trade-offs that have been mentioned.




--

Angel Java Lopez

unread,
Apr 8, 2016, 9:07:57 AM4/8/16
to elixir-l...@googlegroups.com
Well... usually, in Clojure, a list has a distintive element, the first element, that can hold a form

And arrays, in Clojure, has no distinguished elements. 

That is one origin of the difference, in Clojure, according to Stuart Sierra. Maybe are others, like interop with Java



gvim

--
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.

Gilbert Kennen

unread,
Apr 8, 2016, 9:39:51 AM4/8/16
to elixir-l...@googlegroups.com
On 04/08/2016 05:14 AM, gvim wrote:
> I'm not sure "use x instead" or "I don't use y much" is a good argument

It's a good start.

We already see new people come to Elixir and try to implement their
established patterns with bad results. One of the most common problems
is people using lists like arrays.

The problem is that, given the environment that Elixir runs in, arrays
are almost never the right tool for the job. There is so much emphasis
on asking for concrete use-cases because it will either be something so
profound that we will all have our minds blown (which we would seriously
love), or we can explain how an array isn't the right choice.

Part of learning an immutable language is throwing out or seriously
re-thinking a lot of what is standard practice under other regimes.
Large arrays are just not very useful in Elixir (for small arrays we
have tuples); try to be open to this possibility and implement things in
a new way, it can actually be fun and educational.

Gilbert

Onorio Catenacci

unread,
Apr 8, 2016, 9:49:20 AM4/8/16
to elixir-lang-talk, gil...@firewatcher.org
Can't speak for anyone else but for me when I ask for a use case I ask because otherwise the conversation is all based on theoretical considerations. I don't know about anyone else but I can't code theories.  My coding all involves actual details so most technical questions and most technical decisions I make are based on specific details. And what may work terrifically in one case may not work in a different case with just one or two details altered.  That's why it's really important to discuss details and context (which actual use cases provide).


--
Onorio
 

gvim

unread,
Apr 8, 2016, 9:56:34 AM4/8/16
to elixir-l...@googlegroups.com
On 08/04/2016 14:39, Gilbert Kennen wrote:

> Part of learning an immutable language is throwing out or seriously
> re-thinking a lot of what is standard practice under other regimes.
> Large arrays are just not very useful in Elixir (for small arrays we
> have tuples); try to be open to this possibility and implement things in
> a new way, it can actually be fun and educational.
>

Unless you're limiting Elixir to non-computational domains or explicitly
avoiding deeply nested data structures large arrays are very useful. The
same argument for using them applies as with any other language,
immutable or not. When I learned Clojure (immutable) I learned a lot of
new, functional idioms and concepts but it never crossed my mind to
ignore vectors. In fact, I couldn't imagine getting anything done in
Clojure without vectors. No, tuples and lists are no substitute.

gvim

Ben Wilson

unread,
Apr 8, 2016, 10:05:40 AM4/8/16
to elixir-l...@googlegroups.com
I would say without question that very few people at the moment are using Elixir for computationally expensive operations. It's an unfortunate characteristic of the BEAM that its number crunching performance is rather poor. The BEAM is built around IO bound applications, and it's also built with the tools (nifs and ports) to let you push computationally expensive operations to lower level languages that will always win at that game. I've built some basic ML algorithms in elixir and erlang just for fun, and they were positively murdered by even the Go equivalents, much less Rust or C.

I'm not sure what deep nesting has to do with arrays. There's nothing intrinsic to nesting that says we're gonna use index based access. Maybe the use case is just a treewalk. Obviously if you use an array you can nest it, but it sounds like what you're really talking about is random access into deeply nested structures, where index is a desired access pattern, and maps with integer keys won't do.

Erlang Factory 2016 talked about work that has been done to bring a JIT to BEAM so maybe that will change in the future.



--
You received this message because you are subscribed to a topic in the Google Groups "elixir-lang-talk" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/elixir-lang-talk/5K7IZWODawE/unsubscribe.
To unsubscribe from this group and all its topics, send an email to elixir-lang-ta...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-talk/5707B88E.6050402%40gmail.com.

gvim

unread,
Apr 8, 2016, 10:09:08 AM4/8/16
to elixir-l...@googlegroups.com
On 08/04/2016 14:49, Onorio Catenacci wrote:
> Can't speak for anyone else but for me when I ask for a use case I ask
> because otherwise the conversation is all based on theoretical
> considerations. I don't know about anyone else but I can't code
> theories. My coding all involves actual details so most technical

How is a question about making arrays first-class in Elixir
"theoretical"? I'm not asking about a particular difficulty I
encountered with some code so it has nothing to do with use cases.
Jose's last comment was the most informative as it seems to relate to
pattern-matching. I'm sure we can get by without arrays - I could even
use a map with numeric keys if it comes to that. I was asking about the
omission of arrays in general in Elixir's standard library and data types.

gvim

Onorio Catenacci

unread,
Apr 8, 2016, 10:15:21 AM4/8/16
to Elixir Lang Talk
You're still talking theory and generality gvim.  If arrays are so essential to getting things done in Clojure then name a specific case in Clojure that has to have arrays; that should be a piece of cake if it's that important in Clojure.  Just pick one and tell us all about it.

Even if arrays are essential to Clojure that still doesn't mean we need to add array primitives to Elixir when Erlang already has them. 

--
Onorio



On Fri, Apr 8, 2016 at 9:56 AM, gvim <gvi...@gmail.com> wrote:


--
You received this message because you are subscribed to a topic in the Google Groups "elixir-lang-talk" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/elixir-lang-talk/5K7IZWODawE/unsubscribe.
To unsubscribe from this group and all its topics, send an email to elixir-lang-ta...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-talk/5707B88E.6050402%40gmail.com.

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

gvim

unread,
Apr 8, 2016, 10:17:08 AM4/8/16
to elixir-l...@googlegroups.com
On 08/04/2016 15:05, Ben Wilson wrote:
> I would say without question that very few people at the moment are
> using Elixir for computationally expensive operations. It's an
> unfortunate characteristic of the BEAM that its number crunching
> performance is rather poor. The BEAM is built around IO bound
> applications, and it's also built with the tools (nifs and ports) to let
> you push computationally expensive operations to lower level languages
> that will always win at that game. I've built some basic ML algorithms
> in elixir and erlang just for fun, and they were positively murdered by
> even the Go equivalents, much less Rust or C.
>
> I'm not sure what deep nesting has to do with arrays. There's nothing
> intrinsic to nesting that says we're gonna use index based access. Maybe
> the use case is just a treewalk. Obviously if you use an array you can
> nest it, but it sounds like what you're really talking about is random
> access into deeply nested structures, where index is a desired access
> pattern, and maps with integer keys won't do.
>

Yes, I had in mind the type of nested data structure where indexed
access is essential. Maybe that's what it comes down to, then - BEAM's
limitations - in which case I can see how arrays/vectors may not be a
good choice. The NIF option, however, leaves me a bit cold as I've heard
bad things about them in Erlang.

gvim

Peter Hamilton

unread,
Apr 8, 2016, 12:20:11 PM4/8/16
to elixir-l...@googlegroups.com
It sounds like there are two proposals that can emerge from this.

1) Add native syntax for arrays. Something like %[1,2,3,4] (just pulling that out of thin air). This is a fairly controversial one, largest argument against is that pattern matching will be difficult.

2) Add a stdlib module for Arrays. Similar discussions: 

If #1 is the goal, I think the pattern matching is a pretty big hindrance.
If #2 is the goal, I think everyone should review those 3 threads and then start a discussion around specifically creating an Array module and whether it fits with the community's direction and the purpose of the stdlib.

Just my 2 cents.

--

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.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-talk/5707BD61.5070306%40gmail.com.

José Valim

unread,
Apr 8, 2016, 12:29:02 PM4/8/16
to elixir-l...@googlegroups.com
Thanks for the summary Peter. It felt at times folks were talking past each other and I think that sums it up well.



José Valim
Skype: jv.ptec
Founder and Director of R&D

gvim

unread,
Apr 8, 2016, 1:01:59 PM4/8/16
to elixir-l...@googlegroups.com
On 08/04/2016 17:19, Peter Hamilton wrote:
> It sounds like there are two proposals that can emerge from this.
>
> 1) Add native syntax for arrays. Something like %[1,2,3,4] (just pulling
> that out of thin air). This is a fairly controversial one, largest
> argument against is that pattern matching will be difficult.
>
> 2) Add a stdlib module for Arrays. Similar discussions:
> Queues:
> https://groups.google.com/d/topic/elixir-lang-core/zvsBt6ndLwk/discussion
> Math:
> https://groups.google.com/d/topic/elixir-lang-core/5qxH1apXbzQ/discussion
> Lightweight Stdlib and the erlang ecosystem:
> https://groups.google.com/d/topic/elixir-lang-core/xjJtFs1ggT4/discussion
>
> If #1 is the goal, I think the pattern matching is a pretty big hindrance.
> If #2 is the goal, I think everyone should review those 3 threads and
> then start a discussion around specifically creating an Array module and
> whether it fits with the community's direction and the purpose of the
> stdlib.
>
> Just my 2 cents.

Yes, something like %[1, 2, 3, 4] is what I had in mind. What are the
problems with pattern-matching arrays, incidentally?

gvim

José Valim

unread,
Apr 8, 2016, 1:38:55 PM4/8/16
to elixir-l...@googlegroups.com
Pattern matching is implemented at the VM level. So if we implement a new type like array, it would have to be implemented in terms of the existing types that can be compiled to patterns within the VM restrictions.

The description above may sound too abstract, so I'd suggest to implement an array/1 macro that returns arrays and can be used in patterns. At the simplest level, you can implement arrays as maps:

    array([:foo, :bar]) == %{0 => :foo, ...}

But then expand it to be a proper type that supports operations like push and pop efficiently while keeping the pattern matching semantics.
--
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/d/optout.


--

Peter Hamilton

unread,
Apr 8, 2016, 1:42:51 PM4/8/16
to elixir-l...@googlegroups.com
Pattern matching is provided by BEAM, so we can only pattern match on the structures it supports and use guards it supports. So let's walk through it:

If we have %[0,1,2,3,4....] (an array of the first n numbers) then what would we (in a perfect world) pattern match on?

1. We can pattern match on the structure itself (verify that the value is indeed an array).
2. We can pattern match on any number of values in specific positions.
3. We can guard on the length of the array.

#1 is easy to do (provided there's a unique structure in place).
#3 is easy to do (we have tuple_size, length, and map_size available in guards).

#2 is the tricky one. Ignoring the Erlang array module implementation, our arrays will be composed of tuples, lists, and maps.

Pattern matching lists requires matching elements from the beginning of the list. so to match the 4th element, we would need to do [_,_,_,_,4 | _ ] = list. This is linear time.

Pattern matching tuples is fast. The 4th element is matched via {_, _, _, _, 4} and is constant time. However, the size of the tuple must be known, as the example will not match if there are more elements in the tuple.

Pattern matching maps is easy and doesn't depend on size. %{4 => 4} = map will ensure the key 4 has value 4. It is O(logn) for large maps.

What does the erlang array module look like?

Arrays have an odd structure. Here are some examples:

{:array, 0, 10, :undefined, 10}

We have an :array, the next slot is 0 (it's empty), it's order of magnitude is 10, it has a default value of :undefined, and the actual data right now is just "10 empty slots".

{:array, 18, 100, :undefined,
 {10,
  {:undefined, :undefined, :undefined, :undefined, :undefined, :undefined,
   :undefined, true, :undefined, :undefined}, 10, 10, 10, 10, 10, 10, 10, 10,
  10}}

Again, we have an :array, the next slot is 18 (I set 17 to true), it's order of magnitude is 100, default is still :undefined, the data is "10 empty slots", 10 slots (of which the 7th is true), "10 empty slots" * 9.

{:array, 118, 1000, :undefined,
 {{{:undefined, :undefined, :undefined, :undefined, :undefined, :undefined,
    :undefined, true, :undefined, :undefined},
   {:undefined, :undefined, :undefined, :undefined, :undefined, :undefined,
    :undefined, true, :undefined, :undefined}, 10, 10, 10, 10, 10, 10, 10, 10,
   10},
  {10,
   {:undefined, :undefined, :undefined, :undefined, :undefined, :undefined,
    :undefined, true, :undefined, :undefined}, 10, 10, 10, 10, 10, 10, 10, 10,
   10}, 100, 100, 100, 100, 100, 100, 100, 100, 100}}

Again, :array, 118 is the next slot (I set both 7 and 117 to true), it's order of magnitude is 1000. default is still :undefined. The data is a bunch of entries, each representing a range of 100. The first one has 7 and 17 set to true. The second one has 17 set to true (to represent  117). The rest are just "100 empty slots".

This is hard to pattern match on. Length and type are easy, but pattern matching on a particular index is hard because it changes depending on the length.

Hope that helps explain it,

Peter
--
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.

Myron Marston

unread,
Apr 8, 2016, 9:56:19 PM4/8/16
to elixir-lang-talk
On Friday, April 8, 2016 at 7:17:08 AM UTC-7, g vim wrote:
Yes, I had in mind the type of nested data structure where indexed
access is essential. Maybe that's what it comes down to, then - BEAM's
limitations - in which case I can see how arrays/vectors may not be a
good choice. The NIF option, however, leaves me a bit cold as I've heard
bad things about them in Erlang.

gvim

Maybe this is my lack of experience with a wide range of other languages showing through, but I tend to think of elixir tuples as being arrays (they provide constant time access to the elements by index, and AFAIK, are layed out sequentially in memory like a C array) and lists as being linked lists.  While tuples are normally used for fixed- size heterogenous collections and lists for variable-sized homogenous collections, there's no hard-and-fast rule about that.  If what you're looking for is fast, constant-time access to an item in a collection by index, tuples work great for this.  In my benchmarks, tuple access by index takes about 0.1µs, regardless of the size of the tuple and which index is being accessed.

Granted, tuples are not going to work very well if you need to repeatedly update the collection (since tuples are not designed for efficient sharing the way lists and maps are).  In our case, this hasn't been a problem -- we use maps while building an index and then convert it to a tuple for later use when our nested data structure is queried.

I'm not familiar with Clojure at all.  Is the thing Clojure vectors provide over Elixir tuples efficient repeated updates?

Myron

José Valim

unread,
Apr 9, 2016, 4:35:29 AM4/9/16
to elixir-l...@googlegroups.com
I'm not familiar with Clojure at all.  Is the thing Clojure vectors provide over Elixir tuples efficient repeated updates?

Clojure vectors is structured similar to large Elixir maps (based on HAMT).

Here is a series of articles on the topic: http://hypirion.com/musings/understanding-persistent-vector-pt-1

Here is the latest paper (that I know of) that attempts to improve on Clojure/Scala implementations: http://infoscience.epfl.ch/record/169879/files/RMTrees.pdf



José Valim
Skype: jv.ptec
Founder and Director of R&D

--
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.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-talk/8453f2ab-ae9e-4cfa-9a3b-5eba9e87a2af%40googlegroups.com.

Ben Wilson

unread,
Apr 9, 2016, 9:55:27 AM4/9/16
to elixir-l...@googlegroups.com
So basically a map with integer index keys would serve the same role?

--
You received this message because you are subscribed to a topic in the Google Groups "elixir-lang-talk" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/elixir-lang-talk/5K7IZWODawE/unsubscribe.
To unsubscribe from this group and all its topics, send an email to elixir-lang-ta...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-talk/CAGnRm4L-FrPhsjARBXMcvJLgegCf7yRGwt-tmYGDz8ZSAyLRFg%40mail.gmail.com.

gvim

unread,
Apr 9, 2016, 10:26:41 AM4/9/16
to elixir-l...@googlegroups.com
On 08/04/2016 15:05, Ben Wilson wrote:
> that will always win at that game. I've built some basic ML algorithms
> in elixir and erlang just for fun, and they were positively murdered by
> even the Go equivalents, much less Rust or C.
>
I think comparing Elixir with Go or any binary-compiled language is
apples to oranges. I'd be more interested in how Elixir computations
compare with Python or Ruby.

gvim


Ben Wilson

unread,
Apr 9, 2016, 10:37:39 AM4/9/16
to elixir-l...@googlegroups.com
That too actually very rapidly turns into an apples to oranges comparison. Ruby and Python go out of their way to push computationally expensive functions to C as well. IIRC even plain python and plain ruby beat elixir in single threaded arithmetic. However again it's hard to call this an apples to apples comparison because python and ruby have put a lot of effort over the last few years into making bare arithmetic calls as close to C operations as they can. Ruby mathematical performance used to be a lot worse in the 1.X days IIRC.

Setting that aside, I'm surprised you aren't addressing the developments in this thread Re: Clojure vectors as HAMTs. This is a relatively major development as far as the overall goal of this thread is concerned. I would be curious to see some benchmarks of various array like operations on a map as opposed to the older `:array` module.



gvim


--
You received this message because you are subscribed to a topic in the Google Groups "elixir-lang-talk" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/elixir-lang-talk/5K7IZWODawE/unsubscribe.
To unsubscribe from this group and all its topics, send an email to elixir-lang-ta...@googlegroups.com.

Peter Hamilton

unread,
Apr 9, 2016, 10:38:53 AM4/9/16
to elixir-l...@googlegroups.com

I actually like the idea of %[a, b, c] being shorthand for %{0 => a, 1 => b, 2 => c} and having %[a, b, c][1] == b.

I don't have a strong use case personally, I just think that syntax would gel well with the rest of the language. I suppose a sigil would accomplish that fairly easily.


gvim

unread,
Apr 9, 2016, 10:45:38 AM4/9/16
to elixir-l...@googlegroups.com
On 09/04/2016 15:37, Ben Wilson wrote:
> That too actually very rapidly turns into an apples to oranges
> comparison. Ruby and Python go out of their way to push computationally
> expensive functions to C as well. IIRC even plain python and plain ruby
> beat elixir in single threaded arithmetic. However again it's hard to
> call this an apples to apples comparison because python and ruby have
> put a lot of effort over the last few years into making bare arithmetic
> calls as close to C operations as they can. Ruby mathematical
> performance used to be a lot worse in the 1.X days IIRC.
>

Yes, I appreaciate Python and Ruby use a lot of C for computation so
maybe Elixir can also call these languages when something heavier is
need. I had a look at ZeroMQ a while back and that looked promising.

> Setting that aside, I'm surprised you aren't addressing the developments
> in this thread Re: Clojure vectors as HAMTs. This is a relatively major
> development as far as the overall goal of this thread is concerned. I
> would be curious to see some benchmarks of various array like operations
> on a map as opposed to the older `:array` module.
>

I have been following these developments but, like I said, I don't have
a CS background so I'm not in a position to comment on implementation
details.

gvim

José Valim

unread,
Apr 9, 2016, 11:01:21 AM4/9/16
to elixir-l...@googlegroups.com
So basically a map with integer index keys would serve the same role?

Kinda. You still need to answer questions what is the performance of operations like concat, push, pop, shift, unshift. For example, if you add one element at the beginning (unshift), will you have to shuffle all of the indexes? That's not efficient. Then you need to store the offset and the size in the data structure (which is ok but it means it won't be pattern matchable).

José Valim

unread,
Apr 9, 2016, 11:19:43 AM4/9/16
to elixir-l...@googlegroups.com
Yes, I appreaciate Python and Ruby use a lot of C for computation so maybe Elixir can also call these languages when something heavier is need. I had a look at ZeroMQ a while back and that looked promising.

It is not only about performance, it is about semantics. We want Elixir vectors to be immutable, so how to implement them efficiently? Mutable arrays have been discussed and implemented at length. On the other hand, we have papers as recent as 2012 discussing improvements to immutable vectors.

This thread is a bit maddening because Elixir is being compared against everything and nothing at the same time. Elixir is Elixir. It is better at somethings, it is worse at others. Give me a problem you would like to solve and this discussion is going to be much more productive. Almost everything else is going to be an apples to oranges comparison when you don't have a problem in place.

Peter Hamilton

unread,
Apr 9, 2016, 11:46:05 AM4/9/16
to elixir-l...@googlegroups.com


On Sat, Apr 9, 2016, 8:01 AM José Valim <jose....@plataformatec.com.br> wrote:
So basically a map with integer index keys would serve the same role?

Kinda. You still need to answer questions what is the performance of operations like concat, push, pop, shift, unshift. For example, if you add one element at the beginning (unshift), will you have to shuffle all of the indexes? That's not efficient. Then you need to store the offset and the size in the data structure (which is ok but it means it won't be pattern matchable).
I'm still not super clear on what we would pattern match on, especially if these are large data structures. Some form of partial matching might be useful, but my guess is that in practice it wouldn't be used very frequently. A guard for array size and a match on type are really the main things, and those both should be easy enough. (Size might be tricky).

--
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.

José Valim

unread,
Apr 9, 2016, 12:54:08 PM4/9/16
to elixir-l...@googlegroups.com
I can at least imagine matching on them like I would on maps:

case map do
  %{^key => value} ->
  ...
end

Except in this case I would match on certain indexes.


José Valim
Skype: jv.ptec
Founder and Director of R&D

Reply all
Reply to author
Forward
Message has been deleted
0 new messages