POV-Ray : Newsgroups : povray.off-topic : Smart little programming tricks, where to find ? : Re: Smart little programming tricks, where to find ? Server Time
10 Oct 2024 23:17:14 EDT (-0400)
  Re: Smart little programming tricks, where to find ?  
From: Darren New
Date: 21 Mar 2008 12:01:15
Message: <47e3e9db@news.povray.org>
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

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.