POV-Ray : Newsgroups : povray.off-topic : 10 things to use a Min Heap for : Re: (Tainted) Server Time
7 Sep 2024 23:27:33 EDT (-0400)
  Re: (Tainted)  
From: Orchid XP v8
Date: 20 Jun 2008 14:42:07
Message: <485bf9ff$1@news.povray.org>
>> Yeah, typically in Haskell you'd either do something like takeWhile to 
>> grab just the data you want, or write a custom loop yourself.
> 
> But by writing the loop yourself, you've separated the logic of the loop 
> from the logic the loop loops over.  I.e., your control isn't anywhere 
> near (textually) your actions.

I meant that you could write the loop and the processing logic as a 
single function, if you really wanted to. (I tend to do this if the flow 
control is complex enough that no standard combinator is likely to 
implement it easily.)

>> Wanna pass more information around? Change the state data structure.
> 
> So you have it all wrapped up in some other data structure, and you're 
> adding to that. You still have to track down places you created it, and 
> add the additional information.

True, but there shouldn't be very many of those.

> I.e., since looping requires recursion, every time you change what data 
> persists between iterations, you have to change all the recursive calls. 
> Maybe the state monad helps, and you could probably do the same thing by 
> wrapping your stuff in a record in Erlang, but that's just really 
> covering up the problem, in some ways.

Not sure what gave you that idea... Add a field to the data structure, 
and only the places that use that new field have to care about it. It's 
a lot less work than passing lots of parameters individually.

>> It's a parser library, and the usual way to implement a parser is with 
>> some kind of state machine. However, Parsec uses a parser monad to 
>> implement complex flow control (choice, iteration, back-tracking, 
>> error handling, etc.)
> 
> Oh, Erlang has that sort of stuff. I guess I could write a turn-based 
> video game as a finite state machine.

Parsec allows you to write parsers without needing to explicitly build 
state machines. Stuff like

   integer = do
     ds <- many1 digit
     return (read ds)

   decimal = do
     ds1 <- many1 digit
     char '.'
     ds2 <- many1 digit
     return (read $ ds1 ++ "." ++ ds2)

   number = do
     try decimal <|> integer

Now you can parse any valid number, without having to worry about the 
actual state machine transitions needed to do that.

> That still doesn't clarify how the 
> control flow flows. I.e., you can't just read off the steps for 
> performing a turn. Stuff like
>   Ask for a word
>   While the word is not valid
>     explain why, ask again
>   Ask for a number
>   while the number is invalid,
>     explain why, ask again
> 
> That winds up being like ten separate functions in Erlang,
> once you deal with stuff like "the thing the user typed isn't
> a number" and so on. It becomes really unobvious to me reading
> the code just what the control flow is.

Hmm, let's see:

   word <- untilM valid_word ask_for_word
   numb <- untilM valid_numb ask_for_numb

(Haskell has a function called "until", but there is no untilM function 
for some reason. However, it is not hard to implement.)

Depending on how complex the validity and requesting code is, you can 
write it inline or as a seperate function. Note that the validity check 
code is still within the IO monad, so it can output an explanation of 
why the answer isn't valid if needed.

>> In that case, it's probably best to define the information you're 
>> trying to keep track of as a data type and just add/remove fields as 
>> required when the design changes. That way you only pass around a 
>> single parameter.
> 
> Yeah, even more obscure, unfortunately. :-) Now you not only have 
> hard-to-follow control flows, but you wind up passing a large record 
> full of stuff to a function that really only needs one or two fields, or 
> you wind up extracting just those couple of fields for that call at 
> which point you're back to the same problem again.

Well... I guess it depends on just how complex your flow control is. 
Like I said, the key is finding the best way to structure your program - 
and that means seperating out all the parts that don't really influence 
each other, and finding a way of grouping things so you can get a nice 
flow of code. This is easier said than done...

-- 
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.