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 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 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 initialised object satisfying the class invariant and offering
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?
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 steven.cla...@microsoft.comwrote: 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
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?
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 o...@cs.otago.ac.nzmailto: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 initialised object satisfying the class invariant and offering meaningful default behaviour; such objects almost always require adjustment to get them into the state
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);
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?
hi, On Mon, Mar 26, 2012 at 3:20 PM, Brad Myers b...@cs.cmu.edu 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?
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?
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 still on topic.) It