[ANSI-Smalltalk] Smalltalk file streams

Steve Wart steve.wart at gmail.com
Mon Oct 20 02:24:31 BST 2008


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.

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.

If I am mistaken you are welcome to ignore this suggestion :)

Steve

On Sun, Oct 19, 2008 at 5:11 PM, Richard O'Keefe <ok at cs.otago.ac.nz> wrote:

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


More information about the ANSI-Smalltalk mailing list