© Jason Lee Hodges 2019
J. L. HodgesSoftware Engineering from Scratchhttps://doi.org/10.1007/978-1-4842-5206-2_3

3. Contextual Knowledge

Jason Lee Hodges1 
(1)
Draper, UT, USA
 

In order to learn any type of programming, you must be comfortable with two main topics. First, the operating system that you will be programming on, its origins, and common usages. Second, the concepts of languages as a whole – spoken, written, and symbolic or coded. Without this prerequisite context, some of the instructions in the coming chapters will be difficult to follow. So, before we attempt to learn anything in Scala, let’s briefly dive in and gain a deeper understanding of these topics as they will build a strong foundation for your software engineering career.

Command-Line Operating Systems

When you start up your computer today, you will likely see a Windows or Apple logo. Sometimes you might see some start-up scripts running by the screen really fast and you have no idea what they are and you likely never will need to know. As long as the operating system gets you to your desktop so that you can click on icons and run applications, that’s all you need to see. But behind your desktop, running in the background, as alluded to by those start-up scripts, is just a simple command-line operating system that has been built up with incrementally increasing complexity over time. How the operating system works and how it came to work that way are hidden from you so that you don’t have to worry about it. You can simply browse the Internet, write a program or a book, or generate some other type of content. You can be productive on a computer by building off of a piece of code that was written by others and, as long as it works for you as intended, you will never need to know how it was created. This is a concept known as abstraction. There are several abstractions in this book, including a lot of concepts that could have been covered in the first chapter that will be glossed over in order to focus only on what’s important in the context of software engineering in Scala. That being said, in order to write programs in their most basic form, it will be useful to peel back the layers of abstraction on an operating system to understand how it works.

Your desktop has elements that can be clicked on, dragged, or modified in different ways. The way you interact with your desktop is known as input. The way the computer responds to your input is known as output. Input and output (I/O) are the building blocks of an operating system. In fact, the very first operating systems were simple text input and text output. There was no graphical user interface (GUI) – no pictures, no mouse cursor, no icons, no windows or graphics of any kind. Just a command line waiting for input, ready to respond with output. In this way, the first operating systems were not unlike a basic calculator, albeit perhaps with more input keys.

More specifically, the process the operating system would go through to interact with user input was a Read, Evaluate, Print, and Loop cycle. This is also known as REPL and it is one way that you can interact with a computer to write software (more on that in the coming chapters). The “Read” step is simply the computer waiting for input from the user. Once the user types something into the command line and hits enter or return, the operating system reads in the input and stores it in memory. The next step is an “Evaluation” of the input. Typically, the user would expect the computer to do something with their input. In the case of a simple calculator, the user input of “2 + 2” would need to be evaluated to an answer of 4. Once the computer has determined that the output should be 4, what’s next? That’s where “Print” comes in. It is not enough for the computer to know that 4 is the answer; it must also let the user know that it evaluated their input and the answer is 4. So the operating system must print the answer out to the screen as output. You will often see this referred to as “printing to the console.” The console is just another word for the output terminal or command-line screen. Finally, the computer “Loops” back to the start where it again waits for user input to read.

So, what type of input is the computer expecting? Probably the most intimidating thing about working with a command-line-based operating system is knowing by heart what commands to enter into the “Read” step of a REPL in order to get anything done. Rest assured, you do not need to memorize everything in order to get things done with the command line. By gaining a simple understanding of the way the file system of an operating system works and how to navigate that file system, you should have the majority of what you will need as a software engineer when working from the terminal.

File Systems

One of the most common evaluations a user might ask an operating system to do is store data of some kind. This might be pictures of your family, a research paper, or some music. In the case of software engineering, the data that will often be stored is simply a file that contains a programmer’s code that needs to be executed at a later time. As you likely have experienced, as your data storage gets bigger and bigger, it becomes more and more important to have a system of organization to navigate to the files that you want to find. That’s where the file system comes in. Most, if not all, operating systems have some type of file system for managing and organizing content.

Current Windows operating systems run off of a file system called NTFS which stands for New Technology File System (as opposed to the old system that was called FAT32, which was a 32-bit File Allocation Table). Both Apple computers and Linux-based operating systems run on the Unix File System. Both NTFS and Unix file systems support similar terminal input commands for navigating, storing, and moving data around on a computer. This will be important as you start to write software so that you can quickly and easily access the programs that you write without needing a graphical user interface. The reason you don’t want to rely on the GUI is so that you can write programs that can access and interact with other programs or files. This is much easier to accomplish if you can write a simple file system command that you can pass to the operating system to execute for you.

The most important thing for you to understand about the file system on a command-line operating system is that you can navigate through it similar to how you would on a graphical user interface. In the GUI you open up windows and double-click on folders to see the sub-folders and files that they contain. The same can also be accomplished directly from the command line using input commands rather than using a mouse cursor.

Navigation

The digital file systems that operating systems use were modeled after a traditional, physical, filing cabinet system with folders and files. In order to access a file, you must first open the folder that the file resides in. But in a digital filing system, you can’t see the physical folders from the command line, so how do you know what folder to open?

The first input command you will learn is ls (for Unix) and dir (for NTFS) which stand for “list” and “directory,” respectively. Both of these commands list all of the contents of the directory or folder that you are currently in. It is important to note that folders can contain other folders. Given that, there can be infinitely many levels of nested folders to navigate through, but each directory or folder can list out its contents as well once you open them. So, once you’ve decided on a sub-folder to open from the list of folder contents that the ls or dir command returns, how do you open that sub-folder?

The next important command is the same for both Unix and NTFS file systems and that is cd, which stands for “change directory.” The cd command should be following by something called an input parameter. In this case, the input parameter is the name of the directory that you want to open. Listing 3-1 provides an example of listing the contents of a directory and then changing the directory to a sub-folder.
> ls
Desktop
Documents
Downloads
Pictures
example.log
install.sh
> cd Documents
/Documents> ls
example.doc
rough_draft.txt
/Documents> cd ..
>
Listing 3-1

Listing the contents of a directory and then changing directory from a command-line interface

Note

For command-line examples in this book, the folders in each directory will be in plain text, while the files are denoted in italics. How they are formatted on your file system is going to depend on the settings of your particular shell or terminal. This example starts from a home directory. Oftentimes in a Windows or NTFS file system, you will start out in a hard drive directory like your C: drive. But for the sake of unified examples, this book will use the Unix commands throughout.

From the home directory in this example, if you input ls, you will see the folders labeled “Desktop,” “Documents,” “Downloads,” and “Pictures.” You will also see two files, one labeled “example.log” and one labeled “install.sh.” In this example, let’s assume you want to access a file from your documents folder. To change directories and go into that documents folder, you would type in cd Documents and the file system would then change to the “Documents” directory. You’ll notice that the input prompt will now show you that you are in the “Documents” directory, denoted by /Documents>. From there, you can list the contents of that directory again using ls. That command shows you that the Documents directory contains two files named “example.doc” and “rough_draft.txt.” Finally, assume that you changed your mind because you couldn’t find the file you wanted and you wanted to go back up to your home directory. The command you would use for that is cd .. . The two periods tell the file system to go back up one directory. This is the same for both types of file systems.

If you know the entire path of the folder you want to go to in a nested file structure, you can also cd into a full path as demonstrated in Listing 3-2.
> cd Downloads/StockTickers/data/2018/Q1
/Downloads/StockTickers/data/2018/Q1> cd ../..
/Downloads/StockTickers/data>
Listing 3-2

Changing directly into a nested directory

Just as you can navigate several layers deep in one command, you can also go back up several levels in one command. By typing in ../.. you’ve told the file system to go back up twice given the twice instantiation of the double period operator. The opposite of the double period operator is the single period operator which basically tells the file system that you would like to access a file or folder that is relative to the current directory (as opposed to the parent directory as denoted by the double period). This is useful when writing a program that needs to access other files in the same directory, but you are not yet sure which directory the program will be installed on or saved to. You will see examples of that later on in this book.

You can open a file in a text editor program by typing in the command for the editor that you prefer, followed by a space and then the file name (the file name being the input parameter). If the file name that you entered does not exist in the current directory, it will create one for you. In Unix, a popular editor that comes with most operating systems is nano. On a Windows operating system, you can use the command edit to open the MS-DOS Editor. Both of these will open the file for editing in a text editor. Each of these programs will have their own commands for creating text files that falls outside the scope of this chapter.

To create a folder in the current working directory, you can type in mkdir followed by the folder name that you want to create as an input parameter. Both file systems will accept this command the same way. To remove a folder in Unix, you would type in rm -rf foldername which will delete the folder and all of its contents if you have the appropriate permissions to do so. You can also precede this command with the sudo keyword to give yourself super user access (you will be prompted for your administrator password). On Windows you would type in rmdir foldername to obtain the same behavior. To delete a file instead of a folder, the command is rm filename.txt on Unix and del /f filename.txt on Windows. Listing 3-3 demonstrates these commands.
> ls
Documents
> mkdir foldername
> ls
Documents
foldername
> cd foldername
/foldername> nano filename.txt
/foldername> ls
filename.txt
/foldername> rm filename.txt
/foldername> ls
/foldername> cd ..
> rm -rf foldername
> ls
Documents
Listing 3-3

Commands to create and remove files and folders. Note after the “rm filename.txt” command, the “ls” command returns a blank line to denote that the folder is now empty

That should give you a pretty solid base understanding of how to navigate between folder structures from the command line, how to create and remove folders and files, and how to point to relative directories. These are commands that you should memorize. All other command-line-based commands can be easily looked up on the Internet if you ever need to use them, depending on what it is you are trying to do. But for now, let’s stick to the minimum necessary amount of commands to maintain the digestibility of the concepts. Once you feel confident with these commands, you can move on to understanding more about language constructs as a whole. All of this will be useful context when writing your own software later in this book.

Exercise 3-1

From the command line, create a file system–based representation of your family tree starting with a single relative. Try to go back as far as you can – a great, great, grandparent would be excellent. Each folder should be labeled with the names of the parents of the family, and there should be a folder for each child within that household. Navigate between the levels of folders to create sub-folders. Try to build this out as far as you can so that creating folders and moving between them becomes like second nature.

Once you’ve created the entire family tree, try the following exercises:
  1. 1.

    See if you can create a file in each of the child folders that contains the birthday of that particular child.

     
  2. 2.

    Remove some of the individual files you just created.

     
  3. 3.

    Once you’ve deleted a few files, delete an empty sub-folder.

     
  4. 4.

    Delete a folder that contains files.

     
  5. 5.

    Remove a folder that contains sub-folders.

     

Language Syntax and Semantics

Programming languages, just like spoken languages, have a set of rules that govern what is an acceptable pattern of lexeme combinations. A lexeme is simply a part of speech (like a noun or a verb) used in the construction of an interpretable code unit or sentence (in the case of spoken languages). When a compiler or a human encounters a code unit or a sentence and parses through it to extract the meaning, this is called lexical analysis. The main difference between the lexical analysis that a human performs and the analysis that a compiler performs is that the human brain can easily interpret improper grammar such as slang, sarcasm, or simple mistakes and extrapolate the connotative meaning behind what was said nonetheless. Conversely, a computer’s compiler can only do exactly what it is told according to the rules defined by the language. Any deviation from the predefined grammar rules can cause either an error in the compiler or a behavior other than what was connotatively expected.

Consider the following quote from a comic published in 1997 depicting cavemen inventing language. To the human brain, it is easy to interpret what the connotative meaning of the sentence is without it following the actual grammar rules of the English language. However, without following exact grammar rules, a computer would not be able to understand the meaning of this sentence.

Words down got we’ve good pretty… Should now invent we syntax!

—Bob Thaves, 1997

Alternatively, the sentence might have said, “We have.” Syntactically that sentence would be correct. It has a subject and a verb in the correct order with the correct punctuation. A computer would not throw a compiler error trying to parse this syntax. But what does it mean? What do we have? Why does it matter? What is it that you are trying to communicate? It’s hard to derive any context from those two simple words. Computers can often compile correctly with proper syntax and yet fail to execute as expected due to a lack of meaning derived from a “sentence” of code.

The study of languages and their grammar, which includes rules like punctuation, parts of speech, and their order, is called linguistics. The study of linguistics becomes very important for those who are interested in creating their own programming languages as much of the subject areas overlap. Within linguistics, the governing rules of a language are referred to as a language’s syntax.

Referring back to the Thaves quote, even though we can infer the meaning behind what the caveman is trying to say, the order of his words is syntactically incorrect. English syntax would dictate the he should have structured the sentence starting with a noun, and then a verb, followed by a direct object, and so on. The correct syntax for this sentence should have been, “We’ve got words down pretty good. Now we should invent syntax!” The meaning has not changed in this corrected sentence, but the order of the words is now consistent with what has been agreed upon in English as the correct way to state the idea.

The connotative meaning derived from this properly formatted or syntactically correct sentence is called semantics. As demonstrated earlier, it is possible to have a syntactically correct sentence that is semantically meaningless. These concepts apply equally as well to coded or symbolic language as they do to spoken or written language. For our purposes, it is extremely important that all sentences or code units are both syntactically correct and semantically meaningful as the computer will not be able to interpret your code otherwise. Understanding both syntax and semantics will be very important in your software engineering journey as it will help you best diagnose where potential errors or unexpected behaviors are occurring in your software.

Exercise 3-2

Answer the following questions to the best of your ability. Choose the option that best answers the question.
  1. 1.
    Which of the following sentences has a syntax error?
    1. A)

      computer science is the study of computation

       
    2. B)

      a2 + b2 equals c squared

       
    3. C)

      Software engineering

       
    4. D)

      All of the above.

       
     
  2. 2.
    Which of the following sentences has the most semantic meaning?
    1. A)

      Where did you learn?

       
    2. B)

      Albeit underwhelming, the study of superfluous references is of the utmost anxieties.

       
    3. C)

      “Turing Tests” were named after Alan Turing who came up with the idea for measuring artificial intelligence.

       
    4. D)

      All of the above.

       
     

Summary

In this chapter, you’ve learned the contextual foundation that you will need in order to build your software engineering skill set. Do not move on from this chapter until you feel like you can do the exercises from this chapter in your sleep. You should be able to create and delete files and folders and navigate up and down a tree of files in a file system from the command line with ease. You should also have a thorough understanding of the difference between syntax and semantics and their corresponding impact on spoken and coded languages. In the next chapter, you will begin to get to know the Scala language using mathematical expressions and variable assignments, similar to the work that early computer scientists started with.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
52.15.55.18