POV-Ray : Newsgroups : povray.off-topic : Liquid Physics : Re: Liquid Physics Server Time
1 Oct 2024 09:24:23 EDT (-0400)
  Re: Liquid Physics  
From: Invisible
Date: 31 Mar 2008 10:56:14
Message: <47f1099e@news.povray.org>
>> Ah, right, so it's overloaded but that's not shown in the article?
> 
> Yup, it is in the source code however.

Ah, OK. I thought it was just a typo or something...

>> (BTW, I thought printf() was only for C, not C++?)
> 
> Well it is for C, but anything you can do in C you can do in C++.  Not 
> that it's a good idea though...

Ah yes, C++ is a superset of C. But I was thinking (hoping?) that in C++ 
you have something less hellish than prinf() to play with...

>> Did the Haskell version look "readable"?
> 
> Not really, I tried to add some to your code to show what I meant with 
> the other evaluate function, but I couldn't work out what was going on!

No, Haskell doesn't support overloaded functions, so you'd have to make 
some moderately radical (oxymoron?!) alterations to make it work.

> Seems logical, but without thinking about it too much, how would you 
> keep track of the state of the system while it's running?

Ah, grasshopper, you are still thinking in imperative terms. ;-)

A true Haskeller would define a notionally infinite list which 
notionally contains the entire state of the system at every future point 
in time. Examining the elements of this list causes the integration to 
actually be performed, and assuming you let go of the start of the list, 
the GC will delete each state after it has been calculated.

In other words, define an infinite list, and then map some monadic 
function over it which displays the state of the screen or dumps it to a 
file or otherwise "does" something with it. And the result will be more 
or less like this C++ example.

Now, if you want to use *user input* to alter the integration as it 
proceeds, then you must take an somewhat different approach. (See below.)

> Are you 
> basically saying that variables are write-once in Haskell?

You *could* put it that way. It would be more correct to say that a 
variable is *defined* as having a specific value in Haskell. Consider this:

   let node1 = Node {next = node2, prev = node4}
       node2 = Node {next = node3, prev = node1}
       node3 = Node {next = node4, prev = node2}
       node4 = Node {next = node1, prev = node3}
   in ...

As you can see, it's not so much that you can only assign once to a 
variable, it's that you are *defining* what a variable's value *is*. The 
compiler will chase dependencies - even circular ones - and resolve them 
for you, figuring out what order to initialise everything and so forth.

(You can't really speak of assigning several values to the same variable 
"one after the other" because [pure] Haskell function don't have any 
notion of "time".)

> So I couldn't do something like:
> 
> currentState = Integrate(currentState);

No, you couldn't.

You could, however, write

   animate state = do
     dispaly state
     let new_state = integrate state
     animate new_state

which will display the initial state, call your integrate function to 
compute the next state, display that state, and so forth. (This method 
*does* allow you to accept user input and do something different based 
on what the user input is.)

A third way would be to use explicitly mutable state - something like this:

   state <- takeMVar my_state
   writeMVar (integrate state)

But there's no particular advantage in doing that here, and it just 
takes more typing to write out.

-- 
http://blog.orphi.me.uk/
http://www.zazzle.com/MathematicalOrchid*


Post a reply to this message

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