[Haskell-cafe] Re: [Haskell] Top Level <-

Ganesh Sittampalam ganesh at earth.li
Tue Sep 2 16:19:32 EDT 2008


On Tue, 2 Sep 2008, Ashley Yakeley wrote:

> Ganesh Sittampalam wrote:
>> I have a feeling it might be non-trivial; the dynamically loaded bit of 
>> code will need a separate copy of the module in question, since it might be 
>> loaded into something where the module is not already present.
>
> Already the dynamic loader must load the module into the same address 
> space and GC, i.e. the same runtime. So it should be able to make sure 
> only one copy gets loaded.

I don't think it's that easy, modules aren't compiled independently of 
each other, and there are lots of cross-module optimisations and so on.

> What is the status of dynamic loading in Haskell? What does hs-plugins 
> do currently?

I don't know for sure, but I think it would load it twice.

In any case, what I'm trying to establish below is that it should be a 
safety property of <- that the entire module (or perhaps mutually 
recursive groups of them?) can be duplicated safely - with a new name, or 
as if with a new name - and references to it randomly rewritten to the 
duplicate, as long as the result still type checks. If that's the case, 
then it doesn't matter whether hs-plugins loads it twice or not.

>> Let's suppose some other module uses a <-, but returns things based on that 
>> <- that are some standard type, rather than a type it defines itself. Is 
>> module duplication still safe?
>
> In this case, duplicate modules of different versions is as safe as 
> different modules. In other words, this situation:
>
>  mypackage-1.0 that uses <-
>  mypackage-2.0 that uses <-
>
> is just as safe as this situation:
>
>  mypackage-1.0 that uses <-
>  otherpackage-1.0 that uses <-
>
> The multiple versions issue doesn't add any problems.

Agreed - and I further claim that duplicating the entire module itself 
can't cause any problems.

>> Well, let me put it this way; since I don't like <-, and I don't 
>> particularly mind Typeable, I wouldn't accept IOWitness as an example of 
>> something that requires <- to implement correctly, because I don't see any 
>> compelling feature that you can only implement with <-.
>
> Why don't you like <-? Surely I've addressed all the issues you raise?

I'm still not happy that the current specification is good enough, 
although I think this thread is getting closer to something that might 
work.

Even with a good specification for <-, I would rather see the need for 
"once-only" state reflected in the type of things that have such a need.

> There is an obligation regarding dynamic loading, but it looks like 
> dynamic loading might need work anyway.

I think the obligation should be on <-, and the obligation is the 
duplication rule I proposed above.

> Since this is a matter of aesthetics, I imagine it will end with a list of 
> pros and cons.

Agreed.

>> There's some unsafety somewhere in both Typeable and IOWitnesses, and in 
>> both cases it can be completely hidden from the user - with Typeable, just 
>> don't let the user define the typeOf function at all themselves. 
>
> It's worse than that. If you derive an instance of Typeable for your 
> type, it means everyone else can peer into your constructor functions 
> and other internals. Sure, it's not unsafe, but it sure is ugly.

True. I would argue that this is better solved with a better typeclass 
hierarchy (e.g. one class to supply a witness-style representation that 
only supports equality, then the typereps on top of that if you want 
introspection too).

>>> Sometimes you want to do witness equality tests rather than type equality 
>>> tests. For instance, I might have a "foo" exception and a "bar" exception, 
>>> both of which carry an Int. Rather than create new Foo and Bar types, I 
>>> can just create a new witness for each.
>> 
>> This is precisely what newtype is designed for, IMO. We don't need another 
>> mechanism to handle it.
>
> It's not what newtype is designed for. Newtype is designed to create 
> usefully new types. Here, we're only creating different dummy types so 
> that we can have different TypeRep values, which act as witnesses. It's 
> the TypeReps that actually do the work.

newtype is frequently used to create something that you can make a 
separate set of typeclass instances for. This is no different. You can 
argue that this use of newtype is wrong, but there's no point in 
just providing an alternative in one specific case.

Ganesh


More information about the Haskell-Cafe mailing list