On 3/18/15 4:53 AM, Elazar Leibovich wrote:
On Friday, 13 March 2015 at 17:31:09 UTC, Andrei Alexandrescu wrote:
For example the expression (assuming s is e.g. a string)
File("/tmp/a").byChunk(4096).joiner.startsWith(s)
opens a file, progressively reads chunks of 4KB, stitches them
together at no cost, compares against a prefix until it makes a
decision, then closes the file and returns the result. A putative Go
user wouldn't even dream of using HasPrefix directly on a stream
coming from a file; the whole endeavor would be a function that
painstakingly takes all of these steps by hand.
I personally, would have no idea what this piece of code is doing
upon first sight. I'll have to look at the documentation of
at least two functions to understand that, and I'll have to
think carefully about what and who would throw in case of an error.
Yah, that's a problem with documentation. Such idioms should be well known.
Something like
while (n != EOF) {
n = read(fd, buf, sizeof(buf));
if (n==-1) throw(...);
if (strcmp(buf, PREFIX) == 0) {
return buf;
}
}
return NULL;
Requires no prior knowledge, and have similar effect.
And doesn't work. The code that works is a fair amount less trivial than
that, and actually needs to do pretty much what the algorithms do.
I'd rather have a loop written by hand in my production code any day,
so that when debugging it, and reading it I'll have easier time
to understand it, even though it would cost me a few more lines
when writing the code.
No.
What if this pattern repeats a few times in the code?
So much the better.
I'd rather have a single function that have the explicit loop than
having this pattern in slight variations spread in the code.
No.
Writing code is easy, maintaining it afterwards is costly.
Agreed but works against your point.
Andrei