Y-combinator in Ruby with REAL λ!

Posted by flori Mon, 08 Oct 2007 17:02:00 GMT

#!/usr/bin/ruby -KU
# -*- coding: utf-8 -*- 

# Do ":imap <C-l> <C-k>l*" in vim

alias λ lambda

Y = λ{ |c|
  λ{ |f| f[f] }[
    λ{ |f| c[
      λ{ |x| f[f][x] } ] } ] }

Y[ λ{ |f| λ{ |n| n < 1 ? 1 : n * f[n-1] } } ][10] # => 3628800

And they say reading ruby-core doesn't pay off! :-)

Tags , ,  | no comments

Ruby's Operator Precedence: More subtle than you might think

Posted by flori Wed, 08 Aug 2007 10:25:00 GMT

I just read Rick DeNatale's article about Ruby's Operator Precedence, in which he mentioned, that Ruby's and and or operators have a weaker precedence than && and || (and also weaker than =). This is similar to Perl's and and or operators, and the reason why I use the following rules of thumb for the use of the different operators in both languages:

  1. Use && and || for expressions (especially more complex ones) like a = a && b || c.
  2. Use and and or instead of if enabled then do_it end or do_it if enabled as in enabled and do_it.
  3. Or use and and or for very simple expressions as in if a and b then ... end.

Rule 3 exists only, because I think it is slightly more readable to use and or or than && and ||. This advantage goes pretty much away if you have to start using parentheses to render more complex expressions unambiguous. It could as well be dropped.

But in Ruby other than in Perl there is another reason for rule 3:

Ruby's and and or operators have the SAME precedence!

Yeah, you read this right: So, for example, true || true && false # => true, but true or true and false # => false.

This is a rather surprising (as in unfortunate) peculiarity of Ruby, and I do not think, that it is a good idea. I guess most people are unaware of this issue, and their code does only work by accident - until it stops doing so for unknown reasons. Matz' rationalisation of this behaviour (somewhere on ruby-talk) was "'and' and 'or' don't have different precedence in English either." It didn't convince me then and doesn't convince me now: We don't program in English, because it is too unprecise. Why burden Ruby with the same problem as well?

Tags ,  | no comments

Feeling at home in Ruby (if you're coming from C)

Posted by flori Fri, 03 Aug 2007 22:13:00 GMT

class Fixnum
  alias __oldref :[]

  def [](obj)
    if Fixnum === obj
      __oldref(obj)
    else
      obj[self]
    end
  end
end

if $0 == __FILE__
  2[0] # => 0
  2[1] # => 1
  a = [2,3,5,7,11]
  a[2] # => 5
  2[a] # => 5
end

Tags , , ,  | no comments

Older posts: 1 2 3 ... 6