Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Lisp on Lines

5 views
Skip to first unread message

luke

unread,
Jul 23, 2005, 11:11:28 PM7/23/05
to
Read on the comp.lang.lisp group that someone is developing 'Lisp on Lines'

http://groups.google.co.nz/groups?q=%22lisp+on+lines%22&hl=en

I've always admired Lisp from afar. I wonder what it could do for a web
framework?

Luke


Ara.T.Howard

unread,
Jul 24, 2005, 11:31:04 AM7/24/05
to

http://www.paulgraham.com/articles.html

specifically:

http://www.paulgraham.com/avg.html
http://lib.store.yahoo.com/lib/paulgraham/bbnexcerpts.txt

cheers.

-a
--
===============================================================================
| email :: ara [dot] t [dot] howard [at] noaa [dot] gov
| phone :: 303.497.6469
| My religion is very simple. My religion is kindness.
| --Tenzin Gyatso
===============================================================================

luke

unread,
Jul 24, 2005, 5:07:14 PM7/24/05
to
Yes, I've read Paul Graham's book "Hackers and Painters", which is what
inspired me to think programming could be for me in first place.

William James

unread,
Jul 24, 2005, 6:19:15 PM7/24/05
to
How much less powerful than Lisp is Ruby?

Joe Cheng

unread,
Jul 25, 2005, 1:22:39 PM7/25/05
to
I've only had passing experience with Lisp but the macro facility seems
incredibly powerful and useful, especially for defining mini-languages.
Also functions are real first-class constructs in Lisp and not in Ruby,
afaict. I'm sure there's other stuff but those are the features I envy
from Lisp.

Now, how much less readable than Ruby is Lisp? ;)

zak.w...@gmail.com

unread,
Jul 25, 2005, 5:38:37 PM7/25/05
to
This looks like first class functions to me:

def accgen (n)
lambda {|i| n += i }
end

foo = accgen(5)
foo.call(5) # returns 10
foo.call(5) # returns 15

accgen function borrowed from http://www.paulgraham.com/accgen.html

Lisp macros are the main area in which Lisp has more power than Ruby,
and are closely related to Lisp's syntax (or non-syntax). Macros allow
for new language constructs much like OOP allows for new types, for
example, if Common Lisp didn't have unless, you could add it like this:

(defmacro unless (test &rest forms)
`(if ,test 'nil
,@forms))

Joe Cheng

unread,
Jul 25, 2005, 6:25:39 PM7/25/05
to
Perhaps I'm misunderstanding here, please bear with me. Ruby doesn't
have the ability to do this:

a = "test".length
a() => 4

Instead, you have to do this:

a = lambda {"test".length}
a.call()

To me it seems that the closure is first-class but the actual
function/method is not. You cannot pass non-anonymous functions as
arguments, you cannot assign them to variables, you cannot compare them
for equality, as you can in Lisp (and many other functional languages). No?

Dave Fayram

unread,
Jul 25, 2005, 6:45:13 PM7/25/05
to
On 7/24/05, William James <w_a_...@yahoo.com> wrote:
> How much less powerful than Lisp is Ruby?
>


Lisp has many more features, in fact the entire language could be
viewed as a feature expression system.

That doesn't mean that Ruby is at a huge disadvantage. Ruby has most
of the important parts of lisp. It does lack macos, but very few
languages have the uniform syntax necessary to make macros as easy and
natural as they are in Lisp. Ruby has higher order functions (albeit
with a keyword massage sometimes), lambdas, closures, garbage
collection, and OO.

Some people would argue that Lisp's Object system, CLOS, is more
powerful than Ruby's because it supports multiple dispatch, and it may
be true that some things express themselves more gracefully in CLOS,
but Ruby's method has a lot of strengths too. Ruby also has a very
strong advantage in the meta-object-programming department. While CL
does have a standard for this, called "the MOP," implementation is
spotty and often subtle details cause incompatibility across Lisp
interpreters, and the MOP itself is often poorly understood even on
comp.lang.lisp.

Actually, that's kind of the story of modern Lisp. "Subtle details
cause incompatibility across Lisp interpreters." It's sad to see such
a fine language ritualistically beat and abuse itself, but its
community insists on a perpetual fork. This fork doesn't just extend
between open source and commerical lisps, which might be
understandable, but also among several open source inheritors, none of
which really could constitute a universal distribution.

--
--
Dave Fayram (II)
dfa...@lensmen.net
dfa...@gmail.com


Kirk Haines

unread,
Jul 25, 2005, 6:55:02 PM7/25/05
to
On Monday 25 July 2005 4:25 pm, Joe Cheng wrote:
> Perhaps I'm misunderstanding here, please bear with me. Ruby doesn't
> have the ability to do this:
>
> a = "test".length
> a() => 4
>
> Instead, you have to do this:
>
> a = lambda {"test".length}
> a.call()
>
a = "test".method(:length)
a.call
=> 4


Kirk Haines


zak.w...@gmail.com

unread,
Jul 25, 2005, 7:10:48 PM7/25/05
to
Joe Cheng wrote:
> Perhaps I'm misunderstanding here, please bear with me. Ruby doesn't
> have the ability to do this:
>
> a = "test".length
> a() => 4
> Instead, you have to do this:
>
> a = lambda {"test".length}
> a.call()

It's the same in Lisp. In your first example, "test".length gets
evaluated, and that value is assigned to a:

Ruby:
a = "test".length
a.class #Fixnum
a #4

a = lambda {"test".length}

a.class #Proc
a.call() #4

Lisp:
(setf a (length "test"))
(a) ;error
(type-of a) ;(INTEGER 4 4)
a ;4

(setf a (lambda () (length "test")))
(type-of a) ;EVAL:INTERPRETED-FUNCTION
(funcall a) ;4

luke

unread,
Jul 25, 2005, 8:52:46 PM7/25/05
to

Thanks Dave for the interesting post. Would these problems be solved if
Common Lisp went open source?

I noticed a post on a site

http://lemonodor.com/archives/000671.html

that suggests there are some promising dialects of Lisp that are open
source, but currently aren't as rich as, say Common Lisp.

When choosing a new and flexible language, one of the deciding factors for
me choosing Ruby was the fact it was open source.


"Dave Fayram" <dfa...@gmail.com> wrote in message
news:6fb0069505072...@mail.gmail.com...

zak.w...@gmail.com

unread,
Jul 25, 2005, 9:07:20 PM7/25/05
to
Common Lisp is an open standard. There are implementations of it that
are proprietary, and implementations that are open source. Clisp, CMUCL
and SBCL are popular open source implementations; Allegro CL and
LispWorks are popular proprietary implementations, and a number of
others exist. Problems arise where the standard isn't quite specific
enough, but these are usually fairly trivial; Common Lisp offers reader
macros to conditionally read code depending on which implementation is
in use.

Daniel Brockman

unread,
Jul 25, 2005, 9:58:36 PM7/25/05
to
Devin Mullins <twi...@comcast.net> writes:

> 1. class Foo; def thing; nil end end
> 2. f = Foo.new; f.thing #=> nil
> 3. m = f.method :thing; m.call #=> nil
> 4. class Foo; def thing; 5 end end
> 5. f.thing #=> 5
> 6. m.call #=> nil
>
> Heh, it seems that Ruby really does have first class
> functions. ;) (Why is this happening, btw? Does this have
> something to do with continuations?)

No... nothing to do with continuations. It's quite simple:
On line 3, a reference to the method body that was defined
on line 1 is stored in the method object bound to ‘m’; the
fact that the Foo#thing method is subsequently replaced on
line 4 does not affect the method object, which still has
its reference to the old method body.

--
Daniel Brockman <dan...@brockman.se>

So really, we all have to ask ourselves:
Am I waiting for RMS to do this? --TTN.

Mark J. Reed

unread,
Jul 25, 2005, 10:46:43 PM7/25/05
to
"luke" <ldun...@eml.nope> writes:
>Thanks Dave for the interesting post. Would these problems be solved if
>Common Lisp went open source?

>I noticed a post on a site

>http://lemonodor.com/archives/000671.html

>that suggests there are some promising dialects of Lisp that are open
>source, but currently aren't as rich as, say Common Lisp.

Huh? Is GNU Common Lisp not actually an implementation of Common Lisp?
GCL is not only open source, it's Free Software(TM) in the
Richard Stallman-approved sense.

Joe Cheng

unread,
Jul 25, 2005, 10:48:58 PM7/25/05
to
zak.w...@gmail.com wrote:

>It's the same in Lisp. In your first example, "test".length gets
>evaluated, and that value is assigned to a:
>
>Ruby:
>a = "test".length
>a.class #Fixnum
>a #4
>
>a = lambda {"test".length}
>a.class #Proc
>a.call() #4
>
>Lisp:
>(setf a (length "test"))
>(a) ;error
>(type-of a) ;(INTEGER 4 4)
>a ;4
>
>(setf a (lambda () (length "test")))
>(type-of a) ;EVAL:INTERPRETED-FUNCTION
>(funcall a) ;4
>
>

Sorry, please bear with me... the Lisp I had in mind was more like:

(setf a #'length)
(funcall a "foo")

(Hard to make an exact parallel because Ruby has methods not functions,
and Lisp AFAIK has functions not methods...?)

Setting a variable to the function itself seems pretty different than
wrapping a call to the function in a lambda, but honestly, now I can't
think of what the actual implications would be... other than a little
bit of additional terseness in calls like

(reduce #'+ '(1 2 3))
vs.
[1, 2, 3].inject {|a,b|a+b}

Are they really, for all intents and purposes, the same?


Devin Mullins

unread,
Jul 25, 2005, 9:48:08 PM7/25/05
to
zak.w...@gmail.com wrote:

>This looks like first class functions to me:
>
>def accgen (n)
> lambda {|i| n += i }
>end
>
>foo = accgen(5)
>foo.call(5) # returns 10
>foo.call(5) # returns 15
>
>accgen function borrowed from http://www.paulgraham.com/accgen.html
>
>

Perhaps we need a new term. According to Google, "First class
hooberglobbers" seems to mean hooberglobbers can be assigned to
variables, parameters, and return values, and then, though the assignee,
can be manipulated in all the ways that hooberglobbers can be
manipulated. Under this definition, yes, Ruby has first class functions.

I have a stricter definition. Let's call it "patrician hooberglobbers."
Patrician hooberglobbers, to me, have the additional quality that the
syntax for manipulating a hooberglobber is the same whether it is
referred to statically or by evaluation/substitution (as through a
variable, or return value of a function call). In this sense, Ruby has
patrician classes:

a = String.new
b = String
c = b.new

However, while Lisp, Python (from the examples I've seen), and Unlambda
have patrician functions, Ruby does not. I can think of two simple
enough reasons for this:

1. Because Ruby has a "poetry mode," there is no way to refer to a
function by reference -- simply referring to it invokes it. The closest
you can get is to refer to the Symbol representing its name, or to
create a Method object, which really just wraps an invocation of the
method inside a class.

This could be "fixed" by creating a syntax to "thunk" function names,
and to later apply them. So that, given some function 'foo', you could say:

foo "hello"; ^foo("hello"); a = ^foo; a("hello");

But then ^ is just syntactic sugar for self.method, and () sugar for
Method#call. This doesn't escape the fact that a can't be treated the
same as foo.

2. Actually, when I was writing reason #2, I wrote some example code to
show that a method is just a way for an object to receive messages in
Ruby, but got a surprising result, so there is no #2. Here's the code,
though:

class Foo; def thing; nil end end

f = Foo.new; f.thing #=> nil

m = f.method :thing; m.call #=> nil

class Foo; def thing; 5 end end

f.thing #=> 5
m.call #=> nil

Heh, it seems that Ruby really does have first class functions. ;) (Why
is this happening, btw? Does this have something to do with continuations?)

Now, does a language need patrician functions? I dunno, I seem to be
enjoying Ruby, and my opinion is pretty much all anybody needs to
concern themselves with.

Devin

Ara.T.Howard

unread,
Jul 25, 2005, 11:17:02 PM7/25/05
to

harp:~ > irb
irb(main):001:0> a = lambda{ p 42 }
=> #<Proc:0xb755d848@(irb):1>

irb(main):002:0> a ()
42
=> nil

irb(main):003:0> a()
42
=> nil

irb(main):004:0> b = a
=> #<Proc:0xb755d848@(irb):1>
irb(main):005:0> b()
42
=> nil

harp:~ > ruby -v
ruby 1.9.0 (2005-05-16) [i686-linux]

harp:~ > irb -v
irb 0.9.5(05/04/13)


getting pretty close...

zak.w...@gmail.com

unread,
Jul 26, 2005, 12:39:15 AM7/26/05
to
Devin Mullins wrote:

> class Foo; def thing; nil end end
> f = Foo.new; f.thing #=> nil
> m = f.method :thing; m.call #=> nil
> class Foo; def thing; 5 end end
> f.thing #=> 5
> m.call #=> nil

I think what's going on here is that it's making a copy of the method
instead of just pointing a variable at it. Lisp does the same thing:

(defun foo () 'nil)
(foo) ;nil
(setf bar #'foo)
(funcall bar) ;nil
(defun foo () 5)
(foo) ;5
(funcall bar) ;nil

Brian McCallister

unread,
Jul 25, 2005, 9:07:37 PM7/25/05
to

On Jul 25, 2005, at 8:55 PM, luke wrote:

>
> Thanks Dave for the interesting post. Would these problems be
> solved if
> Common Lisp went open source?

Er, there are quite a few open source CL implementations

http://www.cliki.net/Common%20Lisp%20implementation

-Brian

Daniel Brockman

unread,
Jul 26, 2005, 12:58:45 AM7/26/05
to
Hi Joe,

> Sorry, please bear with me... the Lisp I had in mind was
> more like:
>
> (setf a #'length)
> (funcall a "foo")
>
> (Hard to make an exact parallel because Ruby has methods
> not functions, and Lisp AFAIK has functions not
> methods...?)

Ruby has both methods and functions, but methods are more
primitive than functions. In particular, functions are
objects and thus have methods. Methods, on the other hand,
are not objects (and they are not functions). So functions
are implemented using methods, not the other way around.

As for the example code, the closest Ruby equivalent would
have to be something like the following:

a = :length
"foo".send(a)

This is because in Ruby, polymorphism is implemented by
having different ‘length’ methods for different objects,
whereas in Lisp, there is just one function ‘length’ that
handles all types of objects. (Of course, CLOS simplifies
the task of adding new clauses by way of defmethod, but a
generic function is still just one function.)

> Setting a variable to the function itself seems pretty
> different than wrapping a call to the function in a lambda,

Again, there is not just a single ‘length’ method in Ruby,
so you can't “set a variable to the function itself.” The
closest analogy to the “function itself” is the method name.

> but honestly, now I can't think of what the actual
> implications would be... other than a little bit of
> additional terseness in calls like
>
> (reduce #'+ '(1 2 3))
> vs.
> [1, 2, 3].inject {|a,b|a+b}

You could actually define the equivalent of Lisp's ‘+’
function in Ruby, by doing this:

module Kernel
def +(a, b) a + b end
end

Then the example with inject could be written like this:

[1,2,3].inject &method(:+)

But this will fail when someone overrides the ‘+’ operator,
in which case you need to do something like this:

[1,2,3].inject &Object.new.method(:+)

Much cleaner would be to define the function in a separate
namespace so that name clashes are avoided:

Function = Object.new
class << Function
alias [] method
def +(*terms) terms.inject(0) { |a, b| a + b } end
end

Now the example looks like this:

[1,2,3].inject &Function[:+]

You could go one step further:

class Symbol
def to_proc
Function[self].to_proc
end
end

Note that if you take the Kernel#+ approach, the above
implementation needs to be much hairier:

class Symbol
def to_proc
Binding.of_caller do |boc|
eval(%{method(:#{self})}, boc).to_proc
end
end
end

Now you can reduce the original example (no pun intended)
to the following,

[1,2,3].inject &:+

which is actually *shorter* than the equivalent Lisp code.

By the way, a more popular definition of Symbol#to_proc is
to have ‘foo.each &:bar’ equal ‘foo.each { |x| x.bar }’.
This won't work in the above example because we cannot use
the Fixnum#+ method to fold an array of integers (since it
only takes one argument!).

(If you want both variants of Symbol#to_proc, I guess you
could use a unary plus or minus operator to disambiguate.
However, ‘[1,2,3].inject &-:+’ is starting to look rather
much like line noise.)

Daniel Brockman

unread,
Jul 26, 2005, 1:21:15 AM7/26/05
to
zak.w...@gmail.com writes:

> Devin Mullins wrote:
>
>> class Foo; def thing; nil end end
>> f = Foo.new; f.thing #=> nil
>> m = f.method :thing; m.call #=> nil
>> class Foo; def thing; 5 end end
>> f.thing #=> 5
>> m.call #=> nil
>
> I think what's going on here is that it's making a copy of
> the method instead of just pointing a variable at it.

Actually, since methods are themselves immutable, making a
copy of one would have the same effect as “just pointing a
variable at it,” except it would be slower.

My point is that ‘def a.b ; 1 end ; def a.b ; 2 end’ is more
like ‘a.b = lambda {1} ; a.b = lambda {2}’ and less like
‘a.b = lambda {1} ; a.b.body = "2"’. (Of course, this last
statement is completely bogus.)

If that doesn't make sense, forget I ever said anything.
I know I mean, and I know you know what you mean. :-)

Joe Van Dyk

unread,
Jul 26, 2005, 12:26:18 AM7/26/05
to

Is 1.9 going to be 2.0 when it's released?


Lothar Scholz

unread,
Jul 26, 2005, 2:37:10 AM7/26/05
to
Hello Brian,


BM> On Jul 25, 2005, at 8:55 PM, luke wrote:

>>
>> Thanks Dave for the interesting post. Would these problems be
>> solved if
>> Common Lisp went open source?

BM> Er, there are quite a few open source CL implementations

BM> http://www.cliki.net/Common%20Lisp%20implementation

Unfortunately there is no good plattform independent CL
implementation - all of them lack windows support. And none of
the free have good multithreading support, for this you must send
some many to Franz Inc.

It's sad to see the Lisp world in such a bad state.


--
Best regards, emailto: scholz at scriptolutions dot com
Lothar Scholz http://www.ruby-ide.com
CTO Scriptolutions Ruby, PHP, Python IDE 's

Adrian Howard

unread,
Jul 26, 2005, 6:21:12 AM7/26/05
to

On 26 Jul 2005, at 07:37, Lothar Scholz wrote:
[snip]

> Unfortunately there is no good plattform independent CL
> implementation - all of them lack windows support. And none of
> the free have good multithreading support, for this you must send
> some many to Franz Inc.
[snip]

OpenMCL has native threads doesn't it? Now if you want unicode /and/
threads you're out of luck ;-)

Adrian

Devin Mullins

unread,
Jul 26, 2005, 8:42:54 AM7/26/05
to
One could generalize that solution:

class Symbol
def to_proc
lambda { |a,*b| a.send(self,*b) }
end
end

[1,2,3].inject(&:+)

(For some reason, irb complained unless I put parens around it.)

For an even shorter version, here's my APL subset for Ruby:

class Symbol
def *(ary)
ary.inject {|a,b| a.send(self, b)}
end
def [](*ary)
self * ary
end
end
class Array
def +@
:+*self
end
def -@
:-*self
end
end

Now, :+*[1,2,3], :+[1,2,3], and +[1,2,3] are all valid. (Not that I
actually use this libary; just came up with it to make a point about
Ruby to somebody. :P)

(I would've overloaded /, but Ruby kept thinking I was trying to
construct a regular expression.)

And here's a vaguely neat extension of that idea:

class Symbol
def **(ary)
ary.inject { |a,b| a.send(self, *b) }
end
end

:gsub ** ["Hello!",
[/Hell/,"Good"]
[/o!/,"bye.]]

Talk about reducing duplication. :)

Devin

Daniel Brockman wrote:

>to have ‘foo.each &:bar’ equal ‘foo.each { |x| xbar }’.

Joe Cheng

unread,
Jul 26, 2005, 11:43:33 AM7/26/05
to
Daniel Brockman wrote:

>Hi Joe,
>
>
>
>>Sorry, please bear with me... the Lisp I had in mind was
>>more like:
>>
>> (setf a #'length)
>> (funcall a "foo")
>>
>>(Hard to make an exact parallel because Ruby has methods
>>not functions, and Lisp AFAIK has functions not
>>methods...?)
>>
>>
>Ruby has both methods and functions, but methods are more
>primitive than functions. In particular, functions are
>objects and thus have methods. Methods, on the other hand,
>are not objects (and they are not functions). So functions
>are implemented using methods, not the other way around.
>
>

Interesting--that's the first I've heard of it. Do you have a link to
some documentation about functions? I don't see anything in the PickAxe
or ri.

Oh, is it the Function[] syntax you demonstrate below?

>As for the example code, the closest Ruby equivalent would
>have to be something like the following:
>
> a = :length
> "foo".send(a)
>
>This is because in Ruby, polymorphism is implemented by
>having different ‘length’ methods for different objects,
>whereas in Lisp, there is just one function ‘length’ that
>handles all types of objects. (Of course, CLOS simplifies
>the task of adding new clauses by way of defmethod, but a
>generic function is still just one function.)
>
>

I understand. I was not concerned about polymorphic methods vs.
functions, but rather the ability to directly capture a reference to a
[method|function].

Let me try illustrating in Boo instead:

class Foo:
def bar():
print("hello")

a = Foo() # calling Foo constructor
b = a.bar
b() # same as calling a.bar()

This is different than what you are trying to accomplish in your post,
and admittedly, even pretty different from what my Lisp example was in
terms of functionality.

>>Setting a variable to the function itself seems pretty
>>different than wrapping a call to the function in a lambda,
>>
>>
>Again, there is not just a single ‘length’ method in Ruby,
>so you can't “set a variable to the function itself.” The
>closest analogy to the “function itself” is the method name.
>
>

I was looking for something like the above example in Boo. Although
using lambda/proc, send(:symbol), or method(:symbol), they all seem to
accomplish the task (with useful differences in behavior between the
three of them).

>>but honestly, now I can't think of what the actual
>>implications would be... other than a little bit of
>>additional terseness in calls like
>>
>>(reduce #'+ '(1 2 3))
>>vs.
>>[1, 2, 3].inject {|a,b|a+b}
>>
>>
>You could actually define the equivalent of Lisp's ‘+’
>function in Ruby, by doing this:
>
> module Kernel
> def +(a, b) a + b end
> end
>
>Then the example with inject could be written like this:
>
> [1,2,3].inject &method(:+)
>
>

That is actually pretty close. I've never seen the &-syntax (that is,
not from the caller)... I can see there are a lot of possibilities with
that.

Wow, that is really cool. Although one problem... my irb is complaining
about Binding.of_caller not being defined. Do I need to require
something first?

>By the way, a more popular definition of Symbol#to_proc is

>to have ‘foo.each &:bar’ equal ‘foo.each { |x| xbar }’.


>This won't work in the above example because we cannot use
>the Fixnum#+ method to fold an array of integers (since it
>only takes one argument!).
>
>(If you want both variants of Symbol#to_proc, I guess you
>could use a unary plus or minus operator to disambiguate.
>However, ‘[1,2,3].inject &-:+’ is starting to look rather
>much like line noise.)
>
>

I didn't mean to emphasize #'+, it is just the canonical example in the
Lisp tutorials I've read... :)

Thanks for the very interesting response, I learned a lot.

Daniel Brockman

unread,
Jul 26, 2005, 6:40:56 PM7/26/05
to
Devin Mullins <twi...@comcast.net> writes:

> One could generalize that solution:
>
> class Symbol
> def to_proc
> lambda { |a,*b| a.send(self,*b) }
> end

Wow, I really like it! Why didn't I think of that?

You've unified my version with the usual definition,
resulting in the be-all and end-all of Symbol#to_proc.

This *so* needs to be put in the standard library. :-)

> class Symbol
> def *(ary)
> ary.inject {|a,b| a.send(self, b)}
> end

Way cool! I actually like this one, and I'm not kidding.
Redefine Array#* to double-dispatch on symbols and this will
actually be usable. Think about it—

[1,2,3] * "+" means [1,2,3].join("+"),

so it makes sense for

[1,2,3] * :+ to mean [1,2,3].inject(&:+).

More intuitively, we think of ‘[*foo] * "bar"’ as joining
the elements of ‘foo’ by "bar". Analogously, we can think
of ‘[*foo] * :bar’ as joining, or more correctly *recuding*,
the elements of ‘foo’ using :bar.

This strikes me as highly intuitive:

[1,2,3] * "+" #=> "1+2+3"

[1,2,3] * :+ #=> 1 + 2 + 3

As does this (though perhaps slightly less so):

[1,2,3] * "foo" #=> "1foo2foo3"

[1,2,3] * :foo #=> 1.foo(2).foo(3)"

> [crazy APL stuff snipped]


>
> Now, :+*[1,2,3], :+[1,2,3], and +[1,2,3] are all valid.
> (Not that I actually use this libary; just came up with it
> to make a point about Ruby to somebody. :P)

That's cool; you really managed to take this to its extreme.
Of course, ‘:+[1,2,3]’ is too cryptic and ‘+[1,2,3]’ is
better written as ‘[1,2,3].sum’, but still. :-)

> (I would've overloaded /, but Ruby kept thinking I was
> trying to construct a regular expression.)

Hmm, what would you have had that do?

> And here's a vaguely neat extension of that idea:
>
> class Symbol
> def **(ary)
> ary.inject { |a,b| a.send(self, *b) }
> end
> end
>
> :gsub ** ["Hello!",
> [/Hell/,"Good"]
> [/o!/,"bye.]]
>
> Talk about reducing duplication. :)

Wow... amazing. Of course, this

["Hello!", [/Hell/, "Good"], [/o!/, "bye."]] ** :gsub

is both longer and more cryptic than this,

"Hello!".gsub(/Hell/, "Good").gsub(/o!/, "bye.")

but still... the former has *no* duplication. :-)

By the way, the above example suggests that it might be
useful to have String#gsub take multiple arguments:

class String
unless method_defined? :gsub1
alias :gsub1 :gsub
def gsub(*a)
(a.size == 1 ? a.first : a.pairs).
inject(self) { |a, b| a.gsub1 *b }
end
end
end

module Enumerable
def pairs ; groups(2) end
def groups(n)
(a = entries).each_index { |i| a[i, n] = [a[i, n]] }
end
end

"Hello!".gsub(/Hell/ => "Good", /o!/ => "bye.") #=> "Goodbye."

Using a hash to visually pair each expression to its
replacement has the unfortunate side effect of effectively
randomizing the order of the substitutions, so you'll have
to use commas if order is significant:

"Hello!".gsub(/Hell/, "Good", /o!/, "bye.") #=> "Goodbye."


Anyway, thanks for sharing your cool inventions, Devin. :-)

Joe Van Dyk

unread,
Jul 26, 2005, 11:55:41 PM7/26/05
to
On 7/25/05, Lothar Scholz <mailin...@scriptolutions.com> wrote:
> Hello Mark,

>
> MJR> "luke" <ldun...@eml.nope> writes:
> >>Thanks Dave for the interesting post. Would these problems be solved if
> >>Common Lisp went open source?
>
> >>I noticed a post on a site
>
> >>http://lemonodor.com/archives/000671.html
>
> >>that suggests there are some promising dialects of Lisp that are open
> >>source, but currently aren't as rich as, say Common Lisp.
>
> MJR> Huh? Is GNU Common Lisp not actually an implementation of Common Lisp?
> MJR> GCL is not only open source, it's Free Software(TM) in the
> MJR> Richard Stallman-approved sense.
>
> Here, in an image based system like LISP, free in the GPL sense is a very very
> bad idea. Only BSD image based systems are useable for commercial
> applications. This is a fundamental difference to the gcc compiler
> where the GPL makes sense.

What do you mean by "image based system"? And what does that have to
do with the GPL?


Devin Mullins

unread,
Jul 27, 2005, 12:23:02 AM7/27/05
to
Daniel Brockman wrote:

>Wow, I really like it! Why didn't I think of that?
>
>

You weren't being challenged by someone showing you a code snippet
claiming that APL is a superior language. :) BTW, change *b to b, in my
code.

>This *so* needs to be put in the standard library. :-)
>
>

Aww... that's the nicest thing anybody could ever say...

>Way cool! I actually like this one, and I'm not kidding.
>Redefine Array#* to double-dispatch on symbols and this will
>actually be usable. Think about it—
>
> [1,2,3] * "+" means [1,2,3].join("+"),
>
>so it makes sense for
>
> [1,2,3] * :+ to mean [1,2,3].inject(&:+).
>
>

Actually, I like that a lot more than :+ * [1,2,3].

>>(I would've overloaded /, but Ruby kept thinking I was
>>trying to construct a regular expression.)
>>
>>
>Hmm, what would you have had that do?
>
>

Sorry, I just assumed that everybody except me knew APL, so I could just
talk about it as if I knew what I was talking about and get buy-in from
everybody else. In APL, the syntax for doing that is something akin to
"+ / 1 2 3". But you showed an excellent reason why "*" makes more sense
for Ruby.

>Wow... amazing. Of course, this
>
> ["Hello!", [/Hell/, "Good"], [/o!/, "bye."]] ** :gsub
>
>is both longer and more cryptic than this,
>
> "Hello!".gsub(/Hell/, "Good").gsub(/o!/, "bye.")
>
>but still... the former has *no* duplication. :-)
>
>

Well, if you're doing, like, seven gsubs, the former will win out, but
if you're chaining seven gsubs, you're probably doing something wrong. I
suppose you could use "** :gsub" to aid in some sort of configuration
file thing:

class Array
def **(sym)
inject {|a,b| a.send(sym,*b)} end end

gsubs = YAML::load [[/Hell/,"Good"],[/o!/,"bye."]].to_yaml #your config
file here
some_words_ive_got_lying_around = %w{cat dog tree Hello! french oreo!}
some_words_ive_got_lying_around.map! {|word| [word,*gsubs] ** :gsub }
#=> ["cat", "dog", "tree", "Goodbye.", "french", "orebye."]

>By the way, the above example suggests that it might be
>useful to have String#gsub take multiple arguments:
>
> class String
> unless method_defined? :gsub1
>
>

Heh, never seen that "unless method_defined?" thing before. I like it, I
think. (I'm still not comfortable about the alias-and-call-original
trick, and this makes me a little more comfortable about it.)

> "Hello!".gsub(/Hell/ => "Good", /o!/ => "bye.") #=> "Goodbye."

> "Hello!".gsub(/Hell/, "Good", /o!/, "bye.") #=> "Goodbye."
>
>

Hehe, neat. I actually haven't used gsub a lot, so I can't comment on
its usefulness, but I see a lot of other people gsubbing a lot, so I bet
it would be a pretty desired addition.

>Anyway, thanks for sharing your cool inventions, Devin. :-)
>
>

You're welcome, and thanks for calling my inventions cool! Makes me feel
better for not contributing a library or toolkit or whatever to the Ruby
community. :)

Random aside: I learned something about #map just now:

irb(main):001:0> [1,2,3].map
=> [1, 2, 3]
irb(main):002:0> [1,2,3].map!
LocalJumpError: no block given
from (irb):2:in `map!'
from (irb):2

Odd... :P

Devin

Bob Hutchison

unread,
Jul 27, 2005, 2:38:03 AM7/27/05
to

In an image based system, like lisp or smalltalk, all software is
loaded into memory and directly accessed. There is no concept of
linking. That explanation is a bit simplistic maybe, but it gives you
the idea. I think the difficulty is more to to with the LGPL than the
GPL, since the LGPL is defined in terms of linking while the GPL is
defined in terms of use. In an image based system you can't have
linking, so you can't be LGPL compliant, and so you must be GPL
compliant. There is actually something called the LLGPL, where the one
of the 'L's stands for 'lisp', that deals with this situation.

I *think* what Lothar is arguing is that using GCL is different than
using GCC for commercial applications because of the fact that GCL is
image based. This isn't necessarily true, it depends on how the runtime
is licensed and designed since GCL compiles to native via GCC and so
has a linking step hidden away in there -- but I'm too
apathetic/unconcerned to look up the details. As usual, if you don't
like the GPL don't use GPLed software. Simple. (Maybe a more
interesting question is whether you are allowed to run
non-GPL-compatibly licensed software with the GCL runtime at all?)

I don't understand why Lothar says only the BSD license is safe for
commercial use -- that is trivially not true since there are several
commercially licensed CL implementations that are definitely not BSD
licensed, nor is it necessarily true of open source implementations as
there are dozens/hundreds of OSI approved licenses -- so I imagine he
is just being a bit overly specific. His point is clear enough if you
don't take it literally.

I hope this makes some sense... I suppose I really shouldn't be posting
this late.

Cheers,
Bob

----
Bob Hutchison -- blogs at <http://www.recursive.ca/hutch/>
Recursive Design Inc. -- <http://www.recursive.ca/>

Daniel Brockman

unread,
Jul 27, 2005, 2:05:19 AM7/27/05
to
Devin Mullins <twi...@comcast.net> writes:

>> Wow, I really like it! Why didn't I think of that?
>
> You weren't being challenged by someone showing you a code
> snippet claiming that APL is a superior language. :)

Hmm, yeah, I guess that would've done it. :-)

> BTW, change *b to b, in my code.

Why? I can't think of any iterators that pass three or more
arguments to the block off-hand (at least I can't think of
any such cases where it makes sense to simply invoke a
single method upon each yield), but does it hurt to support
that hypothetical case anyway?

>> Way cool! I actually like this one, and I'm not kidding.
>> Redefine Array#* to double-dispatch on symbols and this
>> will actually be usable. Think about it—
>>
>> [1,2,3] * "+" means [1,2,3].join("+"),
>>
>> so it makes sense for
>>
>> [1,2,3] * :+ to mean [1,2,3].inject(&:+).
>>
>>
> Actually, I like that a lot more than :+ * [1,2,3].

Yeah... I was thinking they should both work, but I guess
that's unnecessary, given that ‘"+" * [1,2,3]’ doesn't work.

Random aside: In mathematics, a non-commutable + operator
is pretty damn near unthinkable, wheras in computer science
it's completely normal. I think that's kind of interesting.

>>> (I would've overloaded /, but Ruby kept thinking I was
>>> trying to construct a regular expression.)
>>
>> Hmm, what would you have had that do?
>
> Sorry, I just assumed that everybody except me knew APL,
> so I could just talk about it as if I knew what I was
> talking about and get buy-in from everybody else.

Ah. In light of this thread, I'm actually a little curious
about what other insights one might get from learning APL.

> In APL, the syntax for doing that is something akin to
> "+ / 1 2 3". But you showed an excellent reason why "*"
> makes more sense for Ruby.

I see.

>> Wow... amazing. Of course, this
>>
>> ["Hello!", [/Hell/, "Good"], [/o!/, "bye."]] ** :gsub
>>
>> is both longer and more cryptic than this,
>>
>> "Hello!".gsub(/Hell/, "Good").gsub(/o!/, "bye.")
>>
>> but still... the former has *no* duplication. :-)
>
> Well, if you're doing, like, seven gsubs, the former will
> win out, but if you're chaining seven gsubs, you're
> probably doing something wrong.

Good point. Although I don't think lots of gsubs are any
indication that you are doing something wrong. (I'd hate to
think *I* ever did something wrong.)

> I suppose you could use "** :gsub" to aid in some sort of
> configuration file thing:
>
> class Array
> def **(sym)
> inject {|a,b| a.send(sym,*b)} end end

Nice to see someone else stuffing away those pesky ‘end’s
like that. I have my Emacs coloring them really dimly.

> gsubs = YAML::load [[/Hell/,"Good"],[/o!/,"bye."]].to_yaml
> #your config file here
> some_words_ive_got_lying_around = %w{cat dog tree Hello! french oreo!}
> some_words_ive_got_lying_around.map! {|word| [word,*gsubs] ** :gsub }
> #=> ["cat", "dog", "tree", "Goodbye.", "french", "orebye."]

Okay, but with my modified String#gsub, that's better
written like this:

gsubs.flatten!
some_words.map! { |word| word.gsub(*gsubs) }

>> By the way, the above example suggests that it might be
>> useful to have String#gsub take multiple arguments:
>>
>> class String
>> unless method_defined? :gsub1
>
> Heh, never seen that "unless method_defined?" thing before.
> I like it, I think. (I'm still not comfortable about the
> alias-and-call-original trick, and this makes me a little
> more comfortable about it.)

Yeah. Having been bitten a few times by the double-aliasing
bug that comes into play when a file that uses the “alias
and redefine” idiom is loaded twice, I always try to make
sure my (declarative) code is resistant to being loaded
multiple times.

benny

unread,
Jul 27, 2005, 6:44:46 AM7/27/05
to
William James wrote:

> How much less powerful than Lisp is Ruby?

BTW: did anyone try to write a Ruby interpreter in Lisp?
Might be challenging...

benny

Lothar Scholz

unread,
Jul 27, 2005, 8:19:05 AM7/27/05
to
Hello Bob,

BH> I *think* what Lothar is arguing is that using GCL is different than
BH> using GCC for commercial applications because of the fact that GCL is
BH> image based. This isn't necessarily true, it depends on how the runtime
BH> is licensed and designed since GCL compiles to native via GCC and so
BH> has a linking step hidden away in there -- but I'm too

The question is what is the runtime ?

If you for example want any user customizable parts of your
application, you normally allow the loading of lisp files and then the
problem comes up. There are no clear borders and normally you end up
very soon with using the whole lisp system.

BH> I don't understand why Lothar says only the BSD license is safe for
BH> commercial use -- that is trivially not true since there are several
BH> commercially licensed CL implementations that are definitely not BSD
BH> licensed, nor is it necessarily true of open source implementations as

Yes i meant for open source lisp implementations, the commercial ones
are normally okay by definition.

I only know a few of the licenses and so to cut a long story short _I_
would only accept a BSD lisp systems or one that is completely public
domain. And there is none available.

gabriele renzi

unread,
Jul 27, 2005, 9:08:40 AM7/27/05
to
benny ha scritto:

no, but there were some scheme implementations in ruby ;)

Devin Mullins

unread,
Jul 27, 2005, 9:16:51 AM7/27/05
to
Daniel Brockman wrote:

>>BTW, change *b to b, in my code.
>>
>>
>Why?
>

[[1,2,3],[4,5,6],[7,8,9]] * :+ should => [1,2,3,4,5,6,7,8,9]

>Random aside: In mathematics, a non-commutable + operator
>is pretty damn near unthinkable, wheras in computer science
>it's completely normal. I think that's kind of interesting.
>
>

Well, in Ruby it's completely normal. I can't think of any other
language that does that by default...

One thing that's okay in programming but not in math is that 5/2 == 2 :)

>Ah. In light of this thread, I'm actually a little curious
>about what other insights one might get from learning APL.
>
>

Not much, I don't think. It's a language whose primary use is processing
lists and matrices of numbers, and whose sole focus is absolute
terseness at the expense of readability in any sense of the word. But
hey, maybe I'm being pessimistic. I shouldn't prevent you from a
potential learning experience:

http://en.wikipedia.org/wiki/APL_programming_language
http://www.thocp.net/software/languages/apl.htm
http://www.thefreecountry.com/compilers/apl.shtml
http://www.engin.umd.umich.edu/CIS/course.des/cis400/apl/apl.html
http://www.users.cloud9.net/~bradmcc/APL.html
http://www.acm.org/sigs/sigapl/

My favorite quote from the wikipedia page:
"APL is a mistake, carried through to perfection. It is the language of
the future for the programming techniques of the past: it creates a new
generation of coding bums."
--Edsger Dijkstra

>Nice to see someone else stuffing away those pesky ‘end’s
>like that. I have my Emacs coloring them really dimly.
>
>

I did that just for you. :) Also because it was an email, and I was
going for fewness of lines.

>Okay, but with my modified String#gsub, that's better

>written like this: <snip>
>
>
True.

>Yeah. Having been bitten a few times by the double-aliasing
>bug that comes into play when a file that uses the “alias

>and redefine” idiom is loaded twice, ...
>
>
I'm eager to see when Behaviors is ready for prime-time. Ruby needs more
support for this sort of thing.

Also, what do you think of an 'original' keyword for when you redefine a
method (assuming that Behaviors solves your loaded-twice problem)?
class String
def gsub(*a)
if a.size == 1 then original
else original(a[0]).gsub(a[1..-1])
end
end
end

One could use the original keyword like one uses the super keyword.

Devin

Jaypee

unread,
Jul 27, 2005, 10:48:29 AM7/27/05
to
Devin Mullins wrote:

> Daniel Brockman wrote:
>
>> Ah. In light of this thread, I'm actually a little curious
>> about what other insights one might get from learning APL.
>>
>>
> Not much, I don't think. It's a language whose primary use is processing
> lists and matrices of numbers, and whose sole focus is absolute
> terseness at the expense of readability in any sense of the word. But
> hey, maybe I'm being pessimistic. I shouldn't prevent you from a
> potential learning experience:
...
Choosing a comment of Dijkstra on APL is as valid having the creator of
COBOL comment on Ruby. It's just irrelevant.

The terseness of of APL is only a reflection seen from outside. In fact
there are many idioms, that you quickly recognize and don't need to
spell out. It does give you some different ways to solve a problem,
because of the richness of operators. For example as sorting is one of
those operators, sorting is easily used as part of an instruction,
amongst other operations.
I have spent the first 4 years of my professional life coding in APL.
The scars are benigne, not as bad as the same amount of Visual Basic.

Example: Imagine you had to emulate an old time text processor to
justify lines to a given width, by adding spaces where there are already.
The width is w
(line iota ' ') yields a vector of indices of white spaces in the line
(it's the dyadic iota: A iota B)

(rho line) is the length of the line (monadic rho)
iota n is the vector 1..n (monadic iota)
Let's make a vector of all indices of the line : iota rho line

Let's reuse as many indices of white spaces as needed:
(w - rho line) rho line itota ' '
The dyadic rho is used here, (size rho pattern), it reuses the
pattern as many time as needed to fill the result to the specified size.

Let's sort all the indices:
sort (iota rho line), (w - rho line) rho line itota ' '

Then use the resulting vector with the original line so:
line[sort (iota rho line), (w - rho line) rho line itota ' ']
is the answer of the problem ...

Sorry for the length and OT twist of that reply ;-)
J-P

William James

unread,
Jul 27, 2005, 11:53:58 AM7/27/05
to
Jaypee wrote:

> Example: Imagine you had to emulate an old time text processor to
> justify lines to a given width, by adding spaces where there are already.
> The width is w

w=60

DATA.each_line {|line|

t=line.split;n=t.size-1;q,r=(w-t.join.size).divmod(n)
print t.zip([" "*q]*n,[" "]*r);puts""

}

print "="*w

__END__
The quick red fox jumps over the lazy brown hogs.
The quick red fox jumps over lazy brown hogs.
The quick red fox jumps over lazy hogs.
The quick fox jumps over lazy hogs.
The quick fox.


-----
The output is

The quick red fox jumps over the lazy brown hogs.
The quick red fox jumps over lazy brown hogs.
The quick red fox jumps over lazy hogs.
The quick fox jumps over lazy hogs.
The quick fox.
============================================================

Daniel Brockman

unread,
Jul 27, 2005, 12:28:02 PM7/27/05
to
Devin Mullins <twi...@comcast.net> writes:

>>> BTW, change *b to b, in my code.
>>
>> Why?
>
> [[1,2,3],[4,5,6],[7,8,9]] * :+ should => [1,2,3,4,5,6,7,8,9]

class Symbol
def to_proc
lambda { |a, *b| a.send(self, *b) } end end

[[1,2,3],[4,5,6],[7,8,9]].inject(&:+) #=> [1..9].to_a

class Symbol
def to_proc
lambda { |a, b| a.send(self, b) } end end

[[1,2,3],[4,5,6],[7,8,9]].inject(&:+) #=> [1..9].to_a

It only matters when the iterator (‘inject’, in this case)
passes more than two arguments to the block. ...right?

>> Random aside: In mathematics, a non-commutable +
>> operator is pretty damn near unthinkable, wheras in
>> computer science it's completely normal. I think that's
>> kind of interesting.
>
> Well, in Ruby it's completely normal. I can't think of any
> other language that does that by default...

There are lots and lots and lots of examples. To choose
just one, Java overloads + non-commutatively for strings:

("foo" + "bar").equal("bar" + "foo") // => false

> One thing that's okay in programming but not in math is

> that 5/2 == 2. :)

It's not okay with me. :-)

I'd much rather have the ‘/’ operator not perform any
truncation, and use ‘5.div 2’ to get integer division.

>> Ah. In light of this thread, I'm actually a little
>> curious about what other insights one might get from
>> learning APL.
>
> Not much, I don't think. It's a language whose primary use
> is processing lists and matrices of numbers, and whose
> sole focus is absolute terseness at the expense of
> readability in any sense of the word. But hey, maybe I'm
> being pessimistic. I shouldn't prevent you from a
> potential learning experience:
>
> http://en.wikipedia.org/wiki/APL_programming_language
> http://www.thocp.net/software/languages/apl.htm
> http://www.thefreecountry.com/compilers/apl.shtml
> http://www.engin.umd.umich.edu/CIS/course.des/cis400/apl/apl.html
> http://www.users.cloud9.net/~bradmcc/APL.html
> http://www.acm.org/sigs/sigapl/

Hmm... maybe some day. :-)

>> Yeah. Having been bitten a few times by the
>> double-aliasing bug that comes into play when a file that
>> uses the “alias and redefine” idiom is loaded twice, ..
>

> I'm eager to see when Behaviors is ready for prime-time.
> Ruby needs more support for this sort of thing.

I haven't heard of Behaviors before, but it seems
interesting. I'm going to read up on them, thanks.

> Also, what do you think of an 'original' keyword for when
> you redefine a method (assuming that Behaviors solves your
> loaded-twice problem)?
>
> class String
> def gsub(*a)
> if a.size == 1 then original
> else original(a[0]).gsub(a[1..-1])
> end
> end
> end
>
> One could use the original keyword like one uses the
> super keyword.

That's a great idea. I really like it. The idiom is so
common and ugly that it definitely could use some sugar.

The semantics are straightforward, too: Only redefine a
method when its current body differs from the new one, and
give the redefined method a reference to the old one,
accessible through ‘original’. (For efficiency, the
original method should probably only be saved if the new
method uses the ‘original’ keyword.)

twi...@comcast.net

unread,
Jul 27, 2005, 1:35:13 PM7/27/05
to
>Choosing a comment of Dijkstra on APL is as valid having the creator of
>COBOL comment on Ruby. It's just irrelevant.
Fair point. It's funny, though!

Sorry to be so negative about the language. I really haven't
looked into it much so I shouldn't be so harsh to judge. Didn't
fully understand the example, but I appreciated it, anyhow.
Point taken, however.

Though I may not (yet) dig using APL as a language to write
anything longer than one line, it is really good at many one-liners,
and certain things that require a lot of typing to say something
stupid could easily be abstracted into a more comprehensive
Array library, say. That's where array * :+ came from, and there
are probably more like it.

>It only matters when the iterator (ãàÏÊnjectãà in this case)


>passes more than two arguments to the block. ...right?

Yeah, right. I'm on crack, nevermind.

>There are lots and lots and lots of examples. To choose
>just one, Java overloads + non-commutatively for strings:

Yeah, okay, I'm still on crack.

>It's not okay with me. :-)

>I'd much rather have the ãàãàoperator not perform any
>truncation, and use ãà.div 2ãàto get integer division.
Ditto. Doesn't Pascal act like this?

>> One could use the original keyword like one uses the
>> super keyword.
>That's a great idea. I really like it. The idiom is so
>common and ugly that it definitely could use some sugar.

Great! Now go write an RCR for me. :Q

Devin
I have no idea where my webmail gets all those funky "ãàãà"
characters from.


zak.w...@gmail.com

unread,
Jul 27, 2005, 5:00:15 PM7/27/05
to
SBCL and CMUCL are mostly public domain, those parts that are not are
BSD licenced. Clisp is GPL, with an LGPL-like exception for saved
images.

Dave Fayram

unread,
Jul 27, 2005, 7:10:02 PM7/27/05
to
On 7/25/05, luke <ldun...@eml.nope> wrote:
>
> Thanks Dave for the interesting post. Would these problems be solved if
> Common Lisp went open source?

It already is, but the quality of open source implementations varies
wildly. Not quality as in "are they good." The amount of ego and
expertise that tends to reside in the lisp community assures that the
projects meet their goals. Quality as in, "What problems does this
solve?" Some CMUCL, for example, is an incredibly good compiler when
you need very fast lisp. However, it's harder to use than SBCL, which
has my vote for easiest lisp distro to use in general (and it's what
Peter Seibel distributes as "Lisp In A Box"). On a mac, OpenMCL has a
ton of great features.

The commerical offerings solve enterprise solution problems. Ever seen
a CORBA->Lisp binding? They actually make CORBA usable! But you pay a
lot and LispWorks and Allegro still compile slower mathmatical code.


> that suggests there are some promising dialects of Lisp that are open
> source, but currently aren't as rich as, say Common Lisp.

They are all common lisp.

And the first thing that drew me to Ruby was its peculiar and very
right-seeming "Ruby Way." Matz has impeccable taste in coding, and
Ruby reflects that taste.


--
--
Dave Fayram (II)

dfa...@gmail.com


Gavin Kistner

unread,
Aug 3, 2005, 7:49:22 PM8/3/05
to
On Jul 25, 2005, at 7:48 PM, Devin Mullins wrote:
> I have a stricter definition. Let's call it "patrician
> hooberglobbers." Patrician hooberglobbers, to me, have the
> additional quality that the syntax for manipulating a hooberglobber
> is the same whether it is referred to statically or by evaluation/
> substitution (as through a variable, or return value of a function
> call). In this sense, Ruby has patrician classes:


What do you call patrician hooberglobbers that can be invoked with
binding to instances of arbitrary classes, such that 'self' and
instance variables refer to the supplied instance?

That's what I think of when I think of first-class functions, given
my JS background: a single function that may be anonymous, assigned
to a variable, and invoked with a specific binding. (And if it's also
a closure, so much the better.)

There are few things that make me cry about Ruby, but of those that
do, few make me cry more than the current situation with Methods/
UnboundMethods/Procs/blocks/lambdas. It's workable, but it really
isn't elegant. (IMO)


ruby-talk ML

unread,
Aug 3, 2005, 9:16:33 PM8/3/05
to
Gavin Kistner wrote:

> There are few things that make me cry about Ruby, but of those that
> do, few make me cry more than the current situation with Methods/
> UnboundMethods/Procs/blocks/lambdas. It's workable, but it really
> isn't elegant. (IMO)

As a relative newcomer to Ruby, I would appreciate hearing you elaborate
on this point.

Thanks!
John


Trans

unread,
Aug 4, 2005, 8:44:06 AM8/4/05
to

Search the ruby-talk archives and you'll find a good bit about it.
Basically we have four/five differnt entities that are all almost but
not quite the same things. Hopefully Rite/Ruby2 will simplify this
some.

T.

0 new messages