4 ms·
"Those techniques are based on the idea that most code "does not use the full dynamic power that it could at any given time" and that Python can quickly check t
by jerf 5y ago
"Those techniques are based on the idea that most code "does not use the full dynamic power that it could at any given time" and that Python can quickly check to see if they are using the dynamic features."
If anyone has a burning desire to try to write the next big dynamically-typed scripting language, I've often noodled in my head with the idea of a language that has a dynamically-typed startup phase, but at some point you call "DoneBeingDynamic()" on something (program, module, whatever, some playing would have to be done here) and the dynamic system basically freezes everything into place and becomes a static system. (Or you have an explicit startup phase to your module, or something like that.)
The core observation I'm driving this on is much the same as the quote I give from the article. You generally set up the vast majority of your "dynamicness" once at runtime, e.g., you set up your monkeypatches, you read the tables out of the DB to set up your active classes, you read the config files and munge together the configurations, etc. But then forever after, your dynamic language is constantly reading this stuff, over and over and over and over again, millions, billions, trillions of times, with it never changing. But it has to be read for the language to work.
Combine that with perhaps some work on a system that backs to a struct-like representation of things rather than a hash-like representation, and you might be able to build something that gets, say, 80% of the dynamicness of a 1990s-era dynamic scripting language, while performing at something more like compiled language speeds, albeit with a startup cost. If you could skip over the dozens of operations resolving
x.y.z.q = 25
a dynamically-typed language like Python needs to properly implement that and get down to a runtime that can do the same thing compiled languages do by pre-computing the offset into a struct and just setting the value, you might get near static-language performance with dynamic typing affordances.
You can also view this as a Lisp-like thing that has an integrated phase where it has macros, but then at some point puts this capability down.
I tend to think it's just fundamentally flawed to take a language that is intrinsically defined as "x.y.z.q" requiring dozens of runtime operations versus trying to define a new one where it is a first-class priority from day one that the system be able to resolve that down to some static understanding of what "x.y.z.q" is. e.g., it's OK if y is a property and z is some fancy override if the runtime can simply hardcode the relevant details instead of having to resolve them every time. You can outrun even JIT-like optimizations if you can get this down to the point where you don't even have to check incoming types, you just know.
- coldtea 5y ago>I've often noodled in my head with the idea of a language that has a dynamically-typed startup phase, but at some point you call "DoneBeingDynamic()" on something (program, module, whatever, some playing would have to be done here) and the dynamic system basically freezes everything into place and becomes a static system. (Or you have an explicit startup phase to your module, or something like that.) V8 tries to guess that for classes and objects based on runtime information - that's how it gets some of its speed (it still needs checks about whether this is violated at any point, so that it can get rid of the proxy/stub "static" object it guessed). For a more static guarantee, there are also things like Object.freeze which does about what you describe for dynamic objects in JS (#). # https://gist.github.com/briancavalier/3772938 https://gist.github.com/briancavalier/3772938
- jerf 5y agoI'd be curious to see if a language developed with the idea that this is what it's going to do from scratch could do better than trying to bodge it on afterwards. Rather than pecking around what could be done literally decades after the language is specified, what if you started out with this idea? I dunno. It's possible the real world would stomp all over this idea in practice, or the resulting language would just be too complex to be usable. It does imply a rather weird bifurcation between being in "the init phase" and "the normal runtime phase", and who knows what other "phases" could emerge. Although technically, Perl actually already has this split, although generally it can be ignored because it's of much less consequence in Perl precisely because there mostly isn't much utility to having something done in the earlier phase, unlike this hypothetical language.
- gpderetta 5y agoIt seems that lisp-like macros or more generally multistage compilation is close to what you have in mind.
- jerf 5y agoYes, it's not a brand-new dimension of programming languages, merely a refinement of existing ideas. However I'm not aware of anything quite like it out there. Lisp could be used to implement it, but, I mean, that's not a very strong statement now is it? Lisp can be used to implement anything. The question is about whether it exists. Partially I throw this idea out as a bone to those who like dynamic languages. Personally I don't have this problem anymore because I've basically given them up, except in cases where the problem is too small to matter. And if you already know and like Lisp, you don't really have this problem either. But if you are a devotee of the 1990s dynamic scripting languages, you're getting really squeezed right now by performance issues. You can run 40-50x slower than C, or you can run circa 10x slower than C with an amazing JIT that requires a ton of effort and will forever be very quirky with performance, and in both cases you'll be doing quite a lot of work to use more than one core at a time. Python is just hanging in there with the amazing amount of work being poured into NumPy, and from what I gather from my limited interactions with data scientists, as data sets get larger and the pipelines more complex, the odds you'll fall out of what NumPy can do and fall back to pure Python goes up and the price of that goes up too. I think a new dynamic scripting language built from the ground up to be multithreadable and high performance via some techniques like this would have some room to run, and while hordes of people will come out of the woodwork promising that one of the existing ones will get there Real Soon Now, just wait, they've almost got it, the reality is I think that the current languages have pretty much been pushed as far as they can be. Unless someone writes this language, dynamic scripting languages are going to continue slowly, quite slowly, but also quite surely, just getting squeezed out of computing entirely. I mean, I'm looking at the road ahead and I'm not sure how Go or C# is going to navigate a world where even low-end CPUs casually have 128 cores on consumer hardware.... Python qua Python is going to face a real uphill battle when the decision to use it entails basically committing to not only using less than 1% of the available cores (without offloading on to the programmer a significant amount of work to get past that), but also using that core ~1.5 orders of magnitude less efficiently than a compiled language. You've always had to pay some to use Python, sure, but that's an awful lot of orders of magnitude for "a nice language". Surely we can have "a nice language" for less price than that.