[ ghc-Bugs-681062 ] Confusing Error Message if package-name is omitted

2004-11-25 Thread SourceForge.net
Bugs item #681062, was opened at 2003-02-05 17:09
Message generated for change (Comment added) made by simonmar
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detailatid=108032aid=681062group_id=8032

Category: Driver
Group: None
Status: Closed
Resolution: Fixed
Priority: 5
Submitted By: Wolfgang Thaller (wthaller)
Assigned to: Nobody/Anonymous (nobody)
Summary: Confusing Error Message if package-name is omitted

Initial Comment:
I compiled a library as a GHC package without adding the appropriate 
package-name flag to the ghc command line.
When trying to compile a module that used the package, ghc complained that it 
couldn't find package quot;Mainquot;.

This happens with the HEAD. With GHC 5.04 it (seemingly) was no problem to 
leave out the -package-name specifier.

Why is the -package-name flag needed at all?

--

Comment By: Simon Marlow (simonmar)
Date: 2004-11-25 13:57

Message:
Logged In: YES 
user_id=48280

-package-name will be gone in 6.4 (yay!), so I can close
this bug.

--

You can respond by visiting: 
https://sourceforge.net/tracker/?func=detailatid=108032aid=681062group_id=8032
___
Glasgow-haskell-bugs mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs


[ ghc-Bugs-1073424 ] Segfault during (FFI)malloc with ghci

2004-11-25 Thread SourceForge.net
Bugs item #1073424, was opened at 2004-11-25 13:17
Message generated for change (Tracker Item Submitted) made by Item Submitter
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detailatid=108032aid=1073424group_id=8032

Category: None
Group: 6.2.1
Status: Open
Resolution: None
Priority: 5
Submitted By: Nobody/Anonymous (nobody)
Assigned to: Nobody/Anonymous (nobody)
Summary: Segfault during (FFI)malloc with ghci

Initial Comment:
From: Tom Pledger [EMAIL PROTECTED]

The attached program halts with a segmentation fault 
when run using ghci, but not when compiled with ghc 
and run natively

Platform: Mandrake, linux kernel version 2.4.27-xena-1


--

You can respond by visiting: 
https://sourceforge.net/tracker/?func=detailatid=108032aid=1073424group_id=8032
___
Glasgow-haskell-bugs mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs


[ ghc-Bugs-1073501 ] checkProddableBlock: invalid fixup in runtime linker

2004-11-25 Thread SourceForge.net
Bugs item #1073501, was opened at 2004-11-25 17:56
Message generated for change (Tracker Item Submitted) made by Item Submitter
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detailatid=108032aid=1073501group_id=8032

Category: None
Group: 6.2.1
Status: Open
Resolution: None
Priority: 5
Submitted By: Nobody/Anonymous (nobody)
Assigned to: Nobody/Anonymous (nobody)
Summary: checkProddableBlock: invalid fixup in runtime linker

Initial Comment:
From: Tom Pledger [EMAIL PROTECTED]

Platform: Mandrake, linux kernel version 2.4.27-xena-1

This one has a good workaround: leave off the -g flag 
when compiling C for use with ghci.

$ echo int hello(){}  hello.c
$ gcc -g -c hello.c
$ ghci hello.o 
   ___ ___ _
  / _ \ /\  /\/ __(_)
 / /_\// /_/ / /  | |  GHC Interactive, version 6.2.1, 
for Haskell 98.
/ /_\/ __  / /___| |  http://www.haskell.org/ghc/
\/\/ /_/\/|_|  Type :? for help.

Loading package base ... linking ... done.
Loading object (static) hello.o ... done
final link ... ghc-6.2.1: internal error: 
checkProddableBlock: invalid fixup in runtime linker
Please report this as a bug to glasgow-haskell-
[EMAIL PROTECTED],
or http://www.sourceforge.net/projects/ghc/


--

You can respond by visiting: 
https://sourceforge.net/tracker/?func=detailatid=108032aid=1073501group_id=8032
___
Glasgow-haskell-bugs mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs


Re: [Haskell] Real life examples

2004-11-25 Thread Lennart Augustsson
Ben Rudiak-Gould wrote:
Lennart Augustsson wrote:
  What do you mean when you say the interface is pure?
 
  If your module is really pure then there should be an implemenation
  of it (which could have really bad complexity) with the same observable
  behaviour that uses only pure Haskell.  Is this possible?
Really? I agree with the converse of that statement, but I don't think 
it goes both ways. To me a function or module is pure when you can use 
it without compromising the equational properties of the language. I 
don't think Data.Dynamic or Control.Monad.ST satisfy your criterion for 
purity, but I would call them pure (after discarding the functions 
marked unsafe in the latter).
Agreed, there can pure functions that cannot be written with the pure
primitives, but then you have a proof obligation.  An easy way to
prove it is to provide an equivalent implementation that uses only
pure functions.  As far as I remember Control.Monad.ST can be written
purely.  And I think the same is true for Data.Dynamic.
-- Lennart
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell] A puzzle and an annoying feature

2004-11-25 Thread Lennart Augustsson
[EMAIL PROTECTED] wrote:
G'day all.
Quoting Lennart Augustsson [EMAIL PROTECTED]:

Here is a small puzzle.

You can understand this one because the closed world hypothesis doesn't
apply to type context inference. 
I have no problem understanding the technical reason for this.
But I now think it's a poor design.
-- Lennart
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell] Real life examples

2004-11-25 Thread George Russell
John Meacham wrote (snipped):
 George Russell's library is precicly an invalid use of unsafePerformIO.
 Internally, it does the invalid unsafePerformIO (newIORef) trick which
 is exactly the problem we are trying to solve. hiding it in a module doesn't
 make it go away.
Why does it matter to you if it uses unsafePerformIO, so long as you are
protected from all the unsafe consequences?
Would you be happier if I required all values to instance (Read,Show) and
then implemented exactly the same interface with this additional restriction
using completely standard Haskell 98 by writing values to files and reading
them back again?
 I am not positive, but it also would also add the overhead of a
 finitemap lookup across all global variables for every look up. which
 doesn't really meet efficiency requirements. a global counter should
 only need a single peek poke to a constant location, not some data
 structure lookup.
Oh really, we're not arguing about efficiency at this stage of the game
are we?  Actually you could implement the whole thing with a single
hash table.  I would have done, if TypeRep and ThreadId exposed their
internal integer contents for hashing purposes.
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell] Real life examples

2004-11-25 Thread George Russell
Lennart wrote (snipped):
 An easy way to
 prove it is to provide an equivalent implementation that uses only
 pure functions.  As far as I remember Control.Monad.ST can be written
 purely.  And I think the same is true for Data.Dynamic.
I don't see how it can be, since you can use Data.Dynamic to provide an
unsafe function
   cast : a - b
newtype UnsafeCast a = UnsafeCast a
instance Typeable (UnsafeCast a) where
   typeOf _ = mkAppTy (mkTyCon ) []
cast :: a - b
cast a =
   let
  Just (UnsafeCast b) = fromDynamic (toDyn (UnsafeCast a))
   in
  b
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell] Real life examples

2004-11-25 Thread Lennart Augustsson
I don't necessarily agree that you can do this trick
in all implementations of Dynamic and Typable.
You're relying on more things than the interface to
Dynamic promises.  Your fromDynamic could very well
return Nothing.  And should!
But that doesn't matter.  The unsafeCast function doesn't
really worry my much.  It's unsafePerformIO that worries me.
Using unsafe casts just makes us program in the untyped
lambda calculus, where the beta rule still holds, so no
worries.  Whereas unsafePerformIO opens an entirely different
can of worms.
-- Lennart
George Russell wrote:
Lennart wrote (snipped):
  An easy way to
  prove it is to provide an equivalent implementation that uses only
  pure functions.  As far as I remember Control.Monad.ST can be written
  purely.  And I think the same is true for Data.Dynamic.
I don't see how it can be, since you can use Data.Dynamic to provide an
unsafe function
   cast : a - b
newtype UnsafeCast a = UnsafeCast a
instance Typeable (UnsafeCast a) where
   typeOf _ = mkAppTy (mkTyCon ) []
cast :: a - b
cast a =
   let
  Just (UnsafeCast b) = fromDynamic (toDyn (UnsafeCast a))
   in
  b
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


[Haskell] Re: Top-level -

2004-11-25 Thread John Meacham
On Thu, Nov 25, 2004 at 10:07:20AM +0100, George Russell wrote:
 John Meacham wrote:
  Now, my mdo proposal as written would have hello outputed exactly once
  at module start up time no matter what, whether x is demanded or not. it
  is equivalant to a program transformation that collects all the top
  level initializers and declarations, puts them all in a mdo block and
  runs it with the semantics explained in the fixIO paper. (with a
  deterministic, but partially undefined order)
 
 What happens if you write the following?
 
y - f
x - 
let f = something depending on x
 
 Will it know to evaluate x before y, or is this not allowed?
 
 What about if the assignments to y and x occur in different modules?  Will 
 the
 RTS have to analyse the dependencies to work out which order to run the 
 assignments
 in?`

No. The semantics are completly and precicely defined by the fixIO
paper. there is a simple desugaring to haskell which I gave in my
original proposal. The basic gist is that things occur almost*
identically to if everything were simply placed in a single mdo block. 
no dependency analysis or strange translation beyond the normal haskell
desugaring mechanisms is required.

recursive top level declarations are no more tricky than are normal
recursive lets. Yes it is possible to write divergent statements, in the same 
way it
is possible to say

bottom = bottom
you can also say
bottom' - return bottom' 

(these are actually equivalant.)


Remember, that unlike normal monadic binding, this is using recursive
monadic binding, meaning the results of future computations can be used
as long as they arn't strictly evaluated, in the same way you can write
mutually recursive variables but if both are strict in each other they
will diverge :). The fact that everyone seems to get along fine despite
the ability to write divergent computations with recursive lets makes me
think this won't be too much for anyone to handle. 


John


* The differences, which I elaborated on earlier are due to a
  monomorphic restriction on user-written 'mdo' let-bound variables which is
  irrelevant to the desugaring so the translation from mdo - haskell
  expression is slightly different than presented in the paper. 


-- 
John Meacham - repetae.netjohn 
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell] Real life examples

2004-11-25 Thread Adrian Hey
On Wednesday 24 Nov 2004 9:37 pm, John Meacham wrote:
 On Wed, Nov 24, 2004 at 03:48:56PM +, Keean Schupke wrote:
  Having admited to wavering on the edge of accepting top level TWIs,
  perhaps one of the supporters would like to comment on qualified
  importing... IE what
  happens to the unique property if I import 2 copies like so:
 
 module Main where
 
 import Library as L1
 import Library as L2
 
  Although each library's internal state is initialised once, as required,
  any real
  IO could lead to problems... With the device driver example I now have
  two bits of code that think they have exclusive access to the device...
  But I can do:

 Hmm? I am not really sure what you are asking. With my mdo proposal, and
 I think all proposals brought forth, the module system behaves identically
 to how it normally does for namespace control. top level initializers
 are just constant definitions for all most everything is concerned.

 modules do not change code at all, they are pure syntantic sugar for
 deciding what names you can see.

 i.e. it does not matter whether you do

 import List as L1
 import List as L2

 L1.sort and L2.sort refer to the same thing. it would be no different if
 sort were written with global state or even was a top level binding.

I think Keean is assuming the idea is that one should be able to duplicate
top level TWIs by importing the same module twice. But of course this is
not what's wanted. For example, it would enable users to short circuit the
safety provisons of all the oneShot examples.

If the purpose of a module is to allow users to have multiple distinct
(top level or otherwise) TWIs then it should be exporting an appropriate
newTWI constructor which is used in the usual manner by the importing
module(s)..

 myTWI  - newTWI
 myOtherTWI - newTWI

Regards
--
Adrian Hey

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


[Haskell] Lexically scoped type variables

2004-11-25 Thread Simon Peyton-Jones
| This is a great example, thanks for posting it. However, I feel like
| the real problem in this example is the lexically-scoped type
| variables declared with your function f.

Paul's message gives me an excuse to consult the Haskell list about the
design of lexically scoped type variables.   I have a two particular
questions I'd like your advice about.  (This is nothing to do with
monomorphism restriction, or Lennart's original puzzle.)

I'm sending this message to the main Haskell list, to maximise
readership, but I suggest that

you reply to [EMAIL PROTECTED]

Thereby to avoid spamming the main Haskell list, which is meant to be
low-bandwidth.  I believe I've set the reply-to field of this message to
achieve this goal.  [Perhaps others can do the same?!] 

Simon

 Background 

First, for background you might want to glance at Lexically scoped type
variables, an unpublished paper available at
http://research.microsoft.com/%7Esimonpj/papers/scoped-tyvars
I don't want to take time in this message to discuss why we want scoped
type variables; I'll just take it for granted here.

One design choice discussed in the paper, and implemented in GHC, is
that we can bring new lexically-scoped type variables into scope by
mentioning them in a pattern type signature:
f (x::a) = 
Here 'a' is a name for the type of x, and 'a' scopes over f's body, and
can be mentioned in type signatures in f's body.  Sometimes one wants to
name types in the result* of f, rather than it its *arguments*.  For
example
head (xs::[a]) :: a = ...
Here, the :: a before the = gives the type of head's result.  If a
result type signature binds a type variable, that type variable scopes
over the right hand side of the definition.

In GHC, it's not necessary for the type that 'a' names to be a type
variable; it could be Int, for example:
f (x::a) = x + (1::Int)
Already this embodies several design choices.  For example, we know that
'a' is a *binding* for 'a' because there is no 'a' already in scope,
otherwise it'd be an *occurrence* of 'a'.  (An alternative would be to
mark binding sites somehow.)  Also once could require that 'a' names a
type variable rather than an arbitrary type.  But for this message I
want to take GHC's design as given.

 QUESTION 1 -

In GHC at present, a separate type signature introduces no scoping.  For
example:
f :: forall a. a - a
f x = (x::a)
would be rejected, because the type signature for 'f' does not make
anything scope over the right-hand side, so (x::a) means (x::forall
a.a), which is ill typed.

An obvious alternative, taken up by (among others) Mondrian and
Chamaeleon, is to say that

the top-level quantified variables of a separate type signature
scope over the right hand side of the binding

In the above example, then, the 'a' bound by the 'forall' would scope
over the right hand side of 'f'.  

I've argued against this in the past, because the construct (forall a.
type) patently scopes 'a' only over type.  But my resolve is
weakening.  It's just too convenient!  Furthermore, it binds a *rigid*
type variable (i.e. 'a' really must name a type variable) and that's
important for GADTs... which strengthens the case.

In short, I'm considering adopting the Mondrian/Chameleon rule for GHC.
There are two variations

  1a) In the example, 'a' is only brought into scope in the
 right hand side if there's an explicit 'forall' written by
the programmer
  1b) It's brought into scope even if the forall is implicit; e.g.
f :: a - a
f x = (x::a)

I'm inclined to (1a). Coments?


- QUESTION 2 --

Question 2 concerns degenerate bindings. First, consider pattern
bindings.  For example:
let 
(x::[a], y) = rhs
in body
The LHS of the let-binding is a pair, so it's called a pattern binding.
What should the scope of 'a' be?  GHC's current story is that it is the
same as the scope of term variables bound in the same pattern, so just
as 'x' scopes over both rhs and body, so does 'a'.  And that in turn
means that we can't generalise over 'a', so 'x' is monomorphic.

An alternative would be to say that type variables bound in a pattern
binding scope only over the right-hand side.

 The degenerate case: variable bindings 

Now the nasty case

let 
f :: a - a = \x - x
in (f True, f 'c')

Is the binding for 'f' 
(A) a (degenerate) function binding no arguments, but with a
result signature?
or  (B) a (degenerate) pattern binding with pattern (var::type)?

If we consider it to be (A) then arguably 'a' scopes only over the
right-hand side, and f gets the polymorphic type (forall a. a- a).

If we consider it to be (B) then currently 'a' scopes over the right
hand side and the body of the let, so 'f' has to be monomorphic, with
type ty-ty for some ty; and no ty will do, so the program is rejected.

The trouble is that the 

RE: [Haskell] Real life examples

2004-11-25 Thread Josef Svenningsson


 -Original Message-
 From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On
 Behalf Of Marcin 'Qrczak' Kowalczyk
 Sent: den 25 november 2004 11:49
 To: [EMAIL PROTECTED]
 Subject: Re: [Haskell] Real life examples
 
 Lennart Augustsson [EMAIL PROTECTED] writes:
 
  An easy way to prove it is to provide an equivalent implementation
  that uses only pure functions. As far as I remember Control.Monad.ST
  can be written purely. And I think the same is true for Data.Dynamic.
 
 I think neither of them can.
 
I agree with Marcin. I challenge you (Lennart) to write Control.Monad.ST in
Haskell98. I (and many others) have tried and failed. An interesting summary
by Koen can be found here:
http://www.haskell.org/pipermail/haskell/2001-September/007922.html

Cheers,

/Josef

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


Re: [Haskell] Real life examples

2004-11-25 Thread Lennart Augustsson
No, with exactly the type signatures they have I don't think
you can.  But the untyped version of them can be implemented.
And that is good enough to convince me that the beta rule is
still valid.
-- Lennart
Josef Svenningsson wrote:

-Original Message-
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On
Behalf Of Marcin 'Qrczak' Kowalczyk
Sent: den 25 november 2004 11:49
To: [EMAIL PROTECTED]
Subject: Re: [Haskell] Real life examples
Lennart Augustsson [EMAIL PROTECTED] writes:

An easy way to prove it is to provide an equivalent implementation
that uses only pure functions. As far as I remember Control.Monad.ST
can be written purely. And I think the same is true for Data.Dynamic.
I think neither of them can.
I agree with Marcin. I challenge you (Lennart) to write Control.Monad.ST in
Haskell98. I (and many others) have tried and failed. An interesting summary
by Koen can be found here:
http://www.haskell.org/pipermail/haskell/2001-September/007922.html
Cheers,
/Josef
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


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

2004-11-25 Thread Adrian Hey
On Wednesday 24 Nov 2004 11:50 am, Keean Schupke wrote:
 There is no problem getting multiple copies of the channels... I take it
 you are not familiar with the internals of OSs

IME there is no uniformity wrt OS internals, and I can't claim to be
familiar with them all. It's also fairly safe to assume that I know
nothing about the internals of your OS.

In any case, this is irrelevant to the scenario I originally posited.
Remember I wrote:
 What if there is no OS or device driver?
---^

I.E. A typicial embedded environment (though it's common to use OSs
here too, but the main reason for that is inadequacy of C). So all
you have to work with is one complete, type safe, Haskell program,
and the metal. In this scenario the only initialisation that's
done prior to running main is initialisation of the Haskell rts.

That said, the approach you outline below is workable and AFAICS
immune to the problems I was talking about. But you've introduced
an artificial distinction between OS and application to do this
and as a result..

* Made comms between application and hardware really awkward IMO
* Sacrificed type safety in these comms I think.

 (I have written a small
 OS myself, complete with real device drivers)... The OS is started at
 boot, it initialises its own state, then it forks the device drivers, then
 it forks user processes (simplified but adequate).

 Lets design a small Haskell OS, the OS has the handles for the device
 driver.
 The program MUST be passed the channels to the OS (there is no other
 way)... These channels allow other channels to be opened, they would be
 like the master device.

 main :: Chan CMD - Chan RSP - IO ()
 main cmd rsp = do
writeChan cmd (OpenDevice devname)
h - readChan rsp
case h of
   (OpenOK in out) - do
 writeCan out  (DeviceWriteString hello)
 status - readChan in
   _ - error could not open device

 Here you can see that we could try and open the device again, however the
 OS would either multiplex or serialize the device depending on type.

So you've gone for the third approach I identified, but with a slight
variation. You've wrapped all the separate device drivers into a single
uber device driver (world driver?) and called it the operating system.
I think this approach has it's pros and cons, but you're right that it
does solve the problem. But my original monosyllabic summary of MHO re.
this approach still applies I'm afraid.

Regards
--
Adrian Hey
 







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


Re: [Haskell] A puzzle and an annoying feature

2004-11-25 Thread Keean Schupke
I have already asked Simon PJ if this can be implemented in GHC... So if 
more people
ask for it, it might get done!

   Keean
Lennart Augustsson wrote:
Here is a small puzzle.
-- The following generates a type error:
f :: Char - Char
f c =
let x = g c
in  h x
-- But this definition does not:
f :: Char - Char
f c =
let x :: Bool
x = g c
in  h x
Furthermore, replacing Bool by any other type in the
latter definition will always give a type error.
How is this possible?
Scroll down for the answer.























Here is the module:
module Puzzle(f) where
f :: Char - Char
f c =
let x = g c
in  h x
class C a where
g :: Char - a
h :: a - Char
instance C Bool where
g c = c == 'T'
h b = if b then 'T' else 'F'
The error message from ghc is
Puzzle.hs:5:12:
Ambiguous type variable `a' in the top-level constraint:
  `C a' arising from use of `g' at Puzzle.hs:5:12
I know the technical reason why this is happening.
But it's hard for me to motivate why this is reasonable.
The type variable `a' is not ambiguous at all, the only
type it can possibly have is Bool; any other type is an error.
Furthermore, there can never be any other instance of the
class C added to any program using the module Puzzle since
the class C is not exported.
So in what sense is this really ambiguous?
I think it would be quite reasonable to allow the Puzzle module
to compile, resolving `a' to be Bool.  I.e., if there is only one
instance that can satisfy a constraint and there is no possibility
of adding instances outside the compiled module, I think resolving the
overloading makes sense.
-- Lennart
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell

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


Re: [Haskell] A puzzle and an annoying feature

2004-11-25 Thread Keean Schupke
No, closed classes are different, here we are talking about lazy overlap 
resolution, so
if at _call_ time only one instance fits we choose it. Closing a class 
is different.

   Keean.
Daan Leijen wrote:
Lennart Augustsson wrote:
[snip]
So in what sense is this really ambiguous?
I think it would be quite reasonable to allow the Puzzle module
to compile, resolving `a' to be Bool.  I.e., if there is only one
instance that can satisfy a constraint and there is no possibility
of adding instances outside the compiled module, I think resolving the
overloading makes sense.

You may be interested in a recent paper by Bastiaan Heeren and Juriaan
Hage [1] about type class directives. The closed directive in that 
paper is more or less implied by your example. Here is a quote from 
the paper:

The main advantage of a closed type class is that we know the fixed 
set of instances. Using this knowledge, we can influence the type 
inference process. As discussed in the introduction to Section 2, we 
can reject definitions early on (in case the set of instances for a 
certain type class is empty) or improve a type variable to a certain 
type (in case the set of instances is a singleton).

All the best,
 -- Daan Leijen.
[1] http://www.cs.uu.nl/~bastiaan/papers.html#typeclassdirectives
(to appear in PADL 2005)   


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


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

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


Re: [Haskell] A puzzle and an annoying feature

2004-11-25 Thread Daan Leijen
Keean Schupke wrote:
No, closed classes are different, here we are talking about lazy overlap 
resolution, so
if at _call_ time only one instance fits we choose it. Closing a class 
is different.
A closed class directive however is an explicit specification that
makes the intention of the designer explicit in the program. Since
it would solve the puzzle in a rather elegant and explicit way, I
thought that it was interesting to mention.
All the best,
 -- Daan.
   Keean.
Daan Leijen wrote:
Lennart Augustsson wrote:
[snip]
So in what sense is this really ambiguous?
I think it would be quite reasonable to allow the Puzzle module
to compile, resolving `a' to be Bool.  I.e., if there is only one
instance that can satisfy a constraint and there is no possibility
of adding instances outside the compiled module, I think resolving the
overloading makes sense.

You may be interested in a recent paper by Bastiaan Heeren and Juriaan
Hage [1] about type class directives. The closed directive in that 
paper is more or less implied by your example. Here is a quote from 
the paper:

The main advantage of a closed type class is that we know the fixed 
set of instances. Using this knowledge, we can influence the type 
inference process. As discussed in the introduction to Section 2, we 
can reject definitions early on (in case the set of instances for a 
certain type class is empty) or improve a type variable to a certain 
type (in case the set of instances is a singleton).

All the best,
 -- Daan Leijen.
[1] http://www.cs.uu.nl/~bastiaan/papers.html#typeclassdirectives
(to appear in PADL 2005)  

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


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

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


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


Re: [Haskell] A puzzle and an annoying feature

2004-11-25 Thread Graham Klyne
I have a concern with this, if I understand the issue correctly.
Suppose I have a source module that compiles and runs correctly.
Now suppose I add a restricted (selective) import statement to the file, 
explicitly introducing a name that I know does not clash with anything in 
my module.  I expect the module to continue to compile and run correctly.

If I understand Lennart's proposal correctly, adding such an import could 
cause the compilation to fail, by adding new instance options that then 
needs to be disambiguated.

Under the present regime, this is not a problem, because information to 
disambiguate the instance selection needs to added even if there's only one 
visible instance, so adding the restricted import cannot introduce this 
failure.

Similar concerns might apply if new instances are added to a module that is 
already a restricted import.

I suspect that the proper fix to this is that a selective import should 
also name the instances that are imported.  Then disambiguation of 
instances can reasonably be based on just the visible imports.  The 
automatic import of instances, even when the restricted form of import is 
used, has often seemed a little odd to me.

#g
--
At 14:36 25/11/04 +, Keean Schupke wrote:
I have already asked Simon PJ if this can be implemented in GHC... So if 
more people
ask for it, it might get done!

   Keean
Lennart Augustsson wrote:
Here is a small puzzle.
-- The following generates a type error:
f :: Char - Char
f c =
let x = g c
in  h x
-- But this definition does not:
f :: Char - Char
f c =
let x :: Bool
x = g c
in  h x
Furthermore, replacing Bool by any other type in the
latter definition will always give a type error.
How is this possible?
Scroll down for the answer.























Here is the module:
module Puzzle(f) where
f :: Char - Char
f c =
let x = g c
in  h x
class C a where
g :: Char - a
h :: a - Char
instance C Bool where
g c = c == 'T'
h b = if b then 'T' else 'F'
The error message from ghc is
Puzzle.hs:5:12:
Ambiguous type variable `a' in the top-level constraint:
  `C a' arising from use of `g' at Puzzle.hs:5:12
I know the technical reason why this is happening.
But it's hard for me to motivate why this is reasonable.
The type variable `a' is not ambiguous at all, the only
type it can possibly have is Bool; any other type is an error.
Furthermore, there can never be any other instance of the
class C added to any program using the module Puzzle since
the class C is not exported.
So in what sense is this really ambiguous?
I think it would be quite reasonable to allow the Puzzle module
to compile, resolving `a' to be Bool.  I.e., if there is only one
instance that can satisfy a constraint and there is no possibility
of adding instances outside the compiled module, I think resolving the
overloading makes sense.
-- Lennart
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell

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

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


Re: [Haskell] Real life examples

2004-11-25 Thread Keean Schupke
Thanks Adrian, for some reason I did not get the original reply to this 
post.

This was my point, I may _want_ two copies of the library. Lets say I 
want to
write a virtual machine emulator in haskell, and I then wish to use your
library to drive the virtualised hardware... There must be some way to
encapsulate the state requirement of the library such that the VM software
can manage multiple states. At the momemt (with the handle approach)
this is entirely possible:

   a - initLibrary
   b - initLibrary
With you suggestion this VM cannot be written in Haskell any more. This is
the point that I object to (and have been trying to explain badly).
Perhaps the following extension would fix things:
   main = do
  a - import Library -- a would be a record containing top level 
of library
  b - import Library

Keean.
Adrian Hey wrote:
On Wednesday 24 Nov 2004 9:37 pm, John Meacham wrote:
 

On Wed, Nov 24, 2004 at 03:48:56PM +, Keean Schupke wrote:
   

Having admited to wavering on the edge of accepting top level TWIs,
perhaps one of the supporters would like to comment on qualified
importing... IE what
happens to the unique property if I import 2 copies like so:
  module Main where
  import Library as L1
  import Library as L2
Although each library's internal state is initialised once, as required,
any real
IO could lead to problems... With the device driver example I now have
two bits of code that think they have exclusive access to the device...
But I can do:
 

Hmm? I am not really sure what you are asking. With my mdo proposal, and
I think all proposals brought forth, the module system behaves identically
to how it normally does for namespace control. top level initializers
are just constant definitions for all most everything is concerned.
modules do not change code at all, they are pure syntantic sugar for
deciding what names you can see.
i.e. it does not matter whether you do
import List as L1
import List as L2
L1.sort and L2.sort refer to the same thing. it would be no different if
sort were written with global state or even was a top level binding.
   

I think Keean is assuming the idea is that one should be able to duplicate
top level TWIs by importing the same module twice. But of course this is
not what's wanted. For example, it would enable users to short circuit the
safety provisons of all the oneShot examples.
If the purpose of a module is to allow users to have multiple distinct
(top level or otherwise) TWIs then it should be exporting an appropriate
newTWI constructor which is used in the usual manner by the importing
module(s)..
myTWI  - newTWI
myOtherTWI - newTWI
Regards
--
Adrian Hey
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell
 

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


Re: [Haskell] Real life examples

2004-11-25 Thread Ben Rudiak-Gould
John Meacham wrote:
I should say that efficiency is the only thing I have been concerned
about in this conversation. As I said in the mdo proposal, there is no
efficient and safe way to do global variables in haskell.
I think George Russell's library (with a simple extension) can be used 
to create global variables safely and with the same per-access 
efficiency as the other proposals:

   http://www.mail-archive.com/haskell@haskell.org/msg15709.html
Your library addresses a different issue, it provides an interface
for global variables, but it doesn't address the fundamental problem
that your library or ones like it cannot be implemented in haskell.
[...much elaboration on this idea omitted...]
I think I completely answered this objection in another message yesterday:
   http://www.mail-archive.com/haskell@haskell.org/msg15723.html
