PDA

View Full Version : FP intro night (my Scheme stuff)


Strike
12-10-2002, 01:52 AM
In honor of what became sort of the ad hoc "Functional Programming night" in #coderforums, I decided to do all the stuff that ink and Vince and I were working out in Haskell .. in Scheme as well :) I actually even got one function done in Scheme that we haven't worked out how to do in Haskell yet. Anyway, here are the snippets for:
* factorial - a tail-recursive implementation
* mymap - a map rewrite
* mult - basically the equivalent of "folding" the multiplication operator a cross a list
* myfilter - a filter rewrite (Scheme only, so far)

factorial.scm

(define (factorial x)
(if (= x 0)
1
(* x (factorial (- x 1)))))


mymap.scm

(define (mymap func ls)
(if (null? ls)
'()
(cons (func (car ls)) (mymap func (cdr ls)))))


mult.scm

(define (mult ls)
(cond
((null? ls)
1)
((= 1 (length ls))
(car ls))
(#t
(* (car ls) (mult (cdr ls))))))


myfilter.scm

(define (myfilter test? ls)
(cond
((null? ls)
'())
(else
(if (test? (car ls))
(cons (car ls) (myfilter test? (cdr ls)))
(myfilter test? (cdr ls))))))


This was a lot of fun. Kind of like XP's "Pair programming" in a way, except we had 3 people. We all had varying levels of familiarity, and they played off of each other well. I'd love to do this again some other time.

GnuVince
12-10-2002, 08:20 AM
Definitly should do it again. I'll do these scheme examples in O'Caml today

GnuVince
12-10-2002, 09:26 AM
OK, I got the functions, here they are:


let rec fact n =
if n <= 1 then 1
else n * fact (n-1);;

let rec my_map func lst = match lst with
| [] -> []
| h::t -> (func h)::(my_map func t);;

let rec mult lst = match lst with
| [] -> 1
| h::t -> h * mult t;;

let rec my_filter cond lst = match lst with
| [] -> []
| h::t -> if cond h then h::my_filter cond t else my_filter cond t;;

bwkaz
12-10-2002, 09:40 AM
Even though I wasn't there, I'd volunteer to do these all in Common Lisp. Except for the fact that that would be trivially easy, considering Scheme and clisp are so close -- what I would come up with is only slightly syntactically different from the Scheme stuff here...

Ah well.

inkedmn
12-10-2002, 10:28 AM
Strike, Vince:

thanks again for all your help and for taking the time to explain things to me REPEATEDLY :)

i'm thinking we could do it again either tonight or tomorrow night...

same time, same place? ;)

GnuVince
12-10-2002, 10:29 AM
Oh, here's uniq:


let rec uniq lst = match lst with
| [] -> []
| h::t -> if (List.mem h t) then
h::uniq (List.filter ((<>) h) t)
else
h::uniq t;;

GnuVince
12-10-2002, 10:30 AM
What time was it again? We're in 3 different time zones... But yeah, I'd do it again tonight. You could try to write foldl and foldr functions

GnuVince
12-10-2002, 10:43 AM
My very own fold left and fold right functions:

let rec foldl f acc lst = match lst with
| [] -> acc
| h::t -> foldl f (f acc h) t;;

let rec foldr f lst acc = match lst with
| [] -> acc
| h::t -> f h (foldr f t acc);;

jamessan
12-10-2002, 01:18 PM
I just had to write foldl and foldr functions for my scheme class, although the foldr function could recurse on the function itself. Instead you had to use 'let'.

PrBacterio
12-10-2002, 02:04 PM
Originally posted by Strike
* factorial - a tail-recursive implementation

So - where is it? Come on don`t tease us - show it to us :)

GnuVince
12-10-2002, 02:17 PM
PrBacterio: ;) I'll make mine in O'Caml tail-recursive


let fact n =
let fact_aux acc n =
if n <= 1 then acc else fact_aux (n*acc) (n-1)
in
fact_aux 1 n;;

PrBacterio
12-10-2002, 02:28 PM
Originally posted by GnuVince
PrBacterio: ;) I'll make mine in O'Caml tail-recursive

That`s better 8)

Here it is in Scheme for completeness´ sake:
(define (factorial n)
(let iter ((r 1) (n n))
(if (> n 1)
(iter (* r n) (- n 1))
r)))

Also, there`s nobody in #coderforums (on irc.openprojects.net, right?), I`m all alone in there right now :(

GnuVince
12-10-2002, 02:43 PM
We switched servers. We're on #coderforums on irc.oftc.net

Strike
12-10-2002, 04:08 PM
Ah yeah, I didn't make it tail-recursive though I'd planned on it. Whoops. Tyop.

Strike
12-11-2002, 12:48 AM
Okay, using the filter function from above (renamed to just filter since that's not a built-in):
uniq

(load "filter.scm")

(define (not-equal num)
(lambda (num2)
(not (equal? num num2))))

(define (uniq ls)
(cond
((null? ls)
'())
(else
(cons (car ls) (uniq (filter (not-equal (car ls)) (cdr ls)))))))

I could selectively apply the filter by using member? (thanks, jamessan), but I was lazy :)

(edit) code tags are good