(tl;dr It is risky to modify reference parameters like the exercise requires.)
Hello! I arrived here by way of an excellent (though advanced) book called 99 Bottles of OOP, and I’m trying out the JS track here. The sixth suggested exercise in the syllabus is “Elyses Enchantments”, which introduces arrays and some of its common methods.
I tried to be fancy and return the result in one line, which required that I ignore the normal methods of push() and pop(), so I ended up returning an updated copy of the array and leaving the original alone. For the tests that checked the returned array it worked fine, but for the multi-action tests, modifying the original was expected and so the tests failed. (I have copied one of the relevant tests below.)
const stack = [1];
insertItemAtTop(stack, 5);
insertItemAtTop(stack, 9);
const expected = [1, 5, 9];
expect(stack).toStrictEqual(expected);
Now I remember a time when modifying parameters passed by reference like this was the normal way to have the called function provide a result, but this was long before the establishment of OOP and the dominance of languages that expect it. Nowadays, it can cause all manner of frustration to have a called function modify the data that is sent in since no one expects it and the errors, when they appear, are usually subtle and pop up far from the original function call.
I recognize that this exercise is intended to introduce early concepts and common array functions to fresh coders, but solving this set off a lot of programmer alarm bells for me, and it would be wise to instill standard coding practices from the beginning. With that in mind, I have some suggestions on how to address this issue:
-
Pre-insert code in the function that copies the array. This does not guarantee that the original array will not be modified, but it does encourage it.
-
Have the function return nothing. The standard practice in procedural languages that pass back results through reference parameters is to have the functions return
void
or at least not the object itself. (I can’t think of a single functional language that returns a modified reference parameter.) -
Update the exercise description. Looking back, I see the phrase “Return the adjusted stack” in each function and recognize the intention of having them return the original array modified, and yet I can see that phrase also describing the array methods
map
andfilter
, which both return copies and not modified originals. Perhaps it can be explicit about modifying the argument? -
Change the tests to allow for array copying. If nothing else, please update the tests so that updating and returning a copy instead of the original will pass. Assigning the results of the function call to
stack
on each line should do it.
It is clear to me that this one example will not dramatically affect how people program, but I wanted to at least mention this issue since, as one person I found online talking about this issue commented, “Modern JavaScript is taking a lot of notes from the functional programming world these days… If I saw you do that in a tech interview… you would definitely not get the position.”
Thank you!