functional programming

  • Thread starter Haris Bogdanovic
  • Start date
P

Pascal J. Bourguignon

David A. Black said:
Hi --

Mike Gold said:
Pascal J. Bourguignon wrote:

Why is func.call() or func[] or func.() "very useful" compared to
func()? As I mentioned, in every case I've found it to be a
hassle, for the reasons previously stated.

The reason is because Ruby is a lisp-2. The same name can be used to
designate both a method and a variable. So you need two syntaxes, to
make reference to the method of a name, or to the variable.

No, that's not the reason. It is because Ruby allows method invocation
without parens. Therefore parens cannot be used to unambiguously
"dereference" a function.

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.
 
D

David A. Black

Hi --

David A. Black said:
Hi --

Pascal J. Bourguignon wrote:

Why is func.call() or func[] or func.() "very useful" compared to
func()? As I mentioned, in every case I've found it to be a
hassle, for the reasons previously stated.

The reason is because Ruby is a lisp-2. The same name can be used to
designate both a method and a variable. So you need two syntaxes, to
make reference to the method of a name, or to the variable.

No, that's not the reason. It is because Ruby allows method invocation
without parens. Therefore parens cannot be used to unambiguously
"dereference" a function.

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:

Right -- that's my point :) 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 (http://manning.com/black2)

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

Gary Wright

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 Wright
 
P

Pascal J. Bourguignon

David A. Black said:
Right -- that's my point :) 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.
 
H

Haris Bogdanovic

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.
 
P

Pascal J. Bourguignon

Haris Bogdanovic said:
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)
 
M

Mike Gold

Pascal said:
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,073
Latest member
DarinCeden

Latest Threads

Top