5 ms·
(1..100).inject(&:+)
- akehurst 19y agoWhy I hate ruby.
- raganwald 19y agoThe post? Or the quoted snippet of code? ;-)
- mrtron 19y agoSince I don't use ruby either...I tried a web based interpreter. >> (1..100).inject(&:+) TypeError: wrong argument type Symbol (expected Proc) from (irb):1 I also am not a fan of doing things a thousand different obscure ways. I like doing things one way, and having that way highly optimized. Typing 10 characters or 20 characters doesn't impact my programming speed, I spend far more time thinking about how to do things the right way. edit: Ok, did his monkeypatch and it worked. You get 5050. So it is equiv to sum(range(101)) in python, and much less readable. I fail to see why this is a good thing.
- Xichekolas 19y agoIt won't work unless your web-based interpreter runs Ruby 1.9, or you also paste in his monkeypatch to the Symbol class.
- raganwald 19y agoI refuse to be blamed for Symbol#to_proc, it's a part of Rails and also Ruby Facets.
- Xichekolas 19y agoYeah I didn't mean to blame you... I actually like it, so consider it a complement, but it was just the easiest way to describe what patch I was talking about, since you had it in your article. Any idea who specifically wrote it initially?
- deleted 19y ago[deleted]
- raganwald 19y ago"I fail to see why this is a good thing." Why what is a good thing? Why that line of code is a good thing? maybe it isn't, maybe arrays need a sum method, maybe you could just write: (1..100).inject { |acc, n| acc + n } ...and get the same result. But the article has nothing to do with why that line of code is a good thing, it is about the fact that being able to modify the Symbol class in this manner is what makes a langauge like Ruby evolve from the bottom up. So... do you think that is a good thing? Or a bad thing?
- mrtron 19y agoI think that style of code is rather hard to read and really doesn't add any functionality that couldn't be done in a much more readable way in the same number of characters. So I am wondering why the author thinks its so fantastic. As for developing the language, I am usually for flexibility and allowing anything to be modified, however this type of change strikes me as not very useful.
- raganwald 19y ago"I am usually for flexibility and allowing anything to be modified, however this type of change strikes me as not very useful." That's entirely the point. If you are in favour of flexibility, you have to accept that people will use it for all sorts of things, not just ones you like.
- mrtron 19y agoI was talking about the fact that they are making that change on the core language. Providing the flexibility is different from putting it in the language. Anyways, I don't really care, saying anything other than 'I love ruby' is shunned anyways.
- raganwald 19y ago"saying anything other than 'I love ruby' is shunned anyways." Well... I welcome criticism of Ruby. Please say whatever you like in a comment right on the post. I've never shied away from writing about the things in Ruby that irritate me. How else will we progress if we don't scratch when we have an itch?
- Xichekolas 19y agoHahaha... Reg, it's like you wrote this in response to the recent article on Monkeypatching floating around here... Thanks! I enjoyed your writing as much as always... and it's especially timely today. (http://news.ycombinator.com/item?id=123071 http://news.ycombinator.com/item?id=123071 if you don't know to which I am referring.)
- raganwald 19y agoWeeeel... The truth is, I wrote the idea behind this a while back using String#to_proc to compare the way Ruby (roll your own) and Python (Guido decides) evolve. But considering I have no Python experience, I never published the post. Then today, for some reason, I was thinking about Open Classes again :-)
- spydez 19y agoAnyone want to explain that code to someone who doesn't know Ruby?
- wvenable 19y agoI'm not a ruby programmer and it's not immediately obvious what the result would be. I know a pretty large number of languages to the point where, unless it's LISP, I can look at code in any language and have some idea of what it does. When a languages gets "so cool" that it's cryptic than I no longer see the benefit.
- raganwald 19y agoWould (1..100).fold(&:+) be more obvious? How about (1..100).reduce(&:+)? If either one of those makes sense, perhaps it is a question of Matz choosing Smalltalk's names for methods (collect, select, detect, reject, inject). Please let me know if changing the name of the method doesn't help.
- spydez 19y agoA little explanation in your article would've been fine. The non-ruby people in the crowd have no clue what "&:+" does, so you lost us really early on when you neglected to explain your fancy one-liner. 'inject' makes sense (in retrospect), but until it was explained, I had no clue why injecting symbol soup into a range of integers was interesting.
- raganwald 19y ago"I had no clue why injecting symbol soup into a range of integers was interesting." Lisp flavours? "A little explanation in your article would've been fine." Done, thank you.
- Xichekolas 19y agoSums the first 100 integers. You are basically injecting a function (plus in this case) between each element and evaluating it (to describe in very non-technical sense).
- henning 19y agoThe VB.NET equivalent is Enumerable.Range(1, 100).Sum, which seems clearer to me. Why is this so impressive? If Visual Basic comes close to your beloved code snippet, it's probably not that big of a deal. In real life, the answer is to know some math and realize that 1 + ... + n = n(n+1)/2, so the entire thing is pointless anyway. (And if you want to add methods to a given class ad-hoc, you can do it statically with extension methods; Sum is an extension method.)
- raganwald 19y agoThe article does not claim that this is a good thing! It claims that the line of code says a lot about Ruby the language.
- henning 19y agoThat it's obsessed with obfuscatory, slow language constructs?
- raganwald 19y agoLet me ask you a question: you arrived at the top of the article with a preconceived idea about Ruby. Did reading the article give you any insight, did you learn something about Ruby or about yourself by reading the post? If not, please downmod it, I have failed.
- mynameishere 19y agoor about yourself At the risk of getting even more downmods for saying true things here, can I just point out that it's a little arrogant to pretend that a blog post about Ruby is going to move someone towards self-actualization? Anyway, have you failed? No. You wanted to show us your favorite line of Ruby code, and you did. As for me, I don't really have a favorite "one line" of code, but I fondly remember when I was a kid typing in Nibble Magazine's "one and two-liner" programs. Actually, the "lines" were lines as defined by the Apple II's command line buffer limit. Here's an example: http://www.apple2.org.za/mirrors/ground.icaen.uiowa.edu/apple8/Pgms/rotatecube.bas http://www.apple2.org.za/mirrors/ground.icaen.uiowa.edu/appl... Maybe I'm not a sufficiently abstract person. My favorite two lines of code was an honest-to-god graphical car driving program in two lines of APPLESOFT BASIC [1]. Two lines of code in a language so crappy it's basically a joke. And yet...a full-on-graphical-car-racing program. I'm strongly tempted to think that APPLESOFT BASIC is superior to Ruby, based on the evidence I've seen. Point is: The next time you show a feature of a langauge, maybe make it solve a problem, or create something real, rather than just showing how few characters it takes to do something banal. Adding numbers together? Seriously, it's a solved problem. [1] Sorry for the capital letters, but I'm in Apple mode now: http://www.apple2.org/images/Literature/a2/BlueBook.JPEG http://www.apple2.org/images/Literature/a2/BlueBook.JPEG
- Tichy 19y agoActually he is wrong about Java: people did add features to it without changing Java itself, for example AspectJ, and CLIB (I think is the name) that generates Java Code on the fly. Hibernate uses it, for example, to change the behaviour of the mapped Objects behind the scene.
- raganwald 19y agoYou would be amazed what people will do to Java. Just the other day I was reading something here about writing Java code using an Excel spread sheet. I'm pretty sure that wasn't in any of the JSRs.
- kommissar 19y agoWhat does the &: do in Ruby?
- raganwald 19y agoActually, it's &(:+) not &:(+). The & takes its argument and converts from a Proc to a block. :+ is a symbol that implements the method #to_proc to give you a block that sums its receiver and its argument.
- kommissar 19y agoOh, cool. I knew the colon meant a Ruby symbol, but I did not know that you could use & to convert a Proc to block.
- Darmani 19y agoTokens beginning with a colon are literal Ruby symbols. Prepending an ampersand before the last argument of a method call means that argument should be converted into a Proc and sent as a callback block to that method.
- mattjones 19y agoTo some degree, using open classes is just how you write functions in Ruby. Say there exists a class called Errors in some Ruby library. It doesn't have an each() method, but I'd like it to. Nobody would complain if I wrote a function each_error() which took an Errors object as an argument. Reopening the Errors class and giving it an each() method is the way you do that in Ruby, and it's not really any more dangerous.
- foonamefoo 19y agoThen lets say you packaged that up as a library. Another guy did the same thing, but it worked a little different. Now random code breaks.
- ken 19y agoIt turns out not to be a problem in practice. I could list the 20 things I hate most about Ruby and the 20 things I hate most about Rails, and this wouldn't make either list. I don't know that I've ever seen it happen. And on the "technically, could it happen?" side, sure, it could. You can also write a Java library that, in weird cases, could screw up other Java libraries, but the Java folks (even as much as they love to try to keep you safe) don't care, either. Besides, "each" is quite standard in Ruby. Defining it to mean something other than "call the proc with each element, in order" would be weirdbad, like a C++ programmer defining operator+ to mean subtraction. If you do something weirdbad like that, your library deserves to lose.
- mynameishere 19y agoThat sort of thing, for all of its doubtless glories, represents nothing so much as a contempt of the next programmer who has to deal with it. We're just moving bits and bytes around here, people. Please sum up the numbers and don't introduce any mysteries into the plumbing. ALL OF THE REAL INNOVATION IN SOFTWARE IS RELATED TO THE PROBLEM DOMAIN AND NOT THE LANGUAGE
- pg 19y agoIf you're saying something that's actually true, you don't need to use all uppercase.
- mynameishere 19y agoONE PLUS ONE EQUALS TWO. God, I hope I didn't just rip open the space/time continuum.
- futureNameHere 19y agoIndeed you did. I'm from the future to tell you that really don't need to use caps.
- mhartl 19y agoI use Symbol#to_proc every day. I've never cared for the term "inject", though (or Python's "reduce", for that matter); I find SICP's "accumulate" much more mnemonic. For what it's worth, (1..100).to_a.sum works in Rails, though (1..100).sum doesn't.
- dusklight 19y agoSo just out of curiosity .. what do you think is the most beautiful way to right the equivalent code in arc?
- tel 19y agoIn this case, the "equivalent" code isn't a line that produces the same result, but is instead a line that illustrates the dynamic culture of the given language's evolution. For Arc, right now, practically every line is an equivalent.
- raganwald 19y agoThank you, exactly!!!
- dusklight 19y agoWell okay let me elaborate on my question. pg has stated that code brevity is one of the main design goals of arc. But what is pretty obvious is that code brevity is not the only consideration. It is desirable to be able to write very short code, but it should be readable as well. If you write very short code that is difficult for other people to read, that is bad enough. If you write very short code that ends up being difficult even for yourself to read -- then we have a problem. The above ruby code snippet is a great example of code where reducing the length not only did not reduce readability, but actually increased it. I know some people have complained about it being obfuscated on this board. But to me, and I am sure to a number of other people on this board, it was easy to understand, intuitive even. so .. in arc, what would be a similar way to create a list of numbers from 1 to 100, and to evaluate the sum of that list?
- tel 19y agoThat question is somewhat interesting just a little off-topic in this thread. In Arc, that line would be: (reduce + (range 1 100)) which is nice, but not much different from Scheme. Pretty readable.
- rontr 19y agoIf Symbol#to_proc is so great, I'd like to see how it can elegantly express something that can't be hidden behind a simple library function. In any decent language the programmer would write "sum(1,100)". Even if the function's implementation in Python/Java/C++/Smalltalk/Lisp/etc required a few more characters, it wouldn't be a meaningful difference. Does Symbol#to_proc add any real power to Ruby or beyond enabling such linguistic brain teasers?
- raganwald 19y agoYour question takes my breath away. May I quote you?
- rontr 19y agoOnly if you first answer it.
- raganwald 19y agoThere are so many answers! Here are a few: The article does not claim that (1..100).inject(&:+) is great. It claims that it is a totemic example of Ruby code. There is nothing that technique X can do that technique Y cannot do given that X and Y are both Turing Equivalent. Of course you can write a library function to sum numbers. Do you also need a library function for the product of numbers? If so, you now know of a salient difference between the two approaches. One needs a function for each thing you want to do, the other gives you some pieces you combine in different ways to do what you want. Is one better than the other? That's up to you to decide, you are the programmer. Ruby lets you write your program either way. Now, Symbol#to_proc doesn't, in my opinion, add what I would call power. That's because you can always use a block or a lambda wherever you would use a symbol. But I may not have written the article well: the powerful and dangerous feature in Ruby is not Symbol#to_proc, it's Open Classes. Symbol#to_proc is an example of something you can do with an Open Class. Something else you can do with an Open Class is Hash#to_proc. Something else is Object#andand, a low-rent version of the Maybe Monad in Haskell. I consider Open Classes to be powerful and dangerous. Am I advocating them? Of course not, it is up to you to decide whether they are a good idea or not. What I find interesting about them is that Rubyists are pushing the language in new directions with them, like Symbol#to_proc. The idea of a language growing from the fringe is also powerful and dangerous. The fringe is an uneducated, seething mass.