That's not very useful, but you get an idea of the problem and what I was trying to do. Using iterators/generators is nice here because I don't have to worry about too much input filling up memory. Also, I don't build a list I don't need or use. Unfortunately, Erlang doesn't have iterators. I thought I would use lists instead and work from there. I could have had the input function read everything into a list, the transformation function transforms it into another list, and the output function writes a list's contents to disk. It wouldn't have been pretty, but it would have worked. Part way through coding this, I realized that Erlang has a great solution to this: concurrency.from __future__ import with_statement import csv def input(filename): with open(filename, 'rb') as f: for row in csv.reader(f): yield row def transform(rows): rows = iter(rows) while True: rows.next() yield rows.next() def output(rows, filename): with open(filename, 'wb') as f: writer = csv.writer(f) writer.writerows(rows)
Stay tuned tomorrow, when the hero attempts to use powerful Erlang concurrency and ends up hoisted on his own petard.
2 comments:
Iterators can be easily defined in
Erlang - either with strict of lazy
semantics, or using processes.
for example:
map(F, [H|T]) -> [F(H) | map(T)];
map(F, []) -> [].
a lazy map
map(F, [H|T]) ->
{F(H), fun() ->
map(F, T)
end}.
so map(fun(X) -> 2*X end, [2,4,7])
returns {4, F1}
and F1() returns {8, F2}
and F2() return {14, F3}
and so on
Or you can just use chains of processes
Right. I was considering using a post to look at the functional style you describe here, but you've done such a good job that I think I'll pass on a longer explanation.
Post a Comment