Re: [Haskell] modern language design, stone age tools

2004-06-23 Thread Fergus Henderson
On 23-Jun-2004, Hal Daume III <[EMAIL PROTECTED]> wrote:
> On Wed, 23 Jun 2004, Fergus Henderson wrote:
> 
> > On 23-Jun-2004, MR K P SCHUPKE <[EMAIL PROTECTED]> wrote:
> > > This may not be the right answer to the question (which is of
> > > course lets write a debugger) - But I have never used a debugger,
> > > and find them more or less the most unfriendly and useless things
> > 
> > So how do you debug problems like "Prelude.head: empty list"
> > in large programs?
> 
> Wasn't addressed to me, but here's what I do:
> 
> write the following function:
> 
>   head_ x [] = error ("head_: " ++ show x)
>   head_ _ l  = head l
> 
> and then replace each occurance of "head" with "head_ 1" or "head_ 2" 
> etc., so I can know where it failed.

Well, there are quite a lot of such occurrences in the code that I'm working
on:

bash$ find . -name \*.hs -o -name \*.lhs | xargs grep -w head | wc -l
130

Replacing all of those occurrences by hand is going to be very very
tedious and somewhat time-consuming.  Doing it with a script would be
better, but that's not a trivial task.

Even once that is done, there's no guarantee it will actually help to
find the problem.  After all, the problem might well be arising from a
call to "head" in one of ghc's standard libraries:

bash$ find ~/ghc6-6.2/hslibs \*.hs -o -name \*.lhs | xargs grep -w head | wc -l
104

So not only do I have to edit my own code, and the libraries written by
my colleagues, I also need to edit the ghc library code, and figure out
how to build and reinstall the ghc libraries.  That could take a long time.

After all that, hopefully I will finally know which function called
"head" with an empty list.  But even then there's still no guarantee
that I've actually found the source of the problem; the real problem
might be in that function's caller, or the caller's caller, etc.  So I
might have to go through the whole process again.

> (it is rather sad that this is the best approach i could come up
> with...basically tries to get around the [lack of/uselessness of/inability
> to use with ghci] stack traces)

Yes :-(

-- 
Fergus J. Henderson |  "I have always known that the pursuit
Galois Connections, Inc.|  of excellence is a lethal habit"
Phone: +1 503 626 6616  | -- the last words of T. S. Garp.
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell] modern language design, stone age tools

2004-06-23 Thread Fergus Henderson
On 23-Jun-2004, Ketil Malde  wrote:
> > Thirdly, profiling seems to be incompatible with the use of ghci; there
> > doesn't seem to be any easy way to build a workspace so that you can
> > get stack traces and use ghci in that workspace at the same time.
> 
> You can compile with: -prof -auto-all -hisuf p.hi -osuf p.o 
> This will create separate object and interface files for profiling.

Thanks!  That is a useful tip.

-- 
Fergus J. Henderson |  "I have always known that the pursuit
Galois Connections, Inc.|  of excellence is a lethal habit"
Phone: +1 503 626 6616  | -- the last words of T. S. Garp.
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell] modern language design, stone age tools

2004-06-23 Thread Fergus Henderson
On 23-Jun-2004, MR K P SCHUPKE <[EMAIL PROTECTED]> wrote:
> This may not be the right answer to the question (which is of
> course lets write a debugger) - But I have never used a debugger,
> and find them more or less the most unfriendly and useless things

So how do you debug problems like "Prelude.head: empty list"
in large programs?

-- 
Fergus J. Henderson |  "I have always known that the pursuit
Galois Connections, Inc.|  of excellence is a lethal habit"
Phone: +1 503 626 6616  | -- the last words of T. S. Garp.
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


[Haskell] modern language design, stone age tools

2004-06-22 Thread Fergus Henderson
\begin{gripe}

Seeing as Haskell is apparently such a popular language these days,
I don't suppose a working debugger would be too much to ask for, would it?
Or even just a decent call stack trace when a program terminates with an exception?

In case you're wondering, yes I have already tried using Hat and Buddha.
But I'm trying to debug a real application, not a toy one, and neither Hat
nor Buddha support enough of Haskell.  Buddha doesn't even come close,
as far as I can tell, and Hat lacks support for library modules such as Data.Word.

I've also tried using ghc's profiling to get stack traces, but that doesn't
work very well either.  Firstly, the stack traces that you get only include
function names, not line numbers.  Secondly, the stack traces are often
incomplete, for reasons that I don't fully understand.  One likely cause is
tail call optimization.  (Is there any option to switch off tail call optimization?
I didn't see any such option in the ghc man page.)
Thirdly, profiling seems to be incompatible with the use of ghci; there
doesn't seem to be any easy way to build a workspace so that you can
get stack traces and use ghci in that workspace at the same time.
And ghc is slow enough (even on a 3.2GHz Pentium 4) that recompiling
the whole workspace is highly unpalettable.

There's a hell of a lot of languages out there that _do_ support decent
stack traces when an exception is thrown.  

What's the point of using a high-level functional language if it means
you're stuck with poor library support and/or stone-age tools?

\end{gripe}

-- 
Fergus J. Henderson |  "I have always known that the pursuit
Galois Connections, Inc.|  of excellence is a lethal habit"
Phone: +1 503 626 6616  | -- the last words of T. S. Garp.
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: Haskell naming conventions

2003-12-28 Thread Fergus Henderson
On 23-Dec-2003, Sean L. Palmer <[EMAIL PROTECTED]> wrote:
> It occurs to me that Haskell would be quite a bit easier for OO and
> traditional programmers to grasp if Haskell would actually use the
> correct, or at least more commonly used, names for things.

> For instance, 
> 
> data Maybe a = Nothing | Just a
> 
> Maybe is a type constructor and Nothing and Just are data constructors.
> 
> So it makes me wonder why the use of the data keyword... wouldn't it make more sense 
> to say: 
> 
> type Maybe a = Nothing | Just a
> 
> ?

I agree.  That's one of the reasons why Mercury uses the word "type"
rather than "data" when declaring discriminated union types.

The corresponding declaration in Mercury is

:- type maybe(A) ---> nothing ; just(A).

> Likewise with class, type class, and instance:
> 
> class Eq a where
> (==) :: a -> a -> Bool
> 
> That actually declares a type class, not a class.  So why the use of
> the keyword class?  Is it done merely to confuse C++ and Java programmers?

This is indeed potentially confusing for programmers familiar with
C++/Java/C#/Ada/etc.

In Mercury, we adopted Haskell-style type classes, using semantics
very similar to those in Haskell.  But we did adapt the syntax a bit.
In particular, we use "typeclass" rather than "class" for type class
declarations.  So in Mercury, the corresponding declaration would look
like this:

:- typeclass eq(A) where [
func '=='(A, A) = bool
].

> The concept of type class in Haskell apparently roughly corresponds
> to the concept of "interface" in Java.  So why not call it interface?

Haskell interfaces are really quite a bit more general than Java interfaces,
particularly when you consider common extensions such as multi-parameter
type classes, constructor classes, and functional dependencies.  So I think
it would not help to use the word "interface".

-- 
Fergus Henderson <[EMAIL PROTECTED]>  |  "I have always known that the pursuit
The University of Melbourne |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  | -- the last words of T. S. Garp.
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: Annotating Expressions

2003-12-16 Thread Fergus Henderson
On 16-Dec-2003, [EMAIL PROTECTED] <[EMAIL PROTECTED]> wrote:
> G'day all.
> 
> Quoting John Meacham <[EMAIL PROTECTED]>:
> 
> > Imagine I have a data structure like so:
> >
> > data E = EAp E E | ELam Int E | ELetRec [(Int,E)] E | EVar Int
> >
> > now, I want to annotate every occurence of E with some pass specific
> > information, such as free variables or levels for lambda lifting.
> 
> http://haskell.org/hawiki/DecoratingStructures
> http://haskell.org/hawiki/IndirectComposite

Unless I missed something, none of those solve all the problems that
Meacham is trying to solve (numbers 1 and 2 in his original mail).

-- 
Fergus Henderson <[EMAIL PROTECTED]>  |  "I have always known that the pursuit
The University of Melbourne |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  | -- the last words of T. S. Garp.
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: Annotating Expressions

2003-12-16 Thread Fergus Henderson
On 16-Dec-2003, John Meacham <[EMAIL PROTECTED]> wrote:
> newtype Id a = Id a
> 
> type Er f = f (E f)  -- E used recursivly
> data E f = EAp (Er f) (Er f) | ELam Int (Er f) | 
> ELetRec [(Int,Er f)] (Er f) | EVar Int
> 
> [...] problem 2 persists. If I don't want to be constantly
> casting to and from Id, I have to use both the seperate annotated and
> unannotated versions.
> 
> is this actually the case? is there a better solution I don't see? perhaps
> something using crazy GHC extensions? if not, are there any proposed
> extensions which would solve this promlem?

I think views <http://www.haskell.org/development/views.html>
would solve this problem, wouldn't they?

You could define a view of `E Id' with constructors
that skip over the conversions to/from Id

view EId of E Id = App (E Id) (E Id) | Lam Int (E Id) |
LetRec [(Int,E Id)] (E Id) | Var Int
   where
eid (EAp (Id x) (Id y)) = Ap x y
eid (ELam x (Id y)) = Lam x y
eid (ELetRec (B bindings) (Id e)) = LetRec bindings' e
   where bindings' = map (\(v,(Id x))->(v,x)) bindings
eid (EVar v) = Var v

Then you can traverse expressions without needing to write
any explicit conversions to/from Id, e.g.

-- "occurs v e" returns True iff v occurs somewhere in e
occurs :: Int -> (E Id) -> Bool
occurs v (Lam v1 e) = v == v1 || occurs v e
occurs v (Ap x y) = occurs v x || occurs v y
occurs v (LetRec bindings e) =
any (\(vi,ei)->v==vi || occurs v ei) bindings || occurs v e
occurs v (Var v1) = v == v1

-- 
Fergus Henderson <[EMAIL PROTECTED]>  |  "I have always known that the pursuit
The University of Melbourne |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  | -- the last words of T. S. Garp.
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: pattern-matching extension?

2003-12-07 Thread Fergus Henderson
On 05-Dec-2003, Derek Elkins <[EMAIL PROTECTED]> wrote:
> "Abraham Egnor" <[EMAIL PROTECTED]> wrote:
> > I've occasionally wanted some sort of equivalent of an instanceOf
> > function in haskell, i.e. one that would let me define a function that
> > could dispatch on the type of its argument as well as the value.  One
> > option I've seen for this is
> > "http://okmij.org/ftp/Haskell/class-based-dispatch.lhs";, but that
> > unfortunately has the downside of requiring you to write both a
> > constructor for PACK and an instance of Packable for each type you'd
> > like to dispatch on.
> > 
> > The thought occurred to me that it is (intuitively) natural to do this
> > via extending the pattern-matching facility to include types as well
> > as literal values, i.e. something like:
> > 
> > f :: a -> String
> > f (a :: Int) = "got an int, incremented: "++(show (a+1))
> > f (a :: Show q => q) = "got a showable: "++(show a)
> > f _ = "got something else"
> > 
> > This has a couple of nice features - it's a simple extension of the
> > syntax, and acts as a sort of type-safe typecast.  However, I have
> > zero knowledge of how hard it would be to implement this, and there
> > may be theoretical difficulties I haven't seen.  Thoughts?
...
> data Showable = forall a. Show a => Showable a
> 
> instance Show Showable where
> show (Showable showable) = show showable
> 
> -- extension: pattern guards (I think Hugs has them but I don't think
> -- NHC does. They are only used for prettiness here.)
> f :: Dynamic -> String
> f val | Just (a :: Int) <- fromDynamic val
> = "got an int, incremented: "++show (a+1)
>   | Just (a :: Showable) <- fromDynamic val
> = "got a showable: "++show a

Casting to a "Showable" is not the same as a dynamic class cast.  For the
approach that you have suggested to work, the user of this function f
would need to explicitly wrap up any showable values in a "Showable"
before calling f.  This is a leaky abstraction: in general the caller
may need to know a lot about the implementation of f in order to call
it properly.  So it would be nice to have a way of doing dynamic class
cast, rather than just dynamic type cast.

However, there are some theoretical difficulties with dynamic type
class cast.  In particular, it has some nasty interactions with dynamic
loading.  If you dynamically load a new module which has some new instance
declarations, then it may affect the results of dynamic type class casts.

-- 
Fergus Henderson <[EMAIL PROTECTED]>  |  "I have always known that the pursuit
The University of Melbourne |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  | -- the last words of T. S. Garp.
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: incompatible signatur syntax within instance definition

2003-12-07 Thread Fergus Henderson
On 05-Dec-2003, Christian Maeder <[EMAIL PROTECTED]> wrote:
> >instance Show a => Show (List a) where
> >showsPrec _  Nil = showString "[]"
> >showsPrec _ l =
> >showString "[" . showsl l . showString "]"
> >where -- showsl :: List a -> ShowS-- for ghc
> >  -- showsl :: Show a => List a -> ShowS  -- for hugs

I think the issue here is that in ghc (with -fglasgow-exts),
the "a" here refers to the same type variable "a" in the
top of the instance declaration, which has already been
constained, and cannot be constrained again.
With Haskell 98, it is a fresh type variable, for
which the constraint is necessary.

Try renaming the type variable as "b" in the inner declaration:
the following should work both with and without -fglasgow-exts.

  showsl :: Show b => List b -> ShowS

-- 
Fergus Henderson <[EMAIL PROTECTED]>  |  "I have always known that the pursuit
The University of Melbourne |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  | -- the last words of T. S. Garp.
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: Arbitrary precision reals?

2003-03-25 Thread Fergus Henderson
On 25-Mar-2003, Tom Pledger <[EMAIL PROTECTED]> wrote:
> 
> The floating point part of the GNU mp library looks difficult to fit
> into Haskell's numeric classes, because the type signatures in class
> Floating don't include a how-much-precision-do-you-want parameter.

How about using a function type which takes a precision and gives
you back an answer to that many digits, and making this function
type an instance of the numeric type classes?

E.g.

data MPF_T  -- abstract, corresponds to GNU mp's mpf_t
type PRECISION = Int
type ARBITRARY_PRECISION_REAL = (PRECISION -> MPF_T)

instance Floating ARBITRARY_PRECISION_REAL where
sqrt x = (\prec -> mpf_sqrt_ui (x (prec + sqrt_lossage)))
   where sqrt_lossage = 1  -- amount of precision lost by sqrt
...

Here mpf_sqrt_ui would be an interface to GMP's mpf_sqrt_ui() function,
which takes as input an mpf_t and a precision and produces an mpf_t as output.

-- 
Fergus Henderson <[EMAIL PROTECTED]>  |  "I have always known that the pursuit
The University of Melbourne |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  | -- the last words of T. S. Garp.
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: simulating dynamic dispatch

2003-03-20 Thread Fergus Henderson
On 20-Mar-2003, Hal Daume III <[EMAIL PROTECTED]> wrote:
> i'm hoping to be able to simulate a sort of dynamic dispatch based on
> class instances.  basically a function which takes a value and depending
> on what classes it is an instance of, does something.

I call this feature "dynamic type class casts".

But there are some difficulties in defining the semantics of this.
What should it mean in the presence of dynamic loading?
If you're allowed to dynamically load new modules that might contain
new instance declarations, and you're allowed to check (in a
non-IO-monad context) whether a type is an instance of a type class,
and you want things to remain referentially transparent, then you've
got a problem.

> i tried something like:
> 
> class FooBar a where 
> wasFoo :: a -> Maybe FB  -- will be MkFoo
> wasBar :: a -> Maybe FB  -- will be MkBar
> wasFoo _ = Nothing
> wasBar _ = Nothing
> 
> instance Foo a => FooBar a where
> wasFoo a = Just (MkFoo a)
> 
> instance Bar a => FooBar a where
> wasBar a = Just (MkBar a)
> 
> but this complains about duplicate instance declarations (for obvious
> reasons).

You can use instance declarations for whichever ground types you need, e.g.

instance FooBar Int where ...
instance FooBar String where ...

-- 
Fergus Henderson <[EMAIL PROTECTED]>  |  "I have always known that the pursuit
The University of Melbourne |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  | -- the last words of T. S. Garp.
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: data vs. newtype, abstractly

2003-03-18 Thread Fergus Henderson
On 09-Mar-2003, Hal Daume III <[EMAIL PROTECTED]> wrote:
> well, yes, but if you export:
> 
> mkN :: Int -> N
> mkD :: Int -> D
> 
> or something like that, then they'll still bea ble to tell the difference,
> right?

Not necessarily.  For example mkD could be defined as

mkD x = x `seq` D x

in which case I think it would behave exactly the same as mkN.

-- 
Fergus Henderson <[EMAIL PROTECTED]>  |  "I have always known that the pursuit
The University of Melbourne |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  | -- the last words of T. S. Garp.
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: seeking ideas for short lecture on type classes

2003-01-27 Thread Fergus Henderson
On 26-Jan-2003, Norman Ramsey <[EMAIL PROTECTED]> wrote:
>  > > In a fit of madness, I have agreed to deliver a 50-minute lecture
>  > > on type classes to an audience of undergraduate students.  These
>  > > students will have seen some simple typing rules for F2 and will
>  > > have some exposure to Hindley-Milner type inference in the context
>  > > of ML.
>  > 
>  > Will they have had exposure to more "traditional" OO programming?  If
>  > so, it might be useful to note the difference between Haskell type
>  > classes and C++/Java/whatever classes, namely that Haskell decouples
>  > types and the interfaces that they support.  The advantage is that you
>  > can extend a type with a new interface at any point, not just when you
>  > define the type.
> 
> Hmm --- you are talking about the `instance' declarations, right?

Yes -- the fact that Haskell has separate instance declarations,
as opposed to making this information part of the `data' declaration.
In most OO languages inheritence relations need to be specified in the
type definition.

-- 
Fergus Henderson <[EMAIL PROTECTED]>  |  "I have always known that the pursuit
The University of Melbourne |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  | -- the last words of T. S. Garp.
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell



Re: seeking ideas for short lecture on type classes

2003-01-27 Thread Fergus Henderson
On 24-Jan-2003, Norman Ramsey <[EMAIL PROTECTED]> wrote:
> In a fit of madness, I have agreed to deliver a 50-minute lecture
> on type classes to an audience of undergraduate students.  These
> students will have seen some simple typing rules for F2 and will
> have some exposure to Hindley-Milner type inference in the context
> of ML.  I am soliciting advice about
>   * Cool examples of type classes
>   * Papers I could read to explain how to implement type classes,
> especially if I could show the `dictionary translation' which
> is then followed by ordinary Hindley-Milner type inference
>   * Any other material on which I might base such a lecture

I quite like the idea of treating of type checking/inference as constraint
solving: ordinary Hindley-Milner style type inference involves
solving type unification constraints, and with type classes
you just generalize this to first-order predicate calculus
(type classes are predicates on types, and instance declarations
are clauses).

@InProceedings{demoen_et_al,
author =   {B. Demoen and M. {Garc\'{\i}a de la Banda} and
P.J. Stuckey},
title ={Type Constraint Solving for
Parametric and Ad-Hoc Polymorphism},
booktitle ={Proceedings of the 22nd
Australian Computer Science Conference},
pages ={217--228},
month =jan,
year = {1999},
location = {Auckland},
publisher ={Springer-Verlag},
isbn = {981-4021-54-7},
editor =   {J. Edwards},
}       

-- 
Fergus Henderson <[EMAIL PROTECTED]>  |  "I have always known that the pursuit
The University of Melbourne |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  | -- the last words of T. S. Garp.
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell



Re: seeking ideas for short lecture on type classes

2003-01-27 Thread Fergus Henderson
On 26-Jan-2003, Dean Herington <[EMAIL PROTECTED]> wrote:
> On Sun, 26 Jan 2003, Norman Ramsey wrote:
> 
> > A fact that I know but don't understand the implication of is that
> > Haskell dispatches on the static type of a value, whereas OO languages
> > dispatch on the dynamic type of a value.  But I suspect I'll leave
> > that out :-)
> 
> Perhaps I misunderstand, but I would suggest that "fact" is, if not 
> incorrect, at least oversimplified.

I agree.  The above characterization is highly misleading.  It would be
more accurate and informative to say that both Haskell and OO languages
dispatch on the dynamic type of a value.

-- 
Fergus Henderson <[EMAIL PROTECTED]>  |  "I have always known that the pursuit
The University of Melbourne |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  | -- the last words of T. S. Garp.
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell



Re: seeking ideas for short lecture on type classes

2003-01-27 Thread Fergus Henderson
On 26-Jan-2003, John H?rnkvist <[EMAIL PROTECTED]> wrote:
> 
> On Saturday, January 25, 2003, at 04:14 AM, Andrew J Bromage wrote:
> 
> >G'day all.
> >
> >On Fri, Jan 24, 2003 at 06:13:29PM -0500, Norman Ramsey wrote:
> >
> >>In a fit of madness, I have agreed to deliver a 50-minute lecture
> >>on type classes to an audience of undergraduate students.  These
> >>students will have seen some simple typing rules for F2 and will
> >>have some exposure to Hindley-Milner type inference in the context
> >>of ML.
> >
> >Will they have had exposure to more "traditional" OO programming?  If
> >so, it might be useful to note the difference between Haskell type
> >classes and C++/Java/whatever classes, namely that Haskell decouples
> >types and the interfaces that they support.  The advantage is that you
> >can extend a type with a new interface at any point, not just when you
> >define the type.
> 
> While Java and C++ don't support it other object oriented languages do.

Some others do, some others don't.  And in fact it seems that most
mainstream OOP languages don't.  For example C#, Eiffel and Ada-95 don't,
if I recall correctly.  Sather does support it, but Sather is hardly
mainstream (the language is just about dead these days). 
GNU C++ used to support it, with the "signature" extension,
but doesn't anymore (support for that extension was dropped).
Of the vaguely mainstream OOP languages, I think only the dynamically-typed
ones support it.

-- 
Fergus Henderson <[EMAIL PROTECTED]>  |  "I have always known that the pursuit
The University of Melbourne |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  | -- the last words of T. S. Garp.
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell



Re: dynamic types

2003-01-14 Thread Fergus Henderson
On 08-Jan-2003, Andrew J Bromage <[EMAIL PROTECTED]> wrote:
> On Wed, Jan 08, 2003 at 08:42:20AM +1100, Thomas Conway wrote:
> 
> > Mercury has a type "univ" which might be declared something like:
> 
>   data Univ = forall a. Univ a
> 
> > I believe (nth hand) that something similar has been done in haskell, but
> > my understanding is that it isn't in the standard library.
> 
> That would be Data.Dynamic:
> 
>   data Dynamic-- abstract
>   toDyn :: (Typeable a) => a -> Dynamic
>   fromDynamic :: (Typeable a) => Dynamic -> Maybe a
...
> The Typeable class basically implements RTTI explicitly:
> 
>   class Typeable a where
> typeOf :: a -> TypeRep
> 
> Unfortunately, Typeable can't be derived automatically.

That's not the only problem.  The other problem is that because
`Typeable' instances aren't built-in, `fromDynamic' is not type-safe.
The implementation of `fromDynamic' calls `typeOf' and then if the types
match, it does an unsafe cast.  If `typeOf' lies, then `fromDynamic' may
break type safety.  So it is not safe to allow the use of `fromDynamic'
if you are executing untrusted code.

> Maybe in Haskell 2.

Yes, it would be nice to have a built-in, type-safe, version of Dynamic
in Haskell 2.

-- 
Fergus Henderson <[EMAIL PROTECTED]>  |  "I have always known that the pursuit
The University of Melbourne |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  | -- the last words of T. S. Garp.
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell



Re: diff in Haskell: clarification

2002-11-21 Thread Fergus Henderson
On 21-Nov-2002, George Russell <[EMAIL PROTECTED]> wrote:
> There is an algorithm known as Myer's algorithm, but obviously I want
> it in Haskell rather than C, and it would be nice if someone else had
> written it so I don't have to.

Would a Mercury version help?  The Mercury distribution includes a
Mercury version of Myer's algorithm: it's in the directory `samples/diff'.

You might find it easier to translate from Mercury to Haskell than from
C to Haskell.  (Then again, you might not ;-)

-- 
Fergus Henderson <[EMAIL PROTECTED]>  |  "I have always known that the pursuit
The University of Melbourne |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  | -- the last words of T. S. Garp.
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell



Re: UTF-8 library

2002-08-09 Thread Fergus Henderson

On 06-Aug-2002, George Russell <[EMAIL PROTECTED]> wrote:
> 
> Converting CStrings to [Word8] is probably a bad idea anyway, since there is
> absolutely no reason to assume a C character will be only 8 bits long, and
> under some implementations it isn't. 

That's true in general; the C standard only guarantees that a C character
will be at least 8 bits long.

But Posix now guarantees that C's `char' is exactly 8 bits.

Posix hasn't taken over the world yet, and doesn't look like doing so
in the near future.  So Haskell should not limit itself to being only
implementable on Posix systems.  However, systems which don't have 8-bit
bytes are getting very very rare nowadays -- it might well be reasonable
for Haskell, like Posix, to limit itself to only being implementable
on systems where C's `char' is exactly 8 bits.

-- 
Fergus Henderson <[EMAIL PROTECTED]>  |  "I have always known that the pursuit
The University of Melbourne |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  | -- the last words of T. S. Garp.
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell



Re: Storable tuples and what is 'alignment'?

2002-08-09 Thread Fergus Henderson

On 06-Aug-2002, Alastair Reid <[EMAIL PROTECTED]> wrote:
> 
> Andrew J Bromage <[EMAIL PROTECTED]> writes:
> > This number is called the "alignment", and a good rule of thumb for
> > computing it is:
> 
> >  instance Storable a where alignment a = sizeOf a `min` machine_word_size
> 
> The way we calculate it in GHC and Hugs is:
> 
>   #define offsetof(ty,field) ((size_t)((char *)&((ty *)0)->field - (char *)(ty *)0))

You shouldn't define offsetof() yourself.  The C standard provides
offsetof() in  -- you should use that rather than defining
it yourself.  Defining offsetof() yourself is an error if 
is included, because you are stepping on the implementation's namespace.
Furthermore, the definition there is not standard-conforming C code,
since it dereferences a null pointer.

-- 
Fergus Henderson <[EMAIL PROTECTED]>  |  "I have always known that the pursuit
The University of Melbourne |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  | -- the last words of T. S. Garp.
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell



Re: can't write instance Storable

2002-08-01 Thread Fergus Henderson

On 01-Aug-2002, Hal Daume III <[EMAIL PROTECTED]> wrote:
> Okay, I'm dumb and can't figure this out.  I'm migrating hMPI from GHC
> 4.08 to GHC 5.04 (fun fun) and am having trouble writing an instance of
> Storable.  The relevant information is:
> 
> > import Foreign.Storable
> > type MPI_Rank_Type = Int
> > newtype MPI_Rank = MPI_Rank MPI_Rank_Type deriving (Eq)
> > 
> > instance Storable MPI_Rank where
> > sizeOf(MPI_Rank r) = sizeOf r
> > alignment (MPI_Rank r) = alignment r
> > peek addr = do r <- peek addr
> >  return (MPI_Rank r)
> > poke addr (MPI_Rank r) = poke addr r
> 
> which doesn't work [...]
> I have no idea what's wrong.  if i make it "...do (r :: Int) <- ..." it
> complains: [...]
> it's like it doesn't realize that "peek" is part of the class and can be
> overloaded.

The argument type for `peek' has changed from `Addr' (or something like that)
to a parameterized type `Ptr a'.  So the problem is essentially that
your `peek' method takes a parameter of type `Ptr MPI_Rank',
but needs to call `peek' with a parameter of type `Ptr MPI_Rank_Type'.
You need to use `castPtr' to convert between the two pointer types.
I think the following (untested) code should do it:

 peek addr = do r <- peek (castPtr addr)
return (MPI_Rank r)

Likewise for `poke'.

-- 
Fergus Henderson <[EMAIL PROTECTED]>  |  "I have always known that the pursuit
The University of Melbourne |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  | -- the last words of T. S. Garp.
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell



Re: [Fwd: F#]

2002-05-31 Thread Fergus Henderson

On 31-May-2002, Simon Peyton-Jones <[EMAIL PROTECTED]> wrote:
> 
> General remarks about targetting .NET from GHC.
> 
> * There is no reason in principle why one can't write a back end
> for GHC to generate .NET IL.   
>
> * Generating *verifiable* IL is noticeably harder: you have to 
> take much more care; to deal with parametric polymorphism you
> need Generic IL, which isn't "out" yet;

You don't _need_ Generic IL.  You can deal with parametric polymorphism
by translating polymorphic types to "System.Object".

> and even then, higher kinded type variables are a serious problem.

I think System.Object helps here too.

> Being verifiable almost 
> certainly requires some runtime checked type casts, which hurt
> performance -- and reducing them to a minimum complicates the
> compiler.

It's certainly true that being verifiable is likely to cost some
performance.  But I don't think it would be difficult to implement.

For the Mercury compiler's .Net back-end, there's a --verifiable
option which controls whether the generated IL code is verifiable or not.

-- 
Fergus Henderson <[EMAIL PROTECTED]>  |  "I have always known that the pursuit
The University of Melbourne |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  | -- the last words of T. S. Garp.
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell



Re: uniqueness typing

2002-03-15 Thread Fergus Henderson

On 12-Mar-2002, Dana Harrington <[EMAIL PROTECTED]> wrote:
> 
> I believe Mercury borrowed their uniqueness type (mode) system from 
> Clean.

Nope.  The support for unique modes in Mercury was developed before
we were aware of Clean.  They achieve similar aims, but it's a case
of convergent evolution, because we were both trying to solve the same
problem, rather than borrowing.  (This is in contrast to e.g. Mercury's
support for type classes, which was pretty much directly lifted from
Haskell.)

In fact Clean's support for uniqueness is better than Mercury's.
In particular, Clean supports uniqueness polymorphism,
whereas Mercury only supports overloading on uniqueness.

-- 
Fergus Henderson <[EMAIL PROTECTED]>  |  "I have always known that the pursuit
The University of Melbourne |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  | -- the last words of T. S. Garp.
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell



Re: Another H'98 Report query

2002-01-31 Thread Fergus Henderson

On 31-Jan-2002, Malcolm Wallace <[EMAIL PROTECTED]> wrote:
> The subordinate names c_i (f_i) must not contain duplicates.
> 
> Yet later in the text it is stated that
> 
> Exports lists are cumulative: the set of entities exported by an
> export list is the union of the entities exported by the individual
> items of the list.
> 
> I see no reason to disallow duplicates at the subordinate level if
> they are permitted otherwise.

Well, disallowing duplicates here may improve error detection,
catching some unintentional typos and cut-and-paste errors.

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

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



Re: if-then-else inside a "do"

2002-01-29 Thread Fergus Henderson

On 29-Jan-2002, Andre W B Furtado <[EMAIL PROTECTED]> wrote:
> In the following code, will "other things" be executed or the "return ()"
> will end function f? I guess the answer is yes ("other things" WILL be
> executed anyway), but I'd like to understand why won't the "return ()" be
> the [state change/result produced] created by f.
> 
> f :: IO ()
> f = do
> -- lots of things
> if False then doSomething else (return ())
> -- other things

The "if" here is actually irrelevant to the question.
The same issue arises for the following function:

g :: IO ()
g = do
return ()
-- other things

Unlike in C, "return" does not terminate execution of the enclosing
function.  Rather, "return ()" is a just a computation of type IO ()
which has no effect and which returns the value "()".  By "returning"
here I mean returning from that computation, not returning from the
enclosing function.

When you have two actions in sequence in a "do" like this,

do
action1
action2

the meaning of the `do' expression is an action whose effect is to
execute the first action (action1), throw away the return value,
and then execute the second action (action2), and whose return
value is the return value form the section action.
So
do
return ()
action2

is an action whose effect is to first do nothing, throwing away the return
value "()", and then do action2 -- in other words this do expresion as
a whole is exactly equivalent to action2.

Compare this example with one where you don't throw away the return value:

h :: IO ()
h = do
x <- return ()
    -- other things

This example is the same as

h :: IO ()
h = do
let x = ()
-- other things

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

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



Re: type specs not making it in to functions

2002-01-28 Thread Fergus Henderson

On 25-Jan-2002, Hal Daume III <[EMAIL PROTECTED]> wrote:
> consider the following definition:
> 
> > class C a where foo :: a -> Int
> > instance C Bool where foo _ = 5
> 
> I can then say:
> 
> > bar :: C a => a -> Int
> > bar (x :: a) = foo (undefined :: a)
> 
> But not:
> 
> > bar :: C a => a -> Int
> > bar x = foo (undefined :: a)
> 
> because it tries to use a new scope for the type variable a and doesn't
> unify it with the one in the type spec.  Why not?

I don't know why it isn't the case in Haskell.
In Mercury we do allow type variables in function type declarations
to scope over explicit type qualifications in clause bodies.

One drawback with allowing this is that the type declaration may be
separated from the clause by an arbitrary amount of text,
e.g.
bar :: C a => a -> Int  -- type var `a' introduced here...
foo :: Int
quux :: String

foo = 42
quux = "hello world"
bar x = foo (undefined :: a)-- ... and used here.

which means that this feature can be used in ways that have the
potential to make programs harder to read.

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

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



Re: varying number of arguments restriction

2001-10-31 Thread Fergus Henderson

On 30-Oct-2001, Hal Daume <[EMAIL PROTECTED]> wrote:
> I'm curious why the following code is invalid (from a language design
> point of view):
> 
> > foo :: [(Int, String)] -> String
> > foo [] = ""
> > foo = snd . head
> 
> ghc complains:
> 
> Varying number of arguments for function `foo'
> 
> I don't understand why this should be invalid?

While it would be possible to define a semantics for such code,
I suspect that this sort of thing commonly arises as a result
of accidental errors in Haskell programs.

Allowing such programs would therefore (a) let some unintended errors
slip past the compiler and (b) result in much more obscure error messages
(from the type checker) for some other unintended errors.

Since it's easy for the user to write function definitions so that all
clauses have the same number of arguments, and since requiring this helps
the compiler give better error messages and/or catch errors earlier,
I think it makes good sense to do so.

-- 
Fergus Henderson <[EMAIL PROTECTED]>  | "... it seems to me that 15 years of
The University of Melbourne | email is plenty for one lifetime."
WWW: <http://www.cs.mu.oz.au/~fjh>  | -- Prof. Donald E. Knuth

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



Re: Haskell 98 - Standard Prelude - Floating Class

2001-10-15 Thread Fergus Henderson

On 15-Oct-2001, Simon Peyton-Jones <[EMAIL PROTECTED]> wrote:
> 
> The proposal is only to give "default declarations"
> in the class defn for sinh, cosh, and perhaps as Lennart suggests
> asinh, acosh, atanh. They give a reasonable first cut if you
> don't write definitions yourself.  But you can overrride them at will.
> The only reason not to do this (which amounts to giving a default
> decl of "error") is if the default decl is so awful that it's badly
> misleading to provide it.  Which doesn't look true in this case.

Not giving a default definition is *not* the same as giving a default
definition that calls "error".  It's significantly safer.  The difference
is that the former makes it much easier for compilers to issue warnings
when you forget to define a class method in an instance declaration.
With the latter, compilers can't issue such warnings without getting
too many false positives.

The whole idea of letting you omit method definitions for methods with
no default and having calls to such methods be run-time errors is IMHO
exceedingly odd in a supposedly strongly typed language, and IMHO ought
to be reconsidered in the next major revision of Haskell.

-- 
Fergus Henderson <[EMAIL PROTECTED]>  | "... it seems to me that 15 years of
The University of Melbourne | email is plenty for one lifetime."
WWW: <http://www.cs.mu.oz.au/~fjh>  | -- Prof. Donald E. Knuth

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



Re: macros. Was: Arrow notation, etc.

2001-10-14 Thread Fergus Henderson

On 12-Oct-2001, Jerzy Karczmarczuk <[EMAIL PROTECTED]> wrote:
> 
> They [macros] are heavily used in Clean, so, there *are* people
> who see a need for them in a lazy language.

Well, that depends on what you mean by "macros".  Clean's "macros"
have essentially the same semantics as inline functions, don't they?
If I understand correctly, the denotation semantics of Clean's macros
is exactly the same as ordinary functions, the only difference is that
operationally they are guaranteed to be inlined.

So, unless I'm missing something, they are just an efficiency hack,
and one which is already looking somewhat dated -- a bit like the
"register" keyword in C.

This is quite different to the kind of macros that would
allow you to extend the language syntax to support things
like arrow notation or views.

-- 
Fergus Henderson <[EMAIL PROTECTED]>  | "... it seems to me that 15 years of
The University of Melbourne | email is plenty for one lifetime."
WWW: <http://www.cs.mu.oz.au/~fjh>  | -- Prof. Donald E. Knuth

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



Re: Namespaces (was Re: GUI Library Task Force)

2001-10-11 Thread Fergus Henderson

On 10-Oct-2001, Hal Daume III <[EMAIL PROTECTED]> wrote:
> So, barring this, I'm curious how other people handle this issue.
> 
> I have multiple projects.  Call them A, B, C.  They are in directories:
>   ~/projects/A
>   ~/projects/B
>   ~/projects/C
> repsectively.
> 
> Say I'm creating a new project, D, in ~/projects/D that uses code that
> I've written in packages A, B and C.  Now, as far as I can see, I have
> two options:
> 
>  1) Copy all the .(l)hs files from /A, /B, and /C to /D that I need to
> import
>  2) Include projects/A, projects/B and projects/C in my search path for
> ghc(i)
> 
> I hate both of these options.  1 is terrible because I have multiple
> copies of the same code lying around and, if I make changes to one, I
> have to remember to copy the changes over to the others.  2 is a big
> nuisance, especially since ghc (seems to) lack an environment variable
> that it looks at to get command line options every time it runs
> (HUGSFLAGS, I think it was for Hugs).

Well, I wouldn't be invoking ghc manually anyway; I'd put the commands
to invoke ghc in a script or, more likely, in a Makefile.

-- 
Fergus Henderson <[EMAIL PROTECTED]>  | "... it seems to me that 15 years of
The University of Melbourne | email is plenty for one lifetime."
WWW: <http://www.cs.mu.oz.au/~fjh>  | -- Prof. Donald E. Knuth

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



Re: Application letters at the Haskell workshop: suggestion

2001-09-25 Thread Fergus Henderson

On 15-Sep-2001, Mark Carroll <[EMAIL PROTECTED]> wrote:
> On 14 Sep 2001, Mike Gunter wrote:
> 
> > The problem is not a loss of referential transparency but the
> > requirement that evaluation order must be specified.  E.g.
> > what should
> > 
> > raise "left" + raise "right"
> > 
> > return? 
> (snip)
> 
> Ah! Yes, I see what you mean - this explains what Andy Moran was thinking,
> probably. (-: Moreover, if we have a pseudo-Haskell code snippet like,
> 
>try
>  f (a 1) (b 2)
>catch
>  error-1 -> 1
>  error-2 -> 2
>where
>  a _ = raise error-1
>  b _ = raise error-2
> 
> ... then is the return value of this 1 or 2? AFAICS a simple way to get
> out of this is to only have one exception type that carries no information
> instead of different ones so we can't distinguish one exception from
> another, but that's obviously not great.

Unfortunately even that doesn't work, because there are still problems with
non-termination.  Consider the following example:

try
  f (a 1) (b 2)
catch
  error-1 -> 1
where
  a _ = raise error-1
  b n = b n

Should this program return 1, or loop?

Giving this program deterministic behaviour requires specifying the order of
evaluation.

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

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



Re: type classes and generality

2001-07-09 Thread Fergus Henderson

On 09-Jul-2001, Alexander V. Voinov <[EMAIL PROTECTED]> wrote:
> Hi All,
> 
> Fergus Henderson wrote:
> > Ah, now I think I understand your problem.  You want to `random' to
> > generate random numbers that span all the possible values of the type
> > within the range [0, 1], or at least a substantial subset, but the "Real"
> > class doesn't let you generate any numbers other than integers.
> > The above approach will give you random numbers from `random', but they
> > will only ever be 0 or 1, so maybe they are not as random as you needed! ;-)
> 
> Each pseudorandom generator generates a countable sequence of values,
> which is isomorphic to a sequence of integers. In good old (Turbo)C we
> got something between 0 and MAXINT and then divided by (double)MAXINT.
> Can't _this_ be done in Haskell?

Sure, it can be done, but not on a value whose type is constrained only by
the "Real" class, because the "Real" class doesn't have any division operator!

Haskell's "/" operator is a member of the "Floating" class, and "Floating"
is not a base class of "Real".  It is a base class of the "RealFrac"
class, so you could use that approach for "RealFrac"... but the original
poster was asking for the solution to a more difficult problem.

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

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



Re: type classes and generality

2001-07-09 Thread Fergus Henderson

On 09-Jul-2001, Norman Ramsey <[EMAIL PROTECTED]> wrote:
>  > On 09-Jul-2001, Norman Ramsey <[EMAIL PROTECTED]> wrote:
>  > > I'm trying to model probability and leave the
>  > > representation of probability unspecified other than
>  > > it must be class Real.  But I'm having trouble with
>  > > random numbers; how can I show that if a type has class Real,
>  > > it also has class Random.Random?  Is there a way to accomplish
>  > > this goal other than by changing the library?
>  > 
>  > I'm not sure if I fully understand your goal.
>  > But one thing you can do is to define a wrapper type
>  > 
>  >newtype WrapReal r = WrapReal r
>  > 
>  > and make the wrapper an instance of Random.Random
>  > if the underlying type is an instance of Real
>  > 
>  >instance Real r => Random.Random (WrapReal r) where
>  >...
>  > 
>  > Then you can use the wrapper type whenever you want to get a random number.
> 
> The problem is that without intensional type analysis, I wouldn't know
> how to fill in the instance methods in the `...'

How about like so?

import Random

newtype WrapReal r = WrapReal r
wrap r = WrapReal r
unwrap (WrapReal r) = r

instance Real r => Random (WrapReal r) where
random = randomR (wrap 0, wrap 1)
randomR (min, max) gen0 = (wrap (fromInteger r), gen) where
(r, gen) = randomR (imin, imax) gen0
imin = ceiling (toRational (unwrap min))
imax = floor (toRational (unwrap max))

Ah, now I think I understand your problem.  You want to `random' to
generate random numbers that span all the possible values of the type
within the range [0, 1], or at least a substantial subset, but the "Real"
class doesn't let you generate any numbers other than integers.
The above approach will give you random numbers from `random', but they
will only ever be 0 or 1, so maybe they are not as random as you needed! ;-)

