Re: UnHappy 55 tuple [was: Re: PrelTup]

1998-06-16 Thread Simon L Peyton Jones

 Hi Sigbjorn,
 
 I had another look at the 55 tuple problem.  And this time,
 I could find a short program that produces the error.

...

 I had a look at `PrelTup.lhs' and it seems to define tuples
 up to 37 tuples or so.  Maybe this is the problem.
 
 What shall I do?  Hack `PrelTup.lhs'? (Doesn't seem very
 attractive...)

Yes, that's the problem.  I've often thought of making tuples
more generic, but it never seems worth the bother (which is,
belive me, non-trivial).  I think the simplest solution would
be to transform big tuples into nested smaller tuples... but
I havn't gotten around to doing it.  You could do it yourself
of course, or hack PrelTup...

Sorry about this.  I hate it when compilers embody arbitrary limits.

Simon




minor bug and help with alpha-debian-linux ?

1998-06-16 Thread Kristoffer Rose

Hi Guys,

First a small bug: then line 1185 of the ghc-2.10 configure script has a
bug: it is

   1185 if test `eval $cmd_string 2/dev/null` != "1"; then

but should be

   1185 if test x`eval $cmd_string 2/dev/null` != x"1"; then 
  
in case one uses egcs (as I do).

Anyways, I want to make ghc 2.10 on my alpha.  It runs Debian GNU/Linux.
Fortunately, the alpha-dec-osf image works somewhat so I hope to be able to 
bootstrap.

But please

(1) tell me if you know of others who did this, and

(2) put me on the ghc haskell mailing list!

Ta,
Kristoffer

-- 
Kristoffer H?gsbro Rose, Ph.D., prof.associe  [EMAIL PROTECTED]
Laboratoire de l'Informatique du Parallelisme  equipe PLUME, bureau LR5-026
Ecole Normale Superieure de Lyon; 46, Allee d'Italie; F-69364 Lyon 07 cedex
phone: +33(0)4 7272 8642; fax:...8080http://www.ens-lyon.fr/~krisrose



Re: Exceptions are too return values!

1998-06-16 Thread Fergus Henderson

On 15-Jun-1998, Peter White peter@galois wrote:
 
 On June 15, Fergus Henderson writes
 
  As noted earlier, things like heap overflow, and stack overflow 
  are different from other kinds of exceptions.  They can't be modelled
  using the domain-theoretic semantics.  Rather, they reflect the failure
  of the operational semantics to accurately reflect the domain-theoretic
  semantics.  Thus the treatment of these exceptions may need to be
  different to the treatment of ordinary exceptions.
 
 One of the advertisements of Haskell is that you can reason
 about your program, by performing mathematical proofs about
 the program. Haskell has gone a long way to incorporating IO
 and stateful computations in such a way that you still get
 referential transparency, and you can still reason about programs.
 If the operational semantics fails to reflect, the domain-theoretic
 semantics, then it would appear that the ability to reason about
 the programs dissappears.

This is not the case here.  The reason is that although the operational
semantics are not complete w.r.t. the denotational (domain-theoretic)
semantics, they are sound.  That is, you can't use the denotational semantics
to prove that your program won't get a heap overflow; but you can use them
to prove that if your program doesn't get a resource failure like that,
then it will compute the right answer.

If you want to reason about resource limits, then you need to use
an operational semantics, not the denotational semantics.

 I think it is a requirement upon a
 Haskell implementation to preserve the independence of threads
 by "localizing" the resources to the threads, such that each thread
 can predict by itself, independently of any other thread, whether
 its resources will be sufficient.

I don't think this is desirable in the general case.
I think it would be useful to *allow* threads to reserve
resources, but often it is difficult to predict in advance
exactly how much each thread will use, and frequently it
is better to deal with resource failures when they arise.

-- 
Fergus Henderson [EMAIL PROTECTED]  |  "I have always known that the pursuit
WWW: http://www.cs.mu.oz.au/~fjh  |  of excellence is a lethal habit"
PGP: finger [EMAIL PROTECTED]| -- the last words of T. S. Garp.





Re: FW: Exceptions are too return values!

