Live data from Hacker News

Why Ruby is an acceptable Lisp (2005)

randomhacks.net

81–90 of 115 posts

Re: Why Ruby is an acceptable Lisp (2005)

#81

Earlier quoted context omitted.

On large team Lisp projects, you don't have every individual person arbitrarily invent their own idiosyncratic abstractions. The project as a whole has a common set of abstractions that fit the domain, which are designed and modified the way you would design the abstractions regardless of the language and programming paradigm you're using. Macros are a language tool that lets you build abstractions, in some cases imo…

> Macros are a language tool that lets you build abstractions, in some cases imo allowing better abstractions than would be possible without macros I guess 'better' is the operative word I question here. You're creating syntax that no-one has seen before. How is that a good thing? Meanwhile in languages like Python, with syntax built-in, people build large apps without ever doing this, making their code far more unde…

No, what he's saying is that a good team knows when to use the guns, and how to aim them. A good OO team knows how to layer their types, how to relate them, and when to stop. A good asm team knows how to handle nonlocal jumps, when to use them and when not to. Every paradigm has its guns. You're just paying extra attention to the lisp ones.

Re: Why Ruby is an acceptable Lisp (2005)

#82

Tcl is a better lisp than Ruby. Homoiconic. Yield and tailcall make it easy to implement FP idioms. Macros available if needed.

I am forced to use tcl a lot at work because that's what the ASIC tool vendors settled on for a scripting language. It's awful. Just plain awful. I avoid it as much as I can, but I'm forced to use it thanks to Synopsys.

The Synopsys extensions are a bear to work with but at least you can define procs which was impossible to do with their old scripting language where you had to simulate them with repeated includes.

Re: Why Ruby is an acceptable Lisp (2005)

#83

Earlier quoted context omitted.

...No. Clojure is lisp, but it's a weird little language, and most of us lispers schemers aren't really totally happy with it. We're used to more flexability, less functionalism, and less opinionation. Plus, Clojure's equality and conses don't work at all the way a lisper would expect, and the conses are way less useful. There's a reason there will never be a universal language.

As a clojure fan, I agree about conses. It's rare to use something like that. Personally I'm happy equality doesn't work like common lisp. See here for a post explaining equality in CL: http://eli.thegreenplace.net/2004/08/08/equality-in-lisp It's old and I don't use common lisp, so please correct me or the post if needed. I've tried to get into lisp numerous times. Clojure was the one that clicked for me. I can't sa…

How are conses in Clojure different from those in Scheme? Is it the implementation? Because the API seems the exact same to me.

Re: Why Ruby is an acceptable Lisp (2005)

#84

Earlier quoted context omitted.

On large team Lisp projects, you don't have every individual person arbitrarily invent their own idiosyncratic abstractions. The project as a whole has a common set of abstractions that fit the domain, which are designed and modified the way you would design the abstractions regardless of the language and programming paradigm you're using. Macros are a language tool that lets you build abstractions, in some cases imo…

> Macros are a language tool that lets you build abstractions, in some cases imo allowing better abstractions than would be possible without macros I guess 'better' is the operative word I question here. You're creating syntax that no-one has seen before. How is that a good thing? Meanwhile in languages like Python, with syntax built-in, people build large apps without ever doing this, making their code far more unde…

> in languages like Python, with syntax built-in, people build large apps without ever doing this, making their code far more understandable for the next person that touches it.

No. Lack of macros makes code bigger, more error prone and harder to understand.

When I use something like cl-ppcre:do-register-groups, this one word hides all the loop orginization, and underlines meaning of local variables which are bound to regex groups.

Or cl-sql:select, which allows programmer to use SQL syntax as part of lisp while hiding special chars escaping, converting numbers to strings, ensuring sql-syntax is correct.

Or simplier example: gl:with-primitives, which hides glBegin(...); ... glEnd(). Note, it not just hides, it makes impossible to forget glEnd.

Macros makes life easier. Otherwise no one would use it. Macros such a convinient way to make an abstractions, that switching from Lisp to any other language becomes a great pain. One start to see tons of boilerplate code, which needs to be written by hands, checked for errors with eyes, which hides logic somewhere inside of boilerplate... It becomes better with practice, but nevertheless lisp nostalgia will last forever.

Re: Why Ruby is an acceptable Lisp (2005)

#85
post #51

Earlier quoted context omitted.

Maybe this is meta (the wish) :-) I remember tcl in the early 90s then it disappeared from my radar, mostly web and mobile apps. Honest question: is it still relevant in some application area?

