In this tutorial, we will extend the concept of encapsulation to include abstraction – the ability to have subpatcher logic live in a separate, reusable file that you can then use inside of any patcher you like.  Once saved outside as a separate file, abstractions can be modified to use arguments to make a generic Max patch useful to your specific application.  By using abstraction for your most-used programming tasks, you will be able to reuse that work for future projects without any other programming at all.
Abstractions are key to supporting your increased Max knowledge while maximizing your ability to reuse previous work.  The abstraction mechanism can make your subpatches look and act like built-in Max objects, and can also accept arguments to further tune its functionality.
In our tutorial patcher, you will see that there are three different patches.  In this case, each of them do the exact same thing, but at different levels of abstraction.  The first section (labeled 
1) is the fully-functional patch.  If you turn on the 
metro with the 
toggle, we see that the patch tracks your cursor around the screen and draws a scaled version of your mouse movements in the 
lcd display.  We make use of the 
bucket object in this patch; a simple example of the object is shown on the left next to the 
lcd; in its most simple form, upon receiving a value, 
bucket always puts out the last value it received.  This makes it useful as a single-event delay object, which we use in the main patcher to construct 
linesegment messages that link the current position of the mouse to its previous position.
In the case of section 1, we have a lot of logic on the screen, and it might be useful to encapsulate it into a subpatcher (as we did in the previous tutorial).  However, the patcher logic that polls the mouse and scales it based on the size of our screen looks like something that could be useful elsewhere; it would be interesting to have it available for other patches without having to copy and paste from one patch to the next.
This is where abstractions come into play.  An abstraction is a subpatcher that is saved as an external file, and can be used just like a standard Max object.  As long as your abstraction can be found in the Max file path, you can type its name into a new object box and it will be loaded directly into your patch.  The abstractions used in this tutorial are in the same folder as the patcher accessing them; a library of abstractions can easily be created by placing them in a folder (or a bunch of folders) inside the "patches" folder of your Max installation, or anywhere else Max looks for files.
The second section of our patch (labeled 
2) shows an abstraction at work.  Turn off the 
metro for section 
1, hit the space bar (which will 
clear the 
lcd) and turn on the 
metro for section 
2.  You will see that the program works exactly as it did before.  The “object” called 
WTHITM (for "Where The Heck Is The Mouse?") is actually an 
abstraction of the scaling logic from section 
1.  If you double-click on the 
WTHITM abstraction, a new patcher window will display the contents of this abstraction.  Notice that this looks very much like an encapsulation with one exception – you cannot unlock the window to edit the contents.  This is because 
WTHITM exists as a separate patcher 
file living in the same folder as our tutorial patch.
Abstractions are meant to be shared among several patches, so you would not want to edit the contents in one patcher, since this might break its functionality in other patchers. If you do want to edit an abstraction, you need to open the abstraction file itself.
While there are several ways to open the abstraction file, we'll mention only two: We can open a New File Browser (from the File menu) and type WTHITM into to the search window and then double-click on the patcher file that appears in response to our query, or we can Alt/Option-Click on the title bar of the WTHITM patcher window - a pop-up will appear with the patcher hierarchy from the abstraction leading up to the top.  If we select WTHITM, the original file being referenced will open within Max. However you choose to do it, open the WTHITM source file.  You will again see the abstraction contents, but now you can edit the logic.  If you change something and save the file, all patchers that use this abstraction will reflect the changes – even if the patcher is currently loaded.  You can see this in action by adding a second inlet to the WTHITM abstraction and saving it.  The instant that Max sees a new version of the abstraction, it reloads it and adds a new inlet to the WTHITM abstraction in your tutorial patch.
While we have the 
WTHITM patch open, let’s look at the documentation that has been added to the 
inlet and 
outlet objects. If you open the inspector for the 
inlet, you see that there are several different types of built-in documentation.  The first is called 
Annotation; any text placed in the annotation field will show up in the 
Clue window when you hover over the object. Text placed in the second documentation field, the 
Hint field, will display in a hint balloon when you hover over the 
inlet object in a 
locked patcher.  Finally, text placed in the 
Comment section doesn’t display in the patcher; rather, this text is shown as the 
assistance text when you hover over the 
inlet of the "object" in the higher-level patcher.  It is wise to document your 
inlet and 
outlet objects in often-used abstractions, since it can provide simple but effective documentation for your reusable logic.
In our 
WTHITM abstraction, there is no logic that needs to know about the higher level patcher.  However, what if we wanted the abstraction to properly scale the output based on our 
lcd object’s size?  In this case, we would have to inform the abstraction of the 
lcd display size, which we can do using 
arguments to the abstraction.
Section 
3 of the tutorial patch is similar to section 
2, but the abstraction used is called 
WTHITM_scaled, and includes two 
arguments that represent the horizontal and vertical sizes of the 
lcd object. If we open the "WTHITM_scaled.maxpat" patch (using the 
Open command in the 
File menu), we see something very interesting: the multiplication factors use 
#1 and 
#2 as placeholders for values to be provided as arguments.  As you might expect, 
#1 is replaced with the value of the first argument, while 
#2 is replaced with the value of the second.
The use of these replaceable values (called 
pound-sign arguments) is key to making abstractions that are flexible and reusable.  If you would have “319.” and “239.” hard-coded into the abstraction, you could only use 320x240 
lcd objects to display the mouse movements. On the other hand, if you forced the top-level patcher to perform the final scaling (as we did in section 
2), you are forcing the top-level patch to duplicate work that could be easily abstracted into the lower-level patch.  By using replaceable values in your abstractions, it makes the high-level patcher as simple as is practical.
By saving your logic in an abstraction, you can create modules that can be used in future work with little or no additional programming.  This allows you to parlay your Max knowledge into more efficient work in the future, and will help you create programming systems that are modular and easier to maintain.
See Also
| Name | Description | 
| bucket | Pass a number from outlet to outlet, out each one in turn |