An agent in 100 lines of Lisp
51–60 of 84 posts
Re: An agent in 100 lines of Lisp
#52Earlier quoted context omitted.
> the supposed benefit of Lisp is completely irrelevant here Yeah, it's a small example (it's in the title, "100 lines") so obviously doesn't highlight the best benefits once you reach larger codebase size. Still think ~8 lines for the core loop is probably more elegant, readable and concise than you can achieve in other algol/C-like languages, but happy to be shown that I'm wrong :)
Most of the code in agents is to handle unhappy paths and human friendly interfaces. I’m sure you could trim most languages core loop too if you discarded all the stuff that actually make agents peasant to use.
Re: An agent in 100 lines of Lisp
#53Earlier quoted context omitted.
Most of the code in agents is to handle unhappy paths and human friendly interfaces. I’m sure you could trim most languages core loop too if you discarded all the stuff that actually make agents peasant to use.
Please do show the equivalent of those ~8 lines in the other languages you think of so we can explicitly compare :) I gave it a try in the other languages I know, the Clojure one I have still ends up the smallest and fastest to comprehend.
And once you start including the boilerplate code you end up with something that’s a lot more equivalent to the other languages you tried.
I love functional languages, and LISP specifically too. But the point of that article wasn’t even to say “LISP is better at code golfing than other languages”. so this doubling down on the SLOC that you’re doing isn’t even a relevant tangent.
Re: An agent in 100 lines of Lisp
#54Prolog would have been a better choice
Re: An agent in 100 lines of Lisp
#55I like Lisp, I’ve used Common Lisp with a passion, but this doesn’t seem like a valid argument for Lisp. Homoiconicity, as I understand, is that the code is structured data that is easy to programmatically modify, hence allowing Lisp macros. While some might disagree, I see Rust macros as the closest thing that demonstrates homoiconicity in mainstream Algol-based languages, as Rust macros modify the loosely structure…
A Lisp program that writes a Lisp program really just needs to produce a list of (nested lists) of tokens. A JavaScript program that writes a javascript program needs to generate a string that is syntactically valid JavaScript code. That is a much bigger task than just constructing a (nested) list. Because Lisp syntax is so much simpler than that of JavaScript etc. it is much easier to avoid errors when generating co…
But maybe I’m interpreting you too narrowly?
Re: An agent in 100 lines of Lisp
#56Earlier quoted context omitted.
A Lisp program that writes a Lisp program really just needs to produce a list of (nested lists) of tokens. A JavaScript program that writes a javascript program needs to generate a string that is syntactically valid JavaScript code. That is a much bigger task than just constructing a (nested) list. Because Lisp syntax is so much simpler than that of JavaScript etc. it is much easier to avoid errors when generating co…
> A Lisp program that writes a Lisp program really just needs to produce a list of (nested lists) of tokens. A JavaScript program that writes a javascript program needs to generate a string that is syntactically valid JavaScript code. That is a much bigger task than just constructing a (nested) list. > Because Lisp syntax is so much simpler than that of JavaScript etc. it is much easier to avoid errors when generatin…
Yet I still had the idea that LLMs should be better at lisp than other languages.
A fascinating contradiction, thanks for pointing this out.
Re: An agent in 100 lines of Lisp
#57 import json,sys,uuid;from subprocess import getoutput as sh;from urllib.request import Request as R,urlopen
b={"model":"gpt-5.6","prompt_cache_key":uuid.uuid4().hex,"input":[],"tools":[{"type":"custom","name":"shell"}]}
while prompt:=input("> "):
b["input"]+=[{"role":"user","content":prompt}]
while True:
o=(r:=json.load(urlopen(R(sys.argv[1],json.dumps(b).encode(),{"Content-Type":"application/json"}))))["output"]
b["input"]+=o;calls=[i for i in o if i["type"]=="custom_tool_call"];used=r["usage"]["total_tokens"]/10500
if not calls: print(o[-1]["content"][0]["text"],f'\n[{used:06.3f}%]'); break
b["input"]+=[{"type":"custom_tool_call_output","call_id":i["call_id"],"output":sh(i["input"])} for i in calls]Re: An agent in 100 lines of Lisp
#58Re: An agent in 100 lines of Lisp
#599 lines of python: import json,sys,uuid;from subprocess import getoutput as sh;from urllib.request import Request as R,urlopen b={"model":"gpt-5.6","prompt_cache_key":uuid.uuid4().hex,"input":[],"tools":[{"type":"custom","name":"shell"}]} while prompt:=input("> "): b["input"]+=[{"role":"user","content":prompt}] while True: o=(r:=json.load(urlopen(R(sys.argv[1],json.dumps(b).encode(),{"Content-Type":"application/json"…
- stdlib only, 0 external dependencies
- works with openai compatible api (including local models)
- shows context usage in % when turn goes back to user
- cache friendly (keeps stable prefix and provides uuid v4 as session cache key)
- uses 'shell' as open ended tool
'shell' as tool name is sufficient context for gpt 5.6 sol