views:

474

answers:

6

Is is that I'm a newbie learning Ruby, or does it really have more ways to write (the same) things than Java/C#? Also, if it is more flexible than Java, are there any linguistic features of Ruby that are generally not used to avoid confusion?

Examples might be parallel assignment and all the different ways to write Strings, perhaps?

Note: I'm not asking for a comparison with Java/C#... just this language question, please...

Edit: I understand that C#, Java and Ruby are strongly typed, and that only Ruby (like Python and others) is dynamically typed (while Java/C# are statically typed). Some of the answers say that dynamically-typed languages are more flexible. Is this necessarily true, and how does it affect syntax? I am only asking about syntactic flexibility.

(PHP is also dynamically typed and it does not seem more flexible than Java/C#, as far as I've seen. Again, I mean in terms of syntax, not in terms of deployment nor any other aspect...)

+1  A: 

Ruby is a dynamic language. C# and Java are both statically typed language with strong typing. C# in v4.0 will add dynamic features but till now, Java and C# have had a completely different and more strict paradigm than dynamic languages such as Ruby and Python.

Mehrdad Afshari
But Ruby is strongly-typed as well, right? Anyway, how does this change your options? It just means you don't have to define variable types... no?
Yar
In fact, no. It's not statically typed. Dynamic typing means the variable is not bound to specific type at compile time. It means the type can change. The nature of dynamic typing and dynamic dispatch gives the languages outstanding flexibility that's less seen in static languages.
Mehrdad Afshari
To clarify, "var x = 5;" in C# is statically typed, even though you didn't say "int x = 5;", the C# *compiler* will infer it at compile time and "x" will be an "int" in both cases. This is not the case in dynamic languages.
Mehrdad Afshari
Yes Ruby is strongly typed, but strongly typed != statically typed. In Java variables have types - in Ruby values have types.
Rene Saarsoo
Rene, exactly. This was what I tried hard to say, buy your statement was simple and great!
Mehrdad Afshari
Thanks Mehrdad. I still don't see how your answer actually answers the question. Ruby is not statically typed, C#/Java are. All three are strongly typed. So?
Yar
Ruby is not *statically* typed while C#/Java are. Dynamic typing allows deferring many checks to runtime and not nagging the programmer at compile time for unresolved method references or such things.
Mehrdad Afshari
There's a difference between "statically typed" and "strongly typed". Python is dynamically typed but also strongly typed. Languages like PHP are weakly typed, meaning the type changes depending on context. Adding two numeric strings can yield a number, for example.
Soviut
A: 

All dynamically typed languages (like Ruby) usually are more flexible than statically typed ones (like Java). You don't have to fight with the type system, which you often end up doing in statically typed languages.

Rene Saarsoo
+4  A: 

Another dynamic language that's fairly similar to Ruby is Python. However, in the Zen of Python, one of the rules dictates that "there should be one, and only one, way of doing something". This is a polar opposite to Ruby which allows so much meta-programming that there are essentially an infinite number of ways to do the same thing.

That said, its somewhat ironic that up until Python 3.0 (aka: 3000) string and unicode values were different types. While it makes sense, people sometimes get into issues where they're converting between the two a lot to perform text operations.

If you have a choice, I'd almost recommend using Python as your introduction to dynamic languages. There's nothing wrong with Ruby, but you may find you'll run into fewer situations where the "right" way to do something isn't totally obvious.

In response to PHP being dynamically typed:

PHP's type system is flexible, allowing types to be automatically converted based on what context they're used in. This doesn't actually make then real dynamic types, however. The language itself is mostly static and won't allow you to add attributes to objects at runtime, for example (at least, the last time I checked).

Python, and quite possibly Ruby, are actually strongly typed, meaning you can confidently do type comparisons, and can't do PHP tricks like adding numeric strings to get a number. True dynamic languages also often allow for meta-classing where you can adjust the type of an instance or class, or add attributes to either, all at runtime.

Soviut
Thanks. Fascinating and great answer. What about compared to non-dynamic langs like Java and c#? [I have no choice: I am "forced" to use Ruby and Rails.]
Yar
Also let me mention that, while it's off topic, Ruby has Rails and Python has a million different choices including DJango. And having a God is worth something these days, I think.
Yar
+7  A: 

As for me the most used features in Ruby and missing in Java are code blocks/lambdas/closures.

Another great (but maybe dangerous) feature is open classes - you can change whatever class you want - add new method, change old, etc. You can even add method to specific object, not the whole class :).

rkj
The word to describe the second paragraph is metaprogramming. not criticising you that is a good explanation just adding my thoughts.
andHapp
Awesome answer. Could you give a tiny example of a block/lambda/closure? Also, what do you personally NOT use in Ruby because it's too dangerous? THANKS for your answer.
Yar
Very often you want to supply a method with data which effects its result. What if you could also supply a method with a procedure in the same way?A very nice article called "Can your programming language do this?" features on the JoelOnSoftware blog;http://www.joelonsoftware.com/items/2006/08/01.html
deau
A: 

I don't know Java or C#, but I let the fact that you can redefine how + works on numbers talk for itself.

August Lilleaas
What does it say when it speaks for itself? "I do not exist in Java, use me with caution?"
Yar
Or is it, "like me, there are a whole bunch of other flexible features of Ruby that do not exist in Java/C#?"
Yar
+1  A: 

I commented on rkj's answer above regarding lambda's. This code demonstrates the example you asked for;

def abs(n); (n < 0) ? -n : n; end
def square(n); n * n; end
def average(x, y); (x + y) / 2; end

def fixed_point(x, point, process, test)
  return point if test.call(x, point)
  fixed_point(x, process.call(x, point), process, test)
end

def sqrt(n)
  process = lambda {|n,g| average g, (n/g) }
  test = lambda {|n,g| abs(square(g) - n) < 0.001} 
  fixed_point(n, 1.0, process, test)
end

The first point to notice is that the fixed_point method handles the general idea of progressively applying a process to some data until it passes a certain test. The sqrt function defines the process of finding a square root and the test to determine when we're to be satisfied. These 'procedures' are then passed just like any other form of data so that fixed_point can work it's magic.

Instead of temporarily storing the process and test the whole thing could be anonymous. We could rewrite sqrt as;

def sqrt(n)
  fixed_point( n, 1.0, 
      lambda {|n,g| average g, (n/g)},
      lambda {|n,g| abs(square(g) - n) < 0.001} )
end

Without this ability, I would have to define both the process and the test as individual functions and create a special sqrt_fixed_point function to call them. As far as I'm aware Java can do something similar using Functors but I don't know enough to comment. The consensus I've seen in blogs or similar is that Java makes this so horrendously complicated that you'll get a nosebleed just trying it.

Of course, another option that Ruby gives is metaprogramming. I could rewrite sqrt so that it rewrites (on the fly) fixed_point using the correct process and test, but this is probably an abuse of the feature :-)

ps. The JoelOnSoftware link is posted deserves repeating; http://www.joelonsoftware.com/items/2006/08/01.html

deau
Thanks for that. I'll have to read this over after sleeping. One thing I will point out is that lamba's and blocks are cute, but non-anonymous functions serve a HUGE function: they give names to code blocks... real names with real LOCAL variable names too. This makes code easy to understand, which is good (assuming it is essentially equivalent).... anyway, I'll comment m ore when I've worked through this fixed_point stuff.
Yar
Fascinating stuff, thanks for that. I do think that some of this syntactic compression (e.g., your last sqrt method) results in code that uses less characters but is less readable and NO more efficient. The lambda's are defined but don't get assigned to variables. My GUESS is that for Ruby it's the same (for efficiency, let's say) but the code is not quite as readable. Unless you are playing code golf, I prefer to define variables whenever it makes sense. Anyway, thanks and +1.
Yar