Functional programming

Hi –

On Wed, 14 Jan 2009, Pascal J. Bourguignon wrote:

“dereference” a function.
It’s clear, f() calls the def f.
You need and have another expression to call the lambda.

And this is because there are two things that are designated by the identifier f here:

Right – that’s my point :slight_smile: I thought that you were suggesting the
unification of calling a method and calling a function that’s stored
in a variable.

David


David A. Black / Ruby Power and Light, LLC
Ruby/Rails consulting & training: http://www.rubypal.com
Coming in 2009: The Well-Grounded Rubyist (The Well-Grounded Rubyist)

http://www.wishsight.com => Independent, social wishlist management!

On Jan 14, 2009, at 9:09 AM, Pascal J. Bourguignon wrote:

“David A. Black” [email protected] writes:

But what would this be:

f = lambda {}
def f; end
f()

It’s clear, f() calls the def f.
You need and have another expression to call the lambda.

Maybe something like:

(f())()

But, like David, I still don’t see the net benefit to the language
involved in this line of thinking.

f[]

Seems to meet most needs without trying to make Ruby something
that it isn’t.

Gary W.

“David A. Black” [email protected] writes:

func()? As I mentioned, in every case I’ve found it to be a
It wouldn’t matter if we had not to distinguish calling a named
function from calling a function stored in a variable.

But what would this be:

f = lambda {}
def f; end
f()

It’s clear, f() calls the def f.
You need and have another expression to call the lambda.

And this is because there are two things that are designated by the
identifier f here:

  • A function defined with def.
  • A variable assigned with =.

Or, said more concisely, Ruby is a lisp-2.

I started to learn Common Lisp and I saw that it is a great language.
You have interpreter but you can also compile code. On list of projects
made
by CL is even an operating system. That’s impossible with Ruby and
interpreted languages in general. You have functional language which is
also
pure object oriented like Smalltalk or Ruby. 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.
And also CL has a lot of other advantages. As I understood Pascal, you
can
make code that makes other code and you have support for logic
programming
like Prolog.

“Haris B.” [email protected] wrote in message
news:[email protected]

“David A. Black” [email protected] writes:

And this is because there are two things that are designated by the identifier f here:

Right – that’s my point :slight_smile: I thought that you were suggesting the
unification of calling a method and calling a function that’s stored
in a variable.

No such suggestion. It’s just a classification. You have languages
with a single name space for values and functions, and you have
languages with distinct namespaces. Scheme is in the former. Ruby,
emacs lisp, Common Lisp are in the later.

Pascal J. Bourguignon wrote:

Ok, here is how you could implement an object with Ruby closures:

define_method lets you implement objects using locals bound to a
closure,

object = Class.new {
data = 0
define_method(:data) {
data += 1
}
}.new

p object.data #=> 1
p object.data #=> 2

“Haris B.” [email protected] writes:

I started to learn Common Lisp and I saw that it is a great language.

Good, go on! :slight_smile:

[…] 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)