1998-06-16 Thread Simon L Peyton Jones


 I thought about this problem some more, and I have realized that the
 problem of nondeterminacy for Haskell exceptions would in fact be
 considerably worse that I had previously considered.  The trouble is
 that in the general case the problem is not just that the choice of
 which exception is raised is nondeterministic -- instead, it would be
 much worse: the choice of whether you raise an exception or loop
 forever can be also be nondeterministic.  This occurs because of
 expressions such as `0/0 + loop'.  Or, to take a more realistic (and
 nasty) example, `f 0' where `f x = 1/x + g x' where `g x' happens to
 loop if `x' is zero.

I don't agree that this is a problem.  If (g x) loops when x is zero
then you should jolly well test for that:

f x | x == 0= raise "x is zero"
| otherwise = 1/x + g x


I simply don't think it's reasonable to comletely prescribe
the evaluation order of a lazy functional program.

At the moment, Haskell has the fiction that a divide-by-zero
exception and non-termination are the same value, i.e. bottom.
That allows us to say that the behaviour of

f x = 1/x + g x

is identical regardless of whether "+" evaluates its first
argument first or second.  But we all know that the behaviour
in these two cases is quite different: one prints a message and
halts, and the other fails to terminate.  So in this sense
the behaviour of Haskell programs is already non-deterministic.

The nice thing about the NDSet story is that it makes clear
precisely where the non-determinism occurs.  Equational reasoning
is not impaired, nor is the implementation penalised.  I think
it's a great idea.

So I appear to be in disagreement here with Alex, Amr, and Fergus about
the importance of being able to say precisely which exception is raised.
I'm quite content with knowing which *set* of exceptions can be raised.
Ha!

Simon






RE: FW: Exceptions are too return values!

1998-06-16 Thread Hans Aberg

At 11:06 +0200 98/06/16, Erik Zuurbier wrote:
... Exceptions are merely a way to structure
the code, so that the main line and error handling can be neatly separated.

  This is the original idea, but I pointed out that exceptions are in fact
much deeper: They can be used as a programming technique too, and further,
many common language constructs (such as "return", "break", etc in C++) can
be viewed  as special cases of exception handling.

  Hans Aberg
  * Email: Hans Aberg mailto:[EMAIL PROTECTED]
  * Home Page: http://www.matematik.su.se/~haberg/
  * AMS member listing: http://www.ams.org/cml/






RE: FW: Exceptions are too return values!

1998-06-16 Thread Dave Tweed

On Tue, 16 Jun 1998, Erik Zuurbier wrote:

 I have read many, but not all of the messages on this subject. Did any of those
 shed any light on the intended use of exceptions? Maybe that could explain
 the disagreement. I can imagine:
 1) You use exceptions for debugging your program, with the goal (naive maybe)
 that none will ever be raised in the final program.
 2) You learn to rely on the defined behaviour, deterministic or not, and the final
 program can be perfectly acceptable if it raises any number of exceptions as long
 as they are caught and handled in time. Exceptions are merely a way to structure
 the code, so that the main line and error handling can be neatly separated.

There's a third case, I think:

3) You are writing code which may be reused (either by design or
fortuitous circumstance); consequently if any of your `externally usable'
functions can throw an exception, you can't rely upon the user reading and
understanding you code to the degree that they appreciate all the nuances
of exactly which exception was thrown in some intricate circumstance. (I
think haskell is still a way from the C++ situation where there are
distributed _binary libraries_ which can throw exceptions, so you can't
assume you can even read the source.) Thus you have to deliberately make
circumstances where knowing _exactly_ what the primary error is (rather
than just that `an error occurred whilst doing this overall thing')
exactly predictable yourself, strictifying code if necessary.


cheers, dave

email: [EMAIL PROTECTED]   "Taught the wife some html. __Bad
www.cs.bris.ac.uk/~tweed/pi.htm   move__." -- Alan Cox
work tel: (0117) 954-5253  





Re: Exceptions are too return values!

1998-06-16 Thread Fergus Henderson

On 15-Jun-1998, Fergus Henderson [EMAIL PROTECTED] wrote:
 On 12-Jun-1998, Scott Turner [EMAIL PROTECTED] wrote:
  At 14:40 1998-06-10 +0100, you wrote:
  
  Here's a reasonable design for exceptions in Haskell:
  
  * handle :: (String - IO a) - IO a - IO a
  
  You probably realized more quickly than I how this
  can leak exceptions.
 ...
  Is this considered a drawback?
 
 This kind of exception handling can "leak" exceptions, but not in the
 way you described.
...
  What I mean is
  
  main = do quotient - handle (const (return 0)) (return (0 / 0)
   -- Looks plausible
   -- but the exception isn't raised yet.
print quotient -- Here the expression 0/0 is evaluated
   -- and the exception is raised with no handler.
 
 This is not correct.  This example would print out `0' rather than raising
 an uncaught division by zero exception.

I'm afraid I must retract those statements.  Scott Turner was quite correct,
and I was mistaken.  My apologies!

As Scott pointed out to me in personal email, SLPJ's definition of `handle'

  | * handle :: (String - IO a) - IO a - IO a
  |   (handle h a) tries to perform the action a.
  |   If doing so delivers a set of exceptional values then
  |   apply the exception handler h to the string that names
  |   one of them.  It is not defined which of the exceptional
  |   values is picked.

means that it only catches exceptional values in the I/O action,
not exceptional values in the return value.

Regarding Scott's question

 Is this considered a drawback?

my answer is still much the same -- yes, it's a drawback,
but I'd place the blame more on laziness than exception handling.
I consider it only a minor drawback, since the "leakage" can be
avoided if you use a version of `handle' which is strict in the return
value, e.g.

strict_handle handler action = handle handler strict_action where
strict_action = do value - action
   seq value return value
   -- or with `hyper_seq' instead of `seq'

-- 
Fergus Henderson [EMAIL PROTECTED]  |  "I have always known that the pursuit
WWW: http://www.cs.mu.oz.au/~fjh  |  of excellence is a lethal habit"
PGP: finger [EMAIL PROTECTED]| -- the last words of T. S. Garp.





Re: FW: Exceptions are too return values!

1998-06-16 Thread Hans Aberg

At 14:40 +0100 98/06/10, Simon L Peyton Jones wrote:
Here's a reasonable design for exceptions in Haskell:

  A think one can use a monadic approach, as a monad
(X, unit_X, bind_X): HaskellX - HaskellX
where HaskellX is and extension of Haskell with exceptions.

* A value of Haskell type T can be
   EITHER one of the values we know and love
  (bottom, or constructor, or function,
   depending on T),

   OR it can be a set of exceptional values.

  So this says that X(T) = T | Exception, where Exception is a type in
HaskellX which labels objects in Haskell as exceptions. This monad is such
as old Haskell code can always be run in the new HaskellX.

* raise :: String - a
  (raise s) returns a single exceptional value, named by string s

  I would suggest that an exception could not just be a string, but any
value in HaskellX.

* All strict operations (case, +, etc) return the union of
  the exceptional values returned by their strict arguments
  For example, if both arguments to "+" return an exceptional value
  then "+" returns both. Similarly, any strict context.

  Actually, if a function f in Haskell has type T, and is altered so that
it raises an exception, then its type becomes T | Exception. If a function
g: A - B is altered to raise an exception, there is a difference between
the types
A - (B | Exception)  and  (A | Exception - B | Exception), but the monad
is such that one can always simplify to the latter, and one can use the
abbreviation
  (A - B) | Exception
for the latter.

  So the type handling mechanism should not need to be that much more
complicated: Just replace T with T | Exception if the function raises an
exception. Functions that do not raise an exception can always be extended
to this, T | Exception, on the fly when encountering an exception via the
monad proeprties, so these functions need not get an altered type.

* handle :: (String - IO a) - IO a - IO a
  (handle h a) tries to perform the action a.
  If doing so delivers a set of exceptional values then
  apply the exception handler h to the string that names
  one of them.  It is not defined which of the exceptional
  values is picked.

  Then handle() should not only handle strings and IO, but any Exception
(of course), and any action a.

  The handle function must be able to determine if it can handle the
exception, so it should have a function f: Exception - Boolean as an extra
argument; the exception is handled only if this evaluates to "true" for the
exception it handles.

  Hans Aberg
  * Email: Hans Aberg mailto:[EMAIL PROTECTED]
  * Home Page: http://www.matematik.su.se/~haberg/
  * AMS member listing: http://www.ams.org/cml/






Re: FW: Exceptions are too return values!

1998-06-16 Thread Fergus Henderson

On 16-Jun-1998, Simon L Peyton Jones [EMAIL PROTECTED] wrote:
 
 [Fergus wrote:]
  I thought about this problem some more, and I have realized that the
  problem of nondeterminacy for Haskell exceptions would in fact be
  considerably worse that I had previously considered.  The trouble is
  that in the general case the problem is not just that the choice of
  which exception is raised is nondeterministic -- instead, it would be
  much worse: the choice of whether you raise an exception or loop
  forever can be also be nondeterministic.  This occurs because of
  expressions such as `0/0 + loop'.  Or, to take a more realistic (and
  nasty) example, `f 0' where `f x = 1/x + g x' where `g x' happens to
  loop if `x' is zero.
 
 I don't agree that this is a problem.  If (g x) loops when x is zero
 then you should jolly well test for that:
 
   f x | x == 0= raise "x is zero"
   | otherwise = 1/x + g x

Simon, I'm sure that a really thorough programmer such as yourself
would never forget to insert such a test.  But, as was recently
demonstrated on this mailing list ;-), I'm quite fallible.
I'm sure there are many other fallible Haskell programmers around.

