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
$102.50
Apple Inc.
+0.25
MSFT
$45.43
Microsoft Corpora
+0.55
GOOG
$571.60
Google Inc.
+2.40

MacTech Search:
Community Search:

Software Updates via MacUpdate

VueScan 9.4.41 - Scanner software with a...
VueScan is a scanning program that works with most high-quality flatbed and film scanners to produce scans that have excellent color fidelity and color balance. VueScan is easy to use, and has... Read more
Cloud 3.0.0 - File sharing from your men...
Cloud is simple file sharing for the Mac. Drag a file from your Mac to the CloudApp icon in the menubar and we take care of the rest. A link to the file will automatically be copied to your clipboard... Read more
LibreOffice 4.3.1.2 - Free Open Source o...
LibreOffice is an office suite (word processor, spreadsheet, presentations, drawing tool) compatible with other major office suites. The Document Foundation is coordinating development and... Read more
SlingPlayer Plugin 3.3.20.505 - Browser...
SlingPlayer is the screen interface software that works hand-in-hand with the hardware inside the Slingbox to make your TV viewing experience just like that at home. It features an array of... Read more
Get Lyrical 3.8 - Auto-magically adds ly...
Get Lyrical auto-magically add lyrics to songs in iTunes. You can choose either a selection of tracks, or the current track. Or turn on "Active Tagging" to get lyrics for songs as you play them.... Read more
Viber 4.2.2 - Send messages and make cal...
Viber lets you send free messages and make free calls to other Viber users, on any device and network, in any country! Viber syncs your contacts, messages and call history with your mobile device,... Read more
Cocktail 7.6 - General maintenance and o...
Cocktail is a general purpose utility for OS X that lets you clean, repair and optimize your Mac. It is a powerful digital toolset that helps hundreds of thousands of Mac users around the world get... Read more
LaunchBar 6.1 - Powerful file/URL/email...
LaunchBar is an award-winning productivity utility that offers an amazingly intuitive and efficient way to search and access any kind of information stored on your computer or on the Web. It provides... Read more
Maya 2015 - Professional 3D modeling and...
Maya is an award-winning software and powerful, integrated 3D modeling, animation, visual effects, and rendering solution. Because Maya is based on an open architecture, all your work can be scripted... Read more
BBEdit 10.5.12 - Powerful text and HTML...
BBEdit is the leading professional HTML and text editor for the Mac. Specifically crafted in response to the needs of Web authors and software developers, this award-winning product provides a... Read more

Latest Forum Discussions

See All

This Week at 148Apps: August 25-29, 2014
Shiny Happy App Reviews   | Read more »
Qube Kingdom – Tips, Tricks, Strategies,...
Qube Kingdom is a tower defense game from DeNA. You rally your troops – magicians, archers, knights, barbarians, and others – and fight against an evil menace looking to dominate your kingdom of tiny squares. Planning a war isn’t easy, so here are a... | Read more »
Qube Kingdom Review
Qube Kingdom Review By Nadia Oxford on August 29th, 2014 Our Rating: :: KIND OF A SQUARE KINGDOMUniversal App - Designed for iPhone and iPad Qube Kingdom has cute visuals, but it’s a pretty basic tower defense game at heart.   | Read more »
Fire in the Hole Review
Fire in the Hole Review By Rob Thomas on August 29th, 2014 Our Rating: :: WALK THE PLANKUniversal App - Designed for iPhone and iPad Seafoam’s Fire in the Hole looks like a bright, 8-bit throwback, but there’s not enough booty to... | Read more »
Alien Creeps TD is Now Available Worldwi...
Alien Creeps TD is Now Available Worldwide Posted by Ellis Spice on August 29th, 2014 [ permalink ] Universal App - Designed for iPhone and iPad | Read more »
Dodo Master Review
Dodo Master Review By Jordan Minor on August 29th, 2014 Our Rating: :: NEST EGGiPad Only App - Designed for the iPad Dodo Master is tough but fair, and that’s what makes it a joy to play.   | Read more »
Motorsport Manager Review
Motorsport Manager Review By Lee Hamlet on August 29th, 2014 Our Rating: :: MARVELOUS MANAGEMENTUniversal App - Designed for iPhone and iPad Despite its depth and sense of tactical freedom, Motorsport Manager is one of the most... | Read more »
Motorsport Manager – Beginner Tips, Tric...
The world of Motorsport management can be an unforgiving and merciless one, so to help with some of the stress that comes with running a successful race team, here are a few hints and tips to leave your opponents in the dust. | Read more »
CalPal Update Brings the App to 2.0, Add...
CalPal Update Brings the App to 2.0, Adds Lots of New Stuff Posted by Ellis Spice on August 29th, 2014 [ permalink ] | Read more »
Baseball Battle Review
Baseball Battle Review By Jennifer Allen on August 29th, 2014 Our Rating: :: SIMPLE HITTINGUniversal App - Designed for iPhone and iPad Simple and cute, Baseball Battle is a fairly fun baseball game for those looking for something... | Read more »

