Three points Richard is missing are (1) the issue of what to do with the values are you are assembling them. One of the arguments for the create-set-call style that Richard is missing is that people don't like to have to invent a bunch of local variables to hold the parameters if they have to be computed in advance, or computed in a particular order. The users in the study preferred to set them directly into the object as they are calculated.
Another issue (2) reported in the article is that the assumption that having the parameters required at object creation time assures that the object is always valid and that the implementer can then avoid checking things is flawed, because programmers send in invalid values, or send in valid values that become invalid later. So the object must always be checking its fields' values at runtime anyway. So why not ALLOW users to create the object empty and fill it up as values are calculated. o = new Obj(n: NIL; size: 0, name: "") or o = new Obj(n: param1_val, ...); destroy param1_val; use o; Finally, (3) the article (as well as our similar articles), discuss WHAT REALLY HAPPENS in the field, and how people think, which is only somewhat influenced by the particular language features. Thus, I disagree that the study is not relevant to C#4.0 or other languages. Brad A. Myers Professor Human-Computer Interaction Institute School of Computer Science Carnegie Mellon University 5000 Forbes Avenue Pittsburgh, PA 15213-3891 (412) 268-5150 FAX: (412) 268-1266 b...@cs.cmu.edu http://www.cs.cmu.edu/~bam -----Original Message----- From: Richard O'Keefe [mailto:o...@cs.otago.ac.nz] Sent: Wednesday, March 28, 2012 10:10 PM To: John Daughtry Cc: Steven Clarke; Brad Myers; Raoul Duke; Ppig-Discuss-List Subject: Re: studies of naming? On 29/03/2012, at 1:50 AM, John Daughtry wrote: > > You introduced a third option. However, it is a deviation of the implementation behind the interface as opposed to an alternative interface. I introduced at least three alternative options. The first of those was what *in practice* create-set-call seems to turn into. I am not sure what you mean by "a deviation of the implementation". Can you rephrase that? > Are you suggesting that every API study should consider all of the limitless alternative implementations? No. The paper covered what it covered; it covered that pretty well; the more options you consider the harder (time, people, thinking, money) it gets to do an experiment. What I'm saying is that a study with an extremely limited range of alternatives gets to make extremely limited claims. The idea of naming parameters in a call goes back to Algol 60, making the idea at least fifty years old. I note that modern languages with keyword parameters include Fortran 95 and >> C# 4.0 <<. > Perhaps I misunderstood the design alternative you suggest as the third option. > > Your further discussion (e.g., initializer objects) supports the notion that any attempt to achieve both usability and robustness is tedious and laborious in dominant languages. I just discovered that 'initializer objects' has a name already: Builder. (It's not clear that they are the same, but the essential point that an incompletely initialised object is never *exposed* remains.) I am having a little trouble believing your claim that my discussion supports the idea that doing it right is 'tedious and laborious in dominant languages'. VB.net and C# 4 have keyword parameters and optional parameters. To return to > new FileStream(String, FileMode, FileSystemRights, > FileShare, Int32, FileOptions) it should be possible to do new FileStream(name: aString, mode: aMode, rights: someRights, share: aSharing, bufferSize: anInt, options: someOptions) *if* the constructor had suitable documented argument names. The arguments can be ordered freely (that's what keyword arguments are all about) and C# 4.0 has optional parameters, so you only need to supply the ones with non-default values, and all told, it is really REALLY hard to see how this could be in the slightest way justly called tedious or laborious. Compare inp = new FileStream( name: 'foo/bar', mode: FileMode.Open, rights: FileSystemRights.ReadData + FileSystemRights.ReadExtendedAttributes, share: FileShare.None, bufferSize: 64*1024, options: FileOptions.RandomAccess); with inp = new FileStream('foo/bar', FileMode.Open); inp.SetRights(FileSystemRights.ReadData + FileSystemRights.ReadExtendedAttributes); inp.SetShare(FileShare.None); inp.SetBufferSize(64*1024); inp.SetOptions(FileOptions.RandomAccess); I am, of course, assuming for the sake of argument that C# counts as a "dominant language". I am no admirer of Microsoft or its works, and have been sniggering happily at the reception of Windows 8. But C# is very definitely a better Java than Java. (And of course it's a better C# (now) than C# (was) -- the book I was learning C# from only covers C# 2.0.) I definitely think that it is safe to say that a study that did not cover a parameter style possible in C# 4.0 is no longer a good basis for guiding API design in C#. The presence of keyword arguments in a language makes a *huge* difference to API design: in particular a good choice for a keyword name is _not_ necessarily a good choice for a local variable holding the same information. Prepositions can be good keyword parameter names; seldom or never can they be good variable names. (Yes, we are still on topic.) -- The Open University is incorporated by Royal Charter (RC 000391), an exempt charity in England & Wales and a charity registered in Scotland (SC 038302).