Programming C, C++, Java, PHP, Ruby, Turing, VB
Computer Science Canada 
Programming C, C++, Java, PHP, Ruby, Turing, VB  

Username:   Password: 
 RegisterRegister   
 [WIP] [SML] An Introduction to Programming
Index -> Programming, General Programming -> Functional Programming
View previous topic Printable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic
Author Message
wtd




PostPosted: Sun Sep 24, 2006 9:28 am   Post subject: [WIP] [SML] An Introduction to Programming

So you've never programmed before? That's what this tutorial will assume. If you have, please don't be offended by this assumption.

This tutorial will assume that you understand how to use a computer, and that you're using Windows 2000 or Windows XP.

This tutorial will cover some basic ideas before explaining how to actually use the example code. Please try to be patient.

This tutorial will be concise. If you have questions, feel free to pose them.

Introduction

Programming really breaks down to be about three things.


  • Values
  • Transformation of values into other values
  • Side-effects that occur on the way


Values

Values are simply pieces of information in your program. They come in many flavors.

Integers

One of the most fundamental types of data in a computer program is the integer. These are simply whole numbers.

The number one:

code:
1


The number forty-two:

code:
42


The number negative twenty-seven:

code:
~27


Real Numbers

Real numbers are numbers which do not have an exact whole number number value. In addition to such a value, there is also a fractional portion.

The real number two point seven:

code:
2.7


The real number negative one:

code:
~1.0


Characters

A character is a single unit of printable text.

The first character in "Foo":

code:
#"F"


The second character:

code:
#"o"


A dot:

code:
#"."


Strings

Strings are composed of zero or more characters.

"Foo":

code:
"Foo"


An empty string:

code:
""


Lists

Lists can contain zero or more values of the same type.

An empty list:

code:
[]


A list containing three integers:

code:
[1, 42, ~27]


A list containing two strings:

code:
["Foo", "Bar"]


Tuples

Tuples can contain multiple values, and they can be of different types. Tuples sharing the same number of values, in the same positions and of the same types are considered to be of the same type.

A tuple containing just a single value is not a tuple at all but rather is equivalent to that value.

A tuple containing a string and an integer:

code:
("Wooble", 42)


A tuple containing an integer, a real number, and a character:

