4 ms·
Metaprogramming doesn't need to have a performance impact. VM languages like Java, C#, and JS allow you do define and modify code at runtime JS you can redefin
by eggsnbacon1 6y ago
Metaprogramming doesn't need to have a performance impact. VM languages like Java, C#, and JS allow you do define and modify code at runtime
JS you can redefine anything, Java support is pretty good, C# better support is coming with generators
- rantwasp 6y agoyou obviously did not do metaprogramming in Ruby. Try it and you will never look at the "metaprogramming" capabilities of other languages in the same way. no offence to JS, but JS and a proper programming language are not even the same species.
- YorickPeterse 6y agoRuby's meta-programming capabilities is why optimising Ruby is so darn difficult. It's extremely powerful, but also complicates a lot of things.
- eggsnbacon1 6y agoI reason the difference is mostly when metaprogramming can happen. In Java, redefining or adding code is very explicit, it can't just happen whenever. Same with C#. And there are lots of rules. A class can't modify itself, and there's limits to what changes you can make. And to make changes you must have control over the "classloader" that loaded that code. JS on the other hand can do most of what ruby does, to my knowledge. Objects are key value pairs so you're free to mess with them in virtually any way you please. You can also mess with the inheritance by altering JS prototype chains. I don't think metaprogramming itself has much to do with the speed of Ruby, with my admittedly limited knowledge of this stuff
- hosh 6y agoHowever, JS does not treat everything as an object as pervasively as Ruby does. A JS object and a JS integer are two different abstract data types. A Ruby number literal "1" is treated as an object of the Integer class. There are no separate abstract data type other than an object. All operators for an Integer can be overriden (in runtime), or perhaps, a specific object's methods can be overridden. Now granted, the runtime cheats and implements certain things in C ... but those can be overriden during runtime ... If you want to find out more about the limits of what can be done to optimize Ruby, check out the Truffle project. That came out of someone's PhD dissertation on novel methods for doing JIT optimization for Ruby. It is sufficiently difficult and novel to warrant awarding a PhD for. Last time I heard, Truffle still could not run Rails.
- gavinray 6y agoA JS integer is actually an instance of the "Number" object, you can to a small degree alter fundamental behavior even with primitive types
- hosh 6y agoI stand corrected.
- jiofih 6y agoNo it is not. It is a primitive, this difference is well defined in the ECMAScript spec. Same for strings. An instanceof String is strictly not the same as a string primitive (and there are runtime consequences).
- ulucs 6y agoYou need to enclose numbers to access the prototype: 1.toString is undefined, whereas (1).toString() is "1"
- kipply 6y agoOn top of Ruby metaprogramming being unique, V8 and Hotspot are amazing premium deluxe engines that have had more time and/or resources.
- aardvark179 6y agoMetaprogramming definitely has a cost, but it's one that you can minimise if you have the ability to either invalidate and recompile code at run time, or if you can perform extensive whole program analysis when ahead of time compiling. The more extensive the meta programming you can do, the more work it is to implement this under the scenes. For example in Java you can change the visibility of fields, and you can load new classes, so that's not too hard to take account of, but in Ruby you can redefine methods, add refinements so they behave differently depending on where they are called, or radically change the inheritance hierarchy. Implementations like TruffleRuby can maintain high performance even with these features being used, but it's taken a lot of work to achieve that.
- hosh 6y agoRuby's "metaprogramming" is something Java, C# and JS don't do well -- dynamically redefining things during runtime. Everything in Ruby, including literals and operators, can be redefined during runtime, because everything is an object, and every message passed to any object can be redirected, filtered, transformed ad hoc. It's not just classes can be modified. Specific objects can be modified. Well-crafted Ruby code breaks things up into mixins that can be composed together. The closest comparison is one of Ruby's inspiration -- Smalltalk. I think the most exciting optimization people have seen with Ruby is Truffle. I don't regret the 14 years I put into writing Ruby professionally. I've used and abused metaprogramming, and it has shaped how I reason and architect things. I learned to appreciate well-designed, semantically-meaningful DSL. But I've moved on. I write server code with Elixir these days, and I'm exploring other ways of reasoning and writing code.
- Scarbutt 6y agoWhy did you have to move on?
- hosh 6y agoI didnt have to move on. I chose to. I had learned what I wanted from Ruby, and I started to realize that the problems I was facing was leading me to reimplement some of the things that OTP already offered. I was getting more interested in concurrent, resilient systems. It came about the time when it converged with my interest in permaculture (which is also about resilient, regenerative systems).
- saagarjha 6y agoJava and C# essentially let you dynamically load/JIT code (not to be confused to the JIT-to-native virtual machine implementation they often run on); JavaScript is much closer to Ruby in that sense. It also gets really slow if you try to do any of those things extensively.
- chrisseaton 6y ago> Metaprogramming doesn't need to have a performance impact. Optimising away the performance impact of most of the metaprogramming features I mentioned there requires truly heroic optimisations, beyond what has ever been used for any other language. Some of them are even worse - I'm not sure there any way to optimise away the non-local effects of Proc#binding, which allows you to access local variables not lexically referenced.