Computer Science Canada

Best Way to Teach FP

Author:  rdrake [ Wed Oct 18, 2006 12:21 pm ]
Post subject:  Best Way to Teach FP

Briefly touched on in Is functional programming difficult to learn/teach? was the idea of FP being difficult to teach to your average student.

My question to you is, how should FP be taught? Should students be allowed to analyze random snippets of code and try and figure out how they work? Is it best to teach the method behind FP first?

I personally think it's a bad idea to just through out random snippets of code without explaining to an extent how they work. I like testing them out and learning how they work, but I still don't find myself fully understanding the thought process behind FP.

I feel as though explaining some background, especially to somebody coming from another programming "style" would be best. In this way, they would understand why the snippet does something, rather than just expecting it to do something and it not. This, I feel, is fundamental in teaching FP to a larger audience.

Now, I'd be very interested in hearing the thoughts of others Smile.

Author:  wtd [ Wed Oct 18, 2006 12:29 pm ]
Post subject: 

Well, this is complicated by the fact that functional programming is surrounded by lots of peripheral concepts.

In any given program, values are being created like crazy. As a result, it's impractical to not have garbage collection. In addition to GC, many fucntional programming languages feature type-inferencing. The Lisp-ish languages feature dynamic typing, which can be quite a shift for someone primarily educated in statically-typed languages. Many functional programming languages feature rich data structures built-in. This can be disorienting.

On a more superficial note, many functional programming languages feature syntax that is quite different from more "mainstream" languages.

Figuring out what the problem is would be the first step in figuring out how to address it.

Author:  rdrake [ Wed Oct 18, 2006 12:30 pm ]
Post subject: 

So basically... give the student code, intrigue their mind and make them want more, then go over how it works.

Sounds good.

Author:  wtd [ Wed Oct 18, 2006 12:32 pm ]
Post subject: 

Well, it's more a matter of getting to know each student. Maybe computer science is too mainstream, and academia no longer has time to do this, since there are expectations as to how many code monkeys they should spit out each year.

Author:  TheZsterBunny [ Wed Oct 18, 2006 12:32 pm ]
Post subject: 

I've recently started to learn functional programming in class.

We use Miranda. It's kinda like Haskell.

The way our prof. taught it was to introduce a few snippits, and compare them with code we already knew.

For instance: the HCF program
code:

hcf x x = x
hcf x y = hcf x-y y, if x > y
             = hcf y-x x, otherwise

is far shorter than you could do it in Java
code:

public class HCF {
         public int hcf (int x, int y) {
                   if (x > y) {
                             return hcf(x-y,y);
                   } else if (y > x) {
                             return hcf (y-x, x);
                   } else {
                             return x;
                   }
         }
}

