A-level Computing/WJEC (Eduqas)/Component 1/Principles of programming
Paradigms
editA paradigm is the fundamental approach of a programming language.
Procedural
editProcedural languages carry out actions and calculations used in a logical step-by-step process for solving a problem. C and Python are examples of languages that use this approach. They obey ordered instructions and each step is precisely defined. They allow tight control over the underlying operation of the hardware used. They are typically used in large complicated programs where procedures and functions are run at various stages of execution. The paradigm is part of the larger imperative programming paradigm meaning that statements can be grouped into smaller procedures and functions.
Non-Procedural
editNon-procedural languages allow programmers to specify the results they want rather than specifying how to solve the problem. They are to do with making queries, for example in database interrogation when retrieving data is more important than the exact process required to retrieve the data. They also are used in artificial intelligence, grammar checking and language translation applications.
Visual
editRather than typing code out, the visual paradigm is used particularly for production of objects, buttons and icons. The visual paradigm is suitable for developing in a GUI or an event-driven language. Scratch and GameMaker are examples of programs that use this approach. For instance, Scratch uses a drag-and-drop application where commands are dragged in from a set group of commands and this generates code. The visual paradigm is better as it is more intuitive, easier to learn for a beginner as there is lots of help and tools provided.
Event-driven
editThe event-driven paradigm is based on a GUI and makes use of any events that occur when the program is running. VB.NET Windows Forms use this approach. Programs sit in a constant loop, waiting for any input from the user. When an interaction is triggered, for example a user clicking a button, a listener is called. The listener then processes the event and executes the relevant code in the program.
Object Orientated Programming
editObject orientated programming (OOP) uses objects and classes. It enables the production of buttons and icons which is useful in a visual environment. An object is a combination of attributes (data) and methods. They have many advantages: once they are created, knowledge of their implementation is not necessary to use them. Objects control how other objects interact with them, preventing errors e.g. a programmer cannot set the width of a window to -500. In some languages like event-driven languages these objects are placed on forms (event-driven languages). They can be re-used across a variety of other programs once they have been created. A class is a template specifying the methods (a program routine) and attributes (information).
OOP uses three key principles: encapsulation, inheritance and polymorphism.
- Encapsulation is when the technical implementation is hidden within the object. This means data is kept inside the class, and is inaccessible to the rest of the program. An secondary advantage of encapsulation is that once an object is created, knowledge of its implementation is not necessary to be able to use it. Objects created this way can easily be reused in other programs, and by different programmers.
- Inheritance is when properties and methods are copied to another class. It comes about where classes are grouped by similar attributes and methods. Attributes and methods that are in common across their classes can be given to a parent class, and the other classes become subclasses of this parent class. The affect of this is that the subclasses inherit the methods and attributes of their parent class, they can use them as their own. This is a benefit, as it means a method that is held in common only has to be defined once, and then all other classes that use it can look to their parent class instead. Inheritance is relevant when new objects are created (instantiation).
- Polymorphism is when a general object is created which can be used with a wide range of data types. It is simply the idea that a method can work differently depending on the class that runs it or the data it is given to work with. For example, an Area method would calculate area different for the classes 'circle' and 'square', but both would inherit the class from their parent class - 'shape'.
Languages
editMark-up
editMark-up languages add commands to a text document to offer some meaning to the text. These commands give instructions on how to format and display the text. An example is HTML where commands are called tags and are enclosed within chevron characters, for example:
<h1> This represents text in a heading in HTML. </h1>
Commands are opening so any text after will have the formatting, e.g. a heading, applied to the text. They are subsequently closed by a tag with a forward slash.
Another example is XML (eXtensible Mark-up Language) is sometimes used to structure data for storage rather than displaying it. XML has no set conventions and the developer is free to add their own meaning to each piece of data, for example see the image to the right. These Mark-up languages are commonly used in conjunction with other languages such as JavaScript with HTML.
Scripting Language
editA scripting language is embedded into other languages and can add extra functionality to webpages (JavaScript).
Special Purpose Languages
editSpecial purpose languages are ones that were designed with a specific purpose in mind. They might include essential/helpful features relevant to the application. Special purpose languages are available in fields such as simulation and control. They are very unique with built-in functions/abilities that lend themselves directly to solving the problem that the language was designed to work on. They are Commonly used in applications such as Computer-aided design (CAD), Artificial Intelligence (AI), expert systems, scientific applications and games programming.
High-level Programming
editHigh-level programming languages are easier to understand, learn and program as the code is more alike to English (compared to low-level programming). It makes use of identifiers which can be self-documenting and modules which can be re-used throughout the program. High-level languages translate into many lines of executable machine code (0s and 1s).
Low-level Programming
editIn low-level programming languages the developer has direct access and can manipulate the memory registers and the CPU, as well as being able to directly communicate with the hardware devices attached to the computer. Different CPU architectures execute a different instruction set, and the developer can access these instructions via low-level programming. Languages such as Assembly can be used, which utilises mnemonics to execute machine code. To convert Assembly back to high-level code, an assembler must be utilised.
Low-level programming languages are used when speed is paramount, e.g. bootstrap program on the ROM and embedded systems. They are much more efficient than high-level languages due to the fact they are smaller. Because they are smaller they take less time to translate to machine code. Languages such as Assembly are used where commands have a one-to-one mapping (one line of Assembly = one line of machine code).
Principles
editStandardisation
editThe USB (Universal Serial Bus) connection medium is an example of a standard. Standards are used to ensure that various products can integrate with one another, for example an external HDD via USB to read/write files on an operating system, which makes use of the USB standard on all computers. Groups will be formed with various people involved in the process in order to develop a standard.
Standards are useful because one program written in one language is more likely to run on a completely different computer architecture and programmers familiar with using a programming language can easily change to using another language, even on a different architecture. It is difficult to standardise because of different manufacturers which may not be keen to standardise for commercial reasons (market share for instance).
Unambiguous Syntax
editAmbiguity is when meaning is uncertain and different interpretations are possible. High-level programming languages must be unambiguous so there is only one way to interpret each statement, e.g. two Else statements are ambiguous. This is to allow accurate translation into executable machine code. Backus-Naur Form (BNF) uses unambiguous rules.
Guide to Backus-Naur Form
editBackus Naur Form (BNF) is a formal way of writing the grammar of a programming language. The main idea is to introduce rules to ensure that the source code is syntactically correct (the arrangement of each part is correct) and unambiguous. BNF is preferred to English because English is ambiguous and BNF is not. To introduce these concepts to code, we use grammar rules like normal English, these being contained within chevrons (<>). There are two parts that can be included in one of these 'grammar rules': terminal symbols and non-terminal symbols. A terminal cannot be evaluated any further (this simply means it cannot be broken down any more), whereas a non-terminal requires further evaluation (it must be broken down before it can be interpreted). To create a rule, we must first be familiar with the symbols used within rules, and what they represent. Here is an example:
<Digit> ::= 0|1|2|3|4|5|6|7|8|9
<Digit> is used to start the rule and give it the name of 'Digit', note the chevrons used. "::=" is used to represent assignment. "|" is used to represent the logical operator OR (this is a pipe character). This rule can be used to construct any number we need since all numbers must contain 0-9. It is very important that you start from 0 otherwise you could not include large numbers such as 100 or 900. The numbers in this example (0-9) would be considered terminals since you cannot evaluate them any further.
<TwoDigitNumber> ::= <Digit><Digit>
Here we have declared the rule 'TwoDigitNumber' which consists of two 'Digit' rules. As you can see, we need to consult the 'Digit' rule to see what this rule means - we need to evaluate it further - so this is a non-terminal. You may be wondering how we can construct words or letters with BNF and quite rightly so! Let's imagine we're creating an email using BNF to represent everything. We would need the following rules to do so:
<Uppercase> ::= A|B|C|D|E ... |Z
(note here how we've used ... to represent the continuation, you can do this too in the exam!)
<Lowercase> ::= a|b|c|d|e ... |z
This allows for use of any letter in the alphabet, but as a lowercase character.
<Digit> ::= 0|1|2|3|4|5|6|7|8|9
(usually needed in all BNF questions, e.g. some emails may contain an EmployeeID in this case.) These are all the rules we need so far for creating our email, but there is a problem with the current rules we've used. People can only have an email consisting of single letters and digits. This is obviously problematic when we want to have a full name in the email. We can use a concept covered before, recursion, to combat this issue:
<Name> ::= <Lowercase>|<Lowercase><Name>
In the <Name> rule there are two possible paths, the first and the second one. In the first path it accepts a singular lowercase character, which will be called if there is a single letter only. Otherwise the second path will be called which will accept a single character but will also call the rule again - so there can be as many lowercase characters as you desire, creating a full name. This way of thinking is very helpful as it allows you to remember the recursion rule properly, as it must be in this exact format otherwise it is not correct (this format is the one on the mark scheme). There must be two paths, either just the singular character or the singular character and the rule being called again.
Finally, after we've addressed all the possible constraints on the data, we create a final rule which contains all the logic. The question used for this example is below:
Email Exam Question The email addresses of staff at National Bank are made up of a first name, followed by a full stop, followed by a surname, followed by a single digit, followed by the @ sign, followed by 'nb.co.uk'. All first names consist of lower case letters only, and can be any length. Answer: <Lowercase> ::= a|b|c|d|e ... |z <Digit> ::= 0|1|2|3|4|5|6|7|8|9 <Name> ::= <Lowercase>|<Lowercase><Name> <Email> ::= <Name>.<Name><Digit>@nb.co.uk
|
Syntax Diagrams
editWe can also represent BNF in a diagrammatic form, but this is only for people to easily see what it represents rather than having a bigger purpose. Three shapes are used to do so: a rectangle with two lines to the left and the right within which represents a non-terminal, an oval to represent a terminal and an arrow which represents the flow of information (the path taken). Within both symbols there is text within them to show what they represent. An oval (terminal) may contain "1" and a rectangle (non-terminal) may contain "Digit". Recursion is represented just drawing a line with arrows going back before the decision to go through the non-terminal, so this shows that you can go back until the entire string has been constructed.