Compare and contrast functional and imperative programming languages ( 10 marks)
Functional programming works by evaluating expressions, its stateless and deals with immutable data. In contrast imperative works with statements, which when executed alters its global state. Functional programming requires the functions to be treated more or less like any other value, that can be passed or returned from a function, this concept is also regarded as functions being first-class. Further more this allows functions to be nested in code blocks called closures, these functions are as easy called or manipulated as any other function. Imperative languages like C/C++ lacks this capability.
example of an expression
project x (a,b,c) = (a, x,(projectDataColumns x (a,b,c)))
example of an statement
p += 15;
example of a closure in haskell
f x = (\y -> x + y)
Imperative languages has no implementation of referential transparency, i.e the output of an expression might be different based on the state of execution, resulting in side effects. Functional languages has its roots in Lambda Calculus, i.e the functions implementations mimic that of mathematical function notations. This ensures that calling a function say 'f' and passing it the value x once or multiple times will always result in the same answer f(x), eliminating side effects. Functions without side effects make code easy to understand and less prone to error.
Iterations are handled very differently in functional and imperative languages. Imperative languages use the more traditional approach, which utilizes the use of loops (for, while, do, etc), whereas in functional languages iteration is carried out via the use of tail recursions or list comprehensions. To illustrate this principle lets look at a nest for loop.
Imperative approach
for($i=1;$i<=12;$i++)
{
for($j=1;$j<=12;$j++)
{
$string .= $i*$j;
}
}
The above code calculates the answer to the multiplication table from 1 to 12. In Haskell this code can be implemented using list comprehensions illustrated below.{
for($j=1;$j<=12;$j++)
{
$string .= $i*$j;
}
}
[x*y|x<-[1..12],y<-[1..12]]
Functional Programming offers more support to create structured programming than imperative languages, which is essential for abstractions and creating of components, facilitating code reuse. For example its easy to abstract out a recursive bit of code in a high order function which will make the code more declarative and comprehensive.
Functional programming languages like Haskell has automatic garbage collection, imperative languages like C/C++ doesn't have this feature. Having manual memory management means the code will be prone to memory leaks, this pitfall is avoided in functional languages, therefor the program is less likely to crash because of memory leaks.
5 concepts of functional programming languages (10 marks)
Higher Order Functions, when functions return other functions or accept other functions as arguments these are called higher order functions. For example, given a function to double an integer.
Double::Int->Int
Double x = x* 2
The prelude function Map. can take this function as a parameter as illustrated below
xs = [ 1,3,5,6]
doubleList xs = map double xs
This applies the double function to each element of the list xs. The function Map takes function Double as a parameter.
Pure Functions, these functions are functions that have no side effects, i.e they will only return values not yield other actions.(modify state).
for example a function a function that changes degree Celsius to degree Fahrenheit is a pure function, and conversion of exchange rate, MYR to USD is an impure function, it depends on a lot of external factors, i.e, the answer can be different time to time.
Lazy Evaluation, evaluation takes place only when required. It will only evaluate an argument to a function if that's arguments value is needed to compute the overall result. If the argument is structured, i.e if its a tuple or a list, it will only evaluate those parts that are needed.
an example of lazy evaluation is illustrated below.
x = fst ( sqrt(16), sqrt(9)
here the only the first part sqrt(16) get evaluated, the other part is ignored.
Currying, This is transforming a function that takes multiple arguments in such a way that it can be called with a chain of functions each with a single argument. An non-curried function's arguments would probably contain tuples.
an example of an curried function is illustrated below.
Multiply m n = m*n
non - curried version of this would look like this.
Mutilply (m,n) = m*n
The curried version can accept one argument and return a function. this function is a higher order function.
Referential Transparency, this means the function always evaluates the same no matter what the context is. There are no side-effects and it does not depend on the state.
for example the mathematical function sin(x) is transparent, i.e it returns the same value for sin(x) no matter what the context is. however the expression x++; ( x = x+1) is not transparent because it alters the value in variable x.
Explain The term Tuple in context of functional Programming paradigm, Give 3 examples? (5 marks)
Tuples is a way to storing multiple values in a single value. But it requires you to know exactly how many values are to be stored in the tuple. In functional programming languages tuples are useful when we want to return multiple values from a function, or it a can even be used as a primitive data type.
example 1: tuples can be used in a function to return cordinates.
Cordinates :: Int->Int->(Int,Int)
Cordinates x y = (x,y)
example 2: Returning compound result, min and max from 2 Ints
minAndMax :: Int -> Int -> (Int, Int)
minAndMax x y
| x >= y = (y, x)
| otherwise = (x, y)
example 3: Functions over tuples, for pattern matching.
addPair :: (Int, Int)-> Int
addPair (x,y) = x+y
Critically access any 3 Characteristics of procedural Programming Languages and include 2 possible benefits.( 16 marks)
Procedural languages are based on procedures (also known as routines or subroutines),
consisting of a series of computational steps to be carried out. It evaluates the code sequentially ( one way) and is a combination of variables, loops and functions.
Characteristics.
Modularity, Procedural languages allows the code to be modular, a function that is used to perform a certain task can be used over and over again with out repeating the code. Modules ensure separation of concerns, this improves maintainability and future expansion.Having the codes in modules makes it really easy to manage, and encourages code reuse, same code can be implemented in multiple projects via libraries.
Scoping , in specially large systems, involving a lot of variables being passed around in functions, scoping can be very helpful, in ensures that the variables used in function stays within that function. procedures cant use variable from other procedures or another instance of the same procedure without explicit permission.
example to illustrate basic scoping in procedural languages.
//code
var variable1
function A{
var variabe2;
function C{}
}
function B {
}
In the code illustrated above, variable1 is a global variable accessible to all functions, bu variable2 can only be accessed by function A and C. Similarly function C is not available to function B.
Incremental State, most procedural languages have incremental state as a function of time, i.e the state alters as the program is executed and as the user interacts with it.
Benefits
Simplicity , Procedural languages are simple compared to declarative, they offer a clear and concise solution, specially when considering simple tasks, it doesn't force you to create objects or classes to do a simple task ( as some object oriented languages like java do).
Efficiency, procedural languages are more efficiently translated into machine language, and they run more efficiently because the level of abstraction is low, in other programming paradigms like declarative the level of abstraction is very high, its more similar to a natural language which translates less efficiently into machine code.
Critically access any 3 characteristics of declarative programming languages ? ( 9 marks)
Dynamically typed, declarative programming languages are dynamically typed, i.e variable types and function types are accessed only at run time, therefore some type checks are left for run time. This can be a good thing and a bad thing depending on ones point of view.
Bad, because it offers comparatively less documentation, specially if its a large project. This can also help catch errors at compile time.
Good, because very frequently in a statically typed language to do computations manual type casting is required this brings, and often it makes it prone compiler errors. Dynamically typed languages eliminate this pitfall.
Minimize side effects, a declarative language tries to minimize or eliminate side effects completely, it accomplishes it by describing what to do, instead on describing how to go about doing this task, which is what an imperative language would do by implementing a detail description of the algorithm.
Single Assignment, in declarative languages variables can only have one value assigned to them and this cannot be altered during program execution. This is called non-destructive assignment. This encourages the use of recursive techniques.
Program flow, the flow of the program is not determined by control structures, it is left to the language it self. This minimizes logic errors that may occur if a programmer decided to implement this. This is true for other programming paradigms like imperative languages. Further more order of how execution of code is irrelevant.
Critically assess the current use of prolog lanaugage, identify 5 areas where the prolog language plays an important role. (10 marks)
Expert Systems, prolog is used in expert systems, for example it can be used to study and monitor traffic. and provide intelligent traffic control systems, controlling traffic light times and synchronizations based on statistical data collected overtime. Another example would be a medial expert system.
Natural Language Processing, Prolog is very suitable to parse and do natural language processing. It is used to create spelling correctors or applications that seek out grammetical errors.
Robotics, prolog is used in robotics to write create AI programs.
Intelligent Systems.
Knowledge representation and reasoning,
Pattern matching,
Planning and Search. i.e. Prolog is good at Symbolic AI
Function to the exponent of a value. ( 25 marks )
Power :: Float->Float->Float // function definition
Power m n //function declaration, m^n, where n is exponent
| n == 0 = 1 //any integer to the power of 0 is 1
| m == 0 = 0 //0 to the power any integer is 0
| n > 0 = m * power m (n-1) //positive powers
| otherwise = (1 /m) * power m(n+1) //negative powers
Finding out weather a number is odd or even (25 marks)
oddEven :: Int -> String //function definition
oddEven m //function declaration, m is the input
| m == 0 = "Even" // 0 is even
| (mod m 2) == 0 = "Even" // even numbers are divisible by 2
| otherwise = "Odd" //if its not an even number thats make it odd.
Using if and else construct a recursive function to compare y = x ^ n, where n > 0 and is out type integer ? ( 10 marks )
toPower :: Float -> Float -> Float
toPower m n =
if (n > 0)
then
m * power m (n-1)
else
1