Format PTC-Lisp values for human/LLM display.
Handles special Lisp types that should not expose internal implementation:
- Closures:
{:closure, params, body, env, history, metadata}→#fn[x y] - Builtins:
{:normal, fun}etc. →#<builtin>
Works recursively, so closures nested in maps/lists are also formatted.
Examples
iex> PtcRunner.Lisp.Format.to_string({:closure, [{:var, :x}], nil, %{}, [], %{}})
"#fn[x]"
iex> PtcRunner.Lisp.Format.to_string({:normal, &Enum.map/2})
"#<builtin>"
iex> PtcRunner.Lisp.Format.to_string(%{a: 1})
"%{a: 1}"
Summary
Functions
Format a Lisp value as Clojure syntax for LLM feedback.
Format a Lisp value as a string for display.
Functions
Format a Lisp value as Clojure syntax for LLM feedback.
Produces Clojure-style output that matches the syntax the LLM writes:
- Maps:
{:key value}instead of%{key: value} - Lists:
[1 2 3](space-separated) instead of[1, 2, 3] - Keywords:
:foo(same as Clojure) - Strings/numbers/booleans: standard literals
Returns {formatted_string, truncated?} tuple.
Options
:limit- Maximum items to show in collections (default: :infinity):printable_limit- Maximum string bytes to show (default: :infinity)
Examples
iex> PtcRunner.Lisp.Format.to_clojure(42)
{"42", false}
iex> PtcRunner.Lisp.Format.to_clojure([1, 2, 3])
{"[1 2 3]", false}
iex> PtcRunner.Lisp.Format.to_clojure(%{id: 101, count: 45})
{"{:count 45 :id 101}", false}
iex> PtcRunner.Lisp.Format.to_clojure(%{"name" => "Alice", "age" => 30})
{~s({"age" 30 "name" "Alice"}), false}
iex> PtcRunner.Lisp.Format.to_clojure({:closure, [{:var, :x}], nil, %{}, [], %{}})
{"#fn[x]", false}
iex> PtcRunner.Lisp.Format.to_clojure({:var, :x})
{"#'x", false}
iex> PtcRunner.Lisp.Format.to_clojure(nil)
{"nil", false}
iex> PtcRunner.Lisp.Format.to_clojure(:keyword)
{":keyword", false}
iex> PtcRunner.Lisp.Format.to_clojure([%{a: 1}, %{b: 2}])
{"[{:a 1} {:b 2}]", false}
iex> PtcRunner.Lisp.Format.to_clojure([1, 2, 3, 4, 5], limit: 2)
{"[1 2 ...] (5 items, showing first 2)", true}
iex> PtcRunner.Lisp.Format.to_clojure("very long string here", printable_limit: 10)
{~s("very long ..."), true}
iex> {str, _} = PtcRunner.Lisp.Format.to_clojure(%{title: "Hello", _body: "secret"})
iex> str
~s[{:title "Hello"}]
iex> {str, _} = PtcRunner.Lisp.Format.to_clojure(%{title: "Hello", _body: "secret"}, filter_hidden: false)
iex> str
~s[{:_body "secret" :title "Hello"}]
Format a Lisp value as a string for display.
Options
All options are passed through to Kernel.inspect/2 for regular values:
:pretty- Use pretty-printing:limit- Maximum items to show in collections:width- Target width for pretty printing:printable_limit- Maximum string bytes to show
Examples
iex> PtcRunner.Lisp.Format.to_string(42)
"42"
iex> PtcRunner.Lisp.Format.to_string({:closure, [{:var, :x}, {:var, :y}], nil, %{}, [], %{}})
"#fn[x y]"
iex> PtcRunner.Lisp.Format.to_string({:var, :my_var})
"#'my_var"
iex> PtcRunner.Lisp.Format.to_string([1, 2, 3], limit: 2)
"[1, 2, ...]"
iex> PtcRunner.Lisp.Format.to_string(%{f: {:closure, [{:var, :x}], nil, %{}, [], %{}}})
"%{f: #fn[x]}"