From: pjb@... (Pascal J. Bourguignon) Date: 2009-01-16T07:09:14+09:00 Subject: Re: functional programming "Haris Bogdanovic" writes: > I started to learn Common Lisp and I saw that it is a great language. Good, go on! :-) > [...] Haskell is pure functional > language and I don't see how programmers can manage large portions of code > without objects. It's like procedural language with functions instead of > procedures. First, in sane programming languages, you have the notion of closure: an anonymous function catches its free variables and encloses them. A function is no more a dead function, it's both a function and some data enclosed in the "closure". And what an object is? Some data enclosed (encapsuled) along with some methods, that is functions. That's exactly the same. You can implement closures with objects, and you can implement objects with closures. Since Haskell is a functional programming language that has closures (it wouldn't work otherwise), you can easily implement an object system, and build big software in Haskell. However, in PURE functional programming language, where there is no assignment, there's no state so to speak, since you cannot change it. So it's hardly worthwhile to make an object. You couldn't write a purely functional method to do anything to such an object. You could only write methods that would build new objects, all objects being immutable. But most functional programming languages introduce some impurities, so it's usually quite usable. See for example Ocaml, which is Objective Categorical Abstract Meta Language, a functional programming language with objects, modules, pattern matching, polymorphism, strongly typed, type inference, statically typed, etc. Ok, here is how you could implement an object with Ruby closures: (get the missing functions from my previous recent posts). (def first(list) (car list) end) (def second(list) (car (cdr list)) end) (def third(list) (car (cdr (cdr list))) end) (def fourth(list) (car (cdr (cdr (cdr list)))) end) (def fifth(list) (car (cdr (cdr (cdr (cdr list))))) end) (def assoc(key,alist) (if (null alist) nil elsif (key == (car (car alist))) (car alist) else (assoc key,(cdr alist)) end) end) (o = (begin (a = 1) (b = 2) (methods = (list (list :getA,(lambda { a })), (list :setA,(lambda { | newA | (a = newA) })), (list :getB,(lambda { b })), (list :setB,(lambda { | newB | (b = newB) })), (list :doSomething,(lambda { | x | (a = (a - b)) ; (b = x) })))) (lambda { | message , *args | (method = (assoc message,methods)) (if (method == nil) (throw "No such method "+(message . to_s)) else (funcall (second method),*args) end) }) end)) irb(main):146:0> (funcall o,:getA) (funcall o,:getA) 1 irb(main):147:0> (funcall o,:getB) (funcall o,:getB) 2 irb(main):148:0> (funcall o,:setA,42) (funcall o,:setA,42) 42 irb(main):149:0> (funcall o,:doSomething,3) (funcall o,:doSomething,3) 3 irb(main):150:0> (funcall o,:getA) (funcall o,:getA) 40 irb(main):151:0> (funcall o,:getB) (funcall o,:getB) 3 irb(main):152:0> You can also rename funcall as send, if you want to get a more "oo" feeling: (send o,:getB) -- __Pascal Bourguignon__