Although arrays are rather optimized for operations like this now, compared to earlier, they are still arrays as in C-arrays. That means shift and unshift isn't necessarily a very smart operation. Tail functions, i.e push and pop, wouldn't typically be as bad (especially pop since that wouldn't have to change anything ever).
That said, list operations used to be incredibly slow when each operation reallocated the whole array.
Actually. shift/unshift. push/pop can simply use realloc and never have to actually copy all elements like the head operations do.
To clarify:
shift a => a = a[1..]; unshift a, value => a = ({value}) + a push a, value => a += ({ value }) pop a => a = a[..strlen(a)-2]
I don't know if unshift and push operations are optimized but I'm guessing they might be if there's free space on the head or tail of the array a.