It's still great at what it was always great at: embedding, acting as a CLI, and doing random grunt work. It's Lua's main competitor, but it can also go toe-to-toe with python and ruby in terms of libraries in some areas (although by no means all of them). In particular, the ease of construction for graphical applications is arguably unmatched (IUP is probably the closest), SQLite was built to work with it, metakit i…

This comment is a great representation of tcl's relevance, which is nice to see because tcl is often dismissed nowadays by people who don't understand it

Re: Why Ruby is an acceptable Lisp (2005)

#86
post #21

Author here. Let me explain where this article came from, since people keep digging it up every few years to discuss it. :-) I spent some time during the late 90s learning all kinds of cool ways to use Lisp, courtesy of a couple Boston startups, including IS Robotics (now better known as iRobot). And I'd helped introduce Scheme to another employer. Scheme made it ridiculously easy to create domain-specific languages,…

Interesting article and thanks for chiming back in. I also discovered and enjoyed the metaprogramming features of ruby perhaps 5+ years ago. As I've been learning it recently, can I ask if you have any particular take on lua? To me, it feels a bit paired back, more purist, smaller core/libraries than ruby, but also drawing from the same tradition - ie. lua's tables/functions equate well to lisp's lists/S-expressions (though practically largely equivalent and including metaprogramming support) - despite not being directly derived from a lisp.

Re: Why Ruby is an acceptable Lisp (2005)

#87

Earlier quoted context omitted.

...No. Clojure is lisp, but it's a weird little language, and most of us lispers schemers aren't really totally happy with it. We're used to more flexability, less functionalism, and less opinionation. Plus, Clojure's equality and conses don't work at all the way a lisper would expect, and the conses are way less useful. There's a reason there will never be a universal language.

As a clojure fan, I agree about conses. It's rare to use something like that. Personally I'm happy equality doesn't work like common lisp. See here for a post explaining equality in CL: http://eli.thegreenplace.net/2004/08/08/equality-in-lisp It's old and I don't use common lisp, so please correct me or the post if needed. I've tried to get into lisp numerous times. Clojure was the one that clicked for me. I can't sa…

Yes, CL has old and useless functions.

There is zero need to ever use SETQ for example. SETF is a pure superset of SETQ's functionality. For other examples, I don't know that I've seen a serious use of PROGV or PROG in this century either.

Most experienced lisp programmers never use EQ, since EQL is more well designed, and the overhead is either negligible or nonexistent. Yes it's annoying that EQUAL doesn't recurse into non-string vectors.

Useful equality in CL is roughly: EQL for comparing non-aggregate types and identity checking of aggregate types, EQUAL for comparing lists, and EQUALP for case-insensitive comparisons. Some people add in = for numeric comparisons, but that's a style question (seeing = means "these arguments are definitely going to be numbers" and not much else, as if you're doing an equality test between e.g. an integer and a float, then you're doing it wrong, and differing numeric types is the only time = is different from eql when all arguments are numbers).

Comparing non-primitives is typically done with domain-specific comparison functions, as there are many ways to decide if two arbitrary objects are "equal" (for the old-saw OO example of 2d geometric shapes, you might have shape-area-equal, shape-perimeter-equal ...).

Some things I like about CL:

I find its package and macro system combine to be an amazing sweet spot of simplicity and power for metaprogramming. Scheme's hygienic macro system is the stuff that earned several people their doctorates; CL's is explainable in under a minute, and 99% of hygiene problems are solved by the package system (IIRC Clojure inherits its macro system from CL, using namespaces to solve the "FLET" problem).

CLOS+MOP made me feel like perhaps OO wasn't the colossal mistake I'd always thought it was. It's not the only great OO system out there, but it is great and so much better than the various C++ derived systems that I was first exposed to that it will always have a special place in my heart.

