|
|
Invisible wrote:
> Haskell supports random number generators. And I/O. And asynchronous
> exceptions. It just cleanly seperates what *is* deterministic from what
> is *not*, that's all. ;-)
So does Erlang, from what I can see. Every statement always works the
same way. It's nondeterministic because it depends on the timing of
statements between asynchronous events. But once a message is in your
queue, you'll process it the same way every time. Again, as far as I can
tell from my reading so far...
Now, Erlang does have stuff like the "process dictionary" that is
imperative, but every mention of it is followed by "don't use this if
you don't know what you're doing, because it's stateful and imperative!"
>> Who throws the exception? The machine running the calculation isn't in
>> any shape to do so.
>
> I would presume the exception is just thrown to whoever is waiting for
> the answer?
Right. As an asynchronous message, unless you're not trapping it, in
which case you too throw the same message.
(You don't wait for results. You send a message, and optionally wait for
one to come back, perhaps with a timeout. But you can "link" processes,
which means a failure of one of them will cause the others to fail with
the same exit code, unless they're "trapping exits", in which case the
failure will be translated into a notification.)
So, overall, still functional.
> To be honest, I'm not really seeing a clean way to handle this in *any*
> language, but I haven't thought about it for that long yet.
Erlang does it by running the old version and new version at once. As
long as your code only makes local calls, it keeps running the old code.
If it makes a tail-recursive call to a fully-qualified method, then the
latest version of that method gets run.
So you have code like this (not in actual erlang syntax):
method myserver::loop(State)
receive {request, Params} from Sender ->
{Result, NewState} = calculate(Params, State);
send Result to Sender;
loop(NewState);
receive {upgrade, TransformFunction} ->
NewState = TransformFunction(State);
myserver::loop(NewState);
end.
So it runs along happily, processing requests, in the loop. If you want
to upgrade, you recompile the code, load the new version, write an
anonymous function that transforms the data the server is holding from
what the old version uses to what the new version uses, and tell the
server to restart the loop after passing the state through the transform.
And this is all managed by the release management code, too. *That* is
the complicated part: all the infrastructure already built.
>>> If by "simple and straight forward" you mean "assumes referential
>>> transparency but doesn't actually enforce it or make any attempt to
>>> check that it's there", then sure. Go knock yourself out. ;-)
>>
>> Where do you think it doesn't assume referential transparency?
>
> Please reparse my sentence. I said it *does* assume referential
> transparency yet does nothing to *enforce* or even *check* for it.
> In other words, if you're not careful, you can easily cause the system
> to massively malfunction with a few incautiously chosen commands.
Like what? I mean, that's true in some sense, but it's true of any
system depending on what you mean by "massively malfunction". Since
processes *can* have side-effects, you don't get referential
transparency. But I don't think you have that with monads in Haskell,
either, yes? Are references to the IO monad referentially transparent?
I thought that was kind of the point of monads.
>> By "simple and straightforward" I meant in the sense that there are
>> relatively few types and primitives and interactions between them.
>> More like Tcl or C than Ada or C++.
>
> I consider Haskell to be quite simple in this respect too.
Yes, exactly.
> I'm looking at you, Oracle. Trying to figure out where to start reading
> to actually comprehend this stuff is *far* too hard!
Just Oracle, or SQL in general? But yah, giant lumps of code like that
are a mess to grok.
I once was looking at a program called Scopus (functionality not unlike
SAP), and I spent literally a full work day trying to get a record
entered into the database.
Me: Create a contact.
It: You first have to create the company the contact works for.
Me: Create a company.
It: You have to create the city the company is in.
Me: Create a city.
It: You first have to create the salesman responsible for that city.
Me: Create a salesman
It: You first have to create the department the salesman works for.
Literally. I gave up after about 40 of these indirections, some of which
seemed circular.
--
Darren New / San Diego, CA, USA (PST)
"That's pretty. Where's that?"
"It's the Age of Channelwood."
"We should go there on vacation some time."
Post a reply to this message
|
|