29
$\begingroup$

In writing software we name things. In Java we name classes, interfaces, methods, variables, etc. How can we teach both the importance and the skill of choosing good names?

What teaching practices will lead students naturally to good practice in naming their programming constructs?

How important is naming in the creation of quality software? In particular, how important is it to teach good naming and insist on it in student programs?

Moreover, what practices impede the student from learning and practicing this skill?

Good naming is important for both the creation and maintenance of programs. Good naming also makes the evaluation of the student programs easier when the student uses, for example, intention revealing names consistently. .

Note that much of this applies to other languages, but Java is a popular teaching language. Java is mandated in the Advanced Placement courses commonly taught in the United States. It is also a common language in first courses taught to undergraduates.

$\endgroup$
  • 1
    $\begingroup$ I teach my students their job will not be writing working perfect programs at first shot, but trying to understand and fix problems in programs that should work but don't. So, using good naming practices from start will help and actually require much less work. $\endgroup$ – Michel Billaud Apr 9 '18 at 20:13
  • 1
    $\begingroup$ Make them code something, forget it for 6 months, and then alter it to add new functionnalities. After 6 months, even your code, is not yours anymore. Add to the mix a bit of unit mixing (milliseconds / seconds / meter, etc), and they'll understand that coding clearly is mandatory for any code that will stay around. $\endgroup$ – Thierry Apr 10 '18 at 7:39
  • 3
    $\begingroup$ @Thierry why make them wait 6 months? Just ask them to make sense of code written by the last bunch of students 6 months ago. $\endgroup$ – Racheet Apr 10 '18 at 10:48
  • 1
    $\begingroup$ You could, but i find it of greater value that you do not understand your own code 6 months later, when you wrote it, you understood it perfectly, and you found it was understandable enough at that time. With code from someone else, you could always argue that you wouldn't have written it the way it was, and that your way would have been better. $\endgroup$ – Thierry Apr 10 '18 at 11:42
  • 2
    $\begingroup$ @Thierry and MichelBillaud Please avoid answering the question in a comment. Answers in comments will be deleted as mentioned in this meta post. $\endgroup$ – thesecretmaster Apr 10 '18 at 12:04

11 Answers 11

26
$\begingroup$

Fair warning, I do not demand any particular naming convention (such as NetBeans) from my students. This leaves me with variable naming only for the purpose of clarity.

I speak constantly to my students about the two different audiences for code: the computer itself (which is the one kids naturally think about), and other is human beings, which students find more difficult. And I also strongly believe that this is the single biggest impedance to good naming: students don't think that it matters, because they think they are writing for a computer.

I also grade all of my labs using code interviews, and my students are aware that I will be looking for clarity above almost all other considerations. (There is good reason for this; deeply clean and clear code also has very few bugs. When you engage in the difficult process of cleaning and refactoring, you can polish your code until there is basically no room left for them!)

My intuition is that good code correlates much more with good writing than it does with good mathematical skills. Good code demonstrates a clean rhetorical structure. This part of the code cleanly and clearly accomplishes this task, while that part carefully lays out the thinking and organization for that task.

This could simply be a function of the kinds of people who are naturally attracted to coding, but I have found that asking kids to write clean code is often very difficult for them.

What works

I have found that the following question is a useful overriding guide for most of my students:

"If you were not someone who had just spent the last 15 hours looking over this code in detail, what are the odds that you could figure out what it was doing at a quick glance?"

Naming norms

This is the best tool that I use, and these work for all of my students. There are a few direct practices that I ask for in all submitted code:

  • With regard to booleans, what do we know if this variable is true? Create a name based on the true condition. (e.g. if this variable will be true whenever the foo is inside the bar, we would name the variable fooInBar)
  • With regards to accessor methods, what information is being returning? Simply name this information. (totalTrials(), unusedElements(), nextItem(), etc.)
  • With regards to mutators, what command (verb) is being issued? Use this verb, possibly with an attached noun. (increment(), consume(Item i), fixVertex(), etc.)
  • Single letter variable names should be used only for throwaway counters and such. (e.g. for(int k = 0; k < items.length(); k++))
  • For other variables, we enter into broader territory, and things can get trickier. Which brings us to...

Miscellaneous variables

Unintuitively, I have had mixed luck with the question,

"what does this variable actually represent?"

This is the question that I ask myself while I code, and it works for many students, but for students who really struggle to come up with good names, the question does not seem to grant much insight.

This doesn't mean that I don't use the question, but it has become a last resort. Students who present poorly named variables often seem unable to cleanly articulate what a particular variable is accomplishing.

If I'm honest, the fact that this question rarely helps strugglers makes little sense to me (and is rather disheartening), but I have come to accept it as a fact. Going back to my intuition that strong writers create clean code, there could be some language difficulty going on here, but that is only a hunch.

For such strugglers, I might help them by having them describe the variable in broad terms, and writing what they say. I will then sit and progressively distill what they have written with them until we arrive at a good name together. Unfortunately, this practice is time intensive and does not scale well, but it works, and I haven't found any better solutions for my strugglers.

$\endgroup$
  • 1
    $\begingroup$ "This leaves me with variable naming only for the purpose of clarity." - This is exactly right, and the reason programmers are strongly encouraged - when not forced - to follow naming conventions for the language. If you want to give an example to your students, show them two snippets of code: one with proper names and the same snippet but with meaningless single-character names. The reasoning will become obvious when they see it. $\endgroup$ – Strikegently Apr 9 '18 at 15:54
  • 4
    $\begingroup$ "There is good reason for this; deeply clean and clear code also has very few bugs." -- Yes, but the bugs you do end up with are much harder to root out, because they're based on mistaken assumptions, and those are incredibly difficult to spot. That doesn't mean it's bad to write clean code; I'm just salty that I spent four hours last night trying to figure out why a function was giving me the "wrong" result when I passed the parameters in the wrong order. $\endgroup$ – Nic Hartley Apr 9 '18 at 18:11
  • 3
    $\begingroup$ @NicHartley I dunno. Mismatched params will exist in clean or dirty code, and I think it's easier to catch the the mistake in (firstName, lastName, middleName) than (name, name2, result). I mean, the only reason you even know the second one is out of order is because I just told you. $\endgroup$ – Lord Farquaad Apr 9 '18 at 18:17
  • 1
    $\begingroup$ One good argument for considering the human audience: copare the number of times code is written to the number of times it's read. $\endgroup$ – Reinstate Monica Apr 10 '18 at 10:20
  • 1
    $\begingroup$ @Angew I've made that argument to students, but I haven't found that it has much traction. The kids are still writing labs that will essentially be read only once, and they have a tough time imagining the costs of poorly written code in a large code base over time. $\endgroup$ – Ben I. Apr 10 '18 at 10:37
18
$\begingroup$

There are at least two parts to teaching naming. The first is to have a good standard that the students know and understand. This can be provided in a checklist. But the more important aspect is to always demonstrate good naming in all examples that you use and in all quizzes and exams that you give them; even for very simple exercises.

The Naming Standard

The goal of a naming standard is to make programs easy to understand and to reason about. There are a number of possibilities here and you can and should develop your own. Here is one I use:

  1. Intention Revealing Names: A name should always have semantic content related to the problem being solved. Don't use abstract names like $x$ and $y$ . Use semantic names like $size$ and $figure$ .

  2. Names from the problem space, not the solution space. If you are totaling up some array, don't use $total$, use $sumOfAges$ , if that is a concept in the problem space. This can permit each statement in the program to read like a description of some thing or action in the language of the problem being solved.

  3. In Java, use singular nouns for class names. Use verbs and verb phrases for the names of mutator methods, describing what the method does. Use nouns and noun phrases for accessor methods, describing what the method returns. Predicates can usefully start with $is$ , as in $isRunning$ . An implication is that methods should not be simultaneously an accessor and a mutator. There are other reasons why access-mutators are a bad idea in any case.

  4. One name per concept. The same concept will occur in a program in several ways. A class name $Ramp$ describes how to construct a ramp. A variable name can be $ramp$ . An accessor method in some class might be $ramp()$ . A field in some class might be $ramp$ . Java does a good job of keeping these distinct, thought you sometimes need to (and should) write $this.ramp$ . Since the language can distinguish them the programmer doesn't need to keep track of an entire set of names for the one concept. And, concept is from the problem space, not the solution space. This helps the student programmer imagine that their program is a model of some "real" world scenario, not just a set of notations providing a result. (See Miller's Rule, below)

  5. Avoid names that emphasize the implementation of a class. Names should emphasize the structure and evolution of a concept, not the fields of a class and their modifications. Unfortunately names like $getSize()$ and $setSize()$ emphasize that there is likely a field named $size$ . (See below for more).

  6. Don't abbreviate names. Ever. Always spell out your names and never abbreviate them. You will, over a lifetime of programming spend more time looking back for the definition of something you abbreviated to use it consistently than you will just typing it out in the first place. A few exceptions to this rule can be tolerated for standard things, but in general, you waste time abbreviating. The thing that makes programming hard isn't typing. It is understanding. Modern IDEs can help you with word completion, of course.

Note that good naming will usually mean that you need fewer (if any) inline comments. Providing java doc to document the intent and usage of classes and methods is nearly always sufficient.

Also note that I haven't mentioned the capitalization preferences in my standard, though I do observe and expect them: Bumpy case for most things. All CAPS for constants, etc. I'm more concerned with the clarity and instant understandability of the names in the above.

Teaching the Standard

For students to easily and naturally adopt the standard there are a few tricks that don't involve forcing students. The first rule is to be consistent yourself when you show them examples and when you test them. Even when teaching the lowest level concepts, you can have some metaphor in mind that guides your naming and makes the "problem space" rule natural. For example if you are teaching the a loop to sum an array, it is common to use an example like:

int x= 0;
for(int i = 0; i < n; ++i){
    x += y[i];
}

But this example has no semantic context. What is $x$ ? How is it related to $y$ ? How is $n$ related to $y$ . For experienced programmers this isn't an issue and if they already have good naming practice, an abstract example like this works fine, but it doesn't emphasize the larger lesson that naming is always important. You can just as well show them:

int totalPrice = 0; 
for(int i = 0; i < priceCount; ++i){
    totalPrice += allPrices[i];
}

or, for the absolute purist:

int totalPrice = 0; 
for(int index = 0; index < priceCount; ++ index){
    totalPrice += allPrices[index];
}

The structure is the same, but the relationship between the three variables is much clearer now. (Yes, $index$ is from the solution space, I realize.)

If you are developing an example in real time (black/white board...) you can have a mental metaphor before you start. It can even be fun to ask for suggestions from the students for a "problem space" in which you will create names (or even ask for them).

This is based, of course, on the idea that students will naturally emulate what you do. If you normally and naturally just use abstract names for things, then they will be lulled into thinking that it is ok to do so. So try, with beginners, to always give them some semantic context in which to think about problems.

The above goes for quizzes and exams as well. Give them (only) problems, even quite small problems, in which the names at least potentially mean something in a supposed problems space.

In doing OO programming the understanding of a program can be enhanced by using good variable names for objects. If you have a declaration

Particle x = ...

then a half a page later, when you see $x$ again, you want to know what can be done with it. What messages does it accept? So, say the following, instead:

Particle particle = ...

Now it is clearer what the variable refers to and so the student requires a much simpler mapping process to proceed.

In evaluating student work it is a good practice to note their poor naming when it occurs and ask them to improve it. The compiler doesn't care, of course, but you do, as you need to understand what they have written. Modern Java IDEs are good about changing names using contextual (not just textual) replacement. You can change the name of a variable from $x$ to $size$ without changing every "x" in the program as a word processor would do.

Miller's Rule of Seven (plus or minus two)

In a famous Paper in Psychology, George Miller suggests that the human mind is capable of simultaneously juggling only about seven concepts. Many of the rules of the naming convention above are informed by this rule. For example, one name per concept reduces the load of detail that the programmer much keep track of while thinking higher level thoughts.

Likewise naming from the problem space, rather than the solution space is helpful because the "world out there" is, itself, logically consistent, so using naming and concepts from there (or from a suitable consistent metaphor) keeps the number of concepts more reasonable.

Moreover, the very idea that our programs build higher level abstractions is informed by Miller's rule, since the abstractions we build are normally built on a lot of detail, that we abstract away in our classes and functions. Once we have built a class, we can think of the objects as a simple thing (the abstraction) rather than the detail on which they depend. Thus our limited capacity for detail is overcome by thinking about higher level things, upon which we build still higher level abstractions.

get-set considered harmful

Many teachers seem to use the JavaBean naming convention when teaching Java to novices. Students adopt this, thinking that it is a Java Standard. It is not.

JavaBeans, from Oracle, introduced a Java method naming "convention" that lets the system infer some things about objects. These are the "getter" and "setter" methods, normally used to get and set values of fields. However, I find that this "convention" is not conducive to teaching students good OO programming habits since the names themselves indicate to the student (as they do to the Bean system) that there is a field that is being retrieved or set. This is all about the implementation of the class, not the concept that it represents. It leads students to think in terms of implementation too early.

My preference in teaching students how to write a class is to ignore the implementation at the beginning and to think about the concept. One good way to do this is to develop a formal interface for the class using names from the problem space. What is is that an object should be able to do? What should it be able to tell me? Look at some potential code that refers to this interface to be sure that what you have is likely complete and sensible. Then, and only then, write the class. You don't need "getters" and "setters" since the fields are hidden and only used for implementation, rather than being exposed (even safely) to clients. I use the words "accessor" for getting information (not fields) and "mutator" for updating the state of the object. And, for other reasons, prefer mutators, using the "Tell, Don't Ask" rule of OO software that is discussed elsewhere.


Programs should read like poetry.

$\endgroup$
  • 3
    $\begingroup$ @VGR, the consistent contract is actually not dependent, externally, on knowing that a field exists. A mutator updates the state of the computation, somehow, not necessarily the state of a variable. Get/Set leads to an improper, overly mechanistic view. It forces low-level thinking when OO is about high-level thinking. If a mutator exists for logical reasons and later, when you build the class, the best implementation is a field, then it isn't a problem. The problem arises when you think about objects as bundles of fields, rather than bundles of behavior. $\endgroup$ – Buffy Apr 9 '18 at 17:18
  • 1
    $\begingroup$ I find point 6 a bit too strong and accept/write abbreviations if they are well known, either in the problem or solution space. I really prefer HttpProxy over HyperTextTransportProtocolProxy. ☺ $\endgroup$ – BlackJack Apr 10 '18 at 15:09
  • 2
    $\begingroup$ I know this might be a bit controversial but the idiom of using i as a loop counter has been around so long and used so widely, I think it's a bad idea to try to teach people not to use it. It's something the students will see in practice and if it isn't 'normal' to them, it will be harder to grok real production code. This form is the exception for loops now in Java; I it's not worth the trouble to try to change this. The loop counter becomes invisible if you follow the idiom and abnormal for loops are apparent. It's like the sign of an electron (negative): it's too late to change now. $\endgroup$ – JimmyJames Apr 10 '18 at 16:18
  • 2
    $\begingroup$ @GypsySpellweaver I've honestly never really understood why people have a problem with using i this way. Do people look at the for loop and wonder what the i variable is about? Frankly when people use something else, I find it distracting. In Java, the : ("in") syntax should be preferred anyway. $\endgroup$ – JimmyJames Apr 11 '18 at 13:39
  • 1
    $\begingroup$ @GypsySpellweaver With lcv you create worse code than with i because every reader except you will wonder what lcv means. i, j, k as index variable names are around even longer, because they are often used in formulas/mathematics. Even before any programming languages/computers. So that's a quite strong idiom. $\endgroup$ – BlackJack Apr 11 '18 at 14:02
6
$\begingroup$

Something I have used is to present the students with a paper form (like an application form). Each of the fields is labeled sequentially with A, B, C, etc. Then I ask the students to fill out the form with information about themselves and tell them that getting all the answers correct will determine whether they pass the course or not.

