TweetFollow Us on Twitter

MCL
Volume Number:9
Issue Number:1
Column Tag:Tools of the trade

Macintosh Common Lisp

MCL - a powerful development environment often overlooked by Macintosh programmers

By Michael S. Engber, The Institute for the Learning Sciences, Northwestern University

Abstract:

Macintosh Common LISP (MCL) is a powerful development environment which is often overlooked by Macintosh programmers. This article will show why you should consider using MCL, and explore some of the ways it can enhance your productivity. Prior LISP or MCL experience is not assumed.

This article is aimed at the typical Mac developer who uses C or Pascal. I am going to try to avoid arguing the general merits of LISP versus other programming languages. There is already plenty written on this topic. Instead, I will emphasize aspects of MCL and LISP most relevant to Mac development.

Languages are a religious issue among programmers and opinions about LISP are even more polarized than most. So I would like to apologize in advance for the editorial and first person comments, but one of my purposes is to get you to overcome any prejudice you have and take a closer look at Macintosh Common LISP. I could present just the cold facts, but that is not likely to be any more informative than reading the manual.

“LISP, doesn’t that stand for Lots of Infernal Stupid Parentheses?”

If you are like most programmers, you probably regard LISP as a toy language, something you used years ago to do a few AI assignments. You were probably fluent in Pascal or C at the time, so LISP was an obstacle which made otherwise simple programs more difficult. That was certainly my experience. At the University of Wisconsin, we had a cluster of thirty or so Xerox Dandelions whose CRTs put out enough heat to keep the lab at 90 degrees in the dead of winter. Apart from Phys. Ed., Intro to AI was the only course which required changing into a t-shirt and shorts. Ignoring the physical environment, just the simple act of logging in took forever. Using the editor was difficult at best; and as for saving your files, don’t even ask.

So, if you already have a bad taste in your mouth from LISP, let me start by assuring you that MCL is very easy to use. A novice can write “hello, world” faster in MCL than in any other Mac development environment - even THINK Pascal. All one has to do is type (print “hello, world”) and hit return. There are no libraries to include and no compilation scripts to run. Just type in the code and let MCL evaluate it.

On the surface, the editor looks pretty much like any other Mac text editor. In addition, it has an addictive code formatting command, an EMACS mode for EMACS fans, programming hooks from LISP so you can customize it to do anything you please, and a variety of LISP specific niceties. The compiler is editor aware, allowing you to select a section of code and execute it with a keystroke. MCL provides a variety of development tools including a stepper to let you execute your code one line at a time, and a backtrace tool that lets you explore the LISP stack (annotated and readable - not MacsBug style) after an error occurs.

MCL comes with an object library that supports the standard user interface elements. It offers all of the familiar benefits of object oriented user interface code. dI will forego the gratuitous examples of how to put up a dialog box, attach an action to a menu, or customize a dialog item. Given the widespread use of MacApp, I do not think the details of how you do this in MCL would be very enlightening.

Before going on, I would like to tackle that classic LISP objection.

“Isn’t LISP slow?”

First, LISP is not an interpreted language by definition. LISP can be compiled into efficient code. That is how MCL normally evaluates expressions. It compiles the expression and then executes the compiled code. This process is so fast that you will probably think it is interpreting the expression.

Second, this question really needs to be directed at a particular LISP implementation rather than at LISP in general. It is true that there are aspects of LISP (dynamic linking, for instance) that introduce runtime overhead that you do not have in C or Pascal, but the actual effect is less than most people imagine.

It is almost pointless to talk about speed without reference to a particular piece of code or algorithm. In addition, speed-critical sections of code comprise only a small fraction of most applications. I wish I could end the discussion here by just saying that MCL is generally fast enough to get the job done, but I do not imagine the skeptics will be satisfied unless I say more.

I am going to try to divide and conquer the issue by addressing it in three parts: the user interface, the development cycle, and general execution speed. I will attempt to make some meaningful generalizations about the first two, and I will wave my hands a bit at the third.

User Interface Speed

A user’s impression of speed is strongly influenced by the user interface. Does it scroll quickly? Do buttons highlight immediately when hit? Does dragging keep up with the mouse? Fortunately, this paper is focused on Mac programming, so I can also argue that this is what most of your code is devoted to.

MCL definitely excels when it comes to writing user interface code. I have implemented a variety of widgets and graphic effects in MCL, including: PICT buttons, draggable dialog items, image dissolves, animation, on-screen video, and even an MDEF. In fact, MCL’s own user interface is written using MCL’s object library. Speed is not a problem. No one is going to be saying, “Boy, these dialog items take forever to draw,” or “These buttons are sure sluggish.”

This should come as no surprise since the ToolBox, especially QuickDraw, does most of the work. However, even the simple act of pressing a button involves more than just ToolBox calls. MCL detects the mouse down event and determines which window object should handle it. The window object has to determine which of its sub-views was hit. Views can be nested so this step recurs until we bottom out at the dialog item. The dialog item then highlights itself and begins tracking the mouse. It is important to point out that MCL’s object system is implemented efficiently enough not to interfere with performance.

Development Cycle Speed

The speed of the compile/link/run cycle is important in evaluating a development environment. This is the biggest advantage that the THINK compilers have over MPW and probably one of the bigger complaints among MPW users. With dynamic linking, MCL excels in this area. The bigger the project, the more pronounced MCL’s advantage becomes. The ability to recompile just the function you changed is hard to beat.

For developers, this will turn out to be the biggest advantage of using MCL. The effect has to be seen to be believed. This is discussed further in the section on dynamic linking.

General Execution Speed

The best I can do is assert that MCL is fast enough for most purposes. If you are doing computationally intensive stuff, there is bound to be some code that just will not run as fast as you want - probably the same code you find yourself wanting to hand code in assembly language.

Keep in mind that it is easier for novices to write inefficient code in LISP than in other languages. What I mean by inefficient is more serious than just calculating the same value twice; I mean turning an O(N) algorithm into an O(N2) algorithm (in time or space). This is hard to illustrate without getting into the details of LISP, but if you come up with an example of something that is really fast in C, yet your LISP version is slow as molasses, odds are it is the way you implemented it in LISP, not the LISP compiler.

Currently, MCL is slow in dealing with double floats. This is a black mark if you’re doing high-precision numerical analysis. This is strictly an implementation issue, not something inherent in LISP. It is reasonable to expect improvement in future releases.

Before you can really say anything definitive on speed, you have to try out MCL for your particular needs. In general, I think you will be pleasantly surprised.

What LISP/MCL/CLOS offers over more traditional languages

Dynamic Linking

Many programmers have a hard time understanding what the big deal is about dynamic linking. “Sure, there is this new thing from Apple called Dinker. It lets you do dynamic linking of MacApp classes, but doesn’t that just make it easier to distribute optional code modules for your product? Big deal.”

In MCL, dynamic linking means being able to modify and add code continuously, even while your code is running. Say you are testing your program, you pull down a menu and it does not do what you expect. Maybe the code executed is totally bogus and generates an error. You locate and edit the function associated with that menu item’s action. You hit the enter key to recompile that one function. The compilation only takes a second. Then you try the menu again. Notice that your program has continued to run the whole time. This is the development cycle in MCL - you test and repair as you go along.

Dynamic linking encourages changing programs in small increments, testing each change before going on. In theory, that’s how you are supposed to develop software. The long compile/link/run turnaround time in most development environments discourages this, especially when the program gets big.

For example, the above menu scenario played out using MacApp and C++ would have taken minutes instead of seconds.

I do not think you can fully appreciate dynamic linking until you use it. If you have written scripts in HyperCard, you have had a taste of what dynamic linking offers. The ease with which you can try code out is very addicting. Once you get used to it, you will not want to go back.

Macros

A macro in LISP is far more powerful than a #define is in C. Their syntax is much richer and you have the full LISP language available at macro expansion time.

As a common example from Mac programming, consider changing the drawing state of the current port, doing some drawing, and restoring the drawing state. It is pretty simple to do, but it clutters up your code and It is easy to make a mistake. Using macros improves your code’s legibility and reliability with no cost at runtime.

Here are two simple examples. The first executes its body with the clip region temporarily changed. The second temporarily alters the pen state.

[1]
(with-clip-rgn some-rgn
 statement1
 statement2
  )
(with-text-state ( :txMode #$srcBic
 :txFace #$italic)
 statement1
 statement2)

This second form expands into the code shown in Figure 1. It looks nasty, but this is essentially the same code you would have to write in any language. In LISP you never see this mess unless you choose to expand the macro. In addition, there is no way to forget one of the steps. It is also worth pointing out that with-text-state accepts keywords for text font and size, but since they were not used in this case, code was not generated to save and restore them.

Here is a brief list of some more interesting with-xxx macros along with the changes they temporarily affect:

with-locked-GWorld

Locks the specified GWorld’s pixels.

with-purgeable-resource

Loads the specified resource and makes it non-purgeable.

without-res-load 

Turns resource loading off.

with-QDProc

Installs custom QuickDraw bottlenecks

with-res-file

Makes the specified resource file current. Takes keyword options to specify what to do in special casessuch as: file is not open, file does not exist, file does not have a resource fork.

Error Cleanup

The unwind-protect LISP form allows you to guarantee a certain section of code will execute, even if an error occurs. This is useful for all sorts of things like ensuring a file will be closed, restoring the current port, and disposing a handle. Most of the with-xxx macros previously presented expand into unwind-protect forms to ensure the changes they make will be undone. A typical use might be to ensure the disposal of a temporarily created region.

[2]
(let ((rgn (#_NewRgn))
 (unwind-protect
 (progn
 ;misc rgn calculations
 (#_FrameRgn rgn))
 (#_DisposeRgn rgn))

Multiple Inheritance

I know there are those who believe multiple inheritance is as evil as using goto statements, but I disagree. Not having it sometimes leads to clumsy and awkward class design. MacApp ended up introducing adorners to view drawing because it did not have multiple inheritance to take care of the problem properly. There are times when multiple inheritance is the most direct and elegant solution.

For example, in MCL I have a class that handles dragging a dialog item around. If I want to make a draggable button, I create a dialog item that inherits from button and draggable. If I want to make an icon draggable, I create one that inherits from icon and draggable. No extra code is written apart from specifying draggable in their class inheritance lists. Without multiple inheritance you end up writing a special dragging method for each dialog item class. Isn’t one of the points of object oriented programming to avoid duplicating code?

At this point someone will point out that I could put all the dragging code in the view which contains the items. I would argue that each class should handle dragging itself so it can easily customize the way it drags. This type of back and forth can continue endlessly. Let me end it here by saying that the Common LISP Object System (CLOS) supports multiple inheritance. I find it simplifies my code. If you do not want to use it, you do not have to.

Modest Development System Requirement

Since MCL applications are a bit large in terms of disk and memory space, you might mistakenly assume MCL itself is a major resource hog. MCL works adequately in its default 3M memory partition. At first glance, this may not sound modest, but remember there are no additional memory requirements. The partition is shared among the compiler, editor, debugger, and your code. As for disk space, the MCL compiler and libraries take up under 5M of disk space. This is about the same as Think C and significantly less than MPW. It’s feasible to use MCL on a 4M PowerBook 100. The same cannot be said for MacApp which would not even fit on the 20M hard drive.

Embedded Languages

Many of the high-end spreadsheets, communication packages, and word processors provide pseudo-programming languages for their “power users.” Most of these languages are poorly designed and a nightmare to use. Ever try using Excel’s macro language? Applications written in LISP get the full LISP language and all its debugging tools for free. On other (non-Macintosh) platforms there are popular LISP-based products, such as AutoCad and Interleaf, which take advantage of this.

If you do not think your users will like LISP’s syntax, it is easy to write your own language using LISP. You just have to do enough to translate the user’s source into LISP and you are done. Language design is one of the classic applications for LISP, so LISP has many features that make this easy to do.

Bignums, Fractions, and Complex Numbers

In addition to the numerical types you find in other languages, LISP provides an assortment of more exotic types. Bignums are integers which can be of any size. Fractions are rational numbers like 2/5 (i.e., no round off error, 7 * 1/7 equals 1 exactly). LISP even supports complex numbers. Needless to say, all the standard library functions operate correctly on any type of number they are passed.

I know I said I would not get into issues not directly related to Mac programming, but MCL has a really impressive implementation of these types. It is hard to resist showing off MCL computing 1000 factorial. Consider this simple definition of factorial:

(defun fact (x)
 (if (<= x 1) 1 (* x (fact (- x 1)))))

It computes 1000!, a 2568 digit number, in 1.2 seconds on an SE/30 and less than half a second on a IIfx.

You might ask, “Of what practical value is this?” Try implementing the RSA public key encryption algorithm. You need to do computations like raising xy mod z where x, y, and z are 100 digit numbers. I used MCL to implement RSA along with the Solovay and Strassen prime test so I could generate 100 digit primes to use as keys. The point is, if your job was to implement RSA, you would have the entire algorithm up and running in MCL long before you even got two 100 digit numbers multiplied together in C.

Is MCL of any practical use to developers?

I see three ways Mac developers can view MCL: as a delivery platform, as a prototyping environment, and as a Toolbox exploration environment.

MCL as a Delivery Platform

Yes, it is feasible to deliver software written in MCL, but do not count on using it to write 50K utilities. MCL is suitable for delivering large applications. It creates stand-alone applications by dumping an image of LISP memory to disk. These applications are big, starting at 1.5M and requiring a 2M RAM partition to run.

As your code grows in size, the application size does not really increase that fast. A typical LISP application might take up 4M on disk. However, RAM needs can go up more quickly. It is hard to make meaningful generalizations about RAM requirements. They are driven by application specific things such as how many GWorlds you use and how many PICT handles you keep around, but it is not too unusual for a good-sized LISP application to require a 4M or 6M partition.

Before you hurl, take a look at the sizes and memory requirements of some of the high-end graphics programs and word processors. You will see that MCL’s requirements are comparable.

Do not make the mistake of extrapolating that your application will quickly grow to requiring 100M of RAM. Once you pay the initial overhead, you are over the hump. Doubling the functionality of your program does not double the size or memory requirements. All that user interface code is already there and can be reused. If this argument sounds familiar, you have probably heard it given in the early days of MacApp when people complained about its overhead.

MCL as a Prototyping Environment

I am sure the term prototyping strikes fear into the hearts of many programmers. It probably brings back memories of writing a quick demo in HyperCard only to find yourself hacking it into a bigger and bigger mess because there was never enough time to go back and do a total rewrite in Pascal.

With MCL you are not going to run into the same roadblocks you do with HyperTalk. LISP is a fully developed programming language; you will not find yourself wishing for data structures. MCL gives you access to the Toolbox, so you will not have to extend the language with XCMDs. You can take your prototypes as far as you want, even turning them into a finished product.

I will not claim that MCL is as easy to use as HyperCard, but a novice LISP coder will be able to get working dialog boxes and menus up in an afternoon. He will not have to learn MPW, know what resources are, nor what a handle is.

MCL as a Toolbox Exploration Environment

I find the best way to read “Inside Macintosh” is with MCL up and running so I can try things out as I go along. MCL lets me evaluate the Toolbox call without my having to build a supporting program.

Why is this such a big win? How many hours have you wasted because you wrote a bunch of code only to throw it out because a Toolbox call does not work the way you thought it would? Sometimes this is due to a poor description in “Inside Macintosh,” other times the Toolbox is so complex that it defies written description. The solution is to try things out; but because it’s so painful, most programmers don’t. You have to create a project, write code to put up a window, make your Toolbox call, convert your results into strings, and write code to print the strings. In MCL, all you have to do is make the call and use standard LISP i/o primitives to print the results.

Here’s an example. Have you ever looked at the description of PBGetVInfo? It is nasty. If ioVolIndex is positive, it does one thing. If it is zero, it does another. If it is negative, it does yet another. By the time you are done reading it, you cannot even remember what you originally set out to do. In MCL you can try the call with three different values for ioVolIndex in less time than it takes to reread the description. Better yet, you can be confident you got it right. You won’t be saying to yourself, “I’ll try this for now, but if my code doesn’t work I’ll have to remember to come back here again.” Or, “Should I take the time to make sure this call works in all cases? Nah.”

Using MCL to explore the ToolBox

Of the three uses I have presented, Toolbox exploration is the only thing I can demonstrate quickly. Certainly, the biggest gains to be made from MCL come from using it as your implementation language, but it would be tough to demonstrate that in a short example and without first teaching you some LISP.

So in this section, I will scratch the surface of MCL’s power by showing how easy it is to access the Toolbox. Even if this is all you ever use MCL for, it will be well worth the price. The examples I will present are taken from the development of a freeware utility, Save A BNDL, which I recently released. Save A BNDL was prototyped in MCL and then translated to Think C for compilation into a 15K application.

Save A BNDL installs a file’s BNDL information into the Finder without requiring rebuilding the desktop or rebooting. It uses the desktop database, the Process Manager, System 7 File Manager calls, and Apple Events. These are all things I had never done before, so of course I immediately got out MCL and tried them.

The code that follows is what I used to explore the desktop database. Initially, the code is straightforward, but one quickly realizes there are far more subtleties to the desktop database than “Inside Macintosh” would lead one to believe. MCL made this exploration process much less painful than it might have been.

But First, Some Basic Syntax

Even if you do not know LISP, you should be able to get the gist of this example code. In fact, knowing LISP might even be a hindrance since this code uses MCL extensions to access the Toolbox. Here are a few things you should know.

• LISP symbols are not limited to alpha-numeric characters as they are in most languages. For example, %stack-block is a legal function name.

• Function calls are made using the syntax:

(function-name arg1 arg2 )

• Trap calls look like function calls, but they begin with #_

• LISP data is not in the same format as Toolbox data. The fact that LISP integers can be 100 digits long may have tipped you off that they are not simply stored as 32 bits. This means that data passed to the Toolbox must be allocated and retrieved in a special way. Table 1 covers what you need to know for the purposes of this article.

Table 1 - Access to ToolBox Data from MCL

Example Explanation

(rlet ((pb :DTPBRec rlet declares and initializes a Pascal style record. The

:ioNamePtr (%null-ptr) example declares pb of type DTPBRec and initializes two

:ioVRefNum 0)) of its fields.

(%stack-block ((buf 200)) %stack-block declares an untyped variable and allocates space on the stack for it. The example binds buf to 200 bytes.

(with-pstrs ((fn "HD:TeachText")) with-pstrs declares and initializes a Pascal style string. The example declares fn to be string containing a full pathname.

(pref pb :DTPBRec.ioDTRefNum) pref references a field of a Pascal style record. The example returns the ioDTRefNum field of a DTPBRec variable.

(%get-text buf 10) %get-text returns a LISP string created by using the specified bytes of memory as ASCII code. The example returns a 10 character string created from the memory pointed to by buf.

And now, for the code

Start by using PBDTGetPath to get the reference number of the desktop database.

[3]
(rlet ((pb :DTPBRec
           :ioNamePtr (%null-ptr)
           :ioVRefNum 0))
  (#_PBDTGetPath pb)
  (pref pb :DTPBRec.ioDTRefNum))
Æ 754

Create a global variable for the desktop database reference number so we can refer to it symbolically.

(defvar *DTDB-refNum* 754)
Æ *DTDB-refNum*

Try out PBDTGetComment which returns the Finder comment associated with a file.

[4]
(with-pstrs ((fn “HD:ResEdit”))
  (%stack-block ((buf 200))
    (rlet ((pb :DTPBRec
               :ioNamePtr  fn
               :ioDTRefNum *DTDB-refNum*
               :ioDTBuffer buf
               :ioDirID    0))
      (when (zerop (#_PBDTGetComment pb))
        (%get-text buf (pref pb :DTPBRec.ioDTActCount))))))
Æ “wow! what a useful comment”

A quick check with the Finder’s Get Info command verifies it is the correct value.

PBDTGetIconInfo returns the file type, icon type, and icon size of icons entered in the desktop database for the specified creator, in this case ResEdit. It is an indexed call. You make it repeatedly until it returns afpItemNotFound.

[5]
(rlet ((pb :DTPBRec
           :ioDTRefNum    *DTDB-refNum*
           :ioIndex       1

           :ioTagInfo     0
           :ioDTReqCount  1024
           :ioFileCreator “RSED”))
   ;format is roughly equivalent to a printf in C
   (format t “~%~2@a: ~s  ~3@s   ~4@s~%” #\# ‘type ‘icon ‘size)
   (loop
    ;break on error or when afpItemNotFound is returned
    (unless (zerop (#_PBDTGetIconInfo pb)) (return (pref pb :DTPBRec.ioResult)))
    (format t “~2@s: ~s  ~3@s   ~4@s~%”
            (pref pb :DTPBRec.ioIndex)
            (symbol-name (pref pb :DTPBRec.ioFileType))
            (pref pb :DTPBRec.ioIconType)
            (pref pb :DTPBRec.ioDTActCount))
    (incf (pref pb :DTPBRec.ioIndex))))
Æ
[6]
 #:  type  icon   size    all the icons associated with ResEdit
 1: “APPL”    1    256
 2: “APPL”    2    512
 3: “APPL”    3   1024
 4: “APPL”    4     64
 5: “APPL”    5    128
 6: “APPL”    6    256
 7: “RSRC”    1    256
 8: “RSRC”    2    512
 9: “RSRC”    3   1024
10: “RSRC”    4     64
11: “RSRC”    5    128
12: “RSRC”    6    256
13: “paul”   -1    256    ¨ what’s this?1
14: “rsrc”    1    256
15: “rsrc”    2    512
16: “rsrc”    3   1024
17: “rsrc”    4     64
18: “rsrc”    5    128
19: “rsrc”    6    256
20: “ssrc”    1    256    ¨ stationary document icons
21: “ssrc”    2    512
22: “ssrc”    3   1024
23: “ssrc”    4     64
24: “ssrc”    5    128
25: “ssrc”    6    256
-5012   ¨ afpItemNotFound

Closer inspection reveals that the paul icon isn’t actually an icon at all. It’s used by the Finder to store the file types which can be dragged and dropped onto the application. This code uses PBDTGetIcon to retrieve the raw icon data. It then prints it out as a text string.2

[7]
(%stack-block ((buf #$kLarge8BitIconSize))
  (rlet ((pb :DTPBRec
             :ioDTRefNum *DTDB-refNum*
             :ioTagInfo 0
             :ioDTBuffer buf
             :ioDTReqCount #$kLarge8BitIconSize
             :ioIconType -1
             :ioFileCreator “RSED”
             :ioFileType “paul”
             ))
    (when (zerop (#_PBDTGetIcon pb))
      (print (pref pb :DTPBRec.ioDTActCount))
      (%get-text buf (pref pb :DTPBRec.ioDTActCount)))))
Æ
 256 
“rsrcRSRC****” ¨ 

This is actually a 256 character string. The 244 trailing null characters are not shown.

As you can see, it is pretty simple to access the Toolbox: no windows to create, no managers to initialize, no make-files to write. When code is evaluated, the resulting value is printed to the Listener window, a standard part of the MCL environment. The print function outputs to the Listener by default.

MCL played a pivotal role in the development of Save A BNDL. First, I used it to learn about the desktop database, including the existence of the undocumented paul icon. Then, I used it to figure out how to kill and restart the Finder using Apple Events and the Process Manager. Before a single line of C code was written, I had already solved most of the interesting problems.

“If MCL is totally awesome, why isn’t everyone using it?”

Arguments against using MCL are usually along the lines of: “No one else is using MCL;” “LISP might be too slow;” “I already have a big investment in C;” “Why should I learn something new?” Do these objections sound familiar? They sound a lot like the complaints the PC community raised when the Macintosh first came out. They are all pretenses for avoiding change.

If you are still not sold on MCL, remember that I have kept this article focused on the benefits of MCL directly related to Mac programming. There are also plenty of reasons to choose LISP over traditional programming languages. For a set of relevant articles, see the September 1991 issue of the Communications of the ACM. It has a special section on LISP and CLOS.

There has been a lot of talk about Object Oriented Dynamically Linked languages (OODLs) being the wave of the future. Object-oriented languages have already changed the face of Mac development. Dynamic languages have the potential to completely revolutionize it. MCL is not some promise of the future. It is here now, it works, and you can benefit from it.

References and Suggested Reading

Apple Computer, “Macintosh Common LISP 2.0 Reference - Draft.” 1991, Apple Computer. Comes with MCL (available from APDA). I have not seen the final version yet. The 2.0b1 draft has plenty of errors and omissions. MCL’s Apropos tool goes a long way toward making up for the deficiencies.

Card, Orson Scott, “Ender’s Game.” 1991, Tom Doherty and Associates. Very entertaining. Even people who do not normally like science fiction will enjoy this one.

Engber, Michael S., "The Sound Manager with LISP". MacTutor, March 1991, pp. 84-89. An informative and well written article, if I must say so myself. It covers the basics of ToolBox access and illustrates them by using the Sound Manager. It was written in the days of MACL 1.32, so parts are dated.

Keene, Sonya E., “Object-Oriented Programming in Common LISP.” 1989, Addison Wesley. A very complete and digestible introduction to CLOS. It can be read straight through (if you ignore that extended example on the lock class).

Kleiman, Ruben, The Power of Macintosh Common LISP, develop, Winter 1991, pp. 85-113. Covers the basic MCL environment and object system in detail. Lots of example code.

Norvig, Peter, “Paradigms of Artificial Intelligence Programming: Case Studies in Common Lisp” 1992, Morgan Kaufman Publishers, Inc. Common Lisp from a to z, with lots of good examples and two chapters on efficiency issues.

Steele, Guy L., “Common LISP - The Language” 2nd edition. 1990, Digital Press. Comprehensive, precise, essential, very dense. This is one of those books whose prerequisite is a solid understanding of the subject it covers. Not a tutorial.

Sherwood T.K. and Wilcox F.C., “Sabotage of Gasoline Engines.” 1946, Office of Scientific Research . A definite must.

Wilensky, Robert, “Common LISPcraft.” 1984, WW Norton and Company. If you already know something about programming and you are looking for a book you can sit down, read, and come away with the impression, albeit mistaken, that you know something about LISP, this is it. It has good, readable, explanations of the fundamentals. Appendix A is a good Common LISP reference, although not as encyclopedic as Steele. When you outgrow Wilensky, you will be ready for Steele.

Acknowledgments

I would like to thank the following individuals for their input: Jorn Barger, Mark Chung, Martha Engber, Josh Golub, Dan Halabe, Alice Hartley, Mike Korcuska, Rich Lynch, David Moon, David Neves, Tamar Offer, Chris Riesbeck, Bill St. Clair, and Steve Strassmann.

The Institute for the Learning Sciences was established in 1989 with the support of Andersen Consulting, part of The Arthur Andersen Worldwide Organization. The Institute receives additional funding from Ameritech (an Institute Partner), IBM, the Defense Advanced Research Projects Agency, the Air Force Office of Scientific Research, and the Office of Naval Research.

1 Notice the undocumented type of icon associated with paul files. It turns out that most applications have an entry for this mysterious paul icon in the desktop database, but none of them seems to have it in their BNDL resource. How odd.

2 The paul icon is actually an array of OSType’s. Notice it contains an entry for files of type ****. This is a wild card type you can specify in a BNDL resource if you want to accept files of any type. Other wild card types are: fold to accept folders, disk to accept disks, and ???? to accept applications. This last type is not documented, but without it there is no way to only accept APPL files (recall the APPL entry in a BNDL specifies the application’s icon).

 
AAPL
$97.67
Apple Inc.
+0.64
MSFT
$44.50
Microsoft Corpora
+0.10
GOOG
$589.02
Google Inc.
-4.33

MacTech Search:
Community Search:

Software Updates via MacUpdate

TinkerTool 5.3 - Expanded preference set...
TinkerTool is an application that gives you access to additional preference settings Apple has built into Mac OS X. This allows to activate hidden features in the operating system and in some of the... Read more
Audio Hijack Pro 2.11.0 - Record and enh...
Audio Hijack Pro drastically changes the way you use audio on your computer, giving you the freedom to listen to audio when you want and how you want. Record and enhance any audio with Audio Hijack... Read more
Intermission 1.1.1 - Pause and rewind li...
Intermission allows you to pause and rewind live audio from any application on your Mac. Intermission will buffer up to 3 hours of audio, allowing users to skip through any assortment of audio... Read more
Autopano Giga 3.6 - Stitch multiple imag...
Autopano Giga allows you to stitch 2, 20, or 2,000 images. Version 3.0 integrates impressive new features that will definitely make you adopt Autopano Pro or Autopano Giga: Choose between 9... Read more
Airfoil 4.8.7 - Send audio from any app...
Airfoil allows you to send any audio to AirPort Express units, Apple TVs, and even other Macs and PCs, all in sync! It's your audio - everywhere. With Airfoil you can take audio from any... Read more
Microsoft Remote Desktop 8.0.8 - Connect...
With Microsoft Remote Desktop, you can connect to a remote PC and your work resources from almost anywhere. Experience the power of Windows with RemoteFX in a Remote Desktop client designed to help... Read more
xACT 2.30 - Audio compression toolkit. (...
xACT stands for X Aaudio Compression Toolkit, an application that encodes and decodes FLAC, SHN, Monkey’s Audio, TTA, Wavpack, and Apple Lossless files. It also can encode these formats to MP3, AAC... Read more
Firefox 31.0 - Fast, safe Web browser. (...
Firefox for Mac offers a fast, safe Web browsing experience. Browse quickly, securely, and effortlessly. With its industry-leading features, Firefox is the choice of Web development professionals... Read more
Little Snitch 3.3.3 - Alerts you to outg...
Little Snitch gives you control over your private outgoing data. Track background activityAs soon as your computer connects to the Internet, applications often have permission to send any... Read more
Thunderbird 31.0 - Email client from Moz...
As of July 2012, Thunderbird has transitioned to a new governance model, with new features being developed by the broader free software and open source community, and security fixes and improvements... Read more

Latest Forum Discussions

See All

New Trailer For Outcast Odyssey, A New K...
New Trailer For Outcast Odyssey, A New Kind of Card Battler Posted by Jennifer Allen on July 25th, 2014 [ permalink ] Out this Fall is a new kind of card battle game: Outcast Odyssey. | Read more »
Garfield: Survival of the Fattest Coming...
Garfield: Survival of the Fattest Coming to iOS this Fall Posted by Jennifer Allen on July 25th, 2014 [ permalink ] Who loves lasagna? Me. Also everyone’s favorite grumpy fat cat, Garfield. | Read more »
Happy Flock Review
Happy Flock Review By Andrew Fisher on July 25th, 2014 Our Rating: :: HERD IT ALL BEFOREUniversal App - Designed for iPhone and iPad Underneath the gloss of Happy Flock’s visuals is a game of very little substance. It’s cute, but... | Read more »
Square Register Updates Adds Offline Pay...
Square Register Updates Adds Offline Payments Posted by Ellis Spice on July 25th, 2014 [ permalink ] Universal App - Designed for iPhone and iPad | Read more »
Looking For Group – Hearthstone’s Curse...
For the first time since its release (which has thankfully been a much shorter window for iPad players than their PC counterparts), Blizzard’s wildly successful Hearthstone: Heroes of Warcraft CCG is sporting some brand new content: the single... | Read more »
Poptile Review
Poptile Review By Jennifer Allen on July 25th, 2014 Our Rating: :: SIMPLY FUNUniversal App - Designed for iPhone and iPad Simple yet a little bit glorious, Poptile is a satisfying entertaining puzzle game with oodles of the ‘one... | Read more »
Modern Combat 5: Blackout Review
Modern Combat 5: Blackout Review By Brittany Vincent on July 25th, 2014 Our Rating: :: LESS QQ, MORE PEW PEWUniversal App - Designed for iPhone and iPad The fifth entry into the blockbuster Modern Combat series is what mobile... | Read more »
Watch and Share Mobile Gameplay Videos W...
Watch and Share Mobile Gameplay Videos With Kamcord Posted by Jennifer Allen on July 25th, 2014 [ permalink ] iPhone App - Designed for the iPhone, compatible with the iPad | Read more »
THE KING OF FIGHTERS '98 (Games)
THE KING OF FIGHTERS '98 1.0 Device: iOS Universal Category: Games Price: $3.99, Version: 1.0 (iTunes) Description: Series’ masterpiece “KOF ’98” finally joins the battle on iPhone! FEATURES:■ The best game balance in the “KOF”... | Read more »
LEX Goes Free For One Day In Honor of Ne...
LEX Goes Free For One Day In Honor of New Update Posted by Jennifer Allen on July 24th, 2014 [ permalink ] Universal App - Designed for iPhone and iPad | Read more »

Price Scanner via MacPrices.net

iMacs on sale for $150 off MSRP, $250 off for...
Best Buy has iMacs on sale for up to $160 off MSRP for a limited time. Choose free home shipping or free instant local store pickup (if available). Prices are valid for online orders only, in-store... Read more
Mac minis on sale for $100 off MSRP, starting...
Best Buy has Mac minis on sale for $100 off MSRP. Choose free shipping or free instant local store pickup. Prices are for online orders only, in-store prices may vary: 2.5GHz Mac mini: $499.99 2.3GHz... Read more
Global Tablet Market Grows 11% in Q2/14 Notwi...
Worldwide tablet sales grew 11.0 percent year over year in the second quarter of 2014, with shipments reaching 49.3 million units according to preliminary data from the International Data Corporation... Read more
New iPhone 6 Models to Have Staggered Release...
Digitimes’ Cage Chao and Steve Shen report that according to unnamed sources in Apple’s upstream iPhone supply chain, the new 5.5-inch iPhone will be released several months later than the new 4.7-... Read more
New iOS App Helps People Feel Good About thei...
Mobile shoppers looking for big savings at their favorite stores can turn to the Goodshop app, a new iOS app with the latest coupons and deals at more than 5,000 online stores. In addition to being a... Read more
Save on 5th generation refurbished iPod touch...
The Apple Store has Apple Certified Refurbished 5th generation iPod touches available starting at $149. Apple’s one-year warranty is included with each model, and shipping is free. Many, but not all... Read more
What Should Apple’s Next MacBook Priority Be;...
Stabley Times’ Phil Moore says that after expanding its iMac lineup with a new low end model, Apple’s next Mac hardware decision will be how it wants to approach expanding its MacBook lineup as well... Read more
ArtRage For iPhone Painting App Free During C...
ArtRage for iPhone is currently being offered for free (regularly $1.99) during Comic-Con San Diego #SDCC, July 24-27, in celebration of the upcoming ArtRage 4.5 and other 64-bit versions of the... Read more
With The Apple/IBM Alliance, Is The iPad Now...
Almost since the iPad was rolled out in 2010, and especially after Apple made a 128 GB storage configuration available in 2012, there’s been debate over whether the iPad is a serious tool for... Read more
MacBook Airs on sale starting at $799, free s...
B&H Photo has the new 2014 MacBook Airs on sale for up to $100 off MSRP for a limited time. Shipping is free, and B&H charges NY sales tax only. They also include free copies of Parallels... Read more

Jobs Board

*Apple* Solutions Consultant (ASC) - Apple (...
**Job Summary** The ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The ASC's role is to grow Apple Read more
*Apple* Solutions Consultant (ASC) - Apple (...
**Job Summary** The ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The ASC's role is to grow Apple Read more
Sr. Project Manager for *Apple* Campus 2 -...
…the design and construction of one building or building components of the New Apple Campus located in Cupertino, CA. They will provide project management oversight for Read more
WW Sales Program Manager, *Apple* Online St...
**Job Summary** Imagine what you could do here. At Apple , great ideas have a way of becoming great products, services, and customer experiences very quickly. Bring Read more
*Apple* Solutions Consultant (ASC) - Apple (...
**Job Summary** The ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The ASC's role is to grow Apple Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.