Why did the developer perform the functions of a vector, map, and set in clojure?

Rich made functions of a vector, map and set, while a list and sequence are not functions. Why can't all of these collections be compatible?

Also, why don't we make all of these data components a function that maps position to internal data?

If we make all this composable data as functions, then in clojure only data on functions and atoms will be displayed. This will minimize the fundamental elements of this language?

I believe that a minimal, better only 2, set of fundamental elements will make the language simpler, more expressive and more flexible. Is it correct?

+5
source share
2 answers

Vectors, maps, and sets are all associative data structures. Maps are the most obvious; they simply associate arbitrary keys with arbitrary values. A vector can be considered as a card, the set of keys of which must be the set of all non-negative integers smaller than the size of the vector. Finally, sets can be thought of as cards that display keys for themselves.

It is important to understand that the consistent nature of the vector and the associative nature of the vector are two orthogonal things. This is a data structure that should support both abstractions well (to some extent, for example, you cannot effectively insert at the beginning of a vector).

Lists are simpler than vectors; they are finite sequential data structures, nothing more. A list cannot efficiently return an element at a specific index, so it does not reveal this functionality as part of its main interface. Of course, you can get a list item by index using nth , but in this case you explicitly see it as a sequence, not an associative structure.

So, to answer your question, IFn implementations for vectors, maps, and sets exist because of the extremely close relationship between the idea of ​​an associative data structure and the idea of ​​a pure function. Lists and other sequences are not inherently associative; therefore, for consistency, they do not implement IFn .

+9
source

Elogent's answer is excellent. There is another reason that for lists, it doesn't make sense to be functions:

Literal lists already have a different, very important role, so they also cannot be considered functions in the way vectors are.

Let's start with a vector containing two functions: partial and + , and the number - 5 . We can consider a vector as a function, as you know, to return a value indexed by its argument:

 user=> ([partial + 5] 2) 5 

So far so good. Suppose we want to use a list (partial + 5) instead of a vector, as you said, to return the value 5 . Will an error message appear? No! But we will not get 5 as a result:

 user=> ((partial + 5) 2) 7 

What happened? (partial + 5) returns a function - a function that adds 5 to a single argument - and then this function was applied to argument 2 .

When a list is evaluated, its first element is evaluated and should return a function. If the first item is a character, it is evaluated, and then a function in which its value is applied to arguments that are other items in the list. If the first argument of a list is itself a list, then it is evaluated as if it were at the top level. The entire expression in this internal list should return a function that will then be applied to other elements of the external list.

Since the internal list, in which the first element of the list that has already been evaluated, already has this role, it also cannot reproduce the role played by the first elements of the vector.

+2
source

Source: https://habr.com/ru/post/1246750/


All Articles