You get the correct result. But you don't take it into some variable, and thus your mylist still "points" to the original data.

Keep in mind that there's no in-place data mutation in Elixir. You can't change the content of mylist. You can only invoke the function which will return the new data based on the original one. You need to take the result of the function in another variable. You can also take the result into the variable of the same name in which case the variable is "rebound" - it will point to a different data, while the original data is unaffected.

This should prove that your data is immutable. Var list2 holds the modified version of the to-do list, but the original is not modified. As explained in section 2.4.5, as much of the data as possible will be shared between two instances.

If one permist entering a list of titles, the result of TodoList.entries(....) becomes ugly: not simply a list of entries, but probably also a list of simple entries mixed with lists of entries: e.g.
[["bookmaker","Vet"], "Dentist",.....]

Yes, this happens because your first add_entry will insert a "plain" title (i.e. not a list). The next add_entry then builds a so called improper list, where the tail is not a list. Instead the tail will be the first entry you added, and the result can then look weird. What's worse, it can be hard to interpret such result, because you may end up with a potentially deep nested list.

This is why we use [title] in the original code. It ensures that when the first entry is inserted for some date, we immediately create a one-element list. Subsequent invocations of add_entry will just prepend the new element to the properly constructed list, so we know we always have a list of titles.

It's also worth looking how HashDict.update works. It's explained in the help for Dict.update.

Something is strange there. The output is definitely not expected if you use just title, instead of [title]. My guess is that the newer version of the module is somehow not loaded. I'd suggest you exit the shell, make sure to delete any .beam files and try again. Maybe by just directly copy-pasting to the shell.

Notice the character | between two elements. This is an indication you have an improper list. The tail of the list is not the list itself. This is quite expected, since in the first update, we created a string under the given key. The next update, however, assumes the value is list, and appends with

[title | titles]

But titles is not a list itself. Now, that code won't actually break, but you'll get an improper list. This now may become a problem, because many functions won't work anymore:

In practice, improper lists are something you probably never need to use. I don't remember I've ever needed them.

The bottom line is to keep in mind you always construct the desired data format. In the given example, we want to keep the list of entries under the given date. Thus, by using [title] in the third argument to HashDict.update, we make sure that we'll construct the list when adding the first entry on a given date. Subsequent updates then prepend new entries with [title | titles], and that will work properly only if whatever is in titles is in fact a list.