学习slime


本来有个stanford的教程,现在打不开了(404),幸好有Clementson老兄转载了下,好东西我要再转一下。


Clementson's Blog


Reposted here:


CL, Music and SLIME Tutorials

Sunday, May 1, 2005

I was listening to Luke Gorrie's presentation at ECLM the other night (both the actual presentation in Emacs Lisp and the bootleg video are available off of Edi Weitz's ECLM page). In it, he mentioned that SLIME was being used in a music course at Stanford University. I googled for that and found out that Fernando Lopez-Lezcano, a Lecturer, Composer and System Administrator at Stanford University is teaching "220b: Synthesis Techniques, Compositional Algorithms, Psychoacoustics and Spatial Processing" at Stanford. The course sounds really interesting, being a mixture of music and Lisp:

"This is the second course in the 220 series. It covers some basic sound synthesis techniques not covered last quarter (see 220a), algorithmic composition techniques, spatialization and some psychoacoustics. The course uses the  CLM-3 (Common Lisp Music) environment to create all sound examples and the Common Lisp programming language (in which clm-3 itself is implemented) for all programming examples. 

Common Lisp Music (CLM) is a public domain sound design language written on top of Common Lisp, currently running in Macintosh PowerPCs, Windows and several UNIX environments including SGI, Sun, NeXT and Linux. 

Evaluation consists of 4 assignments and a final project. Each assignment builds on the knowledge of the previous one, and the final outcome is a final project which is usually a computer music composition. This project is going to be presented during the finals week."
Although the course itself looks pretty neat, there is also some interesting material linked off of the  course description page . In addition to using CLM in the course, Fernando recommends using Emacs and SLIME. Now, for CL afficionados, the combination of Emacs and SLIME is pretty much the de facto Common Lisp development environment (definitely so for open source CL's, but also very popular with users of the major commercial CL products as well); however, it is not an easy combination for CL newbies to get into. One of the nice things about SLIME is that it has so much neat functionality. One of the "not so nice" things about SLIME (at least, from a newbie standpoint) is that the user manual is more of a reference than a way to learn SLIME. However, as part of the first assignment in the course, there is a  SLIME tutorial  that demonstrates some of the basic features of using SLIME! Here are some snippets from the tutorial:
" SLIME

The last software package you need to know about is  SLIME, the "Superior Lisp Interaction Mode for Emacs". SLIME is the system that runs Lisp from within Emacs and does all kinds of wonderful fancy things to integrate your Lisp interpreter with your text editor. The only SLIME documentation we know about is the SLIME user manual, which you can get as a  PDF file from the web. There's also a copy on the CCRMA filesystem at /usr/share/doc/slime-1.0/slime.pdf which you can look at with the Linux "acroread" program. I recommend that you start learning SLIME by following the tutorial below; once you've gotten through that and are comfortable with Emacs then the SLIME user manual will make a lot more sense.

Tutorial
  1. Learn Emacs

    Learn at least enough to move the cursor around, open and save files, follow the instructions below (which are in terms of the "Control" and "Meta" keys), and get out of trouble if you get confused. 

    I recommend the built-in Emacs tutorial or some of the other resources listed above.

  2. Install SLIME 

    You need to add some mumbo-jumbo to a file called ~/.emacs whose purpose is to customize Emacs. 

    emacs ~/.emacs

    Add these lines to that file: 

    ;; slime
    (setq inferior-lisp-program "/usr/bin/cm-cmucl")
    (add-to-list 'load-path "/usr/share/slime")
    (require 'slime)
    (slime-setup)

    Minus 10 points if you retyped those 133 characters into Emacs! I would have done it by selecting that text in the Mozilla window (with left-click and drag), and then pasting it into the Emacs window (with middle-click). 

    Save your .emacs file.
    Quit emacs.
    Start emacs.
    Type <meta>x (meta is the ALT key)
    Type slime<enter>
    Watch slime initialize.

    Cool, huh? OK, quit Emacs again and go back to the Unix terminal.

  3. Make a directory for the course and put some goodies in it 

    Make yourself a directory called 220b, go into it, and make a subdirectory for this tutorial: 

    cd
    mkdir 220b
    cd 220b
    mkdir tutorial

    Make a symbolic link giving you easy access to the CLM instruments we'll use in the course, then copy the fm-violin instrument from there into your tutorial directory, then go into that directory: 

    ln -s /usr/share/common-lisp/source/clm .
    cp clm/v.ins tutorial
    cd !$

  4. Basic Interaction with SLIME 

    Start Emacs, then type M-X slime to start SLIME. You'll see that the Emacs window is now labeled "slime-repl"; that stands for "Read-Eval-Print Loop", meaning that in this window SLIME continuously reads what you type, evaluates it, and prints the result. That's the basic mode of interaction with any Lisp interpreter. 

    Type a number like 234 and hit return. As soon as you hit return, SLIME changes what you typed to bold face to show that it was passed to Common Lisp. Below that, SLIME prints 234 again, this time not in bold. That's the "eval-print" part; it means that (according to Common Lisp) the value of 234 is 234. Deep, huh? 

    Now we'll intentionally cause an error so you can get used to dealing with them. Type "hello" and hit enter. The screen will split in two, with the "slime-repl" window you just typed into at the top, and a new "sldb" window at the bottom. First of all, notice that in the upper window, "hello" is now in bold, showing that it was sent to Lisp, but there's nothing below it, meaning that "hello" has no value, i.e., Lisp was unable to evaluate it. 

    Now let's look at the "sldb" window. I believe this stands for "SLime DeBugger." Unfortunately, like most "debuggers," this one doesn't actually remove your bugs; it just lets you poke around and try to figure out for yourself what the problem was. 

    The most important thing is the error message itself, which came from Lisp: 

    Error in KERNEL::UNBOUND-SYMBOL-ERROR-HANDLER: the variable HELLO is unbound.
    [Condition of type UNBOUND-VARIABLE]

    That word "unbound" appears three times, so it must be important. Indeed, it means that Lisp was trying to interpret something (in this case, "hello"), as a variable but that variable doesn't exist, i.e., there's no value "bound" to it. 

    The next text in the SLDB window is a list of options for "restarts". They're called "restarts" because they're your options for dealing with the error and getting back to work. Sometimes when you make an error you might be able to correct it directly from the SLDB window and then carry on with the rest of what your program was doing. So you're going to see more "Restart" options for other errors. In this case, there are only two: 

    Restarts:
    0: [ABORT] Abort handling SLIME request.
    1: [ABORT] Return to Top-Level.

    To bail out completely, select "Return to Top-Level". This is always a good idea if you want to just start over and try something else; it will take you out of the debugger and back to the normal mode of interaction. Move the cursor to that line and hit enter. Now the SLDB window goes away and you're back to just the slime-REPL window filling the whole screen. Now, below the bold "hello", you'll see this: 

    ; Evaluation aborted

    That's SLIME's way of reminding you that you aborted the evaluation of the expression "hello". You'll see another prompt, so now you're back to the read-eval-print loop. (The semicolon is a comment character.) 

    To finish our tour of the SLDB window, let's cause the same error again but in a different context. Type this: 

    (+ hello 2)

    (By the way, before you hit return, notice that when you type the close parenthesis, the cursor briefly flashed to the corresponding open parenthesis. For complicated Lisp programs this "blink" feature is extremely helpful.) 

    Once again the SLDB window will open, with the same error message and list of two possible restarts. At the bottom of the SLDB window is a section called "Backtrace": 

    Backtrace:
    0: (EVAL HELLO)
    1: (EVAL (+ HELLO 2))
    --more--

    The cursor is on the first of these lines. It's telling you that the immediate context in which the error occured was trying to evaluate the expression HELLO. Below that you can see that Lisp was trying to evaluate the expression HELLO because it was trying to evaluate the expression (+ HELLO 2). You can imagine that this kind of "what was going on when the error occured?" information could be useful in debugging more complicated programs; it's called a "backtrace" because it traces backwards from the error through all the stages of what the program was trying to do when the error occurred. 

    If you hit enter on any of these backtrace lines then you get even more information about what was going on when the error occurred. For this simple example that information isn't very useful, but it's nice to know it's there. 

    You can always type the "q" key to skip out of the debugger. 

    Let's make a different kind of error. Ask Lisp to spell out all the numbers from one to a billion: 

    (loop for x from 1 to 1000000000 do (format t "~R~%" x))

    Well, it's very impressive, but this is obviously going to take too long to complete. So interrupt Lisp by typing C-c C-c, which will take you back to the debugger, where you can abort this program.

  5. Make a sound with CLM 

    Tell Common Lisp to use the CM/CLM/CMN package: 

    (in-package :cm)

    Tell Common Lisp to compile and load the fm-violin instrument that you copied into this directory. (What do I mean by "this" directory? Common Lisp has a notion of the "current" directory, just like the Unix shell. So does Emacs. When you start Emacs, Emacs' current directory is set to the current directory of the Unix shell in which you typed "emacs". Likewise, when you start Common Lisp from Emacs (via SLIME), Common Lisp's current directory is set to Emacs' current directory. So since you were in your ~/220b/tutorial directory when you launched Emacs, and since you didn't change Emacs' current directory before starting SLIME, Common Lisp is "in" your ~/220b/tutorial directory too.) 

    (compile-file "v.ins")
    (load "v.cmucl")

    Invoke the fm-violin instrument: 

    (with-sound () (fm-violin 0 1 440 0.1))

    You should hear a one-second long note with pitch 440 Hertz (A above middle C).

  6. Fancy Interactive SLIME 

    Let's enjoy some of the cool features of SLIME.

    Completion 

    Type only the beginning of a call to fm-violin: 

    (fm

    Now hit the tab key. A new Emacs window named "completions" comes up listing all the Lisp names in the current package (which includes CM, CLM, and CMN) that begin with the letters "fm". Type the next two characters, "-v": 

    (fm-v

    Now hit the tab key again. SLIME knows that everything whose name begins "fm-v" actually begins with "fm-violin", so it automatically filled in the "iolin" then showed you everything whose name begins with "fm-violin". Nice, huh?

    Automatic documentation retrieval 

    Now type space, and an Emacs window pops up at the bottom of the screen listing all the parameters to fm-violin, like this: 

    (fm-violin startime dur frequency amplitude &key (fm-index 1.0)
     (amp-env '(0 0 25 1 75 1 100 0)) (periodic-vibrato-rate 5.0)
     (random-vibrato-rate 16.0) (periodic-vibrato-amplitude 0.0025)
     (random-vibrato-amplitude 0.005) (noise-amount 0.0) (noise-freq 1000.0)
     (ind-noise-freq 10.0) (ind-noise-amount 0.0) (amp-noise-freq 20.0)
     (amp-noise-amount 0.0) (gliss-env '(0 0 100 0)) (glissando-amount 0.0)
     (fm1-env '(0 1 25 0.4 75 0.6 100 0)) (fm2-env '(0 1 25 0.4 75 0.6 100 0))
     (fm3-env '(0 1 25 0.4 75 0.6 100 0)) (fm1-rat 1.0) (fm2-rat 3.0) (fm3-rat 4.0)
     (fm1-index nil) (fm2-index nil) (fm3-index nil) (base nil) (frobber nil)
     (reverb-amount 0.01) (index-type :violin) (degree nil) (distance 1.0)
     (degrees nil) (no-waveshaping nil) (denoise nil) (denoise-dur 0.1)
     (denoise-amp 0.005) &allow-other-keys)

    Of course you don't know what all of these mean yet, but the point is that it's telling you all the possible arguments to fm-violin. The first four, startime, dur, frequency, and amplitude, are regular arguments and must appear every time you call fm-violin. The rest are optional "keyword" arguments. Don't worry about all this detail now, just appreciate the way SLIME is trying to help you. History of expressions sent to Lisp 

    The other thing I love about SLIME is scrolling through previous inputs to Lisp. Get back to a top-level REPL prompt and type M-p. It calls up the "p"revious thing that you sent to Lisp. Each time you type M-p it goes back through the history of what you sent Lisp. M-n goes to the "n"ext one. These are just like C-p and C-n for moving up and down by lines, except that they move up and down by expressions you sent to Lisp. 

    Now type "(w" at a top-level REPL prompt and then M-p. It goes back to the last expression from your history that begins with "(w", which is probably the previous call to with-sound.

    Automatic Indentation 

    Say you want to synthesize a "song" with three notes. You could type them in all on one line, but that's ugly and hard to read: 

    (with-sound () (fm-violin 0 1 440 0.1) (fm-violin 1 1 392 0.1) (fm-violin 2 1 350 0.1)) 

    Instead, type just "(with-sound ()" and then hit return. Notice that SLIME automatically indents your cursor to be underneath the letter "i", so you can see visually that what you're about to type will be inside the body of the call to with-sound. Notice also that what you've typed so far has not turned bold, meaning that it hasn't been sent to Lisp (because it's not yet a complete expression (because the parentheses aren't balanced yet, like this parenthetical comment. 

    Now type the first call to fm-violin on the second line and hit return again. Keep going, and you'll end up with this much more attractive and easy-to-understand formatting: 

    (with-sound ()
     (fm-violin 0 1 440 0.1)
     (fm-violin 1 1 392 0.1)
     (fm-violin 2 1 350 0.1)) 

    Experienced Lisp programmers rarely count parentheses; they rely on Emacs to indent their code properly and learn to read the indentation level to see what's inside what.

  7. Writing Programs in Emacs 

    Split Emacs into two vertical windows with C-X 2. In one window, use C-X C-F to open a new file called mysound.lisp. Because the name of the file you're working on ends in ".lisp", Emacs figured out that you're going to type a Lisp program, and so the mode of that buffer is "(Lisp Slime)". Even though this isn't the SLIME REPL buffer where you talk to Lisp, you'll get a lot of the nice features of SLIME, including paren blinking, automatic indentation, automatic documentation retrieval, and tab completion. 

    Type your own little Lisp program into this buffer, with a call to with-sound and one or more calls to fm-violin. 

    When you're ready to try your program, put the cursor inside it somewhere and type C-M-x. This will send your program to Lisp. If there's an error it will bring up the debugger as before. Otherwise, your program will run, and you'll see the return value (which will probably be the string "test.snd") at the very bottom of Emacs. 

    Another way to run your program is to save the file (C-X s) and then load it into Lisp: 

    (load "mysound.lisp")

    You can also explicitly copy and paste between the buffer that contains your file and the SLIME REPL buffer, M-C-k is super useful, because it cuts an entire Lisp expression (i.e., a complete set of balanced parentheses and everything between them).

  8. Managing Emacs buffers 

    So far we've used many different Emacs buffers: 

        * * slime-repl[1]*, SLIME's interactive read-eval-print loop
        * sldb, SLIME's debugger
        * *completions*, where Emacs listed all the things you might want to type that began with the letters "fm".
        * *Messages*, where SLIME shows you the arguments to functions
        * The buffer in which you're editing the file mysound.lisp
        * Behind the scenes, the buffer *inferior-lisp*, where CMUCL is actually running

    For the most part, SLIME does a good job of popping up these buffers in Emacs windows when you need them, then making them go away when you're done with them. But eventually you're going to have to manage these buffers yourself. I get by with these five commands:

    1. C-x o: move the cursor to the "o"ther window.
    2. C-x 1: Make there be only one window (the one with the cursor in it)
    3. C-x 2: Split the current window vertically into two windows
    4. C-x b: Switch the current window to a different buffer, whose name I will type. (Space does name completion.)
    5. C-x C-b: Show a list of all the buffers (along with some other information like what Emacs mode each one is in, what file is loaded into each one, etc.). Moving the cursor over one and hitting enter loads that buffer into the current window.

    Also, if you click on the name of the buffer (which is in bold at the bottom of a window), it cycles through all the buffers.

  9. Loading and Modifying Programs We Provide 

    This simple program is based on the idea of "forking" a note; at each time step each note becomes two notes, one higher and one lower: 

    violin-forker.lisp 

    Copy this file into your tutorial directory and load it into Lisp: 

    (load "violin-forker.lisp")

    Don't type the whole filename; after the letter "i" hit tab to get filename completion. You don't have to compile it because it's not an instrument; it's just a program that calls the fm-violin instrument. 

    Loading the file into Lisp is not the same thing as loading it into Emacs. What you've done so far is just make Lisp aware of one new function called violin-forker. To look at the file yourself, edit it, etc, you should load it into Emacs with C-X C-F. 

    In your violin-forker.lisp Emacs buffer, scroll down to "Some examples". Evaluate these to run my procedure. 

    I hope you will be inspired to modify the violin-forker function to do something different."
It's nice to see a new university course being taught with CL, Emacs, and SLIME!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值