
Part of the reasoning behind only providing the engine sources is that we want to deter you from hard coding any solutions. Most of the problem set asks you to extend the functionality of the engine and create the necessary instantiations. Keep your solutions as general as possible.
Also, you should note that line lengths are still required to be 72 characters or less. Our entire source tree abides by this, and considering that we have well over 3000 lines of well formed, stylistically elegant code that maintains these line lengths, you can do the same. One particularly helpful hint for situations when you are trying to write a single string but it doesn't fit is to use echos. Simply break the string into two, and use echos to put them back together at evaluation time. Do not in any circumstance leave a string unterminated at the end of a line.
This is truly your first problem set where you are allowed to make use of side effects. Now that you have this freedom, you are expected to use it responsibly. When writing solutions, hesitate every time you write set!. As with the code in this problem set, your solutions should use set! and other side effects in the appropriate situations.
Another area you should focus on is the return values of your functions. Remember that side effects do not return a value. Take heed to the following functions:
- (for-each function list)
This function acts exactly like map, except it is used for side effects. So you can write (for-each echo '(1 2 3)) to write 1 2 3 to the output. It's preferred to use for-each rather than map, since map constructs a new list to return. You should try writing (map echo '(1 2 3)) and see what happens.- (when condition body)
Takes in a condition and a body. If the condition evaluates to true, then the body is evaluated. The return value of when is undefined, and is used only for side effects.- (unless condition body)
Takes in a condition and a body. If the condition evaluates to #f, then the body is evaluated. Just like when, unless has an undefined return value and is used only for side effects.Note that you should never use if as a substitute for when or unless.
The following discussion is likely to be useful if you plan on doing the game extension contest. As described in the problem set, you will not be using global definitions unless requested. You will also not have direct access to any specific game object instance.
When writing large programs, it is absolutely vital that the sources remain organized. Often times, organization and efficiency go hand in hand. Object-oriented programming in general is a useful model for organizing information in a large program. But it only goes so far.
It is really up to the programmer to take on some responsibility in keeping the sources organized. This leads to namespace conventions. You have already seen a rather useful convention in problem set three, where colons are used to separate module names. We use that in this problem set as well to separate the names for the instantiations.
When declaring a value in the global namespace, we have adopted the convention to put * around the name. For example, *default* would be a global default value.
In addition to keeping the namespace clearly organized, it is vastly important to keep the namespace from being polluted. This often occurs by declaring helper functions globally. Namespace pollution often creates problems when two programmers try to declare two different functions with the same name. In addition, namespace pollution can impact the performance of your program. Declaring helper functions locally can greatly improve readability, and if done right it can be extremely efficient.
Here are some additional functions that you may find handy: