Let us return to the topic of functions which manipulate lists, and see how to write them in idiomatically correct Mythryl.

We have presented such functions previously in these tutorials, but they were written in a “C written in Mythryl syntax” style which would make any experienced Mythryl programmer wince.

Recall that the fundamental operator for constructing lists is the
Mythryl ’!’ operator — what Lisp calls `cons`. By repeatedly
using ’!’ to prepend values to the empty list, we can build up any
valid Mythryl list:

linux$ my eval: "abc" ! []; ["abc"] eval: "abc" ! ("def" ! []); ["abc", "def"] eval: "abc" ! ("def" ! ("ghi" ! [])); ["abc", "def", "ghi"]

Recall also that Mythryl functions allow pattern matching against arguments.

In fact, we now know that all the “argument lists” we have been using in our functions in the tutorials have really been extracting values from argument tuples via pattern matching. (I warned you that pattern matching keeps popping up in Mythryl where you least expect it!)

Put those two facts together with our new knowledge that
Mythryl functions may accept arguments of any type — in particular,
lists — and that Mythryl function syntax can encode implicit
`case` statements, and we are now able to understand one of
the list idioms dear to the Mythryl programmer’s heart:

#!/usr/bin/mythryl fun sum_list list_of_integers = sum_it (list_of_integers, 0) where fun sum_it ( [], sum) => sum; sum_it (i ! is, sum) => sum_it( is, sum + i); end; end; printf "%d\n" (sum_list [1,2,3,4] );

Running the above will give you:

linux$ ./my-script 10

The above is a list-processing idiom that you will see over and over again, and if you write any significant amount of real Mythryl code, you will write it over and over again.

Three points to note:

- The
`where`syntax.We could have written the above as the entirely equivalent

#!/usr/bin/mythryl fun sum_list list_of_integers = { fun sum_it ( [], sum) => sum; sum_it (i ! is, sum) => sum_it( is, sum + i); end; sum_it (list_of_integers, 0); }; printf "%d\n" (sum_list [1,2,3,4] );

but the preceding version is clearer because it motivates the

`sum_it`function before it defines it, which makes it easier for the reader to understand why the function is being defined and thus how to interpret it. - The helper function idiom.
Lists are recursive datastructures, and recursive datastructure processing calls for recursive functions, but typically the recursive function doing the work needs extra result-so-far state arguments beyond those supplied by the original caller.

These leads to a bog-standard idiom in which the externally visible function is just a wrapper for the recursive function which does the work.

In the above example, the external caller supplied only the list argument, but to compute the sum we needed an extra argument containing the sum of the list values seen so far.

- The
`[] / (i ! is)`list processing idiom.Look again at the initial parameter patterns in the

`sum_it`function:fun sum_it ( [], sum) => sum; sum_it (i ! is, sum) => sum_it( is, sum + i); end;

The

`[]`case detects end-of-iteration and returns the final result.The

`i ! is`case (read as “

and more*'i'*

s”) pries one element off the start of the list; we process it, combine what we learn from it with one or more of our result-so-far state parameters, and then finish up by calling ourself recursively on the rest of the input list.*'i'*

You will see this general pattern over and over again, until you can recognize it at a glance.

A frequent variation of it accumulates the result-so-far in a list.
In this case, by the time we reach the terminating `[]` case on
input, our result-so-far list is in the reverse order of of the
original input list. We have been taking values from the
front of the input list and adding them to the front of the
result list, so in the end the first value processed, derived from
the first element of the input list, is now at the end of the
result list.

Consequently, the `[]` case will almost always `reverse` the
result list before returning it:

#!/usr/bin/mythryl fun list_to_upper list_of_strings = f (list_of_strings, []) where fun f ( [], results_so_far) => reverse results_so_far; f (s ! ss, results_so_far) => f( ss, (string::to_upper s) ! results_so_far); end; end; map (printf "%s\n") (list_to_upper [ "abc", "def", "ghi" ] );

When run, the above produces

linux$ ./my-script ABC DEF GHI linux$

Note how the `reverse` in the `[]` clause makes the results come out
in the expected order.

Note also how the helper function is this time simply called `f`.
I do not particularly approve of this idiom, but it is one you will
see quite a bit in production Mythryl code, so it is good to get
used to it. It certainly has the virtue of brevity.

Comments and suggestions to: bugs@mythryl.org