To minimize the bugs in my programs, I use a lot of different tools
and techniques.  I write in languages that have a lot of static checking,
so that the compiler will catch a lot of my mistakes.  I get my colleagues
to review my code.  And last but not least, I test my code.

For the kind of bug referred to above, static checking isn't going to
help (at least not given the current state of the art -- no doubt
improvements are possible).  Code reviews would help, but my colleagues
are fallible too.  And this kind of bug is very difficult to test for. 
Not only is it difficult to construct test cases that exercise all the
exceptional cases, even that is not sufficient, since it might work
fine with one implementation and then fail with another.

So, I don't think it is reasonable to say that this is not a problem.
It may not be a big problem, but I do consider it a problem.

Now, we can certainly debate the likely frequency of such bugs, and
their cost, and compare this with the advantages and disadvantages
of exception handling.  In fact, it does seem likely that such
bugs would be very rare.  The cost of each such bug may be high,
but if they occur infrequently enough, then the overall cost will be small.
So maybe you just meant that it wasn't likely to be a significant problem
in practice.  If that was what you meant, then I'm inclined to agree
with you.

 I simply don't think it's reasonable to comletely prescribe
 the evaluation order of a lazy functional program.

Why not?  Because it would inhibit optimization?
This is true, but for some applications reliability (and hence
determinism) is much more important than efficiency.
For these applications, I think it would be reasonable
to specify the behaviour exactly, even if it means giving
up some optimization opportunities.  Do you agree?

Conversely, there are many applications for which efficiency
is more important than determinacy, so for those applications
I agree the behaviour should not be specified exactly.

Fortunately a single language can support both kinds of applications,
as I outlined in previous mail.

 At the moment, Haskell has the fiction that a divide-by-zero
 exception and non-termination are the same value, i.e. bottom.
 That allows us to say that the behaviour of
 
   f x = 1/x + g x
 
 is identical regardless of whether "+" evaluates its first
 argument first or second.  But we all know that the behaviour
 in these two cases is quite different: one prints a message and
 halts, and the other fails to terminate.  So in this sense
 the behaviour of Haskell programs is already non-deterministic.

That's true, but since both the fatal error message and non-termination
constitute program bugs, this is not so much of a worry.
The nondeterminism doesn't make testing any more difficult, for example.

-- 
Fergus Henderson [EMAIL PROTECTED]  |  "I have always known that the pursuit
WWW: http://www.cs.mu.oz.au/~fjh  |  of excellence is a lethal habit"
PGP: finger [EMAIL PROTECTED]| -- the last words of T. S. Garp.





Exceptions and functions. Second round?

1998-06-16 Thread Jerzy Karczmarczuk

