
The issue about ‘*’ seems to be this
* We need a way to write down the kind of types. E.g. Int :: ???
What is the “???”
· There are several possibilities
1. Continue to use * as built in syntax. It’s a massive wart; you can’t write (*->*) because GHC thinks that’s a single lexeme; and * is a terrifically useful infix operator, so stealing it is horrible. I’m sure we would never do this today.
2. Import a module Data.Type to bring Type into scope using the normal module scoping mechanism.
* Advantage: no new special things
* Disadvantage: an extra import; and error messages might say Data.Type.Type fully qualified if you didn’t have the import.
3. Same, but export Type from Prelude.
* Advantage: no need for that special import
* Disadvantage: would break existing programs that define Type, and import Prelude, regardless of flags.
I suppose we could say that you only get Type from Prelude if -XTypeInType is also on, but that IS new (and ad hoc) mechanism.
4. Define Type as a new keyword (with TypeInType). It does not need to be imported; it cannot be overridden or redefined. (Just like (->).)
* A variant of this (which I quite like) is to use the existing keyword type (lowercase).
* Advantage: simple clear story
* Note: won’t break existing code; only code that says TypeInType
Is that a fair summary of the design space?
Simon
From: Iavor Diatchki [mailto:iavor.diatchki@gmail.com]
Sent: 09 February 2018 17:47
To: Simon Peyton Jones
On Feb 1, 2018, at 8:58 PM, Joachim Breitner
mailto:mail@joachim-breitner.de> wrote: In particular in light of our use of “type” as a explicit namespace token – so far in export and import lists and fixity declarations – I worry that we will prevent ourselves from using more such explicit namespace things in the future.
This is a really good point. In private musings, I've often wondered about using the keyword `type` in expressions to denote a namespace change. More concretely, I'm worried about the Dreaded Namespace Problem (DNP): that is, a dependently typed language does not want to have separate type-level and term-level namespaces. Of course, Haskell has this. The best solution I have so far to the DNP is to introduce a *new* namespace, distinct from the two namespaces we have so far. Let's call it the "default" namespace. When -XDependentTypes is on, the default namespace is in effect. Name lookup looks first in the default namespace. If that fails the namespace consulted next depends on context: the "data" namespace in terms and the "type" namespace in type signatures. (This last bit needs to be specified more concretely, but you get the idea.) Or, perhaps, a failed lookup in the default namespace will look up in both the type and data namespaces, erroring if a name appears in both. If a user wants to specify a namespace directly, they have a very easy way to do so: `type Foo` will look in the type namespace, `data Foo` will look in the data namespace, and `default Foo` will look in the default namespace. :) Because these keywords make sense currently only at the beginning of a line, this Just Works. I also imagined these constructs could scope over a subexpression: `type (T S)`. All of this deserves a proper proposal and it's too early for that proposal. Nevertheless, I'm grateful that Joachim said something here, given that adding `type` as a spelling of `Type` would invalidate this approach. I also am swayed by the fact that `Type` isn't fully primitive, and making a keyword mean something that's not primitive is a bit awkward. I thus retract this proposed alternative and will update the proposal accordingly. Richard _______________________________________________ ghc-steering-committee mailing list ghc-steering-committee@haskell.orgmailto:ghc-steering-committee@haskell.org https://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-steering-committee