I believe I’m on the right track in converting my first function to only use assignments and loops. I know this is against functional programming, but it’s what a professor wants.
Recursive function:
fun sub (x, y, []) = []
| sub (x, y, z::zz) = if x = z then y::sub(x, y, zz)
else z::sub(x, y, zz);
Iterative translation:
fun sub2 (x, y, z) =
let val ret = ref []; val temp = z;
in
while !temp <> []
do (if x = hd(!temp) then ret := !ret::y; temp := tl(!temp)
else ret := ret::hd(!temp); temp := tl(!temp));
!ret;
end;
I receive the following errors running on smlnj. The first on the line with the do, and second being at the end.
Error: syntax error: replacing END with EQUALOP
Error: syntax error found at EOF
I’d appreciate help debugging or perhaps a cleaner way to accomplish this iterative function.
Why oh why would he ever wan’t that? Never mind…
There are quite a few problems.
!temp <> nullwill make the restriction. It would be “best practice” to use the List.null function instead.!ret;should not be there as your sequence stops, elseendwill become part of the sequence which will fail.retin you else part of the condition.'a * 'a listand thus takes an element and then a list of elements. One way of fixing this and still preserving the order of elements is to use the append (@) function and then placing the element to append in a singleton list. However there are so many ways of handling this in a better way as the append function performs very poorly on big lists.Following is a function that works:
One obvious thing that can be improved here is that you always update temp with the same value. So this could be factored out. And the condition could be changed to a case instead
Especially notice how the elements are not appended but to the resulting list, but placed in the front and then at the end the resulting list is reversed to get the correct order. This will give you much better performance on big lists. There are however still better ways of doing this when you go imperative style in SML.
As you have already seen, it can be done in a functional way. But it could also be done simpler. Consider the following using map.