The condition system is great. The only quick summary I can give is that you can have condition handlers run in the stack context in which the exception was thrown (which lets you do much more useful things than running in the context in which you establish the handler, which is how all other exception systems I've seen work).

Common Lisp has amazing development tools; in particular the combination of SBCL/SLIME puts nearly all other F/LOSS IDEs to shame[1]:

It's a high-level language, but you can view a function's disassembly, capture instruction-level profiling data, recompile a single function and rerun all of that without stopping your program. The overhead of edit/compile/debug is essentially zero.

All that being said, I do need to take a look at clojure again (I went through Fogus's "Joy of Clojure" book when it was new, but haven't touched the language since).

1: http://pryrepl.org/ is apparently an attempt to bring some of this to Ruby, but I have on many occasions seen Ruby programmers say that "If you're using a debugger you're doing it wrong" and Pry doesn't seem to have a lot of users.

Re: Why Ruby is an acceptable Lisp (2005)

#88
post #83

Earlier quoted context omitted.

As a clojure fan, I agree about conses. It's rare to use something like that. Personally I'm happy equality doesn't work like common lisp. See here for a post explaining equality in CL: http://eli.thegreenplace.net/2004/08/08/equality-in-lisp It's old and I don't use common lisp, so please correct me or the post if needed. I've tried to get into lisp numerous times. Clojure was the one that clicked for me. I can't sa…

How are conses in Clojure different from those in Scheme? Is it the implementation? Because the API seems the exact same to me.

Not a Clojure developer but, IIRC, Clojure doesn't have conses, but rather the function cons creates a seq. A Seq in Clojure is immutable and (usually) lazy, which is nothing like what CONS makes in lisp (a mutable pair that is the basis for building singly-linked lists).

Note that linked-lists are only a good data structure in fairly narrow contexts (e.g. shared structure, certain types of mutation you can do). Since Clojure is focused on limiting mutation, it makes sense for them to use Seqs instead of linked-lists.

Re: Why Ruby is an acceptable Lisp (2005)

#89

Earlier quoted context omitted.

GPP asked what lisp's got that Ruby doesn't. I told him. Lisp isn't the end-all be-all. If you can't trust your teammates, than maybe you shouldn't be using Lisp. But keep in mind that you can write INTERCAL in any language. Lisp just makes it easier, because Lisp does its best not to limit you. Besides, who would invent their own language in macros for no reason? Also, the syntax is one of the best parts about Lisp.…

> Also, the syntax is one of the best parts about Lisp. I think you're in the minority there. I would hope most people agree that Lisp 'sacrifices syntax in the name of homoiconicity'. If not, then we have different definitions of syntax and I'm not sure any discussion on that is likely to go anywhere.

In the case of code that works with code, rich syntax is a problem, not a solution. Getting rid of tons of syntax is not a sacrifice at all, when you're wrapping, transforming, and/or generating code. And as I've stated elsewhere, the fact that you can do this now so easily means it opens up that power for quick little inline tools, where in most other languages that sort of thing is reserved for major undertakings.

It also eliminates many syntactic bugs, makes searching & editing code easier for humans, makes editor tools easier to create and more broadly useful when they exist, and eliminates ambiguous precedence completely.

You begin to notice that syntax itself really is an anti-feature, after working across a wildly varying range of languages and styles, and designing many fully custom DSLs.

Re: Why Ruby is an acceptable Lisp (2005)

#90

Earlier quoted context omitted.

> Also, the syntax is one of the best parts about Lisp. I think you're in the minority there. I would hope most people agree that Lisp 'sacrifices syntax in the name of homoiconicity'. If not, then we have different definitions of syntax and I'm not sure any discussion on that is likely to go anywhere.

In the case of code that works with code, rich syntax is a problem, not a solution. Getting rid of tons of syntax is not a sacrifice at all, when you're wrapping, transforming, and/or generating code. And as I've stated elsewhere, the fact that you can do this now so easily means it opens up that power for quick little inline tools, where in most other languages that sort of thing is reserved for major undertakings.…

> Getting rid of tons of syntax is not a sacrifice at all

Getting rid of syntax that usefully expresses common cases absolutely is a sacrifice. What was that Turing tar pit thing about making things of interest easy? Lisp is powerful, but its lack of syntax makes it inexpressive.

> It also eliminates many syntactic bugs

How so?

> makes searching & editing code easier for humans

I disagree, code that lacks basic syntax such that programmers end up writing macros, does not make code easier to search and edit.

> makes editor tools easier to create and more broadly useful when they exist

I can see how that would work, because you're writing ASTs like you're a robot, which of course machines can understand better, just not humans.

> eliminates ambiguous precedence completely

That is a totally overstated problem. I've literally never been bitten by this in about 10 years of programming. Everyone in every other language just adds parens by default.

> You begin to notice that syntax itself really is an anti-feature

Having given Clojure I think 'a fair go', I just don't see that happening. Being able to read my teammates code will never be an anti-feature.

I just don't agree with the trade-off ...

Post reply on HN