The proof that you can only generate integers values of the real type
(by which I mean values of the real type for which toRational returns
an integer) is that the only methods of class Real which return values
of the type are "fromInteger", and the operators ("+", "*", "-",
"negate", "abs", and "signum"), which are all integer-preserving --
when given integers they will always return other integers.
So by induction you can't generate any non-integers.

I'd advise you to  add an extra "Random t" class constraint to those
parts of your application that rely on generating random numbers.
If you find yourself using `Real t, Random t' frequently, you can
use a derived class for that:

class (Random t, Real t) => RandomReal a where
-- no methods

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

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



Re: type classes and generality

2001-07-09 Thread Fergus Henderson

On 09-Jul-2001, Norman Ramsey <[EMAIL PROTECTED]> wrote:
> I'm trying to model probability and leave the
> representation of probability unspecified other than
> it must be class Real.  But I'm having trouble with
> random numbers; how can I show that if a type has class Real,
> it also has class Random.Random?  Is there a way to accomplish
> this goal other than by changing the library?

I'm not sure if I fully understand your goal.
But one thing you can do is to define a wrapper type

newtype WrapReal r = WrapReal r

and make the wrapper an instance of Random.Random
if the underlying type is an instance of Real

instance Real r => Random.Random (WrapReal r) where
...

Then you can use the wrapper type whenever you want to get a random number.

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

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



Re: Haskell 98 Report

2001-05-31 Thread Fergus Henderson

On 31-May-2001, C.Reinke <[EMAIL PROTECTED]> wrote:
> 
>  "..it's easy enough for programmers who want a generalized version to just cut
>and paste the code from the Haskell report and give it a more general type
>  signature,.." 
> 
>   Fergus Henderson, June 2001
> 
> Is this definition of reuse in Haskell quotable?-)

Sure, feel free to go ahead and quote it (you just did already ;-).

But it's taken a little out of context.
Certainly I wouldn't recommend that as a method of code reuse
in ordinary cases, let alone posit it as a _definition_ of reuse.

However, in this particular case, where the algorithm is fairly trivial,
and the code is well tested, the costs of cut-and-paste reuse are not
high, and specifically the downside of that approach is comparable
to the downside of the other approach, namely the need to diagnose
and fix type errors in programs like the one I posted.
So we need to consider the likely frequency of these scenarios,
and the benefits/costs of keeping the Haskell 98 standard as stable
as possible or making minor changes like this that could also cause
problems when converting between one "Haskell 98, 2002 revision"
compiler and another "classic Haskell 98" implementation.

It's all about trade-offs.

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

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



Re: Haskell 98 Report

2001-05-31 Thread Fergus Henderson

On 31-May-2001, Simon Peyton-Jones <[EMAIL PROTECTED]> wrote:
> We should either generalise all three
>   deleteBy
>   deleteFirstsBy
>   intersectBy
> or none.
> 
> In favour:
>   the more general types are occasionally useful
>   no programs stop working

Actually some programs will stop working, because the types will be
underconstrained, so the compiler won't know how to satisfy some type class
constraint.

For example:

import List
main = print (deleteBy (\x _y -> x > 0) 1 [])

With the generalized type, you'd get an unresolved `Show' constraint.

The number of real programs for which this is a problem is most likely very
small, and the work-around (typically just adding an explicit type
qualification) is not hard once you understand what the problem is, but
figuring out what the problem is could take some time.

Since it does break some obscure programs, and since it's easy enough
for programmers who want a generalized version to just cut and paste
the code from the Haskell report and give it a more general type signature,
my preference would be to leave this out of Haskell 98, but include it
in the next version of Haskell. 

(It would be good for someone, perhaps Simon P-J., to keep a list of
issues like this which have been left out of Haskell 98 due to backwards
compatibility concerns, so that they don't get forgotten about when it
comes to time for the next version.)

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

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



Re: Unicode

2001-05-25 Thread Fergus Henderson

On 24-May-2001, Marcin 'Qrczak' Kowalczyk <[EMAIL PROTECTED]> wrote:
> Thu, 24 May 2001 14:41:21 -0700, Ashley Yakeley <[EMAIL PROTECTED]> pisze:
> 
> >>   - Initial Unicode support - the Char type is now 31 bits.
> > 
> > It might be appropriate to have two types for Unicode, a UCS2 type
> > (16 bits) and a UCS4 type (31 bits).
> 
> Actually it's 20.087462841250343 bits. Unicode 3.1 extends to U+10,
> ISO-10646-1 is said to shrink to U+10 in future, so maxBound::Char
> is '\x10' now.
> 
> Among encodings of Unicode in a stream of bytes there are UTF-8,
> UTF-16 and UTF-32 (with endianness variants). AFAIK terms UCS2 and
> UCS4 are obsolete: there is a single code space 0..0x10 and
> various ways to serialize characters.
> 
> Ghc is going to support conversion between internal Unicode and
> some encodings for external byte streams. Among them there will be
> UTF-{8,16,32} (with endianness variants), all treated as streams
> of bytes.
> 
> There is no point in storing characters in UTF-16 internally.
> Especially in ghc where characters are boxed objects, and Word16 is
> represented as a full machine word (32 or 64 bits). UTF-16 will be
> supported as an external encoding, parallel to ISO-8859-x etc.

What about for interfacing with Win32, MacOS X, or Java?
Your talk about "external" versus "internal" worries me a bit,
since the distinction between these is not always clear.
Is there a way to convert a Haskell String into a UTF-16
encoded byte stream without writing to a file and then
reading the file back in?

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

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



Re: Templates in FPL?

2001-05-23 Thread Fergus Henderson

On 22-May-2001, Carl R. Witty <[EMAIL PROTECTED]> wrote:
> 
> I agree with Marcin about the bad points of templates.

Me too.  Marcin summed it up very well.
Of the five disadvantages that he mentioned,
I think at least three (lack of explicit interfaces,
incredibly complicated rules about name lookup,
and very poor error messages) are very serious problems.

For an example of the problems caused by the lack of explicit
interfaces, the C++ standards committee has still not
agreed on what the interface to vector is. The standard
is contradictory, because the vector specialization
doesn't obey the rules specified for vector, and as yet
there's no concensus about which should be changed.

For an example of the problems caused by the complicated rules about
name lookup, just today someone posted a bug report for gcc 2.95.* to
[EMAIL PROTECTED], reporting a problem where one of the standard library
templates didn't work when they had a typedef named `destroy' in their
code.  My guess is that it was probably because the standard library code
was using the function std::destroy(), but the standard library
implementor didn't realize that it had to be explicitly namespace
qualified; in other words, the rules were too complex and/or too
cumbersome for the standard library developer to understand and/or apply.

Marcin already posted a good example of a poor error message ;-)

> (I'd like to
> point out, though, that the idea that "adding new code can't change
> the meaning of a program" no longer holds in Haskell extended with
> overlapping type classes.)

Yes... hence overlapping type classes are EVIL! ;-) ;-) ;-)

;-)

> There are some very cool things about C++ templates; they are more
> powerful than you might suspect.
> 
> Basically, templates let you extend the compiler.  You get a primitive
> functional programming language, with which you can do basically
> arbitrary computations on types and on integers;
> In the functional programming language, you have conditionals, the
> usual arithmetic operations, pairing, recursion, etc.; basically, it's
> a real programming language (although a very annoying one -- the
> syntax is atrocious).

Right.  It wasn't designed for that purpose, it just turned out
that it could be used for it.  It's a bit like that simulation of
Conway's game of life in vi macros!  Makes for a very impressive
demo, but there are serious drawbacks to using such techniques in
day-to-day work.

I agree that it would be very nice if Haskell and other FPLs had some
equivalent feature, with a nicer syntax.  I think you might be able to
do a lot of it using ordinary Haskell syntax with just some additional
annotation that directs the compiler to evaluate part of the program at
compile time.

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

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



Re: Integers to Ints

2001-05-16 Thread Fergus Henderson

On 16-May-2001, Steinitz, Dominic J <[EMAIL PROTECTED]> wrote:
> Can someone explain the following behaviour? Or is it a bug in hugs?

It looks to me very much like it is a bug in Hugs.

ghc 4.04 does not suffer from this bug.

It's easy to make mistakes like this, which can often arise from forgetting
the assymetric nature of twos-complement signed integers, which have more
negative numbers than positive numbers.  We once had a similar kind of bug
in the Mercury standard library implementation, where string__to_int was
not handling the most negative integer correctly.  We fixed that one in
March 1998.

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

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



Re: BAL paper available

2001-05-15 Thread Fergus Henderson

On 15-May-2001, Wojciech Moczydlowski, Jr <[EMAIL PROTECTED]> wrote:
> On 15 May 2001, Marcin 'Qrczak' Kowalczyk wrote:
> > What should be improved compared to existing STUArray Int Double
> > and similar?
> 
> A simple standard proposal, not using ST and multiparameter type classes,
> so that it would be possible to implement it in other compilers (namely nhc),
> would be a great improvement for me.

I think multiparameter type classes or other extensions to Haskell 98 are
really needed to solve these kinds of problems in a simple and elegant way.

The right solution, IMHO, is to extend nhc and other Haskell compilers
to support multiparameter type classes, not to try to shoehorn things
that don't fit into Haskell 98.

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

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



Re: CA proposal by D.Thurston

2001-05-14 Thread Fergus Henderson

On 14-May-2001, S.D.Mechveliani <[EMAIL PROTECTED]> wrote:
> I was said that there exists an algebraic library proposal for 
> Haskell (version 0.02) dated by February (2001?), by Dylan Thurston.
> 
> Who could, please, tell me where to download this document from?
> For I could not find it from  http://haskell.org

It was posted to the haskell-cafe list,
and is available from the archives of that list:
<http://haskell.org/pipermail/haskell-cafe/2001-February/000331.html>.

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

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



Re: User defined Ix instances potentially unsafe

2001-05-07 Thread Fergus Henderson

On 07-May-2001, Simon Peyton-Jones <[EMAIL PROTECTED]> wrote:
> In thinking about this I've realised that there's an assumption in 
> the Ix interface that
> 
> (*)   map index (range (l,u)) = [0..rangeSize (l,u)-1]
...
> The constraint (*) also specifies that 'range' returns subscripts
> in increasing order of index.  That seems reasonable, but perhaps
> less important.  One could alternatively say 
> 
> (*a)  index (l,u) l = 0
> (*b)  index (l,u) u = rangeSize (l,u) - 1
> 
> In the spirit of making minimal changes/additions to H98, perhaps (*a)
> and (*b) would be better.

Given that (*a)+(*b) already pin the end-points, I *think* you might as
well go all the way and use (*); I don't *think* the extra flexibility
of (*a)+(*b) would be useful.  Given a type T which satisfies (*a)+(*b)
one can defined a new range function which sorts the elements by index

range' b@(l,u) = sortBy compareIndex range b where
compareIndex x y = compare (index b x) (index b y)

and then after renaming range as e.g. unsortedRange and
range' as range, the type will now satisfy (*).

So for Haskell 200X, (*) would certainly be preferable, IMHO.
For Haskell 98, I'm not sure; perhaps it is best to be conservative.

> PS: none of this answers Matt's original question which I can rephrase
> thus:
> if a user provides implementations of index, range etc that do not obey
> the specified invariants, can that crash the system?  I would rather the
> answer were 'no'.

I think the answer should be "no, unless the user specified the
appropriate compiler option to disable array bounds checking".

> But that means the implementation would have to check the output of
> 'index' against the size of the array allocated from the supplied bounds.
> Which means that in the common case that 'index' also makes such a
> check there'd be two  checks.

If you really want to squeeze the last drops of performance out, then
there's always that compiler option to disable array bounds checking...

> Unless the compiler was clever enough
> to eliminate one of them, which isn't easy since one is at the 'ix'
> type and the other at 'Int'.

One possible way to eliminate them would be to add an extra method called
unchecked_index or __unchecked_index to the Ix class.  By default this
would do the same as index

class Ix t where
...
__unchecked_index = index

but you could define the instances for the standard library types
such as Int, Char, etc. so that they just skip the check and return
an out-of-range Int; for array operations such as (!) where you're
going to do a range check on the value returned from index,
you can safely use __unchecked_index instead.

The reason for using a name such as __unchecked_index rather than just
unchecked_index would be for strict compatibility with Haskell 98: to
avoid clashing with user-defined identifiers, you need to use a name
that is reserved for use by the implementation, Unfortunately, unless I
missed something, Haskell 98 does seem to reserved any identifiers at all
for use by the implementation, other than the standard reserved words,
so I think even using a name like `__unchecked_index' here would not be
100% strictly Haskell 98 compatible.  I think it would be good enough in
practice, though.

For Haskell 200X, where strict backwards compatibility is not required,
unchecked_index should be introduced as a documented new method for the
Ix class.

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

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



Re: polymorphic recursion (was: Re: Implict parameters and monomorphism)

2001-05-06 Thread Fergus Henderson

On 06-May-2001, Bernard James POPE <[EMAIL PROTECTED]> wrote:
> 
> If you applied the Mercury algorithm to Haskell (ie used fixed point iteration
> to search for a type, rather than requiring a type annotation), would 
> the new type inference algorithm accept/reject the same programs as the
> existing Haskell algorithm? (assuming an arbitrary user-defined iteration
> limit, and suitable type annotations for the existing Haskell algorithm).

Yes, I believe so.

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

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



Re: Implict parameters and monomorphism

2001-05-05 Thread Fergus Henderson

On 04-May-2001, Simon Peyton-Jones <[EMAIL PROTECTED]> wrote:
> Lennart Augustsson [mailto:[EMAIL PROTECTED]] wrote:
> | It is not at all surprising that you can write this.  
> | Originally type signatures only allowed you to put a 
> | signature that was more specific.
> | Polymorhic recursion on the other hand allows you to make the 
> | type more general by putting a type signature on a 
> | definition. Combining these you can make the signature be 
> | incomparable to the deduced type.  Using the class system you 
> | can then dispatch on the type and get different behaviour.
>
> Now that is a *really* amazing example.  I had no
> idea that polymorphic recursion would do this.  

Blaming polymorphic recursion is not really fair, IMHO.
In particular, Mercury allows polymorphic recursion,
but does not suffer from this problem, because it's
type inference is capable of inferring the correct most
general types even for examples that use polymorphic recursion.

In contrast, Haskell uses a type inference algorithm
which sometimes infers what I would call wrong answers:
types which are less general that can be obtained with an explicit
type declaration.  These types might not be what the programmer had
intended, and this can affect a program's meaning and result.

The advantage of Haskell's approach is of course that the type
inference process is guaranteed to terminate.  In contrast,
Mercury's type inference process may fail to terminate for
certain ill-typed programs.   The Mercury compiler uses
a user-configurable iteration limit, and rejects programs
for which type inference exceeds this limit.  In practice
this is very very rare.

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

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



Re: Contexts in Existential Types

2001-03-13 Thread Fergus Henderson

On 13-Mar-2001, Ashley Yakeley <[EMAIL PROTECTED]> wrote:
> Would it be appropriate for Haskell to be able to remember contexts in 
> existential types?

I'm not sure exactly what you mean by that.
But your example requires existentially typed functions.
It would certainly be appropriate for Haskell to support
existentially typed functions.

> For instance, currently this does not work in Hugs:
> 
> --
> class Charable a where
>   obtainChar :: a -> Char
> 
> instance Charable Char where
>   obtainChar c = c
> 
> data AnyCharable = forall c. (Charable c) => MkAnyCharable c
> 
> anyA = MkAnyCharable 'a'
> recoverA = obtainChar ((\(MkAnyCharable c) -> c) anyA)
> --

You can write that kind of thing in Mercury.  However, you need to use
a separate function rather than a lambda expression, since for this
to work the lambda expression has to have an existentially quantified
polymorphic type, and in Mercury (as in Haskell 98), lambda expressions
are always monomorphic.

fjh$ cat test.m
:- import_module char.
:- typeclass charable(A) where [
func obtainChar(A) = char
].
:- instance charable(char) where [
obtainChar(C) = C
].
% Note for Haskell readers:
% in Mercury the constructor name goes on the left of the `=>'
% and the type class constraints go on the right of it
:- type anyCharable ---> some [C] mkAnyCharable(C) => charable(C).

anyA = 'new mkAnyCharable'('a').
recoverA = obtainChar(x(anyA)).
x(mkAnyCharable(C)) = C.

fjh$ mmc -C --infer-all test.m
test.m:001: Warning: module should start with a `:- module' declaration.
test.m:  1: Warning: interface for module `test' does not export anything.
test.m:012: Inferred :- func anyA = (test:anyCharable).
test.m:013: Inferred :- func recoverA = character.
test.m:014: Inferred :- some [C] (func x((test:anyCharable)) = C => (test:charab
le(C))).

Note that the type inferred for `x' is an existentially quantified function
type.

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

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



Re: Synonym Type Constructors

2001-02-19 Thread Fergus Henderson

On 19-Feb-2001, Ashley Yakeley <[EMAIL PROTECTED]> wrote:
> I don't know if this is a bug in Hugs 98, or whether it's a 
> misunderstanding of mine.
> 
> The Haskell 98 Report Sec. 4.2.2 claims that 'type' introduces a new type 
> constructor.

Right.  So by definition, it does.

> Yet it doesn't seem possible to declare the type constructor 
> an instance of a class:
...
> Hugs gives:
> (line 6): Not enough arguments for type synonym "T"

That is also correct.

As the Haskell Report section 4.2.2 says:

 | Type constructor symbols T introduced by type synonym declarations
 | cannot be partially applied; it is a static error to use T without the
 | full number of arguments.

> So is T a real type constructor or not?

The Haskell 98 Report does not define the term "real type constructor".
So this is one of those existential philosphical debates about terminology ;-)
Personally I would describe the type constructors introduced by type
synonym declarations as "real", but not "first class".

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

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



Re: Types from values using existential types?

2001-02-11 Thread Fergus Henderson

On 10-Feb-2001, Dylan Thurston <[EMAIL PROTECTED]> wrote:
> I sent the message.  It seems like
> rather a pain to always wrap your existential types inside data
> structures,

Yes, definitely.

> > You might want to  consider trying this with Mercury, since Mercury
> > has both multiparameter type classes and existential types for
> > functions.  (On the other hand, Mercury's restrictions on instance
> > declarations can cause difficulties for the use of multiparameter
> > type classes, so this design might not be workable in Mercury as it
> > currently stands.)
> 
> Great, thanks!  I looked at it a little, and so far it looks like
> quite an elegant type system.  But is it decidable?

The existential types part is decidable.

(Mercury's type system as a whole is not decidable because we allow
inference of polymorphic recursion.  But decidability is not really so
important.  Being able to infer polymorphic recursion is more useful
than decidability.)

> Where can I read
> about it?  (None of the papers on the home page seemed directly
> relevant.)

David Jeffery and I have been working on a paper on this.  Well, to be
fair, David has been working on it; I really haven't done much in the
way of writing for it yet.  But I don't think the current draft is
ready for public consumption at this point.

Of course, we freely distribute the source code for the Mercury
compiler.

> Does it work with type inference, as in Haskell?

Yes.

> > Mercury's "store" module uses existential types in this fashion to
> > ensure that each call to `store__new' is treated as having a different
> > type, to ensure that you don't use a key from one store as an index
> > into a different store.  This is similar to the Hugs/ghc `runST'
> > function, although `runST' uses continuation passing and explicit
> > universal quantification (a.k.a. "first class polymorphism"),
> > rather than existential quantification.  The paper "Lazy functional
> > state threads" by John Launchbury and Simon L Peyton Jones has a
> > description of how `runST' works, IIRC.
> 
> I'll take a look to see if I can use the techniques in 'runST' to hide
> the existential quantification, though I'm initially sceptical.

Well, I'm pretty sure it could be done, but doing it this way is a pain,
because it forces the user of such a routine to restructure their
program using continuation passing.  Existential types are a nicer
approach.

> > I think there might also be some stuff on types for matrices in Chris
> > Okasaki's work.
> 
> I'll look it up.  Should I look in his book?

I must shamefully confess that I haven't read his book, so I don't
know if it is in there.  I just have a vague recollection from
some talk I've heard or paper I've read.

The stuff I'm thinking of didn't involve existential types,
but used types that represented integers (using successor
arithmetic and the like) as type parameters.

Oh, here we are... I just tried an internet search for
"Chris Okasaki matrix matrices type" and altavista pulled up
the following reference, which I'm pretty sure is the one
I was thinking of:

 | International Conference on Functional Programming, September 1999,
 | pages 28-35. (136K postscript)
 | 
 | Abstract:
 | 
 | Square matrices serve as an interesting case study in functional
 | programming. Common representations, such as lists of lists, are both
 | inefficient--at least for access to individual elements--and
 | error-prone, because the compiler cannot enforce ``squareness''.
 | Switching to a typical balanced-tree representation solves the first
 | problem, but not the second. We develop a representation that solves
 | both problems: it offers logarithmic access to each individual element
 | and it captures the shape invariants in the type, where they can be
 | checked by the compiler. One interesting feature of our solution is
 | that it translates the well-known fast exponentiation algorithm to the
 | level of types. Our implementation also provides a stress test for
 | today's advanced type systems--it uses nested types, polymorphic
 | recursion, higher-order kinds, and rank-2 polymorphism.
 |
 | http://www.cs.columbia.edu/~cdo/icfp99.ps

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

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



Re: Types from values using existential types?

2001-02-09 Thread Fergus Henderson
e) --->
square_matrix(int, func(int, int) = ElementType).

:- type dummy ---> dummy.

new_matrix(N, F) = square_matrix(N, F)
`with_type` square_matrix(dummy, ElementType).

I don't think you need the `singleton' function
or the `singetonValue' type class that you mentioned.
As you can see from the example above, it can be done
just using existentially typed functions and the module system.
I don't think there's any need to generalize it.

Sorry for all the Mercury syntax, but none of the existing Haskell
implementations support existentially typed functions.  The
translation into Haskell would be something like this:

module Matrix(SquareMatrix, new_matrix) where

-- An NxN matrix whose elements are of type T;
-- the type TypeForN is a type that
-- represents the natural number N.
data SquareMatrix type_for_n element_type =
SquareMatrix Int (Int -> Int -> element_type)

data Dummy = Dummy

% new_matrix(N, F) returns the NxN matrix whose
% elements are given by the function F
new_matrix :: some type_for_n .
Int -> (Int -> Int -> element_type) ->
SquareMatrix type_for_n element_type
new_matrix n f = SquareMatrix n f :: SquareMatrix Dummy element_type

but this relies a couple of extensions to standard Haskell, at least
one of which is not supported by any existing Haskell implementation.

I think there might also be some stuff on types for matrices in Chris
Okasaki's work.

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

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



Re: Detail: laziness in show

2001-02-09 Thread Fergus Henderson

On 09-Feb-2001, Patrik Jansson <[EMAIL PROTECTED]> wrote:
> I just uncountered an interesting example of (hidden) laziness - here is
> a very short session with hugs (February 2000):
> 
> Prelude> undefined :: String
> "
> Program error: {undefined}
> 
> Note the starting double quote on the line before the error! In a more
> complicated context this puzzled me for a while until I realized that
> there is an implicit application of show that produces the quote. The show
> instance for strings prints a '"' character before it starts evaluating
> the argument. (With the setting -u for hugs, nothing is printed.)
> 
> So, what about other types?

I spent a few minutes a couple of colleagues yesterday puzzling over a
similar example.  The example was something like this:

instance Show (a -> b) where
showsPrec _ _ = showString ""

f :: Int -> Int -> Int
f = error "f is undefined"

Hugs> f 3

The expected output was "Program error: f is undefined",
since the expression `f 3' should evaluate to `error "..."',
but the actual output was "".

This puzzled us for quite a while, until we realized that
Hugs was only evaluating the expression `show (f 3)',
rather than evaluating `f 3', and our instance of `show'
for functions was lazy.

Fortunately we had defined the instance for functions
explicitly, rather than using `import ShowFunctions',
otherwise it might have taken much longer to figure out
what was going on.

But I wondered afterwards whether it might be better for
Hugs to use

x `seq` show x

rather than

show x

when evaluating expressions at the Hugs command-line
(with the default +u option).

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

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



Re: names, modules, types

2001-02-08 Thread Fergus Henderson

On 07-Feb-2001, Marcin 'Qrczak' Kowalczyk <[EMAIL PROTECTED]> wrote:
> So why is fmap separate now? Probably because having too much
> overloading causes ambiguities.

Perhaps.  But I think there may be other reasons too.

Having fmap separate is useful for beginners and for teaching,
because you can describe `map' without having to talk about type classes.
Also, it is possible that the error messages that you get when you
make a mistake using `fmap' might be harder to understand.

The reasoning here is similar to the reasons that Haskell 98 has list
comprehensions rather than monad comprehensions.

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

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



Re: binary files in haskell

2001-02-08 Thread Fergus Henderson

On 08-Feb-2001, John Meacham <[EMAIL PROTECTED]> wrote:
> A nice advantage of using my mid-level routines is that there are very
> little requirements placed on 'Byte' as a type, this means that as long
> as to the outside world you only read in 8 bit values and spit 8 bit
> values out you can represent it internally however you want. 
> 
> for example you might have a machine where a 16 bit word is the smallest
> addressable entity, if you relied on hPut Word8 then your program would
> not work since Word8 cannot exist on that platform. however if you made
> Byte be 16 bits and only used the bottom half of each word then your
> program will run unchanged even among architectures such as this.

I agree that `Byte' is a useful abstraction.
However, I think what you say about Word8 here is not correct.
Word8 can be implemented on a 16-bit machine just by computing all
arithmetic operations modulo 256.  There is no requirement that Word8
be physically 8 bits, just that it represents an 8-bit quantity.

Indeed, I think ghc uses this technique, representing Word8 as a full
machine word (e.g. 32 bits for x86, of which the topmost 24 are always
zero).

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

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



Re: Problem with functional dependencies

2001-01-03 Thread Fergus Henderson

On 03-Jan-2001, Mark P Jones <[EMAIL PROTECTED]> wrote:
> ... the best way to deal with this is (probably):
>   (i) to infer simpler types whenever possible, but
>  (ii) to allow more polymorphic types when they are requested by
>   means of an explicit type signature.

I agree.

> (Incidentally, in the interests of consistency, such a system should
> also programmers to use types like  Num Int => Int -> Bool.)

Mercury uses the approach you've suggested above for constraints like
these.  That is, you can declare types like that, and the Mercury
type checker will accept them, but it won't try to infer such types.

This feature could be a bit more useful in Mercury than in Haskell,
since in Mercury instance declarations can be private to a particular
module.

(Unfortunately, though, the Mercury runtime system's RTTI
representation of instances is not able to handle such constraints, so
for such examples, the current implementation of the compiler reports
"sorry, not implemented: constraints may only constrain type variables".)

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

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



Re: Haskell Language Design Questions

2000-12-29 Thread Fergus Henderson

On 29-Dec-2000, Doug Ransom <[EMAIL PROTECTED]> wrote:
> 1.  Is the lack of dynamic binding of functions by design or because it was
> too much effort to be justified at the time the language was designed?  In
> object oriented programming there can be several implementations of the same
> interface, and they can be stored in the same collection.

It's just something that didn't make it into Haskell 98.
Hugs and ghc offer a language extension for that.
It will almost certainly be in the next revision of Haskell.  See
<http://www.haskell.org/ghc/docs/latest/set/existential-quantification.html>.

> 2.It seems to me that the Maybe monad is a poor substitute for
> exception handling because the functions that raise errors may not
> necessarily support it.

Hugs and ghc also have exception handling extensions.
See <http://www.haskell.org/ghc/docs/latest/set/sec-exception.html>.
There's also a paper or two on that.  I hope you'll forgive the
self-citation, but the only one for which I happen to have a reference
on-hand is this one:

A semantics for imprecise exceptions. Simon Peyton-Jones,
    Alastair Reid, Tony Hoare, Simon Marlow, and Fergus Henderson.
Proceedings of the 1999 ACM SIGPLAN Conference on Programming
    Language Design and Implementation, May 1999.

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

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



Re: Are anonymous type classes the right model at all? (replying to Re: Are fundeps the right model at all?)

2000-12-25 Thread Fergus Henderson

On 21-Dec-2000, George Russell <[EMAIL PROTECTED]> wrote:
> (3) Finally it would be nice to extend the module syntax to allow named
> instances to be selectively exported and imported, just like variables.  

Mercury's module system allows instance declarations (which, as in
Haskell 98, are unnamed) to be selectively exported.

:- module foo.
:- interface.

:- import_module enum.

:- type t.
:- instance enum(t).

:- implementation.

:- instance enum(t) where [ ... ].

Mercury doesn't directly support selective import -- you can only
import a whole module, not part of it.  But if you really want that
you can achieve it by putting each instance declaration in its own
nested module.

:- module foo.
:- interface.
:- import_module enum.

   :- type t.

   :- module enum_t.
   :- interface.
   :- instance enum(t).
   :- end_module enum_t.

:- implementation.

   :- module enum_t.
   :- implementation.
   :- instance enum(t) where [ ... ].
   :- end_module enum_t.

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

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



Re: Union Types for Haskell!?

2000-11-24 Thread Fergus Henderson

On 24-Nov-2000, Bernd Holzmüller <[EMAIL PROTECTED]> wrote:
> There is one thing I was really missing in all these projects: the
> existence of union types (i.e. the union of value sets of two existing
> data types)

Mercury has a similar type system to Haskell.
This question came up a lot during the early days of Mercury,
since many Prolog programmers were used to a programming style
that made significant use of undiscriminated union types.

What operations would you allow on union types?

There's a number of possible choices.
Here's some of them:
(1) The only operation allowed on a union type
is calling a type class method of a type class
for which all the types in the union are instances.
(2) Allow pattern matching on values of particular types,
using `case'.
(3) Allow both (1) and (2)

If we allow (2), then some programming mistakes that previously
were type errors would instead become just inexhaustive pattern
matches for which you get a run-time error.

For example:

foo :: Maybe a -> b -> Maybe b
foo x y = case list of
[] -> Nothing
(x:xs) -> Just x
where list = case x of
Nothing -> 0-- oops, meant [] instead of 0
Just foo -> [y]

If union types were allowed, with (2) above, this example would be
legal, with `list' having the union type { [a], Integer }.
But `foo Nothing 42' would evaluate to bottom, since the `case list'
expression has no case with a pattern of type Integer.

So allowing union types in this way would reduce static type safety,
at least unless we also forbid inexhaustive pattern matches.

If instead you only allow (1), then probably union types would
not be suitable for expressing the kinds of things that you want
to express with them.

> Is there any reason for this restriction
> in the Haskell type system? Does this lead to losing the principal type
> property?

If you allow (2) above, there may be serious problems for
principal types.  For example, consider

f x = case x of
Nothing -> False
Just _ -> True

What's the most general type for `f'?
The type `f :: Maybe a -> Bool' is less general than
e.g. `f :: Union { Maybe a, ... } -> Bool',
but you certainly don't want to infer the latter type.

So (2) is definitely out.

I guess we could use a separate `typecase' rather than `case', and
require that `typecase' always be exhaustive.  That might solve
some of the problems.

But even then, there may be some tricky problems remaining.  Union
types introduce subtyping, and type inference with subtypes and
polymorphism is tricky -- in fact undecidable, if I recall correctly.
However, there have been some pragmatic attempts to solve this problem
in practice, even though the general case may be undecidable.  I think
there was a paper at the Industrial Applications of Prolog conference
in 1996 on a system called PAN (for "Prolog Analyzer") that had a type
checker that supported undiscriminated unions and/or subtypes.  There
were some cases that it didn't handle, but the authors claimed that
this wasn't a problem since those cases didn't arise in practice.

> I find the existence of union types very attractive. Apart from enhanced
> flexibility in modelling, type error messages would possibly be more
> traceable, because different branches in if- or case-expressions would
> have the *same* relevance, rather than the first branch being
> type-checked becoming normative for all other branches.

A type checker could easily generate better error messages in that sense
simply by checking each case seperately first, and then merging the results,
complaining if the types inferred in any two branches were not unifiable.

But if you allow union types, the type checker couldn't report an error
at the point where the two branches have types that are not unifiable;
instead, it would have to infer a union type there, and the point
where the types become inconsistent is only when the union type is
later used in a context that requires one particular type.  Reporting
the error at that point of use is likely to make it harder to find the
problem, since it is further away from the place where the error occurred. 
So I think allowing union types would most likely lead to *worse*
error messages.

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

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



Re: Hugs and Linux

2000-11-10 Thread Fergus Henderson

On 10-Nov-2000, [EMAIL PROTECTED] <[EMAIL PROTECTED]> wrote:
> 
> I can't get hugs98 to work under my linuxplatform. I have the Red
> Hat distirbution 7.0.
> The problem is that hugs requires a file called "readline.so.3" and
> I have "readline.so.4" on my system. Does anyone know how to get 
> around this problem??

One *possible* work-around is to just try linking readline.so.4 to
readline.so.3.

In general that won't work, because the interface to readline.so.4
will be different from the interface to readline.so.3 (that's why they
gave it a new major number).  But Hugs probably doesn't use that much
of the interface to readline (e.g. there's no support for command-line
completion, except the default file-name completion), so the difference
*might* not matter. 

It's certainly worth a try ;-)

Cheers,
Fergus.

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

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



Re: Passing an environment around

2000-11-08 Thread Fergus Henderson

On 27-Oct-2000, José Romildo Malaquias <[EMAIL PROTECTED]> wrote:
> On Fri, Oct 27, 2000 at 09:07:24AM -0700, Jeffrey R. Lewis wrote:
> > Yes, as implemented using the dictionary
> > translation, implicit parameterization can lead to loss of sharing, exactly in
> > the same way that overloading (and HOF in general) can lead to loss of sharing.
> > 
> > However, I can imagine that a compiler might chose to implement implicit
> > parameters more like dynamic variables in lisp.   Each implicit param essentially
> > becomes a global variable, implemented as a stack of values - the top of the
> > stack is the value currently in scope.  This would avoid the sharing problem
> > nicely.
> 
> I suppose your implementation of implicit parameterization in GHC and Hugs
> uses the dictionary translation, right?

I believe so.

> Would an alternative implementation
> based on a stack of values be viable

Yes.

> and even done?

Unlikely ;-)

> Does it have serious drawbacks when compared with the
> dictionary translation technique?

In the form described by Jeff Lewis above, yes, it does: it's not
thread-safe.

An alternative is to store the values of the implicit parameters in
thread-local storage rather than global storage.  But this is more
complicated.  It may also be less efficient on some targets (depending
on how efficiently thread-local storage is implemented).

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

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



Re: First class modules

2000-11-08 Thread Fergus Henderson

On 07-Nov-2000, Tom Pledger <[EMAIL PROTECTED]> wrote:
> Supposing that (some version of) Haskell had first class modules, and
> type variables could be universally quantified at the module level,
> would rule 2 of the monomorphism restriction go away?

No.

 |Rule 2. Any monomorphic type variables that remain when type
 |inference for an entire module is complete, are considered
 |ambiguous, and are resolved to particular types using the
 |defaulting rules (Section 4.3.4).

Although this rule refers to the "entire module", its typical for
the ambiguity to arise within a single function:

foo = show (read "whatever")

This expression is fundamentally ambiguous unless you somehow
disambiguate what type it is that you are trying to read.
I don't see how first class modules could solve that.

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

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



Re: Overloaded function and implicit parameter passing

2000-10-23 Thread Fergus Henderson

On 23-Oct-2000, José Romildo Malaquias <[EMAIL PROTECTED]> wrote:
> - cut here
> module Main where
> 
> class C a where
> f :: (?env :: Integer) => a -> Integer
> 
> instance C Integer where
> f x = ?env + x
> 
> main = putStrLn (show (f (45::Integer) with ?env = 100))
> - cut here
...
> $ ghc -fglasgow-exts Test1.hs -o test1
> 
> Test1.hs:7:
> Unbound implicit parameter `env_rJX :: Integer'
> arising from use of `env_rJX' at Test1.hs:7
...
> Would anybody comment on what is going on with GHC?

That sure looks to me like a bug in GHC's support for implicit
parameter passing.

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

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



Re: How does one find lazyness bottlenecks?

2000-10-12 Thread Fergus Henderson

On 12-Oct-2000, Sengan <[EMAIL PROTECTED]> wrote:
> Now that ghc 4.08 has a time profiler, I've been improving a program
> I wrote over the last year. However now the GC time dominates the
> execution time (>60%). I can see that my program is not being lazy,
> but I have no idea why.

What makes you think that the GC time is due to insufficient laziness?
My first thought is that high GC times may well be due to the opposite,
too much laziness.  Being lazy means that you create closures to represent
unevaluated expressions, and those closures will eventually need to be
garbage collected.

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

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



Re: Usability of M$ specs [was: Haskell and the NGWS Runtime]

2000-09-14 Thread Fergus Henderson

On 11-Sep-2000, Andrew Kennedy <[EMAIL PROTECTED]> wrote:
> Perhaps some of the non-MS
> .net compiler implementers would like to comment further?

One serious usability problem with the Microsoft .net specs that I
have seen is that Microsoft only provided them in a proprietry
documentation format, which can only be browsed on a Windows system
(in fact I think it even has to be W2k, IIRC).

-- 
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: help, classes!

2000-09-13 Thread Fergus Henderson

On 13-Sep-2000, kirstin reese <[EMAIL PROTECTED]> wrote:
> 
> Surely this is obvious, but I cannot figure out how to properly deal with
> class constraints and monads. For instance, when trying 
> 
> instance Monad Set.Set where 
>   xs >>= f =  Set.unionSet (Set.map f xs)
>   return x =  Set.single x
>   fail s   =  Set.empty
> 
> hugs complains that it "Cannot justify constraints in instance member
> binding" for >>=. unionSet type is Eq a => Set (Set a) -> Set a

Basically there is no way to do this in Haskell.
About the best you can do is to create your own `EqMonad' class,
which is like `Monad' except that it has an `Eq a' constraint
on the type variable.  Then use `EqMonad' instead of `Monad'.
You can't use the `do' syntax, and you can't reuse the library
routines that work on Monads.

-- 
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: Inferring types

2000-09-08 Thread Fergus Henderson

On 08-Sep-2000, Jan Carlson <[EMAIL PROTECTED]> wrote:
> I'm intrigued by the following Haskell behaviour:
> 
> The type of (+) is
> 
> (+) :: (Num a) => a -> a -> a
> 
> Now, if I define
> 
> p = (+)
> 
> the type of p is inferred to be
> 
> p :: Integer -> Integer -> Integer
> 
> How come?
> 
> I guess the answer can be found somewhere in the Haskell report, but I'd
> really appreciate just a rough description of the issue.

The infamous monomorphism restriction strikes again!

Because of the syntax used to define `p', it falls foul of the monomorphism
rule (4.5.5 in the Haskell report).  This requires that its type be
monomorphic.  Then the defaulting rules (4.3.4) come in to play, and
these mean that the type variable `a' gets the value `Integer', since
that is the first type in default default list (Integer, Double)
which satifies the constraint in question, namely `Num a'.

If you define `p' as a syntactic function, e.g.

p x y = x + y
or

p x = (+) x

rather than via

p = (+)

then the monomorphism restriction does not apply, and so the type inferred
for `p' will be the correct polymorphic type `Num a => a -> a -> a'.

-- 
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: inference question

2000-09-01 Thread Fergus Henderson

On 31-Aug-2000, William Lee Irwin III <[EMAIL PROTECTED]> wrote:
> {hugs} Example> :type cmethod . fromNat $ 1
> {hugs} cmethod . fromNat $ 1 :: (C a, Q a) => a
> 
> This is the expected typing, which I expect to be valid.
> 
> But the inferencer chokes on an actual binding like the following:
> x = cmethod . fromNat $ 1
> 
> Example> let x = cmethod . fromNat $ 1 in 0
> ERROR: Unresolved overloading
> *** Type   : (Q a, P a) => Integer
> *** Expression : let {...} in 0

You have run into the infamous monomorphism restriction.
Haskell 98 does not allow variables like `x' above to be polymorphic.
See section 4.5.5 in the Haskell report.  For more information,
try searching the archives of this mailing list for "monomorphism
restriction".

The error message that you get from Hugs could certainly be a lot
clearer than it is.

> For some reason, _explicitly_ typing it is okay.

Yes.  That's because of rule 1 (b) in 4.5.5.

Another work-around is to make `x' a function rather than a variable:

let x _ = cmethod . fromNat $ 1 in 0

-- 
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: Haskell compilers targetting Wintel platforms, or microsoft's ".NET"...

2000-08-29 Thread Fergus Henderson

On 29-Aug-2000, larisys <[EMAIL PROTECTED]> wrote:
> There is at the moment a great fuss around the new Microsoft's ".NET" 
> platform. Articles about the related virtual machine and run-time 
> environment often cite Haskell as a language targetting the ".NET". Does 
> anybody out there knows about existing Haskell compilers generating code 
> for the ".NET", or native code for WinTel platforms ?

There was a long discussion of this quite recently on this list.
You can find the archive for this list on www.haskell.org.
Search for "NGWS".

-- 
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: Haskell and the NGWS Runtime

2000-08-15 Thread Fergus Henderson

On 14-Aug-2000, Benjamin Leon Russell <[EMAIL PROTECTED]> wrote:
> Tyson Dowd <[EMAIL PROTECTED]> wrote:
> > I don't believe you can teach programmers anything by
> > trying to take
> > tools away from them.
> > 
> > I believe you can only teach programmers by showing them
> > a better tool. 
> 
> Aha, but *which* programmers?  The C/C++ programmers who will bother
> learning how to write safe code, or those who won't?

Well, no sane C# course or book will teach the unsafe features of the
language before the safe ones.  So I think the vast majority of C/C++
programmers who learn C# will already know how to write safe C# code
before they learn how to write unsafe C# code.

> The problem is that many programmers will not focus on the safe features
> if the unsafe ones remain.
...
> For example, if the C/C++ programmers are used to explicit memory
> management using malloc() and free(), then they are likely to keep writing
> all their methods using this old style, even when the running time is
> not crucial.  This could potentially introduce more memory-related bugs
> than necessary.

I'm not an expert on C#, so I could be wrong about this, but as I
understand it, C# does not have malloc() and free(), not even in the
unsafe subset.

Unsafe C# is not the same as C or C++.  Furthermore, "unsafe" code
will have a stigma attached to it, just like "goto" does today (or
perhaps more so).  So I think you overestimate the danger of C/C++
programmers continuing to write much of their code using unsafe
features if they switch to C#.

> Suppose the manager starts the project by requiring that all the
> programmers write all non-time-critical portions of their code in pure C#.

Why wouldn't the manager require that they write all non-time-critical
portions of their code in safe C# (i.e. C# without the "unsafe" keyword)?

> > On 14-Aug-2000, Benjamin Leon Russell <[EMAIL PROTECTED]> wrote:
> > > Your not-quite-spoken assumption that it should be possible to write
> > > everything in one language is just something I fundamentally disagree
> > > with.  The requirements of low-level kernel code are quite
> > > different from those of most user-level applications, and
> > > any single language that tries to address
> > > both sets of requirements will do so poorly.
> > 
> > Ah, a testable hypothesis!
> > If you are right, then you should be able to criticize some other
> > features of the language that have suffered as a result of unsafe
> > code in C#.
> 
> Ah, a testable hypothesis!  If you are right, then you should be able to
> provide an example of a language that meets the requirements of writing
> both low-level kernel code and most user applications equally well for
> the bulk of the programmers working with the language!

Well, how about Modula II and Ada?

-- 
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: Haskell and the NGWS Runtime

2000-08-11 Thread Fergus Henderson

On 11-Aug-2000, Sylvan Ravinet <[EMAIL PROTECTED]> wrote:
> On Fri, 11 Aug 2000, R.S. Nikhil wrote:
> > And is Netscape Communicator 4.61 on Linux (bugs and all) a definitive
> > test of portable HTML?  :-)
> 
> Actually it seems to be quite readable by lynx...

Yes -- that's the worst part.  In Lynx and Opera, it *seems* to be
correctly rendered.  Unfortunately it is missing all of the crucial
links to the actual slides!  Of course there is no easy way you could
tell this, except by having seen the same site already with IE, or by
examining the site's source code.

-- 
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: Haskell and the NGWS Runtime

2000-08-11 Thread Fergus Henderson

On 11-Aug-2000, R.S. Nikhil <[EMAIL PROTECTED]> wrote:
> > -Original Message-
> > From: Fergus Henderson [mailto:[EMAIL PROTECTED]]
> > Sent: Friday, August 11, 2000 4:18 AM
> > ...
> > 
> > In particular <http://commnet.pdc.mscorpevents.com/sessions.asp>.
> > However, as seems to be usual (%*&^#*&^#@!) for MS, this page is NOT
> > written in portable HTML.  Certainly it didn't work with Netscape
> > Communicator 4.61 on Linux when I tried it.
> 
> And is Netscape Communicator 4.61 on Linux (bugs and all) a definitive
> test of portable HTML?  :-)

The page doesn't display properly with Lynx (2.8.3dev.9) on Linux
or with Opera (4.02) on Windows either.

-- 
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: Haskell and the NGWS Runtime

2000-08-11 Thread Fergus Henderson

On 02-Aug-2000, Doug Ransom <[EMAIL PROTECTED]> wrote:
> The PDC slides and white papers  should be available if you dig
> through this site:
> http://commnet.pdc.mscorpevents.com/default.asp

In particular <http://commnet.pdc.mscorpevents.com/sessions.asp>.
However, as seems to be usual (%*&^#*&^#@!) for MS, this page is NOT
written in portable HTML.  Certainly it didn't work with Netscape
Communicator 4.61 on Linux when I tried it.

When it comes to open standards, Microsoft are good at "talking the talk",
but if the way they write web pages is any indication, they have a long
way to go before they'll be "walking the walk".

-- 
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: Haskell and the NGWS Runtime

2000-08-11 Thread Fergus Henderson

On 11-Aug-2000, Manuel M. T. Chakravarty <[EMAIL PROTECTED]> wrote:
> Ketil Malde <[EMAIL PROTECTED]> wrote,
> 
> > "Manuel M. T. Chakravarty" <[EMAIL PROTECTED]> writes:
> > 
> > > A good analysis of were C# fits re Java and C++ is at
> > > 
> > >   http://slashdot.org/article.pl?sid=00/08/09/1612254&mode=thread
> > 
> > Wherein we read:
> > 
> > > One new feature that I mentioned already was that of copy-by-value
> > > objects. This seemingly small improvement is a potentially huge
> > > performance saver!

This analysis actually misses the main point.
Performance is not the main reason for wanting value types.
The main reason for wanting value types is that there are many
types which are better modelled as values rather than as objects.
Of all people, functional programmers should surely be well aware of this!

Note that Eiffel, which certainly tends towards purism in its OOP zeal,
originally did without value types, but the Eiffel community found that
this did cause problems and so since Eiffel 3.0, Eiffel has had value
types (though they call them "Expanded Objects" -- I guess so that they
can still call the language "purely" object oriented ;-).
For similar reasons, Sather also distinguishes between value types
and object types.  Likewise I believe that a request for value types
is high up on the Java extensions list.  Complex numbers, for instance,
are an example of a type which is much better modelled as a value type
than as an object type.

>From a modelling perspective, the most important difference between
a value type and an object type is not that an object type is allocated
on the heap, but that an object type has an identity.

However, that said, there are cases where value types can give
significant performance improvements over object types.

> > > With C++, one is regularly tempted to describe the
> > > simplest constructs as classes, and in so doing make it safer and
> > > simpler to use them. For example, a phone directory program might
> > > define a phone record as a class, and would maintain one PhoneRecord
> > > object per actual record. In Java, each and every one of those objects
> > > would be garbage collected!
> > 
> > Now, is this really such a big problem?  Is it a problem because of
> > Java's mark-and-sweep, and if so, couldn't you apply a better GC?
> 
> That's exactly what I thought.  I mean why don't they read a
> couple of research papers?

Using a better garbage collector is certainly a good idea.
However, there is a limit to how good you can make the garbage collector.
Often it is much more cost effective to put work into reducing the
program's allocation rate rather than trying to make the garbage
collector faster.

>From what I have heard, it sounds like MS have put quite a bit of work
into their garbage collector.  They use a generational mark-compact
collector, with I think three generations, the first of which is sized
to fit in the L0 (or was it L1?) cache, and they have several
different versions for different situations, including a concurrent
one for interactive use.  They claim that in situations where you are
frequently allocating small objects, the overhead of allocation is
about 6 cycles per object (this of course does not include the
collection cost), and they claim that in such situations the amortized
overall cost of allocation plus collection is less than 50 cycles per
object.  These claims have not (to my knowledge) been independently
verified, and personally I am somewhat sceptical, particular about
the extent to which these figures, which are no doubt the best case
figures, will extrapolate to real programs.  However, I think it is
fair to say that Microsoft have done their homework on this issue.

I have not yet done any benchmarking of their GC yet.  The reason for
that is that currently the Mercury to IL code generator generates code
which does many unnecessary allocations which we know how to eliminate,
so benchmarking things at this point would give us very little in the way
of of useful comparisons.

-- 
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: Haskell and the NGWS Runtime

2000-08-10 Thread Fergus Henderson

On 10-Aug-2000, Theodore Norvell <[EMAIL PROTECTED]> wrote:
> With Haskell# or Mondrian: Can I use C# to create an instance of
> a Haskell class? Can I use Haskell to extend a C# abstract class?
> I suspect the answer to both these questions is currently no.

I'm not sure either, but I think the answer is no.

A related question to which I do know the answer is "Can I use Mercury
to create an instance of a Haskell class, or vice versa?".
And the answer to that one, despite Mercury and Haskell having a
very similar concept of "class", is still no.  So there's still a long
way to go.

-- 
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: Haskell and the NGWS Runtime

2000-08-10 Thread Fergus Henderson

On 10-Aug-2000, Brent Fulgham <[EMAIL PROTECTED]> wrote:
> I hope they at least get rid of
> the hungarian notation while they are at it. 

Yes, thankfullly they have indeed done that.  That one got a round of
applause even from the (mostly) Microsoft faithful who attended PDC,
when it was mentioned in one of the sessions there.

> > Microsoft spent around $2M funding a bunch of groups working 
> > on research and industrial programming languages to give 
> > feedback on their work. (Haskell, Mercury, ML, Scheme, Oberon,
> > Eiffel, Python, Oz, etc...)  While they acknowledged from the
> > start that getting any changes (apart from tailcall) into 
> > version 1 was pretty unlikely, they have been listening, 
> > taking notes, and even now the C# folks are getting
> > excited about the idea of putting generics into the language.
>
> Well, that sounds good.  Are you speaking from personal knowledge
> here?

Yes, Tyson and I, as well as researchers from other groups, visited
Redmond several times.  Note that tailcall was in already by the time
outside researchers were approached, so I don't know of any technical
suggestions made by outside researchers that have yet been acted on.
However, the fact that they have been asking for our suggestions and
taking notes is at least an improvement.  I guess the really
interesting bit will be to see what goes in version two.

-- 
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: monadic source of randomness

2000-08-10 Thread Fergus Henderson

On 09-Aug-2000, Carl R. Witty <[EMAIL PROTECTED]> wrote:
> Norman Ramsey <[EMAIL PROTECTED]> writes:
> 
> > Does anybody know of work using monads to encapsulate a source of 
> > random numbers?  A quick web search suggested Haskell 98 did not take
> > this path.  I'd be curious for any insights why, or any suggestions
> > about a `randomness monad'.
> 
> My guess as to why Haskell 98 does not provide a stand-alone
> "randomness monad" is that monads are annoying (impossible in general)
> to combine.

Another reason is that some people favour an approach using the
`Random.split' function in preference to using a monad.
Using a monad imposes a sequence on things, whereas using the
`Random.split' function, you can distribute a sequence of random
numbers to several function calls without imposing any sequence.
The resulting code is thus more symmetric and (at least in theory)
more easily parallelizable.

(However, little work has been done on ensuring good randomness of
sequences generated using `Random.split', so if you need high quality
randomness then I would not advise that approach at this point in time.)

-- 
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: Haskell and the NGWS Runtime

2000-08-03 Thread Fergus Henderson

On 03-Aug-2000, Nigel Perry <[EMAIL PROTECTED]> wrote:
> >I understand that point, but if doing that means that you need to
> >implement the basic things like argument passing and procedure
> >calling yourself, using your own virtual machine, rather than
> >by using the underlying runtime's argument passing and procedure calling
> >mechanisms, then I'd say that it is looking more like putting a round
> >peg in a square hole than a good fit.
> 
> Passing arguments on a separate stack is pretty lightweight.

Well, I'm not sure that's true.  Consider what you pay:

- If you only have one stack, then the stack needs to be a
  stack of Object, and so for every argument that you put on the
  stack you need to
- box it before putting it on the stack
  (if it is not already boxed)
- downcast it to the right type after taking it off the stack
- unbox it (if the type is an unboxed type)

  (If you use more than one stack, this can reduce such costs;
  but doing that increases the complexity of the approach
  significantly, and there are some significant costs in terms
  of performance from using multiple stacks that need to be
  weighed against the potential benefits.)

- To get efficient access to your stack, you need to use at least one
  extra register to hold your stack pointer, or (quite likely) two
  extra registers, one for the array base and one for the offset.
  Note that on x86 there are only six general purpose registers,
  so you very quickly run out...

  Alternatively, if these are not in registers, then the cost of
  accessing the stack will be higher.

- By not using the system stack, you reduce locality.
  This shows up in the greater register pressure (see above),
  and can also lead to more cache misses or cache collisions.

- If the stack is an array, then (at least for verified code)
  every push and pop needs a bounds check.

- Because of aliasing issues, the .NET runtime is very
  unlikely to optimize away the pushes and pops to your stack
  when it inlines methods.  And indeed it will treat these
  pushes and pops as more expensive than ordinary argument passing
  (since they are!), and so it will be less inclined to inline
  such methods in the first place.  Of course, doing a good job
  of inlining in the Haskell compiler will help reduce the
  damage here, but the Haskell compiler can't do cross-language
  inlining, and can't do JIT-time inlining across different
  assemblies or of dynamically loaded code, so you will still
  lose out in some scenarios.

However, I guess it depends on what you mean by "light-weight".
I guess one could argue that the costs of most other things pale
in comparison to the costs of having lazy evaluation as the default ;-)

-- 
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: Haskell and the NGWS Runtime

2000-08-02 Thread Fergus Henderson

On 02-Aug-2000, Carl R. Witty <[EMAIL PROTECTED]> wrote:
> Fergus Henderson <[EMAIL PROTECTED]> writes:
> 
> > > The compiler hooks into GHC by translating Core into GOO
> > > and then after some source to source transformations it
> > > can spit out either C# or Java.
> 
> Is there any publically available technical information on what you
> guys are talking about? I've been doing web searches, and searches on
> the Microsoft web site, and I can't find anything on GOO, IL, or
> "Common Language Specification".

Technical information about this stuff (IL, the CLS, etc.) was
included on the CDs that MS gave to the 6000-odd participants of their
recent PDC (Professional Developers Conference) in Florida last month.
So if you can find one of those, you might be in luck.  But I don't
think Microsoft have put anything about it up on the web.

GOO is not a Microsoft invention, and nor is it part of Microsoft's
.NET stuff.  GOO is an intermediate language that was, AFAIK, invented
by the Mondrian group.  It might be described in the following paper:

Erik Meijer and Koen Claessen. The Design and Implementation of
Mondrian. In Proc. Haskell Workshop, 1997. 

-- 
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: Haskell and the NGWS Runtime

2000-08-02 Thread Fergus Henderson
l, these fast entry points definitely sound like an improvement.
They're not mentioned on the Mondrian web page whose URL was posted
earlier in this thread.  Are these something you're planning to
include in the Sept 1 release?

> > Hmm, the "full" adjective here sounds like it might be a bit of an
> > overstatement.  Does that mean that I can call Mercury code from
> > Haskell, have it all statically type checked, and not have to write
> > any additional interface definitions or glue code?  Including
> > procedures which are polymorphic and/or use type classes?
> > If so, I would be very surprised!  I think the current level of interop
> > supported is still a LONG way from what I would describe as "full"
> > interoperability.
> 
> Come on Fergus! You will never achieve interoperability on that level
> except when your semantic domains match exactly or when you have an
> extremely complicated intermediate language. For example, most
> languages don't make the distinction between values and computations
> as Haskell does, and I don't expect or want for example VB programmers
> to do that either. But it does mean that whenever I call a VB function,
> I must write a little glue code to compensate for the difference in
> semantics. The same is true for calling nondeterministic or multi-moded
> Mercury predicate.

No, it's not true.  You can call multi-moded or nondeterministic
Mercury predicates directly from other .NET languages without any glue
code.

For multi-moded procedures, the mode number is part of the IL function
name, so you just pick which function name you want to call, and call it.

For nondeterminstic procedures, the caller needs to pass a success
continuation callback function, which will get called once for each
solution.  But that's not glue code for the purpose of handling
language inter-op; that's just the way in which the interface is
exposed.  If I were writing code in C that needed to use backtracking,
I'd do it the same way, even if there was no Mercury code involved at
all.

(Note that currently you _do_ need to write glue code when
calling other languages from Mercury.  But you don't need to
write glue code when calling Mercury from other languages.
We also plan to automate the generation of glue code when calling
other languages from Mercury, so that you won't need to write
any of it manually.)

> > For example, which of the various CLS (Common Language Specification)
> > categories does the Haskell and/or Mondrian implementation comply with?
> 
> Aha, finally you hit a real issue. To be a CLS extender would require
> a lot of language extensions to a lot of languages, even to OO languages
> like Java! But for Haskell the situation is even more severe.

Indeed.  But will your implementation even meet the specification
for a CLS consumer?

> > Actually that's not really true; compiling to IL is not enough.
> >
> > To support ASP+ for a given language, you also need to implement a
> > certain API.  Now my information on this is mostly second-hand,
> > but as I understand it, this API pretty much assumes that your
> > language is a fairly typical imperative language, with constructs
> > like loops, etc.  So it is fairly easy to implement this API for
> > imperative languages, but not nearly so easy to implement it for
> > functional languages or other non-traditional languages.
> 
> That is right. The thing here is to use the "code behind" style ASP pages.

Could you elaborate?  Or could you give a pointer to where we could
find out more about "code behind" style ASP pages?

-- 
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: Haskell and the NGWS Runtime

2000-08-01 Thread Fergus Henderson

Erik Meijer <[EMAIL PROTECTED]> wrote:
 ^^
> [someone wrote:]
> > Does anyone know where there is some information on Haskell integration
> > with the Microsoft NGWS runtime, which provides
> > cross language integration and a common system for memory managment,
> > library functions etc.
> >
> > I am curious to see if the haskell integration is a good fit or a graunch
> > (square peg into a round hole).
> >
> > I know some work is being done on haskell in this regard, but exactly what
> > I do not know.
> 
> The plan is to have the release out the door by September 1st.

Will that release support Haskell, or just Mondrian?

> The translation is quite elegant IMHO,

I'm afraid I have to disagree on that point.  Basically you translate
quite a few things by implementing your own virtual machine on top of
the .NET runtime.  For example, argument passing is done with explicit
pushes and pops on your own virtual machine stack, rather than by
using the .NET runtime's argument passing.  This approach makes the
compiler is fairly simple, but the generated code is not what _I_
would call elegant.

> it only encodes those features that
> Haskell has, but the .NET runtime lacks, that is lazy evaluation and
> currying (what else can you expect).

Don't you currently encode tail calls too?  And what about
type classes and polymorphism?

Also, as I understand it, Haskell/Mondrian programs that don't make use of
currying -- e.g. those in which all functions have only one argument --
still get encoded, rather than being mapped directly.  So the encoding
is not done in way that you only pay for it when you use those features.
This makes interoperability with other languages more difficult.

> As we demo-ed at the PDC, we have full bidirectional interop between Haskell
> and other .NET languages.

Hmm, the "full" adjective here sounds like it might be a bit of an
overstatement.  Does that mean that I can call Mercury code from
Haskell, have it all statically type checked, and not have to write
any additional interface definitions or glue code?  Including
procedures which are polymorphic and/or use type classes?
If so, I would be very surprised!  I think the current level of interop
supported is still a LONG way from what I would describe as "full"
interoperability.

So, could you elaborate on what sense you mean when you say we have
"full" bidirectional interop?
For example, which of the various CLS (Common Language Specification)
categories does the Haskell and/or Mondrian implementation comply with?

> The fact that there is a common runtime is a really great thing. In the old
> days for example, you had to implement your own so called ActiveX scripting
> engine to host Haskell programs in HTML pages, ASP pages, or WSH. Now you
> only have to target to IL and get those goodies already paid for, ie you can
> write ASP+ pages in Haskell, COBOL, Mercury, Perl, Phyton, APL, Smalltalk,
> Scheme, Component Pascal, Eiffel, Oberon, ... (The corresponding thing for
> Java would be that if I compile Haskell to Java, I get Haskelletes already
> paid for).

Actually that's not really true; compiling to IL is not enough.

To support ASP+ for a given language, you also need to implement a
certain API.  Now my information on this is mostly second-hand,
but as I understand it, this API pretty much assumes that your
language is a fairly typical imperative language, with constructs
like loops, etc.  So it is fairly easy to implement this API for
imperative languages, but not nearly so easy to implement it for
functional languages or other non-traditional languages.

In addition, I think your compiler also needs to support attributes?

P.S.  My research group has received substantial funding from MS,
so my opinion on these issues may not be entirely objective.

-- 
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: Classes

2000-07-27 Thread Fergus Henderson
 a missing 
> instance.  And even if we could express our intention, f's type would
> still not be instantiated to match the only instance of C [Hugs says
> "cannot justify constraints" when trying to load f, and "unresolved 
> overloading" when I try to use g after commenting out f; what do
> batch-compilers say, and do they change messages when we rename
> the module to Main and include some definition of main?].

I translated this example to Mercury:

:- module example.
:- interface.

:- typeclass c(T) where [].
:- instance c(float) where [].

:- func f = A <= c(A).
:- func g = int <= c(int).

:- implementation.

f = 1.
g = 2.

The current Mercury compiler (like Haskell 98) does not support
constraints of the form `c(int)'; it reports a "sorry, not implemented"
error for the type declaration for `g'.

If you comment out the declaration and clause for `g', then
the Mercury compiler reports

example.m:013: In clause for function `example:f/0':
example.m:013:   in function result term of clause head:
example.m:013:   type error in unification of variable `HeadVar__1'
example.m:013:   and constant `1'.
example.m:013:   variable `HeadVar__1' has type `A',
example.m:013:   constant `1' has type `int'.

Note that even if you remove the type class constraint, `f' still has
a type error.  That's why the error message doesn't mention type class
constraints.  This error message could be improved, by explaining why
it is that the type variable `A' can't be bound.  The reason is that
`A' is universally quantified.

If you use an existential quantifier,

:- some [A] func f = A => c(A).

then you get a different error message, more like the one that I think
you were expecting:

example2.m:013: In clause for function `example2:f/0':
example2.m:013:   unsatisfiable typeclass constraint(s):
example2.m:013:   `example2:c(int)'.

> > What I can't tell the compiler is "there will not be any other instances
> > FA [foo] [bar], so if you need one, you may assume that foo == bar".
> 
> Both seem reasonable from a logic-programming perspective, as well 
> as a few other modifications, but with the current lack of control over 
> the scope of instance declarations, it is hard to define "these" in "these 
> are the only instances of class C".

If a type class is not exported from a module, then only that
module can contain instances of that type class.  So the type
checker could perhaps handle that case specially.  On the other
hand, it would be problematic if simply exporting some previously
private entity could change whether the module is type-correct.

-- 
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: Precision problem

2000-07-25 Thread Fergus Henderson

On 25-Jul-2000, Julian Assange <[EMAIL PROTECTED]> wrote:
> Fergus Henderson <[EMAIL PROTECTED]> writes:
> 
> > Jon Fairbairn was talking about Haskell.  MSVC is a C/C++ compiler,
> > not a Haskell compiler.  For C and C++, there are many many areas of
> > undefined, unspecified, or implementation-defined behaviour.  If a
> > C or C++ program gives different behaviour on different runs or with
> > different compilation flags, this is almost always due to the program
> > depending on one of those areas, rather than due to the compiler not
> > conforming to the standard.
> 
> Standard, shmandard. If a compiler can't produce reproducable code,
> then its of little value for scientific computing.

*If* you write C code which strict conforms to the standard, then any
conforming compiler will give you reproducible results.
The only times that you will not get reproducible results is if
you either accidentally or deliberately write code which is not
strictly conforming, if you invoke the compiler in a
non-standard-conforming mode, or if there is a compiler bug.

Writing strictly conforming C code is difficult.  Very difficult.
If you want reproducible results, and you don't know how to write
strictly conforming C code, then don't use C!  There are plenty of
languages which make it much easier to get reproducible results.

-- 
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: The type of zip

2000-07-24 Thread Fergus Henderson

On 24-Jul-2000, Chris Angus <[EMAIL PROTECTED]> wrote:
> Has anyone ever thought of trying to use reflection in these cases.

Yes, I've thought of it.  That is how we implement the generic
`read' and `print' in Mercury.  Using reflection like this
seems to be a quite powerful technique; I think that using
reflection you can do quite a lot in the language that in Haskell
currently seems to instead be done with external preprocessors
(e.g. "Deriv", or whatever it is called now).

-- 
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: Precision problem

2000-07-23 Thread Fergus Henderson

On 23-Jul-2000, Julian Assange <[EMAIL PROTECTED]> wrote:
> Jon Fairbairn <[EMAIL PROTECTED]> writes:
> > [George Russell wrote:]
> > > Surely this is obvious to Haskell programmers?
> > to me, anyway.  If two runs (with different flags) of the
> > compiler produce programmes that give different results,
> > then one of them isn't adhering to the standard, (and so
> > should be noted as such).

That statement is not completely true.  The Haskell report does not
completely define the semantics of all Haskell programs.
For example, the range of `Int' and the result of computations
which overflow are left undefined.  Such implementation-dependent
qualities could certainly be subject to change depending on which
compiler flags the user specifies.

Furthermore, not all Haskell programs have deterministic behaviour.
Programs that make non-trivial use of the IO monad can have
nondeterministic behaviour.  In fact, for some programs that make
use of the `Random' module, such as the following,


import Random
main = do
r <- randomRIO (1, 100)
print (r :: Int)

the whole idea is that you _won't_ get the same result each time.
If the program produces the same results each time then this is
arguably evidence that the implementation does NOT conform to
the Haskell report!

So, the best that you can really say for Haskell is that within a
single run, for code which does not use the IO monad, you should
get the same result each time within that run.

> Microsoft VCC once (still?) suffers from this problem. Whether
> it is because it accesses random, unassigned memory locations
> or because the optimiser has time thesholds, is unknown.

Jon Fairbairn was talking about Haskell.  MSVC is a C/C++ compiler,
not a Haskell compiler.  For C and C++, there are many many areas of
undefined, unspecified, or implementation-defined behaviour.  If a
C or C++ program gives different behaviour on different runs or with
different compilation flags, this is almost always due to the program
depending on one of those areas, rather than due to the compiler not
conforming to the standard.

-- 
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: Precision problem

2000-07-18 Thread Fergus Henderson

On 18-Jul-2000, Sven Panne <[EMAIL PROTECTED]> wrote:
> 
> Nevertheless, there seems to be some consensus that optimization should
> not change the outcome of a computation. Note that GCC's -O flag *does*
> change it, at least if -ffloat-store is not given in addition. The newly
> introduced GHC option -fstrictfp is intended to give back that guarantee,
> but after this discussion I feel that it should be the default behaviour.

I agree.  And the inverse option (`-fno-strict-fp') should be documented
as not conforming to the Haskell report.

> A short description of GHC's internal handling of floating point values
> and the accompanying problems:
> 
>* GHC uses IEEE arithmetic for Float and Double.

Is that true for every platform that GHC targets?

>* Floating point values are internally represented as Rationals, which
>  is completely OK for literals given by the programmer. It is flexible
>  enough to make cross-compilation possible (which GHC currently can't
>  do for other reasons), a possibility which would be lost if Float/Double
>  were used for this, so this approach would be a step in the wrong
>  direction.

If all the platforms that GHC target use the same IEEE arithmetic
and representation for Float/Double, why does GHC need to use
Rational to represent floating pointer values?

-- 
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: Precision problem

2000-07-18 Thread Fergus Henderson

On 18-Jul-2000, Keith Wansbrough <[EMAIL PROTECTED]> wrote:
> > IMHO GHC's documentation should clearly warn that programmers should
> > not depend on even basic stability and exactness of floating point
> > computations, and only stability is provided by -fstrictfp.
> 
> GHC is no different from any other compiler for any other language in 
> this respect.

There's a huge difference between languages like C, which have
unspecified and/or undefined behaviour lurking in every nook and
cranny, and pure functional languages like Haskell.  Haskell functions
are supposed to be referentially transparent mathematical functions:
for any given function in any given program, for any given inputs to that
function, you should get the same output from that function every time.

> Floating-point values are *not* the mathematical `real 
> numbers', and should not be treated as such.

Yes, but for any given Haskell program execution, the sum of any two
floating-point values should be the same every time you compute it.
In general it need not be the same as the sum of the equivalent real
numbers, because floating point numbers are subject to rounding,
overflow, etc., and of course it might vary from platform to platform,
or from compiler to compiler, or perhaps even from run to run;
but nevertheless, Haskell or any other language which aims to be
referentially transparent, for any given program execution the sum
should be the same each time in that program execution.

-- 
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: Library conventions

2000-06-26 Thread Fergus Henderson

On 24-Jun-2000, Marcin 'Qrczak' Kowalczyk <[EMAIL PROTECTED]> wrote:
> When an Either result encodes a good result or an error, the error
> should be Left and the good result should be Right. Rationale:
> partially applied type is a good Functor and Monad. Seems to be
> consistently used (MonadEither, Parsec).

Actually I dislike this practice of using `Either' for something which
is either a good result or an error.  In this case, there is an
assymetry in the meaning we attach to the two cases.  Using `Left' and
`Right' for such cases is fundamentally confusing since it is not
clear what the meaning of `Left' and `Right' is.  I much prefer using
a separate type defined as e.g.

data Result error val = ResultError error | ResultOK val

This tends to lead to much more readable code.

-- 
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: "Boxed imperatives" to implement pure functions (Was: Inverse Indices)

2000-06-06 Thread Fergus Henderson

On 06-Jun-2000, Bjarke Dahl Ebert <[EMAIL PROTECTED]> wrote:
> Has anyone made a generalization of accumArray, which allows users to
> implement a pure function using imperative features?

Yes.  See the documentation for the `ST' module in the Hugs/ghc extension
libraries.  I enclose a brief extract.

 | 3.16. ST
 | 
 |This library provides support for strict state threads, as described
 |in the PLDI '94 paper by John Launchbury and Simon Peyton Jones
 |[LazyStateThreads]. In addition to the monad ST, it also provides
 |mutable variables STRef and mutable arrays STArray.
...
 | data ST s a-- abstract type
 | runST  :: forall a. (forall s. ST s a) -> a
...
 | data STArray s ix elt -- mutable arrays in state thread s
 |   -- indexed by values of type ix
 |   -- containing values of type a.
 | newSTArray  :: Ix ix => (ix,ix) -> elt -> ST s (STArray s ix elt)
 | boundsSTArray   :: Ix ix => STArray s ix elt -> (ix, ix)
 | readSTArray :: Ix ix => STArray s ix elt -> ix -> ST s elt
 | writeSTArray:: Ix ix => STArray s ix elt -> ix -> elt -> ST s ()
 | thawSTArray :: Ix ix => Array ix elt -> ST s (STArray s ix elt)
 | freezeSTArray   :: Ix ix => STArray s ix elt -> ST s (Array ix elt)
 | unsafeFreezeSTArray :: Ix ix => STArray s ix elt -> ST s (Array ix elt)

-- 
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: mode in functions

2000-06-02 Thread Fergus Henderson

On 02-Jun-2000, Ketil Malde <[EMAIL PROTECTED]> wrote:
> Fergus Henderson <[EMAIL PROTECTED]> writes:
> 
> > An interactive command line tool and a programming language intended
> > for writing non-trivial applications have very different requirements.
> > For the former, brevity may well be more important than readability,
> > but for the latter it is definitely the other way around.
> 
> But verbosity is not the same as readability!  "head" is a perfectly
> good name for a function that returns the first element of a list,
> even though firstElementOf might be more descriptive.
...
> So, commonly used names should be short

I agree.  But single character names, as originally suggested in this
thread, are too short; at that point, readability has definitely been
compromised.  Only the most pervasive operations would warrant names
so short, and modes for operations like sorting certainly don't fall
into that category.

-- 
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: mode in functions

2000-06-02 Thread Fergus Henderson

On 02-Jun-2000, S.D.Mechveliani <[EMAIL PROTECTED]> wrote:
> Ketil Malde <[EMAIL PROTECTED]> writes
> 
> > I could accept "mode flags" if the algorithm is extremely similar,
> > e.g. passing a comparator function to a sort is a kind of mode flag
> > (think ordered/reversed) which I think is perfectly acceptable.
> > Having flags indicating algorithm to use (sort Merge (s:ss)) is IMHO
> > silly. 
> 
> 
> Not at all. Silly it to call differently the functions that compute
> the same map.
> Also silly is to have  quotRem & divMod   
> instead of quotRem .

In addition to the criticisms that have already been leveled against
this approach, another drawback with it is that makes things less
extensible.

For example, with the current approach, if I want to define a new
sorting function, I just go ahead and do so, and apart from the
user of my new function having to import my module, my new sorting
function is completely first class, just like any sorting functions
that are provided by the Prelude or standard libraries.

But if we use mode arguments with some enumeration type, then there's
no easy way for me to add a new enumeration constant to the enum, or
to change the standard `sort' function so that it can call my sort
function.  So my new sort function ends up being in some sense a
second-class citizen in comparison to the various different sort
functions encapsulated as different modes of the standard `sort'
function.

For example, someone writing an algorithm that makes use of a sorting
function might well make the mistake of abstracting away which kind of
sort function is used by passing in a SortMode argument,

foo :: SortMode -> ...
foo mode ... =  (sort mode) ...

rather than by passing in a sort function.  If they did that, then
I wouldn't be able to make `foo' use my own sort function.

(Note that using `Char' rather than an enumeration doesn't help with
this problem.)

-- 
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: mode in functions

2000-06-02 Thread Fergus Henderson

On 01-Jun-2000, Ketil Malde <[EMAIL PROTECTED]> wrote:
> Jan Skibinski <[EMAIL PROTECTED]> writes:
> > For tar_x, tar_xv, tar_v kind of things people
> > invented objects, recognizing that "tar -x" 
> > approach is not a user friendly technology.
> 
> Oh?  You realize there are Unix weenies on this list, don't you?
> Cryptic commands with equally cryptic options is very user friendly
> for an interactive command line.

The emphasis there should be on _interactive_.

An interactive command line tool and a programming language intended
for writing non-trivial applications have very different requirements.
For the former, brevity may well be more important than readability,
but for the latter it is definitely the other way around.

-- 
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: mode argument

2000-06-02 Thread Fergus Henderson

On 01-Jun-2000, Ketil Malde <[EMAIL PROTECTED]> wrote:
> Fergus Henderson <[EMAIL PROTECTED]> writes:
> 
> >> Again, `Positive' would not do, it should be something like  
> >> QuotRem_Positive, and so on.
> 
> > This is a problem with Haskell, IMHO.
> 
> > Mercury allows overloading of constructor names, so in Mercury you
> > could use just `Positive' rather than `QuotRem_Positive'.  The type
> > checker will resolve the ambiguity whenever possible.
> 
> How will the type inferencer figure out the type if it isn't declared
> explicitly? 

Well, the type inferencer considers all possibilities and eliminates
those that are not type-correct.  Often only one possibility remains.

If, for example, you write

data Foo = Positive | Negative
data Bar = Sure | Certain | Positive

f Positive = 1
f Negative = -1

g = f Positive

then the type inference can easily infer that `f' has type `Foo -> ...'
rather than `Bar -> ...', since otherwise the second clause of `f'
would not be type-correct.  From the type that it infers for `f',
it can then infer that the occurrence of `Positive' in the definition
of `g' has type `Positive'.

In the cases that we were considering, namely mode arguments for
functions in the standard Prelude, the Prelude would contain type
declarations for those functions anyway, so if you write

h = Prelude.func Positive

then the type inference can figure out the type of `Positive'
in the definition of `h' from the type declaration for `Prelude.func'.

-- 
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: unsafeinterleaveIO

2000-06-01 Thread Fergus Henderson

On 01-Jun-2000, Antti-Juhani Kaijanaho <[EMAIL PROTECTED]> wrote:
> 
> Like there is no way in Haskell 98 to access OS services beyond a certain
> subset, there is no way in C90 or C99 to access OS services beyond a
> certain subset.  Haskell's subset is actually larger than C's.
> 
> Like Haskell, C has no provisions for accessing code written in other
> languages.
>
> In both languages, if you want to access OS services beyond the
> standardized subset, or if you want to access code written in other
> languages, you need to go beyond the standard and use some things that
> make your programs a little more unportable.

That may be true in some theoretical sense, but in the
real world there are a zillion C libraries like OpenGL, Xlib, etc.,
which have already been ported to all the systems of interest,
and which can be trivially accessed from C.  Furthermore,
these libraries are portable between different C compilers.
For Haskell, there is currently no way of accessing OpenGL, for
example, that is portable between different Haskell compilers.

> Understand this: I am not against improving the FFI of the Haskell
> systems or making their FFIs compatible.  My point is that making the
> FFI part if the language is not necessarily necessary.

In today's world it is often very difficult to write complete
applications in a single language, especially if you want to
use a nice high-level language like Haskell.  The need to make
use of existing libraries written in other languages is so common
that a language which does not provide portable support for this
is severely lacking.  It's not enough to provide non-portable
ways of doing this; that just locks programmers into using a
single implementation.

This need has been recognized by modern programming languages
and modern programming language standards.  The ISO Ada 95 standard,
for example, specifies standardized interfaces from Ada to C, Fortran,
and COBOL.  The 1998 ISO C++ standard requires C++ implementations to
support a C interface.  The Fortran standardization committee have
been working on a standardized interface between Fortran and C
(I don't know the current status of that).  For Java, the Java
Native Interface (JNI) provides a standard interface to C.
For Mercury, the Mercury language reference manual specifies
a C interface that all Mercury implementations must support.

I strongly urge that a standard FFI should be seen as an important
goal for Haskell-2.  If Haskell does not have a standard FFI, then
programmers who are concerned about not being locked into a single
compiler will turn to other languages that do have a standard FFI.

-- 
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: mode argument

2000-05-31 Thread Fergus Henderson

On 01-Jun-2000, S.D.Mechveliani <[EMAIL PROTECTED]> wrote:
> Why people do not complain on the mode argument outside of Haskell:
>  `zip -r ...'  `unzip -t xxx.zip'  `tar xvfz xxx.tar.gz'
> ?

People do indeed complain about Unix's habit of using cryptic option
sequences like `-r', `-t' or `xvfz'.  Why do you thing long options
(e.g.  `--recursive', rather than `-r') were invented?

Short options like `-r' are useful for interactive use.
But if you're programming (e.g. writing shell scripts),
then you really ought to use the long versions instead,
since it makes the code much more readable.

Unfortunately for historical reasons the long options are not as
portable as the short options, for many standard Unix commands.
But hopefully that will change over time.

> Patrik Jansson <[EMAIL PROTECTED]> writes on 31 May 2000 
> 
> J> On the contrary - you only need one character N instead of threee 'n' if
> J> you use a datatype with two constructors N and (whatever you like for
> J> the other case).
> J> But the length of the argument is not that interesting here - you can have
> J> long names for the constructors of the "mode" datatype and still use short
> J> local abbreviations. 
> 
> 'n' :: Char  does not hold a name in the constructor name space.

Yes, but it is also far from self-expanatory.  With a constructor
name, in a suitable environment you could just click on the
constructor name and the environment would immediately pop up the
declaration and documentation for that constructor and the type that
it belongs to.  Such an environment need not be particularly
sophisticated, e.g. the tags support in vim and Emacs is sufficient.
But with `Char', it would be much much more difficult.
Including `Char' in a function signature provides no information
for the user about what the meaning of that argument is.
It is IMHO bad style.

> And `N' hardly would do. There may be many other constructors wanting 
> short names.
> Suppose there are about 10 functions to provide with the mode.
> It will looke like this
>  
>   quotRem :: ...=> Mode_quotRem -> a -> a -> (a,a)
>   sortBy  ::   Mode_sort -> Comparison a -> [a] -> [a]
>   ...
>   data ModeQuotRem = QuotRem_minRem | QuotRem_positive | QuotRem_other
>  deriving(Eq,Ord,Enum,Show,Read)
>   -- contrived
> 
>   data Mode_sort = Sort_quick | Sort_merge | Sort_insert | Sort_other 
>deriving(Eq,Ord,Enum,Show,Read)
>   ...
> Again, `Positive' would not do, it should be something like  
> QuotRem_Positive, and so on.

This is a problem with Haskell, IMHO.

Mercury allows overloading of constructor names, so in Mercury you
could use just `Positive' rather than `QuotRem_Positive'.  The type
checker will resolve the ambiguity whenever possible.  Note that if
such a constructor was used as the first argument of a function like
the `quotRem' and `sortBy' functions you've declared above, there
would be no ambiguity.

> For example, my program contains many expressions like
> 
>  f x y b = myRem 'c' ((myRem '_' x b)*(myRem '_' y b)) b
> 
> Now, it has to be, maybe,   remP  = rem QuotRem_positive
> remO  = rem QuotRem_other
>     f x y = remP ((remO x b)*(remO x b)) b
> Maybe,  Char  is better?

No, IMHO Char would definitely not be better.
In this case, I think separate functions would be best,
a single function with a properly typed mode argument second best,
and a single function with a `Char' mode argument worst.

-- 
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: unsafeinterleaveIO

2000-05-30 Thread Fergus Henderson

On 30-May-2000, George Russell <[EMAIL PROTECTED]> wrote:
> Fergus Henderson wrote:
> > (If nothing at all can be guaranteed, then no-one should be using those
> > features, and they should be removed from the Hugs/ghc extension libraries.
> > But it should be possible to make some guarantees.)
> What on earth is a guarantee?  GHC is a research project.  I don't expect to
> be able to sue Microsoft or the University of Glasgow [...]

I was not talking about a legal guarantee.
Just some documentation that explains the intended specification.

Providing library procedures without providing a specification
for them is fundamentally bad practice.

-- 
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: unsafeinterleaveIO

2000-05-30 Thread Fergus Henderson

On 30-May-2000, George Russell <[EMAIL PROTECTED]> wrote:
> "Ronald J. Legere" wrote:
> > 
> > SUMMARY: How about a supplement to the standard that contains the
> >   'standard' extensions that everyone uses.
> One problem I have with this is that "unsafe" operations, being unsafe,
> are difficult to fit in with the rest of the language.  For example
> a common use of unsafePerformIO is to set up global variables:
> 
> counter :: MVar Int
> counter = unsafePerformIO(newMVar 0)
> 
> What exactly does this mean?  I presumably want only one counter for the
> whole program.  But what is a program?  Suppose "counter" is declared as
> part of a "where" clause in a bigger function.  Is the compiler allowed 
> to lift it so that there is only one counter, or should it create only one?
> And so on.  I think the current situation, where such functions are only
> supplied as extensions with "caveat emptor" implied, is probably best.

I have to say that the current situation, where the Hugs/ghc
documentation for these features is worse than non-existent,
is certainly far from the best imaginable.  The Hugs/ghc implementors
should bite the bullet and explicitly document exactly what is
guaranteed about the behaviour of these features.  Likewise for the
implementors of any other Haskell implementations which support such
features.

(If nothing at all can be guaranteed, then no-one should be using those
features, and they should be removed from the Hugs/ghc extension libraries.
But it should be possible to make some guarantees.)

-- 
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: import List(..)

2000-05-22 Thread Fergus Henderson

On 22-May-2000, Koen Claessen <[EMAIL PROTECTED]> wrote:
> I think there are two separate issues here:
...
>   2. Syntactic sugar which is translated away using prelude
>  functions.
...
> Issue number 2 is completely different and unrelated. Note
> that this also includes normal prelude functions without
> special syntax (such as >>=, return, mfail, fromInteger,
> etc.). What happens in general when one uses this special
> notation in a module which redefines these operators? I
> think the easiest thing to do is just to make the
> translation *always* refer to their prelude definitions.

That may well be the *easiest* thing to do, but the question
we should be asking is what is the *best* thing to do.
The easiest thing has been tried already, and -- dare I say it --
found wanting!

-- 
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: import List(..) ?

2000-05-21 Thread Fergus Henderson

On 21-May-2000, Marcin 'Qrczak' Kowalczyk <[EMAIL PROTECTED]> wrote:
> Sun, 21 May 2000 17:26:13 +1000, Fergus Henderson <[EMAIL PROTECTED]> pisze:
> 
> > But being able to import and/or re-export such symbols is necessary
> > if you want to be able to implement an alternative prelude.
> 
> No: they can be simply always available, just as \ and let.

OK, I guess that would work too.

Just to elaborate a little: with this suggestion, I suppose the
following module would be legal:

module Foo(List, nil, cons) where
import Prelude ()
type List t = [t]
nil = []
cons = (:)

Neither Hugs nor ghc currently allow this; Hugs complains about `:'
being undefined (but allows it if the definition of cons is replaced
with e.g. `cons = cons'), while ghc complains about both `:'
and `Prelude.[]' not being in scope.

But looking at the Haskell report, I think your suggestion looks
like it is the correct interpretation of the current wording,
and Hugs and ghc are wrong.  The current wording is as follows:

 | 5.5.3  Closure
 | 
 |Every module in a Haskell program must be closed. That is, every name explicitly 
 |mentioned
 |by the source code must be either defined locally or imported from another module.
 |Entities that the compiler requires for type checking or other compile time 
 |analysis need
 |not be imported if they are not mentioned by name.

Note that `:' and `[]' are not names (see 2.4).

P.S.
On a related note, Hugs and ghc both allow the following module

module Bar(List(..)) where
type List = []

without complaint, but according to the Haskell report (5.2) the
syntax `(..)' should only be used for algebraic data types,
not for type synonyms.

-- 
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: import List(..) ?

2000-05-21 Thread Fergus Henderson

On 21-May-2000, Marcin 'Qrczak' Kowalczyk <[EMAIL PROTECTED]> wrote:
> Sat, 20 May 2000 13:13:22 -0700, Simon Peyton-Jones <[EMAIL PROTECTED]> pisze:
> 
> > Explicit lists [a,b,c]
> > List comprehensions
> > Numeric constants (1 means 'fromInteger 1')
> > do notation
> > 
> > Here is an idea for an extension to Haskell 98 to support this.
> [...]
> 
> It has small problems (and IMHO nobody should need to replace the
> list type etc.).
> 
> What about string literals - do they refer to Prelude list type or
> the replacement?

For consistency, I would recommend the latter.

> The first is a bit inconsistent, the second does
> not allow optimizations.

Why do you say the second does not allow optimizations?
Surely the compiler can perform exactly the same optimizations,
if it just makes those optimizations conditional on this feature
not being used.  If you don't use the feature, you don't pay for it!

Of course a compiler could also do better, and perform the same
kind of optimizations even if an alternative prelude was used,
so long as those optimizations still make sense.  That might be a
little more difficult to implement, since the optimizations would have
to be done in a slightly more general way.  But I don't see it
as being infeasible.

> If list comprehensions are translated literally as the report says,
> they don't allow optimizations too, unless the compiler is smart
> enough to optimize the translation. Currently GHC does not optimize
> concatMap (\x -> [x]) into identity.

The issue here is the same.  GHC can do exactly the same optimizations
it currently does, if it just makes them conditional on this feature
(the `{#- SYNTAX -#}' pragma, or whatever syntax is chosen for it)
not being used.  If the feature is used, then it would have to use
the translation in the report, and then optimization might be a bit
harder; but optimization is still possible, it's just a quality of
implementation issue.

> If the programmer says:
> data [a] = () | a:[a]
> data ()  = []
> is [1,2,3] a type error (because it gets translated to 1:2:3:[])?
> 
> If he says:
> data X= Int:Stop
> data Stop = []
> is [1] permitted?
> 
> Is this permitted:
> type (,) = Prelude.[]
> type [] = Either
> f :: (,) ([Int] String)
> f = [Left 5, Right "foo"]

So far no-one has proposed allowing special symbols such as `[]',
`()', or `:' in definitions -- only in import and export lists.
So with the current proposals, those examples would all be
syntax errors.

Unless someone can suggest a good reason why there would be some
benefit in allowing people to define those symbols, I see no reason to
do so.  But being able to import and/or re-export such symbols is
necessary if you want to be able to implement an alternative prelude.

> Must the type of Main.main be Prelude.IO something, or it can be a
> replacement of IO? The latter does not have a semantics, so it must
> be the former.

Right.  But an alternative prelude could define a function 

run :: AltPrelude.ReplacementForIO t -> Prelude.IO t

and then `main' could be defined using `run'

main = run (...)

so I don't see that as being a problem.

-- 
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: import List(..) ?

2000-05-20 Thread Fergus Henderson

On 20-May-2000, Simon Peyton-Jones <[EMAIL PROTECTED]> wrote:
> Of course, that doesn't solve the problem!  Sergey essentially wants to
> replace the entire prelude, special syntax and all.  There are lots
> of small but important things under the heading of special syntax:
> 
>   Explicit lists [a,b,c]
>   List comprehensions
>   Numeric constants (1 means 'fromInteger 1')
>   do notation
> 
> Here is an idea for an extension to Haskell 98 to support this.  Suppose
> we added a pragma, or compiler flag, that let us say where the special
> syntax should come from:
> 
>   module M where
>   import Prelude ()
>   import {-# SYNTAX #-} MyPrelude
> 
> Here, I've expressed it as a pragma.  The idea is that wherever we have
> a special syntax think, like [Int], it means 'S.[] Int', where S is
> either 'Prelude' or, if there's a SYNTAX pragma, the module specified
> in the pragma.
...
> I don't think this would be too hard to implement in GHC.  Now I think
> about it, it's rather attractive. I wonder what other people think?

I like this proposal.  I'm not rapt about the particular syntax you've
chosen for it, though.  I think I'd prefer something that was part
of the language syntax proper, rather than a pragma.  Perhaps

module M where
import Prelude ()
import syntax MyPrelude

where `syntax' here would be treated as a special-id (like `qualified')?

Or how about just

module M where
import prelude MyPrelude

?

> That module had jolly well better export all the things
> needed to support special syntax (which we'd need to enumerate). 

It may be best to check that requirement lazily: the module would only
be _required_ to export the things needed for those parts of the
syntax which the importing module actually uses.  This would make it
easier to develop an alternative prelude in a step-by-step manner.

> Note that if we chose to do this, we'd want the ability to have '[]' in
> export lists, so that MyPrelude was able to explicitly export '[]', so that
> the SYNTAX lookup would find it.  So we'd also have to extend the syntax of
> import and export lists as Fergus suggests.  But this facility would only
> be useful for (the) module intended to be imported with {-# SYNTAX #-}

Another alternative to this would be to simply define the `[]' and
`:' constructors as syntactic sugar for `ListNil' and `ListCons', and to
define the `[]' list type constructor as just syntactic sugar for `ListType'.
The list type could then by defined in the Prelude using ordinary Haskell
syntax:
data ListType t = ListNil | ListCons t (ListType t)
Then these symbols could be mentioned in import and export lists using
the existing syntax.

I don't have any particular preference as to which of those two solutions
is adopted, but I thought the alternative worth mentioning.

-- 
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: how to replace Num.fromInteger 2

2000-05-20 Thread Fergus Henderson

On 20-May-2000, Marcin 'Qrczak' Kowalczyk <[EMAIL PROTECTED]> wrote:
> Sat, 20 May 2000 20:45:47 +1000, Fergus Henderson <[EMAIL PROTECTED]> pisze:
> 
> > For the next version of Haskell, I propose changing the wording to
> > 
> >   The integer literal i is equivalent to fromInteger i.  Normally
> >   fromInteger is a method in the standard Prelude class Num (see Section
> >   6.4.1), but it is also possible for modules to use `import qualified
> >   Prelude' and then define their own fromInteger function or method,
> >   or import fromInteger from another module.
> 
> Such breakage of lexical scoping is generally dangerous and bad
> language design (like using C preprocessor); not because it is a
> change, but in itself.
> 
> I would be disappointed if code like:
> bad x = -x
> where
> negate = ...
> did not use standard meaning of unary negation.

You raise a good point about accidental redefinition for cases like this.
But the current definition of Haskell doesn't just prevent accidental
redefinition, it also prevents deliberate redefinition.  Wouldn't it
be better if we could somehow allow deliberate redefinition, so people
like S.D.M. could design alternative preludes, while still preventing
all or at least almost all cases of accidental redefinition?

I think it would.

One way to achieve this would be simply to define all the syntactic
constructs to expand to calls to functions with a long prefix that
people are unlikely to define accidentally.  For example, rather
than defining the `do' syntax to call `>>' directly, it could be
defined to call say `__builtin_do_syntax__BIND__', which would
be defined in the standard Prelude to call `>>'.
Similarly, unary minus could be defined in terms of
`__builtin_negation_syntax__NEGATE__', which would be defined
in the standard Prelude to call `negate'.

I understand why you would be disappointed if code like

 bad x = -x
 where
 negate = ...

did not use standard meaning of unary negation.
But if the code looks like

 bad x = -x
 where
 __builtin_negation_syntax__NEGATE__ = ...

then it's much more obvious that something funny is going on here.
If you would still complain about this, I would say that it is a small
price to pay in order for people to be able to define alternative
preludes.

-- 
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: how to replace Num.fromInteger 2

2000-05-20 Thread Fergus Henderson

On 20-May-2000, Marcin 'Qrczak' Kowalczyk <[EMAIL PROTECTED]> wrote:
> Sat, 20 May 2000 20:45:47 +1000, Fergus Henderson <[EMAIL PROTECTED]> pisze:
> > This is somewhat ambiguous; if it is really intended that unary -
> > always refer to the negate function define in the Prelude, it really
> > ought to be written as
> > 
> >   The special form -e denotes prefix negation, the only prefix operator in 
>Haskell , and is
> >   syntax for Prelude.negate (e).
> >  
> 
> IMHO it is better to state that all such names mentioned in the report
> refer to Prelude versions, than to clutter the report with explicit
> Prelude qualification everywhere.

Looking at the report again, I see that in fact it does do this:

 | 3  Expressions
 | 
 |In this section, we describe the syntax and informal semantics of Haskell 
 |expressions,
 |including their translations into the Haskell kernel, where appropriate.
 ...
 |Free variables and constructors used in these translations refer to entities
 |defined by the Prelude. To avoid clutter, we use True instead of Prelude.True or 
 |map
 |instead of Prelude.map. (Prelude.True is a qualified name as described in Section 
 |5.3.)

So I retract that criticism.
Sorry, I didn't notice that section of the report first time around. 

-- 
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: how to replace Num.fromInteger 2

2000-05-20 Thread Fergus Henderson
7;) on the arguments to be
monads.  As Haskell currently stands there is no way to use the monad
syntax for such types, even though it would make good sense to do so.
So again, for the next version of Haskell I propose the wording
be changed to make it clear that the `>>' and `>>=' in the translation
for `do' expressions need not refer to the methods defined in the
standard Prelude.

Comments?

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




  1   2   3   4   5   >