Tony Finch cites Hans Aberg, who comments the posting of Eric Zuurbier
who writes that: "... Exceptions are merely a way to structure the code, 
so that the main line and error handling can be neatly separated."


*  This is the original idea, but I pointed out that exceptions are in
*  fact much deeper: They can be used as a programming technique too,
*  and further, many common language constructs (such as "return",
*  "break", etc in C++) can be viewed as special cases of exception
*  handling.  [HA]

 
 Indeed, in Modula-3, RETURN and EXIT are defined in terms of
 exceptions.
 
 I like the idea of the non-deterministic exception system that has
 been proposed, but it'll be interesting to see how well it works in
 real life...
 
 Tony.
 

I am afraid that we are repeating what has been already said, but OK,
this is the essence of wisdom...

I don't think that I would agree with such philosophy. "break" in C is
nothing more than a structured "goto". Break from "switch" is just
a jump, from a loop it might do some cleanup (if the loop index is
stacked). "Return" is also a jump with the cleanup of the last instance
frame.


As we all know, all this can be represented by continuations, and this
is a practical issue, not a statement that "all Turing machines are
equal, only some are more equal than the others..."

There is - in my opinion - nothing "exceptional" in *standard* imperative
control structures. OK, I admit that I am a sinner myself, and I had
written some small event-driven programs using (ppardonnez le mot)
"longjump" in C, but I believe strongly that the functional programming
community with the monadic religion etc. is much more close to the Truth.

Jerzy Karczmarczuk
Caen, France









RE: FW: Exceptions are too return values!

1998-06-16 Thread Erik Zuurbier


SLPJ writes:

So I appear to be in disagreement here with Alex, Amr, and Fergus about
the importance of being able to say precisely which exception is raised.
I'm quite content with knowing which *set* of exceptions can be raised.

I have read many, but not all of the messages on this subject. Did any of those
shed any light on the intended use of exceptions? Maybe that could explain
the disagreement. I can imagine:
1) You use exceptions for debugging your program, with the goal (naive maybe)
that none will ever be raised in the final program.
2) You learn to rely on the defined behaviour, deterministic or not, and the final
program can be perfectly acceptable if it raises any number of exceptions as long
as they are caught and handled in time. Exceptions are merely a way to structure
the code, so that the main line and error handling can be neatly separated.

Erik Zuurbier






Re: Exceptions and functions. Second round?

1998-06-16 Thread Hans Aberg

At 14:01 +0200 98/06/16, Jerzy Karczmarczuk wrote:
There is - in my opinion - nothing "exceptional" in *standard* imperative
control structures. OK, I admit that I am a sinner myself, and I had
written some small event-driven programs using (ppardonnez le mot)
"longjump" in C, but I believe strongly that the functional programming
community with the monadic religion etc. is much more close to the Truth.

  I think you are raising the issue of exceptions without handling it
properly. :-)

  Of course, when leaping to the next level of abstraction, exceptions are
as exceptional as irrational numbers are irrational and the imaginary
complex unit is imaginary in the original linguistic semantic sense, that
is, not at all. And C is a language whose trademark is the absence of
logical structure described by theory, so what's done in that language is
rather misleading if one wants to produce a new generation of languages
admitting new abstractions for the convenience to people that can think in
terms of abstractions and by that do more efficient work.

  In fact, the opposite seems to happen, the new concept of exceptions
seems to fit those old imperative ad hoc structures into a nice single
abstraction.

  As we sit here with a language, Haskell, which normally does not admit
imperative structures, using exceptions might be a neat way to do it.

  Hans Aberg
  * Email: Hans Aberg mailto:[EMAIL PROTECTED]
  * Home Page: http://www.matematik.su.se/~haberg/
  * AMS member listing: http://www.ams.org/cml/






Re: Exceptions are more than just return values!

1998-06-16 Thread Hans Aberg

At 12:15 +0100 98/06/16, Tony Finch wrote:
I like the idea of the non-deterministic exception system that has
been proposed, but it'll be interesting to see how well it works in
real life...

  Perhaps one can have them both with handlers handle_absolutely and
handle_maybe, so that user can play around with them both and compare.

  Hans Aberg
  * Email: Hans Aberg mailto:[EMAIL PROTECTED]
  * Home Page: http://www.matematik.su.se/~haberg/
  * AMS member listing: http://www.ams.org/cml/






