Oct 16 2020 | 8:07 am
- Oct 16 2020 | 2:58 pmThe main issue (to me!) is that the JS issue only runs in the low priority thread, rendering it useless for anything timing related. It works great for jitter related work as that is all in the low-priority thread anyway, but any kind of midi output or sequencing is unreliable. It's also fine for manipulating data that you then work with in Max, ie using JS to fill buffers or tables, and then driving those separately from Max patches with a metro or midi objects. Node for Max also suffers here in that it's in a separate process, so you get some amount of somewhat unpredictable latency. This is one of the main reasons I created the Scheme For Max: so that one can do timing critical work in the high priority thread in a text language (S7 Scheme Lisp). It's still beta software but I am using it in real world projects for timing related tasks and it's working well. I will have a new release out in the next month or so, but you can check out the previous one's demo video, linked from the docs. https://github.com/iainctduncan/scheme-for-max https://www.youtube.com/watch?v=ErirIFCTdjg&t=4s
- Oct 16 2020 | 3:02 pmOne pattern that I have been doing recently and quite happy with is using Scheme For Max as the main engine and using Node For Max as a way to do asynchronous jobs. I have S4M send messages to node, and get the response when it's done. This has worked really well for working with the underlying OS (i.e. file system directory scans and reading and writing) as Node has great libraries for all that kind of stuff, and hooking up a callback in Scheme is very simple.
- Oct 17 2020 | 4:22 pmHi Nick, thanks! I did check out your ClojureScript work when I was in the prelim research stage of this, and got it working. Now having used this in a real world context (www.weeksfeellikedays.com) I've found that being able to use the Node object in addition to the S7 interpreter is really handy, so I expect to dig back into it again later.The work I'm doing on the next release is all focused on scheduling and threads for building sequencers and so on, as well as direct i/o to tables, buffers, and dicts. So the plan is to allow the user to specify which thread an s4m object runs in with an attribute for High, Low, or Any. If they choose High or Low, any incoming messages are promoted or deferred *before* hitting the S7 interpreter (while still in the C), thus protecting against having multiple threads calls into the S7 interpreter and clobber each other. I intend to add wrappers for critical_enter/exit so that advanced users can use Any if they want, but "officially" say: if you want both high and low threads, just make two s4m instances and treat it like an actor model, sending messages between them or using tables/buffers/dicts as ways to pass thread protected data. So far this seems to be working well, so I imagine my workflow will be to have a two s4m instances and a node instance with async communication between them.
- Oct 17 2020 | 4:24 pm(also I know of at least two companies using Groovy from my regular work!)
- Oct 17 2020 | 6:49 pmYeah, running the whole instance at one priority level sounds like a good design choice. (If that choice is an attribute, though, what if someone tries to change it dynamically?)It would be good to see your Scheme package in the official Max package manager...
- Oct 17 2020 | 6:54 pmAh good point. I think the sensible thing is to do reset in that case, where reset wipes the interpreter, which is already what happens if you change the object box. And that can be thread protected. I'll have to make clear in docs that this is what will happen, but that makes sense to me. Thanks for the tip, I hadn't thought about that case yet.And yes, when I get it to the point that I feel this is stable for wide use, I will certainly be asking to get it in the package manager. Hopefully this year, but want to make darn sure I've not got some thread issues in there. :-)