56
BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: [email protected] WWW: http://staffnet.kingston.ac.uk/~ku02309

BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: [email protected] WWW: ku02309

  • View
    217

  • Download
    1

Embed Size (px)

Citation preview

Page 1: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: Software Development

Functional Programming in Haskell

2010/2011

Dan Russell

Email: [email protected]: http://staffnet.kingston.ac.uk/~ku02309

Page 2: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 2

Administration

Materials for the course, including handouts,

the module guide, and the lab session worksheets, will be on my SWD web page at:

http://staffnet.king.ac.uk/~ku02309/courses/swd1011.html

This page can be accessed directly from StudySpace.

Exercise Classes: using the Hugs interpreter.

Page 3: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 3

Software Development

A.K.A. The Development of Software

A.K.A. The analysis of a problem and the

design (using a choice of media) and implementation (using a programming

language) of a solution to the problem.

Page 4: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 4

Programming Paradigms

Various including:

Imperative/Procedural, Object-Oriented and Functional

Each paradigm is populated with a collection of

programming languages and support tools such

as analysis and design methodologies (ADMs).

Page 5: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 5

Programming Languages

Imperative/Procedural: Fortran, Cobol, Pascal, Basic and C

Object-Oriented: C++, Java and C#

(plus JavaScript which is a Web

scripting language that you will use

at Level 5)

Functional: Miranda, Scheme, ML and Haskell

Page 6: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 6

Functional Programming

Programming with functions

in contrast to

Programming with objects

and also in contrast to

Programming with procedures

Page 7: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 7

Functional Programming

The programming language we use on this course

is Haskell 98.

See http://www.haskell.org/

There are various implementations of the language. The one we will use on this course is Hugs 98.

Runs on: Windows, Unix, Linux and MacOS.

See http://www.haskell.org/hugs/

Page 8: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 8

FORMALITY

Every programming language is a formal language which has to be adhered to for a program to work.

That is, it will have a set of rules regarding things like:

-- what is an acceptable name;

-- what is acceptable layout;

-- whether it is case-sensitive or not;

and so on…

Page 9: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 9

FORMALITY

Rule 1:

Every function name MUST begin with a lower case letter.

Rule 2:

No spaces are allowed in any name.

Page 10: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 10

Your First Problem

Define a function which doubles its input.

The analysis could include some sample input/output values to:

i. make sure that you understand the problem;ii. get an idea of the number and kind of input(s)

required;iii. get an idea of the kind of output required.

Note: These are non-programming issues. If you don’t understand the problem there is no way you can find a solution.

Page 11: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 11

Your First ProblemDefine a function which doubles its input.

Input Output

1

7

43

-9

A textual description of the function based on the above is often useful.

Multiply the input value by 2.

So how many input(s) are required, what are they, and what kind of output is required?

Page 12: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 12

Your First Problem

So when designing the solution we need a function which requires a single number input, and returns a number as output.

Part of the design process is deciding on a name for the function and a name for each input value.

The function name should suggest what the function does.

The input name should be short but should also give an indication of what the input is, if possible.

Page 13: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 13

Your First Problem

Which of the following combinations of function and input names is sensible?

Function Name Input Name

f x carrot k square t double double double n

d n

So now all we have to do is implement the solution!

Page 14: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 14

Your First Haskell Program

module Program1 where

-- This is a comment. A module hosts a collection

-- of definitions. A module name begins with an

-- upper case (CAPITAL) letter.

double n = 2 * n

-- Another comment. The function called

-- double returns double the input value.

-- The input value is called n.

Page 15: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 15

Your First Haskell Program

Lets use the program that we have just written.

Main> :l Program1

Reading file "Program1.hs":

Hugs session for:

C:\Program Files\Hugs98\lib\Prelude.hs

Program1.hs

Main> double 3

6

Main> double 27

54

Main> double 1312

2624

Main> double 43.2

86.4

This is how you load the program

This confirms that the program has been found and is OK.

Examples of using a function definedin the program.

Note: the function ALWAYS appears to the left of its argument(s).

Page 16: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 16

Your First Haskell Program

Lets try to use a program that we have not yet written.

Main> :l Program2

Reading file "Program2":

ERROR "Program2" - Unable to open file "Program2"

Main> :l Program1

Reading file "Program1.hs":

Hugs session for:

C:\Program Files\Hugs98\lib\Prelude.hs

Program1.hs

Main> duoble 7654ERROR - Undefined variable "duoble“

Main>

This indicates that the programdoes not exist.

Now Program1 has to be loaded again.

This error message is receivedwhen the function cannot be found.

Page 17: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 17

Your First Haskell Program

Lets continue to use the program.

Main> double

Main> double 'B'

ERROR - Illegal Haskell 98 class constraint in inferred type

*** Expression : double 'B'

*** Type : Num Char => Char

This indicates that the functionis being applied to the wrongtype of thing.

Page 18: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 18

FORMALITY

Rule 3:

When using a function it must always appear to the left of the thing(s) to which it is applied (the argument(s)).

Rule 4:

There must always be at least one space between a function and its argument(s).

Page 19: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 19

Your Second Problem

Define a function which returns the maximumof two integers.

The analysis could include some sample input/output values to:

i. make sure that you understand the problem;ii. get an idea of the number and kind of input(s)

required;iii. get an idea of the kind of output required.

Note: These are non-programming issues. If you don’t understand the problem there is no way you can find a solution.

Page 20: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 20

Your Second Problem

Define a function which returns the maximum oftwo integers.

Input 1 Input 2 Output 1 5 7 3 43 43 - 9 0

A textual description of the function based on the above is often useful.

If the first input is less than the second then the second is returned. If the first input is greater than or equal to the second then the first is returned.

Page 21: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 21

Your Second Problem

So when designing the solution we need a function which requires two integer (whole number) inputs, and returns an integer as output.

Part of the design process is deciding on a name for the function and a name for each input value.

The function name should suggest what the function does.

The input names should be short but should also give an indication of what the input is, if possible.

Page 22: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 22

Your Second Problem

Which of the following combinations of function and input names is sensible?

Function Name Input 1 Name Input 2 Name

f x y carrot k t double m n maxOf2 i i maxOf2 i j maximum x y

So now all we have to do is implement the solution!

Page 23: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 23

Your Second Haskell Program

module Program2 where

-- The function maxOf2 takes two integers-- and returns the maximum

maxOf2 i j = if i < j then j else i

-- Note how the definition mimics -- the description.

If the first input is less than the second then the second is returned. If the

first input is greater than or equal to the second then the first is returned.

Page 24: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 24

So What Does One Do?

Analyse: Investigate the problem, identifying the

essential features.

Design: Develop an implementable solution using

a chosen medium (i.e. text, pseudocode,

actual code or graphical)

Implement: Write code in your chosen programming

language that faithfully implements

the design.

Page 25: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 25

Essential Building Blocks of Functional Programming

#1

FUNCTIONSFUNCTIONS

A function is something which given a particular input

value(s) returns one particular output value.

We implement software in Haskell (Hugs) by defining

a collection of functions.

Page 26: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 26

Which of the following are functions?

1. daysInMonth

2. countryVisitedThisYear

3. capitalCityOf

4. sittingNextTo

Page 27: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 27

Some Functions...

-- addOne simply adds one to the input value

addOne n = n + 1