Price Scanner via MacPrices.net

Labor Day Weekend MacBook Pro sale; 15-inch m...
B&H Photo has the new 2014 15″ Retina MacBook Pros on sale for up to $125 off MSRP. Shipping is free, and B&H charges NY sales tax only. They’ll also include free copies of Parallels Desktop... Read more
Labor Day Weekend iPad mini sale; $50 to $100...
Best Buy has the iPad mini with Retina Display (WiFi models) on sale for $50 off MSRP on their online store for Labor Day Weekend. Choose free shipping or free local store pick up. Price is for... Read more
13-inch 1.4GHz MacBook Air on sale for $899,...
Adorama has the new 2014 13″ 1.4GHz/128GB MacBook Air on sale for $899.99 including free shipping plus NY & NJ tax only. Their price is $100 off MSRP. Read more
It’s Official: Apple Issues Invitations To Se...
Apple has issued one of its characteristically cryptic press invitations for a special event to be held at the Flint Center for the Performing Arts in hometown Cupertino on Sept. 9, 2014 at 10:00 am... Read more
Tablet Shipments To See First On-year Decline...
TrendForce analyst Caroline Chen notes that when the iPad launched in 2010, it was an instant hit and spurred a tablet PC revolution, with tablets so popular that that notebook PC sales stagnated and... Read more
SOBERLINK Releases Apple iOS Compatible Handh...
Cypress, California based SOBERLINK, Inc., creator of the first handheld Breathalyzer designed to improve recovery outcomes, continues to show prominence in the mobile alcohol monitoring space with... Read more
New 21″ 1.4GHz iMac on sale again for $999, s...
Best Buy has the new 21″ 1.4GHz iMac on sale for $999.99 on their online store. Their price is $100 off MSRP. Choose free shipping or free local store pick up. Price is for online orders only, in-... Read more
Smartphone Outlook Remains Strong for 2014, U...
According to a new mobile phone forecast from the International Data Corporation (IDC) Worldwide Quarterly Mobile Phone Tracker, more than 1.25 billion smartphones will be shipped worldwide in 2014,... Read more
Save up to $60 with Apple refurbished iPod to...
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
12-Inch MacBook Air Coming in 4Q14 or 2015 –...
Digitimes’ Aaron Lee and Joseph Tsai report that according to Taiwan-based upstream supply chain insiders, Apple plans to launch a thinner MacBook model either at year end 2014 or in 2015, and that... Read more

Jobs Board

*Apple* Retail - Multiple Positions (US) - A...
Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, you're also the Read more
*Apple* Retail - Multiple Positions (US) - A...
Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, you're also the Read more
*Apple* Retail - Multiple Positions (US) - A...
Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, you're also the Read more
*Apple* Retail - Multiple Positions (US) - A...
Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, you're also the Read more
Senior Event Manager, *Apple* Retail Market...
…This senior level position is responsible for leading and imagining the Apple Retail Team's global event strategy. Delivering an overarching brand story; in-store, Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.