Of course, I immediately get questions about what goes in each filed? "Isn't it obvious?". After a little time I show a form that was filled out correctly. However, I use names in several fields that could easily be either a first name or family name (e.g. Paul, Kelly). In the short field between the two names, I put a "A". Most students assume it is a middle initial. Some of the fields contain numeric values values that could be almost anything.

Finally, I reveal the actual "names" of the fields. The short values between the names is labeled "Grade I expect to get in this class". The point of the exercise is to reinforce that the names of variables should define the information they contain. Otherwise, reading the code and understanding what is does is difficult, even for the author after only a little time away from it.

I follow up using short (often single line) helper methods in lieu of inline code. . For example, an if statement may have a complex set of conditions. I demonstrate how to pull this out into a single line function and, if the function is well named, how it makes code easier to read. For example I use something like comparing if (row == (numRows - 1)) vs if (atEnd(row)).

I'm not sure my experiment has really taught he students to create better names, but when I review student code, I do make comments on naming. I suggest that students read other code for conventions and adopt a "style" that suits them. I also suggest that when the students work in existing code, they adopt the style of that code. I believe consistency is more important that the actual convention.

$\endgroup$
  • 3
    $\begingroup$ "The names of variables should define the information they contain" - depending on the programming language, it could also be the name and type in the variable declaration. $\endgroup$ – Bergi Apr 9 '18 at 17:37
  • $\begingroup$ @Bergi, Given that we are talking about Java which is strongly typed, I strongly disagree that you should include the type of the data in the name. I've frequently seen identifiers like 'studentList' because the data structure happens to be a list, Even if a Collection is all that is required. When the code is refactored to make the variable another type of Collection, maybe a Set, the variable is never renamed. That said Units, if not guaranteed by the data type, should be part of the variable name e.g. 'timeInSeconds' $\endgroup$ – Stormcloud Apr 11 '18 at 15:50
  • $\begingroup$ @Stormcloud No need to disagree with me, I never said you should include the type in the name :-) I meant that the combination of name and type should define the information the variable contains, so you can keep the type separate from the name. It's irrelevant whether the language is strongly typed or not, it depends on the variable declaration syntax or how easy you can infer the type in the given context. List students = something;, var studentList = something; and var students = List(something); would all be fine. $\endgroup$ – Bergi Apr 11 '18 at 16:02
4
$\begingroup$
  1. When you are reviewing code with them, individually or as a class, make them fully describe any ambiguously named variable every time it is used. They will quickly tire of explaining it and will catch on if they don't have to explain the appropriately named variable. If they use abbreviations, make them spell the abbreviation without looking at the screen. (There are so many ways to abbreviate CompletedDate). You could also ramp this up by having a different student explain the code in front of the class. That will really help drive home the importance of descriptive names.

  2. Make sure they have an IDE that has some form of intelligence. I find one of the biggest reasons people justify poor variable names is because they don't want to type longer names repeatedly. There is no reason for that if the IDE has some form of autocomplete.

  3. Have students code modules that they must swap (or use yours), database tables or classes, etc. After they finish fixing the discrepancies, both students could lose points for bugs caused by naming issues, (Student A should have named things better, Student B should have paid better attention to the names). That can help drive the team strategy and importance of naming standards. Have them do a second assignment against the other persons names. After that assignment is complete, the students must switch back to their original tables and classes and fix their program again, which helps show what revisiting your work later can feel like.

  4. Deduct points if they use comments to describe a variable with a poor name.

$\endgroup$
  • 1
    $\begingroup$ Hi Wes! Welcome to Computer Science Educators! This is a great first answer, and I hope to see you around the site more :) $\endgroup$ – thesecretmaster Apr 10 '18 at 14:19
  • $\begingroup$ I really like the third set. It's truly amazing how soon one can forget what they just did once they've had to refocus on something else. Sure beats waiting 6 months for their thinking to get lost and the names to become important. $\endgroup$ – Gypsy Spellweaver Apr 11 '18 at 0:18
3
$\begingroup$

For me, the most important part is teaching why we talk about "naming" at all. I won't go into what are good reasons since you demonstrated in your question that you already know that.

Make sure your students know as well. You could, for example, concoct a few good and bad examples. For example, naming a variable number is bad because...; naming something xzyy is bad because...; naming something customer_contract_no is good because... Language X uses CamelCase-with-uppercase-first-letter to denotify constants. Why is it bad to use the same style for a variable name. And so on.

I would not teach any one specific naming method because there are quite a few different ones, and some current languages tend to use either. For example, CamelCase and Upper-SNAKE_CASE in the Java world; and snake_case combined with CamelCase in the Ruby world. UPPER_CASE in SQL, and so on. I would want my students to know at least these variants, but make very sure that they know that those are just examples. I would accept if they write software using any convention, in a test, as long as they adhere to their own choice.

There is a very easy guideline on which one to use: if they program in an existing environment (i.e., in existing source code), they must use the same convention that they already find in the code. If they create a new program they should use the generally accepted standard for that programming language (if there is one). They must take into consideration the standards of the business (or open source project, or...) they are working with. So this kind of flexibility is an important thing for you to teach as well.

$\endgroup$
2
$\begingroup$

For me, this question has a very simple and straightforward answer:

Make them read code. Not their own code. Each others code.

This will teach them the exact skill that is needed, instead of some intermediate implementation of that skill. The purpose of comments and naming standards is to make code readable.

As a teaching thing, let them write code as usual, with an explicit mention about clarity. Then let them exchange programs and explain someone elses code.

$\endgroup$
2
$\begingroup$

My answer is similar to that of Fritz Sieker, in that we both start on paper, but there are enough differences to post an answer of my own.

First of all, note that I've only tested this method on myself, so I have no guarantee that it is widely applicable. However, this would be my approach if I want to teach naming practices to others. Also, I will restrict myself to the naming of functions as 1) these are among the most important code artifacts to name (independent of language!) and 2) the methods I describe are easily adapted for other code artifacts (although it may be overkill for relatively 'low level' parts such as local variables)

How to start with writing a program

Before we worry about names, let's take a look how to start writing a program in the first place. When writing an essay or report, it is often most useful to start with a brief outline of what you want to say before actually writing everything down. (a top-down approach, in other words)

