Wednesday 10 April 2013

Rebol vs Ruby

Today I'll show you the main differences between Ruby and Rebol:

Assigning

Assigning is different, I prefer Rebol way since you don't confuse assigning to evaluation.

RebolRuby
>> a: 3
== 3
>> a = 3
=> 3


Methods vs refinements


They seems different, but they are quite the same.
On Ruby side you may invoke something with a special method (.):

dir.entries

On Rebol side you use the refinement (/):

read/lines

There isn't difference.

Math


RebolRuby
>> 2 + 2
== 4
>> 2 + 2
=> 4
>> 10 + 4 * 10
== 140
>> 10 + 4 * 10
=> 50
>> 10 + (4 * 10)
== 50
>> 10 + (4 * 10)
=> 50
>> 40 / 3
== 13.3333333333333
>> 40 / 3
=> 13

If you don't use parenthesis with Rebol, math expressions are wrong evaluated. This is due to Rebol order evaluation form left to right.

On the other side Ruby use integer as standard result, so results are generally wrong. You have to add floating point to a number to get correct results (i.e. 20.0). Too bad!


String manipulation


RebolRuby
>> reverse "Hello word"
== "drow olleH"
>> "Hello word".reverse
=> "drow olleH"
>> length? "Hello word"
== 10
>> "Hello word".length
=> 10
>> loop 5 [append "" "Hello word"]
== "Hello wordHello wordHello wordHello wordHello word"
>> "Hello word"­ * 5
=> "Hello wordHello wordHello wordHello wordHello word"
>> reverse 40
** Script Error: reverse expected value argument of type: series tuple pair
>> 40.reverse­
=> #<nomethoderror: 40:fixnum="" for="" method="" reverse="" undefined="">
>> reverse to-string 40
== "04"
>> 40.to_s.re­verse
=> "04"
>> a: "My hairs are black, your hairs are red"
>> replace a "hairs" "nails"
== "My nails are balck, your hairs are red"
>> a = "My hairs­ are black­, your hairs­ are red"
>> a['hairs']­ = 'nail­s'
>> print a
=> "My nails are black, your hairs are red"

As you noted function and error are pretty similar, Rebol code is more intelligible. Even Rebol errors a clearer than Ruby ones.

Ruby substring substitution command is very cryptic.

Long text manipulation


We need to invert lines order of the following text:
Hello this is a test
What language do you prefer?
Rebol or Ruby?
Are you sure?



RebolRuby

>> a: {Hello this is a test
What language do you prefer?
Rebol or Ruby?
Are you sure?}

>> a = "Hell­o this is a test
What langu­age do you prefe­r?
Rebol or Ruby?­
Are you sure?­"

>> foreach item (reverse parse/all a "^/") [print item]
==Are you sure?
Rebol or Ruby?
What language do you prefer?
Hello this is a test

>> print a.lin­es.to_a.re­verse.join
=> Are you sure?
Rebol or Ruby?
What language do you prefer?
Hello this is a test


Ruby way is more concise. Even finding is more concise:

RebolRuby

>> true? find a "you"
== true

>> a.include? "you"
=> true

Rebol doesn't have the equivalent of Ruby's include?, so you must use find and true?.
Moreover Rebol found? has nothing relatinve to find, but it declare if a variable is set, this is a bad repetition since Rebol has also value? for the same purpose.

RebolRuby

>> lowercase a
== {hello this is a test
what language do you prefer?
rebol or ruby?
are you sure?}

>> a.lowercase
=> "hello this is a test
what language do you prefer?
rebol or ruby?
are you sure?"

Note that Rebol lowercase function modify the input string, on the contrary Ruby's one not. Rebol behavior should be improved.


Block


A block is a series of commands contained between bracket, Rebol uses square brackets, Ruby uses curly brackests:

RebolRuby

>> loop 5 [print "Hello" ]
== Hello
Hello
Hello
Hello
Hello

>> 5.times {print "Hello"}
=> "HelloHelloHelloHelloHello"


Array / Series


RebolRuby
[ 12 47 35]
== [12 47 35]
[12, 47, 35]
=> [12, 47, 35]
maximum-of [ 12 47 35 ]
== [47 35]
[12, 47, 35].m­ax
=> 47
sort a
== [12 35 47]
a.sort!
=> [12, 35, 47]

Note that maximum-of function return all the series after the maximum value, to isolate the value you need the first function:

>> maximum-of [ 47 52 20 1 2 3]
== [52 20 1 2 3]
>> first maximum-of [ 47 52 20 1 2 3]
== 52

This behavior is strange and may lead to big confusion to users.

Ruby distinction of function is better than Rebol, if a method (function) end with an exclamation mark (!) it changes the input. On the contrary the exclamation mark in Rebol is used just for variables types (money!, date!, etc.). I prefer Ruby way.

Words vs symbol


Ruby has symbols, words not evaluated; Rebol has words. Both ways memory isn't wasted.

RebolRuby

>> 'example

>> :example

Objects vs hashes


Ruby has hashes, Rebol doesn't have them. Hases that are very similar to Rebol objects:

