The jMax Language : jMax is not Max

jMax is based on the same programming paradigm as the other members of the Max family, but it go a little bit further, and introduce a first set of language extensions to augment its expressive power, and to finally simplify the life of patch programmers, by giving better ways to customize and parametrize patches and patch libraries, and to refer data from objects.

This first release of jMax introduce the set of basic mechanisms; these mechanisms will be used as the fundation for a new object library, and will be extended in future releases.

Objects and Patchers

A jMax programm consists of objects, which appear in the context of a patcher and can be connected via connections between their inlets and outlets in order to pass messages between each others.

In general a jMax object represent a statement in the jMax language; as in other programming language, a statement may realise an operation, or declare some data structure (variables), or make reference to system resources (like i/o channels).

The patcher context helps to make modular jMax programms. A patcher can have in- and outlets and can appear in form of a subpatcher or a template just like an object inside another patcher. It is the jMax equivalence to subroutines, functions or classes.

Variables

A variable is a symbolic name associated to a jMax object, that reference a data structure represented by it.

Variables are a generic mecanisms defined to be able to globally share a data structure between objects (a table, a sample, a MIDI sequence, a delay line, a input/output bus, etc).

In older version of the MAX language the sharing of data structure was done with object specific mechanisms, like delay lines. jMax provide a generic mechanism that can be used by all objects representing or using a shared resources.

Any objects can export data by using a very simple API (to be documented) an example is the object const, an object without inlets and outlets, export a value, that correspond to its first argument.

A variable is declared by prepending the variable name followed by a semicolon to the object description, like in sr : const 44100.

A variable value can be used in the instantiation of an object. An argument in the form $variable-name is substituted with the reference to the correspoding data structure before the object is instantiated.

Since the variable substitution is handled by the system, the object code don't need to know about variables, and all the object can be used with variables as arguments.

jMax use local scoping for variables; this means that a variable defined in a patcher will be visible in all its subpatchers, but it will not be visible outside the patcher of definition; a patcher see all the variables defined in its parent and ancestor patchers.

The flexibility given by this scoping rule avoid conflicts and errors in reusing variables names and simplify writing reusable patches.

Variables will be the preferred way to handle reference to any kind of data in the future (like table and table~ objects), so that locality of scoping will be available to all the form of data referencing. In a future version, local variables will be accessible from the outside of a patch by using a composite variable name (like $spat.input.level).

The system keep track of all the dependencies between variables, and automatically update all the depending objects when a variable change value as an effect of an editing operations; since variables can depend on variables, the dependency handling is recursive; all the unresolved dependencies handled as instantiation errors (red objects); the resolving of pending dependencies cause automatic object reinstantiation.

A variable can also contains an array of values; an array can for example be defined by the object rates: const {32000 44100 48000}, and accessed with the standard syntax <tt>$rates[1]</tt>.

Expressions

As we saw in the previous paragraph, we can use a variable in instantiating an object, by putting a $ followed by the variable name in the object arguments. The dollar sign is an evaluation operator, that applied to a name return the value of the corresponding variable; the sequence $name is a very simple expression.

jMax actually support more complex expression; an object argument can be defined as the result of an arbitrary complex expression; the expression syntax is derived from the C programming language expressions, and include parentesys, all the arithmetic, logic, bit-by-bit operators, the conditional operators, array access and function calls, and the variable evalution operator $.

Also the object class can be defined by an expression. Functions calls are calls to a set of predefined functions; this release define a single function, unique() that return a unique number each time is evaluated; future releases will include a complete function library, and the possibility to define functions thru a C API.

The arguments of an object must be simple expressions. A simple expression is either a variable access operation, an array access operation, or a expression between parentesys. In other words, an expression used as object argument should be enclosed in parenthesis.

In the following example patch, we define three variables to parametrize a table object size with respect to the sampling frequency; note that the variable sr will be a system defined variable in a real patch programming case.

Another way to define a variable in jMax is provided by the patcher object.

A patcher object implicitly defines a variable args in it's context containing the arguments of the patcher (including its name).

The arguments passed thru the args variable are positional parameters, i.e. they are assigned to positions in the args corresponding to their position in the patcher object. A patcher can also have named parameters, i.e. define new variables explicitly, adding at the end of the arguments a list of assignement in the form variable = value.

Templates

A template is the implementation of a new object in the jMax language itself; a template definition is the content that will be used to produce new objects; in jMax, any patcher can be used as template definition, because, as we saw in the previous paragraph, the language itself provide a generic mechanisms to pass arguments to patchers, there is not need to make a distinction between a standard patcher file and a template definition file.

Since Templates use the same argument passing paradigm than all the subpatchers, positional and named arguments can be used.

There are several way to define templates, depending on your configuration, and on the project you are working on. Please refer to the wiki page [[ProjectEnvironment | project environment settings]. In general, you define a number directories where template can be stored.

Any file foo.jmax saved to these directories will automatically define a template called foo. You can simply edit a patch and save it to this directory to define your first template.

This method has a problem (common to the ISPW Max environment): Since you are editing a template body, the variables (arguments or variables inherited from the outside scope) used by the template are not defined, so you can neither complete the editing, nor test the template body.

A better way is to create the template you want to define within the context where you want to use it (or in a similar, ad hoc test oriented context). For example, in an empty patcher, create a subpatcher object with some example arguments that you would give to the template, create the template body, test it, and when it work reasonably well, and save the subpatcher it to your template directory using the menu item “Save To” in the patcher editor Once saved, you can instantiate it as many time you want.

What we said about a new subpatcher apply as well to any template instance; you can modify a template instance and save it as the new definition for a template. This is possible because the object text in the template instance is not changed, but stay exactly the same as in the template definition (i.e. the definition of a template is one example instance).

Please note that saving a new template definition will automatically redefine all the existing instances to conform to the new definition.

Note: The template concept is very close to the abstractions of ISPW Max. We use a different name to avoid confusion, since jMax is able to load and use also the older ISPW Max abstractions.

Lexical Conventions

Some simple lexical conventions are applied to whatever one types to a jMax object. On this level intergers, floats, symbols are recognized as follows:

  • integers: A string of an optional sign followed by decimal digits and terminated by a terminating token is interpreted as an integer.
  • floats: A string of an optional sign followed by decimal digits, followed by a decimal dot, followed by some more optional decimal digits and terminated by a terminating token is intepreted as a floating point number.
  • symbols: A string of characters included between double quotes is interpreted as a symbol.A string of characters others than an int or a float terminated by a terminating token is considered as a symbol; a backslash followed by a terminating token is considered as a standard character and do not terminate the symbol.

In addition to the blank charakter the following characters are acting as separators in any textual description of a jMax object:

$ , ( ) [ ] { } : . ; '

This makes for example that the text 1,2 actually represents three symbols “1”, “,” and “2”, while 1+2 represent a single symbol “1+2” (since the binary operators are not considered as separator tokens an expression with a binary operator like 1 + 2 must be written using blanks between the operands and the operator).

(Note that the lexical conventions of jMax differ slightly from that ones of ISPW Max! Objects loaded from original ISPW patches are converted on the fly.)

 
user/thelanguage.txt · Last modified: 2009/04/03 13:53 by maurizio
 
Except where otherwise noted, content on this wiki is licensed under the following license:CC Attribution-Noncommercial-Share Alike 3.0 Unported
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki