[Haskell-cafe] Re: Top Level TWI's again was Re: [Haskell] Re:
gk at ninebynine.org
Tue Nov 23 04:51:02 EST 2004
I think this is a useful debate, because it touches on how Haskell meets
real-world programming needs, so I shall continue in that spirit...
At 22:22 22/11/04 +0000, Keean Schupke wrote:
>Obviously without knowing the details I am speculating, but would it not
>to do a first pass of the XML and build a list of files to read (a pure
>function) this returns
>its result to the IO monad where the files are read and concatenated
>together, and passed
>to a second (pure functional) processing function. If written well this
>can take advantage
>of lazy execution, so both functions end up running concurrently.
In an ideal world, it is certainly possible to separate the pure and
non-pure aspects of the code, and do something like you suggest. But my
position was that I was working with an existing codebase (HaXml) which had
not been structured with this requirement in mind, and I absolutely did not
want to start from scratch (as it was, I was forced into some substantial
refactoring). This was one case where, in order to get any result at all
with the time/effort available to me, I needed to hide the I/OI within an
otherwise pure function.
Yes, there are better ways but, being a "Bear of Very Little Brain", I have
to work with the tools, intellectual and otherwise, that are at my
disposal. Most software is not built in the optimum fashion, or even
anything close to it. I would suggest that one of the challenges for
functional programming is to maker it easy to "do the right thing". I came
to functional programming with quite a strong bias to make it work for me,
inspired many years ago by John Backus' famous paper, and a presentation by
David Turner about KRC, and a few other things. Many programmers I've
spoken to who have tried functional programing have given up on it because
it's too hard.
>It seems to me that as unsafePerformIO is not in the standard and only
>implemented on some
>compilers/interpreters, that you limit the portability of code by using
>it, and that it is best avoided. Also as any safe use of unsafePerformIO
>can be refactored to not use it I could
>certainly live without it.
Well, I am concerned about portability. I insist on using Hugs when many
people use just GHC, and one of the reasons is that I don't want to get
locked into one compiler's extensions. But sometimes it is necessary to
use extensions: there are many features of Haskell-98++ that are almost
essential (IMO) to practical software development. Including, I think,
unsafePerformIO (on rare occasions). My touchstone is that I'll use
language extensions when I have to, provided they are supported by both
Hugs and GHC.
What's my point in all this? I supposed it might be summed up as: "The
best is the enemy of the good".
>Graham Klyne wrote:
>>[Switching to Haskell-cafe]
>>I have used it once, with reservations, but at the time I didn't have the
>>time/energy to find a better solution. (The occasion of its use was
>>accessing external entities within an XML parser; by making the
>>assumption that the external entities do not change within any context in
>>which results from a program are compared, I was able to satisfy the
>>"proof obligation" of not causing or being sensitive to side effects.)
>>The reason this was important to me is that I wanted to be able to use
>>the parser from code that was not visibly in the IO monad. For me,
>>treating Web data transformations as pure functions is one of the
>>attractions of using Haskell.
>>(Since doing that, I had an idea that I might be able to parameterize the
>>entity processing code on some Monad, and use either an Identity monad or
>>IO depending on the actual requirements. This way, I could keep pure XML
>>processing out of the IO monad, but use IO when IO was needed.)
>>In short: I think it's usually possible to avoid using unsafePerformIO,
>>but I'd be reluctant to cede it altogether, if only for sometimes
>>quick-and-dirty pragmatic reasons.
More information about the Haskell-Cafe