Re: studies of naming?
John, Given that many programmers have been trained to believe that opportunism is bad, it is also likely that observation of programming evokes Are many programmers taught anything and if they are does it go in one ear and out the other? I think most developers pick up a rag bag of habits that work. Also one thing about analyzing code is that you quickly learn that what developers say they do and what they actually do often have little in common. -- Derek M. Jones tel: +44 (0) 1252 520 667 Knowledge Software Ltd blog:shape-of-code.coding-guidelines.com Source code analysishttp://www.knosof.co.uk -- The Open University is incorporated by Royal Charter (RC 000391), an exempt charity in England & Wales and a charity registered in Scotland (SC 038302).
Re: studies of naming?
Steven, Given that many programmers have been trained to believe that opportunism is bad, it is also likely that observation of programming evokes non-opportunism. For example, in Rosson and Carroll's "Reuse of Uses" paper, the subjects exhibited opportunism with respect to using an API, but reflected on the behavior as something that they shouldn't have done because it wasn't the way code should be written. They are successful and efficient when they adopt an opportunistic strategy, yet they are taught that it is bad behavior. Have any thoughts? I often here people talking about opportunistic programmers as if this strategy is a persistent individual difference. Is there any proof for the assumption of persistence? I have always found it odd the way we talk about opportunism as being an alternative to, for example, strategic programming. I find it more commensurable with my observations to consider opportunism the default state, and that other approaches, at times and to various degrees, "overload" our default opportunistic behaviors. The questions and descriptions shift slightly under such a view, but it seems more appropriate given every programmer I have ever observed. I realize that in this entire email I may just be hitting on the conflict between personas and a descriptive theory of programming styles; personas are distinct and immutable for a reason. John On Thu, Mar 29, 2012 at 9:28 AM, Steven Clarke wrote: > I'm very aware that there is a lack of respect and understanding of > these different programming styles. That doesn't mean we should cast out > these programmers. My colleagues and I spend a lot of time observing > professional programmers. And many of those programmers exhibit the > opportunistic workstyle. A large number of them earn a good living writing > code this way. > > One of the reasons discussion lists such as this one exist is to discuss > how to accommodate different approaches to programming. I'd rather figure > out ways we can improve their development experience. > > Note that our study was focused on API design, not language design. Note > also that optional and named parameters were not available at the time we > did the study. > > It certainly wasn't our intent to claim that the create set call pattern > is preferred by all opportunistic programmers compared to every design > pattern that ever has and ever will exist. > > Steven > -- > From: Richard O'Keefe > Sent: 29/03/2012 07:55 > To: Steven Clarke > Cc: John Daughtry; Brad Myers; Raoul Duke; Ppig-Discuss-List > > Subject: Re: studies of naming? > > > On 29/03/2012, at 3:39 AM, Steven Clarke wrote: > > > > We don’t have the luxury of dismissing these types of programmers. While > it might strike you with terror that these programmers exist, they are > successfully building applications in many different domains. They may work > differently to you and many other programmers but that doesn’t necessarily > mean that the code they create is worthless. > > Poke around on the web and you will stumble across other people saying > things like "the one thing that frightens me is cut-and-paste programmers" > and "As a programmer, boilerplate scares me, because it is prone to errors > that don't get noticed. Repeated code is an occasion for errors, because > the code that the boilerplate calls may change. It's easy to miss > correcting one of the many repetitions. > > Boilerplate prevention happens when designing a programming interface or > language. It's hard, though. Certain kinds of boilerplate become idiomatic. > (Analogy from English: "for all intents and purposes.") i catch myself not > even noticing them. It's hard to revise the code constantly, looking for > opportunities to strip away unnecessary repetition -- especially when > working in a lower-level programming language." > > There are sound good reasons why a *platform* like .NET needs to support > everybody and his dog (and their lemons). It's not so clear that it is > necessary for a *language* to have to cater to all personalities and > workstyles. > Necessary? It's not even clear to me that a language *can* cater equally > well > to all personalities and workstyles. > > One issue, of course, is that if a constructor has so many arguments that a > cut-and-paste programmer is worried about all the dots, it has _too many_ > arguments. My Smalltalk compiler, for example, only accepts up to 15 > arguments, which is all the ANSI Smalltalk standard requires. No code I've > written has even got past eight parameters. > > I wonder just how 'sucessful' these applications you speak of really
RE: studies of naming?
I'm very aware that there is a lack of respect and understanding of these different programming styles. That doesn't mean we should cast out these programmers. My colleagues and I spend a lot of time observing professional programmers. And many of those programmers exhibit the opportunistic workstyle. A large number of them earn a good living writing code this way. One of the reasons discussion lists such as this one exist is to discuss how to accommodate different approaches to programming. I'd rather figure out ways we can improve their development experience. Note that our study was focused on API design, not language design. Note also that optional and named parameters were not available at the time we did the study. It certainly wasn't our intent to claim that the create set call pattern is preferred by all opportunistic programmers compared to every design pattern that ever has and ever will exist. Steven From: Richard O'Keefe Sent: 29/03/2012 07:55 To: Steven Clarke Cc: John Daughtry; Brad Myers; Raoul Duke; Ppig-Discuss-List Subject: Re: studies of naming? On 29/03/2012, at 3:39 AM, Steven Clarke wrote: > > We don’t have the luxury of dismissing these types of programmers. While it > might strike you with terror that these programmers exist, they are > successfully building applications in many different domains. They may work > differently to you and many other programmers but that doesn’t necessarily > mean that the code they create is worthless. Poke around on the web and you will stumble across other people saying things like "the one thing that frightens me is cut-and-paste programmers" and "As a programmer, boilerplate scares me, because it is prone to errors that don't get noticed. Repeated code is an occasion for errors, because the code that the boilerplate calls may change. It's easy to miss correcting one of the many repetitions. Boilerplate prevention happens when designing a programming interface or language. It's hard, though. Certain kinds of boilerplate become idiomatic. (Analogy from English: "for all intents and purposes.") i catch myself not even noticing them. It's hard to revise the code constantly, looking for opportunities to strip away unnecessary repetition -- especially when working in a lower-level programming language." There are sound good reasons why a *platform* like .NET needs to support everybody and his dog (and their lemons). It's not so clear that it is necessary for a *language* to have to cater to all personalities and workstyles. Necessary? It's not even clear to me that a language *can* cater equally well to all personalities and workstyles. One issue, of course, is that if a constructor has so many arguments that a cut-and-paste programmer is worried about all the dots, it has _too many_ arguments. My Smalltalk compiler, for example, only accepts up to 15 arguments, which is all the ANSI Smalltalk standard requires. No code I've written has even got past eight parameters. I wonder just how 'sucessful' these applications you speak of really are. Or more precisely, I wonder just which of the quality attributes they actually possess. That is, of course, another study. > Within the Visual Studio team at Microsoft we’ve devoted efforts to > attempting to make them successful by adapting to their workstyles when > appropriate. > > There are a few blog posts and papers that describe these personas in more > detail that might be worth reading if you’re interested in how we use them. > > http://p.einarsen.no/programmer-personality-types-and-why-it-matters-at-all/ > > http://drops.dagstuhl.de/opus/volltexte/2007/1080/pdf/07081.ClarkeSteven.Paper.1080.pdf > > http://blogs.msdn.com/b/stevencl/archive/2010/08/19/making-effective-use-of-personas-in-design.aspx > > http://blogs.msdn.com/b/stevencl/archive/2010/12/22/climate-change-and-developer-personas.aspx > > > From: john.m.daugh...@gmail.com [mailto:john.m.daugh...@gmail.com] On Behalf > Of John Daughtry > Sent: 28 March 2012 13:51 > To: Richard O'Keefe > Cc: Steven Clarke; Brad Myers; Raoul Duke; Ppig-Discuss-List > Subject: Re: studies of naming? > > > You introduced a third option. However, it is a deviation of the > implementation behind the interface as opposed to an alternative interface. > Are you suggesting that every API study should consider all of the limitless > alternative implementations? 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. > > John > > > > On Tue, Mar 27,
Re: studies of naming?
On 29/03/2012, at 3:39 AM, Steven Clarke wrote: > On the factory design pattern, that has been studied also. This will likely > make you even more terrified of using software built by other software > engineers J, I boggle at calling these people software engineers. They appear to be, at best, what Ledgard and Tauer called in their book (that seems to have set the basic standard for naming conventions) P-sub-A programmers: people who think they are professionals but are still working in a very amateur way. I'm not basing my judgement on the name "Opportunistic Programmers" that was bestowed on them, but on statements like "want to program without having to understand", found in the CreateSetCall.pdf paper. -- The Open University is incorporated by Royal Charter (RC 000391), an exempt charity in England & Wales and a charity registered in Scotland (SC 038302).
Re: studies of naming?
On 29/03/2012, at 3:39 AM, Steven Clarke wrote: > > We don’t have the luxury of dismissing these types of programmers. While it > might strike you with terror that these programmers exist, they are > successfully building applications in many different domains. They may work > differently to you and many other programmers but that doesn’t necessarily > mean that the code they create is worthless. Poke around on the web and you will stumble across other people saying things like "the one thing that frightens me is cut-and-paste programmers" and "As a programmer, boilerplate scares me, because it is prone to errors that don't get noticed. Repeated code is an occasion for errors, because the code that the boilerplate calls may change. It's easy to miss correcting one of the many repetitions. Boilerplate prevention happens when designing a programming interface or language. It's hard, though. Certain kinds of boilerplate become idiomatic. (Analogy from English: "for all intents and purposes.") i catch myself not even noticing them. It's hard to revise the code constantly, looking for opportunities to strip away unnecessary repetition -- especially when working in a lower-level programming language." There are sound good reasons why a *platform* like .NET needs to support everybody and his dog (and their lemons). It's not so clear that it is necessary for a *language* to have to cater to all personalities and workstyles. Necessary? It's not even clear to me that a language *can* cater equally well to all personalities and workstyles. One issue, of course, is that if a constructor has so many arguments that a cut-and-paste programmer is worried about all the dots, it has _too many_ arguments. My Smalltalk compiler, for example, only accepts up to 15 arguments, which is all the ANSI Smalltalk standard requires. No code I've written has even got past eight parameters. I wonder just how 'sucessful' these applications you speak of really are. Or more precisely, I wonder just which of the quality attributes they actually possess. That is, of course, another study. > Within the Visual Studio team at Microsoft we’ve devoted efforts to > attempting to make them successful by adapting to their workstyles when > appropriate. > > There are a few blog posts and papers that describe these personas in more > detail that might be worth reading if you’re interested in how we use them. > > http://p.einarsen.no/programmer-personality-types-and-why-it-matters-at-all/ > > http://drops.dagstuhl.de/opus/volltexte/2007/1080/pdf/07081.ClarkeSteven.Paper.1080.pdf > > http://blogs.msdn.com/b/stevencl/archive/2010/08/19/making-effective-use-of-personas-in-design.aspx > > http://blogs.msdn.com/b/stevencl/archive/2010/12/22/climate-change-and-developer-personas.aspx > > > From: john.m.daugh...@gmail.com [mailto:john.m.daugh...@gmail.com] On Behalf > Of John Daughtry > Sent: 28 March 2012 13:51 > To: Richard O'Keefe > Cc: Steven Clarke; Brad Myers; Raoul Duke; Ppig-Discuss-List > Subject: Re: studies of naming? > > > You introduced a third option. However, it is a deviation of the > implementation behind the interface as opposed to an alternative interface. > Are you suggesting that every API study should consider all of the limitless > alternative implementations? 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. > > John > > > > On Tue, Mar 27, 2012 at 11:10 PM, Richard O'Keefe wrote: > > On 27/03/2012, at 10:14 PM, Steven Clarke wrote: > > > Yes, you're right Richard. Our study was focused on languages like Java and > > C# (and importantly, as they existed around 2006/2007). So as you say, we > > wouldn't generalize the results to languages that have named parameters. We > > described the two design choices we evaluated at the start of the paper: > > > > "There are two common design choices: provide only > > constructors that require certain objects (a "required > > constructor"). This option has the benefit of enforcing > > certain invariants at the expense of flexibility. An > > alternative design, "create-set-call," allows objects to > > be created and then initialized." > > There are actually three design choices, and I've seen the third > one too often for comfort. Please note that this is a *different* > choice from the one you endorsed: > > Good Smalltalk design: > > Provide a variet
Re: studies of naming?
On 29/03/2012, at 5:49 PM, Richard O'Keefe wrote: > Let's recall the Builder pattern. There are actually two variables. s/variables/variants/ Sorry. -- The Open University is incorporated by Royal Charter (RC 000391), an exempt charity in England & Wales and a charity registered in Scotland (SC 038302).
Re: studies of naming?
On 29/03/2012, at 4:00 PM, Brad Myers wrote: > 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. I have a sticker from Brian Marick, for pointing to in discussions. "An example would be useful around here." Let's recall the Builder pattern. There are actually two variables. Builder: var x = DesiredResult.NewBuilder(); x.SetThis(...); ... x.SetThat(...); var realObject = x.Build(); Configuration Object: var x = DesiredResult.NewConfiguration(); x.SetThis(...); ... x.SetThat(...); var realObject = DesiredResult.Create(x); In both variants, the helper object carries some or all of the information needed to construct DesiredResults. If it's only some, the remainder can be provided in the final creation call. A Builder actively takes charge of constructing the DesiredResult; a ConfigurationObject is passive and DesiredResult is in charge. Both variants of this pattern - let you compute properties in advance - let you compute properties in whatever order you want - never expose a DesiredResult object that is not fully initialised exactly the way you want it initialised - make it easy to make multiple similar objects, e.g., var x = DesiredResult.NewBuilder(); set most of the fields foreach (Datum in Data) { x.SetDatum(Datum); Collection.AddLast(x.Build()); } create-set-call gets the first two only. What is the source level cost of using Builder rather than Incomplete Initialisation? - one extra name for the builder - one extra line to set that up. And as noted before, if you _don't_ want to spread out setting the properties all over the place, you don't even need those: var realObject = DesiredResult.NewBuilder() .SetThis(...) ... .SetThat(...).Build(); > The users > in the study preferred to set them directly into the object as they are > calculated. No, we don't know that, because the study did not have Builder as one of the alternatives evaluated. If people are never offered a choice between A and B, you have no grounds for saying that B is preferred. Maybe they _would_ have preferred B to A, maybe the other way round. It's entirely possible that in the course of their training the subjects of the experiment had never been shown the Builder pattern. If they *had* been given a little training in it, _maybe_ they would have preferred that to Incomplete Initialisation. We just can't tell. I repeat: I am NOT attacking the study. I've only ever tried to do one software engineering experiment and it completely failed to address the question I was interested because the subjects responded far more strongly to "this is black and white on paper rather than syntax-coloured on a screen like I demand it to be" than to the differences I wanted them to look at. This kind of stuff is HARD. Nor do I question the results of the study. What *does* bother me is the idea of extrapolating beyond what the study can legitimately claim. In particular, the study FOR GOOD REASON tells us nothing about user preferences for - C# 4.0 optional and keyword parameters in constructors or for - the Builder pattern because those alternatives were not part of the study. Oh, just in case someone else should raise a red herring, I should point out that a Builder class can be automatically generated from the signature of a constructor-with-named-and-optional-parameters and semi-automatically from a brief annotation on another constructor. So the use of a Builder need not imply non-trivial additional coding effort to define it. > 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. I didn't comment on that because I found it incredible that anyone would make such an assumption or should assume that it was required to support full initialisation. ANY values coming in from an untrusted source must of course be checked. In fact the argument goes the other way, because there is no shortage of constructors where the parameters have to be checked *together* and cannot be checked one at a time. Sticking with my FileStream example, and using an imaginary FileStreamBuilder because you *can't* change the settings after creation, var b = FileStream.NewBuilder(); b.SetMode(FileMode.CreateNew); b.SetRights(FileS
RE: studies of naming?
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(Fi
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).
RE: studies of naming?
Richard, Thanks for laying out the different design options. Unfortunately we're not always in a position to be able to study every design option since we're constrained by our shipping schedule. Sometimes we need to trade off what we know our engineering teams can build in the time we have available with what we would like to do in an ideal world. In many ways the studies we do in the Visual Studio team aim to tip the balance in favor of the user experience. It's one of the differences between the research that we do in the product teams at Microsoft and the research that the teams in Microsoft Research do. Anyway, the more interesting debate is how the opportunistic programmers would deal with the design options you laid out. On the factory design pattern, that has been studied also. This will likely make you even more terrified of using software built by other software engineers :), but take a look: http://www.cs.cmu.edu/~NatProg/papers/Ellis2007FactoryUsability.pdf On the fluent like initializer object style you demonstrated below, I don't believe that will solve all the usability issues we observe opportunistic programmers experiencing with required parameters. These developers are very exploratory in the way that they write code and are looking for shortcuts everywhere they go. They are task oriented, not API oriented. They think about the task they are writing code for, not the way that the APIs work. The success of the fluent style of API would depend on how many 'dots' the user would need to write before they were able to call the method that helped them with their task. If it is too deep, they might even give up exploring the class before they get that far. We don't have the luxury of dismissing these types of programmers. While it might strike you with terror that these programmers exist, they are successfully building applications in many different domains. They may work differently to you and many other programmers but that doesn't necessarily mean that the code they create is worthless. Within the Visual Studio team at Microsoft we've devoted efforts to attempting to make them successful by adapting to their workstyles when appropriate. There are a few blog posts and papers that describe these personas in more detail that might be worth reading if you're interested in how we use them. http://p.einarsen.no/programmer-personality-types-and-why-it-matters-at-all/ http://drops.dagstuhl.de/opus/volltexte/2007/1080/pdf/07081.ClarkeSteven.Paper.1080.pdf http://blogs.msdn.com/b/stevencl/archive/2010/08/19/making-effective-use-of-personas-in-design.aspx http://blogs.msdn.com/b/stevencl/archive/2010/12/22/climate-change-and-developer-personas.aspx From: john.m.daugh...@gmail.com [mailto:john.m.daugh...@gmail.com] On Behalf Of John Daughtry Sent: 28 March 2012 13:51 To: Richard O'Keefe Cc: Steven Clarke; Brad Myers; Raoul Duke; Ppig-Discuss-List Subject: Re: studies of naming? You introduced a third option. However, it is a deviation of the implementation behind the interface as opposed to an alternative interface. Are you suggesting that every API study should consider all of the limitless alternative implementations? 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. John On Tue, Mar 27, 2012 at 11:10 PM, Richard O'Keefe mailto:o...@cs.otago.ac.nz>> wrote: On 27/03/2012, at 10:14 PM, Steven Clarke wrote: > Yes, you're right Richard. Our study was focused on languages like Java and > C# (and importantly, as they existed around 2006/2007). So as you say, we > wouldn't generalize the results to languages that have named parameters. We > described the two design choices we evaluated at the start of the paper: > > "There are two common design choices: provide only > constructors that require certain objects (a "required > constructor"). This option has the benefit of enforcing > certain invariants at the expense of flexibility. An > alternative design, "create-set-call," allows objects to > be created and then initialized." There are actually three design choices, and I've seen the third one too often for comfort. Please note that this is a *different* choice from the one you endorsed: Good Smalltalk design: Provide a variety of factory methods with keyword arguments, all of which provide fully initialised objects satisfying the class invariant; such objects often need little or no mutation afterwards. Good Eiffel design agrees in every respect except 'keyword arguments'. Good create-set-call design: Ensure that the default 'new' constructor returns a fully initi
Re: studies of naming?
You introduced a third option. However, it is a deviation of the implementation behind the interface as opposed to an alternative interface. Are you suggesting that every API study should consider all of the limitless alternative implementations? 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. John On Tue, Mar 27, 2012 at 11:10 PM, Richard O'Keefe wrote: > > On 27/03/2012, at 10:14 PM, Steven Clarke wrote: > > > Yes, you're right Richard. Our study was focused on languages like Java > and C# (and importantly, as they existed around 2006/2007). So as you say, > we wouldn't generalize the results to languages that have named parameters. > We described the two design choices we evaluated at the start of the paper: > > > > "There are two common design choices: provide only > > constructors that require certain objects (a "required > > constructor"). This option has the benefit of enforcing > > certain invariants at the expense of flexibility. An > > alternative design, "create-set-call," allows objects to > > be created and then initialized." > > There are actually three design choices, and I've seen the third > one too often for comfort. Please note that this is a *different* > choice from the one you endorsed: > > Good Smalltalk design: > > Provide a variety of factory methods with keyword arguments, > all of which provide fully initialised objects satisfying > the class invariant; such objects often need little or no > mutation afterwards. > > Good Eiffel design agrees in every respect except 'keyword arguments'. > > Good create-set-call design: > > Ensure that the default 'new' constructor returns a fully > initialised object satisfying the class invariant and > offering meaningful default behaviour; such objects almost always > require adjustment to get them into the state you really want but > all states are meaningful. > > IN ADDITION make sure that all 'initialisation phase' methods > can safely be called AT ALL TIMES. > > Ensure that every public method is *tested* with a default- > initialised object. > > Bad create-set-call design: > > Don't think about class invariants. > Rely on default constructors that leave fields with default > values (0, nil, &c) that satisfy types but not invariants. > Allow objects to be named outside their class in partially > initialised states that require 'initialisation phase' methods > to be called before 'work phase' methods, but do not check > that this has been done. > > Allow 'initialisation phase' methods to be called at any time > without checking it it makes sense, allowing even well-initialised > objects to subsequently be put into inconsistent states. > > Much as I love Smalltalk, a lot of the code that I see using the > create-set-call pattern is actually doing the >bad< version. > Here's an example that took only 2 minutes to find. > In Pharo 1.1 (which is not the current version) >Url new > which is the equivalent of System.out.println(new Url()) > raises an exception. Url new created an uninitialised object. > That's _almost_ fair enough: this is supposed to be an abstract > class, but it should have been caught in #new. Go to a concrete > subclass: >FileUrl new > also raises an exception, trying to print the elements of a nil > String. > > > However, I don't think our result is unsurprising, > > All I can say is that it didn't surprise _me_. > Compare for example >f = fopen(x, y); /*C*/ >s := FileStream read: x. "ST" > >s = new FileStream(y, x); //C# > > Smalltalk: obvious what it does. > C: which argument is which? Compiler can't help. > C#: three different things it could be; the compiler > can tell them apart, but it's not so easy for people. > And when you get to > >new FileStream(String, FileMode, FileSystemRights, >FileShare, Int32, FileOptions) > > this is obviously going to be a lot harder for people to > read than >FileStream read: string rights: rights share: share >bufferSize: int32 options: options > > If you *could* do >s = new FileStream() >.FileName(string) >.Rights(rights) >.Share(share) >.BufferSize(int32) >.Options(options) >.Open(); > that would be a lot clearer. > > And that introduces a fourth design pattern, which the paper did > not investigate, call it "initializer object". > > The general scheme for Initializer Object is >class X has a static Maker() method >returning an instance of X_Maker(). > >X_Maker() has methods like >Facet(value) >returning the same X_Maker() object >and a completion method called something >
Re: studies of naming?
On 27/03/2012, at 10:14 PM, Steven Clarke wrote: > Yes, you're right Richard. Our study was focused on languages like Java and > C# (and importantly, as they existed around 2006/2007). So as you say, we > wouldn't generalize the results to languages that have named parameters. We > described the two design choices we evaluated at the start of the paper: > > "There are two common design choices: provide only > constructors that require certain objects (a "required > constructor"). This option has the benefit of enforcing > certain invariants at the expense of flexibility. An > alternative design, "create-set-call," allows objects to > be created and then initialized." There are actually three design choices, and I've seen the third one too often for comfort. Please note that this is a *different* choice from the one you endorsed: Good Smalltalk design: Provide a variety of factory methods with keyword arguments, all of which provide fully initialised objects satisfying the class invariant; such objects often need little or no mutation afterwards. Good Eiffel design agrees in every respect except 'keyword arguments'. Good create-set-call design: Ensure that the default 'new' constructor returns a fully initialised object satisfying the class invariant and offering meaningful default behaviour; such objects almost always require adjustment to get them into the state you really want but all states are meaningful. IN ADDITION make sure that all 'initialisation phase' methods can safely be called AT ALL TIMES. Ensure that every public method is *tested* with a default- initialised object. Bad create-set-call design: Don't think about class invariants. Rely on default constructors that leave fields with default values (0, nil, &c) that satisfy types but not invariants. Allow objects to be named outside their class in partially initialised states that require 'initialisation phase' methods to be called before 'work phase' methods, but do not check that this has been done. Allow 'initialisation phase' methods to be called at any time without checking it it makes sense, allowing even well-initialised objects to subsequently be put into inconsistent states. Much as I love Smalltalk, a lot of the code that I see using the create-set-call pattern is actually doing the >bad< version. Here's an example that took only 2 minutes to find. In Pharo 1.1 (which is not the current version) Url new which is the equivalent of System.out.println(new Url()) raises an exception. Url new created an uninitialised object. That's _almost_ fair enough: this is supposed to be an abstract class, but it should have been caught in #new. Go to a concrete subclass: FileUrl new also raises an exception, trying to print the elements of a nil String. > However, I don't think our result is unsurprising, All I can say is that it didn't surprise _me_. Compare for example f = fopen(x, y); /*C*/ s := FileStream read: x. "ST" s = new FileStream(y, x); //C# Smalltalk: obvious what it does. C: which argument is which? Compiler can't help. C#: three different things it could be; the compiler can tell them apart, but it's not so easy for people. And when you get to new FileStream(String, FileMode, FileSystemRights, FileShare, Int32, FileOptions) this is obviously going to be a lot harder for people to read than FileStream read: string rights: rights share: share bufferSize: int32 options: options If you *could* do s = new FileStream() .FileName(string) .Rights(rights) .Share(share) .BufferSize(int32) .Options(options) .Open(); that would be a lot clearer. And that introduces a fourth design pattern, which the paper did not investigate, call it "initializer object". The general scheme for Initializer Object is class X has a static Maker() method returning an instance of X_Maker(). X_Maker() has methods like Facet(value) returning the same X_Maker() object and a completion method called something likeOpen() or Create() that returns a fully initialised instance of X. This requires a creation style like s = FileStream.maker() .FileName(string) &c as before .Open(); > You've highlighted the core of the debate when, referring to the people who > prefer the create-set-call pattern, you said " the idea of them writing any > code that might affect my life or the life of anyone known to me is not one > that's going to help me sleep at night ". This was also the initial reaction > of many people inside Microsoft when they heard the results of our study. > > Our response in this debate has always been that different programmers > require
Re: studies of naming?
Hi Raoul As you rightly point out it is not easy to identify a link between software faults and identifier naming problems. Some have tried. See, for example, Arnaoudova et al. Physical and Conceptual Identifier Dispersion: Measures and Relation to Fault Proneness. In Proc. of the Int'l Conf. on Software Maintenance - ERA Track, pages 1-5, 2010. IEEE Computer Society. or our own work http://oro.open.ac.uk/view/person/sjb792.html Other research you might want to look at includes the link between poor identifier naming and program comprehension problems, which Brad Myers identifies elsewhere in this thread. As well as issues of overly long names and esoteric typography, concerns have been expressed about the semantic content of identifier names. Deissenboeck and Pizka Concise and Consistent Naming Software Quality Journal, 2006, 14, 261-282 is probably the best known source. Einar Host's work on the connection between Java identifier method names and method functionality may also be of interest to you. The connection is strong enough for the functionality of methods to be used as an input to name refactoring. (Høst, E. W. & Østvold, B. M. Debugging Method Names Proc. of the 23rd European Conf. on Object-Oriented Programming, Springer-Verlag, 2009, 294-317). Simon On 03/26/2012 11:08 PM, Raoul Duke wrote: hi, Check out my paper from PPIG 2006: http://research.microsoft.com/en-us/um/people/abegel/papers/ppig-naming.pdf Thanks, I just skimmed it. I probably haven't explained well at all what I had in mind. I searched for "bug" and "error" with no hits. It so far appears to me to be a review of how naming is used; doesn't get into the resulting impacts of those uses and choices. Now that I think about it, I guess the sort of thing I have in mind is: has anybody somehow managed to study a bug database and the fixes and figure out %ages of what caused the bugs, and if it is possible to figure out that naming was a problem, how much was due to problems with naming? I guess it would be quite hard to tease it out. Presumably naming hasn't caused Arianne to crash or anything like that (http://www.sans.org/top25-software-errors/) so I'm really probably only ranting about my own little pet peeve. Apologies. sincerely. -- Simon Butler email: si...@facetus.org.uk "No set of mutually inconsistent observations can exist for which some human intellect cannot conceive a coherent explanation, however complicated." Crabtree's Bludgeon -- The Open University is incorporated by Royal Charter (RC 000391), an exempt charity in England & Wales and a charity registered in Scotland (SC 038302).
RE: studies of naming?
Hello, A lot of discussion related to naming can be found in the following documents. http://www.naturalprogramming.com/to_read/doctoral_thesis_of_kari_laitinen.pdf http://www.naturalprogramming.com/to_read/estimating_understandability_etc.pdf I think the discussion is still valid although the papers are not very 'fresh'. (We still communicate mostly with the same words as we used to communicate 15 years ago.) -Kari -Original Message- From: Raoul Duke [mailto:rao...@gmail.com] Sent: 27. maaliskuuta 2012 0:47 To: Ppig-Discuss-List Subject: studies of naming? (i googled, w/out much success.) Wondering if anybody knows of research that tries to get the word out that naming is important. Or proves that naming isn't important! Maybe nobody makes still little mistakes the way I do. Anyway, there are things in the programming language world that make me cringe. They look to me like highway train wrecks, if you'll pardon the metaphor, sneaking around looking for a place to happen. Picking two off the top of my head: Scala: "val" vs. "var". One letter difference?! Knockout JS: "viewmodel" instead of, gosh, say, just "model"?! -Mr. Tempest in a Teapot. -- The Open University is incorporated by Royal Charter (RC 000391), an exempt charity in England & Wales and a charity registered in Scotland (SC 038302).
Re: studies of naming?
On 27/03/2012, at 11:20 AM, Brad Myers wrote: > http://www.cs.cmu.edu/~NatProg/apiusability.html Looking at that page, I picked one paper that addressed an issue I feel strongly about. In my own API design I have followed one principle rigorously: an object should NEVER become accessible until it is fully initialised (defined as "class invariant established"). The paper http://www.cs.cmu.edu/~NatProg/papers/Stylos2007CreateSetCall.pdf promised to teach me something, because it says "programmers strongly preferred and were more effective with APIs that did NOT require constructor parameters." A little further reading revealed two interesting features of the study. First, there was a group of programmers (a group that was known to exist before the study and who were carefully included in the sample) who just don't *get* the idea of constructors having parameters. One wonders what else these programmers don't get, and the idea of them writing any code that might affect my life or the life of anyone known to me is not one that's going to help me sleep at night. But the second feature was a very interesting one. API design I have done (for other people to use) has primarily been - in declarative languages where you *have* to provide all the information when something's created and - languages with keyword parameters including Ada, R, and Smalltalk. Let's take one example from Smalltalk. There is a class SortedCollection which is an integer-indexed sequence of objects kept in sorted order; there is a default ordering (using <=) and you may provide a block [:x :y | ...] to do the comparison. Let's suppose we want to create a sorted collection in descending order, using the initial digits of pi. Method 1: c := SortedCollection sortBlock: [:x :y | x >= y] withAll: #(3 1 3 1 5 9 2 6 5 3 5 8 9). The object is fully initialised in the construction. There is often no need to change it afterwards. The keywords are part of the name. (See? It's not a change of topic!) The keywords can be relatively short because they are interpreted within the scope of the class's public interface. (withAll: indicates adding all the elements of a collection, with: would indicate adding a single element. This is a Smalltalk-wide convention.) Method 2: c := SortedCollection new. c sortBlock: [:x :y | x >= y]. c addAll: #(. The collection is born fully initialised (default sort order, no elements). It is then changed. Smalltalk style would encourage this to be written as c := SortedCollection new sortBlock: [:x :y | x >= y]; addAll: #(3 1 3 1 5 9 2 6 5 3 5 8 9); yourself. where the "adjustment" methods are called in separate calls, but the object isn't *named* until it's fully initialised. The problem with method 2 is that in practice there are methods that people *think of* as part of the "initialisation protocol" of an object, so that's what they *implement*. But there is nothing to enforce this restricted use, and we get Method 3: c := SortedCollection new. c addAll: #(3 1 3 1 5 9 2 6 5 3 5 8 9). c sortBlock: [:x :y | x >= y]. It's not terribly clear in the ANSI standard that setting the sort order sorts the elements, but it is kind of hinted at, and all Smalltalk systems known to me get this right. But it does mean that the collection gets sorted twice. (It does with method 2 as well, but the first time, the collection is empty.) This is harmless for SortedCollection; disastrous for SortedSet. Something very odd was definitely going on in that experiment. For example, task 1 was to write (in Notepad) some code to read a file and send its contents as an e-mail message, using an interface of your own design. Now to me the thing that's most obvious is (MailMessage to: 'ppig-discuss-list@open.ac.uk' contents: 'my-message.txt' asFilename contentsOfEntireFile ) send. Using R syntax, I'd expect something like send.mail(to = '...', contents = file.contents('...')); with the mail message "object" hidden entirely inside the send.mail() function. Yet the paper tells us 4.2. Task 1 Results: Notepad Programming All the participants used create-set-call when creating objects in their Notepad programming task. The opportunistic programmers were more resistant to the idea of writing code outside of an IDE than pragmatic programmers. Why did _none_ of the participants use _ to: _ contents: _ or anything like it as a creation message? Presumably because they'd never seen a creation message with named parameters. If you think "being a parameter" means "being anonymous", as you do if you are a Java or C# programmer, then it's really not surprising if m = new MailMessage(); m.setTo("demons@microsoft"); m.setContents("Can you give me a better language, please?"); m.send(); looks better, because now the information items are *named*. (Yes, we are
Re: studies of naming?
Raoul, Wondering if anybody knows of research that tries to get the word out that naming is important. Or proves that naming isn't important! Maybe There is of course: www.knosof.co.uk/cbook/sent792.pdf Operand names influence operator precedence decisions http://www.knosof.co.uk/dev-experiment/accu07.html There was some naming issues involved in: Classification and grouping into aggregate types http://www.knosof.co.uk/dev-experiment/accu08.html nobody makes still little mistakes the way I do. Anyway, there are things in the programming language world that make me cringe. They look to me like highway train wrecks, if you'll pardon the metaphor, sneaking around looking for a place to happen. Picking two off the top of my head: Scala: "val" vs. "var". One letter difference?! At the difference was at the end that has less attention paid to it. The second part of: http://www.knosof.co.uk/dev-experiment/accu11.html has some experimental evidence that differences at the start of an identifier improve recall performance. Paper and data should be up at the end of the week. Knockout JS: "viewmodel" instead of, gosh, say, just "model"?! -Mr. Tempest in a Teapot. and now you get get a phonetic transcription of that: http://shape-of-code.coding-guidelines.com/2012/03/16/generating-sounds-like-and-accented-words/ -- Derek M. Jones tel: +44 (0) 1252 520 667 Knowledge Software Ltd blog:shape-of-code.coding-guidelines.com Source code analysishttp://www.knosof.co.uk -- The Open University is incorporated by Royal Charter (RC 000391), an exempt charity in England & Wales and a charity registered in Scotland (SC 038302).
Re: studies of naming?
hi, On Mon, Mar 26, 2012 at 3:20 PM, Brad Myers wrote: > These results are not collected in one place, however, and are distributed > throughout our papers. References for the papers that report on all of these > are here: Thanks for the summary and pointers. -- The Open University is incorporated by Royal Charter (RC 000391), an exempt charity in England & Wales and a charity registered in Scotland (SC 038302).
RE: studies of naming?
As part of our larger project on API Usability, we have studied the issue of naming of methods, classes and parameters. It can definitely have a measurable impact. At one point, we tried to design an experiment to test the hypothesis that there was a "sweet spot" in terms of the length of the name -- not too short and not too long, but we never were able to separate the length from the semantics of the words. However, we did report on names that were clearly too long in the SAP eSOA API. And we identified naming as a key aspect of the design that an API designer must take into account in our taxonomy of design issues. Another study showed that people often navigate an API by guessing names first, and you should reserve the most general name (like "File") for classes that people actually use, instead of the current common practice of using the general name for an interface or top-level class that is never actually used, except as a superclass for what people actually are supposed to use. These results are not collected in one place, however, and are distributed throughout our papers. References for the papers that report on all of these are here: http://www.cs.cmu.edu/~NatProg/apiusability.html Brad Myers -Original Message- From: Raoul Duke [mailto:rao...@gmail.com] Sent: Monday, March 26, 2012 6:09 PM To: Ppig-Discuss-List Subject: Re: studies of naming? hi, > Check out my paper from PPIG 2006: > http://research.microsoft.com/en-us/um/people/abegel/papers/ppig-naming.pdf Thanks, I just skimmed it. I probably haven't explained well at all what I had in mind. I searched for "bug" and "error" with no hits. It so far appears to me to be a review of how naming is used; doesn't get into the resulting impacts of those uses and choices. Now that I think about it, I guess the sort of thing I have in mind is: has anybody somehow managed to study a bug database and the fixes and figure out %ages of what caused the bugs, and if it is possible to figure out that naming was a problem, how much was due to problems with naming? I guess it would be quite hard to tease it out. Presumably naming hasn't caused Arianne to crash or anything like that (http://www.sans.org/top25-software-errors/) so I'm really probably only ranting about my own little pet peeve. Apologies. sincerely. -- The Open University is incorporated by Royal Charter (RC 000391), an exempt charity in England & Wales and a charity registered in Scotland (SC 038302).
Re: studies of naming?
hi, > Check out my paper from PPIG 2006: > http://research.microsoft.com/en-us/um/people/abegel/papers/ppig-naming.pdf Thanks, I just skimmed it. I probably haven't explained well at all what I had in mind. I searched for "bug" and "error" with no hits. It so far appears to me to be a review of how naming is used; doesn't get into the resulting impacts of those uses and choices. Now that I think about it, I guess the sort of thing I have in mind is: has anybody somehow managed to study a bug database and the fixes and figure out %ages of what caused the bugs, and if it is possible to figure out that naming was a problem, how much was due to problems with naming? I guess it would be quite hard to tease it out. Presumably naming hasn't caused Arianne to crash or anything like that (http://www.sans.org/top25-software-errors/) so I'm really probably only ranting about my own little pet peeve. Apologies. sincerely. -- The Open University is incorporated by Royal Charter (RC 000391), an exempt charity in England & Wales and a charity registered in Scotland (SC 038302).
Re: studies of naming?
On Mon, Mar 26, 2012 at 2:46 PM, Raoul Duke wrote: > Knockout JS: "viewmodel" instead of, gosh, say, just "model"?! That's my foot in my mouth since the M-V-VM pattern has used the "viewmodel" name for ever, since "model" was already taken. -- The Open University is incorporated by Royal Charter (RC 000391), an exempt charity in England & Wales and a charity registered in Scotland (SC 038302).