impromptu – Parerga und Paralipomena http://www.michelepasin.org/blog At the core of all well-founded belief lies belief that is unfounded - Wittgenstein Wed, 10 Feb 2021 18:13:18 +0000 en-US hourly 1 https://wordpress.org/?v=5.2.11 13825966 A new livecoding project: ‘The Musical Code’ http://www.michelepasin.org/blog/2020/11/23/a-new-livecoding-project-the-musical-code/ Mon, 23 Nov 2020 05:58:29 +0000 http://www.michelepasin.org/blog/?p=3446 I’ve started a new livecoding project on Github called The Musical Code, where I’ll be adding experimental musical code/algorithms created the amazing Extempore programming language (as well as it precursor Impromptu).

I have accumulated so much musical-code ideas so I’ve finally resolved to clean it up, reorganise it and publish it somewhere. Github seemed the best option, these days:

Turns out that just the code by itself won’t do it. Especially considering that the environments I use to ‘run it’ (and to make sounds) can rapidly disappear (become obsolete, or get out of fashion!).

Hence there’s a YouTube channel as well, where one can find a screencast recording of each of the ‘musical codes’.

Hope someone will find something of interest in there. Comments and feedback totally welcome!

]]>
3446
Impromptu language documentation back online! http://www.michelepasin.org/blog/2015/05/06/impromptu-language-documentation-back-online/ Wed, 06 May 2015 22:19:14 +0000 http://www.michelepasin.org/blog/?p=2625 For all Impromptu aficionados: a little online application that can be used to search&browse the language documentation: http://hacks.michelepasin.org/impromptu/

Impromptu is a scheme-based OSX programming language and environment for composers, sound artists, VJ’s and graphic artists with an interest in live or interactive programming.

As part of its original website, Impromptu included a wiki containing documentation and examples. Unfortunately the wiki isn’t available online anymore, which is a real shame so the other day I’ve decided to replace it with a simple searchable index of the programming language functions. This is based on the documentation file coming with the latest Impromptu release (2.5); so, in theory, it shouldn’t be too different from the original wiki site.

Screen Shot 2015 05 06 at 23 15 36

For those of you who are new to all of this, it’s worth mentioning that Impromptu is now being superseded by the Extempore programming language.

Extempore is much more solid and feature rich; also, it is less dependent on the OS X platform APIs. Still, many of the original Impromptu scheme functions are still available, so this documentation could turn out to be useful too.

Enjoy!

 

]]>
2625
Building a master volumes UI with impromptu http://www.michelepasin.org/blog/2013/09/15/building-a-master-volumes-ui-in-impromptu/ Sun, 15 Sep 2013 11:53:33 +0000 http://www.michelepasin.org/blog/?p=2401 Based on one of the examples packaged with Impromptu, I wrote a simple function that uses the objc bridge to create a bare-bones user interface for adjusting your audio instruments master volumes.

The script assumes that your audio graph includes a mixer object called *mixer*. The UI controllers are tied to that mixer’s input buses gain value.

The objc bridge commands are based on the silly-synth example that comes with the default impromptu package.

VolumeSLider

Being able to control volumes manually rather than programmatically made a great difference for me. Both in live coding situations and while experimenting on my own, it totally speeds up the music creation process and the ability of working with multiple melodic lines.

The next step would be to add a midi bridge that lets you control the UI using an external device, in such a way that the two controllers are kept in sync too. Enjoy!

P.s.: this is included in the https://github.com/lambdamusic/ImpromptuLibs

 

]]>
2401
A metronome object for Impromptu http://www.michelepasin.org/blog/2013/02/20/a-metronome-object-for-impromptu/ Wed, 20 Feb 2013 01:34:52 +0000 http://www.michelepasin.org/blog/?p=2319 Metronome: a device used by musicians that marks time at a selected rate by giving a regular tick. If you ever felt that you missed a metronome in Impromptu, here is a little scheme object that can do that job for you.

The make-metroclick function returns a closure that can be called with a specific time in beats, so that it plays a sound for each beat and marks the downbeat using a different sound.

Possibly useful in order to keep track of the downbeats while you compose, or just to experiment a little with some rhythmic figures before composing a more complex drum kit section.

Here’s a short example of how to use it:

Make-metronome relies on the standard libraries that come with Impromptu, in particular make-metro, which is described in this tutoriale and on this video. Essentially, it requires you to define a metro object first, e.g. (define *metro* (make-metro 120)).

Here’s the source code:

 

]]>
2319
The new Livecoding Error Hook in Impromptu http://www.michelepasin.org/blog/2011/05/02/the-new-livecoding-error-hook-in-impromptu/ Mon, 02 May 2011 12:25:58 +0000 http://www.michelepasin.org/blog/?p=1099 Impromptu 2.5 has been out for a while now but I’ve never realised it contained this new handy feature: an ‘error hook’:

The interpreter will now throw to an error hook providing you with greater control over exception handling. You initiate the livecoding error hook by calling (sys:livecoding-error-hook #t). Errors are then passed to the *livecoding-error-hook* function – which you may rebind. By default the function simply returns 1 but can be modified for more specialised behaviour.

This is extremely useful, to say the least, if you are performing live and want to avoid situations in which a (stupid) typo or parenthesis error will mess up your entire gig. The error hook in many cases will prevent your looping function from crashing, giving you time to fix the error. Really neat.

Impromptu: livecoding error hook

Here’s an example from the official release notes:

;; turn on livecoding error hook
(sys:livecoding-error-hook #t)

;; with livecoding-error-hook on   
;; this temporal recursion will continue
;; to play the second note even though 'pitch
;; is an unbound symbol
(define loop
   (lambda (beat) 
      ;; symbol a is not bound but loop continues to function
      (play piano pitch 80 1)
      (play piano 63 80 1)
      (callback (*metro* (+ beat (* 1/2 1))) 'loop (+ beat 1))))

(loop (*metro* 'get-beat 4))

;; by redefining the error hook we can provide
;; additional specialisation - such as replacing
;; any unbound symbol with 60!
;; 
;; eval below and both notes will play
;; 'pitch being replaced by 60
(define *livecoding-error-hook* 
   (lambda (msg a) 
      (cond ((symbol? a) 60)
            (else 0))))

Happy (and safer) livecoding!

 

]]>
1099
An alternative to the ‘play’ macro: ‘iplay’ and ‘with-instrument’ http://www.michelepasin.org/blog/2011/03/29/an-alternative-to-the-play-macro-iplay-and-with-instrument/ Tue, 29 Mar 2011 20:17:12 +0000 http://www.michelepasin.org/blog/?p=1008 The other day I was thinking: when I use the play macro in Impromptu [video tutorial], in my head it’s already obvious what’s the virtual instrument I want to play. So why do I have to specify that all the time? Wouldn’t it be more natural just being able to say, for example, get this instrument and now play this and that note with it

Let me clarify this with an example. Let’s set up the standard Apple’s DLS-synth audiounit and the metronome:

(au:clear-graph)
(define dls     (au:make-node "aumu" "dls " "appl"))
(au:connect-node dls 0 *au:output-node* 0)
(au:update-graph)
(au:print-graph)
(define *metro* (make-metro 100))

Now imagine that we want to play some (dumb) melody with Apple’s DLS. We can use the usual play macro to achieve this quite easily (that’s because above we set up the metronome, which is needed in order to use play – check out the docs if this sounds odd to you).

Sequencing a bunch of notes is thus just a matter of sequencing play macros:

(define the-usual-play
   (lambda (beat) 
      (play dls 60 90 1)
      (play dls 64 90 1)
      (play 1/2 dls 72 90 1)
      (play 3/2 dls 67 90 1)
      (callback (*metro* (+ beat (* 1/2 2))) 'the-usual-play (+ beat 2))))

(the-usual-play (*metro* 'get-beat 4))

That’s where I started getting nervous (so to say). Having to write ‘dls’ each time I play a new note seemed to me redundant and illogical; I know that it’s dls the instrument I want to play – I heard my mind screaming – why can’t I focus on the music instead of making sure I type in the instrument name all the time?

Taking advantage of Scheme, the self-modifying language

Luckily though we’re using Scheme, which differently from most other computer languages allows you to change the language grammar as you like, thanks to macros. So here we go, we can create a new macro similar to play that lets you omit the instrument you’re playing. We’ll call it iplay (shortcut for instrument-play, not itunes :-)):

(macro (iplay args)  
   (cond ((equal? (length (cdr args)) 3)
          `(let ((note ,(cadr args))
                 (vol ,(caddr args))
                 (dur ,(cadddr args))
                 )
              (play my-inst note vol dur)))
         ((equal? (length (cdr args)) 4)
          `(let ((offset ,(cadr args))
                 (note ,(caddr args))
                 (vol ,(cadddr args))
                 (dur ,(cadddr (cdr args))))               
           (play (eval offset) my-inst note vol dur)))
         (#t (print "Error: the function only accepts 3 or 4 argument"))))

Essentially what we’re telling the interpreter here is that every time iplay is used, the original play should be called and the symbol my-inst should be passed as the variable representing our instrument. Now we can modify the simple loop defined above like this:

(define the-usual-play-modified
   (lambda (beat) 
      (let ((my-inst dls))
         (iplay 60 90 1)
         (iplay 64 90 1))
      (play 1/2 dls 72 90 1)
      (play 3/2 dls 67 90 1)
      (callback (*metro* (+ beat (* 1/2 2))) 'the-usual-play-modified (+ beat 2))))

(the-usual-play-modified (*metro* 'get-beat 4))

If you run that, you’ll see that this loop sounds exactly the same as the previous one, although the first two play calls are now iplay macro calls. The whole thing works because we introduced a local variable my-inst and bound that to the dls audio instrument (created at the beginning). Notice that the new macro iplay knows nothing about what instrument is playing: it’s just using blindly the my-inst variable, under the assumption that we’ve associated it to a valid audio instrument.

Some more syntactic sugar

The only hassle now is that each time we want to use iplay we are forced to use the (let ((my-inst dls)).. form. Typing this stuff doesn’t feel very natural too. Rather, in my head, I tend to see things like this: get an instrument first, then play a bunch of notes with it.

So, let’s create some syntactic sugar for the ‘let‘ form, by defining another macro, ‘with-instrument‘:

(macro (with-instrument args)
   `(let ((my-inst ,(cadr args)))
       ,@(cddr args)))

As you can see, this macro doesn’t do much: it just rephrases the let form above in a way that is probably more natural to me (and to others too I believe..).

For example, now we can use iplay like this:

(define justatest
   (lambda (beat)      
      (with-instrument dls 
          (iplay 48 40 1)  ;; iplay with 3 args: pitch, vol and dur
          (iplay (random (list 1/2 1/4 1/8)) (random 60 80) 40 1))  ;; 4 arguments: offset
      (callback (*metro* (+ beat (* 1/2 1))) 'justatest (+ beat 1))))

(justatest (*metro* 'get-beat 4))

Finally, let’s remember that because of the way we defined iplay above, we can pass it 3 or 4 arguments: in the first case, the macro assumes that we’re providing a pitch, a volume, and a duration. In the second case instead the first argument is assumed to be an offset value (while the others remain unchanged).

The original play macro can take another argument too: the channel (or midi port). I haven’t included here cause I normally don’t need it, but if you do I’m sure you can fiddle a bit with the code above and make it do whatever you want!

Conclusion: here is the code you need to evaluate within Impromptu if you want to use the with/iplay constructs (all the source code is also available on BitBucket):

(macro (with-instrument args)
   `(let ((my-inst ,(cadr args)))
       ,@(cddr args)))


(macro (iplay args)
   (cond ((equal? (length (cdr args)) 3)
          `(let ((note ,(cadr args))
                 (vol ,(caddr args))
                 (dur ,(cadddr args))
                 )
              ;(print inst beat note vol dur)
              (play my-inst note vol dur)))
         ((equal? (length (cdr args)) 4)
          `(let ((offset ,(cadr args))
                 (note ,(caddr args))
                 (vol ,(cadddr args))
                 (dur ,(cadddr (cdr args))))
           ;(print inst beat note vol dur)
           (play (eval offset) my-inst note vol dur)))
         (#t (print "Error: the function only accepts 3 or 4 argument"))))

Finally.. a ‘pastebin’ function

Also, here is a pastebin function similar to pb:cb (check out this video tutorial if you don’t know what I’m talking about) that returns a template with the with-instrument macro:

(define pb:iplay (lambda (name dur inst) '()))  ;; fake function definition, useful for autocompletion!

;; macro wrapper for pb-iplay
(define-macro (pb:iplay name dur inst . args)
   `(pb-iplay (sexpr->string (quote ,name)) 
              (sexpr->string (quote ,dur))
              (sexpr->string (quote ,inst))
              ,@(map (lambda (expr)
                        (sexpr->string expr))
                     args)))


(define pb-iplay
   (lambda (name dur inst . args)
      (let ((a (apply string-append (map (lambda (e) (string-append "n      " e)) args))))
         (sys:set-pasteboard
         (string-append 
"(define " name "
   (lambda (beat) 
      (with-instrument " inst "
          " a "
     (callback (*metro* (+ beat (* 1/2 " dur "))) '" name " (+ beat " dur ")))))nn(" name " (*metro* 'get-beat 4))")))))



;;;;;;;;;;;;;;;;
;; call it like this: 
;(pb:iplay myloop 1/4 dls)
;;

;;;;;;;;;;;;;;;;;
;; returns: 
;;;;;;;;;;;;;;;;

;
;(define myloop
;   (lambda (beat) 
;      (with-instrument dls
;
;     (callback (*metro* (+ beat (* 1/2 1/4))) 'myloop (+ beat 1/4)))))
;
;(myloop (*metro* 'get-beat 4))
]]>
1008
What is the reaper time in Impromptu? http://www.michelepasin.org/blog/2011/02/07/what-is-the-reaper-time-in-impromptu/ Mon, 07 Feb 2011 11:01:09 +0000 http://www.michelepasin.org/blog/?p=991 I got this info while reading Kontakt 4 documentation, and I thought it was useful to pass it on. It helps understanding the significance of the ‘reaper time’ setting in Impromptu, which I often playing around with without really getting it… (check Reaper stuff on IM mailing list).

Kontakt 4 is an aaward winning sampler from Native Instrument; I was just going through the docs the other day to figure out what it does or doesn’t do and in the section that explain the various ettings parameters I found the description of the ‘latency optimization’ very useful (2.1.2 Latency Optimization [KONTAKT 4 Getting Started – page 11 – get the pdf of the manual here).

The Latency slider controls the size of the playback buffer.

And here is the explanation of that setting:

The load that typical digital audio calculations generate on your processor is often not constant and predictable; parameter changes, additional voices or other processes can all cause mo- mentary peaks in the load, which can result in drop-outs or other audio artifacts if not properly compensated for. That is why audio programs do not send the audio signals they generate directly to the hardware, but write them to a short buffer in memory instead, whose contents are in turn being sent to the actual hardware. This concept allows the program to bridge short irregularities in the stream calculation and thus be more resistant to processing peaks.
Of course, this “safety net” comes at a price–the buffering causes a delay, known as latency, between the triggering of a note and the actual sound. This delay gets longer with increas- ing buffer sizes. Hence, it’s vital to tune the buffer size in order to find a good compromise between latency and playback reliability. The optimal value depends on such diverse factors as your CPU, memory and hard disk access times, your audio hardware and drivers, and your operating system environment.
In order to find the optimal buffer size for your system, we recommend that you begin by setting the Latency slider described in the previous section to a healthy middle value between 384 and 512 samples, then gradually decrease the value during your normal work. When you begin to notice drop-outs, increase the buffer again by a small amount.
Generally, it’s a good idea to have as few other applications as possible running in the back- ground when working with audio software. Also, if you can’t get below a certain buffer size without getting drop-outs, consult the documentation of your audio hardware to find out whether you can access it via an alternate driver architecture, as some architectures allow more efficient low-level access to the hardware than others.

]]>
991
Opening a Finder’s window from Impromptu (alas how to use the applescript bridge..) http://www.michelepasin.org/blog/2011/01/30/opening-a-finders-window-from-impromptu-alas-how-to-use-the-applescript-bridge/ Sat, 29 Jan 2011 23:00:15 +0000 http://www.michelepasin.org/blog/?p=982 Imagine you’ve got a bunch of audio samples you want to load up while livecoding with Impromptu but you can’t remember exactly their names – it’d be handy to be able to open up the corresponding Finder window directly from scheme, without too much clicking around. Do-able or not?

I spent some time trying to figure this out, and the answer is yes! Quite a nice learning experience… although it came with a surprise at the end.

Originally I thought, let’s do it via impromptu’s ObjC bridge. I don’t know much about ObjC but after a bit of googling it seemed evident that the quickest way to accomplish this is by writing ObjC code that, in turns, runs a simple applescript command that opens a window:

 

NSString *s = [NSString stringWithFormat:
     @"tell application "Terminal" to do script "cd %@"", folderPath];

NSAppleScript *as = [[NSAppleScript alloc] initWithSource: s];
[as executeAndReturnError:nil];

 

So I translated the bottom part of the code above into impromptu/scheme:

 

(define run_applescript
   (lambda (script)
      (objc:call (objc:call (objc:call "NSAppleScript" "alloc")
                            "initWithSource:"
                            script)
                 "executeAndReturnError:" )))

 

That is a generic script-running function, that is, you can pass any script and it’ll run it, eg:

 

(define script0 "
   tell application "Finder" to open folder "Macintosh HD:Users"
   tell application "Finder" to activate"
)

(define script1 "
   tell application "Terminal" to do script "cd ~; open .""
)

(define script2 "
                tell application "System Events"n
                tell dock preferencesn
                set properties to {autohide:false}n
                end telln
                end tell"
)

;; finally, let’s choose randomly one of the scripts above and run it
(run_applescript (random ‘(script0 script1 script2)))

 

Now, back to the original problem: in order to open a Finder’s window at a specified location we need to pass the location variable to our function run_applescript; also, we want to be able to pass unix path expressions (eg ‘/Users/mike/music/’), so we’ve got to transform that path syntax into the semicolon-delimited macintosh syntax (“Macintosh HD:Users:mike:music”) needed by the applescript function we’re using. That’s easily done with string-replace, so here we go:

 

(define open_finder_at
   (lambda (location)
      (let* ((llocation (stringreplace location "/" ":"))
              (script (string-append "tell application "Finder" to activate open folder "Macintosh HD" llocation """)))
         (objc:call (objc:call (objc:call "NSAppleScript" "alloc")
                               "initWithSource:"
                               script)
                    "executeAndReturnError:" ))))

(open_finder_at "/Users/me/")

 

That’s pretty much it really… now we can easily open OsX Finder’s windows from within Impromptu.

But as I said above, there’s a surprise: after getting this far I thought I’d search impromptu’s mailing list for more examples of obj:call …. and guess what, there’s already a system function that runs applescripts, it’s called sys:run-applescript !

Too bad, it’s been a rewarding learning experience anyways…

 

]]>
2188
Impromptu 2.5 released http://www.michelepasin.org/blog/2010/10/13/impromptu-2-5/ Wed, 13 Oct 2010 15:41:12 +0000 http://www.michelepasin.org/blog/?p=858 Screen shot 2010-10-13 at 16.39.24.png

Good news for livecoders: a new version of Impromptu is available (direct link to the 2.5 dmg package).

Apart from various bug fixes, it looks like as if the major development is the ICR (impromptu compiler runtime), a new set of scheme functions that facilitate the creation of faster bytecode, so that computationally-intensive tasks such as real time audio processing or open-gl can perform more efficiently.

The new compiler is a far more robust and serious attempt at providing low level, but completely dynamic programming support within the Impromptu ecosystem. It is designed for situations which require low-level systems style programming. Two primary examples are audio signal processing and opengl programming – both of which require the production of highly efficient code. While attempting to achieve runtime efficiency the ICR also tries to maintain Impromptu’s love of all things dynamic and is designed to coexist with the rest of Impromptu’s infrastructure (Scheme, Objective-C, AudioUnits etc..).

It is important to state from the outset that the new Impromptu compiler is NOT a scheme compiler. It is really its own language. This language looks like scheme (sexpr’s and alike) but is in many ways semantically closer to C (a nice functional version of C :-). This is because the ICR is designed for purposes that are not suitable for the standard scheme interpreted environment. Low level tasks that require efficient processing – such as audio signal processing, graphics programming, or general numerical programming.

Unlike Scheme the Impromptu compiler is statically typed. You may not always see the static typing but it is always there in the background. The reason that you won’t always see the typing is that the compiler includes a type-inferencer that attempts to guess at your types based on static analysis of your code. Sometimes this works great, sometimes it doesn’t. When things fail, as they surely will, you are able to explicitly specify types to the compiler.

A big thanks to Andrew Sorensen for keeping up (and free) this great work!

]]>
858
Learning resources about Scheme http://www.michelepasin.org/blog/2010/08/10/learning-resources-about-scheme/ Tue, 10 Aug 2010 17:27:17 +0000 http://www.michelepasin.org/blog/?p=808 3eangz5w.jpg

So you’ve decided to know everything about scheme and rock the world using fast-paced programming environments like Impromptu.
Well, I confess I did think that on several occasions, but still I haven’t made it even half way through the schemer pilgmim’s path. But I’ve collected quite a few useful resources in the process, and those I can certainly share!

So in what follows I’ve put together a list of learning resources about Scheme that I found useful.. First off, two links that might be useful in all situations:

  • Little Scheme, an online interpreter that you can use for testing things out while you’re on holidays
  • Schemers.org, semi-official website containing news and lots of links to other resources
  • Now, why don’t we start with the definition offered by the self-regulating wikipedia collective intelligence? Here we go:

    Scheme is one of the two main dialects of the programming language Lisp. Unlike Common Lisp, the other main dialect, Scheme follows a minimalist design philosophy specifying a small standard core with powerful tools for language extension. Its compactness and elegance have made it popular with educators, language designers, programmers, implementors, and hobbyists, and this diverse appeal is seen as both a strength and, because of the diversity of its constituencies and the wide divergence between implementations, one of its weaknesses

    If this blurb hasn’t made you proud of learning such a slick language, you’ll surely find more interesting ideas in what follows. I divided up the list in two sections, generic learning materials about scheme, and tutorials about specific topics (for now, only macros are included).
    ———————————-

    1. Learning Resources About Scheme:

  • Scheme for Common Lispers, article

    The Scheme dialect of Lisp was created in 1975 by Guy Steele and Gerry Sussman to explore ideas in programming-language semantics. They showed that a powerful language can be made “not by piling feature on top of feature, but by removing the weaknesses and restrictions that make additional features appear necessary”. Scheme pioneered lexical scope in Lisp, first-class continuations, and tail recursion, and more recently added an advanced macro system. It’s the best-known Lisp dialect after Common Lisp (which it influenced).
    This note summarizes the differences from CL that might slow down a CL programmer trying to read a Scheme program; people without a CL background, or wanting to write programs of their own, should see the references.

  • the Schematics Scheme Cookbook

    The Schematics Scheme Cookbook is a collaborative effort to produce documentation and recipes for using Scheme for common tasks. See the BookIntroduction for more information on the Cookbook’s goals, and the important ContributorAgreement statement.

  • Harvey, Wright, Simply Scheme: Introducing Computer Science, 1999 MIT press [a classic]

    Symbolic programming is one aspect of the reason why we like to teach computer science using Scheme instead of a more traditional language. More generally, Lisp (and therefore Scheme) was designed to support what we’ve called the radical view of computer science. In this view, computer science is about tools for expressing ideas. Symbolic programming allows the computer to express ideas; other aspects of Lisp’s design help the programmer express ideas conveniently. Sometimes that goal comes in conflict with the conservative computer scientist’s goal of protection against errors.

  • Felleisen, Findler, Flatt, Krishnamurthi, How to Design Programs An Introduction to Computing and Programming, MIT 2001

    [..] programming is more than just a vocational skill. Indeed, good programming is a fun activity, a creative outlet, and a way to express abstract ideas in a tangible form. And designing programs teaches a variety of skills that are important in all kinds of professions: critical reading, analytical thinking, creative synthesis, and attention to detail.
    We therefore believe that the study of program design deserves the same central role in general education as mathematics and English. Or, put more succinctly, everyone should learn how to design programs.
    On one hand, program design teaches the same analytical skills as mathematics. But, unlike mathematics, working with programs is an active approach to learning. Interacting with software provides immediate feedback and thus leads to exploration, experimentation, and self-evaluation. Furthermore, designing programs produces useful and fun things, which vastly increases the sense of accomplishment when compared to drill exercises in mathematics. On the other hand, program design teaches the same analytical reading and writing skills as English. Even the smallest programming tasks are formulated as word problems. Without critical reading skills, a student cannot design programs that match the specification. Conversely, good program design methods force a student to articulate thoughts about programs in proper English.

  • Dybvig, The Scheme Programming Language, 2003MIT press

    This book is intended to provide an introduction to the Scheme programming language but not an introduction to programming in general. The reader is expected to have had some experience programming and to be familiar with terms commonly associated with computers and programming languages. The author recommends that readers unfamiliar with Scheme or Lisp also read The Little Schemer [see below]to become familiar with the concepts of list processing and recursion. Readers new to programming should begin with an introductory text on programming.

  • Nils M Holm, “Sketchy LISP” [you can download the book here Update 08/12: this book has become ‘Sketchy Scheme’ and is now for-sale here]

    Sketchy LISP is a step-by-step introduction to functional programming in Scheme. It covers various aspects of the language including data types, conditional evaluation, list processing, lexical scoping, closures, recursion, dynamic typing, etc. By means of numerous examples of varying complexity, it takes the reader on an entertaining and informative tour through the language.
    The Scheme language achieves what only few languages have managed before: to bring fun back to programming. Its simple syntax, clean semantics, and powerful functions open the door to a fresh perspective on program design. Programming in Scheme is fun, and this book is an attempt to share some of that fun.

  • Friedman and Felleisen, The Little Schemer, 1996 MIT press

    The goal of this book is to teach the reader to think recursively. Our first task, therefore, is to decide which language to use to communicate this concept. There are three obvious choices: a natural language, such as English; formal mathematics; or a programming language. Natural languages are ambiguous, imprecise, and sometimes awkwardly verbose. These are all virtues for general communication, but something of a drawback for communicating concisely as precise a concept as the power of recursion. The language of mathematics is the opposite of natural language: it can express powerful formal ideas with only a few symbols. We could, for example, describe the entire technical content of this book in less than a page of mathematics, but the reader who understands that page has little need for this book. For most people, formal mathematics is not very intuitive. The marriage of technology and mathematics presents us with a third, almost ideal choice: a programming language. Programming languages are perhaps the best way to convey the concept of recursion. They share with mathematics the ability to give a formal meaning to a set of symbols. But unlike mathematics, programming languages can be directly experienced—you can take the programs in this book and try them, observe their behavior, modify them, and experience the effect of your modifications.

  • The Weiner Lectures Archives [various videos, but not complete lectures unfortunately]

    The goal of this project is to make knowledge of computer science easily available not only to the students at Berkeley, but also to the entire community. For several years, faculty members have been videotaping lectures in CS large lower division courses, mainly as an aid to students with time conflicts that prevent them from attending lectures. By hosting an archive storing all CS lectures that were recorded, we hope the computing knowledge that has been gathered can be easily shared. As a teaching aid, a ‘greatest hits’ lecture will also be compiled for each course covering all major topics addressed in the corresponding class. The best parts of many different past lectures will be linked together and presented along with slides to make this greatest hits lecture. This lecture should represent the best teaching abilities in the lower division CS lectures and should be a valuable resource in the computer community for basic CS knowledge. Thanks to the generous donation of Larry Weiner this online site should become a permanent resource.

  • ———————-

    2. Specific topics:

    On Macros and metaprogramming:

  • The art of metaprogramming, Part 1: Introduction to metaprogramming, IBM developer works

    Summary: One of the most under-used programming techniques is writing programs that generate programs or program parts. Learn why metaprogramming is necessary and look at some of the components of metaprogramming (textual macro languages, specialized code generators). See how to build a code generator and get a closer look at language-sensitive macro programming in Scheme.

  • Lisp Macros — How to Define Entirely New Languages in Lisp

    This is a very interesting lesson if you want to deeply understand Lisp, and some very deep things about programming, but it’s also entirely optional; We suggest that you do through it, but not worry too much about understanding it in detail. If you get very deeply into programming, you’ll find that Lisp macros are an amazing tool, but they are also somewhat mind-bending, and used rather rarely in simple programming. So, feel free to skip this lesson, or at least, if you do study it, let it flow over you, and maybe come back to it later on if you find yourself wanting to know more about some of the deep and subtle reaches of Lisp programming.

  • Scheme FAQ Macros, on schemewiki.org
  • Sources for learning about Scheme Macros: define-syntax and syntax-rules, a thread on StackOverflow
  • A scheme syntax rules primer, an interesting blog post
  • ———————-

    That’s all for now… I’ll be adding more stuff as I run into it!

    ]]>
    808