RebolRuby

>> a: context [
car: 'good
bike: 'verygood
]

>> a = {"car"=>:good, "bike"=>:good}

Even if Ruby's style it's longer to type, Ruby's hashes are more flexible than Rebol objects. You may add or remove items to an hash, on the contrary an object it's more static.

You may access to the element in very similar ways:

RebolRuby

>> words-of a
== [car bike]

>> a.keys
=> [car, bike]

Functions vs methods


Ok, I admit, both ways are practical identically:
Ruby:

def mymethod(temp)
temp = temp * 2
temp
end


A method declaration start with def and end with end.

Rebol function way is:

myfunc: func [temp][
temp: temp * 2
temp
]


Class vs object

Ruby class and Rebol object are the same thing. Ruby way creation is more complicated. For example let's create a blogentry class/object empty:

RebolRuby

>> blogentry: context [
title: time: fulltext: mood: none
]

>> class blogentry
attr_accessor :title, :time, :fulltext, :mood
end

>> entry: make blogentry []

>> entry = BlogEntry.new
=> #

>> entry/title: "Toda­y Mt. Hood Was Stole­n!"
== "Today Mt. Hood Was Stolen!"

>> entry.titl­e = "Toda­y Mt. Hood Was Stole­n!"
=> "Today Mt. Hood Was Stolen!"

>> entry/time: now
>> entry/mood: 'sick
>> entry/fulltext: "I can't believe Mt. Hood was stolen! I am speechless! It was stolen by a giraffe who drove away in his Cadillac Seville very nonchalant!!"

>> entry.time = Time.now
>> entry.mood = :sick
>> entry.fulltext = "I can't believe Mt. Hood was stolen! I am speechless! It was stolen by a giraffe who drove away in his Cadillac Seville very nonchalant!!"


GUI


Even Ruby's GUI is on every OS as Rebol 2, Ruby GUI uses Tk libraries, but there are other libraries available. Rebol 3 GUI works only on Windows OS:

Rebol 2Rebol 3Ruby
>> view/title layout [
text "Hello, World!"
] "Hello, world"

>> view/options [
text "Hello, World!"
] [title: "Hello, world"]

>> require 'tk'
>> root = TkRoot.new { title "Hello, World!" }
>> TkLabel.new(root) do
text 'Hello, World!'
pack { padx 15 ; pady 15; side 'left' }
end
>> Tk.mainloop






There are many other GUI library available for Ruby, the most famous are:
  • FXruby
  • QTruby
  • Shoes
  • wxRuby
  • GnomeRuby
  • RubyCocoa
  • Winforms

Documentation

The open source essence of Ruby, mixed with a good site and documentation create a huge community. Here is the available documentation:
Rebol Ruby

Branches


The Ruby's developer has been always pleasant with forks of his source, so we have:
Rebol Ruby
  • Rebol 2
  • Rebol 3
  • Rebol 3 Bazaar

  • Jruby: Ruby fo JVM platform
  • Ruboto: Jruby on Android
  • Rhodes: ruby for mobile phones
  • Cruby
  • Ruby 1.9.3
  • Ruby 2.0.0
  • mruby

Verdict


Rebol and Ruby give you the same tools to create your application. Rebol is elegant and a little more simple to write, on the other hand Ruby is better documented and known. You can find anything you want about Ruby on internet, the source, documentation, binaries and libraries. All is open, so it's easy to improve it.
On the contrary in the last 10 years Rebol lost all support, learning Rebol is very difficult and at the present no one know very well the just released code of Rebol 3. Moreover at the present only Rebol 2 is totally cross-platform.

For big project, Ruby is mature and complete, while Rebol needs a big community to reach Ruby level. What you can do? Spread Rebol!

6 comments:

  1. value? and found? are different. value? returns true if the given word HAS a value (ie. not unset!)

    And in control structure no need to use true? or found?

    >> if find "test" "s" [print "ok"]
    ok

    ReplyDelete
    Replies
    1. You are right, my concern is that I would expect "found?" to be relative to "find". Instead "found?" is very similar "value?" and "none?".
      However I like that this post shook the Rebol community :-)

      Delete
  2. Show me any programming language easy to learn?
    REBOL is difficult to learn, but JAVA, C#, C++, VB, F# LISP, COBOL, Pascal, Assembler, APL, SQL etc are difficult too:)

    ReplyDelete
    Replies
    1. You are right. Difficulty of a language in my opinion is the result of 2 elements:
      - language itself (Rebol is extremely easy)
      - documentation (Rebol lacks of good documentation)

      Delete
  3. Ruby: a.sort!
    REBOL: sort copy a

    Ruby: a.sort
    REBOL: sort a

    ReplyDelete
    Replies
    1. About lowercase and other action! function, the Ruby way to notice with an exclamation point functions that modify the argument is good. Rebol sort, lowercase, uppercase, etc., modify the input, but you have to read the help to know it. If I try:

      A: [ 3 4 1 2]
      B: sort A

      both B and A are changed, but user may not know it.

      Delete