Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #197552
| From | ram@zedat.fu-berlin.de (Stefan Ram) |
|---|---|
| Newsgroups | comp.lang.python |
| Subject | Re: an adventure: a Lisp-style linked list |
| Date | 2025-09-04 00:47 +0000 |
| Organization | Stefan Ram |
| Message-ID | <lists-20250904013639@ram.dialup.fu-berlin.de> (permalink) |
| References | <87o6rrt9kq.fsf@somewhere.edu> |
Ethan Carter <ec1828@somewhere.edu> wrote or quoted:
>## 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:
I think this lies in the nature of lists, as the rest can
have at least two types: it might be another list or empty.
>## Can you
>## suggest anything beyond the obvious of ``write Python when using
>## Python''?
I'd use a two-layered approach:
- CONS (dotted pairs), CAR, CDR, NIL and NULL as the lower layer
- lists on top of that.
from __future__ import annotations
from abc import ABC, abstractmethod
from dataclasses import dataclass
from typing import Any
# Layer 0: CONS, CAR, CDR, and NIL
class Object( ABC ): # common interface for CONS and NIL
@abstractmethod
def null( self ) -> bool: ...
@dataclass( frozen=True )
class Cons( Object ): # dotted pairs
car: Any
cdr: Any
def null( self ) -> bool:
return False
@dataclass( frozen=True )
class Nil( Object ):
def null( self )-> bool:
return True
nil: Nil = Nil() # singleton
def null( x: Object ) -> bool:
return x.null()
# Layer 1: lists
def make_list( *args: Any )-> Object:
result: Object = nil
for arg in reversed( args ):
result = Cons( arg, result )
return result
def print_list( lst: Object )-> None:
print( end="(" )
current = lst
first = True
while not null( current ):
assert isinstance( current, Cons )
if not first: print( end=" " )
print( end=str( current.car ))
current = current.cdr
first = False
print( end=")" )
# A perfect LISP imitation would also have special LISP-like int
# objects, but for brevity's sake, here, I just use Python's ints.
l = make_list( 1, 2, 3 )
print_list( l )
prints:
(1 2 3)
Back to comp.lang.python | Previous | Next — Previous in thread | Next in thread | Find similar
an adventure: a Lisp-style linked list Ethan Carter <ec1828@somewhere.edu> - 2025-09-03 20:12 -0300
Re: an adventure: a Lisp-style linked list ram@zedat.fu-berlin.de (Stefan Ram) - 2025-09-04 00:47 +0000
Re: an adventure: a Lisp-style linked list pa@see.signature.invalid (Pierre Asselin) - 2025-09-04 18:41 +0000
Re: an adventure: a Lisp-style linked list Ethan Carter <ec1828@somewhere.edu> - 2025-09-05 13:06 -0300
csiph-web