code:
(27, 3.14, #"a")


Records

Records are similar to tuples. They can contain multiple values, and values of different types, but give names to each of these values. These names are called "fields." As such, the order of the values in the record is not important.

A simple record with a "foo" field of type integer:

code:
{foo=42}


A record containing a first and last name:

code:
{firstName="Foo", lastName="Bar"}


A record equivalent to the previous record:

code:
{lastName="Bar", firstName="Foo"}


Unit

There is only one value of the type "unit." It appears as a tuple with no values. It is the closest thing to "nothing."

code:
()


Booleans

Boolean values are very simply either true or false.

code:
true


code:
false


Types

Each of the types described has a specific type. The names of those types are described below.

code:
Type         | Example            | Type Name
-------------+--------------------+--------------------
Integers     | 1                  | int
Real Numbers | 27.3               | real
Characters   | #"f"               | char
Strings      | "Foo"              | string
Lists        | [1, 2, 3]          | int list
             | ["Foo", "Bar"]     | string list
Tuples       | (1, "hey", 3.14)   | int * string * real
             | (#"r", [1, 2, 3])  | char * int list
Records      | {foo=42, bar=#"a"} | {bar:char, foo:int}
Unit         | ()                 | unit
Booleans     | true               | bool


Giving Names to Values

In a simple example, we give a name to the the integer value 1:

code:
val one = 1


In the previous example, it's worthwhile noting that the type is not explicitly designated. It can be, but the type can be inferred from the value.

code:
val one : int = 1


Reapeted Use of a Name

It is possible to use the same name repeatedly:

code:
val a = 42
val a = "foo"


When the name "a" is later used, its value will be the string "foo" and not the integer 42.

Another example:

code:
val a = 42
val a = a


Here the value of "a" will still be 42, since the old value was used as the value for "a" in the new binding.

Local Use of Names

The previous example is comparable to the use of local names.

code:
val a = let
   val a = 42
in
   a
end


Transformation of Values

Values are of little use if they cannot be tranformed into other values.

Arithmetic

Perhaps the simplest example of this is integer arithmetic. For instance, the "+" operator transforms the values 1 and 2 into the value 3.

code:
1 + 2


Yields:

code:
3


Arithmetic on real numbers works the same way, though arithmetic typically only works on two integers or two real numbers, and not a mixture. How this is dealt with is by performing a transformation from an integer to a real number or vice versa.

Comparisons

Values can be compared to transform them into a boolean value.

Comparison for equality:

code:
1 = 1


Comparison for inequality:

code:
1 <> 1


Greater than comparison:

code:
3 > 4


Less than comparison of the values resulting from other value transformations:

code:
3 / (2 - 1) < 5 * 3 - 4


Which simplifies to:

code:
3 / 1 < 15 - 4


And from there to:

code:
3 < 11


Tranforming Boolean Values

Two boolean values can be transformed into another boolean value. An "or" transformation returns true if either boolean value is true. An "and" transformation returns false only if both values are true.

True:

code:
3 < 11 andalso 5 > 4


False:

code:
3 < 11 andalso 4 > 5


True:

code:
3 < 11 orelse 4 > 5


Tuple and Record Transformation

Selectors can be used to transform tuples and records into other values.

A selector which transforms a tuple containing the values 1 and the character "f" into the character "f":

code:
#2 (1, #"f")


A selector which transforms a record into simply the "lastName" value it contains:

code:
#lastName {firstName="Foo", lastName="Bar"}


List Transformation

Transforming an integer and an empty list into a list containing a single integer value:

code:
1 :: []


The above becomes:

code:
[1]


Similarly:

code:
1 :: [2]


Becomes:

code:
[1, 2]


Conditional Transformation

Conditional transformations make it possible to use a boolean value to determine which of two values to transform into.

Conditional transformation that evaluates to 42:

code:
if 3 < 11 then 42 else 27


Conditional transformation that evaluates to 27:

code:
if 3 > 11 then 42 else 27


Conditional tranformations can result in other conditional transformations.

Tranform that evaluates to 3:

code:
if 3 > 11 then 42
else if 4 < 3 orelse 2 > 1 * 3 then 27
else 3


This can be rewritten as follows to more clearly demonstrate what is happening.

code:
if 3 > 11 then 42
else (if 4 < 3 orelse 2 > 1 * 3 then 27
      else 3)


Pattern-matching Tranformation

Conditional transformations use a boolean value to transform into some value. Pattern-matching provides patterns for values, and maps each pattern to a value.

A simple example, working on an integer that evaluates to "four":

code:
case 4 of
   1 => "one"
 | 2 => "two"
 | 3 => "three"
 | 4 => "four"
 | 5 => "five"
 | n => "something else"


This time the result is "something else":

code:
case 4 + 2 of
   1 => "one"
 | 2 => "two"
 | 3 => "three"
 | 4 => "four"
 | 5 => "five"
 | n => "something else"


Another example, working on a tuple:

code:
case (3.14, "double") of
   (value, "single") => value
 | (value, "double") => value * 2.0
 | (value, "triple") => value * 3.0
 | (value, _) => value


In the above, the result is 6.28. In the last pattern, which will always match, if some previous pattern has not matched, the underscore indicates a value we do not care enough about to give a name to.

Incidentally, the last example also demonstrated pattern-matching with strings.

Pattern-matching also works with records.

code:
case {first="Bob", last="Smith"} of
   {first="Bob", last=_} => "Hello, Bob"
 | {first=_, last=last} => "Hello, Mr. or Mrs. " ^ last


Also demonstrated here is a string tranformation. In this case it's concatenation. The two strings are added together to form a new string.

And one more that simply flips the values in a tuple:

code:
case (12, 34.56) of (a, b) => (b, a)


In the previous example, there is only a single pattern. This is possible due to the fact that the pattern offered always matches.

A pattern-matching example that involves a list and returns a tuple containing an integer and a list of integers:

code:
case [1, 2, 3] of
   [] => (0, [])
 | first::rest => (first, rest)


The above evaluates to:

code:
(1, [2, 3])


Functions

Functions take a single value, and map it to some other value via a series of transformations.

A function which takes an integer and simply doubles it:

code:
fn x => x * 2


The function is then a value which can be given a name.

code:
val double = fn x => x * 2


And can be used:

code:
val four = double 4


The function thus far demonstrated can also be more succinctly expressed as:

code:
fun double x = x * 2


Pattern Matching

Again, pattern-matching returns. It can be used to change the implementation of the function "double" a bit.

code:
val double = fn 0 => 0 | 1 => 2 | x => x * 2


This can be rewritten using the "fun" syntax demonstrated earlier.

code:
fun double x =
   case x of
      0 => 0
    | 1 => 2
    | _ => x * 2


This can be more directly expressed, though.

code:
fun double 0 = 0
  | double 1 = 2
  | double x = x * 2


Multiple Values

That's all well and good, but it's extremely useful to be able to send multiple values to a function. Records, tuples and lists all provide an easy answer to this problem. Any of these represent a good way to group multiple values as a single value.

An add function:

code:
fun add (a, b) = a + b


Which can be called as:

code:
val seven = add (1, 6)


Or perhaps as:

code:
val seven = let
   val pair = (1, 6)
in
   add pair
end


As it happens, this is how the addition operator works. We can also express the fucntion definition as:

code:
fun add (a, b) = op+ (a, b)


As seen earlier, though, functions are values. As "op+" is a function which takes a tuple of integers and adds them, we can get it as a value.

code:
val add = op+


Multiple Values... But Not

It has been established that functions can only take a single value, and transform it into a single other value. This would seem to indicate that tuples and other such things are the only way to pass more than one value to a function. While this is technically true, there is a way around this rule.

Functions are values. That has also been established.

It stands to reason, therefore, that a function can transform a value into a function which itself takes a further value and transforms it into some other value.

A function which takes an integer "a" and transforms it into a function which takes an integer value "b" and adds those two values:

code:
val add = fn a => fn b => a + b


Thi can be simplified a bit:

code:
fun add a = fn b => a + b


This can then be called:

code:
(add 3) 2


But the call can be simplified:

code:
add 3 2


In fact, the definition of the function can be simplified to match that call:

code:
fun add a b = a + b


However, it remains as originally written, and that can be seen by only applying one of the arguments and getting a function back.

code:
val add1 = add 1
val four = add1 3
Sponsor
Sponsor
Sponsor
sponsor
md




PostPosted: Sun Sep 24, 2006 11:33 am   Post subject: (No subject)

Very nice introduction wtd; I am most intrigued with SML now...
Display posts from previous:   
   Index -> Programming, General Programming -> Functional Programming
View previous topic Tell A FriendPrintable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic

Page 1 of 1  [ 2 Posts ]
Jump to:   


Style:  
Search: