First class labels
claus.reinke at talk21.com
Fri Feb 10 07:48:27 EST 2006
thanks for the questions. I'll try to clarify.
>... For example, what does it mean to "remove the need to
>declare labels, make them identifiable as such in use"?
implicit label declarations, basically.
the code for records I posted depends on any two field labels being
distinguishable by type. to get readable records, we want something
like typed constants, e.g.:
data LabelX = LabelX deriving (..)
but all these declarations will be the same, apart from the label name,
so if we had syntactic means to see that something is a label, and the
only inhabitant of its type, there'd be no need for these declarations.
for the sake of discussion, let us assume that we reserve a '#' prefix
before identifiers and types to single them out as label-related.
then we'd know (without explicit declaration) that
#labelX :: #LabelX
why would that be interesting? that brings us to your second issue:
>Then, the code that you enclosed appeared to show that you could
>do without any extension at all.
the code establishes a context for the proposal, nothing more.
the code demonstrates that there are record system variants that we
can implement without any new language extensions. but it could not
be used in practical, multi-module situations, because of the need to
declare those label types.
if we have two modules, A and B (think ...OpenGL and some GUI
library), that both want to use records with fields named 'pointX',
they'd both have to declare the field label as
data PointX = PointX deriving (..)
now, if we ever want to import A and B into the same module C
(think OpenGL windows in a GUI), we are in trouble, because we
have two "conflicting" declarations for PointX. at the moment, that
means that we have two ways out
- either use qualified names in C: A.PointX and B.PointX;
this is awkward, to say the least, and still doesn't let us
identify what should be two instances of the same field
name, forcing upon us superfluous conversions
- or modify the imports: introduce a new module PointX that
declares PointX, and have both A and B import that;
this is impractical: it breaks module composition, and there
is no least upper bound in the import hierarchy where we
can safely place our label declarations once and for all
which brings us to your final suggestion:
>Records are a huge swamp with a very large number of possible variants
>and design choices. Perhaps you might gain more traction if you were
>ruthlessly specific about what language changes you advocate, and what
>benefits they would have (versus the existing situation).
I was trying to single out a minimal extension that might help to steer
around that swamp (which seems to be the undeclared intention for
Haskell'?), while still providing the means for making progress wrt
a better record system for Haskell'. I was explicitly _not_ suggesting
to build any new record system variant into the language.
the code shows by example what is possible without new extensions
while also highlighting issues that are not easily addressed without new
extensions (and making old extensions official parts of the language).
the concrete proposal is to address one of these remaining issues,
namely how to identify record field labels as such. for that, I outlined
three options, although that outline perhaps wasn't concrete enough:
1. make label declarations unneccessary (eg., #pointX :: #PointX)
2. make type sharing expressible (something like the sharing
constraints in Standard ML's module language, to allow you to
say when two declarations from different imports refer to the
3. introduce a least upper bound for shared label imports
(so A and B could just 'import Data.Label(pointX)', which
would magically provide the shared declaration for pointX)
does that clear things up a bit? if anyone still has questions,
More information about the Haskell-prime