0

I'm not certain of the language to use for describing the issue I've encountered, so I'll just illustrate it with an example.

Essentially, it seems that variable assignment with arrays works differently from variable assignment with non-arrays.

Example 1: numbers (behaviour = expected behaviour; description below):

(%i4)   foo1:0$
        bar1:foo1$
        bar1:1$
        foo1;

(%o4)   0

Here, I've assigned bar1 to foo1 and then reassigned bar1 to 1 and then returned foo1. As expected, the value of foo1 has not been changed.

Example 2: lists (behaviour = expected behaviour; description below):

(%i8)   foo2:[0,0]$
        bar2:foo2[1]$
        bar2:1$
        foo2;
(%o8)   [0,0]

Same idea as example 1, but with lists. N.B. the behaviour is the same if bar2:foo2 and bar2:[1,0], so I didn't include that case, here.

Example 3: array (behaviour != expected behaviour; description below)

(%i12)  foo3:[[0,0], [0,0]]$
        bar3:foo3[1]$
        bar3[1]:1$
        foo3;
(%o12)  [[1,0],[0,0]]

Here it seems that an assignment of an element of the list bar3 also affects an the original array foo3.

I didn't think variable assignment worked like this -- it seems like an inconsistency to me; however, I have very little experience with programming.

Any insight would be greatly appreciated!

Rax Adaam
  • 790
  • 3
  • 11
  • The short answer that's the expected behavior, because `bar3:foo3[1]` is essentially telling you where is the list of items instead of just giving you the items. This "where is the stuff you want" is called a reference in computery terms. – Robert Dodier Oct 08 '21 at 00:20
  • Thanks Robert. What would be the "best" or "standard" practice for avoiding this issue, then? using `copy` all the time? I just had the same issue with `listA:listB`, `listB[1]:foo` resulting in `listA[1]` being assigned to `foo`, which I didn't expect (either). – Rax Adaam Oct 08 '21 at 01:21
  • 1
    Calling `copy` is a way to avoid changing the original list, as you know already. A more general approach, which I try to apply, is so-called functional programming, which just means programming without side effects. A side effect is something that happens aside from computing a function result. Assignment is a side effect, and so is printing output, so in a practical sense side effects can't be avoided entirely. However, to the extent that you can avoid side effects, it is easier to comprehend what is going on. – Robert Dodier Oct 08 '21 at 19:47
  • 1
    In the case of working with lists, for example, I try to think about transforming the whole list into another whole list, rather than walking down the list and modifying the elements one by one. E.g. `list2: map(lambda([x], if x > 0 then 2*x else x + 5), list1);` to create a new `list2` by modifying `list1`. A side-effect-ful approach would be something like `list2: copy(list1); for i thru length(list2) do if list2[i] > 0 then list2[i]: 2*list2[i] else list2[i]: list2[i] + 5;` That said, maybe `copy` makes the most sense for the problems you're working on; I wouldn't rule it out a priori. – Robert Dodier Oct 08 '21 at 19:52
  • Thanks for the clear guidance, Robert! Indeed, the stuff I'm working on is often lists of strings, where the value of one element requires the value of the previous / subsequent element to have been determined, already. Perhaps there is some way to achieve such transformations without side-effects but, if there are, they are beyond my level of insight, for now! Something for me to ponder, though. Cheers – Rax Adaam Oct 08 '21 at 23:25

0 Answers0