Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are there ruby equivalents to car, cdr, and cons?

Tags:

Are there ruby equivalents to the lisp car, cdr, and cons functions? For those unfamiliar with lisp, here's what I want from ruby:

[1,2,3].car   => 1 [1,2,3].cdr   => [2,3] [2,3].cons(1) => [1,2,3] 

(in lisp):

(car '(1 2 3))  => 1 (cdr '(1 2 3))  => (2 3) (cons 1 '(2 3)) => (1 2 3) 
like image 809
Bee Avatar asked Oct 05 '09 22:10

Bee


People also ask

Why are car and CDR so named?

The origins of the names for car and cdr are a little bit historical and comes from the IBM 704. car is an acronym from the phrase Contents of the Address part of the Register; and cdr is an acronym from the phrase Contents of the Decrement part of the Register.

What is a CDR in a car?

CDR is the Acronym for “Crash Data Retrieval” This EDR data is also referred to as "crash data". CDR technicians and experts connect their EDR tool to an automobile allowing them to communicate with the vehicle and retrieve the EDR data file.

What does CADR mean in Lisp?

AutoLISP Functions > C Functions > cadr. Returns the second element of a list. (cadr list) In AutoLISP, cadr is frequently used to obtain the Y coordinate of a 2D or 3D point (the second element of a list of two or three reals).


2 Answers

Ruby arrays are not implemented as singly-linked lists, so it is not as useful to have car and cdr and stuff.

If you really wanted, you could do

[1,2,3][0]      => 1 [1,2,3].first   => 1 [1,2,3][1..-1]  => [2,3] [1] + [2,3]     => [1,2,3] 
like image 119
newacct Avatar answered Oct 24 '22 17:10

newacct


This is how you'd implement lisp-like single-linked lists in ruby:

class Object   def list?     false   end end  class LispNilClass   include Enumerable   def each   end    def inspect     "lnil"   end    def cons(car)     Cell.new(car, self)   end    def list?     true   end end  LispNil = LispNilClass.new  class LispNilClass   private :initialize end  class Cell   include Enumerable    attr_accessor :car, :cdr    def initialize(car, cdr)     @car = car     @cdr = cdr   end    def self.list(*elements)     if elements.empty?       LispNil     else       first, *rest = elements       Cell.new(first, list(*rest))     end   end    def cons(new_car)     Cell.new(new_car, self)   end    def list?     cdr.list?   end    # Do not use this (or any Enumerable methods) on Cells that aren't lists   def each     yield car     cdr.each {|e| yield e}   end    def inspect     if list?       "(#{ to_a.join(", ") })"     else       "(#{car} . #{cdr})"     end   end end  list = Cell.list(1, 2, 3) #=> (1, 2, 3) list.list? #=> true list.car #=> 1 list.cdr #=> (2, 3) list.cdr.cdr.cdr #=> lnil list.cons(4) #=> (4, 1, 2, 3)  notlist = Cell.new(1,2) #=> (1 . 2) notlist.list? #=> false notlist.car #=> 1 notlist.cdr #=> 2 notlist.cons(3) #=> (3 . (1 . 2)) 
like image 34
sepp2k Avatar answered Oct 24 '22 18:10

sepp2k