1,271 karma · joined October 10, 2016
But for writing scripts I would reach for Elvish/Nushell. More powerful.
The language is what you write in an $EDITOR. Here Elvish scripts can be nice, succinct and powerful. I like how I don't have to worry about strange "bashisms" like argument quoting etc. Everything feels consistent.
The Nushell and Elvish scripting languages are similar in many ways. I personally find the "shell" experience better in Nushell than Elvish.
Nushell
- Bigger community and more contributors
- Bigger feature set than Elvish
- Built in Rust (Yay :-)! )
Elvish
- Mostly developed by one person
- Built in golang
- Amazing documentation and general attention to detail
- Less features than Nushell
- Feels more stable, polished, complete than Nushell. Your script written today more likely to work unaltered in Elvish a year down the line. However this is an impression. Nushell must have settled down since I last looked at it.
For "one off" scripts I prefer Elvish.
I would recommend both projects. They are excellent. Elvish feels less ambitious which is precisely why I like it to write scripts. It does fewer things and I think does them better.
Nushell feels like what a future scripting language and shell might be. It feels more futuristic than Elvish. But as mentioned earlier both languages have a lot of similarities.
I don't care much for the Elvish shell experience, rather I like the Elvish scripting language. The documentation is top notch and the language evolves slowly and feels stable.
OCaml cared about concurrency (e.g. Lwt, Async are old libraries that provide concurrency -- they didn't need multicore Ocaml). OCaml didn't care so much about true _parallelism_ in threads until recently. Parallelism was to be obtained via processes and not threads in pre OCaml 5.0. True parallelism in threads is available in OCaml >= 5.0
Python is actually trying to go multicore too ! OCaml however beat it to the punch. The strengths of Python are elsewhere though, a topic for another day.
You might claim that that you can have both but bugs are more inevitable in the uninitialised by default scenario. I doubt that variable initialisation is the thing that would slow down HFT. I would posit is it things like network latency that would dominate.
- Type annotations are integrated and work well with PHP now. This results in a kind of scripty Java OOP that is more succinct and type checked ! (it is possible to write PHP without types when you want metaprogramming features also)
- Many inconsistencies in the design of the language (OOP, function naming etc.) have been resolved/smoothed out
- The language recognises the inherent problems with `null` and allows you to make type annotations that rule out null. This is my smell test for a language BTW -- golang for instance does not seem to have a good story for null.
- PHP Language developers have been really good about increasing performance year after year
- Lots of software like web frameworks and CMSes continue to be based on PHP
And -- the greatest part of the design -- PHP remains the best example of the "shared nothing" architecture. An architecture that allows you to scale your application easily.
Maybe instead of a charge this could be a credit. If the recycling happens after a long time the company gets a bigger payback than if it happens before. The money is collected on checkout so the company can't claim bankruptcy or low profits to make the payment.
Also, what happens if you order a product online from another company in a different country ? Does Norway still get to add tax for cleanup on these imported goods ? I would guess that this would be a powerful incentive for customers to skirt these regulations for lower prices.
The American way is to possibly put too few responsibilities on manufacturers. The European way seems to be to saddle them with just too many regulations -- possibly killing so much innovation.
One way to approach this would be to put more responsibilities on large established companies and less on smaller companies. But then the problem is that larger companies will want to arbitrage this somehow by indirectly "owning" these smaller companies with less environmental responsibilities.
This area is far more complex than we think it is.
Also what do we do about totally new materials that are thought to be benign when introduced but then are proved to have harmful effects many years later. Does the company that introduced them now have huge open ended costs and now go bankrupt ?
The solution is as always in the middle ground. Society as a whole bears some cost of cleanup (a kind of insurance policy for all companies) and companies bear some of costs.
You should however discuss politics with close friends -- they probably got close to you because you both share a worldview or they like hearing your worldview (even if it differs from yours).
Closeness means more sharing. That always comes with risks and rewards.
_Software Counter mode_ rr requires robust support for debuginfod in your Linux distribution.
NixOS to my knowledge does not provide debuginfo via a dedicated debuginfod server for all packages so this will make things unreliable for debugging via _Software Counters mode_ rr for packages for which debuginfo is not available via debuginfod.
I recently learned about https://github.com/symphorien/nixseparatedebuginfod for nix (note: I haven't used this so I don't know how reliable or good this is). Anyways, this project requires setting `separateDebuginfo = true;` for the derivation for the debuginfo to be available via debuginfod. This is an opt in approach but we need pervasive support like it exists in Fedora (and some others).
rr uses many advanced features of Linux `ptrace`. Compare `man ptrace` on Linux with that on macOS for example and you will notice that Linux gives a lot of features to `ptrace` that macOS simply does not.
There are a large number of other features required for practical record and replay -- I dont think macOS simply provides them also.
It's probably possible to build _some_ record/replay system on macOS with constraints, restrictions, workarounds and compromises -- never say never as they say. But I don't think it can be as capable/generic as rr on Linux.
Though I do see a lot of promise in the future. rr can help make premature evaluation (many expressions are evaluated earlier than they might typically happen in a real Haskell program because a user may want to inspect a value) in the debugger not matter so much because that evaluation can be executed in a diversion session.
With sufficient usage I think we can make a good case to get merged upstream. This patch introduces dynamic/static instrumentation for ticks counting which is quite different to how things have happened till now on rr. If there are many success stories a stronger case for upstream merge can be made. The rr maintainers are aware of this project but it is early days yet for an upstream merge PR attempt yet
`rr replay` and (the software counters equivalent) `rr replay -W` invokes gdb.
Normal system calls transition to kernel space and return back from kernel space. They will change your program's memory/process state as soon as they complete. This gives rr an easy boundary when it "can do its thing" to record memory/process state changes or insert results (during replay).
When does an io_uring request/response complete ? That's difficult to say. The kernel/userspace when using io_uring communicate with each other by checking a queue head or tail with memory accesses to see if something got added/removed from request/response ring buffer.
Think of io_uring and userspace cooperating via memory. (Yes, sometimes "proper" traditional ring crossing system calls are made but what makes io_uring so fast is communicating via memory and not via system calls most of the time). Anyways all this makes it difficult for rr to intervene on the boundary between kernel and userspace because this boundary is elusive when it comes to io_uring. The memory writes cannot be caught by ptrace ! This explanation is simplified of course.
There are some plans to deal with io_uring by rr maintainers https://github.com/rr-debugger/rr/issues/2613
However, when you try to debug the program you can only debug the C code the Python interpreter is written in.
I suppose you want to be able to debug the Python code itself. Here is something that could do this https://pypy.org/posts/2016/07/reverse-debugging-for-python-... . I don't think the project is active nowadays though. Also I haven't used it so can't say whether it is good or not.
It should be possible to built a Python reverse debugger on top of rr. I know this should be possible because I built something for PHP https://github.com/sidkshatriya/dontbug .
There are other fancy (and possibly better) things that are possible -- instead of building a Python debugger atop rr you can record the full trace of the Python program and then for e.g. store the values of important variables at each executed line of the Python program in a database. This would again use rr as the record/replay substrate but with a slightly different approach. This is an area which I've done some work internally but nothing public released yet :-) !
I don't see any compelling reason why this should _not_ be possible from a broad level technical point of view. Pernosco engineers of course would be able to give a more authoritative reply.
- Performance: slower than using rr with HW counters. Both dynamic and static instrumentation employed by _Software Counter mode_ rr slow things down
- Potential fragility: Dynamic and static instrumentation can often make record/replay a bit more fragile
- Currently only x86-64 support has been publicly released. I have aarch64 support working reasonably well internally and it allows me for instance run to rr in a Linux VM running on macOS ! I have yet to figure out my strategy for the aarch64 release so watch https://github.com/sidkshatriya/rr.soft for any updates.
- Currently can run only on a few recent Linux distributions (e.g. Fedora 40/41, Debian Unstable, Ubuntu 24.10) because it relies on robust debuginfod support that is not widespread yet. See https://github.com/sidkshatriya/rr.soft/wiki#how-does-softwa... for why debuginfod is required. The debuginfod requirement may be relaxed in the future with more work
Regardless of the tradeoffs this allows rr to be used in many more situations i.e. wherever HW Performance counter access is not possible/not reliable/broken.
I would love it if more people tried this out and let me know if things worked out well for them (or not) with their programs.
It relaxes one major limitation with the `rr` debugger - it does NOT require access to CPU HW performance counters.
This allows the debugger to run in containers, cloud VMs etc where access to CPU performance counters is usually disabled or not available.
In case you're wondering: reverse debugging is a powerful approach to locating bugs in your program using record/replay. Please see the blog post (https://github.com/sidkshatriya/me/blob/master/008-rr-everyw...) for a gentle exposition of the concept behind record/replay.
Personally I would still use unsafe safe rust than raw C which has more edge cases. Also when I’m not on the critical path I can always use safe rust.
[Edit: You answered the question when you said that individual attention layers are always dense.]