-- square uses the `to the power of’ operator ^

square m = m ^ 2

-- always7 ignores the input value and returns 7

always7 k = 7

-- isGreaterThan10 tests whether the input

-- number is greater than 10

isGreaterThan10 p = p > 10

Page 28: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 28

Essential Building Blocks of Functional Programming

#2

TYPESTYPES

A type is a collection of values (such as integers and

characters) which are grouped together because they are the same sort of thing.

They are used as part of the design process, and as

a guide to the user of a function as to what can be

input and what will be output.

Page 29: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 29

Some Functions (now with types)...

addOne n = n + 1

square m = m ^ 2

always7 k = 7

isGreaterThan10 p = p > 10

Page 30: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 30

Some Functions (now with types)...

Function Name Input Type Output Type

addOne :: Int -> Int

addOne n = n + 1

square m = m ^ 2

always7 k = 7

isGreaterThan10 p = p > 10

Page 31: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 31

Some Functions (now with types)...

Function Name Input Type Output Type

addOne :: Int -> Int

addOne n = n + 1

square :: Float -> Float

square m = m ^ 2

always7 k = 7

isGreaterThan10 p = p > 10

Page 32: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 32

Some Functions (now with types)...

Function Name Input Type Output Type

addOne :: Int -> Int

addOne n = n + 1

square :: Float -> Float

square m = m ^ 2

always7 :: any -> Int

always7 k = 7

isGreaterThan10 p = p > 10

Page 33: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 33

Some Functions (now with types)...

Function Name Input Type Output Type

addOne :: Int -> Int

addOne n = n + 1

square :: Float -> Float

square m = m ^ 2

always7 :: any -> Int

always7 k = 7

isGreaterThan10 :: Int -> Bool

isGreaterThan10 p = p > 10

Page 34: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 34

Why You Should Love Types! Why You Should Love Types!

The first reason why you should love types is that:

they provide a clear guide in development.

That is, after doing some analysis you can discover the required input type(s) and output type. Thus you know exactly what the functioncan be applied to and what it can return.

It is often the case that one specifies the type of a function well in advance of defining the function. This is so that other developersknow about the existence of the function and about how it may be used.

Note: Most popular programming languages are typed (have types). Thus these arguments apply for Java, C#, C++ and so on.

Page 35: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 35

Why You Should Love Types! Why You Should Love Types!

For example:

aFun :: Int -> Int aFun takes an Int and returns an Int

Page 36: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 36

Why You Should Love Types! Why You Should Love Types!

For example:

aFun :: Int -> Int

bFun :: String -> Bool

aFun takes an Int and returns an Int

bFun takes a String and returns a Bool

Page 37: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 37

Why You Should Love Types! Why You Should Love Types!

For example:

aFun :: Int -> Int

bFun :: String -> Bool

cFun :: Char -> Char -> String

aFun takes an Int and returns an Int

bFun takes a String and returns a Bool

cFun takes two Chars and returns a String

Page 38: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 38

Why You Should Love Types! Why You Should Love Types!

For example:

aFun :: Int -> Int

bFun :: String -> Bool

cFun :: Char -> Char -> String

dFun :: (Float,Float) -> String

aFun takes an Int and returns an Int

bFun takes a String and returns a Bool

cFun takes two Chars and returns a String

dFun takes a pair of Floats and returnsa String

Page 39: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 39

Why You Should Love Types! Why You Should Love Types!

The second reason why you should love types is that:

anybody who wants to use the functions in the futureknows what they require as input and return as output.

Often all that one wants to know about a function that one wantsto reuse is the type(s) of its input, the type of its output, and whatthe function does.

That is, one doesn’t need to know how the function does what it does.

Page 40: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 40

Why You Should Love Types! Why You Should Love Types!

For example:

fFun str = addOne (length str)

Page 41: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 41

Why You Should Love Types! Why You Should Love Types!

For example:

fFun :: String -> IntfFun str = addOne (length str)

The input to fFun is a String and theoutput is an Int. Since length can be applied to a String and returns its length as an Int , and addOne is applied to an Int, this is OK.

We do not care how length is defined!

Page 42: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 42

Why You Should Love Types! Why You Should Love Types!

For example:

gFun s i = i == length s

Page 43: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 43

Why You Should Love Types! Why You Should Love Types!

For example:

gFun :: String -> Int -> BoolgFun s i = i == length s

The inputs to gFun is a String and anInt. The output is a Bool.length can be applied to a String andreturn an Int.== takes two values (of the same type)and returns a Bool.

We do not care how length and== are defined!

Page 44: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 44

Why You Should Love Types! Why You Should Love Types!

The third reason why you should love types is that:

they allow the compiler (e.g. Hugs) to spot errors inthe function definition.

That is, the input(s) and output of the function are specified by typesand the definition needs to be consistent with this.

Note: This is called a compile-time error.

Page 45: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 45

Why You Should Love Types! Why You Should Love Types!

For example:

hFun :: String -> InthFun x = x + 99

Page 46: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 46

Why You Should Love Types! Why You Should Love Types!

For example:

hFun :: String -> InthFun x = x + 99

The input to hFun is a String and theoutput is an Int. The definition tries to add a Stringto 99 which will result in a compile-timeerror.

Page 47: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 47

Why You Should Love Types! Why You Should Love Types!

For example:

hFun :: String -> InthFun x = x + 99

iFun :: (Char, Char) -> BooliFun c1 c2 = c1 == c2

The input to hFun is a String and theoutput is an Int. The definition tries to add a Stringto 99 which will result in a compile-timeerror.

Page 48: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 48

Why You Should Love Types! Why You Should Love Types!

For example:

hFun :: String -> InthFun x = x + 99

iFun :: (Char, Char) -> BooliFun c1 c2 = c1 == c2

The input to hFun is a String and theoutput is an Int. The definition tries to add a Stringto 99 which will result in a compile-timeerror.

The input to iFun is a pair of Chars.The definition uses two Chars.This is not the same and thus a compile-time error!

Page 49: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 49

Why You Should Love Types! Why You Should Love Types!

For example:

hFun :: String -> InthFun x = x + 99

iFun :: (Char, Char) -> BooliFun c1 c2 = c1 == c2

jFun :: String -> Int -> BooljFun s i = if length s == i

then “Same”else “Different”

The input to hFun is a String and theoutput is an Int. The definition tries to add a Stringto 99 which will result in a compile-timeerror.

The input to iFun is a pair of Chars.The definition uses two Chars.This is not the same and thus a compile-time error!

Page 50: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 50

Why You Should Love Types! Why You Should Love Types!

For example:

hFun :: String -> InthFun x = x + 99

iFun :: (Char, Char) -> BooliFun c1 c2 = c1 == c2

jFun :: String -> Int -> BooljFun s i = if length s == i

then “Same”else “Different”

The input to hFun is a String and theoutput is an Int. The definition tries to add a Stringto 99 which will result in a compile-timeerror.

The input to iFun is a pair of Chars.The definition uses two Chars.This is not the same and thus a compile-time error!

The input to jFun is a String and an Int.The output is a Bool.The output in the definition is a String.This clashes with the specification andthus is a compile-time error!

Page 51: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 51

Why You Should Love Types! Why You Should Love Types!

The fourth reason why you should love types is that:

they allow errors to be identified when the functionis actually used.

That is, if one tries to apply a function to the incorrect input thenthe type specification will highlight this error.

Note: This is called a runtime error.

Page 52: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 52

Why You Should Love Types! Why You Should Love Types!

For example:

hugs:> length 7

hugs:> snd “Dan” True

hugs:> double True

Page 53: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 53

Why You Should Love Types! Why You Should Love Types!

For example:

hugs:> length 7

hugs:> snd “Dan” True

hugs:> double True

The input to length is a String.Here we are trying to apply it to an Intwhich results in a runtime error.

Page 54: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 54

Why You Should Love Types! Why You Should Love Types!

For example:

hugs:> length 7

hugs:> snd “Dan” True

hugs:> double True

The input to length is a String.Here we are trying to apply it to an Intwhich results in a runtime error.

The input to snd is a pair of values.Here we are trying to apply it to two values which results in a runtime error.

Page 55: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 55

Why You Should Love Types! Why You Should Love Types!

For example:

hugs:> length 7

hugs:> snd “Dan” True

hugs:> double True

The input to length is a String.Here we are trying to apply it to an Intwhich results in a runtime error.

The input to snd is a pair of values.Here we are trying to apply it to two values which results in a runtime error.

The input to double is an Int.Here we are trying to apply it a Boolwhich is a runtime error.

Page 56: BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: ku02309

BB1756: SWD 56

Why You Should Love Types! Why You Should Love Types!

The final reason why you should love types is that:

without them all of the above benefits would disappear.

That is, -- erroneous code would compile!

-- one could apply functions to inappropriate inputs and something (unexpected) would happen!

-- potential users of functions would have no idea how they should be used!