Functional programming

Hi.

I'm starting to learn functional programming with Ruby.
I would like for someone to write me an example of finding the smallest
number in the list and a sorting algorithm.
I got the concept of map (collect), filter (select, detect and reject) and
reduce (inject) higher order functions but I don't know how to compose
algorithms from them.
So please write me those two algorithms or some other simple ones with some
explanation.
Some links to this subject would be nice also.

Thanks
Haris

I'm starting to learn functional programming with Ruby.

Wouldn't learning OO programming in Haskel be easier?

Since you are using Ruby, here is one Ruby way;

list = [6,4,5,8,12,34,5,6,778,9,777,3,45]
p list.min #> 3
p list.sort #> [3, 4, 5, 5, 6, 6, 8, 9, 12, 34, 45, 777, 778]

···

--
A Look into Japanese Ruby List in English
http://www.kakueki.com/ruby/list.html

Thank you guys for your answers. Ruby is my favourite language mostly
because it is pure object oriented and above that you can incorporate
functional programming which has it's advantages; smaller, clearer, less
error prone code.

"Haris Bogdanovic" <fbogdanovic@xnet.hr> wrote in message
news:gk3m77$1ft$1@gregory.bnet.hr...

···

Hi.

I'm starting to learn functional programming with Ruby.
I would like for someone to write me an example of finding the smallest
number in the list and a sorting algorithm.
I got the concept of map (collect), filter (select, detect and reject) and
reduce (inject) higher order functions but I don't know how to compose
algorithms from them.
So please write me those two algorithms or some other simple ones with
some explanation.
Some links to this subject would be nice also.

Thanks
Haris

"Haris Bogdanovic" <fbogdanovic@xnet.hr> writes:

I'm starting to learn functional programming with Ruby.
I would like for someone to write me an example of finding the smallest
number in the list and a sorting algorithm.
I got the concept of map (collect), filter (select, detect and reject) and
reduce (inject) higher order functions but I don't know how to compose
algorithms from them.
So please write me those two algorithms or some other simple ones with some
explanation.

You would have first to define the concept of list. Indeed, the other
answer may have you misled into believe that [1,2,3] was a list, but it
is not, it is an Array:

irb(main):477:0> [1,2,3].class
Array

(actually it's a vector, Ruby has no multidimentional arrays like
Fortran or Lisp, or any other serrious programming language).

So to make a list, first, the basic building block, the cons cell:

(class Cons
(attr_accessor :car)
(attr_accessor :cdr)
(def initialize(car,cdr)
    (@car = car)
    (@cdr = cdr)
  end)
end)

Let's wrap this object into a functional abstraction layer:

(def cons(car,cdr)
(Cons . new(car,cdr))
end)

(def car(x)
(x . car)
end)

(def cdr(x)
(x . cdr)
end)

(def null(x)
(x . nil?)
end)

irb(main):040:0> (cons 1,2)
#<Cons:0x7fdfb53eb808 @cdr=2, @car=1>
irb(main):042:0> (car (cons 1,2))
1
irb(main):043:0> (cdr (cons 1,2))
2
irb(main):044:0> (null (cons 1,2))
false
irb(main):045:0> (null (car (cons 1,nil)))
false
irb(main):046:0> (null (cdr (cons 1,nil)))
true

Then you can build a list over these cons cells:

(def list(*args)
  (i = (args . length))
  (r = nil)
  (loop {
     (if (i == 0)
        (break)
      else
        (i = (i - 1))
        (r = (cons (args [ i ]),r))
     end)
  })
r
end)

irb(main):127:0> (list 1,2,3)
#<Cons:0x7fdfb53b81d8 @cdr=#<Cons:0x7fdfb53b8200 @cdr=#<Cons:0x7fdfb53b8228 @cdr=nil, @car=3>, @car=2>, @car=1>

Let's print them pretty:

(def printelements(cons)
  (if (Cons === cons)
      (if (Cons === (car cons))
         (printlist (car cons))
        else
         (print (car cons))
      end)
      (if (Cons === (cdr cons))
         (print " ")
         (printelements (cdr cons))
       elsif (not (null (cdr cons)))
         (print " . ")
         (print (cdr cons))
      end)
  else
     (print cons)
  end)
end)

(def printlist(cons)
(print "(")
(printelements cons)
(print ")")
cons
end)

(def terpri()
  (print "\n")
end)

irb(main):263:0> (begin
                   (terpri)
                   (printlist (list 1,2,3))
                   (terpri)
                 end)

(1 2 3)
nil

You can also add some higher level abstractions:

(def first(list)
  (car list)
end)

(def rest(list)
  (cdr list)
end)

(def endp(list)
  (if (Cons === list)
      nil
   elsif (null list)
      true
   else
      (error ("Expected a list instead of the atom " + (list . to_s)))
   end)
end)

Once you've got this list abstraction, you can build functions such as reverse:

(def revappend(list,tail)
(if (null list)
     tail
  else
     (revappend (cdr list),(cons (car list),tail))
  end)
end)

(def reverse(list)
(revappend list,nil)
end)

irb(main):267:0> (begin
                   (printlist (reverse (list 1,2,3)))
                   (terpri)
                 end)
(3 2 1)
nil

Now we also need the function abstraction. In ruby functions have to
be in modules, and always qualified by the module name. This is not
pretty, so we will allow any method to be treated as a function, but
we will ignore it's recipient object, always passing self.

# For methods, the first function argument is the recipient of the
# message:

(def method(designator,arity=(-1))
   # Important: the given arity must include the recipient object, but not the recipient class:
   # (method :==,2) .call(42,42) vs. 42.==(42)
   (if (arity == -1)
      # This is the default, bugged behavior:
      (Proc . new {| x , *args | (x . send(designator , *args))})
    elsif (arity == 0)
      (raise (Exception.exception("An instance method must have an arity>=1, not 0.")))
    else
      (arity = (arity - 1))
      (args = (((arity == 0)? "" : " , ") + (((1 .. arity) . map { | i | ("a" + i.to_s) }) . join(" , "))))
      (eval("(Proc . new { | x" + args + " | " +
            "( x . send( :" + (designator . to_s) + args + " ))})"))
    end)
end)

# for functions, the recipient of the message is always 'self', all
# arguments are passed as arguments.

(def function(designator,arity=(-1))
  # Important: the given arity must include the recipient object, but not the recipient class:
  # (function "SOME_MODULE.someFunction",1) .call(42) vs. SOME_MODULE.someFunction(42)
  # (function :someFunction ,2) .call(42) vs. self.someFunction(42) or someFunction(42)
  (if (String === designator)
     mod , met = (designator . split("."))
     (if (arity == -1)
        # This is the default, bugged behavior:
        (Proc . new {| *args | ((eval mod) . send((met . to_sym) , *args))})
      else
        (args = (((1 .. arity) . map { | i | ("a" + i.to_s) }) . join(" , ")))
        (sep = " ")
        (if (0 < arity)
           (sep = " , ")
         end)
        (eval("(Proc . new { | " + args + " | " +
              "( " + mod + " . send( :" + met + sep + args + " ))})"))
      end)
   else
     (if (arity == -1)
        # This is the default, bugged behavior:
        (Proc . new {| x , *args | (x . send(designator , *args))})
      elsif (arity == 0)
        (eval("(Proc . new {" +
              "(" + (designator . to_s) + " )})"))
      else
        (args = (((1 .. arity) . map { | i | ("a" + i.to_s) }) . join(" , ")))
        (eval("(Proc . new { | " + args + " | " +
              "(" + (designator . to_s) + " " + args + " )})"))
      end)
   end)
end)

(def funcall(fun,*args)
  (fun . call(*args))
end)

irb(main):370:0> (funcall (method :+,2),3,4)
(funcall (method :+,2),3,4)
7

irb(main):478:0> (begin
                   (terpri)
                   (printlist (funcall (function :reverse,1),(list 1,2,3)))
                   (terpri)
                 end)
                                                                                      
(3 2 1)
nil

Now that you have first class functions, you can start to implement higher level functions:

(def mapcar (fun,list)
(if (endp list)
    nil
  else
   (cons (funcall fun,(first list)),(mapcar fun,(rest list)))
  end)
end)

irb(main):271:0> (begin
                   (printlist (mapcar (lambda {|x| (x + 1)}),(list 1,2,3)))
                   (terpri)
                 end)

(2 3 4)
nil

So at least, now you can find the smallest element of a list:

This function implements an accumulator pattern: we pass the partial result
along with the parameters. We process the list item by item and when its finished
we return the result we've accumulated so far:

(def smallestElement(list,minimum)
(if (endp list)
     minimum
  elsif (minimum < (first list))
     (smallestElement (rest list),minimum)
  else
     (smallestElement (rest list),(first list))
  end)
end)

(def smallest(list)
(smallestElement (rest list),(first list))
end)

irb(main):422:0>
(begin
   (terpri)
   (printlist (mapcar (function :smallest,1),(list (list 1),
                                                   (list 1,1,1,1),
                                                   (list 1,2,3,4),
                                                   (list 4,3,2,1),
                                                   (list 1,2,3,4,3,2,1),
                                                   (list 4,3,2,1,2,3,4))))
   (terpri)
end)

(1 1 1 1 1 1)
nil

Oh, and by the way, instead of using Matzacred Lisp aka Ruby, you could
as well use directly the original, Lisp, and without dilation type away:

C/USER[7]> (defun smallest (list)
             (labels ((smallest-element (list minimum)
                        (cond
                          ((endp list) minimum)
                          ((< minimum (first list)) (smallest-element (rest list) minimum))
                          (t (smallest-element (rest list) (first list))))))
               (smallest-element (rest list) (first list))))
SMALLEST
C/USER[8]> (mapcar (function smallest) (list (list 1)
                                             (list 1 1 1 1)
                                             (list 1 2 3 4)
                                             (list 4 3 2 1)
                                             (list 1 2 3 4 3 2 1)
                                             (list 4 3 2 1 2 3 4)))
(1 1 1 1 1 1)
C/USER[9]>

( Try out http://clisp.cons.org or http://sbcl.sourceforge.net
  Have a look at gigamonkey.com - gigamonkey Resources and Information. )

Some links to this subject would be nice also.

http://www.stanford.edu/class/cs242/readings/backus.pdf

For purely functional programming you could learn Haskel, or a language
of the ML family, but Common Lisp is more useful since it's a
multi-paradigm programming language: when you reach the limits of a
given paradigm, such as OO, or functional, you always have yet another
programming paradigm available in lisp (logical, declarative, you name
it).

···

--
__Pascal Bourguignon__

I managed to find a minimum:

[1,6,4,7,8].inject {|a,b| if a < b then a else b end}

but I can't still find a way to sort list (functional way and not with
existing sort method)

Thanks

"Haris Bogdanovic" <fbogdanovic@xnet.hr> wrote in message
news:gk3m77$1ft$1@gregory.bnet.hr...

···

Hi.

I'm starting to learn functional programming with Ruby.
I would like for someone to write me an example of finding the smallest
number in the list and a sorting algorithm.
I got the concept of map (collect), filter (select, detect and reject) and
reduce (inject) higher order functions but I don't know how to compose
algorithms from them.
So please write me those two algorithms or some other simple ones with
some explanation.
Some links to this subject would be nice also.

Thanks
Haris

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 Bogdanovic" <fbogdanovic@xnet.hr> wrote in message
news:gk3m77$1ft$1@gregory.bnet.hr...

···

Hi.

I'm starting to learn functional programming with Ruby.
I would like for someone to write me an example of finding the smallest
number in the list and a sorting algorithm.
I got the concept of map (collect), filter (select, detect and reject) and
reduce (inject) higher order functions but I don't know how to compose
algorithms from them.
So please write me those two algorithms or some other simple ones with
some explanation.
Some links to this subject would be nice also.

Thanks
Haris

I know Ruby programming well but I wanted to add funtional paradigm in my
programming as it is very usefull.
If you don't know and are not interested in it you don't have to insult me.
And Haskell looks pretty useless to me because it is functional paradigm
only language.

"Phlip" <phlip2005@gmail.com> wrote in message
news:rSf9l.8378$8_3.226@flpi147.ffdc.sbc.com...

···

I'm starting to learn functional programming with Ruby.

t
Wouldn't learning OO programming in Haskel be easier?

Pascal J. Bourguignon wrote:

[...]

(def revappend(list,tail)
(if (null list)
     tail
  else
     (revappend (cdr list),(cons (car list),tail))
  end)
end)

[...]

I like how you sneaked in the parentheses. It's a clever way to get
people accustomed to parens without actually using Lisp. A way-point
on the road to enlightenment. The too-many-parens complex is at the
same time a trivial psychological barrier and a roadblock to greater
understanding of the art of programming.

There comes a time when one finds oneself weary of evaling strings.
What's needed is a language that can represent itself. To metaprogram
in the same language of the program--when the metalanguage is the
language--this is the weapon of a Lisper. Not as clumsy or random as
a string eval; an elegant weapon for a more civilized age.

···

--
Posted via http://www.ruby-forum.com/\.

In Ruby everything is an object. That's my favourite Ruby's feature. And you
showed that by just making one module you can have Lisp like functional
programming. So I'll stick with Ruby.

"Pascal J. Bourguignon" <pjb@informatimago.com> wrote in message
news:87vdspbf7i.fsf@informatimago.com...

···

"Haris Bogdanovic" <fbogdanovic@xnet.hr> writes:

I'm starting to learn functional programming with Ruby.
I would like for someone to write me an example of finding the smallest
number in the list and a sorting algorithm.
I got the concept of map (collect), filter (select, detect and reject)
and
reduce (inject) higher order functions but I don't know how to compose
algorithms from them.
So please write me those two algorithms or some other simple ones with
some
explanation.

You would have first to define the concept of list. Indeed, the other
answer may have you misled into believe that [1,2,3] was a list, but it
is not, it is an Array:

irb(main):477:0> [1,2,3].class
Array

(actually it's a vector, Ruby has no multidimentional arrays like
Fortran or Lisp, or any other serrious programming language).

So to make a list, first, the basic building block, the cons cell:

(class Cons
(attr_accessor :car)
(attr_accessor :cdr)
(def initialize(car,cdr)
   (@car = car)
   (@cdr = cdr)
end)
end)

Let's wrap this object into a functional abstraction layer:

(def cons(car,cdr)
(Cons . new(car,cdr))
end)

(def car(x)
(x . car)
end)

(def cdr(x)
(x . cdr)
end)

(def null(x)
(x . nil?)
end)

irb(main):040:0> (cons 1,2)
#<Cons:0x7fdfb53eb808 @cdr=2, @car=1>
irb(main):042:0> (car (cons 1,2))
1
irb(main):043:0> (cdr (cons 1,2))
2
irb(main):044:0> (null (cons 1,2))
false
irb(main):045:0> (null (car (cons 1,nil)))
false
irb(main):046:0> (null (cdr (cons 1,nil)))
true

Then you can build a list over these cons cells:

(def list(*args)
(i = (args . length))
(r = nil)
(loop {
    (if (i == 0)
       (break)
     else
       (i = (i - 1))
       (r = (cons (args [ i ]),r))
    end)
})
r
end)

irb(main):127:0> (list 1,2,3)
#<Cons:0x7fdfb53b81d8 @cdr=#<Cons:0x7fdfb53b8200
@cdr=#<Cons:0x7fdfb53b8228 @cdr=nil, @car=3>, @car=2>, @car=1>

Let's print them pretty:

(def printelements(cons)
(if (Cons === cons)
     (if (Cons === (car cons))
        (printlist (car cons))
       else
        (print (car cons))
     end)
     (if (Cons === (cdr cons))
        (print " ")
        (printelements (cdr cons))
      elsif (not (null (cdr cons)))
        (print " . ")
        (print (cdr cons))
     end)
else
    (print cons)
end)
end)

(def printlist(cons)
(print "(")
(printelements cons)
(print ")")
cons
end)

(def terpri()
(print "\n")
end)

irb(main):263:0> (begin
                  (terpri)
                  (printlist (list 1,2,3))
                  (terpri)
                end)

(1 2 3)
nil

You can also add some higher level abstractions:

(def first(list)
(car list)
end)

(def rest(list)
(cdr list)
end)

(def endp(list)
(if (Cons === list)
     nil
  elsif (null list)
     true
  else
     (error ("Expected a list instead of the atom " + (list . to_s)))
  end)
end)

Once you've got this list abstraction, you can build functions such as
reverse:

(def revappend(list,tail)
(if (null list)
    tail
else
    (revappend (cdr list),(cons (car list),tail))
end)
end)

(def reverse(list)
(revappend list,nil)
end)

irb(main):267:0> (begin
                  (printlist (reverse (list 1,2,3)))
                  (terpri)
                end)
(3 2 1)
nil

Now we also need the function abstraction. In ruby functions have to
be in modules, and always qualified by the module name. This is not
pretty, so we will allow any method to be treated as a function, but
we will ignore it's recipient object, always passing self.

# For methods, the first function argument is the recipient of the
# message:

(def method(designator,arity=(-1))
  # Important: the given arity must include the recipient object, but not
the recipient class:
  # (method :==,2) .call(42,42) vs. 42.==(42)
  (if (arity == -1)
     # This is the default, bugged behavior:
     (Proc . new {| x , *args | (x . send(designator , *args))})
   elsif (arity == 0)
     (raise (Exception.exception("An instance method must have an
>=1, not 0.")))
   else
     (arity = (arity - 1))
     (args = (((arity == 0)? "" : " , ") + (((1 .. arity) . map { | i |
("a" + i.to_s) }) . join(" , "))))
     (eval("(Proc . new { | x" + args + " | " +
           "( x . send( :" + (designator . to_s) + args + " ))})"))
   end)
end)

# for functions, the recipient of the message is always 'self', all
# arguments are passed as arguments.

(def function(designator,arity=(-1))
# Important: the given arity must include the recipient object, but not
the recipient class:
# (function "SOME_MODULE.someFunction",1) .call(42) vs.
SOME_MODULE.someFunction(42)
# (function :someFunction ,2) .call(42) vs.
self.someFunction(42) or someFunction(42)
(if (String === designator)
    mod , met = (designator . split("."))
    (if (arity == -1)
       # This is the default, bugged behavior:
       (Proc . new {| *args | ((eval mod) . send((met . to_sym) ,
*args))})
     else
       (args = (((1 .. arity) . map { | i | ("a" + i.to_s) }) . join(" ,
")))
       (sep = " ")
       (if (0 < arity)
          (sep = " , ")
        end)
       (eval("(Proc . new { | " + args + " | " +
             "( " + mod + " . send( :" + met + sep + args + " ))})"))
     end)
  else
    (if (arity == -1)
       # This is the default, bugged behavior:
       (Proc . new {| x , *args | (x . send(designator , *args))})
     elsif (arity == 0)
       (eval("(Proc . new {" +
             "(" + (designator . to_s) + " )})"))
     else
       (args = (((1 .. arity) . map { | i | ("a" + i.to_s) }) . join(" ,
")))
       (eval("(Proc . new { | " + args + " | " +
             "(" + (designator . to_s) + " " + args + " )})"))
     end)
  end)
end)

(def funcall(fun,*args)
(fun . call(*args))
end)

irb(main):370:0> (funcall (method :+,2),3,4)
(funcall (method :+,2),3,4)
7

irb(main):478:0> (begin
                  (terpri)
                  (printlist (funcall (function :reverse,1),(list 1,2,3)))
                  (terpri)
                end)

(3 2 1)
nil

Now that you have first class functions, you can start to implement higher
level functions:

(def mapcar (fun,list)
(if (endp list)
   nil
else
  (cons (funcall fun,(first list)),(mapcar fun,(rest list)))
end)
end)

irb(main):271:0> (begin
                  (printlist (mapcar (lambda {|x| (x + 1)}),(list 1,2,3)))
                  (terpri)
                end)

(2 3 4)
nil

So at least, now you can find the smallest element of a list:

This function implements an accumulator pattern: we pass the partial
result
along with the parameters. We process the list item by item and when its
finished
we return the result we've accumulated so far:

(def smallestElement(list,minimum)
(if (endp list)
    minimum
elsif (minimum < (first list))
    (smallestElement (rest list),minimum)
else
    (smallestElement (rest list),(first list))
end)
end)

(def smallest(list)
(smallestElement (rest list),(first list))
end)

irb(main):422:0>
(begin
  (terpri)
  (printlist (mapcar (function :smallest,1),(list (list 1),
                                                  (list 1,1,1,1),
                                                  (list 1,2,3,4),
                                                  (list 4,3,2,1),
                                                  (list 1,2,3,4,3,2,1),
                                                  (list 4,3,2,1,2,3,4))))
  (terpri)
end)

(1 1 1 1 1 1)
nil

Oh, and by the way, instead of using Matzacred Lisp aka Ruby, you could
as well use directly the original, Lisp, and without dilation type away:

C/USER[7]> (defun smallest (list)
            (labels ((smallest-element (list minimum)
                       (cond
                         ((endp list) minimum)
                         ((< minimum (first list)) (smallest-element (rest
list) minimum))
                         (t (smallest-element (rest
list) (first list))))))
              (smallest-element (rest list) (first list))))
SMALLEST
C/USER[8]> (mapcar (function smallest) (list (list 1)
                                            (list 1 1 1 1)
                                            (list 1 2 3 4)
                                            (list 4 3 2 1)
                                            (list 1 2 3 4 3 2 1)
                                            (list 4 3 2 1 2 3 4)))
(1 1 1 1 1 1)
C/USER[9]>

( Try out http://clisp.cons.org or http://sbcl.sourceforge.net
Have a look at gigamonkey.com - gigamonkey Resources and Information. )

Some links to this subject would be nice also.

http://www.stanford.edu/class/cs242/readings/backus.pdf

For purely functional programming you could learn Haskel, or a language
of the ML family, but Common Lisp is more useful since it's a
multi-paradigm programming language: when you reach the limits of a
given paradigm, such as OO, or functional, you always have yet another
programming paradigm available in lisp (logical, declarative, you name
it).

--
__Pascal Bourguignon__

"Haris Bogdanovic" <fbogdanovic@xnet.hr> writes:

I managed to find a minimum:

[1,6,4,7,8].inject {|a,b| if a < b then a else b end}

but I can't still find a way to sort list (functional way and not with
existing sort method)

One difficulty is that vectors are difficult to handle with purely
functional programming: you cannot modify them, not a single slot; when
you want to change just one slot of a vector, in purely functionnal
programming, you have to define a whole new vector, that contains the
same elements as the old vector, but for the one that is "changed".

But you asked first for lists, and I showed you how to implement lists.
So now it should be easy to implement a functionnal sort algorithm
working on lists.

For an exemple here is a simple merge sort. We need a function to merge
two lists:

(def mergelist(list1,list2,lessp)
   (if (endp list1)
      list2
    elsif (endp list2)
      list1
    elsif (funcall lessp,(first list1),(first list2))
      (cons (first list1),(mergelist (rest list1),list2,lessp))
    else
      (cons (first list2),(mergelist list1,(rest list2),lessp))
    end)
end)

irb(main):545:0>
(begin
  (terpri)
  (printlist (mergelist (list 1,3,5,7,8,9,11),(list 2,4,6,10,11,12,13),(method :<)))
  (terpri)
end)
                                                                                                         
(1 2 3 4 5 6 7 8 9 10 11 11 12 13)
nil

Then a function to split a list into two parts separated by a pivot (one
list containing all the elements smaller-or-equal to the pivot, and the
other all the elements greater than the pivot):

(def values(*values)
   values
end)

(def splitlistinternal(list,pivot,lessp,less,more)
  (if (endp list)
     (values less,more)
  elsif (funcall lessp,pivot,(first list))
     (splitlistinternal (rest list),pivot,lessp,less,(cons (first list),more))
  else
     (splitlistinternal (rest list),pivot,lessp,(cons (first list),less),more)
  end)
end)

(def splitlist(list,pivot,lessp)
  (splitlistinternal list,pivot,lessp,nil,nil)
end)

(def valuelist(values)
   (list *values)
end)

irb(main):604:0>
(begin
   (terpri)
   (printlist (valuelist (splitlist (list 1,2,3,4,5,6,7),3,(method :<))))
   (terpri)
end)
                                                                                      
((3 2 1) (7 6 5 4))
nil

With these two utilities, writting a functional merge sort is trivial:

(def sortlist(list,lessp)
   (if ((endp list) or (endp (rest list)))
      list
    else
      (pivot = (first list))
      (less,more = (splitlist (rest list),pivot,lessp))
      (mergelist (sortlist less,lessp),(cons pivot,(sortlist more,lessp)),lessp)
    end)
end)

irb(main):635:0>
(begin
   (terpri)
   (printlist (mapcar (lambda{|list|
                          (sortlist list,(method :<))
                         }),(list (list),(list 1),(list 5,4,3,2,1),(list 1,2,3,4,5),(list 1,3,5,4,2),(list 5,3,1,2,4))))
   (terpri)
end)
                                                                                                                                               
(nil (1) (1 2 3 4 5) (1 2 3 4 5) (1 2 3 4 5) (1 2 3 4 5))
nil

···

--
__Pascal Bourguignon__

Pascal J. Bourguignon wrote:

So to make a list, first, the basic building block, the cons cell:

(class Cons
(attr_accessor :car)
(attr_accessor :cdr)
(def initialize(car,cdr)
    (@car = car)
    (@cdr = cdr)
  end)
end)

Let's wrap this object into a functional abstraction layer:

(def cons(car,cdr)
(Cons . new(car,cdr))
end)

(def car(x)
(x . car)
end)

(def cdr(x)
(x . cdr)
end)

(def null(x)
(x . nil?)
end)

irb(main):040:0> (cons 1,2)
#<Cons:0x7fdfb53eb808 @cdr=2, @car=1>
irb(main):042:0> (car (cons 1,2))
1
irb(main):043:0> (cdr (cons 1,2))
2
irb(main):044:0> (null (cons 1,2))
false
irb(main):045:0> (null (car (cons 1,nil)))
false
irb(main):046:0> (null (cdr (cons 1,nil)))
true

Then you can build a list over these cons cells:

(def list(*args)
  (i = (args . length))
  (r = nil)
  (loop {
     (if (i == 0)
        (break)
      else
        (i = (i - 1))
        (r = (cons (args [ i ]),r))
     end)
  })
r
end)

irb(main):127:0> (list 1,2,3)
#<Cons:0x7fdfb53b81d8 @cdr=#<Cons:0x7fdfb53b8200
@cdr=#<Cons:0x7fdfb53b8228 @cdr=nil, @car=3>, @car=2>, @car=1>

Let's print them pretty:

(def printelements(cons)
  (if (Cons === cons)
      (if (Cons === (car cons))
         (printlist (car cons))
        else
         (print (car cons))
      end)
      (if (Cons === (cdr cons))
         (print " ")
         (printelements (cdr cons))
       elsif (not (null (cdr cons)))
         (print " . ")
         (print (cdr cons))
      end)
  else
     (print cons)
  end)
end)

(def printlist(cons)
(print "(")
(printelements cons)
(print ")")
cons
end)

(def terpri()
  (print "\n")
end)

irb(main):263:0> (begin
                   (terpri)
                   (printlist (list 1,2,3))
                   (terpri)
                 end)

(1 2 3)
nil

You can also add some higher level abstractions:

(def first(list)
  (car list)
end)

(def rest(list)
  (cdr list)
end)

(def endp(list)
  (if (Cons === list)
      nil
   elsif (null list)
      true
   else
      (error ("Expected a list instead of the atom " + (list . to_s)))
   end)
end)

Once you've got this list abstraction, you can build functions such
as reverse:

(def revappend(list,tail)
(if (null list)
     tail
  else
     (revappend (cdr list),(cons (car list),tail))
  end)
end)

(def reverse(list)
(revappend list,nil)
end)

irb(main):267:0> (begin
                   (printlist (reverse (list 1,2,3)))
                   (terpri)
                 end)
(3 2 1)
nil

Now we also need the function abstraction. In ruby functions have to
be in modules, and always qualified by the module name. This is not
pretty, so we will allow any method to be treated as a function, but
we will ignore it's recipient object, always passing self.

# For methods, the first function argument is the recipient of the
# message:

(def method(designator,arity=(-1))
   # Important: the given arity must include the recipient object,
but not the recipient class: # (method :==,2) .call(42,42) vs.
42.==(42) (if (arity == -1)
      # This is the default, bugged behavior:
      (Proc . new {| x , *args | (x . send(designator , *args))})
    elsif (arity == 0)
      (raise (Exception.exception("An instance method must have an
>=1, not 0."))) else
      (arity = (arity - 1))
      (args = (((arity == 0)? "" : " , ") + (((1 .. arity) . map { |
i | ("a" + i.to_s) }) . join(" , ")))) (eval("(Proc . new { |
x" + args + " | " + "( x . send( :" + (designator . to_s)
+ args + " ))})")) end)
end)

# for functions, the recipient of the message is always 'self', all
# arguments are passed as arguments.

(def function(designator,arity=(-1))
  # Important: the given arity must include the recipient object, but
not the recipient class: # (function "SOME_MODULE.someFunction",1)
.call(42) vs. SOME_MODULE.someFunction(42) # (function
:someFunction ,2) .call(42) vs. self.someFunction(42)
or someFunction(42) (if (String === designator) mod , met =
(designator . split(".")) (if (arity == -1)
        # This is the default, bugged behavior:
        (Proc . new {| *args | ((eval mod) . send((met . to_sym) ,
*args))}) else
        (args = (((1 .. arity) . map { | i | ("a" + i.to_s) }) .
join(" , "))) (sep = " ")
        (if (0 < arity)
           (sep = " , ")
         end)
        (eval("(Proc . new { | " + args + " | " +
              "( " + mod + " . send( :" + met + sep + args + "
))})")) end)
   else
     (if (arity == -1)
        # This is the default, bugged behavior:
        (Proc . new {| x , *args | (x . send(designator , *args))})
      elsif (arity == 0)
        (eval("(Proc . new {" +
              "(" + (designator . to_s) + " )})"))
      else
        (args = (((1 .. arity) . map { | i | ("a" + i.to_s) }) .
join(" , "))) (eval("(Proc . new { | " + args + " | " +
              "(" + (designator . to_s) + " " + args + " )})"))
      end)
   end)
end)

(def funcall(fun,*args)
  (fun . call(*args))
end)

irb(main):370:0> (funcall (method :+,2),3,4)
(funcall (method :+,2),3,4)
7

irb(main):478:0> (begin
                   (terpri)
                   (printlist (funcall (function :reverse,1),(list
1,2,3))) (terpri)
                 end)

(3 2 1)
nil

You have certainly proved that everything is 10 times as hard
as it should be when you use Commune Lisp!

Ruby:

[1,2,3].reverse
    ==>[3, 2, 1]

[1,2,3].send :reverse
    ==>[3, 2, 1]

Now that you have first class functions, you can start to implement
higher level functions:

(def mapcar (fun,list)
(if (endp list)
    nil
  else
   (cons (funcall fun,(first list)),(mapcar fun,(rest list)))
  end)
end)

irb(main):271:0> (begin
                   (printlist (mapcar (lambda {|x| (x + 1)}),(list
1,2,3))) (terpri)
                 end)

(2 3 4)
nil

Ruby:

[1,2,3].map{|x| x + 1}
    ==>[2, 3, 4]

or:

augment = proc{|x| x + 1}
    ==>#<Proc:0x0282c2cc@(irb):11>
[1,2,3].map &augment
    ==>[2, 3, 4]

So at least, now you can find the smallest element of a list:

This function implements an accumulator pattern: we pass the partial
result along with the parameters. We process the list item by item
and when its finished we return the result we've accumulated so far:

(def smallestElement(list,minimum)
(if (endp list)
     minimum
  elsif (minimum < (first list))
     (smallestElement (rest list),minimum)
  else
     (smallestElement (rest list),(first list))
  end)
end)

(def smallest(list)
(smallestElement (rest list),(first list))
end)

irb(main):422:0>
(begin
   (terpri)
   (printlist (mapcar (function :smallest,1),(list (list 1),
                                                   (list 1,1,1,1),
                                                   (list 1,2,3,4),
                                                   (list 4,3,2,1),
                                                   (list
1,2,3,4,3,2,1),
(list 4,3,2,1,2,3,4)))) (terpri)
end)

(1 1 1 1 1 1)
nil

Ruby:

[[1],[1,1,1,1],[1,2,3,4],[4,3,2,1],[1,2,3,4,3,2,1],[4,3,2,1,2,3,4]].
map{|a| a.min}
    ==>[1, 1, 1, 1, 1, 1]

Yes, COBOL Lisp is an ancient, cumbersome, and clunky language.
Ruby is to it as a transistor is to a vacuum tube.

"Haris Bogdanovic" <fbogdanovic@xnet.hr> 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)

···

--
__Pascal Bourguignon__

Haris Bogdanovic wrote:

I know Ruby programming well but I wanted to add funtional paradigm in
my
programming as it is very usefull.

If you know Ruby well - and you obviously understand functional
programming, because you know it is "usefull" (sic) - then just start
writing functional programs. To do this, make sure that:

1. you don't modify any objects. Only use methods which return new
objects.

2. once a local variable is assigned, you don't reassign it.

However Ruby won't enforce (1) unless you litter your code with 'freeze'
statements, and it can't enforce (2) at all.

a = "hello"
a << " world" # wrong: modifies the string
a += " world" # wrong: new string, but assigned to same variable
b = a + " world" # right

# Example: convert all hash keys to strings
src = {:one=>1, :two=>2}

# Imperative
out = src.inject({}) { |h,(k,v)| h[k.to_s] = v; h }

# Functional
out = src.inject({}) { |h,(k,v)| h.merge(k.to_s => v) }

If you don't know and are not interested in it you don't have to insult
me.
And Haskell looks pretty useless to me because it is functional paradigm
only language.

Who's being insulting now? What are you saying about all Haskell
programmers, and all the language designers? Do you genuinely believe
that useful systems cannot be written in Haskell?

Go and look at Erlang. Massive real-world systems are built out of this,
with incredible reliability, using only functional programming and CSP.
It's also very straightforward to pick up and use, and has a very
comprehensive standard library.

Remember also that functional languages allow all sorts of compile-time
optimisations which are impossible in Ruby, so there is the potential
for much higher performance. For example, OCaml generates code which is
reputedly only half the speed of the equivalent C code.

···

--
Posted via http://www.ruby-forum.com/\.

"Haris Bogdanovic" <fbogdanovic@xnet.hr> writes:

In Ruby everything is an object. That's my favourite Ruby's feature. And you
showed that by just making one module you can have Lisp like functional
programming. So I'll stick with Ruby.

In Lisp too, everything is an object. But there are several kinds of
objects, and you can create your own kinds too (you can write new
meta-classes in CLOS).

C/USER[15]> (defclass automobile () ())
#1=#<STANDARD-CLASS AUTOMOBILE>
C/USER[16]> (defvar *car* (make-instance 'automobile))
*CAR*
C/USER[17]> (class-of *car*)
#1=#<STANDARD-CLASS AUTOMOBILE>
C/USER[18]> (class-of 1)
#1=#<BUILT-IN-CLASS INTEGER>
C/USER[19]> (class-of "string")
#1=#<BUILT-IN-CLASS STRING>
C/USER[20]> (defstruct wheel)
WHEEL
C/USER[21]> (defclass automobile () ((wheels :accessor wheels :initform (list (make-wheel) (make-wheel) (make-wheel) (make-wheel)))))
WARNING: DEFCLASS: Class AUTOMOBILE (or one of its ancestors) is being redefined, instances are obsolete
#1=#<STANDARD-CLASS AUTOMOBILE :VERSION 1>
C/USER[22]> (wheels *car*)
(#S(WHEEL) #S(WHEEL) #S(WHEEL) #S(WHEEL))
C/USER[23]> (class-of (wheels *car*))
#1=#<BUILT-IN-CLASS CONS>
C/USER[24]> (class-of (first (wheels *car*)))
#1=#<STRUCTURE-CLASS WHEEL>
C/USER[25]>

···

--
__Pascal Bourguignon__

Very interesting discussion, I love ruby and I love also haskell,
which I think made me a better programmer.

But does it really make sense to program in a functional way in ruby??

"Functional" code can be much more clean and elegant (in my opinion)
but what about performance issues???

The interpreter is going to have many new objects created around, and
so there will be more work for the garbage collector or more memory
used, am I wrong?

I would like if this sort could be made of Ruby functions; inject,select,
detect, reject, collect, not with "module" you implemented. And it doesnt't
have to be a list sorting; can be an array sorting or something. I'm not an
expert in knowing all differences between all kinds of collections.
And what about recursion ? If I want to sort an array do I have to use
recursion and how ?
There are tutorials on functional programming in general but not with Ruby.
Does anybody maybe has some link to something similar ?

"Pascal J. Bourguignon" <pjb@informatimago.com> wrote in message
news:87d4ewbrgz.fsf@informatimago.com...

···

"Haris Bogdanovic" <fbogdanovic@xnet.hr> writes:

I managed to find a minimum:

[1,6,4,7,8].inject {|a,b| if a < b then a else b end}

but I can't still find a way to sort list (functional way and not with
existing sort method)

One difficulty is that vectors are difficult to handle with purely
functional programming: you cannot modify them, not a single slot; when
you want to change just one slot of a vector, in purely functionnal
programming, you have to define a whole new vector, that contains the
same elements as the old vector, but for the one that is "changed".

But you asked first for lists, and I showed you how to implement lists.
So now it should be easy to implement a functionnal sort algorithm
working on lists.

For an exemple here is a simple merge sort. We need a function to merge
two lists:

(def mergelist(list1,list2,lessp)
  (if (endp list1)
     list2
   elsif (endp list2)
     list1
   elsif (funcall lessp,(first list1),(first list2))
     (cons (first list1),(mergelist (rest list1),list2,lessp))
   else
     (cons (first list2),(mergelist list1,(rest list2),lessp))
   end)
end)

irb(main):545:0>
(begin
(terpri)
(printlist (mergelist (list 1,3,5,7,8,9,11),(list
2,4,6,10,11,12,13),(method :<)))
(terpri)
end)

(1 2 3 4 5 6 7 8 9 10 11 11 12 13)
nil

Then a function to split a list into two parts separated by a pivot (one
list containing all the elements smaller-or-equal to the pivot, and the
other all the elements greater than the pivot):

(def values(*values)
  values
end)

(def splitlistinternal(list,pivot,lessp,less,more)
(if (endp list)
    (values less,more)
elsif (funcall lessp,pivot,(first list))
    (splitlistinternal (rest list),pivot,lessp,less,(cons (first
list),more))
else
    (splitlistinternal (rest list),pivot,lessp,(cons (first
list),less),more)
end)
end)

(def splitlist(list,pivot,lessp)
(splitlistinternal list,pivot,lessp,nil,nil)
end)

(def valuelist(values)
  (list *values)
end)

irb(main):604:0>
(begin
  (terpri)
  (printlist (valuelist (splitlist (list 1,2,3,4,5,6,7),3,(method :<))))
  (terpri)
end)

((3 2 1) (7 6 5 4))
nil

With these two utilities, writting a functional merge sort is trivial:

(def sortlist(list,lessp)
  (if ((endp list) or (endp (rest list)))
     list
   else
     (pivot = (first list))
     (less,more = (splitlist (rest list),pivot,lessp))
     (mergelist (sortlist less,lessp),(cons pivot,(sortlist
more,lessp)),lessp)
   end)
end)

irb(main):635:0>
(begin
  (terpri)
  (printlist (mapcar (lambda{|list|
                         (sortlist list,(method :<))
                        }),(list (list),(list 1),(list 5,4,3,2,1),(list
1,2,3,4,5),(list 1,3,5,4,2),(list 5,3,1,2,4))))
  (terpri)
end)

(nil (1) (1 2 3 4 5) (1 2 3 4 5) (1 2 3 4 5) (1 2 3 4 5))
nil

--
__Pascal Bourguignon__

Mike Gold wrote:

It's a clever way to get
people accustomed to parens without actually using Lisp. A way-point
on the road to enlightenment.

There you have it. Hierophants of Commune Lisp are utter irrational.
It's a religion to them. In comp.lang.lisp you will find threads
named "How did you discover Lisp?", i.e., "How did you get religion?"

"William James" <w_a_x_man@yahoo.com> writes:

Pascal J. Bourguignon wrote:

So to make a list, first, the basic building block, the cons cell:

(class Cons
(attr_accessor :car)
(attr_accessor :cdr)
(def initialize(car,cdr)
    (@car = car)
    (@cdr = cdr)
  end)
end)

Let's wrap this object into a functional abstraction layer:

(def cons(car,cdr)
(Cons . new(car,cdr))
end)

(def car(x)
(x . car)
end)

(def cdr(x)
(x . cdr)
end)

(def null(x)
(x . nil?)
end)

irb(main):040:0> (cons 1,2)
#<Cons:0x7fdfb53eb808 @cdr=2, @car=1>
irb(main):042:0> (car (cons 1,2))
1
irb(main):043:0> (cdr (cons 1,2))
2
irb(main):044:0> (null (cons 1,2))
false
irb(main):045:0> (null (car (cons 1,nil)))
false
irb(main):046:0> (null (cdr (cons 1,nil)))
true

Then you can build a list over these cons cells:

(def list(*args)
  (i = (args . length))
  (r = nil)
  (loop {
     (if (i == 0)
        (break)
      else
        (i = (i - 1))
        (r = (cons (args [ i ]),r))
     end)
  })
r
end)

irb(main):127:0> (list 1,2,3)
#<Cons:0x7fdfb53b81d8 @cdr=#<Cons:0x7fdfb53b8200
@cdr=#<Cons:0x7fdfb53b8228 @cdr=nil, @car=3>, @car=2>, @car=1>

Let's print them pretty:

(def printelements(cons)
  (if (Cons === cons)
      (if (Cons === (car cons))
         (printlist (car cons))
        else
         (print (car cons))
      end)
      (if (Cons === (cdr cons))
         (print " ")
         (printelements (cdr cons))
       elsif (not (null (cdr cons)))
         (print " . ")
         (print (cdr cons))
      end)
  else
     (print cons)
  end)
end)

(def printlist(cons)
(print "(")
(printelements cons)
(print ")")
cons
end)

(def terpri()
  (print "\n")
end)

irb(main):263:0> (begin
                   (terpri)
                   (printlist (list 1,2,3))
                   (terpri)
                 end)

(1 2 3)
nil

You can also add some higher level abstractions:

(def first(list)
  (car list)
end)

(def rest(list)
  (cdr list)
end)

(def endp(list)
  (if (Cons === list)
      nil
   elsif (null list)
      true
   else
      (error ("Expected a list instead of the atom " + (list . to_s)))
   end)
end)

Once you've got this list abstraction, you can build functions such
as reverse:

(def revappend(list,tail)
(if (null list)
     tail
  else
     (revappend (cdr list),(cons (car list),tail))
  end)
end)

(def reverse(list)
(revappend list,nil)
end)

irb(main):267:0> (begin
                   (printlist (reverse (list 1,2,3)))
                   (terpri)
                 end)
(3 2 1)
nil

Now we also need the function abstraction. In ruby functions have to
be in modules, and always qualified by the module name. This is not
pretty, so we will allow any method to be treated as a function, but
we will ignore it's recipient object, always passing self.

# For methods, the first function argument is the recipient of the
# message:

(def method(designator,arity=(-1))
   # Important: the given arity must include the recipient object,
but not the recipient class: # (method :==,2) .call(42,42) vs.
42.==(42) (if (arity == -1)
      # This is the default, bugged behavior:
      (Proc . new {| x , *args | (x . send(designator , *args))})
    elsif (arity == 0)
      (raise (Exception.exception("An instance method must have an
>=1, not 0."))) else
      (arity = (arity - 1))
      (args = (((arity == 0)? "" : " , ") + (((1 .. arity) . map { |
i | ("a" + i.to_s) }) . join(" , ")))) (eval("(Proc . new { |
x" + args + " | " + "( x . send( :" + (designator . to_s)
+ args + " ))})")) end)
end)

# for functions, the recipient of the message is always 'self', all
# arguments are passed as arguments.

(def function(designator,arity=(-1))
  # Important: the given arity must include the recipient object, but
not the recipient class: # (function "SOME_MODULE.someFunction",1)
.call(42) vs. SOME_MODULE.someFunction(42) # (function
:someFunction ,2) .call(42) vs. self.someFunction(42)
or someFunction(42) (if (String === designator) mod , met =
(designator . split(".")) (if (arity == -1)
        # This is the default, bugged behavior:
        (Proc . new {| *args | ((eval mod) . send((met . to_sym) ,
*args))}) else
        (args = (((1 .. arity) . map { | i | ("a" + i.to_s) }) .
join(" , "))) (sep = " ")
        (if (0 < arity)
           (sep = " , ")
         end)
        (eval("(Proc . new { | " + args + " | " +
              "( " + mod + " . send( :" + met + sep + args + "
))})")) end)
   else
     (if (arity == -1)
        # This is the default, bugged behavior:
        (Proc . new {| x , *args | (x . send(designator , *args))})
      elsif (arity == 0)
        (eval("(Proc . new {" +
              "(" + (designator . to_s) + " )})"))
      else
        (args = (((1 .. arity) . map { | i | ("a" + i.to_s) }) .
join(" , "))) (eval("(Proc . new { | " + args + " | " +
              "(" + (designator . to_s) + " " + args + " )})"))
      end)
   end)
end)

(def funcall(fun,*args)
  (fun . call(*args))
end)

irb(main):370:0> (funcall (method :+,2),3,4)
(funcall (method :+,2),3,4)
7

irb(main):478:0> (begin
                   (terpri)
                   (printlist (funcall (function :reverse,1),(list
1,2,3))) (terpri)
                 end)

(3 2 1)
nil

You have certainly proved that everything is 10 times as hard
as it should be when you use Commune Lisp!

Ruby:

[1,2,3].reverse
    ==>[3, 2, 1]

[1,2,3].send :reverse
    ==>[3, 2, 1]

Now that you have first class functions, you can start to implement
higher level functions:

(def mapcar (fun,list)
(if (endp list)
    nil
  else
   (cons (funcall fun,(first list)),(mapcar fun,(rest list)))
  end)
end)

irb(main):271:0> (begin
                   (printlist (mapcar (lambda {|x| (x + 1)}),(list
1,2,3))) (terpri)
                 end)

(2 3 4)
nil

Ruby:

[1,2,3].map{|x| x + 1}
    ==>[2, 3, 4]

or:

augment = proc{|x| x + 1}
    ==>#<Proc:0x0282c2cc@(irb):11>
[1,2,3].map &augment
    ==>[2, 3, 4]

So at least, now you can find the smallest element of a list:

This function implements an accumulator pattern: we pass the partial
result along with the parameters. We process the list item by item
and when its finished we return the result we've accumulated so far:

(def smallestElement(list,minimum)
(if (endp list)
     minimum
  elsif (minimum < (first list))
     (smallestElement (rest list),minimum)
  else
     (smallestElement (rest list),(first list))
  end)
end)

(def smallest(list)
(smallestElement (rest list),(first list))
end)

irb(main):422:0>
(begin
   (terpri)
   (printlist (mapcar (function :smallest,1),(list (list 1),
                                                   (list 1,1,1,1),
                                                   (list 1,2,3,4),
                                                   (list 4,3,2,1),
                                                   (list
1,2,3,4,3,2,1),
(list 4,3,2,1,2,3,4)))) (terpri)
end)

(1 1 1 1 1 1)
nil

Ruby:

No, you're wrong. All the above code IS RUBY!

[[1],[1,1,1,1],[1,2,3,4],[4,3,2,1],[1,2,3,4,3,2,1],[4,3,2,1,2,3,4]].
map{|a| a.min}
    ==>[1, 1, 1, 1, 1, 1]

Yes, COBOL Lisp is an ancient, cumbersome, and clunky language.
Ruby is to it as a transistor is to a vacuum tube.

Wrong, the above code wasn't Lisp, it was Matzacred Lisp, aka Ruby.

Ruby is to a vacuum tube what debris of glass and tungsten filaments
are.

···

--
__Pascal Bourguignon__

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

···

--
Posted via http://www.ruby-forum.com/\.