Module 5: Questions and Answers

Some of our TAs have put together some short videos of answers to commonly asked questions from Module 5:

And here are some of questions that I found interesting and my answers:

Q. Why are we taught iteration before methods?

A. This is a somewhat arbitrary choice....Although some comparable courses introduce functions/methods first, doing iteration first is more common. One advantage is that we can do more meaningful methods (because they can include iteration and if-statements). It also has a slight benefit to people who drop the course --- some people will use computing for very simple tasks, like automating some day-to-day activities, that may require iteration but not creation of new functions. If such people only took about 1/3rd of CSE131 they would still experience these critical concepts.

Q. Whats the difference between a function and a method?

A. The two terms are occasionally used interchangeable to mean a self-contained piece of code that does some work.

  • "Method" is technically the correct term to use for the types of things we've been doing in Java.
  • The term "function" was common in early programming languages where the computation was mainly about computing mathematical formulas and the "functions" in code were often analogous to functions in math. That is, they are provided arguments, perform some computation using the values of the arguments, and result in some value (the returned value).
  • Sometimes the term "procedure" is used to describe a piece of a program that may have arguments but just describes a process for doing something rather than constructing a returned value.

For example, early programs may have used functions to compute the change in altitude of a missile during each 0.1s of flight and a procedure may be used to print a table showing the entire path of the missile over a 1 minute flight. (The procedure for printing the table may use the functions to compute the changes in missile's location). Java is an Object Oriented Language and the term Method refers to a piece of code that is a part of an object / class, so everything we've done so far is a method. We'll talk more about this in Module 7. (The term method outside of computing usually refers to "a way of doing something", like a laboratory method is a precise set of instructions for doing some lab task. In computing a "Method" is a precise set of instructions for an Object to do something).

Q. What's the difference between void and non void f(x)s? How does a "void" method actually function/execute differently, and how do you decide which to use?

A. A "void" function isn't like a mathematical function --- it doesn't "return" a value. Usually "void" functions/methods represent the concept of procedures and non-void functions/methods are used where a piece of code is generating some single answer/result, like a mathematical function. The only difference in their execution is that non-void functions will "return a value" (by leaving the returned value someplace, like on the stack) and void functions will not. So when a non-void Java method returns, the stack has the result on it.

Q. Can you return multiple things in a method?

A. Yes and no. Most programming language, including Java, allow a single "thing" to be returned. But that "thing" can have multiple parts. For example, if you needed a function that returned a 2D point that has x and y coordinates you can't return two separate values, but you could return ONE array that CONTAINS two values (a better approach would be to create a Point class with x and y fields and return a single Point object...See Module 7).

Q. When should we use the function abstraction, and what kind of functions could be combined together?

A. There aren't many solid rules here, but here are some guidelines:

  • Use methods for repeated work. Don't copy/paste code --- use a function instead.
  • Use methods for a "generic" type of work that may be used in multiple programs. (Think about how a process/computation may change depending on a few key values and consider those to be the "parameters")
  • Use methods to help break a complex program into smaller, more understandable parts. I've know people who consider either 1 screen or 1 printed page the "limit" and anything that's much longer gets broken into a few methods. This helps ensure that a normal person can understand each individual part of code in a modest amount of time.

Q. Why is using methods more useful than just typing the code?

A. Because I'm lazy and typing code can be tedious and error prone. For example, if we're writing a program to compute some formula and round it to 2 decimal places we could copy/paste the rounding code everywhere we print a value or we could use a single method to do the rounding. If we later decide to round to 3 decimal places we'd either have to 1) search/update all the places that do the rounding in our code in the copy/paste approach or 2) just update the rounding function in one place in our method-based approach. Often programs are smaller, easier to understand (due to abstractions), easier to write, and easier to debug if they are crated using appropriate decomposition into small, meaningful methods. Modern programs are HUGE. It wouldn't be possible to create them and have them work as reliably as they do without some techniques to help us manage the complexity. Methods/functions are one of the major techniques we use.

Q. How commonly used is Method? Do professionals use it on a daily basis?

A. Very common. I don't know of many "real" programs or apps that use another approach. A large part of what professionals in computing do is string together existing code (methods/functions/etc.) to accomplish new/different work.

Q. Does it ever get easier?

A. If you're asking about the topics/assignments we're currently studying, yes, with deliberate practice Links to an external site. and experience it gets easier to do these types of things, but there are also other challenges with newer topics and larger projects. That's one of the things I enjoy about computer science --- there's always something new/interesting/challenging. (I'd be really really bored otherwise). Of course, I can't say that the remainder of the course will feel "easier" because you're going to continue to experience new topics. On a more meta-level, life as a college student (and life in general) has it's ups and downs. I find this time of semester to be very very busy and stressful, but the beginning of every new semester seems a lot easier.

Q. Why in this exercise everything has been written above public static void main(String[] args) {} ??

A. It was a somewhat arbitrary choice. They could also be written below it. We sometimes order things to make it easier for students to read just part of the file. For example, if we have written a main() for you and you don't need to modify it, we may put it at the bottom so you can focus on the things at the top of the file.

Q. Why can't I return inside a for loop?

A. You can, with some restrictions. The following work fine:

for(int i=1;i<1000;i++) {
  if(i%100==0) {
     return i;  // Silly. Just returns 100 (no need for a loop)
  }
   System.out.println(i);
}

or:

for(int i=0;i<1000;i++) {
    return i;   // Silly.  Just returns 0. No need for a loop.
}

But you can't have code after a return statement. If the code will return, the next statement(s) will be "unreachable". Here's a slight variation of the above that includes "unreachable" code and won't compile:

for(int i=1;i<1000;i++) {
  if(i%100==0) {
     return i;               // Silly. Just returns 100 (no need for a loop)
     System.out.println(i);  // Unreachable -- the return will "return" before getting here. It won't compile
  }
}

Q. Why are these methods static?

A. For now we're using static so we can access the methods easily (without having to create an object). Notice that we've been doing things like:

public class MyClass {
  public static myMethod(int i) {
    ...
  }

  public static void main(String[] args) {
    ...
    myMethod(123);   // Call the method
  }

Since "main()" is static it can only call methods that are also static. If we removed the "static" from myMethod() we couldn't compile and run the code like this. For now, it's enough to know that static methods, like main(), can only easily call other static methods --- so we're making all our methods static (so they can be called from main()). This may lead you to wonder why main() is static. There isn't a short, simple answer, but it's because there's only one starting point to any program and static designates something as unique or unchanging or "a single one of". There's a "single starting point", so main() is static.

Q. What is the meaning of public and static?

A. These will all be covered more in Module 7 (Objects), but they actually represent two different concepts. There are the notions of public, private, protected, and "package-private", which are about Controlling Access to Members of a Class Links to an external site.. Whereas static is used distinguish things that belong to a class as a whole rather than to an instance of the class. (Again, this will make a little more sense after Module 7)

Q. Why isn't my code working?

A. It has a bug Links to an external site..

Q. What is this for loop with String w : words?

A. This is referred to as the "for-each" style loop. Right now we're using arrays to store data, but there are other approaches (we cover some later in the semester and they are a significant part of CSE247/Data Structures And Algorithms). Arrays use the notion of an index to access data, but other means of storing data don't, so using a for-loop to count through indices doesn't make sense. The for-each style loop makes it easy to focus on the loop's meaning --- it's going through each item in some collection, while hiding the details of just how it's doing it. This is another variation of "abstraction" that helps us write meaningful code and makes it easier to read. For more details of why this makes code much easier to read see Oracle's guide to the for-each loop: The For-Each Loop Links to an external site..

Q. Isn't the debugger practically useless? Observing the operations executed using a debugger might only work in case of the programmer's knowledge of the final code result, which is not necessarily, even rarely, the case.

A. Modern programs are very very complex and debuggers are one of many tools and techniques that help us cope with that complexity. Of course, once programmers no longer write buggy code they won't be necessary....but I don't see that happening anytime soon. I suspect everyone in the class will experience a mistake in a program where what they typed isn't what they meant. For example, an if-statement that checks the wrong variable or adding a wrong value, etc. Debuggers can help us spot these sorts of errors. There are also a lot of cases where we may not know the exact thing we want to happen, but we can detect when things have gone wrong. Debuggers can help us identify the conditions that caused things to go wrong and revise our understanding of the problem/solution.

Q. Can program step back while using debug?

A. I'm not aware of Java debuggers that do this, but some other programming languages and debuggers support stepping backwards, often with limitations. Going backwards is very very difficult in many cases --- some operations can't be "reversed", so there must be a history of how everything has changed. It's somewhat like using the "undo" feature on word processor, but even simple programs can have billions of operations that would need to be "undone". Storing all those changes takes computer memory and time.

Q. Going forward, would it help to use the debugger on our code to find issues?

A. This is a tricky issue. It's important to be self-conscious when using the debugger. Yes, the debugger can help you gain much greater understanding of how your code behaves and can help you find problems. That being said, it's easy to be over reliant on it and watch each tedious step of the program when it would be better to stop and think about the behavior instead. Perhaps before using the debugger you should consider one of the two following criteria: a) Can you run an "experiment" to test you code. That is, make a hypothesis (ex: variable x will become y which causes an error), configure the debugger to help you test the hypothesis, and "run the experiment". Or b) Do you know where an error is happening but you need more information to determine the root cause. For example, do you know that you are dividing by zero somewhere, but you're not sure where or how the 0 is being used in a set of equations. If so, you can use the debugger to inspect all variables involved in the calculations.

Q. Should debuggers be used all the time or only when something is wrong or not being processed correctly?

A. There are exceptions, but for now (CSE131) only when you are trying to find and fix a bug and the debugger will help you do so. Running code in a debugger typically has a "cost" --- Code runs slower and/or takes more memory.

Q. I am wondering why the debugging tool seems so archaic, or is it not compared to other IDEs?

A. The Eclipse Debugger is a pretty typical example. It's actually a very very powerful tool, but the course only introduces the basic concepts rather than its full capabilities.

Q. I wonder how someone could use the debugger if their code runs for a really long time. For example, if a program was designed to analyze a sequence of DNA, how would someone use the debugger if there might be thousands of tedious steps involved, only one of which might be incorrect?

A. Using "breakpoints" or "watches" is the key. Breakpoints allow you to stop your program at a key point in your code and only look at the details at that point. Watchpoints allow you to "watch" for a particular condition and only stop the program if the condition happens. For example, if you know that the program crashes when variable x becomes 0, you can "watch" for the condition to happen and only step through details when x is 0. There are also Exception Breakpoints and Condition Breakpoints. For more info, see Debugging the Eclipse IDE for Java Developers Links to an external site..

Q. Can I use a debugger multiple times in one piece of code?

A. Yes. You can use multiple breakpoints or watchpoints and just "debug" when there is something of interest and let the rest of the program execute like normal.

Q. Is there a system that combs through the code like the debugger, but automatically tells you the exact issue and how to fix it?

A. Nope. There are other types of tools that assist in other ways, but for now "debugging" still requires human understanding and ingenuity. (This is one reason there are great career prospects in computing --- we can't be replaced by a program yet!)

Q. What is the debugger bad at catching?

A. The debugger helps you examine how an existing program is behaving. It won't tell you what is wrong with it though. Debuggers also interfere with the timing of programs, so they often don't provide much assistance with errors that are sensitive to the timing of execution ("Race-Conditions Links to an external site." are one example).

Q. Can a method be written inside of another method?

A. Yes and no. This is a form of nesting, like we say with loops and if-statements. In some programming languages nesting functions is much easier than in Java, but there are two common approaches in Java: 1) Using a nested class that includes the function/method. Classes/objects are the topic of Module 7 (and 8-9). One common approach that is beyond the scope of this class is the use of "Anonymous Classes Links to an external site.". 2) Recent updates to Java support an approach called Lambda Expressions Links to an external site.. Lambda expressions are another common concept in many programming languages and are a very powerful, compact way to do many things.

Q. Will we ever deal with private methods?

A. Yes. This will be covered in Module 7 on Objects and Object Oriented Programming.

Q. Do you have to re-create a method (e.g. rounding to two decimal points) each time you are in a new class? Or can you create it on a larger scale to call whenever you want?

A. No, you can create a library or class that gets used in multiple places. StdDraw was created by a few people and used in many programs and by many people --- there's nothing stopping you from creating your own set of "reusable" code.

Q. I am still confused about the concept 'object reference'. Can we say that, an instance variable is an object reference?

A. There's a lot of subtle terminology here. An "instance variable" (or field or property) will be covered more in Module 7 on objects. I'll focus on the two different types of variables: 1) the "primitive types" (int, double, boolean, char, and a few others) and 2) the objects (String and other things created in a class).

  • You can think of variables for primitive types as being a box that literally contains a value. It is directly the value.
  • You can think of variables for object types to be a box that contains an "arrow" to the actual value. That is, it is an indirect way to get to a value.

This concept of direct vs. indirect makes a lot more sense with diagrams. Here's an older page from Wellesley that I think gives a pretty good overview of the way I typically try to explain these concepts: https://cs111.wellesley.edu/~cs111/archive/cs111_fall97/public_html/lectures/ObjectDiagrams/object-diagrams.html Links to an external site. (Hint: Understanding this could really help you with exam questions) I also like these videos, which help explain primitives vs. references:

Q. How would this apply to simulations?

A. There are many different types of simulations, but most use a loop to represent the concept of advancing time (games often do this too). They may use functions to update the "state" of the things being simulated. Simply changing this update function can change what you're simulating or how you're simulating it.

Q. Could methods have been useful to make the code from previous labs shorter?

A. Yes! Since you need to get some credit on extensions anyway, I suggest you do Extension 5.1 and re-do a previous lab or extension using methods for 3 points of extension credit. Lab 2 (Nim) would be a great place to use methods!

Q. Stacks??? Can you explain more in detail?

A. Yes and no. We'll cover the stack (a run-time stack) more in Module 6 on recursion. Stacks are also covered in a variety of places: CSE247 (Data Structures and Algorithms) talks about stacks as an abstract data structure, CSE132 (Computer Science II) introduces the run-time stack in assembly language, CSE361 (Introduction to Systems Software) also covers the run-time stack.

Q. Is Stack based on Array?

A. The stacks shown in the video look very array-like and are using computer memory in an array-like way. The concept of a "stack" is really about how data is being used (last-in-first-out) and the term "stack Links to an external site." indicates this particular abstract concept without implying much about the details of how the data is actually managed. Some implementations of stacks do use arrays. Others use "linked nodes". Abstract Data Types, like the stack, will come up again later in the semester and are a major topic in CSE 247 (Data Structures and Algorithms).