Skip to content

Instantly share code, notes, and snippets.

@mz0
Forked from aburjg/homoiconic-python-post.md
Created May 13, 2024 12:47
Show Gist options
  • Save mz0/a09f35577ec7485215598c04dc9f25d5 to your computer and use it in GitHub Desktop.
Save mz0/a09f35577ec7485215598c04dc9f25d5 to your computer and use it in GitHub Desktop.
Homoiconic Python Post

Substack https://aljamal.substack.com/p/homoiconic-python

First

atom=lambda x:not isinstance(x,list)
eq=lambda x,y:x == y

car=lambda x:x[0]
cdr=lambda x:x[1:]

cons=lambda x,y:[x,y] if atom(y) else [x]+y
append=lambda x,y:x+y

def eval(x):
  if atom(x):              return x
  elif eq(car(x),'quote'): return car(cdr(x))  
  elif eq(car(x),'atom'):  return atom(eval(car(cdr(x))))       
  elif eq(car(x),'eq'):    return eq(eval(car(cdr(x))),
                                     eval(car(cdr(cdr(x)))))     
  elif eq(car(x),'car'):   return car(eval(car(cdr(x))))                            
  elif eq(car(x),'cdr'):   return cdr(eval(car(cdr(x))))                            
  elif eq(car(x),'cons'):  return cons(eval(car(cdr(x))),
                                       eval(car(cdr(cdr(x))))) 
  elif eq(car(x),'cond'):
                       for i in cdr(x):
                         if eval(car(i)):
                           return eval(car(cdr(i)))
  return []

def e(x):
  try:print(eval(x))
  except Exception as e:print(e)

e([atom])
e(42)
e(['quote',[10,20]])
e(['atom',1])
e(['atom',['quote',1]])
e(['atom',['quote',[1,2,3]]])
e(['eq',1,1])
e(['eq',1,2])
e(['car',['quote',[1000,20]]])
e(['cdr',['quote',[10,20,1.1]]])
e(['car',['car',['cdr',['cdr',
                ['cdr',['quote',[1,2,10,[50,100]]]]]]]])
e(['cons',1,['quote',[10,20]]])
e(['cons',['quote',[1,2]],['quote',[10,20]]])
e(['cond',
  [['eq', 1, 1], 'true'],
  [['atom', ['quote', 2]], 'false'],
  ['t', 'default']
])
e(['cond',
  [['atom', ['quote', 2]], 'cake'],
  ['t', 'default']
])
e(['cond',
  [['atom', ['quote',[1,2]]], 'false'],
  ['t', 'default']
])

Second

atom=lambda x:not isinstance(x,list)
eq=lambda x,y:x == y

car=lambda x:x[0]
cdr=lambda x:x[1:]

cons=lambda x,y:[x,y] if atom(y) else [x]+y
append=lambda x,y:x+y

#assoc=lambda x,y:(car(y) if eq(car(car(y)),x) else assoc(x,cdr(y))) if y else []
assoc=lambda x,y:car([cdr(i) for i in y if eq(car(i),x)] or [x])

#pairlis=lambda x,y:cons(cons(car(x),car(y)),pairlis(cdr(x),cdr(y))) if x and y else []
pairlis=lambda x,y:[cons(x[i],y[i]) for i in range(len(x))]

def eval(x,y):
  if atom(x):return assoc(x,y)
  elif atom(car(x)):
   if eq(car(x),'quote'):return car(cdr(x))
   elif eq(car(x),'atom'):return atom(eval(car(cdr(x)),y))
   elif eq(car(x),'eq'):return eq(eval(car(cdr(x)),y),eval(car(cdr(cdr(x))),y))
   elif eq(car(x),'car'):return car(eval(car(cdr(x)),y))
   elif eq(car(x),'cdr'):return cdr(eval(car(cdr(x)),y))
   elif eq(car(x),'cons'):return cons(eval(car(cdr(x)),y),eval(car(cdr(cdr(x))),y))
   elif eq(car(x),'cond'):
    for i in cdr(x):
     if eval(car(i),y):return eval(car(cdr(i)),y)
   else:return eval(cons(assoc(car(x)),[eval(i,y) for i in cdr(x)]),y)
  elif eq(car(car(x)),'lambda'):return eval(car(cdr(cdr(car(x)))),
                                append(pairlis(car(cdr(car(x))),[eval(i,y) for i in cdr(x)]),y))
                                
def e(x):
  try:print(eval(x,[]))
  except Exception as e:print(e)

e([atom]) # error
e(42)
e(['quote',[10,20]])
e(['atom',1])
e(['atom',['quote',1]])
e(['atom',['quote',[1,2,3]]])
e(['eq',1,1])
e(['eq',1,2])
e(['car',['quote',[1000,20]]])
e(['cdr',['quote',[10,20,1.1]]])
e(['car',['car',['cdr',['cdr',['cdr',['quote',[1,2,10,[50,100]]]]]]]])
e(['cons',1,['quote',[10,20]]])
e(['cons',['quote',[1,2]],['quote',[10,20]]])
e(['cond',
  [['eq', 1, 1], 'true'],
  [['atom', ['quote', 2]], 'false'],
  ['t', 'default']
])
e(['cond',
  [['atom', ['quote', 2]], 'cake'],
  ['t', 'default']
])
e(['cond',
  [['atom', ['quote',[1,2]]], 'false'],
  ['t', 'default']
])

e([['lambda', ['x'], ['car', 'x']], ['quote', [1, 2, 3]]])
e([['lambda', ['x'], ['cdr', 'x']], ['quote', [1, 2, 3]]])
e([['lambda', ['x','y'], ['cons', 'x','y']],5,['quote', [1, 2, 3]]])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment