User Tools

Site Tools


philosophy:main

jMax History

You find some discussion of jMax history in the LAC 2009 paper. The paper, the slides and video of the presentation can be found at http://lad.linuxaudio.org/events/2009_cdm/Friday/11_DeCecco/index.html

Why jMax

Recently i found this article comparing jMax and Pure Data, i think presented at the ICMC 2000 conference, and i think it is a good occasion to go back to the original jMax design principle and essentially to try to answer to the Why jMax in more complete a structure text. Also there are nice discussions of Miller Puckette on his ideas behind Max and Pd, that are interesting starting point for discussion casino en ligne francais halloween contacts link building service Restaurant Deals.

There is no intention to compare here jMax and Pure Data. But one of the objectives of the jMax project was to overcome some of the limitation of the older member of the Max families, that had an architecture very close to the Pure Data architecture (of course, coming from the same author). So, many of the comments the paper does apply to the comparison between jMax and the previous versions of Max, targetting essentially the reason for creating jMax. I'll go thru the article, commenting each point.

Users and Software Engineering

You may find in the pd mailing list references to Miller Puckette note on the fact that Max sn't a “programming environment”, and even less a “real-world programming environment”; features are left out because Max users aren't professional programmers, and similar opinions.

I have the greatest admiration for Miller, and very nice remembering of the time spent together working on the ISPW.

But i do not share these positions; IMHO, it is true that you have different categories of users of the Max languages, and that the great success of Max depends on the fact that it can be used quickly and productively by someone that is not a professional programmer.

But once you work one year to produce a large patch library, like it was done in Ircam, you *are* a professional (Max) programmer. Once your professional future depends on the fact your patches works without glitches, you want a development environment offering you all the tools you need to secure your success. Once you publish your patches on the internet, you are allowing others to reuse your work. And so on.

For decades, people dealing with software had to deal again and again with the same problems, problems that you find also in Max: being able to use a third party patch without screwing out yours, being able to understand and modify a patch you wrote one or two years ago, being able to manage a big project with many actors.

There is nothing wrong in seeing what others do in the same case; of course, you can always roll your own solution, too, but sometimes proven solutions may be easier to put in place and to understand; sure, generated IDs works, but well defined scoping may be simpler to understand and use, for example. Complex scoping, on the other side, can make life hard.

The goal is keep the nature of the language, the low entry barrier, the spontaneous approach, but also to allows handling complexity when the need arise.

Evolutivity

One of the main design principle in jMax was Evolutivity: get ready for the future, build a foundation that could be used to build new functionalities without making the system implode.

One striking difference between these two programs is in overall design; jMax is modular while PD is integrated. Modularity is perhaps the most
prominent feature of jMax as can be seen in the client/server model, the separation of the Max objects into individually loadable packages, and in 
the use of modules to provide the majority of the server functionality. For example, the FTS server uses modules to provide scheduling, message
passing, file handling, signal processing, a configuration system, client communications, and audio input and output. 

True (at least, at the time, and if you apply the comparison to jMax and Max/FTS). The main goal of the whole architecture was to be able to add incrementally new functionalities, so that the system could evolve and adapt easily.

The effect of these choices can still be seen in jMax Phoenix: for example, adapting the user interface to a totally new user interface framework required minor modifications of the existing code; the code size of the Java user interface is today less than 10% bigger than the code i started with. The porting to Windows, MacOS X and to new audio and midi technology will require little or no modification to the existing code, including the audio engine and the configuration system.

Being able to have jMax evolve without introducing instabilities was a goal deriving from the high level of quality needs we had at the time. When the success of this night concert depends on the fact you haven't added any new bug, these kind of things are important.

The sad point that must be raised here is that there is no point in investing in the future when there is no future, and if this future is not managed in a coherent and focused way; so, before jMax Phoenix, all this was just a nice experiment in software engineering.

This allows PD to be a much simpler and smaller while providing comparable features; PD has only approximately 
25,000 lines of source code compared to 150,000 for jMax

It is true that modularity and clean coding may have a price in term of code size, but you must be sure to compare apples with apples and oranges with oranges.

It is difficult to say if the above estimations of the jMax code size where correct or not, because no version number is reported. Anyway, the sources of jMax include the whole set of externals that where implemented in the ISPW, needed to run existing compositions.

If you compare the core code size, without objects, we currently get 35000 of C code and 25000 lines of Java for the user interface. The original jMax 2.4.5 i started from had 34000 lines of C code and 22000 lines. This numbers shows that while surely bigger than PD at the time, the difference was not as impressive as reported.

But the real point is how a program evolve, not how it is at a given moment in time. As of today, i cannot say if the jMax kernel code will survive evolution or need to grow a lot more. It would interesting to analyse how the tightly integrated PD evolved in size in the last 9 years, to see if the lack of modularity was actually an advantage in the long term (OK, of course, yes, i counted the pd code lines, around 93000 in the pd kernel, but i don't know if i am comparing apples and oranges here :-|).

By the way, please note that code size has been measured using SLOC Count by David A. Wheeler.

Industrialisation

Another important aspect of jMax was its orientation toward a better industrialisation of its use.

In the context jMax was used, it was common to have a team of two or three people working a year on a single patch, representing a composition. It was also common to have a team of two to four people working on abstraction library or a library of objects for years, release two or four version a year.

The fact the Max is a visual and fun language should not make us forget the fact that Max is a programming language, and that projects as the above are standard software development projects.

So, the priority at the time was to support this view. In a two years development project, adding ten lines of scripts for well packaging your product is not a significant cost, as adding twenty lines of scripts to make your product works in different hardware and i/o configurations. So we provided the technical means to package and configure a product, to assure that an execution environment working on the development machine could be quickly, safely and surely reproduced on the concert machine, that a library could simply specify dependencies on other libraries, and so on.

And since the priority was to support the big, internal, development projects, the effort was put in delivering the mechanisms, like integrating a scripting language, than on providing easy to use graphic interfaces, for example.

This made sense at that point in space and time. Does this still make sense ?

Yes, with a grain of salt.

Patch development and library development is still software development, and all the lessons learnt in software engineering can be applied to jMax.

But new technologies, new ways of doing things arrived in the last 10 years, so jMax Phoenix is trying to adapt the modern times.

Using a scripting language to define packages for example prevent the later use of graphical interfaces, because the information is not available in a declarative form. jMax Phoenix is migrating from a scripting language to XML for configuration and packaging. This allows an incremental development. Current facilities are based on hand coded XML, but later this XML can be generated and edited using higher level tools.

Big projects need sophisticated mechanisms, but small and quick projects need something that just works. jMax Phoenix is adopting the philosophy of convention over configuration where the system is able to choose default behaviour in all cases that are adapted for most of the simple and medium complexity case, so that configuration is needed only in complex cases.

Finally, one of the objectives of jMax Phoenix is to be able to use a package directly from the Web, allowing the creating of central repositories of packages, extending the jMax Phoenix functionalities for every developers, following the maven repository idea.

Language

Both programs have extended the Max programming language to address common issues. jMax introduces named variables and expressions. These variables,
which are static at runtime, have the main advantage of limited scope. They are visible within a patch and its subpatches, but not parent patches.
Variables or variables used in expressions can be used in the instantiation of objects, adding considerable flexibility. 
PD removes integer types and uses only floating-point types for messages, simplifying the internal structure and dramatically 
reducing the overall size of the program.

I can add that jMax added the $ variable abstractions as pd did; by the way we did not know about pd and its abstraction at the time, so it is probably a case of parallel independent development of the same feature for the same reason. Named variables are a generic way, supported at the kernel level, to bind objects to other objects providing a common data structure, like a delay line reader and a writer to the object implementing the delay line, and so on. Expressions add to the language expressive power, at the price of a little of complexity.

About float and ints; jMax have a fully generic type system in the control part, and a fully generic API. Object methods signature do not depends from the message type, like in previous version of MAX and in Pd. Method dispatch is implemented in a generic way, and there is message dependent code. So, at the end, the code for handling messages is very small, a lot smaller than in the older MAXes. You may think that methods may be less efficient, thanks to the genericity of the API, but this is actually not true, because most of the time there is less need to copy data around, and you pass just a pointer. Also, message dispatching is very very fast in jMax, because every connection have a one slot cache with the method pointer. Considering that most if not all of the objects do not change dynamically the type of the value sent on an outlet, 99.99% of the method calls are done using the cache, and not doing a method lookup.

DSP

The most important aspect of both of these programs, and an area of significant difference, is the way in which they execute the signal-processing
graph. jMax uses a virtual machine, called FTL, to execute a compiled DSP graph consisting of both signal-processing functions and data that is 
separate from the control portion of the object. This allows for the optimization of the signal-processing, facilitates the planned multi-threading of 
the FTS server by separating the signal-processing functions and data from the object, and provides several features including error detection. 
PD executes a signal-processing graph by iterating through a function call list in a manner that makes it possible to abstract portions of the graph. 
The implementation of the abstractions is very flexible and has the potential to be used to solve a variety of difficulties. Currently, this allows 
control of signal vector size and overlap, greatly simplifiying the use of algorithms that require a large number of samples. 

The above, for what regards jMax, it is at the same time correct and wrong. The point is that while in the architecture there is layer called FTL that make the role of a virtual machine and allows for future extensions and evolutions, the implementation of FTL just executed a list of function calls, exactly like the previous versions of MAX.

So, it is mostly an example of modularity. To see how modularity can be used: in the future, FTL will be remapped on LLVM, a real virtual machine including JIT compilation to native code. The existing objects do not need to be aware of the change (while new objects will be able to generate directly LLVM code).

philosophy/main.txt · Last modified: 2011/12/14 20:42 (external edit)