Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

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.



SETQ has to exist, because it is the primitive SETF is based upon. EQ is tremendously useful for testing identity (which is kind of its job...), and conveys intent (although I mostly use Scheme, where eq? is a lot nicer). And Scheme's macros don't have to be super complicated. explicit rename, implicit rename, and syntactic closure macro systems are almost as simple as CL macros.




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

Search: