Hi,

(this is a bit long)

A friend has been trying to get me into REBOL for some time. Its a new
scripting language by Carl Sassenrath, a legendary AmigaOS designer.
REBOL is a scripting language much like Ruby, but its syntax is
(from my very limited experience) a bit "different" and its closed-source.

However, it's got some nice properties that my friend has been "hitting"
me with. Below is a summary of some REBOL niceties. I wrote it after
checking out the docs on the REBOL site and trying some very simple
scripts. I'm sure its a very incomplete description of REBOL's nice
features but anyway...

I'm sending this so that we can check that we can do the same things in 
Ruby in a simple manner. Not because we must do the same things as REBOL 
but since they are useful ideas/idioms that we may have something to learn 
from; "Embrace and Rubify" TM. ;-)

There are quite a number of challenges to take on below. I've
added them to the garden wiki so in case anyone wants to step up to the 
challenge please note so there. The page is 
http://www.rubygarden.org/ruby?LibraryModules.

If any Rubyers out there have looked into REBOL I'd also like to hear
your impressions, and how you compare it to Ruby.

Regards,

Robert



REBOL niceties:

R1. "Native" support for Internet protocols 
-------------------------------------------
  HTTP, FTP, SMTP, POP, NNTP, Daytime, Whois, Finger, DNS, TCP, CGI, UDP

  RF comment: I'm not sure about Daytime, Whois, Finger and DNS but the
  other ones are covered?! Rest should be easy as pie. If you want to
  contribute to Ruby then why don't you take on one of those?

R2. Internet protocols can be used very easily
----------------------------------------------
  Examples:

  1. The following example fetches email with the post office protocol
     (POP) and prints all of the current messages but leaves them on the server: 

      foreach message read pop://user:pass / mail.dom [
        print message
      ]

  2. The following example shows how to use the HTTP protocol to read a
     web page: 

       page: read http://www.rebol.com

  RF comment: I think we may have to write some convenience class methods
  that enables this kind of access. Something like

    require 'net/pop'
    Net::POP3.read("user:pass / mail.dom").each {|m| print m}

  and

    require 'net/http'
    page = Net::HTTP.read("www.rebol.com")

  for examples above? Maybe this is available already? If not I think we
  should add it since its good to allow terseness if one wants to do
  simple things.

  We might even add Net.read which can handle URI's so that we could do

    Net.read("pop://user:pass / mail.dom").each {|m| print m}

  and

    page = Net.read("http://www.rebol.com")

  Comments?

R3. All scripts have headers with meta-info
-------------------------------------------
 From REBOL docs:

 "Headers are useful for several reasons. 

 * They identify a script as being valid source text for the REBOL
interpreter. 
 * The interpreter uses the header to print out the script's title and
determine what resources and versions it needs before evaluating the
script. 

 * Headers provide a standard way to communicate the title, purpose,
author, and other details of scripts. You can often determine from a
script's header if a script interests you. 

 * Script archives and web sites use headers for generating script
directories, categories, and cross references. 

 * Some text editors access and update a script's header to keep track of
information such as the author, date, version, and history. 

 The block that follows the REBOL word is an object definition that
describes the script. The preferred minimal header is: 

  REBOL [
    Title:  "Scan Web Sites"
    Date:   2-Feb-2000
    File:   %webscan.r
    Author: "Jane Doer"
    Version: 1.2.3
  ]"

 RF comment:
  I think this is nice even if it shouldn't be mandatory. Similar to whats
  been discussed in Raa.succ/RubyGems threads.

R4. Rebol can be specialized to a special domain by defining a dialect
----------------------------------------------------------------------
 From the docs:

 "Dialects are sub-languages of REBOL that use the same lexical form for
all data types but allow a different ordering of the values within a
block. The values do not need to conform to the normal order required by
REBOL function arguments. Dialects are able to provide greater expressive
power for specific domains of use."

 For example, REBOL includes a simple parser. To write a grammar you use a
 a dialect which allows you to write somthing similar to BNF directly in 
 REBOL. You can use this parser to write your own REBOL dialects.

 For an example of a dialect see R5 below.

 RF comment: I'm not sure what to think of this. On the one hand I think
 its a good thing and essentially what we are doing when defining classes
 and using them. But it does not seem necessary to change the language
 syntax to accomplish it. However, I definitely think we should learn from
 the terseness of expression that these dialects allow. By having a full, 
 ordinary OO model but writing very easy to use convenience methods on top 
 of it I think we can accomplish the same thing. 

 The included parser is nice since its so easy to use. You can probably do
 most of it with Regexps and code or revert to a parser generator for more
 complex stuff. Might be nice with a really simple convenience layer on
 top of a parser gen. I plan to add something along these lines to Rockit
 but its not high prio.

R5. Visual Interface Dialect for writing GUI's
----------------------------------------------
 VID is a dialect for writing GUI's. The GUI's are REBOL-specific and have
 their own look-and-feel but it seems flexible enough to look like native
 widget sets.

 "Two functions are used to create graphical user interfaces in
REBOL: VIEW and LAYOUT. 

 The LAYOUT function creates a set of graphical objects. These objects are
called faces. You describe faces with words and values that are put into a
block and passed to the LAYOUT function. 

 The VIEW function displays faces that were previously created by
LAYOUT. The example below shows how the result of the LAYOUT function is
passed to the VIEW function, and the interface is displayed."

 Example: Creating a message window with a text field and a button:

    view layout [
        text "Layout passes its result to View for display."
        button "Ok"
    ]

 RF comment: I think its a good thing to be able to create GUI's with a 
 minimal of effort. I don't know the existing GUI's for Ruby very well so 
 maybe something like this can already be done. If not it might be a good
 candidate for the top-level GUI abstraction layer? Then GUI binding
 authors can write classes that map the simply top-level stuff to their
 specific GUI.

R6. Compression built-in
------------------------
    compressed_string: compress string

 to compress and

 decompress compressed_string

 to decompress

 RF comment: I think we need to add this ASAP. And written in Ruby not
 in extension. We need portability.

 I think Ryan Leavengood has planned to add zlib's deflate
 algorithm. That's probably good since its so common but I'd propose using
 LZO since its the fastest when decompressing and still compresses almost
 as good or sometimes even better than deflate. This can be important if
 the gems can be compressed and needs to be decompressed by interpreters
 when loaded. Look at 
 http://wildsau.idv.uni-linz.ac.at/mfx/lzo.html. The license is GPL so not
 a problem, or?

R7. Encryption built-in
-----------------------
 Same as R6 but for encryption/decryption of data. I'm unsure which
 algorithms they include.

 My comments are similar as in R6 but to me this is not as high on the
 prio as compression. Probably choose one of the latest algorithms and
 base on an existing implementation since there are pitfalls when doing
 these things...

R8. Request broker Rugby
------------------------
Rugby is not part of REBOL/Core but a much touted add-on. Here's from its
docs:

  Rugby allows you to expose any set of global commands in one line of
code to other Rebol processes.

  A simple sample of Rugby usage, with the incredible useful function
"echo" that returns a compressed version of whatever you put in.

  echo: func [ in [string!]] [ return compress in]

  You can make this incredible service available with the following line
of code:

  serve [ echo ]

  The Rebol process now enters "network listen and serve" mode, and your
first Rugby server is live! But... you want to use it. Say you started the
service on foo.bar.com:8989 and want to have you name echo'ed:

  You simply do:

  do get-rugby-service tcp://foo.bar.com:8989
  echo "Joey"
  >> "Joey"

  As you can see, the first line made the echo function locally available
to you. When you call it, echo handles all communications to the server
'echo function and transparantly returns the result.

 RF comment: We almost have this in dRb, but again I think we could
 simplify its use with some convenience methods. In the commercial version
 of REBOL you can have security in the communication. When we have some
 encryption routines written in Ruby it should be simple to add.