The dollar sign ($) is a special character which can be used in a message box to indicate a changeable argument. When the message box contains a $ and a number in the range 1-9 (such as $2) as one of its arguments, that argument will be replaced by the corresponding argument in the incoming message before the message box sends out its own message.
When a message box is triggered without receiving values for all of its changeable arguments (for instance, when it is triggered by a bang), it uses the most recently received values. The initial value of all changeable arguments is 0.
A message box will not be triggered by a word received in its inlet (except for bang), unless the word is preceded by the word symbol. In that case, the $1 argument will be replaced.
If you want to use a dollar sign in a message without it having this special meaning, you should precede the character with a backslash (\).
The expr, if, sxformat and vexpr objects also use the changeable $ arguments. When you use the $ character with these objects, it must be followed immediately by the letter i, f, or s, which indicates whether the argument is to be replaced by an int, a float, or a symbol.
If a message received in the inlet does not match the type of the changeable argument when using these objects (e.g., if an int is received to replace a $f argument), the object will try to convert the input to the proper type. The expr and if objects cannot convert symbols to numbers, so an error message will be printed if a symbol is received to replace a $i or $f argument.
When you are editing a patcher which will be used as a subpatch within another Patcher, message box objects and most object boxes in the subpatch can be given a changeable argument by typing in a pound sign and a number (e.g. #1) as an argument. When the subpatch is used inside another Patcher, an argument typed into the object box in the Patcher replaces the # argument inside the subpatch.
This lets you use typed-in arguments to supply information to patcher objects and abstractions you create just as you with with regular Max objects. This #1-style argument is a changeable argument that is replaced by whatever number or symbol you type in as the corresponding argument when you use the patch as an object inside another patch. You cannot use a changeable argument to supply the name of an object itself, but you can use it anywhere inside your object as an argument.
You can use a pound sign and a number to provide variations on a name as a part of a symbol argument (e.g. #1_velocity), but the changeable argument must be the first part of the symbol - (e.g. #1-dial will work, but dial_#1 will not).
You can use this technique to create unique names for send and receive objects in a subpatch (e.g. send #1_currentvalue) in order to guarantee that the exchange of messages between objects will only happen within a single (local) instance of your subpatch.
If you are opening a patcher file automatically by sending a load message to a pcontrol object, you can use this method to set values inside the patcher being loaded by providing changeable # arguments as a part of the load message.
Using a zero as with the pound sign has a particular and special meaning. When used as the beginning of a symbol argument (e.g., #0_value) it transforms that argument into an identifier that is unique to each and every patcher (and its subpatchers) when it is loaded. This special usage lets you open multiple copies of a patcher that contains objects like send and receive while having the send and receive destinations remain separate for each copy of the patcher. Note: the numbering of these unique identifiers is done by Max itself, and is not under user control.
Max uses a global name space - Max objects that have names associated with them for collections of data (such as coll, table, or buffer~) or objects that specify named sources or destinations (such as send and receive) share data. This allows you to share data between subpatches and abstractions in Max patch, or to share data between Max for Live devices (in the case of Max for Live devices, the name space is shared, but the "signal processing space" is separate; each Max for Live device processes its audio or data separately).
If you want a named object to be unique to a device, use three dashes (---) to start the name of your buffer or send/receive destination.