(java may not be accurate. didn't test)

After a few more examples (a quick sort, an array reverser...) we kinda got a sense for the language.

Worked for a good chunk of my class.

--added--
Just for fun; Quicksort in Miranda:
code:

qsort [] = []
qsort (x:xs) = [e | e <- xs; e < x] ++ [x] ++ [e | e <- xs; e>= x]

first statement: return nothing for an empty list
second statement: (all elements less than x) and (x) and (all elements greater than or equal to x)
-Z

Author:  wtd [ Wed Oct 18, 2006 12:46 pm ]
Post subject: 

Let's throw out a few other examples:

SML

code:
fun hcf(x, y) =
   case Int.compare(x, y) of
      EQUAL   => x
        | LESS    => hcf(y - x, x)
        | GREATER => hcf(x - y, y)


O'Caml

code:
let rec hcf x y =
   if x > y then hcf (x - y) y
   else if y > x then hcf (y - x), x
   else x


Haskell

code:
hcf x y | x == y = x
        | x > y  = hcf (x - y) y
        | y > x  = hcf (y - x) x


Scheme

code:
(define (hcf x y)
   (cond ((= x y) x)
         ((> x y) (hcf (- x y) y))
         ((> y x) (hcf (- y x) x))))


Common Lisp

code:
(defun hcf (x y)
   (cond ((= x y) x)
         ((> x y) (hcf (- x y) y))
         ((> y x) (hcf (- y x) x))))

Author:  TheZsterBunny [ Wed Oct 18, 2006 12:55 pm ]
Post subject: 

in Haskell '|' is used in list comprehensions.

i.e.
code:

fcn t = [x | x <- t; x > 2]

would take an array of integers as a parameter, and spit out all that are greater than 2. (x being the iterat through array t)

commas are used as guards.

and the first statement
code:

hcf x x = x

acts the same as
code:

hcf x y = x, if x=y


because pattern matching is so integrated to the input.

Note: Single equals is test & assignment. Strange, neh?

-Z[/code]

Author:  Cervantes [ Wed Oct 18, 2006 1:07 pm ]
Post subject: 

My thoughts on this may have shifted over time, but currently, I don't think functional programming is difficult to teach.

If a student is new to programming in general, learning a functional programming language should be fine.

If a student is an experienced programmer in imperative paradigms, make sure that student has a solid footing in recursion. Use that student's imperative language to do tasks using recursion that would normally be done using loops. Then begin with the functional language.


Speaking only in terms of Scheme here, it's simple. The semantics of Scheme are extremely basic, making tracing programs easy. The ability to trace a program fully leads to an understanding of how the program works, leading to a good familiarity with the language.

Author:  wtd [ Wed Oct 18, 2006 1:32 pm ]
Post subject: 

TheZsterBunny wrote:
Note: Single equals is test & assignment. Strange, neh?


There is no such thing as assignment in Miranda or Haskell. Wink

Author:  TheZsterBunny [ Thu Oct 19, 2006 4:13 am ]
Post subject: 

wtd wrote:

There is no such thing as assignment in Miranda or Haskell. Wink


sure there is.

code:

fibonacci n = (phi^n - (phi-1)^n)/sqrt(5)
                         where
                         phi = (1+sqrt(5))/2


in the scope of the program 'fibonacci', phi has been assigned the value of (1+sqrt(5))/2.

But what I really meant was something like this:
code:

equals a b = a = b

Fun to read that aloud. This returns True if a & b have the same value.

Author:  wtd [ Thu Oct 19, 2006 11:18 am ]
Post subject: 

TheZsterBunny wrote:
wtd wrote:

There is no such thing as assignment in Miranda or Haskell. Wink


sure there is.

code:

fibonacci n = (phi^n - (phi-1)^n)/sqrt(5)
                         where
                         phi = (1+sqrt(5))/2


in the scope of the program 'fibonacci', phi has been assigned the value of (1+sqrt(5))/2.


Well, the name "phi" has been bound to a value. It would be wrong to think of phi as a variable, to which a value has been assigned.

When using the word "assign," the first thing to come to mind is mutability. I suspect your problem is one with terminology. Those are reasonably easy to correct. Smile

Quote:
But what I really meant was something like this:
code:

equals a b = a = b

Fun to read that aloud. This returns True if a & b have the same value.


Yes, the same can be seen in SML and O'Caml. Haskell uses == for equality comparison.

Author:  wtd [ Thu Oct 19, 2006 11:38 am ]
Post subject: 

Having not used Miranda, could you not simply?

code:
equals = (=)

Author:  Lazy [ Tue Nov 07, 2006 6:21 am ]
Post subject: 

Programming languages should be learned by doing, just like all skills. To think like a Haskell programmer, you must use C. To think like a Haskell programmer, you must use Haskell. To think like a chef, you must cook - not just read recipes.

Unfortunately, forum posts around the web suggest that they are all too often not learned that way. If a poster claims that functional languages are counterintuitive by nature, then chances are he spent more time cramming lambda calculus and category theory than writing code.

Studying snippets of code, which rdrake mentioned, is useful, but not enough. It teaches you to read a language (passive knowledge), but not how to write it (active knowledge).

For example, I learned Prolog (not a functional language, but still) from the <a href="http://www.amzi.com/AdventureInProlog/advfrtop.htm"> Adventure in Prolog</a>, which walks you through the development of a (simplistic) text adventure. The project, while somewhat unrealistic (who plays text adventures anymore?), is extremely well chosen because it's 1.) readily understandable, 2.) complex enough to cover a number of Prolog techniques and idioms, and 3.) demonstrates uses of Prolog outside its stereotypical function, logical problem solving. Perhaps a similar approach would be helpful for functional languages?


: