tags:

views:

582

answers:

3

I'm trying to do the exercises in "The Little Schemer" using Ruby. I'd like to know the equivalent method of atom? in Scheme for Ruby.

atom? is a method that returns true if the argument passed in is an atom and returns false otherwise. From what I understand, an atom can be a string of characters or a number. It can't be a list.

A: 

By convention, sequence-like objects respond to the 'to_a' (to array) method. A possible atom implementation could be:

   class Object
     def atom?
       not respond_to? :to_a
     end
   end

   42.atom? #=> true
   {foo: 'bar'}.atom? #=> false
Kay Sarraute
in ruby 1.8 this won't work as all objects respond to to_a. this will only work in ruby 1.9 i think
newacct
Sorry, no: irb(main):002:0> {'foo' => 'bar'}.to_a => [["foo", "bar"]]
+1  A: 

I guess the closest equivalent to atoms that Ruby has are the literals - Fixnum, booleans, symbols, and nil. This effectively comes down to an implementation detail, but those objects are represented directly by a value on the stack rather than as a C pointer. So, #atom? might look like this:

class Object
  def atom?
    case self
    when Fixnum, TrueClass, FalseClass, NilClass, Symbol
      true
    else
      false
    end
  end
end
The equivalent of Nil in Scheme is an empty list, which is not an atom. And methods are also atoms.(I don't mean to be obnoxious--I actually don't think this question *has* a good answer.)
Sam DeFabbia-Kane
I guess it comes down to "what's the use case?" - and we don't really have enough info to answer that.
+3  A: 

Atoms in Scheme, as defined by The Little Schemer:

(define atom?
  (lambda (x)
    (and (not (pair? x)) (not (null? x)))))

So atoms in Scheme are everything except lists (things created with the 'cons' operator) and null. In Scheme, that ends up being symbols, numbers, methods, and probably a few more things I'm forgetting. Ruby's a lot more complicated.

So for the purposes of doing is the exercises in The Little Schemer, an atom in Ruby is a FixNum, a Symbol, a TrueValue, or a FalseValue. Or a method. And then for lists, you're going to need to define cons, car, and cdr methods for Ruby's array type. I might actually say that anything that's not an Array and is not nil is an atom. This discussion gets subjective at some point.

And then you're probably going to need to do a good bit more hacking to get everything to behave the same. Quite honestly, while I love The Little Schemer, it really does have some things that are fairly Lisp-specific, and while I can see adapting it to another functional language like Haskell without too much trouble, I think it's going to be more trouble than it's worth to get it to work in a language like Ruby.

Sam DeFabbia-Kane