Any plans to update support for recent versions of JS?

estevancarlos's icon

As it is now, Max supports javascript 1.6 which is known as ecmascript 3. Javascript is now, slowly moving into ecmascript 6 with increasing support from popular browsers. There are some sensible reasons we should all stop using js 1.6, one of which is that it no longer supports coding standards appropriate for javascript--the use of arguments.callee and arguments.caller are somewhat deprecated in ES5 for example and possibly removed from es6. Many new javascript developers are learning very new ways to write proper code with js especially with the introduction of classes and new features in es6. Is it time to update javascript in Max in order to keep up with a few new developments and new javascript programming standards? Eventually it will be awkward writing javascript in the "old fashioned" way in Max.

Andro's icon

A built in debugger, autofill and a library of very clear simple examples is all I'd like from Javascript in Max.
After many failed attempts to use it I just kinda gave up on it a while ago. ( i still can't get an external editor to work with it)
As I've stated before the tutorials go from 0 to a 100 at tut 2.
In processing I learn new things all the time due to the feedback from the software.
A new improved version ?
Yes please :)

ak's icon

I second that request. Eg. arrow function notation allows more concise functional programming, the heart of many algorithmic composition concepts. Not to mention generators and proper collection types.

estevancarlos's icon

I just realized that the documentation in Max is out of date. It states JS is based on es3 but I tested an es5 array method and it works. Max's documentation is making me look kinda stupid.

Anyway, I still think Max should keep it's eyes on es6 and I hope to see that support in a few years. It's not critical now. However in a few years it will be. They should also remove that whole callee/caller thing.

estevancarlos's icon

@ANDRO Debugging in JS has, to my understanding, been messier than other languages. I think that's a challenge that will exist for some time. However there is a way to edit with an external editor but sometimes, from my experience, despite using autowatch = 1, you may sometimes need to close your patch and reload it in order to detect changes. I'm not sure what causes this.

@AK Yeah, it's hard to dislike es6. I won't use the word "beautiful", I'll reserve that for Python, but es6 is inspiring. I just noticed how it fixes string interpolation.

es6:
'a total of ${card.amount * card.unitprice} bucks?';

es5 below:
"a total of " + (card.amount * card.unitprice) + " bucks?";

No extra quotes. Easier to read. Sooo refreshing.

jonah's icon

i was wondering if js engine as part of what's in jweb/chromium embed framework might be integrated more in the future? there are browser based code editors and the max 7 reference does some neat stuff with html/how it works with max patcher, drag n drop. plus web stuff in general has a wide variety of people working to make it faster, better for interface/presentation stuff. i guess google and mozilla are both doing stuff to turn js into asm?

seems like both js, gen and a few other objects would work well with easier ways of feeding in html frontend for viewing/editing. then the language could be abstracted further. when doing code stuff i think it could be useful to think more in terms of 1 language. like in gen tag the 'js' with or something, then write in a more gen style, like when you want to do more macro data/procedural structure stuff where gen gets tricky and switching code syntax/ punctuation/grammar gets me making silly errors. i feel like js in max now is kinda divided in terms of if it's for patcher scripting or data manipulation. plus most of the time i'd rather think/work more max/msp/gen style :) prefer js for more meta stuff dealing with the patcher/layout in a programatic way.

Max Patch
Copy patch and select New From Clipboard in Max.

interesting thing is that w/ jweb website data in get saved somewhere, at least temporarily, i can quit, re-open max and still see changes in web based editors. no ad block in max browser is not so good though. :)

Gert's icon

+1 would be great to have an idea about the roadmap here, I'd love to have access to the 'Set' and 'Map' objects of ES6 :)

knasterbugg's icon

Javascript 1.6 was released over ten years ago! I work professionally with Javascript for both browsers and servers so opening up a Max patch and doing Javascript there feels like
going back to the stoneage. It's such a shame and I really hope we can make a big leap towards a more modern Javascript environment!

I think looking at V8 (the Javascript engine) to see how it can help would benefit enormously. It's the engine that runs javascript in Chrome browser, Node.js and MongoDB, so clear
ly a trusted technology. Also, if V8 is used we get free upgrades by letting the V8 team implement upcoming Javascript features!

Any core developers here to comment on this?

Joshua Kit Clayton's icon

The implementation that integrates completely with Max is based on the spidermonkey engine (and specifically the jaegermonkey JIT compiling version) and corresponds to Mozilla's Javascript 1.8.5 (which is a relatively modern ES 5+ version). There are no plans to update this to more modern engines in the near future, as it represents a significant amount of engineering to do so.

For those of you that wish to develop in ES6/2015 or make use of other modern language features, you have two paths:

1. Make use of a transpiler like https://babeljs.io/ targeting ES 5 output. This is very common for web developers and there are a number of utilities like gulp and such to make your development more smooth to code and have it automatically transpile and update in the background: http://www.barbarianmeetscoding.com/blog/2016/02/21/start-using-es6-es2015-in-your-project-with-babel-and-gulp/ (I'm not an expert at JS toolchains, so please spend some more time googling around if these links aren't enough to point you towards an appropriate workflow).

2. We do use the Chrome Embedded Framework for the implementation of jweb. And you can run javascript inside jweb and communicate back and forth to/from max (asynchronously as it runs in a separate process). This also gives you access to other web browser related extensions which are not in the core language such as DOM utilities, websockets, a more robust XMLHTTPRequest implementation, etc. It isn't going to have the kinds of patcher integration that we have with the integrated spidermonkey version, however. A really cool project which shows this in operation is this one that runs p5.js inside max, recently posted here: https://cycling74.com/forums/sharing-is-maxmspjitter-and-p5js

Hope this gives you a few options to explore.

Lee's icon

nice, thx for the info

nick rothwell | project cassiel's icon

If your argument for a more up-to-date Javascript is newer language features, you could make the jump to CoffeeScript, which I find to be a much more pleasant language to work in (modulo one or two slightly sharp edges in the syntax). It has lambdas, list comprehensions and string interpolation for starters.

yaniki's icon

@Joshua: thanks for mentioning my activities and really comprehensive explanations about Max and JS.

I'm not a JS expert (especially about versions and implementations), but from my perspective I totally agree about your remarks on the [jweb] object - it's a gate to really nice possibilities. Actually nearly all my projects are in some way connected or controlled over internet and mobile devices and on Max side I'm always using [jweb] to handle this kind of stuff. Also more advanced JS structures (+ browser related actions) are in my opinion easiest to integrate within [jweb].

And, instead of using "pure" HTML + JS environments such as P5*js are bringing "scripting" into totally next gen level.

@ESTEVANCARLOS & KNASTERBUGG: try [jweb], guys. For bidirectional communication with Max check my "MaxMSP/Jitter and P5*js" simple solution mentioned by Joshua (https://cycling74.com/forums/sharing-is-maxmspjitter-and-p5js/#.V6MZbmXwy_M) - it' s about P5*js, but working with "ordinary" JS is even simpler.

And here is a demo, how/why you may use web-content (with a lot of JS) loaded inside [jweb] in deep integration with Max: http://paweljanicki.jp/projects_algorithmiclines_en.html

Btw. I'm working on some new stuff intensively using [jweb] and "MaxMSP/Jitter and P5*js" - I think that soon I will be able to share some new ideas and techniques on this forum ;-)

Valery_Kondakoff's icon

As far as I can see there is still ES5 in Max8 (while Node for Max uses much modern version). Any chances JS in Max to be updated?

Joshua Kit Clayton's icon

@valery There are still no plans to update the internal version of JS as used by the js and jsui objects in Max in the near future. The conditions of my earlier reply on this thread remain the same. For more modern JS usage without transpilation, you can use jweb or node for max, and otherwise, you can make use of a transpiling solution as mentioned (node for max could actually be used to accomplish the transpiling in a more integrated fashion, fwiw).

Valery_Kondakoff's icon

Joshua, thank you for the info. It's a pity, there are no plans to update JS used in js/jsui to the ES>5, which is _really_ outdated... I'm not sure it is a good idea to support outdated standards in Max, but, of course, there are reasons for this. Maybe one day we will be able to use Node for Max for patcher scripting/working with Jitter? ;)

Joshua Kit Clayton's icon

We'd love to migrate to a newer standard, but the amount of low level spidermonkey-API specific code in place for our JS integration makes this prohibitively expensive to do and retain backward compatibility with the 15+ years of user code that exists. Someday we might be able to eliminate that technical debt, but it's something we have to balance as a cost against other desirable features and improvements. Yours and other's requests for this to be updated is registered. Thanks!

FWIW, most client side JS web developers I know typically transpile their code to ES5 for universal browser support, so I'd encourage you again to not rule that out as a workflow. Babel is pretty great and there's lots of other utilities out there to make it easier than you might otherwise think. Again, Node for Max could be helpful for that.

Jay Walker's icon

I used JS with Max as a way to learn Javascript. But to know that they are stuck on a very old version of JS totally defeats the point! I can't really expect to ace an interview without knowing the newest things, only relying on an archaic style of scripting! Please update!!!!!!!!

Roman Thilenius's icon

