<div dir="ltr">At the risk of getting dragged into a complicated discussion, I think it would be productive to drop the complaints about the unfortunate "PEBKAC" reference.<br><br>I think it does make sense to have areas where the spec can leave the desired behavior undefined (e.g. low memory conditions, etc.). I interpreted the "problem exists elsewhere" to mean the spec doesn't need to cover every eventuality.<br>
<br>If I am mistaken you are welcome to ignore this suggestion :)<br><br>Steve<br><br><div class="gmail_quote">On Sun, Oct 19, 2008 at 5:11 PM, Richard O'Keefe <span dir="ltr"><<a href="mailto:ok@cs.otago.ac.nz">ok@cs.otago.ac.nz</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><div class="Ih2E3d"><br>
On 17 Oct 2008, at 7:00 pm, Paolo Bonzini wrote:<br>
<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Again, an exceedingly unhelpful response.<br>
</blockquote>
<br>
To explain my short answer of PEBKAC: the keyboard and the chair are the<br>
programmer's, if that's not clear.<br>
</blockquote>
<br></div>
It most definitely wasn't.<div class="Ih2E3d"><br>
<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
The standard *can* provide methods<br>
that sometimes make sense and sometimes don't. If they don't, and the<br>
result could be infinite request of memory or an infinite loop, it's a<br>
problem of the user.<br>
</blockquote>
<br></div>
And now we are back to the ambiguous "user".<br>
<br>
The thing is, if you persist in this attitude, *everything*<br>
ends up being the fault of the woman in the ATM queue.<br>
Everyone else just says "it's not MY problem, PEBKAC PEBKAC PEBKAC".<br>
<br>
I suspect that you may be muddling up two distinguishable<br>
interpretations of "sometimes make sense and sometimes don't".<br>
<br>
(1) If the standard specifies a precondition<br>
and a method invocation violates that precondition,<br>
that's a method that "sometimes makes sense and sometimes doesn't".<br>
If the precondition is not spelled out, it's the standard's fault.<br>
If it spelled out and violated anyway, it's the programmer's<br>
fault, PROVIDED the standard provides means for the programmer<br>
to detect the fault in advance.<br>
<br>
(2) If the standard specifies a precondition and a postcondition<br>
and a method invocation satisfies the precondition<br>
but the postcondition is violated, then it's NOT the<br>
programmer's fault: if the standard has specified a result<br>
that cannot be achieved, it is the standard's fault; if the<br>
standard's result could be achieved but the implementation<br>
doesn't do that, it's the implementor's fault.<br>
<br>
Let's restructure that and introduce some technical terms:<br>
<br>
programmer error:<br>
precondition violated, programmer could have known<br>
programmer incapacity:<br>
precondition violated, programmer could not have<br>
known<br>
implementation error:<br>
precondition ok, postcondition violated,<br>
implementation wrong<br>
implementation limit:<br>
precondition ok, postcondition not established,<br>
implementation basically ok but ran out of something<br>
standard error:<br>
precondition ok, postcondition violated,<br>
no reasonable implementation _could_ get it right.<br>
<br>
<br>
The key discriminant here is the precondition.<br>
I am not saying that the standard could or should specify<br>
only things that work all the time (we'd have no floating<br>
point arithmetic in that case). But I am saying that the<br>
standard should be more explicit about preconditions. It<br>
is explicit about argument types, but that's pretty much<br>
as far as it goes.<br>
<br>
There's also the problem in something like Smalltalk that<br>
the standard has two faces. When <a href="http://5.3.1.1" target="_blank">5.3.1.1</a> says that #=<br>
only returns true and false and has no errors, it is<br>
- making a PROMISE that implementations will get this right<br>
for the standard "classes",<br>
- setting out a REQUIREMENT for users who want to define<br>
the same method.<br>
<br>
Some claims clearly cannot be taken at face value because of<br>
global resource limits: <a href="http://5.3.1.6" target="_blank">5.3.1.6</a> says that #copy has no<br>
errors, but despite that it's obvious that an attempt to<br>
copy some object may fail because there is not enough memory<br>
left. But this is something that applies to *every* method:<br>
#= could try to allocate arbitrary amounts of data on its<br>
way to a true or false. There are similar issues with<br>
opening files.<br>
<br>
The standard needs to say something about this.<br>
If there's a section of the ANSI standard that talks about<br>
it, I've been unable to find it.<br>
<br>
Note that running out of memory is an implementation limit.<br>
It's not PEBKAC. (Hare PEBKAC, hare PEBKAC, hare hare.)<br>
<br>
For an example of something that's a programmer error,<br>
nil perform: #==<br>
because <a href="http://5.3.1.15" target="_blank">5.3.1.15</a> says the behaviour is undefined if the<br>
number of arguments (here 0) does not match that implicitly<br>
required by the syntactic form of the selector (here 1), so<br>
the precondition is violated, and it is practical to check,<br>
so it's an error, not an incapacity.<br>
<br>
Anyone designing a new language would almost surely have<br>
designated a standard exception to be raised when #perform:<br>
gets an arity clash. It seems bizarre that ANSI Smalltalk<br>
has one of the most elaborate exception handling schemes<br>
around and makes so little use of it. But that's another<br>
issue.<div class="Ih2E3d"><br>
<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<br>
<br>
Certainly, it would be *insane* to require that #contents detects device<br>
files where it cannot terminate.<br>
</blockquote>
<br></div>
You keep on talking about cases where #contents cannot<br>
TERMINATE. But I was and remain talking mainly about<br>
cases where #contents cannot START. And it is not only<br>
not insane to detect that, it's quite easy.<br>
<br>
- if you only have write access to an external resource,<br>
you can *never* perform #contents on it. So it doesn't<br>
*EVER* make sense to have #contents in the <writeFileStream><br>
protocol.<br>
<br>
- if you cannot seek back to the beginning of an external<br>
resource, you can *never* find the full contents.<br>
This applies to sockets, pipes, ttys, ptys, and all that<br>
kind of thing. And at least on Windows, VMS, MCP, and<br>
UNIX variants, it's dead simple to recognise such things.<br>
To a first approximation, it doesn't make sense to have<br>
#contents in the interface of anything but a plain disc<br>
file stream.<br>
<br>
Far from being insane, this is exactly what Squeak and<br>
VisualWorks do: for the sake of #position: and #contents<br>
they won't let me open anything where those operations<br>
would not work. Why would anyone call insane what actual<br>
systems actually *do*?<br>
<br>
- if you are reading from a disc file, another process might<br>
be writing to it at the same time. This is why the 'tail'<br>
command has the '-f' option. Of course, in this case the<br>
whole notion of "THE contents" of the stream is problematic.<br>
However, the strategy of determining the size *now* and<br>
reading up to that will work (as indeed the 'tail' command<br>
normally does).<br>
<br>
So #contents belongs in <readFileStream> only,<br>
not in <writeFileStream>, and it requires a precondition<br>
something like<br>
"#contents need not work for all kinds of external<br>
file; it is implementation-defined which."<div class="Ih2E3d"><br>
<br>
<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
And it would be even *impossible* to<br>
detect in advance whether #contents on a socket would terminate,<br>
</blockquote>
<br></div>
Not relevant. Because we can't seek, we can't get the<br>
*PAST* sequence values, so it is quite certain that #contents<br>
does not make sense for a socket.<div class="Ih2E3d"><br>
<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
but yet<br>
it would be useful to provide #contents on a socket.<br>
</blockquote>
<br></div>
I doubt it. I suspect you are thinking of reading up to the<br>
end, which is quite different from #contents.<div class="Ih2E3d"><br>
<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
It's a problem<br>
that *programmers* sitting between a keyboard and a chair have to solve,<br>
not whoever writes the standard.<br>
</blockquote>
<br></div>
The standard needs to first give them the TOOLS.<div class="Ih2E3d"><br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<br>
<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
there is no "THE ... way" that the Array new: call<br>
would fail;<br>
</blockquote>
<br>
But I'd expect #contents on a 500 GB data file to fail *that same* way.<br>
</blockquote>
<br></div>
I wouldn't.<div class="Ih2E3d"><br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<br>
<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
The erratum here is that #contents belongs in <gettableStream> and<br>
<WriteStream>, not in <collectionStream> and <FileStream>. I sent<br>
another email on the subject.<br>
</blockquote>
<br>
Except that for smallish files, #contents is quite useful.<br>
</blockquote>
<br>
Indeed. <FileStream> *is* a <gettableStream> isn't it?<br>
</blockquote>
<br></div>
We both made mistakes here. No, <FileStream> isn't a<br>
<gettableStream>, but <readFileStream>, which I think is what you<br>
meant, _is_.<br>
<br>
However, <gettableStreams> in general cannot support #contents<br>
either. Do we agree that #contents belongs in <ReadStream>,<br>
<WriteStream>, and <fileReadStream>?<div><div></div><div class="Wj3C7c"><br>
<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<br>
<br>
Paolo<br>
<br>
_______________________________________________<br>
ANSI-Smalltalk mailing list<br>
<a href="mailto:ANSI-Smalltalk@lists.openskills.org" target="_blank">ANSI-Smalltalk@lists.openskills.org</a><br>
<a href="http://lists.openskills.org/cgi-bin/mailman/listinfo/ansi-smalltalk" target="_blank">http://lists.openskills.org/cgi-bin/mailman/listinfo/ansi-smalltalk</a><br>
<br>
</blockquote>
<br>
<br>
_______________________________________________<br>
ANSI-Smalltalk mailing list<br>
<a href="mailto:ANSI-Smalltalk@lists.openskills.org" target="_blank">ANSI-Smalltalk@lists.openskills.org</a><br>
<a href="http://lists.openskills.org/cgi-bin/mailman/listinfo/ansi-smalltalk" target="_blank">http://lists.openskills.org/cgi-bin/mailman/listinfo/ansi-smalltalk</a><br>
</div></div></blockquote></div><br></div>