6 ms·
> Ruby isn't the most beautiful language out there Huh, I sure think it is. I wonder what the author thinks the competition might be? Ruby has its issues for s
by sho 8y ago
> Ruby isn't the most beautiful language out there
Huh, I sure think it is. I wonder what the author thinks the competition might be? Ruby has its issues for sure, but aesthetics ain't one of them - far and away my favourite out of any major language.
- smitherfield 8y ago> I wonder what the author thinks the competition might be? I think he meant beautiful in the conceptual sense (e.g. a beautiful algorithm) not the aesthetic sense. Aesthetically speaking, Ruby would definitely be in my top 3 and possibly first. For me its main competition is ML-syntax languages, in particular Standard ML and F#.
- empath75 8y agoI'm not sure what language would be more beautiful than ruby, to be honest, and it's not even my favorite language to use. Let's do a mini code challenge in the thread -- implement fizzbuzz in the most beautiful way you can, in the most beautiful language you know:
- dmitriid 8y agoSounds like a question for Code Golf[1] :) [1] https://codegolf.stackexchange.com https://codegolf.stackexchange.com Off-topic, take a look at "Add a language to Polyglot" which was concluded at 194 languages, but people kept adding more: https://codegolf.stackexchange.com/questions/102370/add-a-language-to-a-polyglot https://codegolf.stackexchange.com/questions/102370/add-a-la...
- mbel 8y agoLet's not forget about immortal RosettaCode: http://www.rosettacode.org/wiki/FizzBuzz http://www.rosettacode.org/wiki/FizzBuzz
- vram22 8y agoOne interesting thing about this set of solutions is that many of the languages seem to use a pattern-matching approach (e.g. Elixir, F#, Rust, others, IIRC). As a result, having been reading about pattern-matching recently (in F# and OCaml), I was able to understand the gist of the solutions in those languages, although I did not know those languages well or even somewhat, in some cases. Of course, this is for FizzBuzz, for which the logic is easy, which makes it easy to make guesses about how the code works (for many languages at least).
- xxs 8y agoOne liner side-channel attacks free/Java: public static void main(String[] a) { for(int n=0; n++<100;) System.out.println(new String[]{String.valueOf(n), "Fizz", "Buzz", "FizzBuzz"}[-n%3 >>> 31 ^1 | -n%5 >>> 30&2 ^ 2]); }
- k3liutZu 8y agoI think the above snippet is a great example of how code can be ugly.
- christophilus 8y ago(defn fizz-buzz [n] (map #(cond (= 0 (mod % 15)) "FizzBuzz" (= 0 (mod % 5)) "Fizz" (= 0 (mod % 3)) "Buzz" :else %) (range 1 n)))
- evdubs 8y agoSincerely, truly a thing of beauty. After writing Lisp code, I don't even understand what people mean when they talk about beauty with respect to programming languages. It's like there are rivers separating the aesthetics of Algol-like languages and an ocean between them and Lisp. Edit: Here is a Racket equivalent (define (fizz-buzz start finish) (for-each (λ (i) (println (cond ((= 0 (remainder i 15)) "FizzBuzz") ((= 0 (remainder i 5)) "Fizz") ((= 0 (remainder i 3)) "Buzz") (else i)))) (range start finish))) (fizz-buzz 1 101)
- Slackwise 8y ago(def fizzbuzz-nums (range 1 101)) (defn fizz? [n] (zero? (% n))) (defn buzz? [n] (zero? (% n 5))) (defn fizzbuzz? [n] (and (fizz? n) (buzz? n))) (defn fizzbuzz [n] (cond (fizzbuzz? n) "FizzBuzz" (fizz? n) "Fizz" (buzz? n) "Buzz" :else n))) (def fizzbuzz-list (map fizzbuzz fizzbuzz-nums)) (apply println fizzbuzz-list)
- christophilus 8y agoSimple. But this brings up a debate I've been having with some folks. I have the memory of a gnat, so I can't keep a lot of context in my head. I prefer the previous two examples to this one, simply because with this one, I have to remember a lot more contextual vocabulary. It's a pet-peeve of mine to pull up a source file, and then have to ping-pong around between 50 different function calls, when the entire thing could have been written linearly in fewer than 50 lines of code. On the other hand, small functions like yours are easier to verify at a glance and move on. I haven't figured out what the right trade-off is. Anyone else want to weigh in on this conundrum?
- vram22 8y agoBy coincidence, I had just posted this earlier and updated it recently: print(" ".join("FizzBuzz" if i % 15 == 0 \ else "Buzz" if i % 5 == 0 else "Fizz" if i % 3 == 0 \ else str(i) for i in range(1, 101))) From: FizzBuzz in Python with nested conditional expressions and a generator expression: https://jugad2.blogspot.com/2018/12/fizzbuzz-in-python-with-nested.html https://jugad2.blogspot.com/2018/12/fizzbuzz-in-python-with-... Not claiming its the best in any way, just a way that I thought of.
- fouc 8y agoHe asked for beautiful. Like if you showed it to a non-programmer, would they think it's beautiful?
- vram22 8y ago1. So what? It's not always that case that people on HN reply (or must do so) to a question with an answer that exactly answers the question and nothing else. Diversions are fine and done a lot by users here, within reason. Otherwise these threads would look and sound like classes in logic or theorem proving, ha ha. We're humans here. 2. Why are you interpreting what he (or she) meant? Let them do it themselves. 3. I qualified my earlier comment as saying that it is not necessarily the best way - up front. 4. Beauty is in the eye of the beholder, and beholders vary a lot in their tastes, whether programmers or non-programmers. Like the "de gustibus" quote: https://en.wikipedia.org/wiki/De_gustibus_non_est_disputandum https://en.wikipedia.org/wiki/De_gustibus_non_est_disputandu... So chill, pal.
- fouc 8y agocoffeescript (ruby-inspired): ['fizz' unless i%3] + ['buzz' unless i%5] or i for i in [1..100]
- fouc 8y agoruby: 1.upto(100) do |n| puts [ ("Fizz" if a = (n % 3).zero?), ("Buzz" if b = (n % 5).zero?), ( n unless (a || b) )].join end
- deleted 8y ago[deleted]
- qyv 8y agoRuby the Ruby way: module FizzBuzz def to_fb s = '' s << (self % 3 == 0 ? 'Fizz' : '') s << (self % 5 == 0 ? 'Buzz' : '') s << self.to_s if s.empty? return s end end Integer.include(FizzBuzz) 1.upto(100) { |i| puts i.to_fb }
- smitherfield 8y agoCleaner and more idiomatic version: https://news.ycombinator.com/item?id=18873581#18877403 https://news.ycombinator.com/item?id=18873581#18877403
- qyv 8y agoIMO monkey-patching built-in classes is idiomatic Ruby! Edit to add: Actually, now that I think about it, using method_missing would have been even better!
- smitherfield 8y agoWell of course. I originally linked to this code: https://news.ycombinator.com/item?id=18873581#18878500 https://news.ycombinator.com/item?id=18873581#18878500 But the edit window had passed by the time I changed it.
- throwaway427 8y ago(1..100).map { |i| i.modulo(15).zero? && "FizzBuzz" || i.modulo(3).zero? && "Fizz" || i.modulo(5).zero? && "Buzz" || i }
- smitherfield 8y ago#!/usr/bin/env ruby puts((1..100).map do |n| "#{:Fizz if (n % 3).zero?}"\ "#{:Buzz if (n % 5).zero?}" .then .find { |s| !s.empty? } || n end)
- jpatokal 8y agoI'm curious: do you genuinely find that beautiful?To me all the enumerable/map/frozen string literal stuff seems pointlessly overcomplicated compared to the simplicity of just writing down what you're supposed to do: (1..100).each do |n| a = String.new a << "Fizz" if n%3 == 0 a << "Buzz" if n%5 == 0 a << n.to_s if a.empty? puts a end (Disclaimer: not my code, on mobile so I stole that off GitHub)
- smitherfield 8y agoNot really; I was basing it off of https://news.ycombinator.com/item?id=18873581#18875961 https://news.ycombinator.com/item?id=18873581#18875961 as a semi-joke. I changed it to a relatively KISS and IMO genuinely beautiful version in the parent, for others' benefits here's the version you were referring to in the above comment: #!/usr/bin/env ruby # frozen_string_literal: true module FizzBuzz Integer.include self def self.array(enumerable = 1..100) enumerable.map(&:to_fizzbuzz) end def to_fizzbuzz "#{:Fizz if (self % 3).zero?}"\ "#{:Buzz if (self % 5).zero?}" .then .find { |s| !s.empty? } || to_s end end puts FizzBuzz.array
- deleted 8y ago[deleted]
- deleted 8y ago[deleted]
- dnautics 8y ago> I'm not sure what language would be more beautiful than ruby. Elixir (with static type analysis) - gets a bit of an edge, IMO, thanks to pipes, which are way prettier than .then: defmodule FizzBuzz do @spec fizzbuzz(integer)::String.t def fizzbuzz(int) do cond do rem(int, 15) == 0 -> "FizzBuzz" rem(int, 5) == 0 -> "Fizz" rem(int, 3) == 0 -> "Buzz" true -> inspect int end end end 1..100 |> Enum.map(&FizzBuzz.fizzbuzz/1) #[0] |> Enum.join("\n") |> IO.puts #[0] function variables are a very slightly "ugly #syntax" part of the language due to erlang legacy Other stuff that's really pretty in elixir is the first class documentation. Elixir docs are out of the box prettier than ruby docs. Compare from the official (but as a user you get these docs too): https://ruby-doc.org/core-2.6/Array.html https://ruby-doc.org/core-2.6/Array.html https://hexdocs.pm/elixir/List.html#content https://hexdocs.pm/elixir/List.html#content But again, it's only a bit prettier. Of course, if you try to browse both on mobile, Elixir wins handily. This is great for when you have to use the bathroom at the same time as you're in the middle of debugging and need to look up what a library module member function does, so there's some developer benefit edge too.
- bonquesha99 8y agoElixir/Unix style pipe operations in Ruby! https://github.com/LendingHome/pipe_operator https://github.com/LendingHome/pipe_operator
- dnautics 8y agoit's not nearly the same. Piping in elixir is a macro; it lets you preserve the other arguments in your function call. The IO.inspect(value, label: "label string") semantic is incredibly powerful. During debugging I often do this: value |> IO.inspect(label: "A") |> do_something |> IO.inspect(label: "B") |> do_something_else |> IO.inspect(label: "C") ... This gives me full visibility over the data transformations that are happening. And removing the IO.inspect's are trivial with an IDE like atom, vscode, etc. Also the way that the BEAM handles concurrent IO means that none of those strings that I send will be interrupted by other content, which is critical to interpretable println debugging in a concurrent environment. I haven't used the debugger (or IEX.pry, whic I hear is powerful) once.
- miraks 8y ago(1..100).each { |n| { 15 => 'FizzBuzz', 3 => 'Fizz', 5 => 'Buzz' }.find { |d, s| n % d == 0 }.then { |_, s| puts s || n } }
- masklinn 8y agoI've always loved the case analysis of a case/match: [case (n `rem` 3 == 0, n `rem` 5 == 0) of (True, False) -> "Fizz" (False, True) -> "Buzz" (True, True) -> "FizzBuzz" (False, False) -> (show n) | n <- [1..100] ]
- hirundo 8y agoThe author of this piece is Dave Thomas, who also wrote: "I came across Ruby in 1998 because I was an avid reader of comp.lang.misc (ask your parents). I downloaded it, compiled it, and fell in love. As with any time you fall in love, it’s difficult to explain why. It just worked the way I work, and it had enough depth to keep me interested. "Fast forward 15 years. All that time I’d been looking for something new that gave me the same feeling. Then I came across Elixir, a language by José Valim, that puts a humane, Ruby-like syntax on the Erlang VM." So while he loves Ruby he's mostly moved on to Elixir, which he loves partly because of how it builds on the ideas in Ruby.