6 ms·
This rubs me the wrong way somehow. All of this functionality could be accomplished with simple functions. They may not be as cool, but they are obvious in the
by kristiandupont 8y ago
This rubs me the wrong way somehow.
All of this functionality could be accomplished with simple functions. They may not be as cool, but they are obvious in the calling code and they are easy to search for. Magic stuff like this conflicts with community conventions. New people are going to be perplexed as to what's going on (or worse, they learn from your code and conversely get perplexed when x[-1] doesn't work on a normal array). Also, you risk confusing various tools in subtle ways.
- vinceguidry 8y agoOf course it does. The point was to demonstrate the technique and give a trivial enough example to grasp what's going on. You wouldn't use it for this for the reasons you give. The availability and accessibility of metaprogramming in Ruby is probably the closest one can get to an objective argument that it's a better language than other dynamic languages. The superpowers metaprogramming gives you are abstraction power tools. If a particular abstraction doesn't really work for a given application, you can use metaprogramming to interface around the abstraction. You usually don't need it, but when you do, the alternative is a painful refactoring mess. They allow you to quickly sketch out prototype code to get a trivial implementation working, and when you're done you can stuff all the code into a method on a module and call it a day. Tomorrow, when you need to instrument it somehow, pull out variables to be passed in, given default values, extend it to work with new formats, you don't have to worry about the language fighting you, and if it does, you can whip out metaprogramming to obliterate the offending semantics, all the way to down to BasicObject and eval if need be. Metaprogramming allows you to mold abstractions like they were clay. In Javascript you just have to suffer if the language fights you. If you see code you can't understand, there's not much that can be done other than to beat your head against it until it works. You don't have to understand how Ruby code works in order to work easily and effectively with it. All you simply have to know is that it works, then to extend you you can simply build an abstraction around it, even if it comes down to concatenating Ruby strings and then running eval on them. You can simply solve the problem quickly and dirtily, and then when time isn't a pressure, you can return to the code and clean up your mess. Things you simply cannot do in other dynamic programming languages, to say nothing of statically-typed ones. The sheer speed at which you can work can be scary. This might seem like fanboy worship but I seriously think that the only language that exists today that we'll still be using in a thousand years is a form of Ruby.
- desc 8y agoLisp has these advantages too, to an infinite degree. It's a wonderful teaching language for this reason: you can literally express any concept any way, introspect upon it, and execute it however. The downside is that you end up building a custom language in the process... It can make one developer incredibly productive, to an almost superhuman degree, and maybe you can scale to a small team, but inducting others into the priesthood can take a very long time. Code needs a limited number of conventions, patterns and cliches so newcomers can rapidly train their mental dictionaries with the common stuff, so they can see through it to what it actually does. > You don't have to understand how Ruby code works in order to work easily and effectively with it. All you simply have to know is that it works, then to extend you you can simply build an abstraction around it, even if it comes down to concatenating Ruby strings and then running eval on them. You can simply solve the problem quickly and dirtily, and then when time isn't a pressure, you can return to the code and clean up your mess. Building an abstraction around something requires that you understand it, or at least how it interacts with the wider world, if that abstraction is not to become the next serious problem itself. (Most docs, even the 'thorough' ones, cover inputs and outputs only: environmental and causal dependencies are rarely properly documented and can really hurt.) Otherwise it's called 'wrapping it in a bin-bag' and should be labelled with 'don't use this anywhere else unless you're prepared to open it and breathe deeply.' It's generally been my experience that if you don't know how it works then it doesn't work, and rarely does anyone sufficiently time-constrained to do it 'dirtily' the first time ever have the time to come back and do it properly later: if it has to be quick and dirty, it should at least be transparent enough that someone else can deal with it. [edit] Also, in a thousand years, Lisp will still exist, because absolutely everything else including Ruby is a mere subset. No one will use it though.
- lispm 8y ago> The downside is that you end up building a custom language in the process You'll do it in many complex programs in many programming languages. Creating the necessary infrastructure in a programming language is called 'Greenspunning'. If we for example need to work with 'state machines', I would implement in Lisp the machinery for it and give it a nicer source code user interface via some macro. The effect could be that the particular state machine definition sees a reduction in code size by, say, factor ten. Now productivity may depend on the size of the code -> productivity goes up. Readability and maintainability of the code goes up, too. Now, if we program the same thing in Java or C++ - would we want to manually code the state machine without linguistic abstraction, where we would like to get shorter source code? Probably not. There are now several ways to work around this. One would be to have an XML scheme describing state machines and a translator to Java code. Or defining a custom external DSL for it. This approach is quite popular. Now you need to learn Java and your custom configuration language, plus its implementation. Lisp just has a different solution for it: developers tend to implement kind of an internal macro-based DSL for these problems. The solution for that may look different from what Java or C++ uses - but they also need to abstract the code. If the code does not -> then you have here the reason why Lisp teams are smaller -> they are more productive. If a C++ program gets large enough, team size may go up ten times... I once heard an example for that from a Lucent manager who worked with a team of hundred people using Lisp.
- tobr 8y agoI could see it being extremely useful for inspecting and debugging, but I shudder to think of working on a large codebase with liberal use of proxies for production behavior. You wouldn’t be able to take anything at face value, not even the most innocuous looking expression. Getters and setters are tricky enough as it is.
- desc 8y agoI wholeheartedly agree with this assessment. Metaprogramming is incredibly powerful, and has its place, but it generally comes down to 'defining your own language'. It cannot merely be Javascript any more: one must learn the idioms of your own personal language which Just Happens to run as Javascript. As a junior dev I used to make maximal use of every language and platform capability I could find. These days, I'd rather just stick to the idioms and conventions of the parent language, because I want neither to maintain a compiler nor teach our junior devs how to use My Custom Language. It's enough to know that those capabilities are there without playing with them constantly. Boring is simple and maintainable. Best to confine the interesting to the 'what' (which it'll infest anyway) rather than the 'how' (which can at least be kept under control).
- dcherman 8y agoI agree. While you can accomplish some really interesting things with Proxy, I think that this article presents some poor examples that are actively harmful. I don't expect `delete` to be O(N) (actually worse if you consider the `ownKeys` implementation. I don't expect setting a property (sort) to invoke an expensive sorting operation. The list keeps going. While I appreciate what the author is trying to accomplish, I think this is an example of what not to do as far as code is concerned. Most of my practical usage of Proxies to date have been limited to some debugging tools that I wrote for AngularJS to help detect property changes that occur outside of a digest cycle. Don't think I've had any use cases that I've shipped to production code yet, though I believe Vue is considering using proxies for their reactivity model in the future to avoid the need for `Vue.get` and `Vue.set` for previous unknown properties or deletions.
- thisacctforreal 8y agoI particularly like the ``JSON.stringify({ name: "Albert Einstein" }) in dbProxy``.