CS4: INTRODUCTION TO PROGRAMMING

This Unit is about introduction to programming.

Before You Start To Code

When you first set out to learn the science and art of computer programming, there is a huge amount to learn and it can sometimes seem a little bit overwhelming. You are effectively learning a whole new language to write your code in, at the same time as learning a wide range of new concepts, principles, working practices, technical terminology, software tools and more. That’s quite a lot to take in all at the same time.

Because of this I think that it is well worth taking the time to learn some programming basics before you even start learning the ins and outs of a programming language and writing your first line of code. These basics include common terminology, working practices, and software tools.

The purpose of this article is to introduce you to some of these programming basics, which you are likely to come across no matter which language you decide to learn

A Beginners Guide to Code Editors

You can’t write code in a word processor, because the document will contain formatting which itself is created using programming code. You can choose to use a basic text editor of the kind which comes pre-installed on most computers and which doesn’t use any formatting, such as the notepad program, but it is much better to get yourself a proper ‘code editor’. Don’t worry – there are plenty of good ones available for free (I’ve include links to the right of this text)

Code editor software makes programming much easier, by making your code more readable and offering you a range of handy features. The first thing that you will notice when using a code editor is that each line is numbered. This makes it easier find things – including errors as you will often be told where in your code the problem has occurred when there is an error. Numbered lines mean that you can easily write a change log to keep track of exactly where modifications to a program have been made, and if you are collaborating it means that you can point a colleague to a particular place with ease.

When you start writing your code you will notice that the program adds colour coding to make it more readable. Because many types of code include the use of brackets, which are there to organise the code and which can cause errors if they are not opened and closed properly, many editors let will highlight the closing bracket when you click next to the opening bracket, and vice versa. They will also automatically indent lines of your code where appropriate.

If you look in the example picture below, you will also see a line down the side with little squares that feature either a plus or a minus sign. These can be used to collapse or expand sections of your code, which is useful when you are working on larger pages.

Most code editors also give you a button to you run your code in your choice of browser, allow you to add plug-ins to customize your editor, and use a range of advanced search features and more. Taking the time to pick out a good editor and explore its various functions before you actually need them is a really good idea.

Syntax

Programming languages are just like human languages – they have their own ‘syntax’, or rules to describe how statements should be written. You will find that many programming languages share a great many common features and functions, but each one will have their own syntax rules.

Getting the syntax right is very important, and as a beginner you will find that many of your errors end up being down to a missing semi-colon, bracket or apostrophe. The solution is to take your time, proofread as you go, and use a good code editor which highlights your syntax and gives each element a different colour.

Yoda Coding

Sometimes the computer doesn't mind which order you put things in, but other programmers might find it strange if you deviate from the norm. This is called 'Yoda Coding'. The example here says 'if 5 is the count', rather than 'if the count is five'.
Sometimes the computer doesn’t mind which order you put things in, but other programmers might find it strange if you deviate from the norm. This is called ‘Yoda Coding’. The example here says ‘if 5 is the count’, rather than ‘if the count is five’. | Source

Commenting, Indentation and Readability

When you are writing code it is very important to maintain readability. It is not just the computer that needs to be able to read your code and understand what it means – there is a good chance you will need to read back over your code at a later date to make changes (or to copy something for a new program!) and in a professional environment other people will need to as well.

Taking a bit of time to choose descriptive words as names for things like variables and functions can really help with this. Structuring your code with indentation is also useful, and you will learn how to do this alongside your language of choice. Each language will have its own format for indentation, but unless you are learning a language like Python where blank spaces are part of the syntax, this is just for your own benefit.

Commenting is also very important. Even when you are an experienced programmer you will find that some code is difficult to read and would take a long time to work through if you wanted to figure out exactly what is happening. Placing regular comments in your code to explain what it is doing is a very important habit, and one which you should work on developing from the very start of your programming career. Good commenting is an art form, as you need to include as much information as possible in as short a space as possible.

Documentation and Libraries

Being good at programming isn’t like being good with gadgets – you have to read the instruction manual. The term ‘documentation’ refers to the instruction manual which will be provided for any language you learn, as well as for third part resources and for SDK’s and API’s (see below). As a developer, you will spend a lot of time reading documentation. And the more time you devote to this, the better you will be at your job.

The simple fact is that no course will teach you everything that you ever need to know about a programming language – and even after getting years of experience under you belt there will still probably be things you aren’t sure about. Getting used to reading and using documentation is very important, and when you start to learn a programming language it is a great idea to browse through the documentation to complement any course you are doing – even if a lot of it doesn’t make much sense to start off with!

Libraries are another very useful repository for information, and it is well worth finding a few good quality libraries and familiarizing yourself with them when you start to learn a new language. Essentially a library is full of pre-written code which you can use to implement common features without having to write a everything from scratch yourself. In Python you can use ‘modules’ to import a set of functions with a single line. A good knowledge of libraries and modules can save you a great deal of time and trouble!

Pseudo Code

Pseudo code is an informal general description of what a piece of code should or does do, written in regular English (or whatever your language is!). It is essential partway between code and human language. It uses a logical and even mathematical style to explain the purpose of a piece of code, but without any of the formal structure and syntax of actual code.

There are no rules for creating pseudo code, so you are free to use it however works best for you.

It is very useful for two reasons:

  • Problem solving / knowing where to start: When you sit down to write a piece of code you often won’t know how it is going to be structured, or even how to start. Writing down your intentions in a very logical way like this before you start can make it easier to figure out where to start with actually writing the code and what structures you will need to use.
  • Commenting: Pseudo code can sometimes be used for comments to explain your code in a succinct and easy to read way. Sometimes you can even use the pseudo code you wrote when you started out as the basis for your comments (perhaps divided up and put in the relevant location) so that you don’t need to write anything new for your comments!

An Example of Pseudo Code

Set score to zero
while quiz is active
	if questions have been answered
		current score = 10 * no. of correct answers
		display current score
	else 
		print 'please begin'
if quiz has been taken
	print score
else
	print 'test your knowledge!'

Integrated Development Environments (IDE)

An integrated development environment (IDE), sometimes also known as an interactive development environment, is essentially one step up from a basic code editor.

An IDE includes a source code editor, as well as ‘build automation‘ tools to automate various tasks, a debugger to help you to identify and fix errors, and perhaps a compiler (see common terminology below), access to code libraries, and more.

If you are learning a common web language like JavaScript or PHP then you may well just use a regular code editor and won’t need an IDE, but for more heavyweight languages they are essential.

Many popular IDE’s support multiple languages, but you must ensure that your choice of IDE is appropriate for the language you are learning.

GIT Version Control and Collaboration

GIT is a term for a piece of distributed revision control software which is also used as a source code management system (SCM).

It is a commonly used tool for developers to keep track of changes that they make to their projects (revision control) – which is very important because if there is a problem with your code you will want an easy way to go back to a previous stable version. It is also used to store and share ‘repositories’ – libraries full of general code that can be reused on different projects, so you don’t need to write common features all over again. Software such as the very popular GitHub also includes powerful collaboration features for teams to work jointly on a project, or for interested parties to contribute towards open source projects.

A ‘software development kit’ or SDK is a bundle of software tools for the creation of new applications for a specific platform or framework. For example, if you want to develop an app for Android smartphones then you will need to download and install the Android SDK on your computer. Often SDKs are free, but some companies will charge new developers for the download. There may also be a range of different license options – so make sure you download the correct SDK for your purposes.

An SDK will often include an Integrated Development Environment, libraries, tutorials and simple code examples.

APIs

An API is an ‘Application Programming Interface’. They contain a set of rules through which your code can communicate with third party software or websites.

You can use API’s to access content and features from, or develop apps for, popular websites such as Twitter or YouTube. This kind of API is generally free to use, as the development of third party tools and integration into other websites can be a very powerful promotional tool for a big site. Another kind of API is created by ‘software as a service’ companies to offer advanced functionality to your site. You will generally have to pay for access to these.

Some Other Common Programming Terminology

  • Algorithm – A set of logical or mathematical procedures to solve a problem
  • Compiler – This is a program which takes the code you have written and translates it into the binary ones and zeros of actual machine code.
  • Concatenation – Combining two things together, such as two lists or strings of text.
  • Control Flow – Controlling the order in which various sections of code are run or the rules by which they are repeated.
  • Dump – a list of data which is saved if a program crashes, often as a text file. It is very useful for diagnosing problems.
  • Floating point – A decimal number where the point can move, such as 1.23. The opposite is an integer, which is a whole number and cannot have a decimal place.
  • Function – a set of instructions which are written once to obtain a particular result, and can then be used whenever necessary by ‘calling’ it.
  • GUI – General User Interface, refers to ‘front end’ of a piece of software which the end user actually sees and interacts with
  • Interpreter – Some languages do not need a compiler, but instead use an ‘interpreter’ which translates to machine code as the program is run.
  • Iteration – A sequence of instructions which are repeated. For example, to perform an action for every item in a list you would ‘iterate’ over that list. Each time it is repeated is one iteration.
  • JSON – A format for transmitting information between locations which is based on JavaScript. Many APIs use JSON.
  • Logical Operation – The use of simple Bolean logical such as andor and not.
  • Loop – a piece of code which keeps running until a certain condition is fulfilled – or isn’t fulfilled in the case of an ‘infinite loop’ which will crash the system running it.
  • Markup Language – A relatively simple language used to format pages, such as HTML.
  • Nested – When one thing is contained within another it is said to be ‘nested’.
  • Recursion – When something refers to itself. For example a variable may add something to itself for each iteration of a code loop.
  • Run time – The time during which a program is running.
  • Sandbox – A place to run a program for testing, and for experimenting.
  • Subroutine – a function or other portion of code which can be run anywhere within a program.
  • Variable – A way to store a piece of data which can then be modified at any time.

Features List

Below you’ll find an ever-growing collection of cool programming features for your perusal. When you’re done browsing, feel free to share some of your favorites in the comments.

Extension Methods

One of the coolest programming language features I’ve had the chance to explore is extension methods. When I first heard about extension methods, I was implementing Hello World in Kotlin. Of course, they’re completely unnecessary for such a trivial program, but I did get a chance to learn of their existence.

If you’re not sure what extension methods are, they allow us to tack on methods to existing classes without extending the class directly. For instance, let’s say we really like the String class in Java, but we think the class could benefit from a mutation method. Currently, the only way we can create a mutation method is by creating our own class which extends String:

  1. public class StringPlusMutation extends String {
  2. public String mutate() {
  3. // Add mutation code
  4. }
  5. }

Meanwhile, in Kotlin, all we have to do is write a method which directly extends the String class:

  1. fun String.mutate():
  2. // Add mutation code

Now, anytime we create a String, we can call mutate on it as if mutate were a part of the original set of public methods in String.

Of course, I should mention that extension methods have their drawbacks. For instance, using our example above, what happens if the String API gains a mutate method? That would be one tricky bug, but it’s probably safe to say it’ll rarely happen.

Macros

For those of you that don’t know, macros are actually a metaprogramming feature. More specifically, macros allow us to modify the language directly by adding rules to the abstract syntax tree. These rules are generated through pattern matching.

That said, the explanation above is pretty dense, so let’s take a look at an example in Rust:

  1. macro_rules! print {
  2. ($($arg:tt)*) => ($crate::io::_print(format_args!($($arg)*)));
  3. }

This rule was taken directly from the Rust source code. As we can see, the print macro has one pattern matching case which essentially accepts any number of arguments and attempts to format them before printing.

If the pattern matching syntax is confusing, it’s probably a good idea to learn a bit about regular expressions. The regular expression syntax is similar to the pattern matching syntax.

Of course, as you can probably see, macros are an extremely complex feature. In fact, they are often difficult to write and equally difficult to debug. That’s why, even in Rust’s documentation, macros are considered a feature of last resort.

Automatic Properties

In addition to macros and extension methods, one of the coolest programming language features is automatic properties. I first learned about automatic properties when I discovered them as a bit of syntactic sugar in C#.

Basically, automatic properties are just shorthand for getters and setters in object oriented programming languages. For instance, let’s say we have a Person class, and we want the class to have some name field. After all, people have names, so it makes sense to give the class this field. Let’s go ahead and implement this in Java:

  1. public class Person {
  2. private String name;
  3. }

Now, if we want to be able to set the name, we’ll probably want to write a public method to update the private name field. Colloquially, we call these methods settersbecause they set a property of an object. However, officially, they’re called mutator methods.

In Java, the following creates a mutator method:

  1. public setName(String name) {
  2. this.name = name;
  3. }

Already we have six lines of code, and we can’t even request the person’s name yet. To do that, we write a getter or accessor method:

  1. public getName() {
  2. return this.name;
  3. }

In languages with automatic properties, we can completely remove these six lines of boilerplate code. For instance, in C#, the following class is identical to the one we just created in Java:

  1. public class Person
  2. {
  3. public string Name { get; set; }
  4. }

With automatic properties, we can reduce six lines of code to a single line for every field we want to expose—wonderful!

Optional Chaining

