Hi! That bit of the docs is a bit outdated. We're probably gonna make it optional. The reason for that choice was that the filters for Rotonda need to be very quick and don't really require loops as long as you can do `contains` checks on some lists for example.
So it should probably say "Roto _in Rotonda_ does not have loops". Roto the language as a separate project can then have loops.
Hi! Author here. You could try but there are some fundamental limitations.
The biggest limitation is that we don't have access to the full type system of Rust. I don't think we can ever support registering generic types (e.g. you can register `Vec<u32>` but not `Vec<T>`) and you don't have access to traits. So it would work if you can reduce your API to concrete types.
Otherwise - apart from some missing features - you could probably write big chunks in Roto if you wanted to. You could also prototype things in Roto and then translate to Rust with some simplified types.
Also you'd have to accept that it gets compiled at runtime.
Hi! Author here. Mun is super cool, but works slightly differently as far as I know. You compile Mun scripts outside of your application to a dynamic library, which can then be (re)loaded by your application. The advantage of that approach is that you can ship the compiled script with your application.
The downside is that it's not really possible to share types between the host application and the script as far as I know. They have something called called `StructRef` which does this a bit, but it's all runtime checks if I understand correctly.
If somebody here knows more about Mun, I'd be happy to be corrected. This is just my understanding from their documentation.
Hi! Author here. Would be super cool, but while the compiled scripts would work without allocations, the compiler itself does a lot of allocations. So unfortunately I don't think I could make that work.
First, this language is syntactically a lot like Rust but semantically quite different. It has no references for example. We're trying to keep it simpler than Rust for our users.
Second, using Rust would require compiling the script with a Rust compiler, which you'd then have to install alongside the application. Roto can be fully compiled by the host application.
I think your approach might be preferred when the application author is also the script author. For example, if you're a game developer who is using a script to quickly prototype a game.
It depends. I'd love to make a prototype using Bevy with Roto. What I'm trying to say is that if you only want something to make Rust compile faster, then Rust might the better option. If you want something that behaves more like a scripting language and you don't mind that is compiled at startup, then Roto might be good for that purpose (with the caveat that there are missing features of course).
Having not yet actually tried it, I assume I could compile at startup on a separate thread with no issues? This seems like a dream scripting language--or "application language" as someone else called it.
Yes, you definitely could! And thanks for the kind words! If you try it out for your own purposes, you'll probably run into some missing features (e.g. lists and loops), but we'd be happy to hear what you think!
Thank you for putting this out there! I'll make sure to let you know what I think when I try it out—but I have some wood to chop on other parts of my app before I get into scripting.
Re: lists and loops, is that not supported because it hasn't been a priority or because it requires some fundamental redesign? Which is to say, if I wanted to add those down the road, is this something I could try my hand at implementing on my own and possibly contributing back?
They're on the roadmap for sure. While loops are quite easy to add I think, but it would also need an assignment operator to make it useful. Lists are complicated because they're generic over the element type. That's why I've waited so long to add them.
Hi! So for Roto, our introspection needs are actually fairly limited. We only need the `TypeId`, the type name, the size and the alignment. which Rust can give us without any additional traits. It's not possible currently to - for example - access struct fields and enum variants. That is something that I plan to add, but that might require a crate like `bevy_reflect` or `facet`.
Rust is giving me just enough information to pull the current version of. More powerful introspection/reflection is not possible without derive macros. If you're ok with derive macros though, you could look into the 2 crates I mentioned.
Not many iterations, but a lot of head scratching was involved haha.
I decided against using a trait and a derive macro because I wanted to avoid running into Rust's orphan rule. We have a crate called routecore where most of our types are declared and then a separate crate called Rotonda which uses those types and uses Roto. I wanted Rotonda to be able to register routecore types.
That's also the downside of the current reflection crates; they require each type to have a derive macro.
One of the maintainers of uutils here. We have a few flags that are not in GNU for one reason or another. Some were rejected by GNU, others come from other coreutils implementations like FreeBSD. We document those at https://uutils.github.io/user/extensions.html
We tend to do this sparingly, however, because even just adding new flags might break existing scripts that use abbreviated long options. For example, if the flag you propose is called `--filter` it might break scripts that use `--fi` as a shorthand for `--file-type`, because the prefix is now ambiguous.
Oh wow, I had no idea that was a feature. That significantly hampers extending the tools in the future. Has there ever been a discussion to consider breaking that functionality? (I understand it could be a huge impact & not worth it, but just curious to read the discussion if it exists.)
I can't find any discussion. But I know that some alternative implementations disable this feature. The cause of this behaviour is actually the glibc `getopt_long` function, which does this automatically, so it can't be changed until it's changed in glibc, which has been rejected at least once that I can find: https://sourceware.org/bugzilla/show_bug.cgi?id=6863
That's the first time I hear of this "feature" (using `--fi` instead of `--file`). I tried a few commands in my shell and none actually support it. How common is this?
How about introducing three dahses for these custom parameters/flags?
Regarding filtering. In a busybox situation depending on some regex crate is a given anyway, but if we are talking about separate binaries adding it to `ls` makes it bigger for everyone, even for those who will never use this feature. Does piping the results to grep make things so much slower that adding filtering to ls is "worth it"? Is this pushing the "philosophy" of do one thing well and be compostable too much? How many kilobytes are we talking about anyway?
Care to share your opinion on these theoretical/pragmatic questions? Thanks!
It's possible I suppose, but three dashes already sometimes appears in GNU for hidden options and, probably more importantly, I think it would be frustrating to have to remember whether it was `--filter` or `---filter` for all long flags.
Maybe uutils could have a build feature that specifically turns off the prefix matching and will break stuff but allows using newer and more useful flags in exchange. I've VERY rarely seen prefix-matched flags being used so I'd wager a distro could be fine deploying it that way.
Ie, setup the features "gnu-compatible-opt-matching" and ship it by default, then gate the extra features behind not turning on that feature.
It's a good idea to make the prefix matching optional. I think it might be confusing to gate other features behind it though. I guess we'll get to this once we find flags that are important enough. So far, we haven't really had significant issues with this; compatibility remains our primary focus for now.
> In a busybox situation depending on some regex crate is a given anyway
uutils can behave as a busybox-like binary. But I think there's some confusion over the requested feature, because that can't really be done with regex, but you have to inspect the file metadata to check the type of file. That's also why a grep solution doesn't really work, unless you use `ls --classify` and then use the indicators to filter in `grep`.
> if we are talking about separate binaries adding it to `ls` makes it bigger for everyone, even for those who will never use this feature
It's generally not these kinds of features that increase the binary size, but if it does we could also introduce feature flags for it, where you can choose at compile time whether you want the uutils extensions or not. It still adds a bit of a maintenance burden of course.
That is a very interesting idea! It is not something we've discussed before as far as I know. For some utils (like chmod) it might be possible, but any util that is focused on outputting information currently does so by printing directly to stdout. So, ls doesn't give you a Vec or Iterator of listed files for instance, but instead prints them to stdout. Nevertheless, it would be a cool experiment to see if we can create something like a "ulib" crate that would provide the functions some functions for which it is possible.
I believe I actually had a proof of concept of this functionality in a PR at some point. This would basically have to work like mesabox, where each utility takes some generic input and output and then runs based on them rather than using stdout and friends directly (e.g. to avoid blowing through all your memory by stuffing many gigabytes of output into a Vec on certain commands).
So it should probably say "Roto _in Rotonda_ does not have loops". Roto the language as a separate project can then have loops.