From: William James
Subject: Alternatives 3
Date: 
Message-ID: <70296ad2-8d54-488a-a0a4-aa1030912d2a@n1g2000prb.googlegroups.com>
Can Ruby tackle the challenge of Paul Graham's
On Lisp?


=begin

4.1 Birth of a Utility

What we really want here is a utility which combines find-if and
some, returning both the successful element, and the value
returned by the test function. Such a utility could be defined
as:

	(defun find2 (fn lst)
    (if (null lst)
        nil
      (let ((val (funcall fn (car lst))))
        (if val
          (values (car lst) val)
          (find2 fn (cdr lst))))))

=end

def find2 list, &block
  list.each{|x|  val = block.call( x )
    return [ x, val ]  if val }
  nil
end



=begin

4.3 Operations on Lists


(defun filter (fn lst)
  (let ((acc nil))
    (dolist (x lst)
      (let ((val (funcall fn x)))
	(if val (push val acc))))
    (nreverse acc)))

> (filter #'(lambda (x) (if (numberp x) (1+ x)))
'(a 1 2 b 3 c d 4))
(2 3 4 5)

=end

def filter list
  acc = []
  list.each{|x|
    val = yield( x )
    acc << val  if val }
  acc
end

p filter([:a,1,2,:b,3,:c,:d,4]){|x|
  x.is_a?(Numeric)  and  x + 1 }


=begin

(defun group (source n)
  (if (zerop n) (error "zero length"))
  (labels ((rec (source acc)
		(let ((rest (nthcdr n source)))
		  (if (consp rest)
		      (rec rest (cons (subseq source 0 n) acc))
		    (nreverse (cons source acc))))))
    (if source (rec source nil) nil)))

> (group '(a b c d e f g) 2)
((A B) (C D) (E F) (G))

=end

def group source, n
  acc = []
  0.step(source.size - 1, n){|i|
    acc << source[i,n] }
  acc
end

p group( %w(a b c d e f g), 2)



=begin

(defun flatten (x)
  (labels ((rec (x acc)
		(cond ((null x) acc)
		      ((atom x) (cons x acc))
		      (t (rec (car x) (rec (cdr x) acc))))))
    (rec x nil)))

> (flatten '(a (b c) ((d e) f)))
(A B C D E F)

=end

def flatten x, acc=[]
  return acc  if x.empty?
  flatten( x[1..-1], acc +
    (x.first.is_a?( Array ) ?
      flatten( x.first ) : [ x.first ] ))
end

p flatten( [:a, [:b, :c], [[:d, :e], :f]] )


=begin

(defun prune (test tree)
  (labels ((rec (tree acc)
		(cond ((null tree) (nreverse acc))
		      ((consp (car tree))
		       (rec (cdr tree)
			    (cons (rec (car tree) nil) acc)))
		      (t (rec (cdr tree)
			      (if (funcall test (car tree))
				  acc
				(cons (car tree) acc)))))))
    (rec tree nil)))

> (prune #'evenp '(1 2 (3 (4 5) 6) 7 8 (9)))
(1 (3 (5)) 7 (9))

=end


def prune x, acc=[], &block
  return acc  if x.empty?
  prune( x[1..-1], acc +
    (x.first.is_a?( Array ) ?
      [prune( x.first, [], &block )] :
      (block.call(x.first) ? [] : [x.first]) ), &block )
end
p prune([1,2,[3,[4,5],6],7,8,[9]]){|x| 0==x % 2}

From: Alex Mizrahi
Subject: Re: Alternatives 3
Date: 
Message-ID: <49118d47$0$90269$14726298@news.sunsite.dk>
 WJ> Can Ruby tackle the challenge of Paul Graham's
 WJ> On Lisp?

well, bro, that's not even interesting -- those are simple examples
of recursive functions and closure stuff.. i guess almost any language
that has anonymous functions (and many have them -- Python, JavaScript)
will handle them more-or-less well,
and if it has some syntatic sugar and library functionality, it could
be even simplier than Graham's code. but that doesn't show anything..
if you want to compete in denseness, try competing with Arc.

so this closure stuff is what common is between Ruby and Lisp.
and macros (and lack of thereof) is what different is. if you want
to understand the difference, go further into On Lisp in macros
section. 
From: Stefan Nobis
Subject: Re: Alternatives 3
Date: 
Message-ID: <m1y6zym19p.fsf@familie-nobis.de>
"Alex Mizrahi" <········@users.sourceforge.net> writes:

> well, bro, that's not even interesting

BTW: He cheats. I had only a quick look, but at least one of his
examples (IIRC group) has quite different (read: worse) performace
characteristics (IIRC O(n^2) instead of O(n)). No wonder he likes his
cute short solutions -- if Lispers were such ignorant of simple
algorithms, our code would be much shorter, too. But I think, if you
use Ruby you already did give up on performace... :)

-- 
Stefan.
From: Ariel Badichi
Subject: Re: Alternatives 3
Date: 
Message-ID: <3c854cee-f81b-4c8f-b79a-d8d08f716d67@c2g2000pra.googlegroups.com>
On Nov 5, 6:06 am, William James <·········@yahoo.com> wrote:

> def find2 list, &block
>   list.each{|x|  val = block.call( x )
>     return [ x, val ]  if val }
>   nil
> end
>

This looks nicer:

(defun find2 (fn list)
  (loop for x in list
        for val = (funcall fn x)
        when val return (values x val)))

> def filter list
>   acc = []
>   list.each{|x|
>     val = yield( x )
>     acc << val  if val }
>   acc
> end

This looks nicer:

(defun filter (fn list)
  (loop for x in list when (funcall fn x) collect it))

> def group source, n
>   acc = []
>   0.step(source.size - 1, n){|i|
>     acc << source[i,n] }
>   acc
> end

This looks nicer:

(defun group (source n)
  (loop with length = (length source)
        for i from 0 below length by n
        collect (subseq source i (min (+ i n) length))))

> def flatten x, acc=[]
>   return acc  if x.empty?
>   flatten( x[1..-1], acc +
>     (x.first.is_a?( Array ) ?
>       flatten( x.first ) : [ x.first ] ))
> end

This looks nicer:

(defun flatten (xs)
  (loop for x in xs
        if (listp x) nconc (flatten x)
        else collect x))

> def prune x, acc=[], &block
>   return acc  if x.empty?
>   prune( x[1..-1], acc +
>     (x.first.is_a?( Array ) ?
>       [prune( x.first, [], &block )] :
>       (block.call(x.first) ? [] : [x.first]) ), &block )
> end

This looks nicer:

(defun prune (test tree)
  (loop for x in tree
        if (consp x) collect (prune test x)
        else unless (funcall test x) collect x))

Caveat emptor: I didn't really test these functions - they may be
buggy.

Paul Graham's snippets, as well as your Ruby ones, are written in a
rather
low-level style.  My snippets show that Common Lisp supports a higher-
level
style.  Can you show how Ruby might support such a style?

Ariel
From: Dimiter "malkia" Stanev
Subject: Re: Alternatives 3
Date: 
Message-ID: <get9o5$98i$1@registered.motzarella.org>
> ...low-level style.  My snippets show that Common Lisp supports a higher-
> level
> style.  Can you show how Ruby might support such a style?
> 

Something on Rails, ttttRrrrr...uby.... Choo Chooo!
From: Kaz Kylheku
Subject: Re: Alternatives 3
Date: 
Message-ID: <20081105131240.543@gmail.com>
On 2008-11-05, William James <·········@yahoo.com> wrote:
> Can Ruby tackle the challenge of Paul Graham's
> On Lisp?

Could William James feel good about himself if the answer happened to be no?