4 ms·
If you feel Clojure is less expressive than Ruby, you're not good enough at Clojure yet. I'm not saying you have to prefer Clojure's syntax, and Ruby probably h
by kyllo 12y ago
If you feel Clojure is less expressive than Ruby, you're not good enough at Clojure yet. I'm not saying you have to prefer Clojure's syntax, and Ruby probably has more libraries for a lot of things you want to do. Going from Ruby to Clojure may be a productivity tradeoff for you and your team, but objectively it's not an expressivity tradeoff. Clojure has a bit more expressive power than Ruby.
- davidann 12y agoCould you reference examples of this assertion please?
- kyllo 12y agoI think the biggest reason would be Clojure's macro system. The code itself is an abstract syntax tree that you can rewrite in arbitrary fashion at macro expansion time. There's a good example here of how Clojure's macros are more powerful/expressive than Ruby's instance_eval and class_eval: http://daveyarwood.github.io/2014/07/09/whys-guide-to-ruby-in-clojure-part-5/ http://daveyarwood.github.io/2014/07/09/whys-guide-to-ruby-i... And here's an attempt to objectively rank programming languages by expressiveness, measured as lines of code changed per commit: http://redmonk.com/dberkholz/2013/03/25/programming-languages-ranked-by-expressiveness/ http://redmonk.com/dberkholz/2013/03/25/programming-language...
- akmiller 12y agoNot sure what examples the author was thinking of but functional lisps tend to be extremely expressive just because of their nature. If there is expressiveness you are missing the language can be molded in ways that are simply not possible in non-homoiconic languages.
- davexunit 12y agoEasy. Ruby doesn't support syntactic abstraction via macros. No, 'eval' doesn't count.
- danneu 12y agoI think it's pretty uncontroversial to suggest that Clojure is more expressive than Ruby - without even getting into macros. Just take run of the mill Ruby code and convert it to Clojure. Especially anything that looks like functional programming.
- heliumcraft 12y agoMaybe you're the one who's not good enough at Ruby yet. :)
- ssmoot 12y agoIn Ruby you can't express the concept of an empty List through a Type. When comparing statically typed languages to non, that's generally what "expressiveness" means to me. Any idea can be expressed through expressions in a turing complete language right? That's not a useful metric. In Ruby a method's type-signature expresses almost nothing for example. def f(a,b) Does the method side-effect? What types are a or b? Are they the same type? Does the method mutate the arguments? Return a new value? What sort of values might it possibly return? In Ruby you can't express any of these things outside of naming conventions (that are entirely useless for answering any of these questions to any tooling). Compare that to Scala: def f(a: Int, b: Int): Int Does the method side-effect? Almost certainly not (but it would typically depend on the containing Type). What are the types of a and b? Integers. What does it return? An Integer. Does it mutate the arguments? No; they're immutable. Is it possible for the method to return anything else? Throw an exception perhaps? That would be unexpected. Otherwise you'd write it to return a Try[Int], so you can assume more about the author's intent here.
- kyllo 12y agoWell now you're getting into statically vs dynamically typed, which doesn't apply to this conversation because both Ruby and Clojure are dynamically typed. But in a statically typed language like Scala or Haskell, you can use the typechecker to express proofs about program correctness. That is a form of "expressiveness" that doesn't really exist in Ruby or Clojure (unless you use core.typed).
- ssmoot 12y agoThere's nothing about dynamic typing that prevents declaring types right? Because in Ruby you while you can extend an instance, you can not taketh away Types from it. IOW, Ruby could use the Scala syntax I wrote, and still be just as Dynamic. You're already constrained by how you use that type within your method. You're just not expressing it concisely since you have to read the method to understand the implicit Type it's operating on. In practice a lot of this gets naturally conflated though. Which I think you were getting at. But if we're going to limit ourselves to functions with undeclared types, I guess I'd point to Clojure's partial as something you can't really express with Ruby. Or Pattern Matching in Elixer.