Adding undefined to the list

I debugged the error and found that I undefined

was added to the list, which caused the crash afterwards.

I was expecting that adding something other than a list with an operator ++

would crash. But this does not apply to undefined

. Here's an example:

1> [1,2,3] ++ undefined.
[1,2,3|undefined]

      

While it doesn't crash, the list is no longer fully functional:

1> L = [1,2,3] ++ undefined.
[1,2,3|undefined]
2> L ++ [4].
** exception error: bad argument
     in operator  ++/2
        called as [1,2,3|undefined] ++ [4]

      

Why is this happening? Is this related to the main implementation of lists in erlang?

+3


source to share


2 answers


The reason is that it ++

adds a second argument to the end of its first argument, which must be a list. It doesn't process the second argument, it just adds it as it is. So:

1> [1,2,3] ++ undefined.
[1,2,3|undefined]
2> [1,2,3] ++ [undefined].
[1,2,3,undefined]

      

The reason why you can do this and also:

3> [a|b].
[a|b]
4> [a|[b]].
[a,b]

      

is that the list is the cells of a sequence list, a singly linked list, and not a single data structure per se. If the right-hand sides, called the tail, of each cell is a different cell in the list or []

, then you end up with the correct list. The left side of each cell is called the head and usually contains the list items. This is what we have in 2 and 4 above. Most, if not all, of the library functions assume lists are valid lists and will throw an error if they are not. Note that you need to actually cast the entire list to the end to make sure it is correct or not.



Each cell of the list is written as [Head|Tail]

, and the syntax [a,b,c]

is just syntactic sugar for [a|[b|[c|[]]]]

. Note that the tail of each cell in the list is a list or []

, therefore, this is the correct list.

There is no limitation as to what the list cell head and tail types can be. The system never checks it, it just does it. This is what we have in 1 and 3 above, where the tail of the last cell of the list (only the cell in the list at 3) is not a list or []

.

Sorry, please, a little over-didactic.

EDIT: I see that I've already covered this here: Functional Programming: What is a "wrong list"? p>

+1


source


In Erlang, all members are represented by a compact pointer value called Eterm

. It looks like the list manipulation functions are implemented as agnostic.

Consider from this point of view: inside the erlang VM, all Eterms are equal. Header and tail manipulation operations are counted as very fast. Since defining an opaque type Eterm

requires several operations to determine if it is a list, why bother?



The expected result in such a situation is an error, and you will receive it. Finally.

Something needs to be said to be trusted by the programmer, and when dealing with an operation that adds multiple loops and is frequently used, the potential benefit of ignoring a bad append stacks up, and the only penalty is a weird error.

+1


source







All Articles