In short, his proposal should be considered in the same light as yours, 
as a /primitive/ extension to Haskell. (But I'd prefer you respond to my 
previous message rather than that sentence.)

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


Re: [Haskell] A puzzle and an annoying feature

2004-11-25 Thread Lennart Augustsson
Daan Leijen wrote:
Keean Schupke wrote:
No, closed classes are different, here we are talking about lazy 
overlap resolution, so
if at _call_ time only one instance fits we choose it. Closing a class 
is different.

A closed class directive however is an explicit specification that
makes the intention of the designer explicit in the program. Since
it would solve the puzzle in a rather elegant and explicit way, I
thought that it was interesting to mention.
Indeed, a closed directive would have been fine.  But it's not really
necessary, the class is obviously closed because of not being exported.
But the type checker doesn't use this fact.
I find it somewhat anomalous that there is one unique way to give types
to my program, but that the type checker refuses to do it. :)
-- Lennart
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell] A puzzle and an annoying feature

2004-11-25 Thread Lennart Augustsson
Of course it can.  I might do it myself.  :)
-- Lennart
Keean Schupke wrote:
I have already asked Simon PJ if this can be implemented in GHC... So if 
more people
ask for it, it might get done!

   Keean
Lennart Augustsson wrote:
Here is a small puzzle.
-- The following generates a type error:
f :: Char - Char
f c =
let x = g c
in  h x
-- But this definition does not:
f :: Char - Char
f c =
let x :: Bool
x = g c
in  h x
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell] A puzzle and an annoying feature

2004-11-25 Thread Lennart Augustsson
Graham Klyne wrote:
I have a concern with this, if I understand the issue correctly.
Suppose I have a source module that compiles and runs correctly.
Now suppose I add a restricted (selective) import statement to the file, 
explicitly introducing a name that I know does not clash with anything 
in my module.  I expect the module to continue to compile and run 
correctly.

If I understand Lennart's proposal correctly, adding such an import 
could cause the compilation to fail, by adding new instance options that 
then needs to be disambiguated.
Not in my particular case.  The class is local to the module.  Any
instance declaration would have to be in that module.
-- Lennart
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell] Better Exception Handling

2004-11-25 Thread Lennart Augustsson
John Goerzen wrote:
So why do we have:
catchJust :: (Exception - Maybe b) - IO a - (b - IO a) - IO a
instead of:
catchJust :: (Exception - Maybe b) - (c - a) - c - (b - a) - a
As I'm sure you have gathered from all the answers you can't have the
latter and keep Haskell pure.  But there is an interesting alternative
(at least theoretically).  You could have a function like
mkCatchJust :: IO ((Exception - Maybe b) - (c - a) - c - (b - a) - a)
And you would use it by
do
cj - mkCatchJust
  cj 
The cj function can be used in non-IO code and will behave just as you
want.  But you have to create it in the IO monad, since it's behaviour
is not deterministic (especially not in the face of async exceptions).
The tricky thing is to implement it, because cj should really only be
used once.  Why?  Because it has to behave the same way for the same
arguments every time.  This is not easily implemented. :(
-- Lennart
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell] Better Exception Handling

2004-11-25 Thread Tomasz Zielonka
On Thu, Nov 25, 2004 at 07:52:43PM +0100, Lennart Augustsson wrote:
 As I'm sure you have gathered from all the answers you can't have the
 latter and keep Haskell pure.  But there is an interesting alternative
 (at least theoretically).  You could have a function like
 
 mkCatchJust :: IO ((Exception - Maybe b) - (c - a) - c - (b - a) - a)

How is that different from this?

  mkReadFile :: IO (FilePath - String)

This is wrong. Even if I get a function as a result of an IO computation, I
expect that function to be pure.

 The cj function can be used in non-IO code and will behave just as you
 want.  But you have to create it in the IO monad, since it's behaviour
 is not deterministic (especially not in the face of async exceptions).

IO monad shouldn't be used to create non-deterministic functions. The whole
point in using IO monad is that functions stay pure, regardless of their
origin.

Best regards,
Tomasz
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell] Better Exception Handling

2004-11-25 Thread Jules Bean
On 25 Nov 2004, at 19:24, Tomasz Zielonka wrote:
On Thu, Nov 25, 2004 at 07:52:43PM +0100, Lennart Augustsson wrote:
As I'm sure you have gathered from all the answers you can't have the
latter and keep Haskell pure.  But there is an interesting alternative
(at least theoretically).  You could have a function like
mkCatchJust :: IO ((Exception - Maybe b) - (c - a) - c - (b - 
a) - a)
How is that different from this?
  mkReadFile :: IO (FilePath - String)
This is wrong. Even if I get a function as a result of an IO 
computation, I
expect that function to be pure.
Well, you can presumably give it a semantics which is pure. Whether it 
makes good sense is another question. The semantics is 'it creates a 
function which, when invoked, will return the contents of the file at 
some fixed (undefined) time'.

By the same token, you can just stick the function strangeReadFile :: 
FilePath - String into the language. As long as it is memoized, always 
returning the same value, it doesn't break beta-reduction. I call it 
'strange' because the time that the file is actually read is not 
guaranteed, so if you read more than one file in your program, you have 
no guarantee that you are reading a constant total state that actually 
existed at any point in time.  (Before you think this sounds unbearably 
horrible, there is at least one commercially sold RDBMS which has this 
semantics on its select statements ;P)

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


Re: [Haskell] Better Exception Handling

2004-11-25 Thread Lennart Augustsson
Tomasz Zielonka wrote:
On Thu, Nov 25, 2004 at 07:52:43PM +0100, Lennart Augustsson wrote:
As I'm sure you have gathered from all the answers you can't have the
latter and keep Haskell pure.  But there is an interesting alternative
(at least theoretically).  You could have a function like
mkCatchJust :: IO ((Exception - Maybe b) - (c - a) - c - (b - a) - a)

How is that different from this?
  mkReadFile :: IO (FilePath - String)
This is wrong.
Why is this wrong?

Even if I get a function as a result of an IO computation, I
expect that function to be pure.
Yes, so do I.  The function returned will have to be pure.  Pure in the
sense that given the same argument it always has to return the same
result.  In the case of mkReadFile this is not too hard to implement.
I admit that it is rather awkward, but it can be pure.
-- Lennart
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell] Better Exception Handling

2004-11-25 Thread Lennart Augustsson
Jules Bean wrote:
By the same token, you can just stick the function strangeReadFile :: 
FilePath - String into the language. As long as it is memoized, always 
returning the same value, it doesn't break beta-reduction. I call it 
'strange' because the time that the file is actually read is not 
guaranteed, so if you read more than one file in your program, you have 
no guarantee that you are reading a constant total state that actually 
existed at any point in time.  (Before you think this sounds unbearably 
horrible, there is at least one commercially sold RDBMS which has this 
semantics on its select statements ;P)
It is also strange by the fact that strangeReadFile can very well be
different functions at different runs of the program.  That's why I
think such a function should be generated by the IO monad.  (If you
want it at all!)
-- Lennart
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell] A puzzle and an annoying feature

2004-11-25 Thread Daan Leijen
Lennart Augustsson wrote:
Daan Leijen wrote:
A closed class directive however is an explicit specification that
makes the intention of the designer explicit in the program. Since
it would solve the puzzle in a rather elegant and explicit way, I
thought that it was interesting to mention.
Indeed, a closed directive would have been fine.  But it's not really
necessary, the class is obviously closed because of not being exported.
But the type checker doesn't use this fact.
I find it somewhat anomalous that there is one unique way to give types
to my program, but that the type checker refuses to do it. :)
You are right, I feel like that too: one should expect that the type
checker can figure this out, and perhaps it is even really useful.
On the other hand, suppose you decide later to export the
class, and suddenly your code would no longer type check.
The fact that adding an export defintion would lead to a type
error somewhere else in the code might be rather confusing.
(worse! it might be considered inelegant :-)
Personally, I feel that this problem might be better solved by
making a lot of the implicit assumptions (and semantics) of type
classes more explicit, and bring them under user control. Of course,
I do have not have any idea of how this should be done concretely ;-)
(although type class directives might be a step in the right direction?)
-- Daan
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell] A puzzle and an annoying feature

2004-11-25 Thread Lennart Augustsson
Daan Leijen wrote:
You are right, I feel like that too: one should expect that the type
checker can figure this out, and perhaps it is even really useful.
On the other hand, suppose you decide later to export the
class, and suddenly your code would no longer type check.
The fact that adding an export defintion would lead to a type
error somewhere else in the code might be rather confusing.
(worse! it might be considered inelegant :-)
Yes, that is somewhat strange, I agree. :)
Personally, I feel that this problem might be better solved by
making a lot of the implicit assumptions (and semantics) of type
classes more explicit, and bring them under user control. Of course,
I do have not have any idea of how this should be done concretely ;-)
(although type class directives might be a step in the right direction?)
Yes, I think the type class directives is a step forwards.  :)
-- Lennart
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell] A puzzle and an annoying feature

2004-11-25 Thread Keean Schupke
Daan Leijen wrote:
You are right, I feel like that too: one should expect that the type
checker can figure this out, and perhaps it is even really useful.
On the other hand, suppose you decide later to export the
class, and suddenly your code would no longer type check.
I must have missed a mail... how could adding an export change the
code?
The fact that adding an export defintion would lead to a type
error somewhere else in the code might be rather confusing.
(worse! it might be considered inelegant :-)

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


Re: [Haskell] A puzzle and an annoying feature

2004-11-25 Thread Lennart Augustsson
Keean Schupke wrote:
Daan Leijen wrote:
You are right, I feel like that too: one should expect that the type
checker can figure this out, and perhaps it is even really useful.
On the other hand, suppose you decide later to export the
class, and suddenly your code would no longer type check.

I must have missed a mail... how could adding an export change the
code?
If you export the class you can add another instance to it.  And now
my type variable would really be ambiguous.
-- Lennart
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


[Haskell] Haskell-mode 2.0

2004-11-25 Thread Stefan Monnier

I have recently taken over maintainership of Haskell-mode, and after making
a bunch of changes, I figured it would be a good idea to make a new release.
You can find this new release at:

http://www-perso.iro.umontreal.ca/~monnier/elisp/

If you think it should also be found at
http://www.haskell.org/haskell-mode/, then please tell John Peterson to get
back to me (my email to him seem to go straight to the bitbucket. John?).

This release has several changes that have all been only lightly tested,
especially w.r.t compatibility with various Emacsen.

See appended the NEWS file that describes some of the notewirthy changes.


Stefan


Changes since 1.45:

* keybindings C-c char have been replaced by C-c C-char so as not
  to collide with minor modes.