Before I can really explain optional chaining, we have to get a grasp of what an optional value is. In Swift, variables cannot be empty. In other words, variables cannot store a value of NIL, at least not directly. This is a great feature because we can assume that all variables contain some value.

Of course, sometimes variables need to be NIL. Fortunately, Swift provides that through a boxing feature called optionals. Optionals allow a user to wrap a value in a container which can be unwrapped to reveal either a value or NIL:

  1. var printString: String?
  2. printString = “Hello, World!”
  3. print(printString!)

In this example, we declare an optional String and give it a value of “Hello, World!” Since we know that the variable stores a String, we can unconditionally unwrap the value and print it. Of course, unconditional unwrapping is typically bad practice, so I’m only showing it for the purposes of showing off optionals.

At any rate, optional chaining takes this concept of optionals and applies it to method calls and fields. For instance, imagine we have some long chain of method calls:

  1. important_char = commandline_input.split(‘-‘).get(5).charAt(7)

In this example, we take some command line input and split it by hyphen. Then, we grab the fifth token and pull out the seventh character. If at any point, one of these method calls fails, our program will crash.

With optional chaining, we can actually catch the NIL return values at any point in the chain and fail gracefully. Instead of a crash, we get an important_char value of NIL. Now, that’s quite a bit more desirable than dealing with the pyramid of doom.

Lambda Expressions

We likely couldn’t make it through a list of the coolest programming language features without talking about lambda expressions. Now, to be fair, lambda expressions aren’t a new concept . In fact, they’re older than computing. That said, lambda expressions continue to appear in modern languages—even as new features in established languages like Java.

If you’ve never heard of lambda expressions, you may have heard of anonymous functions. For simplicity, they’re synonymous. The subtle difference is that lambdas can be used as data. More specifically, we can package up the lambda expression in a variable and manipulate it as data:

  1. increment = lambda x: x + 1
  2. increment(5) # Returns 6

In this example, we have essentially created a function, stored it in a variable, and called it like any other function. In fact, we can even make a function return a function, thereby dynamically generating functions:

  1. def make_incrementor(n):
  2. return lambda x: x + n
  3. addFive = make_incrementor(5)
  4. addFive(10) # Returns 15

Now, that’s cool!

Gradual Typing

If you’ve been around coding a bit, you’re probably familiar with the two main varieties of typing: static and dynamic. Of course, let’s not confuse these terms with explicit and implicit typing or even strong and weak typing. All three pairs of terms have different meanings.

One of the coolest programming language features is the intersection between static and dynamic typing called gradual typing. Basically, gradual typing is a language feature which allows the user to decide exactly when they want static typing—otherwise, assume dynamic typing.

In many languages that support gradual typing, this feature manifests itself through type annotations. Type annotations are pretty much what you would normally see in an explicitly typed language, but the annotations are optional:

  1. def divide(dividend: float, divisor: float) -> float:
  2. return dividend / divisor

Here, we have a fully annotated Python function which indicates the expected input and output types. However, we can just as easily remove the annotations:

  1. def divide(dividend, divisor):
  2. return dividend / divisor

Now, I believe nothing is stopping us from passing pretty much anything into this function in either case. However, the first option opens up opportunities for static type checking which can be integrated into IDEs and other static analysis tools. I’d say that’s a win-win.

Immutability

Another one of the coolest programming language features is immutability. When I first discovered immutability, I was actually in a course on high-level languages. In this course, we had an assignment where we had to compare and rate the features of about 10 different languages. Of those features, one of them was value semantics, a feature that implies immutability.

Of course, what is immutability? As it turns out, immutability describes variables—or rather constants—that cannot be changed after creation. Often, immutability is manifested in strings in many languages. That’s why it’s usually considered a bad idea to use concatenation in a loop:

  1. my_string = “”
  2. for i in range(10):
  3. my_string += str(i) # Generates a new string every iteration
  4. print(my_string) # Prints “0123456789”

In fact, you may notice that I never use concatenation in my Reverse a String in Every Language series for that exact reason. Of course, language developers are aware of typical pitfalls, so they do a good job of optimizing our mistakes.

Anyway, I had never actually seen a language implement immutability beyond strings until I played with Hello World in Elm. In Elm, variables are immutable just like in math, so the following code snippet throws an error:

  1. a = 2
  2. a = a – 5

Here, the issue is a matter of recursion. First, we define a. Then, we attempt to redefine a as a function of itself. To those of us who typically use imperative languages, we wouldn’t even bat an eye at this syntax. But to a mathematician, something is just deeply wrong with that second equation.

Of course, the beauty in immutability is the ability to trust a value after it is created. At no point will you have to worry about it changing behind your back.

Multiple Dispatch

Like lambda expressions, multiple dispatch isn’t exactly a new programming language feature, but it’s one of the coolest. That’s because, it allows us to do fun things like have different implementations of the same method in an object hierarchy.

Single dispatch is a programming language feature which allows users to define the same method in different ways in an object hierarchy. For instance, consider the following:

  1. pikachu.tackle(charmander);
  2. charmander.tackle(pikachu);

Here, we assume we have two objects, pikachu and charmander, in some Pokémon hierarchy. Both objects override some generic tackle method. When we run this code, the JVM is able to dispatch the proper tackle method.

Of course, things can go poorly in a single dispatch language because the method selection is only dynamic for the caller. As for the parameters, we’re stuck relying on static types.

So, let’s say that charmander was instantiated as a generic Pokémon. With single dispatch, pikachu is going to use the generic Pokémon tackle method, not the charmander-specific one. As a result, pikachu could miss the tackle.

With multiple dispatch, this is hardly an issue because the method selection process occurs at runtime. Naturally, the proper tackle method is issued, and pikachu lands the tackle.

If I butchered that explanation, let me know in the comments. For a much better explanation, I recommend Eli Bendersky’s article titled A Polyglot’s Guide to Multiple Dispatch.

Destructuring

Remember when I mentioned pattern matching? Well, destructuring—also known as iterable unpacking—is another form of pattern matching used to extract data from collections of data. Take a look at the following example from python:

  1. start, *_ = [1, 4, 3, 8]
  2. print(start) # Prints 1
  3. print(_) # Prints [4, 3, 8]

In this example, we’re able to extract the first element of the list and ignore the rest. Likewise, we can just as easily extract the last element of the list:

  1. *_, end = [“red”, “blue”, “green”]
  2. print(end) # Prints “green”

In fact, with pattern matching, we can extract whatever we want from a data set assuming we know it’s structure:

  1. start, *_, (last_word_first_letter, *_) = [“Hi”, “How”, “are”, “you?”]
  2. print(last_word_first_letter) # Prints “y”

Now, that has to be one of the coolest programming language features. Instead of extracting data by hand using indices, we can just write a pattern to match which values we want to unpack or destructure.

Inline Testing

To be honest, I wasn’t sure what to call this feature because I’m not sure it has a formal name. That said, inline testing is one of the coolest programming language features I’ve ever seen.

I first came across inline testing in Pyret, a language designed for programming education. In Pyret, unit tests are a part of the basic syntax. In other words, we don’t have to import any libraries or build up any suites to run tests.

Instead, Pyret includes a couple of clauses for testing within the source code:

  1. fun sum(l):
  2. cases (List) l:
  3. | empty => 0
  4. | link(first, rest) => first + sum(rest)
  5. end
  6. where:
  7. sum([list: ]) is 0
  8. sum([list: 1, 2, 3]) is 6
  9. end

Here, we can see an awesome list sum function. Within the function, there are two basic cases: empty and not empty. In the empty case, the function returns 0. Otherwise, the function performs the sum.

At that point, most languages would be done, and testing would be an afterthought. Well, that’s not true in Pyret. To add tests, we just include a where clause. In this case, we test an empty list and a list with an expected sum of 6.

When the code is executed, the tests run. However, the tests are non-blocking, so code will continue to run barring any catastrophic issues.

Regardless, I love this feature just in terms of honest maintainability. Testing is never forgotten in the development process when using Pyret.

Inline Assemblers

As it turns out, an inline assembler is a programming language feature which allows a developer to tap directly into the system architecture. When using a language that has inline assembler support, the following code is completely legal:

  1. void *pc;
  2. asm
  3. {
  4. pop EBX ;
  5. mov pc[EBP], EBX ;
  6. }

Here, we have what looks like a mix between C/C++ and assembly programming, and that’s essentially what this is. We have written code that works directly with the underlying architecture, so we know exactly what’s happening.

I find this feature really interesting because languages tend to opt for abstraction when given the opportunity. With D, we can totally forego the built-in functionality and write a custom assembly-level implementation ourselves.

THIS LINK EXPLAINS MORE

https://www.techwalla.com/articles/importance-of-computer-programming

THIS VIDEO EXPLAINS MORE ABOUT PROGRAMMING

 

SEE ALLAdd a note
YOU
Add your Comment
 

DOWNLOAD YAAKA DN APP









X