[comp.sys.mac] Preemptive and Nonpreemptive Multitasking

dwb@Apple.COM (David W. Berry) (03/17/88)

In article <1174@cpocd2.UUCP> howard@cpocd2.UUCP (Howard A. Landman) writes:
>In article <7658@apple.Apple.Com> dwb@apple.UUCP (David W. Berry) writes:
>
>>What I said was that MultiFinder still had some known areas where it
>>could be improved.  Not that it was less than multitasking.  As
>>a matter of fact it is fully and completely multitasking, non-
>>premptive, but multitasking all the same.  Especially when one
>>considers that all macintosh programs should be calling GetNextEvent
>>periodically to interact with the user anyway, and task switching
>>is done there.
>
>You can see the problem but still don't admit it's there?  In real multitasking
>NO SPECIAL CODING IS NEEDED.  Most programs multitask AUTOMATICALLY without any
>special attention from the programmer.
>
>Under MultiFinder, each program (except possibly the last one) must be
>specially coded to be "MultiFinder compatible" by calling WaitNextEvent instead
>of GetNextEvent (if I don't have them reversed).  Why is this a problem?
>Because it only takes one or two programs which fail to do this before
>MultiFinder fails to grant any CPU time at all to the lowest priority task.
>Why is this a problem?  Because there are lots of Mac programs out there which
>were written before MultiFinder and are still useful, but which will never be
>changed.  Companies go out of business.  Shareware authors move on to more
>lucrative pursuits.  Etc.
	Ahh...  But what you're missing is the fact that almost every
application that exists for the Macintosh already periodically calls
GetNextEvent.  Like every time it want's input from the user.  Task switches
are performed on calls to GetNextEvent, WaitNextEvent and, I believe,
EventAvail.  Therefore almost every Macintosh application already allows
task switches at fairly frequent intervals.  No recoding necessary.
No extra work necessary.
	In fact, applications such as Excel already periodically poll
for events during long calculations such as recalculating the spread
sheet to allow the user to scroll to a more useful portion, change more
values, etc, and still have real response.  These applications continue
to work as well or better.
	WaitNextEvent isn't a necessity for task switching.  It's a nicety
which allows a task to more completely specify what kind of tasks it's
interested in.

	A quick summary of pro's and con's of preemptive and nonpreemptive
multitasking:

Task switches:
	With non-preemptive multitasking task switches are simpler
because you know the exact state of the machine when the switch
occurs.  With preemptive you're never quite sure.

Programmer Ignorance:
	With preemptive multitasking the programmer can be completely
ignorant.  He doesn't have to think about the fact that this calculation
is going to take three days and some other task probably ought to run
during that time.

Runaway or inconsiderate programs:
	With nonpreemptive multitasking runaway or inconsiderate programs
can shut a machine down because there's no clean way to get control to
kill them.  With preemptive multitasking they just eat CPU, but they can
probably be cleanly killed.

Indivisible operations:
	Nonpreemptive multitasking makes indivisible operations a snap
because the program is in control of when it let's go of the processor.
With preemptive multitasking you're never sure when the processor will
go away.

Inopportune task switches
	Preemptive multitasking allows task switches at inopportune
times.  Ever have your windowing system lose the processor while your
dragging something around with the mouse, makes for real jerky mouse
movement.

Program control
	Nonpreemptive multitasking gives the program much more precise
control of when it get's switched.

Fairness
	Preemptive multitasking is in general "fairer" in that all
tasks have a more or less equal chance of getting processor time.
This can be modified by priorities, but no one process is going to
get all the processor.  This is desireable in a multiuser timesharing
environment.  It's a much less clear win in a singleuser environment
since it means that tasks that I'm not clearly interested will be
getting a fair share of the processor.

-- 
David W. Berry
dwb@Delphi	dwb@apple.com	973-5168@408.MaBell
Disclaimer: Apple doesn't even know I have an opinion and certainly
	wouldn't want if they did.

dillon@CORY.BERKELEY.EDU (Matt Dillon) (03/18/88)

>	A quick summary of pro's and con's of preemptive and nonpreemptive
>multitasking:

	In general, Dave's comments are true.  But there are extremely 
	simple solutions to most of the "problems" with preemptive
	multitasking.  I always view preemptive multitasking as a
	superset of nonpreemptive multitasking because you still have
	the capability to "turn off" the preemption thereby yielding
	the subset "nonpreemptive multitasking".  At least in microcomputers.
	convoluted OS's like UNIX are still in the dark ages as far
	as program control over multitasking goes.

>
>Task switches:
>	With non-preemptive multitasking task switches are simpler
>because you know the exact state of the machine when the switch
>occurs.  With preemptive you're never quite sure.

	The amount of code required to handle the difference is usually
	a couple of lines... Sometimes none.  Sometimes the additional
	code serves to add power that would otherwise not exist in
	a non-preemptive system.

>	With nonpreemptive multitasking runaway or inconsiderate programs
>can shut a machine down because there's no clean way to get control to
>kill them.  With preemptive multitasking they just eat CPU, but they can
>probably be cleanly killed.

	Here's a cute story:  Once, while writing a program on an Amiga,
	I created a real strange bug that 'hung' the task ... it went into
	an infinite loop.  It took me four tries to find the problem.  At
	the end, I had 4 tasks running in infinite loops while also doing
	the final compile (the one that fixed the problem).  

	I couldn't kill the tasks, but they didn't use much memory and
	I could lower their priority so they didn't effect the rest of
	the system.  So I could afford waiting until I got it right
	before rebooting to "clean up" the sytem.

>
>Indivisible operations:
>	Nonpreemptive multitasking makes indivisible operations a snap
>because the program is in control of when it let's go of the processor.
>With preemptive multitasking you're never sure when the processor will
>go away.

	Yes.  You have to think about it.  But most operating systems
	(micro computer OS's, at least) allow one to temporarily disable 
	task switching for critical operations.  Using the Amiga as an
	example, there are two exec calls: Forbid() and Permit() that
	do this.  The overhead for doing the call is essentially zero...
	they simply increment/decrement a certain location that exec
	looks at next time it wants to switch tasks.  This might seem
	counterproductive but it makes synchronization a snap.  You only
	do it for short (read: uS/mS) periods of time around the
	indivisible operations.


>Inopportune task switches
>	Preemptive multitasking allows task switches at inopportune
>times.  Ever have your windowing system lose the processor while your
>dragging something around with the mouse, makes for real jerky mouse
>movement.
>
>Program control
>	Nonpreemptive multitasking gives the program much more precise
>control of when it get's switched.

	I would disagree here.  This is where task priorities come in.
For instance, you place the window/mouse handler at a higher priority
than the application program.  Then, as soon as an event comes in (from
some interrupt service routine), the application program is preempted
and the window/mouse handler allowed to process the event.

	Thus, you get much smoother operation.  You might ask "what if
we had nonpreemptive multitasking instead"?  Then you are in even worse
shape!  The specific problem you mentioned is inherent in SUN workstations
because the mouse is handled by a process, and UNIX processes have huge
context switch overheads and braindamaged priority schemes.  The only
solution is to make the mouse handled by an interrupt or somewhere in the OS
rather than by a process.

>Fairness
>	Preemptive multitasking is in general "fairer" in that all
>tasks have a more or less equal chance of getting processor time.
>This can be modified by priorities, but no one process is going to
>get all the processor.  This is desireable in a multiuser timesharing
>environment.  It's a much less clear win in a singleuser environment
>since it means that tasks that I'm not clearly interested will be
>getting a fair share of the processor.

	Right, so you use a different priority scheme.  This has been
argued to death in comp.sys.amiga over the way the Amiga implements it.
Essentially, on the Amiga, a higher priority task shares the Cpu ONLY
with other tasks of the same priority (round robin).  Lower priority tasks
don't get a chance.  On the Amiga, application tasks run at the same priority
(0) so this doesn't cause problems.  Supervisors, managers, event handlers,
etc... usually run for only brief instances of time but want to run
as soon as some event happens, so are given higher priorities.  People
usually run demo's at lower priorities so they don't interfere with *real*
work.

>David W. Berry

				-Matt

peter@nuchat.UUCP (Peter da Silva) (03/19/88)

In article <7720@apple.Apple.Com>, dwb@Apple.COM (David W. Berry) writes:
> 	A quick summary of pro's and con's of preemptive and nonpreemptive
> multitasking:

	A few comments based on the fact that you're comparing
yourself to a non real-time operating system. For single-user
use, a real-time operating system (like Amiga's Exec) addresses
virtually every complaint you have with concurrency.

> Task switches:
> 	With non-preemptive multitasking task switches are simpler
> because you know the exact state of the machine when the switch
> occurs.  With preemptive you're never quite sure.

On a machine without memory protection, task switches can be as simple
as:

	timer interrupt occurs in the context of the old task.
	push all registers on old task's stack.
	pop all registers off new task's stack.
	return in the context of the new task.

> Indivisible operations:
> 	Nonpreemptive multitasking makes indivisible operations a snap
> because the program is in control of when it let's go of the processor.
> With preemptive multitasking you're never sure when the processor will
> go away.

So you use semaphores or formal messages to synchronise things. On UNIX
this is handled invisibly by the kernel: a task switch occurs under
control of the operating system. On the Amiga, which has a much more complex
shared memory environment, you use semaphores or use standard library
calls that do the semaphoring for you. I don't care that DrawImage does
WaitBlits and OwnBlits and LockLayers and stuff.

> Inopportune task switches
> 	Preemptive multitasking allows task switches at inopportune
> times.  Ever have your windowing system lose the processor while your
> dragging something around with the mouse, makes for real jerky mouse
> movement.

Nope. Never had any problew3ms with that. The mouse motion is under control
of a high-priority realtime task called "Intuition".

> Program control
> 	Nonpreemptive multitasking gives the program much more precise
> control of when it get's switched.

Not at all. I can keep from getting switched any time I need to:

	Forbid();
	Do something that needs to be atomic.
	Permit();

> Fairness
> 	Preemptive multitasking is in general "fairer" in that all
> tasks have a more or less equal chance of getting processor time.
> This can be modified by priorities, but no one process is going to
> get all the processor.  This is desireable in a multiuser timesharing
> environment.  It's a much less clear win in a singleuser environment
> since it means that tasks that I'm not clearly interested will be
> getting a fair share of the processor.

If the tasks are I/O bound they'll be spending most of their time on
the wait queue. If they're CPU bound you can always knock their priority down
a peg.
-- 
-- a clone of Peter (have you hugged your wolf today) da Silva  `-_-'
-- normally  ...!hoptoad!academ!uhnix1!sugar!peter                U
-- Disclaimer: These aren't mere opinions... these are *values*.

ralph@computing-maths.cardiff.ac.uk (Ralph Martin) (03/21/88)

Posting-Front-End: GNU Emacs 18.47.1 of Mon Nov 23 1987 on v1 (berkeley-unix)


I'm afraid you guys at apple have shot your self in the foot.

By saying that applications such as excel POLL for events during long 
calcultions, you have hit the real nub of the matter. 

In a "real" multitasking operating system, the operating system takes care of
events via interrupts, and deals with them accordingly - even while other
things are going on.

A second thing the OS does is to handle memory management. On the mac, the poor
programmer has to worry about handles, and relocation blowing him away.

Lets face it, the Mac is a machine with a brilliant user interface, but no real
operating system worthy of the name. I much prefer to use my mac to my sun, but
I LOATHE programming it. On the sun, part of the OS (the notifier) takes care
of events and calls the bits of code I want in response to the events. On the
Mac, I have to ask all the time what is going on, figure out if I want it, 
and give it back to the system if I dont, and so on, as well as looking after
memory management too. This has two serious upshots (1) Mac programs are much
more likely to crash - there is no overall way of ensuring programmers 
manage memory in a sensible way, (2) If programs don't both to poll, they
screw the user up if he wants to switch (juggle), and so on. In my opinion,
much of this garbage should be pushed out of the control of the programmer,
for the benefit of all concerned. I can well believe the rumours that the Mac
OS is being written.

lsr@Apple.COM (Larry Rosenstein) (03/25/88)

In article <234@cf-cm.UUCP>, ralph@computing-maths.cardiff.ac.uk (Ralph Martin) writes:
>
> A second thing the OS does is to handle memory management. On the mac, the
>poor programmer has to worry about handles, and relocation blowing him
>away.

Handles on the Macintosh are optional (although very useful).  You can
allocate nonrelocatable blocks if you want, and you can lock handles to
prevent them from moving.  Memory is compacted only when needed, and the
times when this happens are well-documented.

On a machine without an MMU, it would be hard to support highly interactive
applications without a compacting memory manager.

>sun, but I LOATHE programming it. On the sun, part of the OS (the notifier)
>takes care of events and calls the bits of code I want in response to the
>events. On the Mac, I have to ask all the time what is going on, figure out

This is the application model used by MacApp.  MacApp goes beyond handling
user events (eg, moving windows).  MacApp will handle moving & resizing
windows without the programmer having to write any code.  But MacApp also
takes care of printing, file management, memory management, error handling
issues.

-- 
		 Larry Rosenstein,  Object Specialist
 Apple Computer, Inc.  20525 Mariani Ave, MS 32E  Cupertino, CA 95014
	    AppleLink:Rosenstein1    domain:lsr@Apple.COM
		UUCP:{sun,voder,nsc,decwrl}!apple!lsr

hugo@eleazar.Dartmouth.EDU (Peter Su) (03/28/88)

I think a point to consider is this:

The role of the operating system is to manage machine resources and allocate them
to the different tasks running on the system in a way that is transparent to the
programmer.  Thus, I don't think that the way Multifinder does task switching is
very clean or real.  True, most Mac application have to busy wait in a
GetNextEvent loop anyway, but that is just an artifact of bad design in the
beginning.  Busy waiting is ugly and uneeded.

So, my point is that I don't want to think about task switching at all when I'm
coding, I think that that sort of bookeeping is up to the OS to handle.

Pete

-- 
CSNET: hugo@darmouth.edu                  UUCP: hugo@eleazar.UUCP (Sorry)
ARPA: hugo%dartmouth.edu@relay.cs.net

QUOTE:"Our president's crazy!  Did you hear what he said?" - Talking Heads

ralph@computing-maths.cardiff.ac.uk (Ralph Martin) (03/31/88)

I feel I must reply to lsr's comments on my remarks:

>Handles on the Macintosh are optional (although very useful).  You can
>allocate nonrelocatable blocks if you want, and you can lock handles to
>prevent them from moving.  Memory is compacted only when needed, and the
>times when this happens are well-documented.

Optional my foot. Many of the toolbox routines have arguments which are handles
and if the programmer isnt careful in locking them down, he will soon learn
that understanding the Mac's "memory (mis)management model" is NECESSARY!

>>sun, but I LOATHE programming it. On the sun, part of the OS (the notifier)
>>takes care of events and calls the bits of code I want in response to the
>>events. On the Mac, I have to ask all the time what is going on, figure out

>This is the application model used by MacApp.  MacApp goes beyond handling
>user events (eg, moving windows).  MacApp will handle moving & resizing
>windows without the programmer having to write any code.  But MacApp also
>takes care of printing, file management, memory management, error handling
>issues.

OK, so MacApp is supposed to take care of these things. I have also
used MacApp, and all I can say is that it is of limited use. Among my
criticisms are that parts of it are inconsistent or not thought
through enough (e.g.the way modeless dialogs work), there are
omissions (e.g. it is not trivial to put a picture you have a handle
to on the clipboard - a very common requirement), if you try to do
anything serious with it, you soon find that many things you want
to do require overriding MacApp at much lower levels than should be
strictly necessary, and the programmer STILL has to worry about memory
management, despite the comment above - just look at the MacApp example
sources if you want any proof! 

Before MacApp will be truly useful, many of these things will need
sorting out (or better, the Mac OS rewriting!).
A much larger library of classes will be needed (For example, the
usual type of window shows a larger part of the document if it is
expanded.  Equally valid would be to expand the window's contents with
the window).
The classes also need to be much better defined and documented (these
are not the same). This will reduce many of the unfortunate side effects
and interactions which make MacApp so tedious at present.

OK, I will get off my high horse now. I love using the Mac - I just wish that
it wasn't such a pig to program. C'mon you guys - it doesn't HAVE to be like
this. When you bring out the Mac III or whatever it's called by then, lets 
have a REAL operating system, as a firm basis to start from, with a lot of the
tedious rhubarb hidden from the programmer!

rs4u+@andrew.cmu.edu (Richard Siegel) (04/06/88)

I'm sorry, but as a Mac programmer of some experience I need to comment on this
one...

First, I'm going to put words in Mr. Rosenstein's mouth:
> *Excerpts from: 31-Mar-88 Re: Preemptive and Nonpreem.. Ralph*
> *Martin@computing-m (2691)*

> >Handles on the Macintosh are optional (although very useful).  You can
> >allocate nonrelocatable blocks if you want, and you can lock handles to
> >prevent them from moving.  Memory is compacted only when needed, and the
> >times when this happens are well-documented.

I would clarify this by saying that "The use of Handles on the Macintosh for
internal program data types is optional, although very useful."

> *Excerpts from: 31-Mar-88 Re: Preemptive and Nonpreem.. Ralph*
> *Martin@computing-m (2691)*

> Optional my foot. Many of the toolbox routines have arguments which are
> handlesand if the programmer isnt careful in locking them down, he will soon
> learn
> that understanding the Mac's "memory (mis)management model" is NECESSARY!

The User Interface Toolbox routines do, in many cases, require handles as
arguments. However, I know of NO CASE where a handle passed to a UI Toolbox
routine needs to be locked. (There are some cases in the OS calls that require
that a buffer be locked, but you can use a nonrelocatable block or a pointer to
a statically allocated (e.g. an array) data structure. The programmer is not
required to muck around with handles - a good example is the Menu Manager. You
call GetMenu() which returns a MenuHandle. Then you call InsertMenu() which
puts it in the menu bar, and then you forget about it, unless you want to call
DisposMenu, or GetItem, or DisableItem, or some similar procedure. But at no
point in this process does the programmer have to care about what's in the
handle, or have to worry about locking or unlocking the handle.

For my user interfaces, I let the Memory Manager do its thing without
interference, and it works just fine for my purposes.

> *Excerpts from: 31-Mar-88 Re: Preemptive and Nonpreem.. Ralph*
> *Martin@computing-m (2691)*

> (e.g. it is not trivial to put a picture you have a handle
> to on the clipboard - a very common requirement)

Excuse me? EXCUSE ME?! Obviously, you've either never tried to put a picture on
the Clipboard, or you haven't expended the effort to figure out how to do it.
Watch:

        procedure CopyPicture(p : PicHandle);
        var
                err : OSErr;

        begin
                HLock(p);
                err := ZeroScrap;
                err := PutScrap('PICT', GetHandleSize(p), p^);
                HUnlock(p);
        end;

I have probably gotten the order of arguments to PutScrap wrong, because it's
been a while since I last did this. The point is, it *IS* trivial to do this,
whether it's a MacApp oversight or not.

> *Excerpts from: 31-Mar-88 Re: Preemptive and Nonpreem.. Ralph*
> *Martin@computing-m (2691)*

> if you try to do
> anything serious with it, you soon find that many things you want
> to do require overriding MacApp at much lower levels than should be
> strictly necessary, and the programmer STILL has to worry about memory
> management, despite the comment above - just look at the MacApp example
> sources if you want any proof!

I don't use MacApp, (I've posted on the subject and won't rehash it here) but I
am not surprised. First of all, MacApp is not a total application development
library - you can't expect that your application can be implemented by a few
library routines. Consider: MacApp is a "Generic MACintosh APPlication". It is
a FRAMEWORK. It provides the basis so that you don't have to worry about
writing the major user-interface features. I repeat: it IS NOT (and, I suspect,
wasn't designed to be) a total solution.

        *> Excerpts from: 31-Mar-88 Re: Preemptive and Nonpreem.. Ralph*
> *Martin@computing-m (2691)*

> Equally valid would be to expand the window's contents with
> the window).

True, except that expanding the window's contents is a highly
application-specific function. If you're using a text editor, and you make the
window bigger, do you REALLY want to use a bigger typeface? I kinda doubt it.
Graphics applications have use for "Fit In Window" functionality, but again,
that's a trivial case - just supply a different rectangle to scale the picture
in.

> *Excerpts from: 31-Mar-88 Re: Preemptive and Nonpreem.. Ralph*
> *Martin@computing-m (2691)*

> I love using the Mac - I just wish that
> it wasn't such a pig to program.

        I enjoy using it too, and I *don't* think it's hard to program. True,
it's intricate, but there are many things in life that are more complicated.

> *Excerpts from: 31-Mar-88 Re: Preemptive and Nonpreem.. Ralph*
> *Martin@computing-m (2691)*

> with a lot of the
> tedious rhubarb hidden from the programmer!

You have completely missed the point of the Macintosh User Interface Toolbox
and of MacApp. The "point" being that the Toolbox frees you from having to
implement the standard features (menus, windows, etc) for all of your programs,
and that MacApp frees you from having to implement the higher-level details of
using the ROM routines.

        Honestly, you can't expect to get something for nothing. I read from
this that that's precisely what you're after.

                --Rich

===================================================================
Rich Siegel
Confused Undergrad, Carnegie-Mellon University

The opinions stated here do not represent the policies
of Carnegie-Mellon University.

Arpa: rich.siegel@andrew.cmu.edu
UUCP: {decvax,ucbvax,sun}!andrew.cmu.edu!rich.siegel
==================================================================

lsr@Apple.COM (Larry Rosenstein) (04/09/88)

In article <238@cf-cm.UUCP> ralph@computing-maths.cardiff.ac.uk (Ralph Martin) writes:
>
>Optional my foot. Many of the toolbox routines have arguments which are handles
>and if the programmer isnt careful in locking them down, he will soon learn
>that understanding the Mac's "memory (mis)management model" is NECESSARY!

In most of the cases where handles are created by the Toolbox, the
programmer can treat them as uniterpreted 32 bit numbers.  The Toolbox will
take care of locking them if that is necessary, and usually will provide
procedure calls to access their contents.  In some (unusal) cases, however,
you do have to access the contents of a Toolbox handle directly and will
have to dereference it twice.

My original comment was intended to refer to the application-specific parts
of a program.  There is no requierment that you use handles internally in
your program, and since the Mac Memory Manager provides a way to create
pointers to non-relocatable blocks you have the freedom to choose the memory
management model you want.


>used MacApp, and all I can say is that it is of limited use. Among my
>criticisms are that parts of it are inconsistent or not thought

I don't claim that MacApp is perfect, only that it solves many of the
problems of Macintosh programming, andthat it is being improved (based on
developer feedback).

>through enough (e.g.the way modeless dialogs work), there are

The dialog support is being totally rewritten.  Part of the problem in the
old UDialog was that we tried to use the ROM Dialog Manager where possible,
and there was a mismatch in the models used by MacApp and the Dialog
Manager.  In MacApp 2.0, the new dialog unit doesn't use the Dialog Manager
at all, and things are much cleaner and more consistent.

>omissions (e.g. it is not trivial to put a picture you have a handle
>to on the clipboard - a very common requirement), if you try to do

I think this requires defining a new view class, but that's all.  It is true
that there are some classes that would be helpful to provide.  We tried to
make MacApp as solid as possible, and didn't have time to write very many
building blocks.  There are some building blocks available from the MacApp
Developer's Association.

>anything serious with it, you soon find that many things you want
>to do require overriding MacApp at much lower levels than should be
>strictly necessary, and the programmer STILL has to worry about memory
>management, despite the comment above - just look at the MacApp example
>sources if you want any proof! 

I think MacApp's memory management is as easy at will get on the Macintosh.
There is no virtual memory, so you have to worry about memory requests that
can fail.  You have to tell MacApp how much memory to reserve for your
maximum working set, and you have to check for errors returned by the Memory
If you do these 2 things then MacApp will make sure that your program
doesn't crash.

We have gotten some very positive feedback from MacApp users.  The fact is
that people have written some sophisticated programs with MacApp.  They
cover a wide range of application areas (music, word processing, filing,
engineering).  On the other hand, we don't usually hear from developers who
are unsuccessful with MacApp.

>A much larger library of classes will be needed (For example, the

MacApp 2.0 contains a larger variety of view classes.  There is also a way
to create all your views based on the description in a resource.  This
makes it much easier to create windows (including dialogs) in MacApp 2.0.

>The classes also need to be much better defined and documented (these
>are not the same). This will reduce many of the unfortunate side effects
>and interactions which make MacApp so tedious at present.

The manual is being rewritten and will include a tutorial section.  MacApp
2.0 has a lot of improvements to make it easier to use.  The first version
of any large system is always going to have deficiencies.

-- 
		 Larry Rosenstein,  Object Specialist
 Apple Computer, Inc.  20525 Mariani Ave, MS 27-AJ  Cupertino, CA 95014
	    AppleLink:Rosenstein1    domain:lsr@Apple.COM
		UUCP:{sun,voder,nsc,decwrl}!apple!lsr

cole@sas.UUCP (Tom Cole) (04/10/88)

[Dialog between Larry Rosenstein and "Ralph" about MacApp 1.mumble omitted]

So from what I hear, MacApp 2.0 is going to be pretty cool.  When will it
become available (or is it now?).  I just joined APDA and don't yet have any
good feel for when I will get notified of such things.  I have been doing
development in LSP up to now, and it's time to start using a compiler with
a little more optimization sophistication, etc. and I figured that an
interesting benefit of MPW Pascal was object extensions.  Should I order
the current MacApp and get upgraded later, or should I wait :-)
:w