Re: [Haskell-cafe] Re: Top Level TWI's again was Re: [Haskell] Re: Parameterized Show

2004-11-23 Thread Keean Schupke
Can a C function be pure? I guess it can... The trouble is you cannot 
proove its
pure?

But - why would you want to use a pure C function. The chances of any useful
C library function being pure are slim - and the performance of GHC in some
of the benchmarks shows that there is hardly any speed advantage (for a pure
function)...
   Keean.
Benjamin Franksen wrote:
On Monday 22 November 2004 23:22, Keean Schupke wrote:
 

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.
   

With one exception: If a foreign function (e.g. from a C library) is really 
pure, then I see no way to tell that to the compiler other than using 
unsafePerformIO. IIRC, unsafePerformIO is in the standard FFI libraries.

Ben
 

___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: Top Level TWI's again was Re: [Haskell] Re: Parameterized Show

2004-11-23 Thread Graham Klyne
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 +, Keean Schupke wrote:
Obviously without knowing the details I am speculating, but would it not 
be possible
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.

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

#g

Graham Klyne
For email:
http://www.ninebynine.org/#Contact

Graham Klyne
For email:
http://www.ninebynine.org/#Contact
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: Top Level TWI's again was Re: [Haskell] Re: Parameterized Show

2004-11-23 Thread Keean Schupke
Off topic, but interesting, Someone else keeps quoting this at me... I 
prefer Knuth - paraphrased as I cant remember the quote - The best 
software projects are the ones where the source code has been lost about 
half way through the development and started from scratch.

The point is programmers start by exploring a problem space without 
understanding it. Poor programmers just accept the first solution they 
put down. Good programmers re-implement. Great programmers have a sixth 
sense of when things are about to get ugly, and start again (and the 
better you are the less you actually have to implement before you 
realise things can be refactored for the better)...

Graham Klyne wrote:
What's my point in all this?  I supposed it might be summed up as: 
The best is the enemy of the good.

#g
--

___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Top Level TWI's again was Re: [Haskell] Re: Parameterized Show

2004-11-23 Thread Glynn Clements

Keean Schupke wrote:

 Can a C function be pure? I guess it can... The trouble is you cannot 
 proove its
 pure?
 
 But - why would you want to use a pure C function.

Because it already exists? E.g. most BLAS/LAPACK functions are pure;
should they be re-written in Haskell?

[Yes, I know that BLAS/LAPACK are written in Fortran, but I don't
think that changes the argument. The resulting object code (which is
what you would actually be using) wouldn't be significantly different
if they were written in C.]

-- 
Glynn Clements [EMAIL PROTECTED]
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Top Level TWI's again was Re: [Haskell] Re: Parameterized Show

2004-11-23 Thread Conor McBride
Keean Schupke wrote:
Can a C function be pure? I guess it can... The trouble is you cannot 
proove its
pure?
A C function might have no observable side effects, even if it operates
destructively over its own private data structures. It mightn't be too
hard to establish a sound test for this sort of purity (the one we have
already is sound; it always says no; some improvement may be possible).
Clearly completeness is too much to hope for.
But - why would you want to use a pure C function. The chances of any 
useful C library function being pure are slim - and the performance of
 GHC in some of the benchmarks shows that there is hardly any speed
 advantage (for a pure function)...
What about the other benchmarks? There are plenty of operations where
programmers can do a neater job than compilers at deciding that a given
data structure is known only to one consumer and can therefore be
manipulated destructively, recycled aggressively etc. I know modern
recycling is marvellous, but reduced consumption is better, isn't it?
The C functions I'm thinking of are the output from Hofmann co's
LFPL compiler: pure *linear* functional programs which run in the heap
they were born with. There are potential speed gains too: the knowledge
that you don't need to keep the original input means that you can
operate deep inside it in constant time, at the cost of maintaining
some extra pointers. (Does anybody know of a linear type system which
allows this? Basically, a list xs contains a pointer to its tail, so
holding a tail-pointer for xs would be a duplicate reference: problem.
But perhaps it's ok for the holder of xs also to hold its tail-pointer.)
This stuff isn't really my thing, but I'm an interested spectator.
These programs aren't funny interactive hard-drive-formatting things,
so they're probably irrelevant to this particular argument. Nonetheless,
they're hard to write efficiently in functional programming languages as
we know them. They're hard to write safely in C, but sometimes we just
get fed up with knowing useful stuff that we can't tell the compiler.
Is uniqueness worth a second look?
Conor
--
http://www.cs.rhul.ac.uk/~conor  for one more week
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Top Level TWI's again was Re: [Haskell] Re: Parameterized Show

2004-11-23 Thread Keean Schupke
Have you looked at Linear Aliasing, the type system used for TAL (typed 
assembly
language)... one would assume that if a C compiler which compiles to TAL 
were
produces, then you could proove purity?

Keean.
Conor McBride wrote:
Keean Schupke wrote:
Can a C function be pure? I guess it can... The trouble is you cannot 
proove its
pure?

A C function might have no observable side effects, even if it operates
destructively over its own private data structures. It mightn't be too
hard to establish a sound test for this sort of purity (the one we have
already is sound; it always says no; some improvement may be possible).
Clearly completeness is too much to hope for.
But - why would you want to use a pure C function. The chances of any 
useful C library function being pure are slim - and the performance of
 GHC in some of the benchmarks shows that there is hardly any speed
 advantage (for a pure function)...
What about the other benchmarks? There are plenty of operations where
programmers can do a neater job than compilers at deciding that a given
data structure is known only to one consumer and can therefore be
manipulated destructively, recycled aggressively etc. I know modern
recycling is marvellous, but reduced consumption is better, isn't it?
The C functions I'm thinking of are the output from Hofmann co's
LFPL compiler: pure *linear* functional programs which run in the heap
they were born with. There are potential speed gains too: the knowledge
that you don't need to keep the original input means that you can
operate deep inside it in constant time, at the cost of maintaining
some extra pointers. (Does anybody know of a linear type system which
allows this? Basically, a list xs contains a pointer to its tail, so
holding a tail-pointer for xs would be a duplicate reference: problem.
But perhaps it's ok for the holder of xs also to hold its tail-pointer.)
This stuff isn't really my thing, but I'm an interested spectator.
These programs aren't funny interactive hard-drive-formatting things,
so they're probably irrelevant to this particular argument. Nonetheless,
they're hard to write efficiently in functional programming languages as
we know them. They're hard to write safely in C, but sometimes we just
get fed up with knowing useful stuff that we can't tell the compiler.
Is uniqueness worth a second look?
Conor
--
http://www.cs.rhul.ac.uk/~conor  for one more week

___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Top Level TWI's again was Re: [Haskell] Re: Parameterized Show

2004-11-23 Thread Keean Schupke
Glynn Clements wrote:
I thought these libraries did have some global state, like choosing
which solver is used... In which case treating them as pure could
be dangerous...
   Keean.
Keean Schupke wrote:
 

Can a C function be pure? I guess it can... The trouble is you cannot 
proove its
pure?

But - why would you want to use a pure C function.
   

Because it already exists? E.g. most BLAS/LAPACK functions are pure;
should they be re-written in Haskell?
[Yes, I know that BLAS/LAPACK are written in Fortran, but I don't
think that changes the argument. The resulting object code (which is
what you would actually be using) wouldn't be significantly different
if they were written in C.]
 

___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Top Level TWI's again was Re: [Haskell] Re: Parameterized Show

2004-11-23 Thread Benjamin Franksen
On Tuesday 23 November 2004 10:03, you wrote:
 But - why would you want to use a pure C function. The chances of any
 useful C library function being pure are slim - and the performance of GHC
 in some of the benchmarks shows that there is hardly any speed advantage

The typical case (for me) is a foreign library exporting mostly non-pure 
routines, but with one or two pure functions among them.

But as has been stated already, unsafePerformIO is not needed in this case.

BTW, if you reply to the list anyway, don't reply to me in person. Otherwise I 
get everything duplicated (and it goes onto the wrong folder ;-).

Ben
-- 
Top level things with identity are evil.-- Lennart Augustsson
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Top Level TWI's again was Re: [Haskell] Re: Parameterized Show

2004-11-23 Thread David Roundy
On Mon, Nov 22, 2004 at 08:32:33PM +, Graham Klyne wrote:
 [Switching to Haskell-cafe]
 
 At 11:26 22/11/04 +, you wrote:
 I would ask an alternative question - is it possible to live without
 unsafePerformIO? I have never needed to use it!

There are plenty of non-IO reasons to use unsafePerformIO, for which it is
essential.  If you want to write haskell code that uses a pointer
(allocated possibly via an FFI C routine), it has to be in the IO monad.
If you know that this pointer doesn't access memory that'll be changed at
random (or by other routines), you can (and *should*) safely use
unsafePerformIO.

Also, if you're interested in using weak pointers (for example, to do
memoization), you'll almost certainly need to use unsafePerformIO.  Again,
the result can, and should, be encapsulated, so the module that uses
unsafePerformIO exports only pure functions (unless of course, there are
any that actually perform IO).
-- 
David Roundy
http://www.darcs.net
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Top Level TWI's again was Re: [Haskell] Re: Parameterized Show

2004-11-23 Thread Keean Schupke
David Roundy wrote:
There are plenty of non-IO reasons to use unsafePerformIO, for which it is
essential.  If you want to write haskell code that uses a pointer
(allocated possibly via an FFI C routine), it has to be in the IO monad.
If you know that this pointer doesn't access memory that'll be changed at
random (or by other routines), you can (and *should*) safely use
unsafePerformIO.
 

Does it? cant you just declare:
import foreign ccall somefn somefn :: Ptr Double - Ptr Double
Also, if you're interested in using weak pointers (for example, to do
memoization), you'll almost certainly need to use unsafePerformIO.  Again,
the result can, and should, be encapsulated, so the module that uses
unsafePerformIO exports only pure functions (unless of course, there are
any that actually perform IO).
 

Don't know about this one, got a short example?
   Keean.
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Top Level TWI's again was Re: [Haskell] Re: Parameterized Show

2004-11-23 Thread David Roundy
On Tue, Nov 23, 2004 at 01:51:24PM +, Keean Schupke wrote:
 David Roundy wrote:
 
 There are plenty of non-IO reasons to use unsafePerformIO, for which it is
 essential.  If you want to write haskell code that uses a pointer
 (allocated possibly via an FFI C routine), it has to be in the IO monad.
 If you know that this pointer doesn't access memory that'll be changed at
 random (or by other routines), you can (and *should*) safely use
 unsafePerformIO.
 
 Does it? cant you just declare:
 
 import foreign ccall somefn somefn :: Ptr Double - Ptr Double

Right, but if you want to access the contents of that pointer in haskell,
you have to use the IO monad.  True, in principle you could write a pointer
dereferencing function in C:

import foreign ccall readarray readarray :: Ptr Double - Int - Double

but that hardly seems like either an efficient or elegant way of getting
around the fact that haskell can't read pointers outside the IO monad.
Also, of course, this readarray function written in C is no safer than
using unsafePerformIO with peekArray.

In case you're wondering, peekArray needs to be in the IO monad because
there's no guarantee that the memory pointed to by the Ptr is constant--it
may even be a pointer to an mmapped file, in which case it could change
value independently of the program's execution.

 Also, if you're interested in using weak pointers (for example, to do
 memoization), you'll almost certainly need to use unsafePerformIO.  Again,
 the result can, and should, be encapsulated, so the module that uses
 unsafePerformIO exports only pure functions (unless of course, there are
 any that actually perform IO).

 Don't know about this one, got a short example?

I have a long and complicated example...

http://abridgegame.org/cgi-bin/darcs.cgi/darcs/AntiMemo.lhs?c=annotate

This is complicated because it's doing antimemoization rather than
memoization, and being backwards it's a bit trickier.  But it *is* an
example of a module that exports only pure functions, and couldn't be
written without unsafePerformIO (and does no IO).
-- 
David Roundy
http://www.darcs.net
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: Top Level TWI's again was Re: [Haskell] Re: Parameterized Show

2004-11-23 Thread Graham Klyne
At 10:02 23/11/04 +, you wrote:
Off topic, but interesting,
Sure... that's why its in 'cafe, right?
Someone else keeps quoting this at me... I prefer Knuth - paraphrased as I 
cant remember the quote - The best software projects are the ones where 
the source code has been lost about half way through the development and 
started from scratch.

The point is programmers start by exploring a problem space without 
understanding it. Poor programmers just accept the first solution they put 
down. Good programmers re-implement. Great programmers have a sixth sense 
of when things are about to get ugly, and start again (and the better you 
are the less you actually have to implement before you realise things can 
be refactored for the better)...

Graham Klyne wrote:
What's my point in all this?  I supposed it might be summed up as: The 
best is the enemy of the good.
Hmmm... I take your point, and I think my attempted pithy summary missed 
its intended target.  What I was trying to convey was a sense that a great 
language has to let merely average (or worse) programmers do a halfway 
decent job.  There aren't enough great programmers to go round.

And even great programmers sometimes have to work with someone else's 
codebase (which even if written by a great programmer may have had diffent 
goals in mind).

(FWIW, I think Python is a language that scores pretty highly on this count.)
#g

Graham Klyne
For email:
http://www.ninebynine.org/#Contact
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: Top Level TWI's again was Re: [Haskell] Re: Parameterized Show

2004-11-22 Thread Graham Klyne
[Switching to Haskell-cafe]
At 11:26 22/11/04 +, you wrote:
I would ask an alternative question - is it possible to live without
unsafePerformIO? I have never needed to use it!
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.

#g

Graham Klyne
For email:
http://www.ninebynine.org/#Contact
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: Top Level TWI's again was Re: [Haskell] Re: Parameterized Show

2004-11-22 Thread Keean Schupke
Obviously without knowing the details I am speculating, but would it not 
be possible
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.

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.

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

#g

Graham Klyne
For email:
http://www.ninebynine.org/#Contact
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Top Level TWI's again was Re: [Haskell] Re: Parameterized Show

2004-11-22 Thread Benjamin Franksen
On Monday 22 November 2004 23:22, Keean Schupke wrote:
 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.

With one exception: If a foreign function (e.g. from a C library) is really 
pure, then I see no way to tell that to the compiler other than using 
unsafePerformIO. IIRC, unsafePerformIO is in the standard FFI libraries.

Ben
-- 
Top level things with identity are evil.-- Lennart Augustsson
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe