Archive for the 'rebol' Category

Some Haskell vs. Rebol observations (and some Lisp-ness)

Sunday, September 6th, 2009

It’s Sunday morning so I took some time for myself. I have a strong affinity to Functional Programming but I haven’t really done anything with Haskell yet. I read about it a lot but so far preferred OCaml for things where I wanted a compiled language.

Today I started reading Real world Haskell, I didn’t come too far yet, but I noticed two things in comparison to REBOL which I use currently the most.

Infix, Prefix and Parenthesis

Haskell seems to have a whole precedence levels going on, like c++ for example. So you don’t need parentheses in this case from the RWH book:

Function application has higher precedence than using operators, so the following two expressions have the same meaning.

ghci> (compare 2 3) == LT
True
ghci> compare 2 3 == LT
True

If I understand REBOL precedence I think it’s left to right with prefix and infix words, only infix words/operators take precedence over prefix. So the example above is one of the few code patterns where you DO need parenthesis in REBOL (let’s change it a little to some REBOL words so you can run it in REBOL shell):

>> (add 2 3) == 5
== true
>> add 2 3 == 5
** Script Error: add expected value2 argument of type: number pair char money date time tuple
** Where: halt-view
** Near: add 2 3 == 5

That’s why in this cases most rebolers use the prefix words (I think all infix words have prefix variants so you could unify this totally by using just them if you wanted).

>> equal? add 2 3 5
== true

Where you don’t need parenthesis. But if it makes your code more readable you can add them.

>> equal? (add 2 3) 5
== true

If you are a Lisp fan you can also write it like this. You can probably see now why some people call Rebol a Lisp without the parenthesis:

>> (equal? (add 2 3) 5)
== true
>> == + 2 3 5
== true
>> ( == ( + 2 3 ) 5 )
== true

equal? is prefix for == and add is prefix for + so we can write the same thing in another 2 ways, and we don’t need parens for that either:

>> equal? 2 + 3 5
== true
>> 2 + 3 == 5
== true

Function application and Parenthesis

The next example from Haskell book also shows a difference. You HAVE to add parens to this case where there is only function application.

Sometimes, however, we must use parentheses to indicate how we want a complicated expression to be parsed.

ghci> compare (sqrt 3) (sqrt 6)
LT

When REBOL is do-ing it’s code it knows how many values each function needs to consume. That’s why there are no optional function arguments in REBOL (but there are function refinements .. a very interesting feature on it’s own), and that IS the reason REBOL is Lisp without the parenthesis.

The above code does not need the parens in REBOL

>> greater? square-root 3 square-root 6
== false

We could also get all parens crazy and write it like this:

>> >> (greater? (square-root 3) (square-root 6))
== false

Code is data?

Haskell is an advanced, cutting edge research language, so I just forgot somehow that Haskells, OCaml’s and other static languages don’t give me the code-is-data/data-is-code that I got so used in Rebol. The next chapter of book started with Lists and Tuples that look like this:

ghci> head [ 1, 2, 3 ] -- a List
1
ghci> fst (1, 'a') -- a Tuple
1
ghci> snd (1, 'a')
'a'

Oh, no… the comma hell all over again!!! If any advanced language NEEDS to use commas it should at least make it like this to have a consistent, repeatable format.. we are programming here, not writing a letter to our grandma!?!

ghci> head [ 1, 2, 3, ]

:1:11: parse error on input `]'

head / fst / snd / ?? .. I won’t even go into this..

ghci> snd (1, 'a', 2)

:1:4:
    Couldn't match expected type `(a, b)'
           against inferred type `(t, Char, t1)'
    In the first argument of `snd', namely `(1, 'a', 2
    In the expression: snd (1, 'a', 2)
    In the definition of `it': it = snd (1, 'a', 2)

In REBOL, you don’t need tuples, lists (and other N data structures). In REBOL you have just series (sometimes they are also called blocks).

>> first [ 1 2 3 ]
== 1
>> first [ 1 "a" ]
== 1
>> second [ 1 "a" ] ; no comma noise btw!
== "a"

Everything is a series! (yes even that line that I input into shell is a series that is then do-ed). Series can hold anything, besides regular value types also words, lit-words, get-words… etc. and you have tons of words that work on all those series of anything. Let’s do something stupid

>> foo: [ join "Hello" "World" ]
>> insert foo 'print
>> probe foo
[print join "Hello" "World"]
>> if true foo
HelloWorld

This is probably moving into the theme of static vs. dynamic languages and I guess there are only Lisps, Schemes, Factor and REBOL for me if I want cid/dic. So far for now…

Reblog this post [with Zemanta]

REBOL’s actor-net used for real distributed system

Friday, July 3rd, 2009

3 things you probably can’t do in yer daddy’s language…

Friday, June 12th, 2009

Playing with making an Actor-like distributed system in REBOL #3

Monday, June 8th, 2009

Playing with making an Actor-like distributed system in REBOL #2

Tuesday, June 2nd, 2009

A peek into WIP Trail Testing Engine

Friday, April 24th, 2009

Playing with making an Actor-like distributed system in REBOL

Sunday, April 12th, 2009