My first question too, and I checked out the linked book [1], and sure seems like it! There's global functions like `janet_init()` and `janet_loop()` all over the place.
A language shouldn't advertise itself as "embeddable" if it does this. It means you can't have multiple interpreters, you can't use it on multiple threads, etc. GNU Guile does this too, and it's a baffling decision! For my field (audio plugins like VSTs), it means it's absolutely a no-go, because hosts can load any number of instances of your plugins and potentially run them in parallel in the same address space, they can't rely on global state like this. Each interpreter has to be separate.
Lua does this right, as does Python (as of 3.12, when they made the GIL local to each interpreter) and I think most of the JavaScript engines. And it's not hard, instead of a global `janet_init()`, just have an opaque pointer bundle all the state, like `janet_init(interpreter)`. If you want a global interpreter, just stick it in a global variable.
So you can't execute a Janet script on a different thread than it was created on? Still not good: if you're making audio plugins, you don't control the threads which your program runs on. It's just not good enough, IMHO.
Not sure exactly what you're getting at, you mean transfer mid-execution to another thread? You can load and run a script on any thread you can load janet on, and you can coordinate across threads if need be. To clarify, janet_init just sets up the VM
I'd also go take a look at the actual docs and code, I'm not sure I know the exact answer, but assumptions won't help
Edit: there was someone on the Zulip that mentioned working on audio plugins, and there are a couple other audio-related projects you could check out. Someone there might have a better answer -- https://janet.zulipchat.com/
The UI for audio plugins generally work in an event driven manner: you get events like mouseMove, keyDown, repaint, etc. from your host. In response to those events, you run your script to figure out what you need to do. You have no control over which thread calls these things, it can be the GUI thread that runs all of them, it can be run on background threads in parallel, etc. Different hosts do it differently. If Janet using thread-local state, this just doesn't work: the state for one instance is completely different from another, and there's even no guarantee they're running the same scripts.
Consider the most famous embedded language, JavaScript in browsers: you can have any number of tabs open at the same time, and if the JavaScript interpreters for each of those used a bunch of thread-local storage, it would place huge restrictions on how the browsers could schedule and parallelize the callbacks for the JavaScript in those tabs.
The only way I can see this working is if you spin up a thread for each instance, and when these events come in, you wake up those threads, send over the event information, block until the interpreter thread finishes. But that's both inefficient and a real architectural hassle.
All I want is an object that's like `janet_interpreter *interpreter = janet_make_interpreter();` and then you pass that to the functions instead of doing all these magic things with global variables and thread local state. That's it.
Is there any particular plugin system you're referring to? I'm interested to learn more, out of curiosity. Janet's code is pretty easy to read, so you've got me learning about the vm now :)
Sure! The main formats are VST3 (from Steinberg, the most popular format), AU (from Apple, supported by most macOS hosts, and Logic only uses AU), AAX (for Avid Pro Tools) and CLAP (an open source variant, that's the best of all of them but is having trouble getting market share). Then there is also "Standalone", which is when you just run your plugin as a standalone app.
Because of this plethora of standards, most plugin developers (including us, I work at XLN Audio) use the JUCE C++ framework, which provides a uniform interface to all these formats and more. It's available on GitHub under a GPL license if you just want to play with it (it has excellent tutorials and example projects). If you're just curious about development thing, I recommend using Reaper as a host to test in, both because it's essentially free (it's free like WinRAR is free), and it has tons of options for how to run plugins (all in the main process, all in a bridged process, every plugin in a dedicated process, etc.).
Audio plugins are essentially dynamic libraries loaded at runtime, and a common way to run them (used to be universal, but some hosts are changing) is that the dynamic library is just loaded in the main process address space and the host communicates with it by calling functions on it. That means that if a single plugin (out of maybe dozens in a project) crashes, it takes the entire host down. In addition, if you have multiple instances of the same plugin (very common, you might have the same effect on multiple tracks, for instance), all global and thread_local variables are shared between them, which makes global variables a total nightmare, and raises the thread_local problem I mentioned earlier.
Our products use JUCE for the unified interface, but then we have an entirely custom Lua codebase for the GUIs and scripting the products themselves (with lots of connections to the audio engine, which is of course C++). There are very limited languages you can embed this way, because of the requirements I mentioned above. The ones I've looked at which you could possibly do it with is Lua, Python (3.12+), JavaScript and Tcl. I haven't done a lot of testing outside of Lua though, this is just me looking at the embedding APIs. You could also do it with web views, and recent versions of JUCE provides nice ways to do that.
I wouldn't do it with Janet if it uses thread local state this way, but maybe it works. It would definitely work if you spun up dedicated threads for each instance and communicated the events back and forth, but that seems like a bad idea.
Let me know if you have more questions, this is a very weird field of programming that most developers are not exposed to.
My Windows 11 installation broke down after one of the updates. Now I get "Please reinstall Windows" warning in Windows Update settings. And some error hex code which doesn't really help. I've installed like 5 different apps on this machine and never ran any "tweaking" scripts or apps.
I don't think I ever had to reinstall Windows 2000 but here we are.
Yeah Windows 2000 had countless software test engineers, I was one of them and on my team there were 5000 of us. I stared in tech support in 97 and moved into QA and always filed bugs on behalf of the customer, sadly everyone must code and customers must test. It's just not working out but Microsoft really only cares about Corporate America and Windows running on all the main languages. It's great to have alternatives and I've moved to MacOS after using Windows since 1.0.
Thank you for your service. :D Windows 2000 will always be my favorite version. I got a free copy as a university student and it was just awesome. XP was the era where things changed for the sake of change. In Windows 2000 you could learn where absolutely everything was and it was always there for you.
I still have my install CD, though it has suffered from bit-rot and can't be read properly. :(
I think the UI was reasonable and easily understood in 2000. After that it seems links and buttons became interchangeable, and now we end up in the mess where scrollbars may or may not be visible until you try fiddling with the UI etc.
Yep. And 'wget' is often alias for WebRequest in PowerShell. The amount of footguns I ran into while trying to get a simple Windows Container CI job running, oh man
I do still find Invoke-WebRequest useful for testing, because it is magically able to reuse TCP connections whereas curl always opens a new connection per request.
It's a completely new shell, new commands for everything, no familiar affordances for common tasks, so they add user-configurable, user-removable aliases from DOS/macOS/Linux so that people could have some on-ramp, something to type that would do something. That's not a dick move at all, that's a helpful move.
Harassing the creator/team for years because a thing you don't use doesn't work the way you want it to work? That is.
They removed it in PowerShell core 9 years ago! 9 years! And you're still fixated on it!
It is still present in powershell on my up to date windows 11 machine today, so it is disingenuous for you to claim the alias was removed 9 years ago. It is 100% still being shipped today.
The alias confuses people that are expecting to run curl when they type "curl" (duh) and also causes headaches for the actual curl developers, especially when curl is legitimately installed!
Why the hostile tone? Pretty rude of you to claim I'm fixated on the issue for years and harassing the powershell development team with zero evidence.
When you open powershell it says something like “Install the latest PowerShell for new features and improvements! https://aka.ms/PSWindows”
Isn’t it disingenuous to claim it is “up to date” when you know there’s a new version and aren’t using it?
> “The alias confuses people that are expecting to run curl when they type "curl" (duh)”
Yes, once, until you learn what to do about it. Which is … just like any other software annoyance. One you think people would get over decades ago.
> “and also causes headaches for the actual curl developers.”
Linux users can’t comprehend that the cURL developer doesn’t own those four letters.
> “It has very little compatibility with the actual curl command.”
It’s not supposed to have. As I said in another comment the aliases were added to be an on-ramp to PS.
Why aren’t you also infuriated that “ls” isn’t compatible with “ls”? Because you use the full command name in scripts? Do that with invoke-webrequest. Because you expect command to behave different in PS? Do that with curl.
>Linux users can’t comprehend that the cURL developer doesn’t own those four letters.
probably they can comprehend that MS has a history of making things slightly incompatible so as to achieve lock-in and eradicate competing systems.
Also if any program has been the standard for doing this kind of thing for a long time it's curl, it's pretty much a dick move that someone can't just send a one liner and expect it to work on your system because that is often how you have to tell someone working in another system "yes it works, just use this curl script" and then they can see wow it must be something with my code that is messed up.
> "it's pretty much a dick move that someone can't just send a one liner and expect it to work on your system"
No, it isn't. This is what I'm objecting to - this frames the situation in terms of Linux being "the one correct way" to do everything computing, and that all companies, people, tools, operating systems, should do everything the way Linux does - and are dicks if they don't. Not just dicks, dicks to you personally.
Including Linux's 'competitors', they are dicks for including things which help their paying customers in a way that isn't the Linux approved way, and they shouldn't do that because of the demands of Linux users.
This is collectively domineering (everything should be my way!), entitled (I have a say how a tool I don't use, am not developing, don't want, and am not paying for, should work), self-centred (everything which exists should be for my convenience), and anti-progress (nobody can try to change anything in computing for any reason - not even other people improving their system for other people).
That is a framing change which should not go unnoticed, uncommented. It's also common in programming languages where people complain if a language looks a bit like C but doesn't behave exactly like C in every way.
Your arbitrary one liner won't work because Python isn't there. Perl isn't there. `ls` is different. Line endings and character encodings are different. xargs isn't there. OpenSSL, OpenSSH aren't there. `find` isn't there. `awk` isn't there. `sed` isn't there. `/` and `/sys` and `/etc` aren't there. It's a completely different shell! On a different OS!
It's not reasonable to expect that a shell that was designed to not be a *nix shell - because the underlying OS is not *nix - will work exactly like a *nix shell and you will be able to copypaste a one liner over.
It is unreasonable to see some developer trying to create a thing in the world which isn't Unix and take that as them being dicks to you personally. It's also bad to be like "I tried one command in this 'new shell' of yours and without understanding anything it didn't do exactly what I wanted and that's you being mean to me. and I'm still going to be hurt about this in unrelated posts decades later on the internet".
Pretty sure you edited that in afterwards, but here you come into a thread about Copy-Item, instead start talking about Invoke-WebRequest and when I say "start talking" I mean mic-drop calling the developers dicks with no other content. After you've successfully triggered someone into a flamewar (me), you try to take the high road saying I'm the one being rude? Calling that out as well.
> "my impersonal complaint"
There's a person behind the move whom you are calling a dick. That's not impersonal. And it is rude. I suspect it's Jeffrey Snover, but possibly Bruce Payette or James Truher.
I write C++ daily and I really can't take seriously arguments how C++ is safe if you know what you're doing like come on. Any sufficiently large and complex codebases tend to have bugs and footguns and using tools like memory safe languages limit blast radius considerably.
Smart pointers are neat but they are not a solution for memory safety. Just using standard containers and iterators can lead to lots of footguns, or utils like string_view.
I've had similar experiences when working on non-web tech.
There are parts in the codebase I'd love some help such as overly complex C++ templates and it almost never works out. Sometimes I get useful pointers (no pun intended) what the problem actually is but even that seems a bit random. I wonder if it's actually faster or slower than traditional reading & thinking myself.
reply