Hacker News new | past | comments | ask | show | jobs | submit login
MacPaint and QuickDraw 1984 source code (2010) (computerhistory.org)
96 points by tambourine_man on Aug 20, 2023 | hide | past | favorite | 26 comments



Bill Atkinson had incredible programming style. I'll admit, sometimes Pascal reads like poetry. I think it must be the paren-less procedure syntax:

  REPEAT
    UnloadSeg(@InitOnce);       { SegInit    }
    UnloadSeg(@PrintDoc);       { SegPrint   }
    UnloadSeg(@CutOrCopy);      { SegScrap   }
    UnloadSeg(@Paste);          { SegPaste   }
    UnloadSeg(@Rotate);         { SegFlip    }
    UnloadSeg(@ShowPage);       { SegPage    }
    UnloadSeg(@DrawPat);        { SegUpdate  }
    UnloadSeg(@EditPat);        { SegPatEdit }
    UnloadSeg(@ChooseBrush);    { SegBrush   }
    UnloadSeg(@Symmetry);       { SegSym     }
    UnloadSeg(@ShowPicture);    { SegHelp    }

    IF heapJam THEN
      BEGIN
        tempLong := MaxMem(tempLong);   { purge heap }
        heapJam := FALSE;
      END;

    SystemTask;    { give desk accessories a chance }
    IF active THEN TrackCursor;
    IF GetNextEvent(everyEvent,theEvent) THEN ProcessTheEvent;

    IF active AND NOT quitFlag AND (DiskSpace(0) < minDiskSpace) THEN
      BEGIN
        tempWord := SaveAlert(diskAlrt);
        quitFlag := TRUE;
      END;

    IF quitFlag THEN QuitProgram;

  UNTIL quitFlag;
  ExitToShell;
QuickDraw in 68k assembler is beautiful, too; there's a story from the first Mac's development that, when the Macintosh team tried to rewrite as much of the Toolbox in order to fit it after asembly in 68KB of ROM, Bill Atkinson refused to touch QuickDraw [1].

[1] https://www.folklore.org/StoryView.py?project=Macintosh&stor...


I really like this quotation attributed to Bill Atkinson

"If you want to get it smooth, you’ve got to rewrite it from scratch at least five times."

This is so true, and so hard to have the time and motivation to do in practice.


I think it’s hard to do refactorings in the context of a product-oriented team that works in sprints of 2 weeks. I have two options: a) either I make the rewrite 5 times in a row… but that would take a lot of time, so management won’t buy it (and I cannot just do it on the side because it actually takes time), or b) I do the rewrite one at a time, but then for every intermediate rewrite I need to open a PR and spend time with my colleagues doing the review. I don’t have anything against about PR reviews, but reviewing intermediate work feels like a waste of time (and kills the fun, because I know where I’m heading to, it’s just not obvious YET how to achieve it, hence the intermediate steps… I don’t really want to answer questions about intermediate work).

On personal projects, it’s a pleasure to rewrite code until I feel it “looks” good.


Join a team that doesn't do "sprints" if you want to do meaningful work.


There is a different pressure on refactoring in 2023 than in the 1980s / early 1990s.

If you need to fit your application into 5kb of pascal code so it can be bundled with an OS, there’s going to be less code to refactor and probably less ability to not-refactor.

(Not saying refactoring isn’t important now - it’s just more of a choice now and would usually have different goals)


I have also noticed that the improvement possible in one refactoring pass is quite significant, but still limited.

Somehow, I do a lot of refactoring. I noticed that I am unable to improve code by more than two notches of quality in a single refactoring pass. If it's very bad and the end result must be very good (it happens rarely to never that both are true), I need to come back to the code after a year or so and have another go. To understand the original code, I need to get "into its logic", and that understanding, as well as eagerness to fix the worst problems right away, somehow prevent improvements that involve a completely different approach.

The only way to make improvements larger than that is when I've already seen a very good way to handle a similar enough problem to the code in question.

Making a lot of progress in refactoring is even harder for code I have written myself because I understand the original reasoning behind things a little too well. Getting out of that trap probably requires a good amount of external input and / or a particular mental flexibility. I assume that Bill Atkinson had these.


The number of times you have to rewrite something goes down as you gain experience but it never becomes zero. (I also assume that you'd never change your stack so much that a significant part of your experience becomes irrelevant)


They do this with a lot of libraries and programs (GTK, QT, Gnome, KDE, Windows calculator, a lot of libraries in Linux, Windows settings etc.).

It does not seems to work at all.


I think the original quote implies that it needs to be the same person who does the rewrites. Probably with some external input because it's hard to question yourself four times :>


This is the response from a perfectionist who will never ship code on their own. It's a bad trait to have in a developer.


Maybe read a little bit about the man first.

Atkinson invented double-clicking, the selection lasso, MacPaint, QuickDraw, and HyperCard. When Steve Jobs was asked how many man-years QuickDraw took to develop, he asked Atkinson how long it took him. Atkinson said, "four years" so Jobs responded to the reporter, "Twenty-four man-years." Yes, Jobs was a hype machine for the Mac team, but he (and everyone around him) also knew that one Atkinson year was the equivalent of six typical developer years.

https://www.folklore.org/StoryView.py?project=Macintosh&stor...


Bill Atkinson shipped. Like, a lot, by any metric.


Strong disagree, we need more of this. The "move fast and break stuff" is exactly why we end up with companies full of dispensable employees who writer sloppy code they don't care about.


> SketchPad used menus to select patterns and styles to draw with, but Bill replaced them with permanent palettes at the bottom of the screen, and added another prominent palette on the left that contained drawing tools.

This is proof that the Ribbon version of Paint is a step backward: If the Paint window is narrow enough, all the tools end up collapsed, effectively putting them back behind menu.


The early 2000s were peak UI in terms of the accepted UI practices on Windows, with menus (including context menus) and freely customizable toolbars.


I wish MS would officially open-source MSPaint too, even (or especially) if it's the version that came with Windows 3.x, for comparison with this. However, given their history, it's more likely we'll see them open-sourcing the horrible "modern" version instead.


Microsoft freely gives out the next-best thing: Debug symbols. Using Ghidra, you have something similar to the source code.

But anyway, most of the functionality of Paint is actually in GDI itself.


Written initially in Object Pascal.


Partially, at least for MacPaint: “The high-level logic is written in Apple Pascal, packaged in a single file with 5,822 lines. There are an additional 3,583 lines of code in assembler language for the underlying Motorola 68000 microprocessor…”


The typical remark in Pascal discussions.

When Assembly is part of the picture in Pascal projects, it is always pointed out as it being the case.

When C projects make use of inline Assembly all over the place, it is C, even though it isn't part of ANSI C standard, there isn't any reference to inline Assembly support, and not every C compiler does support such extensions.


I code C pretty extensively and am pretty involved in the community. I rarely hear inline asm (itself, not the invocation) referred to as C; in fact it's pretty explicitly made clear by the general community that you should clearly delineate and cleanly separate asm code and mark that logic as machine specific.

The __asm__ inliner is referred to as C, sure; but not the code itself. That would be like calling FFI'd C in Rust, "rust code".

In addition, it 100% is in the standard beginning with "ANSI C" (C89):

> C89/C90 standard (ISO/IEC 9899:1990):

> * G.5.10 The asm keyword

https://en.cppreference.com/w/c/language/asm

It's just an optional extension for compilers versus a core language feature.


Lets say that we don't hang on the same circles, actually it even comes up in some threads on HN.

Yeah, that was the point of not being a core language feature, I should have expressed better.


The article itself is from 2010.


It would be nice to put the source on GitHub now and update the links on the article, that way it could be easily browsed.


Someone webassembly this :)


Has been done already, in a way. Check out https://infinitemac.org




Consider applying for YC's Fall 2025 batch! Applications are open till Aug 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: