Where should Ruby programmers look next?
Author |
Message |
wtd
|
Posted: Thu May 19, 2005 11:44 am Post subject: Where should Ruby programmers look next? |
|
|
Hopefully anyone with an interest in Ruby has an interest in learning different programming languages to explore the similarities and differences, and learn from them.
In that spirit, I'd like to challenge Ruby programmers here at Compsci.ca to learn Scheme. It may look different, but the underlying language feels somehow familiar, and comfortable. |
|
|
|
|
|
Sponsor Sponsor
|
|
|
wtd
|
Posted: Thu May 19, 2005 6:01 pm Post subject: (No subject) |
|
|
Let's look at some basic translations. Let's say we want a range function which constructs a list from a starting number to an ending number.
Granted, in Ruby I could just use something like:
But I'd rather have a nice recursive function.
Ruby: | def range(m, n)
if m >= n
[n]
else
[m] + range(m + 1, n)
end
end |
I could be a bit more succinct by using the ternary operator, I suppose.
Ruby: | def range(m, n)
m >= n ? [n] : [m] + range(m + 1, n)
end |
But the first one looks nicer. Now, let's create the same function in Scheme.
scheme: | (define (range m n)
(if (>= m n)
n
(cons m (range (+ m 1) n)))) |
The basic function definition syntax is:
code: | (define (range m n) ...) |
The name of the function is "range" and it takes two arguments: "m" and "n". The rest is a sequence of statements and expressions. Statements "do" something. Expressions return a new value based on input.
In this case there's only one expression, an "if".
Determines if m is greater than or equal to n.
The first expression following the conditional is what to return if the condition is true. The second corresponds to the "else" clause.
The "cons" function serves to "construct" a list, prepending the first argument to the second to create a new list. So, if we execute something like:
The steps look like:
code: | (cons 1 (range 2 6))
(cons 1 (cons 2 (range 3 6)))
(cons 1 (cons 2 (cons 3 (range 4 6))))
(cons 1 (cons 2 (cons 3 (cons 4 (range 5 6)))))
(cons 1 (cons 2 (cons 3 (cons 4 (cons 5 (range 6 6))))))
(cons 1 (cons 2 (cons 3 (cons 4 (cons 5 6))))) |
|
|
|
|
|
|
wtd
|
Posted: Sat May 21, 2005 1:51 am Post subject: (No subject) |
|
|
Let's look at local variables and input and output a bit.
Ruby: | def get_lines(file_name)
file_handle = File.open(file_name)
first_line = file_handle.readline
print "Get another line: "
get_next_line = file_handle.readline.strip
if get_next_line.downcase == "yes"
[first_line, file_handle.readline]
else
[first_line]
end
end |
And now, a straightforward translation.
scheme: | (define (get-lines file-name)
(let ((file-handle (open-input-file file-name)))
(let ((first-line (read-line file-handle)))
(display "Get another line: ")
(if (string-ci=? (read-line) "yes")
(cons first-line (read-line))
'(first-line))))) |
|
|
|
|
|
|
|
|