ReRe: why isolated components
Joe Armstrong
joe@REDACTED
Fri Aug 22 16:26:04 CEST 2003
On Fri, 22 Aug 2003, Laszlo Varga wrote:
> Hello,
> it seems that we are getting understand each other.
> At least we have no clear idea about what Joe want to have.
> Really, it seems that the motivation is to have something
> process based fault tolerancy or robustness or at least stability.
> UBF is also behind the scene, what makes me suspicious.
>
> Maybe I'm mistaken, but the main point in UBF - I think- the C level,
> the contract. It makes an UBF contract much more strict then an IDL.
> In other words, it specifies the dynamic behaviour while IDLs-are just static.
Yes. APIs are deeply flawed:
Look at this code:
silly() ->
{ok, H} = file:open("foo.dat", read),
file:close(H),
file:read_line(H).
It is stupid - yes, you can't read a line *after* you've closed the file.
Here's the API in some type system:
+type file:open(fileName(), read | write) ->
{ok, fileHandle()}
| {error, string()}.
+type file:read_line(fileHandle()) ->
{ok, string()}
| eof.
+type file:close(fileHandle()) ->
true.
+deftype fileName() = [int()]
+deftype string() = [int()].
+deftype fileHandle() = pid().
Does this help? - No way.
Add states, like this:
+type start x file:open(fileName(), read | write) ->
{ok, fileHandle()} x ready
| {error, string()} x stop.
+type ready x file:read_line(fileHandle()) ->
{ok, string()} x ready
| eof x atEof.
+type atEof | ready x file:close(fileHandle()) ->
true x stop.
+type atEof | ready x file:rewind(fileHandle()) ->
true x ready
Rule (2) says for example that in the state "ready" you can
evaluate file:read_line(fileHandle()) and it will return
something of type {ok, string()} and move into state "ready", or it
will return eof and move into state "atEof"
>
> Is not the THING about building a contract-specified component system?
Yes^100.
Contracts and APIs are *almost* equivalent.
IMHO systems should be made of black boxes (ie my famed components
that I keep blithering on about) - you check the inputs and outputs to
the BBs NOT what goes on at every single function call.
Inside a BB you might program in assembler (whatever) break all rules of
common-sense etc. But "at the door" - when you pass in or out of the
BB you *must* obey the protocol. Observational equivalence applies.
Any two BBs that behave the same way ARE equivalent.
The nice thing about doing dynamic checking is we can add non-functional
requirements.
for example:
ready x read_line -> ( {ok, string()} x ready
eof x error ) within 5 seconds
Which is way beyond the state-of-the-art in statically checked systems.
>
> If it were, i'd like it.
Then you should like this approach
/Joe
>
> Thanks for your time
> Laszlo
>
> >
> > Laszlo Varga wrote:
> > > thanks for the "answer". Right, isolation reduces the (possible) complexity,
> > > but is that the motivation for the wrapper project?
> >
> > Well, *that* is another issue.
> >
> > I don't know Joe's thoughts on the subject, but my impression is that
> > it's about coping with failures.
> > If a subroutine crashes, or if it just detects an abnormal condition and
> > logs it, this is behaviour that punches right through to the top levels
> > of the application. The "let it crash" philosophy of Erlang says: if a
> > component fails, let if fail, and don't burden the caller (or service
> > requester or whatever you name it) with analysis of the crash details,
> > just tell it that the request failed.
> > The toplevel may be unable to cope with the situation, but then passing
> > up crash details will introduce lots of coupling just for the rare case
> > of a crash - the resulting design mess just isn't worth the benefits.
> >
> > Other languages handle this via exceptions.
> > Eiffel got this right: Eiffel exceptions are unsuitable for passing up
> > information on a crash (apart from diagnostic information that helps
> > programmers and debuggers; there's no channel for passing up information
> > that would help the top-level to analyze the error).
> > Java and C++ got it wrong: they make it all too easy to pass up
> > information that allows the caller to continue. The net result being
> > that exceptions create an additional, quite tight coupling between low
> > and high levels of the system. (It's no good if the top-level of a
> > system tries to handle an InternetConnectionFailure exception just
> > because an Internet resource wasn't available ten call levels below it...)
> >
> > Erlang's idea is to separate the layers of processing into separate
> > processes, and to let the process crash. The advantage is that this
> > quite nicely handles any memory leaks that might occur on lower levels
> > (even garbage-collected languages can leak memory: when calling out into
> > C, or when accumulating larger and larger structures).
> > I consider it a disadvantage that this interleaves the issues of crash
> > protection and asynchronous message passing. However, my Erlang
> > experience is *very* limited, so please consider the latter just an
> > uninformed opinion.
> >
> > HTH
> > Jo
> >
>
More information about the erlang-questions
mailing list