for me it is still a mystery why some people are using javascript or java in max to mostly do things which you can as well do in max itself, where it is 15 times more effective than in javascript.

mind you, a java SE is not even part of OSX anymore.

Florian Demmer's icon

Just as a heads up, I did some work on a tool to help with porting modern EcmaScript to be run within [js]. Apart from the transpilation it should also support bundling of npm dependencies when possible (f.e. no native extensions). There is some further work to do (it fe. does not account for converting setTimeout/setInterval to use the Task Object atm) but in my limited tests it seemed to do the trick for small scale examples.

Would definitely appreciate any feedback or contribution to see what might be missing at this point.

The tool comes in the shape of an CLI tool and is available via npm:
https://www.npmjs.com/package/max-js-bundler

For a more contained version or people without a Node install on their machine there is also a simple example wrapping the functionality with N4M:

Florian

tenandtracer's icon

Only just now noticed this. Wow. Going to spend some time exploring this for sure.

Andrew McNaught's icon

Perhaps there is a solution to this problem that does not require a re-write of the js object? I am thinking something along the lines of a new object that serves as a transpiler and bundler? The benefits of being able to quickly leverage the modern JS ecosystem seem to be inline with Max's design philosophy.

estevancarlos's icon

I think you're on to something with the transpiler object idea. One thing Cycling should consider is that many newer people studying JS are only focuses on the recent ECMAscript version. For example, I teach students to avoid the var keyword.

fraction's icon

I'm really getting into js in max. Years after just using max.
It's very complementary in the environment and I would say almost essential. It became my usual workflow when the project is not just the creation of a patch, but the development of more integrated tools. When you plan to have a patch where a lot of messages have to be sent, the chord patching technics has reached its own limit. Basic algorythmic iteration (and also for loop) are also much easier to think with JS compares to max objects data flow.

@roman i think you miss the interest of using js. For most of the classic 'maxmsp' task, using normal max object is way better, but for instance, if you want to develop UI with dynamic controls, a script based langage is much more effective, and allow interacting and maintaining the code in a more efficient way.

So i understand the issue of updating JS in max, but i would really enjoy to see that happen in a close future :)

loadmess's icon

Sorry my silly question, I just wish to get a broad view of the JavaScript integration in Max.
Doesn't node4max uses a more recent
ECMAscript / js version?

Side note, I wished several times there's was a outside of Gen codebox to overcome those moments where cabling reach their limits. From what I can grasp, codebox architecture would be more efficient.














































Joshua Kit Clayton's icon

I just wanted to follow up here that a modern JS engine (v8) is finally available for in process ES6+ javascript in Max. Thanks for all your patience. A lot of work went into making this happen.

Supported language features are ES2022 plus some of ES2023 (same language support as node 18 column in this compatibility chart https://compat-table.github.io/compat-table/es2016plus/).

Valery_Kondakoff's icon

That's it! Great!

Just to make sure: the modern JS engine (v8) will be available in Max 9 only, or there will be an update for Max 8?

Thanks!

Joshua Kit Clayton's icon

The v8 js engine will be available in Max 9 only.

estevancarlos's icon

Heh. I remember posting this question. I remained hopeful and ES6 has arrived. Great work.

Valery_Kondakoff's icon

Almost decade!.. ;)

Mattebass's icon

Is there any change in the scheduler priority with the v8?

Joshua Kit Clayton's icon

No it is still in main application thread only.

Iain Duncan's icon

The JS object has the advantage and disadvantage of being a global intepreter. This is cool because it means you can share global data between js/v8 instances. On the other hand, they aren't isolated, which would make cross thread safety a nightmare.

If you want scripting in the high priority thread, you might like my Scheme for Max, which runs in the scheduler thread. This is possible because Scheme's are ultra-minimal, so the interpreter I used (s7) is totally re-entrant with the entire interpreter embedded in the C code for the external. You pick the thread your instance will run in (default is high), and it is completely isolated from other instances.

More info here if you're interested. I'm working on array and string support for a new release in the next month or two. It is much less full featured than the JS object but runs like a hot damn for tight timing. I make sequencers in it and run them in Max for Live and am able to sync up perfectly with the Ableton sequencers. Scheme is semantically quite similar to JS (it was a major inspiration for the JS design), though syntactically very different.

Shakeeb Alireza's icon

@JOSHUA KIT CLAYTON + cycling74 team

Great work with Max 9.. Really love the improvements overall and also the backward compatibility with current externals is amazing!

I have a couple of questions related to v8, etc.. :

  • What's holding you back from replacing the js object with the v8 engine, considering the latter is a superset of the former (I think)?

  • For external developers, do you have plans for jsextensions (c or c++ compiled objects which can be loaded in the js object) to eventually work similarly with the v8 engine?

  • In the case of Max standalones, if one exclusively uses the v8 engine instead of the js object, is there a way to reduce the size of the standalone which is massive (~500 MB for a hello world example) by omitting the part that supports the js engine while retaining part that supports the v8 engine?

S

yaniki's icon

@JOSHUA KIT CLAYTON + cycling74 team

Yeah, v8, jweb~ and expanded codeboxing are really great things, thx for this!

Joshua Kit Clayton's icon

@Shakeeb Alireza, Thank you for the kind words!

What's holding you back from replacing the js object with the v8 engine, considering the latter is a superset of the former (I think)?

In addition to complete API backwards compatibility being a very large effort (which we will continue to make progress on), there are a few things that will not be possible in the new v8 engine.

  1. Having global scope shared between instances and legacy Javascript based jsextensions loaded at launch. For the former, some mechanism like the Global object or named dictionaries will need to be used to share this data across instances, and for the latter, it is recommended to use include("myjsextension.js"); to include the code within a specific instance. The ability to have singleton classes across instances for these extensions is not possible.

  2. Native jsextentions are not compatible (as you point towards in your next comment) , so for patchers to be able to load and use those legacy native jsextensions, we need to provide the legacy engine.

For external developers, do you have plans for jsextensions (c or c++ compiled objects which can be loaded in the js object) to eventually work similarly with the v8 engine?

Currently, you can already define a "nobox" class with the standard Max SDK, and expose this to both js and v8 engines with the maxclasswrap method--e.g. maxclasswrap("arraywrap", "MaxArray");

There isn't a ton of documentation here, but the simplejs.c example is a good place to start:

This is what we've done for the vast majority of our own bindings to v8, both in order to reduce engine specific dependencies that prevent us from updating the engine over time, as well as allow for these objects and their functionality to be easily wrapped for other language bindings, such as your excellent work with python.

This won't let you do custom things with the v8 engine directly however, and that's something we likely will not be supporting for the reasons stated above. If you have specific needs for your binding that seem like they might not be possible with the current Max SDK API, please let us know.

One of the areas that we have needed more than what was available before was the ability to pass in callback functions. We have made a call back function nobox object to handle these situations, but we aren't ready to publicly support that at this time and can keep you posted as we are ready to do so and have time to make some proper documentation.

In the case of Max standalones, in case one exclusively uses the v8 engine instead of the js object, is there a way to reduce the size of the standalone which is massive (~500 MB in the case of a hello world example) by omitting the part that supports the js engine while retaining part that supports the v8 engine?

It is possible to simply open the contents of the resources folder and delete any items you do not need for your standalone application. The legacy JS binary requirements are pretty slim (~2MB for libmozjs185, ~2MB for js objects and extensions), but we understand that every little bit adds up. Many advanced standalone developers with these needs run commandine scripts to streamline removing and adding specific needs to their standalone applications, codesigning, notarization and more, and I'd recommend that approach.

-Joshua

Iain Duncan's icon

I would love to also be posted about such developments!

Shakeeb Alireza's icon

@JOSHUA KIT CLAYTON

That's great!

Thanks very much for the extensive clarification to my questions, and for your kind words re: my python externals (-:

S

Luke Teaford's icon

I am struggling with some inconsistencies. It seems to me that these two functions should be equivalent.

// This doesn't work (or I'm doing something wrong)
const bang = () => outlet(0, 'hello');
// This does work but requires using function declaration
function bang() {
  outlet(0, 'hello');
}

The top example can be called from the REPL as expected, but it doesn't respond to sending bang messages from the REPL.

I can adapt my style, but it would be great to have a reference to these kinds of "quirks" issues.

Is it possible to set the tabWidth to 2 spaces? (Or better yet 2 actual space characters?)

Thanks,
Luke

Joshua Kit Clayton's icon

For a subtle reason, you can't use const or let in this way. The same is true when declaring attributes. If you use var it will work as expected.

var bang = () => outlet(0, 'hello');

Maybe TMI, but as I recently discovered working on the similar problem for declaring attributes, this is because those keywords at the global scope add to the "Global Lexical Environment" but do not add them as properties to the global this object. Weird I know, but from the implementation, we are not able to safely retrieve values from the Global Lexical Environment without evaluating JS code within the global environment (i.e. we can't from C++ say give us the property "bang" if it is declared with const or let ).

Tab-width/spaces request registered.

Hope this helps!

Joshua

Luke Teaford's icon

Very helpful-- thank you! I suppose const/let are block scoped and var isn't so that is just the way it will work in codeblocks, etc. The modern JS implementation is very nice.