Hacker News new | past | comments | ask | show | jobs | submit login
Matz: Ruby's Lisp features (2006) (nagaokaut.ac.jp)
62 points by juliangamble on Oct 14, 2013 | hide | past | favorite | 29 comments



Take lisp, remove s-expressions.... what are the remaining lisp-like parts?

Ruby's smalltalk influence is pretty clear, and I guess smalltalk says it's lisp-influenced... I dunno. I am dubious that Matz started with lisp rather than smalltalk.


IIRC, Ruby builds an s-expression tree under the hood (disclaimer: this is going by what I've read and I can't find the article right now, please take with several grains of salt). I do know this, however: In Ruby, everything is an expression. So that's why code like..

    foo = if bar?
      :bar
    else
      foo_proxy || :foo
    end
..can be expected to work. One thing I love about Ruby is that I feel as though it works "like a Lisp" under the hood, but doesn't look like one at all. The one thing I could never get over with Lisp-like languages was how difficult the syntax was for me to read. Ruby, OTOH, is a very familiar syntax and includes familiar concepts like various OOP encapsulation features, but it's all built around this expression-driven language that's both syntactically powerful and very easy to read.

edit: I still wouldn't consider it part of the Lisp family, only heavily influenced by that kind of programming...


"Everything as an expression" is concept that exists entirely separate from LISP as a programming language. Eg, in the untyped lambda calculus everything is indeed an expression and it obviously predates LISP.

The thing that makes LISPs interesting is that both data and code have the same representation. Manipulating code and data looks the same and that leads to all sorts of interesting meta-programming constructs

Also I'm not sure what you mean by "under the hood", but Ruby's internal representation is an abstract syntax tree (as with most languages). That AST bears a resemblance to LISP because LISP is both the language and AST rolled into one, but I would never confuse Ruby for LISP because it has an AST representation.


I think the answer is the dynamic environment. In terms of syntax and semantic constructs Ruby is not very much like Lisp at all. But the dynamic runtime is very lisp-like. You can modify any part of the environment at runtime—in fact there is really no distinction between run-time and compile-time.

IMO the biggest flaw in Ruby is that it doesn't really take advantage of this design choice. Of course there is a performance cost to this kind of dynamism, and all it really buys you in Ruby is the ability to monkey-patch other people's code (the advisability of which is debated). In the Lisp world you have tools like SLIME which provide a much shorter feedback loop to the developer by connecting the dynamic runtime to the editing environment.

Tools like pry move Ruby forward in this area but it is still nothing like SLIME. My impression is that the weakness of Ruby's module system, along with heavy use of OO classes, make it unlikely for Ruby to ever support that kind of development process.

(There are other examples of Ruby's Lisp heritage, such as everything-is-an-expression and implicit return values, but I think those are relatively small design choices compared to the runtime thing.)


Although removing s-expressions isn't necessarily critical -- see Dylan, Honu, sweet expressions, etc. -- I think removing macros means you no longer have a lisp.


Removing homoiconicity means you no longer have a lisp.


I disagree, by that definition Racket is not a lisp. AST macros are enough imo.


Racket isn't a Lisp. All of the Lisps have "Lisp" in their name, e.g MacLisp, Common Lisp, ZetaLisp, Interlisp, EuLisp, Elisp, etc.

Look at the conversation between kragen and lispm here [1].

Of course you can almost always informally call various Scheme dialects and Clojure "Lisps" (I do it all the time) because they draw very heavily from Lisps.

[1] https://news.ycombinator.com/item?id=6068732


I said lisp not Lisp. I think it's meaningful to refer to things like Scheme, Racket, Arc, Clojure, Dylan, Honu et al as lowercase lisps.

For example I believe those tick off all 9 items on pg's list: http://www.paulgraham.com/diff.html

Disclaimer for language lawyers: Using lowercase lisp is not intended to infringe Lisp (R), a registered trademark of Sole Arbiter of What's a Lisp Corporation. ;)


Could you explain why Racket isn't homoiconic ?


It doesn't use S-Expressions internally, it uses a different representation called syntax objects. http://docs.racket-lang.org/guide/stx-obj.html


C++ is arguably a lisp then


I am dubious that Matz started with lisp rather than smalltalk.

I'm not dubious. Before writing Ruby, Matz had been a Lisp programmer. But he wasn't a Smalltalk programmer.

Conceptually, it makes sense that he would have started with something conceptually like Scheme, then layered things on top.


My take is that it is essentially that ruby's methods (the basis of OO) are basically based on a simple system of (what ruby refers to as) procs and lambdas (ok, the way they are implemented is not quite the same as the 'proc'/'lambda' objects but you can easily convert between them). These are quite functional and lisp-like. Not that it is done, but you can reduce all of your complex methods to classless functions if you want.

Not sure if this was new in Ruby or came from Smalltalk or somewhere else though.


> Ruby's smalltalk influence is pretty clear, and I guess smalltalk says it's lisp-influenced.

Smalltalk was surely influenced by Lisp.

You can read about Smalltalk's history as described by Alan Kay here

http://gagne.homedns.org/~tgagne/contrib/EarlyHistoryST.html


I guess higher order functions and symbols are the remaining Lispy bits.


Being properly OO kind of messes up the way alot of the HoF stuff works as well, since you don't have a bunch of functions that operate on strings, you have methods on string. You have to have some strange thing like mystrings.map(&:to_upper), rather than just passing map the actual function.


> Being properly OO kind of messes up the way alot of the HoF stuff works as well, since you don't have a bunch of functions that operate on strings, you have methods on string.

It doesn't really - methods are nothing more than closures of general functions around a specific value for the implicit parameter (usually the first parameter). The syntax for doing this in Lisp is pretty straightforward, and that's the way CLOS is structured.

And for what it's worth, Alan Kay (who coined the term "object-oriented") himself said (in 2003!) that the only two object-oriented languages he was aware of were Smalltalk and LISP.


I guess it's not actually about OO, more a syntactic thing of having that special implicit parameter, and needing to transform methods methods into procs that call call the method on their parameter, rather than just passing around functions.

edit: I suppose that the code "f", invokes f with no arguments rather than returns the method with name f also complicates things


> I suppose that the code "f", invokes f with no arguments rather than returns the method with name f also complicates things

Why should it? "a.f(b, c, d)" is just "(apply #'f a b c d)". "a.f" is just (apply #'f a). "f" is just (apply #'f).

This assumes that you know the type of f, of course (f could be a string, which should't be applied). But that's not really much of an issue - you just do something like

    (define (naive-evaluate f)
      (if (applyable-p f) 
          (apply #'f)
          f))

where "applyable-p" checks if "f" is a lambda term that has any free (unbound) variables.

This isn't the most efficient underlying implementation, but you get the idea. From the perspective of the lambda calculus, OO is dead simple.

On a side, note, writing this example out reminded me of how much I really miss writing Lisp every day..... :'(


How would you propose resolving this doubt of yours?


Well, Ruby isn't really homoiconic. I can't speak for OP, but to me, if a language isn't homoiconic, it can't be a Lisp.

Lisps don't have to have parenthesis-based syntax, but the grammars should be close to context-free (like Lisp's is - most of the language can be defined by two production rules). Ruby's grammar is nowhere near as simple.

Compare:

Lisp: http://cui.unige.ch/isi/bnf/LISP/

Ruby: http://stackoverflow.com/questions/663027/ruby-grammar


Matz (except for the tongue in cheek thing about a suggested name at the end) didn't suggest that Ruby was a Lisp, just that in designing it Lisp was a starting point.

So, yes, you have every reason to doubt the claim that Ruby is Lisp -- a claim no one has made.

I don't see how that resolves your stated doubt of Matz claim that Lisp was a starting point for Ruby.


> "the claim that Ruby is Lisp -- a claim no one has made"

Posted without comment: this was written just before Matz wrote this email, but here's someone saying that Ruby is an acceptable LISP: http://www.randomhacks.net/articles/2005/12/03/why-ruby-is-a...


Given the benefits of Lisp that were cited in that article as defining, the conclusion is well-supported by the article.

Obviously, those aren't everyone's central concerns for a Lisp, nor are they the standard criteria for a Lisp. But, in any case, that someone said something like "Ruby is a Lisp" somewhere else in a different context doesn't change that arguing that Ruby isn't a Lisp was something of beating a strawman in this this thread.


I remember "why ruby is an acceptable Lisp" - that was a fun read. This is an equally fun rebuttal by Steve Yegge http://steve-yegge.blogspot.com.au/2006/04/lisp-is-not-accep...


My slightly different take:

  * take Emacs Lisp language (one after CL) and byte code compiler
  * take Emacs Lisp implementation with simple GC and byte code virtual machine
  * remove macros, s-expression.
  * add simple object system (much simpler than CLOS).
  * add blocks, inspired by higher order functions.
  * add methods found in Smalltalk.
  * add functionality found in Perl (in OO way).
Yukihiro Matsumoto mentioned in some talk that the most Lisp he understood was some Emacs Lisp and that he studied the Emacs Lisp implementation.


Matzacred Lisp. :-(


(2006)




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: