Here are a few things that triggered major Aha! moments for me, in no particular order.
- reading the source of cl-ppcre, which illustrated
- run-time compilation (to chains of closures) without using COMPILE or COMPILE-FILE
- parsing regular expression strings, with nice error-reporting via conditions
- that Lisp solutions to practical problems can be concise, comprehensible, and *fast*
- reading Keene's CLOS book
- finding an application of continuable errors; it replaced a convoluted scheme of checking return values at multiple levels with a simple handler-bind wrapper.
- realizing that file formats and communication protocols are just bits on disk or on a wire or sometimes even in memory, and Lisp is pretty good at generating the right bits and octets; inspired by (among other stuff):
- learning that CLX is a Lisp program, not a binding to the C xlib
- learning that Marc's CL-PDF is a Lisp program
- learning about Frode's binary-types
- reading Peter's chapters on parsing binary files
- reading Will Hartung's "Guerilla Lisp Opus"
- realizing that most Common Lisp implementations are mostly written in Common Lisp
A few themes:
- Despite conceptually understanding how tools like CLOS and closures and conditions work, it took a tricky problem solved neatly by the tool to really make an Aha! moment
- Aha! moments have made complicated tasks simpler and unapproachable tasks approachable (given the right amount of time and effort). They take the magic out of things. (Philip Greenspun used to say that his course would teach undergrads how to build Amazon in a semester; despite the hyperbole, it really did take the mystery out of how useful web applications can be constructed.)
Advice:
- Be actively curious about how interesting things work ("how can cl-ppcre be faster than Perl?")
- Be broadly aware of the tools available, and don't worry about immediate application
- Don't settle for tedium (it's hard to have a breakthrough if you have resigned yourself to something that feels substandard)
- People who write one interesting thing usually keep it up; find and watch interesting people (trickle-down Aha! effect?)
Minor delights:
- format tricks (~v and ~{~^~} specifically)
- inspecting a GF object in slime
What are some of the things that triggered your own Aha! moments? What sort of stuff delighted you when you discovered it? What advice would you give people who want to have more Aha! moments?
Zach Beane <x...@xach.com> writes: > Here are a few things that triggered major Aha! moments for me, in no > particular order.
Oops, I forgot one:
- seeing the output of DISASSEMBLE for the first time (it was on a native-compiling Lisp), and the realization that the functionality is part of standard CL
On 27 Sep 2006 17:12:44 -0400, Zach Beane <x...@xach.com> wrote:
> [snip]
> - inspecting a GF object in slime
> What are some of the things that triggered your own Aha! moments? What > sort of stuff delighted you when you discovered it? What advice would > you give people who want to have more Aha! moments?
- macros of course, in particular, writing a DSL for defining GUI menu hierarchies
- learning what generic functions are and what you can do with them in CLOS (e.g. the different kinds of specializers)
- the MOP (and every MOP-related thread in this newsgroup is making me aware that I'm still hanging onto preconceived notions about OOP)
Zach Beane wrote: > What are some of the things that triggered your own Aha! moments? What > sort of stuff delighted you when you discovered it? What advice would > you give people who want to have more Aha! moments?
I guess "code is data" is the most basic lisp aha! But its implications continue to be sources for many more such aha moments.
For instance, in most other programming languages, new abstractions are built by writing code on /top/ of existing abstractions. But in lisp, its possible to build new abstractions by writing code *beneath* existing code.
Here's an example (in scheme):
(define (square x) (* x x)) (define (power x n) (cond ((= n 0) 1) ((odd? n) (* x (power x (- n 1)))) (else (square (power x (/ n 2))))))
This is a simple function which raises x to the integer power n, with a minimum number of multiplications. (let ((x 5)) (power x 3)) returns 125. Now its possible to make the same piece of code return optimized symbolic output by just writing a new implementation of '*' !
> > Here are a few things that triggered major Aha! moments for me, in no > > particular order.
> Oops, I forgot one:
> - seeing the output of DISASSEMBLE for the first time (it was on a > native-compiling Lisp), and the realization that the > functionality is part of standard CL
> Zach
That got me into lisp actually... few months ago. Downloaded the allegro trial, got a book from a colleague (The Winston & Horn one), put some samples, and one of the first things I did was ... compile, then optimizations, and that bought me. Too bad my daily job is C/C++ coding (game development).
On 27 Sep 2006 17:12:44 -0400, <x...@xach.com> wrote:
> Here are a few things that triggered major Aha! moments for me, in no > particular order.
> - reading Keene's CLOS book
For 20 years, I've successfully avoided OOP, halfway thru Keene, I lusted for CLOS. The next program is the CLOS teaching tool.
> - realizing that file formats and communication protocols are just > bits on disk or on a wire or sometimes even in memory, and Lisp > is pretty good at generating the right bits and octets; inspired
STREAMS! It's all streams, and lisp rocks at that. In-line filters and transforms of the 'data-stream', branching and colalescing, sources and sinks.
> - Aha! moments have made complicated tasks simpler and > unapproachable tasks approachable (given the right amount of time > and effort). They take the magic out of things. (Philip Greenspun
s/magic/fear/ s/things/improbables/
> - Be broadly aware of the tools available, and don't worry about > immediate application
The tough one. It's too easy to code up a solution to a problem, you don't think about distributing the answer, since other lispers can code as solution just as fast.
> What advice would you give people who want to have more Aha! > moments?
Well, :Slime 2005-04-27 is there in my usual Emacs setup - I just don't actively or consciously use it. C-h m shows reports no mode specifics. C-h a slime lists very many slime commands. What Swank is I have no idea.
GP lisper wrote: > Then you've never used slime, it's pretty self-evident. > <goes back to ignoring trolls>
Your logic doesn't quite follow.
Slime is a superior interaction mode, yet it doesn't show up as a mode. How Slime helps with "incremental programming" thus remains a mystery.
Adam <nos...@example.com> writes: > Slime is a superior interaction mode, yet it doesn't show up as a mode. > How Slime helps with "incremental programming" thus remains a mystery.
Then do M-x slime-connect from emacs. Open up a source file. Modify a function and type C-c C-c and the new version is compiled into your enviroment.
Petter
-- A: Because it messes up the order in which people normally read text. Q: Why is top-posting such a bad thing? A: Top-posting. Q: What is the most annoying thing on usenet and in e-mail?
Thanks, Petter. I'll try some things out, as I appear to be under-using its potential, it does seem.
Looking at; http://www.cliki.net/SLIME Features and quickly into; http://common-lisp.net/project/slime/doc/html/ I wouldn't say Slime's operation is very transparent, intuitive or easily-grasped, but then I'm just clicking code into a Lisp application, and evaluating from there. I'm not developing any multipart application.
Oh, and yes, my bad. C-h m does pop up with plenty of Slime commands, several only of which I'm regularly using.
> Then do M-x slime-connect from emacs. Open up a source file. Modify a > function and type C-c C-c and the new version is compiled into your > enviroment.
> Petter
Maybe the Aha moment is, that "incremental programming" is inserting newly-compiled chunks into a running Lisp environment.
Adam <nos...@example.com> writes: > Jack Unrue wrote:
> > [ . . . ]
> > - incremental programming with SLIME
> I don't quite follow, Jack. Would you care to expand a little, or point me > to a URL ?
Slime itself wasn't an aha! moment for me, but ILISP was. The basic revelations for me were that the Lisp system I was interacting with didn't follow the usual cycle of edit, compile+run, test, debug, restart; instead, it was something that had a long life and that accumulated state (in the form of functions and objects), and that gently modifying the state was better than trashing all of it and reloading it from scratch. This isn't something specific SLIME, but SLIME enables it in a very nice way.
(The other nice features like arglist display, inline annotation of compilation notes, the inspector and debugger, etc are great too.)
When I first started using Linux, I accidentally unpacked a nethack tarball in the /dev directory. I had no idea how to see what I had done or how to fix the resulting clutter. So I just reinstalled the system from scratch to get back to a known state. (I would also reinstall when my IP address changed, because I only knew that an installation dialog box prompted for the IP.) This is the same sort of wholesale flushing of state that just isn't necessary if you know how to interrogate your evolving, active system and update it to bring it into the state you need.
I haven't used CLOS's object evolution protocol yet (i.e. update-instance-for-redefined-class, make-instances-obsolete), but the fact that the object system accomodates evolution of state without throwing out progress so far is very encouraging.
On Fri, 29 Sep 2006 01:29:35 +1200, Adam <nos...@example.com> wrote:
> Maybe the Aha moment is, that "incremental programming" is inserting > newly-compiled chunks into a running Lisp environment.
Adam,
Yep, that's what I meant -- my Aha! moment here was finding out how much easier slime makes that style of work. The same is possible with a bare REPL, but a lot less convenient.
GP lisper <spamb...@CloudDancer.com> writes: > > - Be broadly aware of the tools available, and don't worry about > > immediate application
> The tough one. It's too easy to code up a solution to a problem, you > don't think about distributing the answer, since other lispers can > code as solution just as fast.
By this I mean being aware, even superficially, of built-in things like CLOS and its standard protocols, conditions, bit-twiddling functions, format, etc. When the need for a tool arises in the future, it's good that it can tickle your memory ("isn't there something in Lisp related to this?") instead of seeming like a frustrating roadblock.
CL series were an Aha! moment for me. I had studied GPU-based algorithms for a little bit and knew about Brook and Cg and "stream-based computation" but, once again, CL had done it years before :) (The whole "on-line" vs. "off-line" series thing is a pretty good encoding of how languages like Brook express their kernels.)
Adam <nos...@example.com> writes: > I wouldn't say Slime's operation is very transparent, intuitive or > easily-grasped, but then I'm just clicking code into a Lisp > application, and evaluating from there.
watch a bit of that and you'll see some of the stuff SLIME can really do. (warning: big file, long movie)
-- -Marco Ring the bells that still can ring. Forget your perfect offering. There is a crack in everything. That's how the light gets in. -Leonard Cohen
> I haven't used CLOS's object evolution protocol yet > (i.e. update-instance-for-redefined-class, make-instances-obsolete), > but the fact that the object system accomodates evolution of state > without throwing out progress so far is very encouraging.
Any point on how to do it? And another question too: how to redefine generic functions in a living environment to change, for example, the number of arguments, supposing that you have already defined methods to that generic function?
Zach Beane wrote: > What are some of the things that triggered your own Aha! moments? What > sort of stuff delighted you when you discovered it? What advice would > you give people who want to have more Aha! moments?
Several moments about read-time, compile-time and run-time, and what can be done at the different times.
I was delighted about getting to be my own language designer through macros. Even if I don't come up with stuff I like all that often, I still think it's a delightful process. :)
"Javier" <javu...@gmail.com> writes: > And another question too: how to redefine generic functions in a living > environment to change, for example, the number of arguments, supposing > that you have already defined methods to that generic function?
r...@rpw3.org (Rob Warnock) writes: > Zach Beane <x...@xach.com> wrote: > +--------------- > | - learning that CLX is a Lisp program, not a binding to the C xlib > +---------------
> Learning that Eric Marsden's "PG" talks the PostgreSQL socket > protocol directly, and is not a binding to "libpq.so".
Yes! New examples keep coming to my mind, too. Two in particular are Franz's NFS server for Windows and their FTP server. When I first saw them, I couldn't imagine that people might write that sort of software from scratch with Lisp.
Zach Beane wrote: > Adam <nos...@example.com> writes:
> > Jack Unrue wrote:
> Slime itself wasn't an aha! moment for me, but ILISP was. The basic > revelations for me were that the Lisp system I was interacting with > didn't follow the usual cycle of edit, compile+run, test, debug, > restart; instead, it was something that had a long life and that > accumulated state (in the form of functions and objects), and that > gently modifying the state was better than trashing all of it and > reloading it from scratch. This isn't something specific SLIME, but > SLIME enables it in a very nice way.
That is the coolest part of lisp -- but once in a while I find myself after a whole day of hacking wanting to make sure something will work on another machine, and end up restarting lisp (and loading everything afresh) to make sure of that (as it could be some old definition or binding lying around in the environment). Is there an easier way than restarting lisp to do this? One very crude thing might be to blow the symbol table away?
"remixer" <remix...@gmail.com> writes: > That is the coolest part of lisp -- but once in a while I find myself > after a whole day of hacking wanting to make sure something will work > on another machine, and end up restarting lisp (and loading everything > afresh) to make sure of that (as it could be some old definition or > binding lying around in the environment). Is there an easier way than > restarting lisp to do this? One very crude thing might be to blow the > symbol table away?
I tend to have Emacs save any unsaved buffers, start a fresh Lisp, and use asdf to load the system from scratch. Then I patch up any problems that crop up in the running Lisp.
Sometimes I do "scratch" development; I have a small experimental project that is contained in one file, with a defpackage/in-package at the top followed by the code. At the REPL I work entirely within the package. When I want to clean things out, I delete-package the package and reload the file.
Marco Baringer wrote: > http://common-lisp.net/movies/slime.mov > watch a bit of that and you'll see some of the stuff SLIME can really > do. (warning: big file, long movie)
Yep, thanks Marco. I've seen that referred to repeatedly. I really must get a copy somehow - have been putting it off on dialup, but will do !
Zach Beane wrote: > Adam <nos...@example.com> writes:
> > Jack Unrue wrote:
> Slime itself wasn't an aha! moment for me, but ILISP was. The basic > revelations for me were that the Lisp system I was interacting with > didn't follow the usual cycle of edit, compile+run, test, debug, > restart; instead, it was something that had a long life and that > accumulated state (in the form of functions and objects), and that > gently modifying the state was better than trashing all of it and > reloading it from scratch. This isn't something specific SLIME, but > SLIME enables it in a very nice way.
That is the coolest part of lisp -- but once in a while I find myself after a whole day of hacking wanting to make sure something will work on another machine, and end up restarting lisp (and loading everything afresh) to make sure of that (as it could be some old definition or binding lying around in the environment). Is there an easier way than restarting lisp to do this? One very crude thing might be to blow the symbol table away?