Yazoo ---> Online Help Docs ---> Yazoo scripting ---> Arrays

Aliasing and jamming

Just as a member can stand in for another by means of an alias, so can it do for array elements; and likewise elements of one array can impersonate elements of another and even simple members, with some provisos. All moves in this masquerade ball are made by way of the old equate-at operator `=@' and its relatives. Simple members can always be aliased to arrays, no problem:


    array_1[5] :: array_2[10] :: al :: double
    al = @array_1[4]
   

We can also alias arrays to other arrays, provided we retarget all of the elements at once to some contiguous block of memory. So after the last two lines we can write


    array_1[1, 5] = @array_2[4, 8]
   

but not


    array_1[3, 5] = @array_2[4, 6]
   

except in the obscure case where indices 3-5 span one complete member (see the discussion in the next section).

The caveats on array-aliasing follow from the rule that elements of an array have to span contiguous memory. There is a way to get around this rule, namely by using proxies. A proxy array is defined by using a variant of the normal define operator: #::.


    array_3[5] #:: double
   

For most practical purposes array_1 and array_3 are equivalent; however, the elements of array_3 can each point to completely different places in memory (they are all initially void). We can now re-alias the members of the array one-by-one, though not all at once as with a normal array. After


    array_3[4] = @al
   

we end up with an array consisting of {*, *, *, 0, *}.

Proxy arrays defined with the void type are most useful, as they can store any collection of aliases. But we do have to be careful about creating new elements of void proxy arrays, because we don't want to redefine the member type. Consider the following code:


    u :: ulong
   
    proxy_array[2] #:: *
    proxy_array[1] = @u
    proxy_array[2] :: slong     | error -- can't redefine the type of element 2
   

The problem here is that the last line tried to both create a variable and specialize the member type of the second element of the proxy array. As explained in the next section, all elements of proxy_array are contained within a second member, and because all elements of a member must be specialized at once this operation is illegal. To properly construct the slong variable without trying to specialize the array we should have written:


    proxy_array[2] @:: slong
   

carefully using the variable-define operator.

Unlike normal array elements, elements of proxy arrays are always void when they are formed. Thus


    my_array[2] #:: double
   

initially contains two void members even though it was assigned the primitive double type, and


    my_array[+3]
   

will create a void third member regardless of whether elements 1 and 2 are still void.

An obnoxious and, unfortunately, unavoidable characteristic of Yazoo's arrays is that they can become `jammed', meaning that they obstinately refuse to be resized. This can only happen if there exists some alias of the array floating around when the resize is attempted. Whenever part of an array is aliased, certain elements of that array can be accessed by two members, so adding or removing elements by resizing either one of its members would also force a resize of the other member. There are cases in which this can't be done without going into fractional indices --- but mathematical limitations aside, resizing an unrelated member would violate the founding principle that no line of code may disrupt other regions of memory that it did not not explicitly name. So for the common good, Yazoo disallows any resizes that would disrupt other members, and it does this by jamming array indices that are double-referenced.

Here is an example of a partly-jammed array, and various legal and illegal attempts at resizing it.


    array_1[3][10] :: ulong
    array_2[4] := @array_1[2][4, 7]  | jams 4 indices of array_1
   
    array_1[*][^12]       | legal
    array_2[^12]          | no, this would cause problems
    delete array_1[*][5]  | not legal
    delete array_1[1]     | legal
   
    remove array_1
    array_2[+3]      | legal only because we removed the jamb
   

Explicit aliases always jam arrays. On the other hand, tokens---unnamed references to objects that are found in sets and function arguments---can never jam arrays. In other words:


    al[1, 3] := @my_array[4, 6]   | jams these elements
    my_array[4, 6]                | does not jam
   

Tokens are `unjammable', both in the sense that they cannot jam, and that they will become `unjammed'---i.e. permanently deactivated---if their referent is resized through another member. Unjammability is on balance a good thing, since it keeps arrays that were passed as function arguments from getting gummed up. The token basically deactivates when the array is resized, and will only be renewed when the function is called again from that same point in the script.

But unjamming can also cause problems, most commonly in the case of a user-defined set.


    a[10] :: ulong, b :: c :: ubyte
    objects :: { a, b, c, a[9] }
   
    a[^8]
   

Here the fourth element of the objects set will become unjammed when `a' gets resized, and we will get an error if we then try to use it. Had we instead defined the fourth member explicitly with member\_4 := @a[9], then the error would have occurred earlier, when we tried to resize the array, in order to protect the alias. Notably, the first element of objects will remain intact in either case since it points to `a' which is a composite variable, not to any of a's indices---a point which we'll elaborate on in the next section.


Prev: Resizing   Next: Members as indices


Last update: July 28, 2013

Get Yazoo scripting language at SourceForge.net. Fast, secure and Free Open Source software downloads