Re: Exceptions and functions. Second round?

1998-06-16 Thread Alastair Reid


[EMAIL PROTECTED] (Greg Michaelson) writes:
 In SML(sorry...), in: exp1 handle exp2
 exp1 is evaluated and any exception raised within it is handled by an
 appropriate handler in exp2. If there isn't one then the exception
 is handled in the enclosing environment for the whole construct. Similarly,
 if an exception is raised in exp2 then it is handled in the enclosing
 environment. So exception handling follows a stack based regime.
 
 Instead, how about having exp2 handle exceptions raised within itself 
 and also allowing mutually recursive handlers?

No need to wire this into the semantics/implementation - it's easy
to implement your "recursive catch" using the plain catch:

  rcatch :: IO a - (IOError - IO a) - IO a
  m `rcatch` h = m `catch` \err - (h err `catch` h)

but notice that I call plain catch when invoking the handler - so
we won't get into infinite loops.

If infinite loops are what you want :-), then we have "really recursive catch"

  rrcatch :: IO a - (IOError - IO a) - IO a
  m `rrcatch` h = m `catch` \err - (h err `rrcatch` h)

Yet another variant would be to invoke the handler up to 10 times (say)
before giving up and invoking the outer handler.

  This might form a very
 nice inter-process communication mechanism, which may be recognised
 by people who have written interrupt driven multi-process systems.

I sort of see how this might work - but I've only _read about_ such systems
- not actually implemented them.  Where could I find out more?


Alastair

ps I'm getting kinda worried about people talking about using the
   exception handling mechanism to implement various control constructs.
   While our non-deterministic semantics is (I hope) fine for writing
   robust programs, I can't see how to build __predictable__ control
   constructs on top of it and I have no desire to modify the implementation
   and semantics just so that you can do so.

   I also think we need to spend some time playing with the GHC-based 
   implementation before we'll really know how it performs.  Just how big
   a problem will it be if an optimiser transforms a program that would have
   raised an error into a program that enters an infinite loop and triggers
   a timeout?  In some applications, this won't be a problem but it could
   be a real problem in others.






Re: Exceptions and functions. Second round?

1998-06-16 Thread Greg Michaelson

In SML(sorry...), in: exp1 handle exp2
exp1 is evaluated and any exception raised within it is handled by an
appropriate handler in exp2. If there isn't one then the exception
is handled in the enclosing environment for the whole construct. Similarly,
if an exception is raised in exp2 then it is handled in the enclosing
environment. So exception handling follows a stack based regime.

Instead, how about having exp2 handle exceptions raised within itself 
and also allowing mutually recursive handlers? This might form a very
nice inter-process communication mechanism, which may be recognised
by people who have written interrupt driven multi-process systems. It
probably has horrendous semantic implications...

Greg Michaelson





Garbage Collection in GreenCard/RedCard/HaskellCOM

1998-06-16 Thread S. Alexander Jacobson

I just reread Dima's answer to my query about the database access in
particular and am confused.  Dima says that he can't allow queries
outside the IOMonad because he has to worry about freeing memory (query
output).  

However, Haskell/Com (built on top of Greencard?) seems to be able to
propagate garbage collection information from Haskell to C so that
when a Haskell/COM Object is no longer in use, there is some functionality
decrements its reference counter automatically.

How does this work?  and can dima use this mechamism to free queries
when they are no longer needed? ..allowing database queries outside
the IOMonad?  

-Alex-

PS The answer to this question is related to my prior unanswered question
on laziness and middleware.

___
S. Alexander Jacobson   i2x Media  
1-212-697-0184 voice1-212-697-1427 fax


