Fri Sep 21 12:17:17 EDT 2007

```

Al Falloon wrote:
>
> SevenThunders wrote:
>> Well it certainly requires some thought here.  As I see it, I now have
>> two
>> reasonable choices.  Either I pull all my matrix operations back inside
>> the
>> IO monad and avoid the matrix action as a matrix variable paradigm  (due
>> to
>> the loss of referential transparency)  or I devise some way to guarantee
>> 'safety' and use unsafePerformIO.  I suppose I can use a somewhat
>> generalized version of safety where if I can guarantee that the order of
>> operations doesn't matter to the final output then I'm OK.  In this case
>> if
>> I can make it so that reording the computations only reorders the
>> locations
>> of my matrices on the stack, but otherwise doesn't affect the contents of
>> the matrices I think I am golden.
>>
>> I believe I got burned by following a nice tutorial interpretation of the
>> IO
>> monad as a way of carrying around an undeclared state variable,  the
>> world.
>> But my little matrix IO variable is not just a world state with some
>> matrix
>> data in it, rather it appears to be a world state with a chain of
>> unapplied
>> function evaluations.  This is due to laziness I believe.  If I had a
>> data
>> structure that looked more like a world state with a reference to a
>> variable
>> in that world state, I could find a way to achieve my goals I think.
>
> think that there is still another alternative that you can consider:
> make an abstract interpreter for your matrix operations.
>
> The basic idea is to use the normal Num et. al. type classes to write
> calculations it instead builds a data structure that represents the
> calculations. You then 'interpret' the data structure in a separate
> function in the IO monad.
>
> The advantage of the approach is that you can pre-process the abstract
> data structure to recognize intermediate matrices that can be consumed
> without copying and other optimizations.
>
> The other advantage is that the matrix math itself doesn't need to be in
> the IO monad, only the interpretation, so you can use all the functional
> goodness when writing the matrix operations.
>
> I was going to whip up a small example, but I am pressed for time. So
> here is a post from Oleg that shows the idea.
> As usual his post is mind-expanding and probably a bit of overkill for
> your problem, but I was the best I could come up with, google was not my
> friend. You might have better luck (try "higher order abstract syntax"
> and "abstract interpretation" and go from there)
>
> _______________________________________________
>
>

That's an interesting approach.  However if performance is a main concern
interpreter in an inner loop of some operation.  I quite frequently write
functions that do hundreds of matrix multiplies using hundreds of different
indexed matrices, where the function iterates over the matrix index.

When I first designed my Matrix library and was interfacing it with Haskell,
I considered the possibility of actually using Haskell to compile my
computations into C.  Thus there would be a matrix data type in Haskell, but
the final output of the Haskell operations would be C code.  In retrospect
that would have had a number of advantages, perhaps both in performance and
interoperability with the 'normal' programming world.  However I also wanted
to take advantage of ghci so that I could interact with my code in real
time.  That too is probably possible with the current toolset, but it would
have taken somewhat longer to develop.
--
View this message in context: http://www.nabble.com/Sequencing-Operations-in-a-Monad-tf4446047.html#a12824919