# -*- mode: python; python-indent-offset: 2 -*-

## As an exercise, I decided to implement a Lisp-style linked list
## using a class List.  I'm a bit surprised by the result: it seems
## polymorphism forces me to write a recursive procedure in two
## halves: one half in the List class itself and the other half in the
## Empty class.  For example, I created a class called Empty as a
## singleton.  So when I wrote the __len__ procedure for a List, I
## cannot treat the base case in the List.__len__ procedure because
## the base case really belongs to another class---since an empty list
## is not really a List, but rather of type Empty.

## This is because the Lisp list is really a union of two types, so
## using classes produces this situation.  What do you think?  Can you
## suggest anything beyond the obvious of ``write Python when using
## Python''?  Perhaps you do know how to implement a union in a more
## elegant way?  I'd love to see if you can workaround this in a
## prettier way.  Thanks very much.

## Usage:
## 
## >>> ls = List(0, List(1, List(2, List.Empty())))
## >>> len(ls)
## 3
## >>> ls[1]
## 1
## >>> ls[2]
## 2
## >>> ls[3]
## Traceback (most recent call last):
## [...]
## Exception: no such element

class List:
  head = None
  tail = None

  def __init__(self, d, ls):
    self.head = d
    self.tail = ls

  def getitem(self, n):
    if n == 0:
      return self.first()
    return self.rest().getitem(n - 1)

  def __getitem__(self, n):
    return self.getitem(n)
  
  def empty(self):
    return self is List.Empty()
  
  def first(self):
    return self.head

  def rest(self):
    return self.tail

  def __repr__(self):
    return f"List({self.head}, {self.rest()})"

  def __len__(self):
    return 1 + len(self.rest())

  class Empty:
    instance = None

    def __new__(cls):
      if cls.instance is None:
        cls.instance = super().__new__(cls)
      return cls.instance

    def __repr__(self):
      return "List.Empty()"

    def __len__(self):
      return 0

    def getitem(self, n):
      raise Exception("no such element")
-- 
https://mail.python.org/mailman3//lists/python-list.python.org

Reply via email to