In my personal experience, this approach also works well for writing programs. First write a "rough outline" of your program on paper (e.g. For input with description X I want output Y. To do this I need functionality A,B,C and data structure D,...), possibly with diagrams or such. (In case the students don't get enough structure, simply ask them to split up a function)

How to name, then?

If you've followed my method so far, you now have a piece of paper with some functions or ideas for functionality that your program needs. As we have determined what we want from our individual functions, we can now give them the name that tells us most clearly what this function is supposed to do or represent. In fact, it is likely that there already is such a name on your paper!

So, the only thing that is left is to check whether you need to change the name to adhere to some conventions. But this is just checking for proper form, which is a lot easier than the proper meaning of the name. In other words, we have already finished the task of finding proper semantics. Finding proper syntax to express it is easy in comparison. (This is a rather mechanical task and some IDE's can even check this automatically!)

Alright, we've named our stuff. Good, however...

Isn't all this paper stuff a waste of time?

...your students may ask. And perhaps they are right. However, there are good reasons to use the paper:

  1. It is important to let the students start with an outline. This comes very naturally if they start on paper, but can easily be forgotten when starting with writing the code immediately.

  2. Although an experienced programmer can often just start writing a function and naming it properly afterwards, this is only because this programmer has already mastered (something similar to) creating program outlines and has the outline in the head.

    As we don't expect our students to be able to do this in their head, giving them paper seems like a good idea.

So, the paper may be overkill for the experienced programmer, but is a useful educational tool for teaching proper program structure and naming.

$\endgroup$
1
$\begingroup$

A bit tongue-in-cheek, but

make a contest-winning colleague tell them they use descriptive variable names to their advantage.

That is what worked for me (however, I was also starting in some competitions, so maybe I was more likely to listen). People starting in programming competitions, where the time is limited, may be expected to cut their variable names to be as short as possible and gain some margins on typing while looking more hacker-like. So when the winning one says that typing time doesn't matter, but having clear name saves him time, it should make you think. As stated, it actually made me start a shift toward longer names. That specific talk was obviously about C++, but applies to any language really.

Encourage reusing their code

I'm not sure how viable way it is, but you can try building subsequent tasks on top of each other, encouraging code reuse - preferably with some tweaks necessary. If you make a few iterations of that, giving clear hints that the code will be reused and good naming will help, at least some will simply try - and find it works.

Encourage treating variables as cheap and creating new ones for intermediate results

This may be simpler done in functional languages, where you are kinda forced to store intermediate results each time in a new place with a new name, but should work in Java as well. Just lead by example, putting intermediate results in named variables wherever it makes sense (i.e. serves a documenting purpose - int fooPlusBar = foo + bar is obviously a bad thing to do).

For some people it may be important to note that the compiler may optimize out or even create variables, so the actual cost of adding them is both none-to-negligible and hard to estimate (i.e. they shouldn't care).

$\endgroup$
  • $\begingroup$ Hi Frax! Welcome to Computer Science Educators! This is an interesting answer that I certainly wouldn't have thought of myself. I hope to see you around the site :) $\endgroup$ – thesecretmaster Apr 11 '18 at 1:07
0
$\begingroup$

The other answers have some really good techniques, the only insight I can add is that learning to give things useful names is something that's going to take many years to learn, so it's useful to keep that perspective in mind when they don't seem to make visible progress.

While there is some uncertainty over who said it first, it's a generally accepted rule of thumb that an author will produce at least a million bad words before they start producing stuff worth reading.

While the subject can be quite mathy, fundamentally programming is writing, so the same principle applies.

Have them practice as much as you can, absolutely use the techniques in the other answers to teach them how critique and improve their own work - because naming isn't really something that can be taught directly, and they probably aren't going to get noticeably better at it until well after they've graduated.

$\endgroup$
  • $\begingroup$ I've downvoted because having patience and being understanding are things which you should be doing anyways. They're relevant to all teaching questions, and so this answer isn't specific to this question. $\endgroup$ – thesecretmaster Apr 10 '18 at 5:24
  • $\begingroup$ @thesecretmaster, true it's not a difference of kind so much as degree. I'll try to clarify in my answer that it's going to take on the order of years to learn this, so a level of patience is called for above and beyond what would normally be expected. $\endgroup$ – Morgen Apr 10 '18 at 5:44
  • $\begingroup$ Thanks for editing, I've retracted my downvote. I think the advice you're giving is good, but it doesn't seem like a complete answer to me -- this alone, without the other answers, wouldn't really answer the question. $\endgroup$ – thesecretmaster Apr 10 '18 at 13:11
0
$\begingroup$

What methods will work depends, in part, on the teaching style. The effectiveness of any method also depends on the instructors consistency in presenting, and using, what's being discussed, and on the costs associated with following vs. not following the set guidelines. Students are no different than any other group of people, and decisions, including unconscious choices of what practices to adopt, are made on the margin. It is not the value the guidelines, or conventions, hold for their future selves that are significant in what they do. Rather, of importance to them now is what benefits they get now by following them, or what costs they pay now for not following the guidelines. "The costs now weighed against the (perceived) benefits now."

I have another answer that deals with the "value" aspect on the How to teach the value of the command line in high school? question, so I'll skip over that. Basically, you can force (require?) the students to do something. Their grades, and there possibility of graduation, may well depend on that performance. You cannot, on the other hand, make them believe, or think, something. You can, however, sell ideas, and lower the costs so that they will likely "buy-in" to the ideas.

The course outline, and the progression of subject matter might not allow this approach, but the method of development that Dijkstra presents in his "Step-Wise Program Composition" example¹ seems to be perfect for automagically creating meaningful names. It is also language agnostic until the very end, which makes it usable in any environment, except possibly the classroom - if the lessons are required to go from low-level to high-level.

As a bonus, if that method is used as the design process, you can use the same project, notes, slides, and handouts for classes in every language, and adjust the final pages for the language of choice. In any case, importance comes from the fact that there is no other way to know what each "machine" does except by its name. No code has been written that explains it, only the name exists. The "skill" is taught, like any other skill, with lots of corrected practice².

As to which teaching practices lead to, and which impeded, the development of good naming practices, it's the same answer: the instructor's behavior. As noted in other answers, if you're consistent in the use of the guidelines in everything you present to them, they will come to accept it as possible. Until then they will be thinking that it's just not possible to always use intention revealing names. The off shoot of that thinking is that if it's not always possible, then it cannot always be required, so using it only when convenient is excusable. If you never fail to use such names, even in disposable, on-the-board examples, then it becomes possible to always use them (you've proven that), and there is, therefore, no grounds to argue for exceptions. The reverse is just as true, and more treacherous. If, sometimes, you slip up, and don't use such names, you've demonstrated that sometimes programmers will not use such names. Even the instructor doesn't do it 100%. If the instructor doesn't always use intention revealing names, why should the student?

I believe the argument that naming is important in the creation of quality software is a bad choice, if not a red herring. First off, the quality of the software does not seem to be related to the names used. If so, programs written in machine code would be abysmal since machine code admits of no names whatsoever. Secondly, I'm quite certain that it's possible to find one or two examples of non-quality software that does, in fact, have good naming throughout. The quality of the software is not related to the goodness of the naming. The ease of understanding the software, now or in the future, by the author or by others, is affected by the naming. The majority of the code created in class projects is disposable code. There is no value to the students in making it easier to fix, modify, or upgrade later because there is no later for that code. That takes us back the the margin, and in light of the marginal costs vs. marginal benefits maintainability is going to loose the majority of the time.

1: EWD249 Notes on Structured Programming - E. W. Dijkstra, ppg. 50 et seq.

2: "Practice doesn't make perfect. Perfect practice makes perfect." - Vince Lombardi

$\endgroup$
  • $\begingroup$ As much as i enjoyed your answer I have to express my profound disagreement with your last paragraph. Proper naming is about maintainability which is the most important/expensive in software's lifetime. "it works" has no value if it can't be maintained effortlessly and cheaply. This is real life. And since a good part of good programming is good habits it pays to get into that habit. $\endgroup$ – Elkady Apr 22 '18 at 20:36
  • $\begingroup$ Another comment about your last paragraph: I'm not sure what you meant by "machine code". If you really meant machine code (i.e. 1s & 0s circa 1940s) then i'd add that assembly language emerged from this as the need for naming the 1s & 0s instructions to make them easier to read and debug. It stared by being programmers' written abbreviations on paper for given sets of 10&0s do and evolved into today's assembly language $\endgroup$ – Elkady Apr 22 '18 at 20:43
  • $\begingroup$ @Elkady Other than using hex more often than binary, your interpretation of machine code is correct. Not all machine code has been converted to assembly, yet has been producing quality software without "good naming". Yes, names help coders, and where common conventions exist, following them improves the ease of maintenance. As to the OP's question, re: importance of good naming to quality software - it is still a red herring. Good names don't make bad code good and bad names don't make good code bad. $\endgroup$ – Gypsy Spellweaver Apr 22 '18 at 21:45
  • $\begingroup$ you'll get no argument from me. I see it was a matter of interpreting what "good code" means. Neither is wrong, just different views / schools of thought that was/is debated infinitly for ages. $\endgroup$ – Elkady Apr 22 '18 at 22:51
  • $\begingroup$ Good software is a living thing. Good naming makes good software evolution easier, at lower cost. $\endgroup$ – Michel Billaud Apr 23 '18 at 14:44
0
$\begingroup$

Although this is a very late reply, I still wanted to add my answer. Previous answers are so informative and detailed in explaining why but i feel it is short on the how (in realistic terms).

From what I see in teaching: students look at good naming practice as us (instructors) telling to do yet another unnecessary thing just to make their life difficult with "all this theoretical/principal stuff".. In most cases they will disregard it.

My solution for this was simple: "you should do this because it is good in this way and that" alone is not enough. So, I point them to the coding-style rules for some major companies (many can be found online, Google is an example) and explain to them why the high-tech industry changed their 90s outsourcing model because of loses cased by bad code quality/maintenance (cost of support/fixes greatly exceeds cost of software). From this point on, they sure listened and followed proper coding practice.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.