Changeset 8723 in project

02/23/08 22:31:38 (12 years ago)

Adding info for (let ...) binding and blocks.

1 edited


  • wiki/chicken-for-ruby-programmers

    r8716 r8723  
    2323procedural fashion (like you would in Pascal, for example) or in a
    2424functional style (a bit like Haskell or ML) and you can even
    25 experiment with message-passing like in Erlang or logic programming
    26 like you would with Prolog.
     25experiment with message-passing like in Erlang, logic programming
     26like you would with Prolog, or stack languages like Forth and Factor.
    2828=== Origins
    216216artifact of an imperative programming style and in clean code you
    217217want to avoid using it.
     219Scheme also allows the ''binding'' of local variables. Bound variables
     220behave like the defined variables above, however, they are only valid
     221within a local scope. The top-level variables we've seen are the equivalent
     222of a global in Ruby.
     224The most common binding constructs are {{let}} and {{let*}}.
     225{{let}} allows for any number of bindings, none of which are related.
     227<enscript highlight=scheme>
     228  (let ((a 5)
     229        (b 10))
     230    (+ a b))
     233{{let*}} is like let, except that the bindings are evaluated in order,
     234so subsequent bindings can reference earlier bindings.
     236<enscript highlight=scheme>
     237  (let* ((a 5)
     238         (b (* 2 a)))
     239    (+ a b))
     242There are other binding forms, such as {{letrec}} and the so-called
     243''named let''. More information about these forms can be found in
     244the [[|Scheme specification]].
    219246=== Procedures
    332359allocate any more.  In the second example it will stay constant and
    333360simply loop forever.
     362=== Blocks
     364Ruby programmers will be familiar with ''blocks.'' Classic example in
     365Ruby is the {{map}} method used to iterate over a collection, executing
     366a ''block'' of code for each item in the collection.
     369  >> [1, 2, 3, 4, 5].map { |x| x * x }
     370  => [1, 4, 9, 16, 25]
     372Scheme also contains blocks, though we call them anonymous functions
     373usually. Functions are created using the {{(lambda args body...)}} body
     374form. This syntax is a little more verbose than Ruby's, but the trade off
     375is that more than one function can be passed as an argument, whereas Ruby
     376generally only allows one.
     379  #;1> (map (lambda (x) (* x x)) '(1 2 3 4 5))
     380  (1 4 9 16 25)
     382A more complicated example involves opening and closing files. Say we
     383wanted to create a utility like {{wc -l}} that counts the number of
     384lines in a file. In Ruby, it might look something like:
     386<enscript highlight=ruby>
     387  count = 0
     388"myfile", 'r') { |fh|
     389      count += 1 while fh.gets
     390  }
     391  puts count
     394Similarly, Scheme uses anonymous functions to create the same behavior:
     396<enscript highlight=scheme>
     397  (with-input-from-file "filename"
     398    (lambda () (port-fold (lambda (line lines-so-far) (+ 1 lines-so-farc)) 0 read-line)))
     401This Scheme code also showcases some typical functional style, using
     402a ''fold'' operation instead of incrementing the value of a variable.
    335405== Data types
Note: See TracChangeset for help on using the changeset viewer.