Opened 9 years ago

Last modified 4 years ago

#4479 new feature request

Implement TDNR

Reported by: gidyn Owned by:
Priority: low Milestone:
Component: Compiler (Type checker) Version: 7.5
Keywords: ORF Cc: griba2001@…, adamgundry
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Test Case:
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:

Description (last modified by gidyn)

A request to implement TDNR.

Change History (32)

comment:1 Changed 9 years ago by simonpj

You are the first person to ask for TDNR! Generally the proposal elicited approximately zero reaction, somewhat to my surprise. Personally I like the idea very much, but it's a significant implementation task, and of course an ongoing maintenance load. So I'm only going to do it if there's a significant body of support. The more support you can drum up the better. Adding some notes about why you like it (ie how it'd help solve your problem) would help to substantiate the motivation.


comment:2 Changed 9 years ago by migmit

I strongly dislike this idea. Using two functions of the same name creates confusion and leads to countless times of trying to figure out why an incorrect version compiles (it's using the wrong function), but a corrected one doesn't (it still contains bugs).

One of the reasons I love Haskell is that it's very clean and readable, and this proposal, if approved, would make it significantly less readable.

comment:3 Changed 9 years ago by simonpj

Don't type classes have exactly the same problem (and benefit)?

comment:4 Changed 9 years ago by migmit

Nope. What I am talking about is accidental name clash, poorly resolved; with type classes, it's never accidental.

comment:5 Changed 9 years ago by igloo

Personally, I'm not sure the extra benefit is worth the extra complexity in the language. Like you say, type classes have already solved a lot of the problem.

Also, I don't think it works well with multi-argument functions. I'd rather write

BS.append x y


x.append y

comment:6 Changed 9 years ago by igloo

Milestone: 7.2.1

comment:7 Changed 9 years ago by gabrielrf

Cc: griba2001@… added

I support it. I think that Haskell will gain a broader audience.

The data transformation sequence will be easier to understand in the reading direction

 xs .reverse .(filter isEven) .(map double)

than right-to-left as today in

 map double $ filter isEven $ reverse xs

comment:8 in reply to:  7 Changed 9 years ago by igloo

Well, you can do

xs .reverse .(filter isEven) .(map double)

today, without a GHC extension, by defining

x . f = f x

but most people don't.

In fact, I wonder if adding an obj.method style will be a hinderance to beginners, as it obscures what type inference can do. For example, if you are used to OO-style mySet.insert, then it may be less clear (or more magical) that an unqualified empty can be used for the empty set, with the type being inferred from the context.

comment:9 Changed 9 years ago by gidyn

Perhaps we can start off by implementing TDNR just for record accessors? That seems to be the greatest benefit, and the least controversial aspect.

comment:10 Changed 8 years ago by igloo

Priority: normallow

comment:11 Changed 8 years ago by gidyn


comment:12 Changed 8 years ago by AntC

For the record(!) there's been a long and convoluted thread around alternative proposals for the 'narrow namespacing issue' with Haskell 98's record system. The wiki page is here: (Some proposals are developments from TDNR, using more recent features in GHC.)

I agree with SPJ for raising the importance of dot notation for record access, and his observation about the thinking style this engenders of object -> access, rather than Haskell's function prefix style.

But I'm against the specifics of TDNR. In particular I think there should be only one variety of Type-Directed xxx Resolution in Haskell, and that should be the familiar class and instance mechanism. The Proposal says: "TDNR is not "overloading" in the sense of type classes". I think that'll be confusing.

H98 record selectors are functions. Record selection is therefore function application. TDNR proposes "The dynamic semantics of a.f is simply reverse application (f a)." I think dot notation should be just sugar for (reverse, tight-binding) function application, with the same semantics and the same instance resolution mechanism.

(Though I'm not going to 'die in a ditch' over which specific operator we use in the sugar. Since dot is currently function composition, there have been voiciferous requests to keep it so.)

So to be able to use the same field name (that is, selector function) in multiple record types, I'd be looking to overload the function. As SPJ notes, there are already GHC extensions (DisambiguateRecordFields and friends) for other use cases of same name/multiple record types.

comment:13 Changed 7 years ago by igloo


comment:14 Changed 6 years ago by guest

difficulty: Unknown

What's the estimated difficulty of implementing TDNR? I have for a long time been interested in this language feature in particular and now I'm about to start on my master's thesis, which is about a semester of dedicated work.

What got me so interested in this feature is that you have to repeat yourself in record syntax, like data MyRecord = MyRecord { myRecordLength :: Int, myRecordWidth :: Int} rather than just data MyRecord = MyRecord { length :: Int, width :: Int}. I found that frustrating and I wondered why nobody else have went ahead and implemented this language feature yet. Now I found myself with one semester of time to do something like this.

Is there any high-level sketch of the implementation on top of SPJ's head? Or is it still not clear which approach is best for doing type checking and name resolution at the same time?

Finally, if you think this is too difficult for a somebody who have not hacked ghc before. Would you suggest him to make a prototype in a smaller haskell compiler?

Best, Arash Rouhani rarash@…

comment:15 Changed 6 years ago by simonpj

Cc: adam.gundry@… added

See Records/OverloadedRecordFields/Plan. Adam is on this.


comment:16 Changed 6 years ago by gidyn

Replying to simonpj:

See Records/OverloadedRecordFields/Plan. Adam is on this.

"we propose no changes to dot syntax for the time being" Looks like Adam is specifically ignoring it?

Version 1, edited 6 years ago by gidyn (previous) (next) (diff)

comment:17 in reply to:  16 Changed 6 years ago by adamgundry

Replying to gidyn:

"we propose no changes to dot syntax for the time being" Looks like Adam is specific ignoring it?

I'm not ignoring TDNR so much as implementing an alternative solution to essentially the same problem, namely the desire to overload record field names. In fact, an earlier version of my proposal did suggest changing dot syntax, but quite a few people weren't keen on it, so the current plan is to leave dot alone for the time being. There is the possibility of treating dot as postfix function application.

comment:18 Changed 6 years ago by guest


That's fantastic that the record issue is being worked on as a GSoC project!


Thanks for doing this! How is it going? Do you have a blog with your progress or something for us to follow?

comment:19 Changed 6 years ago by adamgundry

I don't have anything as organised as a blog, but I'm keeping the page that Simon linked to updated with the design and implementation notes, and discussion of the proposal is happening on the glasgow-haskell-users list.

comment:20 Changed 5 years ago by thoughtpolice


Moving to 7.10.1.

comment:21 Changed 5 years ago by gidyn

Description: modified (diff)
Summary: Add Type Directed Name ResolutionImplement Dot as Postfix Function Apply

comment:22 Changed 5 years ago by thoughtpolice


Moving to 7.12.1 milestone; if you feel this is an error and should be addressed sooner, please move it back to the 7.10.1 milestone.

comment:23 Changed 5 years ago by gidyn

Cc: gideon@… removed

comment:24 Changed 4 years ago by thoughtpolice


Milestone renamed

comment:25 Changed 4 years ago by adamgundry

Cc: adamgundry added; adam.gundry@… removed

comment:26 Changed 4 years ago by thomie

Milestone: 8.0.1

comment:27 Changed 4 years ago by gidyn

There's a proposal for TDNR without syntax changes at SyntaxFreeTypeDirectedNameResolution.

comment:28 Changed 4 years ago by AntC

@gidyn, I don't see what that proposal has to do with dot as postfix function apply (?)

This dot as ... idea is not the same as in TDNR -- despite spj's first comment 6 years ago. Dot as ... is purely syntactic sugar for function apply, with type-directed resolution as per standard class/instance semantics.

There's already too many proposals for records (and related enablers), without mixing them up.

comment:29 Changed 4 years ago by gidyn

Description: modified (diff)
Summary: Implement Dot as Postfix Function ApplyImplement TDNR

Yes, Records/DeclaredOverloadedRecordFields/DotPostfix is orthogonal to type directed name resolution, although spj's original TDNR proposal included both.

This ticked was originally about TDNR, then wondered into DotPostfix as an add-on to ORF. As the dot notation has attracted a fair amount of controversy, and ORF only gives TDNR for records, I've brought up a proposal for TDNR over any function but without syntax changes.

Last edited 4 years ago by gidyn (previous) (diff)

comment:30 Changed 4 years ago by AntC

Then @gidyn, anybody reading this ticket is going to get totally confused -- as I am now. (That's why I'm replying here rather than privately.) Can you change the whole subject of a ticket like that? And then change it back much later? It's bound to invalidate a large proportion of the comments.

I would have thought much better to close this ticket; open new one(s) for TDNR and dot postfix.

For the record(!) again: TDNR includes two elements:

  1. using dot postfix to signal 'here comes a record label'.
  2. using type directed name resolution for that label at that use site.

But the DORF proposal is purely to use dot postfix as syntactic sugar for function apply. Its purpose is (somewhat) incompatible with TDNR point 1, although the syntactic behaviour for dot is the same.

As far as I can see, these two subjects should never have gotten on the same ticket.

comment:31 in reply to:  27 Changed 4 years ago by AntC

Replying to gidyn:

There's a proposal for TDNR without syntax changes at SyntaxFreeTypeDirectedNameResolution.

Hmm. That really is not up to being called a 'proposal'. Contrast its hand-waving with the careful detail in the original TDNR. I've added a couple of links to a ghc-users thread and to what Adam has just delivered in 8.0 DuplicateRecordFields. I think what Adam has delivered is a reasonable stab at the TDNR idea without changing any syntax. (I've made that point several times in the discussion.) I've not seen any detailed explanation that would disagree with that. (There is comment about the full ORF Part 3 Magic type classes.)

If it was my call, and assuming this ticket 4479 is about TDNR, I would close this as fixed by DuplicateRecordFields.

comment:32 Changed 4 years ago by adamgundry

Keywords: ORF added

gidyn, thanks for starting a new proposal. Your effort to push this along is appreciated!

I think your idea for doing TDNR without any syntax can indeed be seen as a proper generalization of DuplicateRecordFields, which permits syntaxless TDNR in the special case of record field names.

Unfortunately I tend to agree with AntC that the proposal needs more precision. We want to avoid the situation that the programs GHC accepts depend on implementation details of the type-checker. This means that we need a (possibly hypothetical) declarative specification of what the typing rules should be for ambiguous names.

Moreover, it's probably best if introducing or removing an ambiguity doesn't lead to different valid types for the same program. This implies that disambiguation should use information gleaned from the existing bidirectional typing rules, but not do additional inference. This requirement is why approaches based on deferring name resolution to the constraint solver, like ORF's magic classes, use a syntactic cue to indicate that the identifier should be treated specially.

These are tough goals to meet, and explain why the current DuplicateRecordFields is quite conservative in what it will accept (see #11343). No doubt it is possible to do something more general, but it's hard to specify, let alone implement. I think that is part of the reason that TDNR has languished over the years.

[AntC already mentioned this on the wiki page, but for future reference, this mailing list thread is very relevant:]

Note: See TracTickets for help on using tickets.