23

I'm going through an introductory programming book and it lists a simple example in pseudocode:

Start
  input myNumber
  set myAnswer = myNumber * 2
  output myAnswer
Stop

Why can't we omit creating another variable called myAnswer and just put the operation into the output command, like this:

Start
  input myNumber
  output myNumber * 2
Stop

Why is the former correct and latter not?

Deduplicator
  • 8,591
  • 5
  • 31
  • 50
user1475207
  • 349
  • 2
  • 5
  • 39
    Does the book say you can't? – Tulains Córdova Jul 10 '17 at 19:41
  • 2
    The book does not say that I can't; it doesn't say anything about it. – user1475207 Jul 10 '17 at 19:44
  • 5
    I think it's quite reasonable to start out with the shorter second block, then convert to the first if you need it. – Mateen Ulhaq Jul 10 '17 at 21:44
  • 13
    Short answer: you can, the author is just doing this (in an attempt) to make it clearer (although honestly, it probably doesn't actually make it clearer at all...). – Jules Jul 11 '17 at 00:36
  • 1
    Both ways work. With more experience you will find, that for serious coding readability is far more important than simplicity or originality of the code. Your code should be easily readable by many others maintaining it. – Frantisek Kossuth Jul 11 '17 at 08:58
  • BTW, an excellent introduction to programming is [SICP](https://mitpress.mit.edu/sicp/), freely downloadable. I recommend reading it too! – Basile Starynkevitch Jul 11 '17 at 11:15
  • In addition to @BasileStarynkevitch's suggestion, I want to suggest [*How to Design Programs*](http://HtDP.Org/). It has similar goals to SICP, but requires less domain knowledge. – Jörg W Mittag Jul 11 '17 at 11:46
  • Be sure to check out these 2 books once you think u r ready to code "Clean Code" by Robert Martin and "Refactoring: Improving the Design of Existing Code" by Martin Fowler. – Songo Jul 11 '17 at 13:16
  • There are no formal rules for pseudocode (that's exactly what's "pseudo" about it), so it can't really be "correct" or not. When someone shows you some pseudocode it basically means "the details of specific programming languages are not important to what I'm telling you; I'm just going to make up and use some language features *that I assume will be obvious to my audience*". As such each specific use of pseudocode is basically its own "programming language". The author probably wants to keep "outputting" and multiplying as separate steps to make things clear for beginners. It isn't important. – Ben Jul 12 '17 at 02:56
  • Another remark that was not mentioned here is that for compiled languages, most compilers would optimize this difference away, meaning that you won't loose time creating a variable that you don't actually use, and reducing this to a question of readability rather than execution. – Maxim Jul 12 '17 at 08:19

6 Answers6

36

You could but the other is so you see what is going on and so you can use myAnswer later in the program. If you use your second one, you cannot reuse myAnswer.

So later down in the program you might want:

myAnswer + 5
myAnswer + 1
etc.

You might have different operations you want to use it for.

Consider swapping numbers:

Start
  input myNumber
  set myAnswerA = myNumber * 2
  output myAnswerA
  set myAnswerB = myNumber * 3
  output myAnswerB
  set temp = myAnswerA
  set myAnswerA = myAnswerB
  set myAnswerA = temp
  output myAnswerA
  output myAnswerB
Stop

That would be difficult without variables. Computer books start real basic, and most programming is easy until you see complexity. Most everything is trivial in tutorials, and it is only in complexity do you see where things do or do not make sense.

johnny
  • 3,669
  • 3
  • 21
  • 35
  • 1
    So it's valid logic but it's not best practise because it does't allow me to reuse the operation in other parts of the program? – user1475207 Jul 10 '17 at 19:45
  • @user1475207 See my edit. In this tiny program it doesn't matter. The author knows you'll be doing much more than outputting the value later on. It is only in complexity you get to see this. Stick with it. – johnny Jul 10 '17 at 19:47
  • ah ok, I see. I'll continue through the book with this in mind. Thanks. – user1475207 Jul 10 '17 at 19:52
  • 29
    @user1475207 Both ways have their place. Sometimes you may have to use the extra variable. Sometimes you may not need the extra variable but want to use it anyway because in some situations, just giving something a well-thought-out name makes it that much more clear. Sometimes you don't want to use the extra variable because it's just added noise. And many times, the difference doesn't really matter. – 8bittree Jul 10 '17 at 20:16
  • 3
    I think it's valid to return the result of an operation without assigning it to a variable beforehand. But I took the habit to create a `result` variable even for short functions, so that debugging by adding `print(result)` is really fast. It's more out of convenience than good practice though. – Right leg Jul 11 '17 at 09:17
33

Another reason, The assignment set myAnswer = myNumber * 2 gives the resulting value a name. A person reading the two line version of your code only knows that it prints out the value of myNumber * 2. A person reading the three line version can see that myNumber * 2 is the answer.

It may not seem important in such a trivial example, but sometimes, assigning a result value to a variable with a meaningful name can make it much easier for other programmers to read and understand your code.

Solomon Slow
  • 1,213
  • 9
  • 14
  • 10
    +1, although this ***only*** applies when the name is meaningful. Using temporary vars like this named `i`, `result`, or some other meaningless identifier does nothing to improve clarity, and only clutters the code – Alexander Jul 10 '17 at 21:59
  • 2
    C# even added `yield` to remove the need for return-only collections. – IllusiveBrian Jul 10 '17 at 22:28
  • 7
    @Alexander: Meaningless names can still be meaningful. `i` had better be an array index. If there's a `result`, the function ought to end with `return result` or the moral equivalent. And so on... – Kevin Jul 11 '17 at 00:55
  • 6
    @Kevin "Meaningless names can still be meaningful" uhhh... are you sure? lol – Alexander Jul 11 '17 at 01:47
  • 3
    @Kevin If you're going to `return result`, then you may as well just inline to return whatever you were assigning to result. We can see it's a result. You're returning it, we get that. – Alexander Jul 11 '17 at 01:47
  • 5
    @Alexander: Obviously you can inline the return if it's a simple expression, but what if you need to build it up over multiple statements? Using a consistent naming scheme makes it clear what you are doing in these cases. – Kevin Jul 11 '17 at 06:17
  • 3
    I'd also remark that, while meaningful names are generally good, they're particularly good if actually visible to the _user_. I.e. rather than introducing a local, temporary result-variable with a meaningful name, one should name the _function_ in which all of this happens. – leftaroundabout Jul 11 '17 at 06:58
  • 2
    @Alexander I'd argue that `myAnswer` is in no way better than `result` and `i` is meaningful to most programmers as loop index or similar. I do agree with your point in general though; I just think you could have picked better examples. – TheLethalCoder Jul 11 '17 at 09:04
  • @leftaroundabout Yeah, purpose-built function with good names are a +1 from me – Alexander Jul 11 '17 at 14:30
  • 2
    @TheLethalCoder Yeah, `myAnswer` falls in the category of "poorly named". Basically what I was trying to communicate earlier was that if a expression is to be extracted to a variable, then it should be given a name above a certain level of "meaningfulness", otherwise there's no point, and it just clutters. Perhaps one exception is if it's used to simplify a really big expression, and no good name is viable. Also, when I was talking about `i`, I didn't mean just a typical loop index, but you see people storing numbers as `x`, `i`, `number`, etc. – Alexander Jul 11 '17 at 14:34
  • 1
    In the case of a returned value though, it's typically more useful to name the function something meaningful. I'd rather infer the meaning of the return value from that and not have to dig into the implementation. – aw04 Jul 11 '17 at 19:31
14

That's pseudocode. It's not supossed to be any particular implemented language.

Some programming languages don't support evaluating an expression and then outoputting the result in the same line of code. For example most assemblers do not support that. Perhaps the author of the book wanted to show things in a low-level fashion.

Tulains Córdova
  • 39,201
  • 12
  • 97
  • 154
  • 2
    And some languages (for example C) allow both at the same time - you can write things like "output (answer = answer * 2)" if you really want to! (but beware than "output (answer == answer * 2)" means something quite different... – alephzero Jul 11 '17 at 08:43
9

Other answers have addressed the specific mechanic details and examples of when one or the other form would be better, but I want to mention a little further background, sort of philosophical:

You're learning a language.

A language is something in which ideas can be expressed and understood (communicated). A computer programming language has the additional property that it can be mechanically parsed by a machine designed to take action (execute) based on ideas (decisions) that are specified and fed in using that language.

In ANY language that's at all useful, there is more than one way to express nearly any idea expressible in that language.


Consider the wide variety of nuance available in the English language. Even a simple sentence, such as

The cat jumped onto the box.

can be varied to express slightly different ideas or place emphasis on different parts of the scene while referring to the same exact physical universe action.

First are grammatical variations:

The box was jumped onto by the cat.

Onto the box jumped the cat.

Then are wider and wider variations, still referring to the same physical action:

The box shook under the impact of the cat.

The cat came down with a thud upon the top of the box.

The feline leaped lightly into the air and landed neatly on a nearby box.

Just look at the implications of the word "nearby" in that last sentence. Its inclusion conveys a whole new range of concepts not otherwise present.


There is always more than one way to do it, Python Zen to the contrary.


Of course, there will be ONE way which perfectly expresses your intention and is most suitable, just as you would choose only ONE of the English sentences above depending on exactly what you wished to communicate. That's what the Zen of Python is about.

But in an introductory programming course or an introductory English course, you must first learn the various ways (wordings, code snippets) in which you can couch an idea before you will develop the judgment to choose which is most perfectly fitting.

Wildcard
  • 544
  • 3
  • 14
  • 3
    Of course, Python breaks its own rule. You have lambdas and nested functions; loops, list comprehensions, and generator expressions; floats, Decimals, and fractions; and `__init__` and `__new__`, just to name a few. The point is that each is appropriate to a subtly different problem. You wouldn't pick one of those English sentences at random, nor would you pick one of these Python language features at random. – Kevin Jul 11 '17 at 01:02
  • 1
    @Kevin, yes, agreed. The point is that for someone *totally new* to programming, the exactness of the syntax required *can* make it seem that there is only one way anything can be accomplished—i.e., copying the *exact* code from the tutorial verbatim, similar to how middle school math problems (573 x 247) have only one right answer. See also questions like "What is **the** program to shrink files?" If you read my answer, I'm not saying to do anything at random; I'm saying that **you *are* always making choices** when you program. – Wildcard Jul 11 '17 at 01:11
  • 1
    That's certainly fair. I think the problem is that you're kind of simplifying/misrepresenting the Zen of Python a bit. The whole point is that those decisions are ultimately dictated by the contours of your problem, and not choices you can make freely. You may need to go through a lot of iteration and refactoring to find the *one* way to do it, the one way that perfectly fits your requirements, is readable, concise, even elegant. But for any given problem, there should be such an ideal solution, and a well-designed language will gently guide you towards it. That's what the Zen means. – Kevin Jul 11 '17 at 01:19
  • @Kevin, agreed again. See edit; I hope that clarifies my stance better. :) – Wildcard Jul 11 '17 at 01:25
  • 4
    A cynic might say 'In Python there is only one way to do it, but every new version of Python applies the "and now for something completely different" function to the way the previous version did it' ;) – alephzero Jul 11 '17 at 08:46
  • 3
    quote from PEP20: "There should be one—and preferably only one—obvious way to do it. Although that way may not be obvious at first unless you're Dutch." –  Jul 11 '17 at 14:54
5

You are asking only about the myAnswer variable that seems to be redundant. Other answers already explaind some of the why and when it would make sense to omit or use it but here's one more: how about this?

Start
  output input * 2
Stop

or even that

Start output input * 2 Stop

In most languages this would still work but can you read it? It's difficult so we often use helper variables because computers are not the only ones who read the code. We need to maintain it and understand it in few months and it's even harder to write code that you can still unterstand later then a working one... usually after only a few days you won't know why you did something in a specific way.

t3chb0t
  • 2,515
  • 2
  • 21
  • 34
  • 2
    ...or even just `(*2)`. I would object, however, that performing input can't necessarily be expressed safely as just accessing a variable / performing an arithmetic operation: it can have observable side-effects. – leftaroundabout Jul 11 '17 at 08:25
2

You can do both variants (in this simple case), but the first variant becomes more readable and structured for more complex cases. The first variant shows the IPO model with one line for each step (two of those already with the right name):

Start
  input myNumber                       // Input
  set myAnswer = myNumber * 2          // Process
  output myAnswer                      // Output
Stop
Raidri
  • 129
  • 5