* The following modules are now automatically activated without having to
  add anything to haskell-mode-hook:
  haskell-font-lock (just turn on global-font-lock-mode).
  haskell-decl-scan (just bind `imenu' to some key).

* In recent Emacsen, haskell-doc hooks into eldoc-mode.

* haskell-hugs and haskell-ghci are superceded by inf-haskell.

* Indentation rules have been improved when using layout inside parens/braces.

* Symbols like - and \ can be displayed as actual arrows and lambdas.
  See haskell-font-lock-symbols.

* Tweaks to the font-lock settings.  Among other things paren-matching
  with things like \(x,y) should work correctly now.

* New maintainer [EMAIL PROTECTED].

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


[Haskell] Re: Top-level -

2004-11-25 Thread George Russell
John Meacham wrote (snipped):
 recursive top level declarations are no more tricky than are normal
 recursive lets.
Perhaps I am missing something, but surely one very important problem with
- at top level is that calling for the value of something defined by -
causes the corresponding action to be performed?  Unless the actions available
are very tightly restricted, this means that for example the meaning of a
program depends on what order arguments to a pure functions are evaluated,
for example.
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Low-level notation for type classes WAS: [Haskell] A puzzle and an annoying feature

2004-11-25 Thread Martin Sulzmann
Hi,

Daan said:

  
  Personally, I feel that this problem might be better solved by
  making a lot of the implicit assumptions (and semantics) of type
  classes more explicit, and bring them under user control. Of course,
  I do have not have any idea of how this should be done concretely ;-)
  
  (although type class directives might be a step in the right direction?)
  

Well, you might not need to look that far :)
To a great extent you can use Constraint Handling Rules (CHRs)
to explain type classes.

E.g., consider

Gregory J. Duck, Simon Peyton-Jones, Peter J. Stuckey and Martin Sulzmann  
Sound and Decidable Type Inference for Functional Dependencies

Peter J. Stuckey and Martin Sulzmann  
A Theory of Overloading


I've just skimmed through the Type Class Directives paper.
Pl correct me if I'm wrong but it appears that
the disjoint directive can be modeled by CHRs.

Example:

disjoint (Integral, Fractional)

can be encoded by

rule Integral a, Fractional a == False (1)

The never directive is in fact a special instance of disjoint.
E.g.,

never Num Bool

can be encoded by

rule Num Bool == False (2)

Note that the Chameleon type debugger provides type error explanation
support if the error is due to rule applications such as (1) and (2).

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


[Haskell-cafe] [Haskell] Re: Global Variables and IO initializers

2004-11-25 Thread George Russell
 This is funny. When I got no immediate reaction from you, I started
 implementing it myself. I ended up with something similar. It has less
 features but is also a lot simpler. This is the interface:

 initGlobal :: Typeable a = a - IO ()
 getGlobal :: Typeable a = IO a
Your implementation is probably much simpler than mine because you don't
implement withEmptyDict.  I'm really quite keen about withEmptyDict, because
one of the MAJOR conceptual problems I have with unsafePerformIO global 
variables
is that you only get one universe, corresponding to the Haskell program.
There shouldn't really be a single the Haskell program anyway; imagine 
something
like GHC or an operating system written in Haskell which run sub-systems which
require their own global variables.  Or imagine a program split between lots of
processors where, for efficiency reasons, you don't want everyone to have to 
refer
to the same set of global variables.o
 Storing (TypeRep,Dynamic) pairs is redundant, since Dynamics already
 contain their own TypeRep (that is how they are made to work).
It is, but I'm not sure if it can be avoided without using stuff not in
the standard libraries.
 I also use a list for the dictionary; and I share your view about
 TypeRep badly needing an Ord instance (probably trivial to provide
 but I could be wrong).
Even better would be a hashable integer.  TypeRep actually is implemented
internally on GHC using a hashcons'd unique integer, so exposing it should be
trivial ...
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] RE: [Haskell] Lexically scoped type variables

2004-11-25 Thread Josef Svenningsson
Let me just begin by sharing my experience with scoped type variables. I've
found them very useful in a project were I was to generalize a substantial
code base. Many of the functions had local definitions whose type were
simply not expressible without scoped type variables. During this work I
found an interesting interplay between multi parameter type classes and
scoped type variables. An example would look something like this:

f :: C a b c = a - b
f a = 
   let g = ...

The important thing to note is that the type variable c in f's signature
occurs neither in the argument nor the result type of f. Hence c is not
bindable by lexically scoped type variables. But suppose c is part of g's
type. Then we still have no way of expressing g's type! This thing has
bitten me and so I welcome the change you're planning.

As for your questions I would prefer 1b although I don't think it is a big
deal. For your second question I would go for 2c (which you've called 2b :).
That's because I don't use result type signatures. Other people will surely
disagree.

Cheers,

/Josef

 -Original Message-
 From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On
 Behalf Of Simon Peyton-Jones
 Sent: den 25 november 2004 11:44
 To: [EMAIL PROTECTED]
 Subject: [Haskell] Lexically scoped type variables
 
 | This is a great example, thanks for posting it. However, I feel like
 | the real problem in this example is the lexically-scoped type
 | variables declared with your function f.
 
 Paul's message gives me an excuse to consult the Haskell list about the
 design of lexically scoped type variables.   I have a two particular
 questions I'd like your advice about.  (This is nothing to do with
 monomorphism restriction, or Lennart's original puzzle.)
 
 I'm sending this message to the main Haskell list, to maximise
 readership, but I suggest that
 
   you reply to [EMAIL PROTECTED]
 
 Thereby to avoid spamming the main Haskell list, which is meant to be
 low-bandwidth.  I believe I've set the reply-to field of this message to
 achieve this goal.  [Perhaps others can do the same?!]
 
 Simon
 
  Background 
 
 First, for background you might want to glance at Lexically scoped type
 variables, an unpublished paper available at
   http://research.microsoft.com/%7Esimonpj/papers/scoped-tyvars
 I don't want to take time in this message to discuss why we want scoped
 type variables; I'll just take it for granted here.
 
 One design choice discussed in the paper, and implemented in GHC, is
 that we can bring new lexically-scoped type variables into scope by
 mentioning them in a pattern type signature:
   f (x::a) = 
 Here 'a' is a name for the type of x, and 'a' scopes over f's body, and
 can be mentioned in type signatures in f's body.  Sometimes one wants to
 name types in the result* of f, rather than it its *arguments*.  For
 example
   head (xs::[a]) :: a = ...
 Here, the :: a before the = gives the type of head's result.  If a
 result type signature binds a type variable, that type variable scopes
 over the right hand side of the definition.
 
 In GHC, it's not necessary for the type that 'a' names to be a type
 variable; it could be Int, for example:
   f (x::a) = x + (1::Int)
 Already this embodies several design choices.  For example, we know that
 'a' is a *binding* for 'a' because there is no 'a' already in scope,
 otherwise it'd be an *occurrence* of 'a'.  (An alternative would be to
 mark binding sites somehow.)  Also once could require that 'a' names a
 type variable rather than an arbitrary type.  But for this message I
 want to take GHC's design as given.
 
  QUESTION 1 -
 
 In GHC at present, a separate type signature introduces no scoping.  For
 example:
   f :: forall a. a - a
   f x = (x::a)
 would be rejected, because the type signature for 'f' does not make
 anything scope over the right-hand side, so (x::a) means (x::forall
 a.a), which is ill typed.
 
 An obvious alternative, taken up by (among others) Mondrian and
 Chamaeleon, is to say that
 
   the top-level quantified variables of a separate type signature
   scope over the right hand side of the binding
 
 In the above example, then, the 'a' bound by the 'forall' would scope
 over the right hand side of 'f'.
 
 I've argued against this in the past, because the construct (forall a.
 type) patently scopes 'a' only over type.  But my resolve is
 weakening.  It's just too convenient!  Furthermore, it binds a *rigid*
 type variable (i.e. 'a' really must name a type variable) and that's
 important for GADTs... which strengthens the case.
 
 In short, I'm considering adopting the Mondrian/Chameleon rule for GHC.
 There are two variations
 
   1a) In the example, 'a' is only brought into scope in the
right hand side if there's an explicit 'forall' written by
 the programmer
   1b) It's brought into scope even if the forall is implicit; e.g.
   f :: a - a
   f x = 

Re: [Haskell-cafe] [Haskell] Re: Global Variables and IO initializers

2004-11-25 Thread Marcin 'Qrczak' Kowalczyk
George Russell [EMAIL PROTECTED] writes:

 Your implementation is probably much simpler than mine because
 you don't implement withEmptyDict. I'm really quite keen about
 withEmptyDict, because one of the MAJOR conceptual problems I have
 with unsafePerformIO global variables is that you only get one
 universe, corresponding to the Haskell program.

I think global variables are a lot less evil if they behave as if they
were dynamically scoped, like Lisp special variables.

That is, there is a construct which gives the variable a new mutable
binding visible in the given IO action. It's used more often than
assignment. Assignment is still available though.

In Common Lisp implementations these variables are not inherited
by threads: each thread starts with toplevel bindings of dynamic
variables. I think this is wrong and they should be inherited.
In my language Kogut they are inherited.

With threads it makes a difference that the variable gets a new
binding, not just a new value. The old binding is still mutable by
threads which have not shadowed it. When the scope of the new binding
finishes, the value restored in this thread might be different than
the value from the time the scope was entered, if other threads have
changed it in the meantime.

In Haskell it would be a new kind of reference, parallel to IORef
and MVar.

In principle dynamic variables need not to be defined at the toplevel.
In Lisp they are effectively always toplevel variables (even if
declared locally); in my language they can be created in arbitrary
places, e.g. as fields of objects. But usually they are toplevel.
It would be pointless to *not* have toplevel dynamic variables,
because their purpose is to avoid manually threading them through
all actions which need them.

This is an alternative design to Haskell's implicit parameters. It's
different in that it applies to the IO monad only (dynamic variables
obviously can't be read from pure code) and that the fact that an
action uses a particular variable is not reflected in its type.

Their primary use is to provide a default setting used in deep places
in a computation, with the assumption that usually a single setting
applies to the whole computation started from a given place. Like the
random number generator, the default output handle (not the *internals*
of stdOut as a statefulobject, but binding the stdOut variable to
different handles, not possible in Haskell), the current locale or
individual settings implied by the locale (I don't know yet how
inheritable settings should be designed, like the locale as a whole
and its parts).

-- 
   __( Marcin Kowalczyk
   \__/   [EMAIL PROTECTED]
^^ http://qrnik.knm.org.pl/~qrczak/
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Yet another IO initializer: Effectful declarations and an ACIO monad

2004-11-25 Thread Jules Bean
On 25 Nov 2004, at 10:07, [EMAIL PROTECTED] wrote:
Way back in this thread, Koen Claessen mentioned the idea of a 
commutative
version of the IO monad for handling things with identity.  That 
doesn't quite
do it, but I have a refinement that might.  The thing is to focus on IO
computations that are:

 a) central -- their effect commutes with every other IO action
 b) affine  -- their effect is not directly observable, and can be 
discarded.

Thus an element u of (IO a) is affine central if for all v::IO b and 
w::IO c,

  do { x - u; v } = v(affine)
If x does not occur in v, I presume?
Jules
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Yet another IO initializer: Effectful declarations and an ACIO monad

2004-11-25 Thread Ian . Stark
On Thu, 25 Nov 2004, Jules Bean wrote:

 On 25 Nov 2004, at 10:07, [EMAIL PROTECTED] wrote:
 
  Thus an element u of (IO a) is affine central if for all v::IO b and
  w::IO c,
 
do { x - u; v } = v(affine)

 If x does not occur in v, I presume?


Yes, and similarly for centrality:

  do { x - u; y -v; w } = do { y - v; x - u; w }  (central)

applies only when x not free in v and y not free in u.

This means that ACIO computations can be rearranged and discarded, but
only within the limits of dataflow dependencies between the values.

Working out these dependencies are the job of a compiler, exactly as with
standard value declarations in Haskell.  I think it should even be
possible to have mutually recursive ACIO declarations, provided non-strict
constructors intervene.

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


[Haskell-cafe] Interview with David Roundy on darcs and Haskell

2004-11-25 Thread Josef Svenningsson
Hi all,

At osdir there is a nice interview with David Roundy about darcs, the
revision control system written in Haskell. He has a few comments about
Haskell as well. Read it here:
http://osdir.com/Article2571.phtml

This was also covered on /. (which is where I found it).

/Josef

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


[Haskell-cafe] Re: [Haskell] Re: Global Variables and IO initializers

2004-11-25 Thread Benjamin Franksen
On Thursday 25 November 2004 10:02, you wrote:
   This is funny. When I got no immediate reaction from you, I started
   implementing it myself. I ended up with something similar. It has less
   features but is also a lot simpler. This is the interface:
  
   initGlobal :: Typeable a = a - IO ()
   getGlobal :: Typeable a = IO a

 Your implementation is probably much simpler than mine because you don't
 implement withEmptyDict.  I'm really quite keen about withEmptyDict,
 because one of the MAJOR conceptual problems I have with unsafePerformIO
 global variables is that you only get one universe, corresponding to the
 Haskell program. There shouldn't really be a single the Haskell program 
 anyway;

Doesn't that run contrary to Adrian Hey's oneShot example/requirement?

 imagine something like GHC or an operating system written in 
 Haskell which run sub-systems which require their own global variables.

Well, that's indeed one major problems with global variables. Sure, you can 
try to solve it with multiple dictionaries, but that makes understanding what 
a certain part of the program does even harder. How do I find out what 
dictionary a write or read to a (no longer global) variable refers to?

Furthermore, I have great difficulty in understanding why different threads 
need different dictionaries. Could you explain why this is useful, or rather, 
more useful than a global single dictionary?

It reminds me of the usual thread-local variables that are offered by most 
systemlevel thread libraries. I think they put them in there so that they can 
easily port non-reentrant libraries (i.e. ones that use global variables 
internally) to a multi-threaded setting without changing their APIs. This 
approach leads to libraries that are extremely inconvenient and dangerous to 
use. Their existence is one of the reasons why I have been arguing so much 
against global variables.

   Storing (TypeRep,Dynamic) pairs is redundant, since Dynamics already
   contain their own TypeRep (that is how they are made to work).

 It is, but I'm not sure if it can be avoided without using stuff not in
 the standard libraries.

What non-standard libraries have I used (that you don't)?

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


[Haskell-cafe] Re: Yet another IO initializer: Effectful declarations and an ACIO monad

2004-11-25 Thread George Russell
Ian Stark wrote (snipped):
 Way back in this thread, Koen Claessen mentioned the idea of a commutative
 version of the IO monad for handling things with identity.  That doesn't quite
 do it, but I have a refinement that might.  The thing is to focus on IO
 computations that are:

  a) central -- their effect commutes with every other IO action
  b) affine  -- their effect is not directly observable, and can be discarded.
Unfortunately I have a number of examples where I use global variables with
initialisation actions which cannot conceivably be proven to be central  affine
by the compiler.  For example, where I want to call up an external program (such
as wish) which I will later use for doing graphics.
The Haskell libraries would run into a similar problem when they tried to
open stdin/stdout/stderr.  Or indeed when they tried to implement RandomGen,
which I presume is going to want to get at the system clock to seed the
random number generator.
My guess is that if we were to have top-level - actions where the actions were
restricted to those certified to be ACIO, it would not be very long before GHC
would implement an unsafeForceACIO function ...
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: Global Variables and IO initializers

2004-11-25 Thread George Russell
Marcin wrote (snipped):
 I think global variables are a lot less evil if they behave as if they
 were dynamically scoped, like Lisp special variables.

 That is, there is a construct which gives the variable a new mutable
 binding visible in the given IO action. It's used more often than
 assignment. Assignment is still available though.
I agree entirely.  The fact that declaring global variables using 
unsafePerformIO
introduces an artificial notion of global and forces it on every part of the
program is a major disadvantage which we haven't heard enough about in this
discussion.  It prevents you doing all sorts of things.  It's bad for 
parallelism.
It prevents you running two independent copies of a (main) action.  It prevents
you writing a Haskell controller which runs over Haskell actions as subprograms.
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: [Haskell] Re: Global Variables and IO initializers

2004-11-25 Thread George Russell
Benjamin Franksen wrote (snipped):
 Doesn't that run contrary to Adrian Hey's oneShot example/requirement?
Remind me again what Adrian Hey's oneShot example/requirement is ...
 Well, that's indeed one major problems with global variables. Sure, you can
 try to solve it with multiple dictionaries, but that makes understanding what
 a certain part of the program does even harder. How do I find out what
 dictionary a write or read to a (no longer global) variable refers to?
This seems to me as unnecessary as asking for which memory location it has.
Provided the no-longer-global variables act as if they were global within
their own universe, there is no problem.   The withEmptyDict operator
I provide gives you a new universe where everything starts from scratch.
It seems to me you have a much bigger problem when you force everything to
have global variables, and then want to run multiple copies of a program,
only to have them clobber each other's variables.
 Furthermore, I have great difficulty in understanding why different threads
 need different dictionaries. Could you explain why this is useful, or rather,
 more useful than a global single dictionary?
Consider Data.Unique implemented over lots of processors.  If you had a single
IORef managed by a single processor used to generate new unique identifiers,
there is the danger that that processor will become a bottleneck for the whole
system.  Much better to have a thread-local or processor-local IORef which 
generates
new identifiers, which you then prepend with a processor tag.
Me (snipped):
 It is, but I'm not sure if it can be avoided without using stuff not in
 the standard libraries.
Ben:
 What non-standard libraries have I used (that you don't)?
OK, but you have to test every element of the dictionary with fromDynamic until
you find one with the type you want, which is not a good idea if the dictionary
is big.  My implementation is equally inefficient now (because TypeRep's have
no Ord), but if TypeRep's had Ord or a hashing function (both would be very
easy to provide from GHC's implementation) I could make my implementation
efficient very easily, while you'd have to completely rewrite yours to get
the same effect.
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] [Haskell] A puzzle and an annoying feature

2004-11-25 Thread Martin Sulzmann

[Discussion moved from Haskell to Haskell-Cafe]

Hi,

Regarding

- lazy overlap resolution aka unique instances

Well, if there's only instance which is not exported, then you can
use functional dependencies.

Assume

class C a
instance ... = C t

Internally, use

class C a | - a
instance ... = C t
 

Furthermore, there seems to be an issue that has been overlooked so far.

- Providing sufficient type annotations

Recall

Lennart Augustsson writes:
  Here is a small puzzle.
  
  -- The following generates a type error:
  f :: Char - Char
  f c =
   let x = g c
   in  h x
  

Lennart magically inserted a type annotation to resolve the ambiguity.

  -- But this definition does not:
  f :: Char - Char
  f c =
   let x :: Bool
   x = g c
   in  h x
  

Clearly, there are a number of ways to resolve the ambiguity.
The Chameleon type debugger assists the user in identifying
which locations are responsible.

Here's the Chameleon type debugger error message generated
for the unannotated function f


temp.ch:2: ERROR: Inferred type scheme is ambiguous:
Type scheme: forall b. C b = Char - Char
  Suggestion: Ambiguity can be resolved at these locations
  b: f :: Char - Char
 f c = let x = g c
   ^   ^
   in  h x
   ^ ^
(The ^ correspond to highlightings of the Chameleon type debugger)


This may help the user to realize where and which annotations are
missing. E.g., each of the following annotations (there are more
possibilities) will do the job.

f :: Char - Char
f c =
 let -- x :: Bool (1)
 x = g c
 in  h x -- h (x::Bool) (2)
 -- (h::Bool-Char) x (3)


Martin

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