On Tue, 26 May 1998 [EMAIL PROTECTED] wrote:

 * SQL: many industrial strength databases provide a snapshot mode where
 the state of the database doesn't change for the duration of the
 connection.  I accept that opening a connection may need to be within a
 do sequence. It doesn't make sense to me that SQL select queries should
 be.  They are functions over a database datastructure in the same way one
 might write functions over lists. (based on looking at the ODBC lib from
 Dima Skvortsov [EMAIL PROTECTED])
 
 I would respond to particularily this question as long as I am still working
 on this ODBC lib. (BTW note my new e-mail is address: [EMAIL PROTECTED],
 the one you mentioned above is not valid any more)
 Feel free to mail me if there are any problems/comments/... with this lib.
 
 Considering SQL queries that do not change state, it seems to me not so easy
 to get rid of putting them into monadic action.
 First of all you need to connect to database first, _then_ perform some SQL
 queries and _then_ disconnect. There is no sense in performing queries
 before connecting. Monad allows to synchronize these steps.
 Second, every SQL statement has its unique identifier (C type is HSTMT).
 It's created with function SQLAllocStmt and should be freed later with
 SQLFreeStmt. This identifier should be kept all the time to obtain query
 results or change parameters or run the query once more.
 Third, this identifier is not the only thing associated with a
 semi-stateless SQL statements. SQL statement identifier must be binded with
 memory buffers to obtain query results or set query parameters. Freeing this
 memory especially in case of fetching data is pretty difficult matter. Note
 that lazy list which represents the data being fetched can be evaluated to
 the end as well as left partly unevaluated. It depends on how many rows were
 fetched or how many elements of the list were binded within strict
 functions. Memory buffers should be freed when the list is fully evaluated
 or when the statement is closed. The best solution to that problem that I
 found required me to maintain an IO reference to the list of allocated
 memory with the SQL statement identifier. Obviously it's not possible
 without monad.
 
 Best regards,
     Dima Skvortsov
 
 
 






Re: Garbage Collection in GreenCard/RedCard/HaskellCOM

1998-06-16 Thread Alastair Reid


 I just reread Dima's answer to my query about the database access in
 particular and am confused.  Dima says that he can't allow queries
 outside the IOMonad because he has to worry about freeing memory (query
 output).  
 
 However, Haskell/Com (built on top of Greencard?) seems to be able to
 propagate garbage collection information from Haskell to C so that
 when a Haskell/COM Object is no longer in use, there is some functionality
 decrements its reference counter automatically.
 
 How does this work?  and can dima use this mechamism to free queries
 when they are no longer needed? ..allowing database queries outside
 the IOMonad? 

The year before I left Glasgow, I added some special GC extensions to GHC.
When I arrived here, I added the same stuff into Hugs.
The details are in a never-completed paper which is hanging off my home
page (URL in signature) but here's an outline:

  ForeignPtrs (nee MallocPtrs) point from Haskell into C
  StablePtrs point from C into Haskell

ForeignPtr is just like Addr (the GHC/Hugs name for void*) except that
when the garbage collector deletes a ForeignPtr it calls a deallocation
function to let C know what's happening.  This deallocation function
might be "free" if the ForeignPtr is a block of memory or it might be
"fclose" if it's a FILE* or it might be a piece of code you wrote
yourself.  (Each ForeignPtr can have a different freeing function if
you want.)  (ForeignPtrs are often called Weak Pointers in other languages)

Since C doesn't have automatic GC, StablePtrs are explicitly allocated and
deallocated.  As long as a stable ptr exists, the Haskell GC knows that
the object is in use and doesn't deallocate it.  Once the stable ptr is
free'd the GC is free to deallocate it (assuming it's not needed for
any other reason).


ForeignPtrs seem to work ok for abundant resources like memory.  
When using scarce resources, code like the following is quite common:

if (i=NUM_HANDLES) {   /* If at first we don't*/
garbageCollect();   /* succeed, garbage collect*/
for (i=0; iNUM_HANDLES  nonNull(handles[i].hcell); ++i)
;   /* and try again ...   */
}
if (i=NUM_HANDLES) {   /* ... before we give up   */
ERRMSG(0) "Too many handles open; cannot open \"%s\"", s
EEND;
}

(This code is part of Hugs.  It doesn't actually involve ForeignPtrs - 
 Mark Jones had used a ForeignPtr-like mechanism to implement file handles
 long before I added ForeignPtrs.)


-- 
Alastair Reid  Yale Haskell Project Hacker
[EMAIL PROTECTED]  http://WWW.CS.Yale.EDU/homes/reid-alastair/