4 ms·
> You can write a TCL list to a file? You mean a TCL string to a file? Lisp can just write strings to files too. To expand upon this, Lisp can write its lists
by emidln 9y ago
> You can write a TCL list to a file? You mean a TCL string to a file? Lisp can just write strings to files too.
To expand upon this, Lisp can write its lists to files (and most other things out of the box) which it can then read back from files and then eval. This is what Lisps mean by a printable/readable object.
In Clojure:
(spit "foo.clj" '(defn foo [] "CONGRATS! YOU CALLED FOO!!!"))
(load-file "foo.clj")
(foo) ; => "CONGRATS! YOU CALLED FOO!!!"
In Common Lisp:
(with-open-file (f "foo.lisp" :direction :output)
(pprint
'(defun foo ()
"CONGRATS! YOU CALLED FOO!!!!") f))
(with-open-file (f "foo.lisp" :direction :input)
(eval (read f)))
(foo) ; => "CONGRATS! YOU CALLED FOO!!!!"
- TeMPOraL 9y agoSerializing code like this is a bad example, because you need to introduce eval into the loop, which is another step entirely from printing and reading objects. Consider this example, from REPL interaction: CL-USER> (with-open-file (f "/tmp/makapaka" :direction :output :if-exists :supersede) (pprint '(a potentially (complex data structure) mixing lists #(and vectors) 2/3 #C(2 5) and stuffs) f)) ; No value CL-USER> (with-open-file (f "/tmp/makapaka") (read f)) (A POTENTIALLY (COMPLEX DATA STRUCTURE) MIXING LISTS #(AND VECTORS) 2/3 #C(2 5) AND STUFFS) In this example, I printed and read back a list containing symbols, lists, vectors, rationals and complex numbers. Basically: the reader converts strings to Lisp objects[0]. The printer converts Lisp objects into strings. When we say that an object has a "readable representation", it means that if you feed the result of the printer into reader, you get the same object back. The evaluator (which I didn't use here, but OP did) evaluates Lisp objects (not strings!), and can e.g. introduce a new function to the environment when evaluating a defun form, i.e. a list of form (defun name (args...) "docstring" code). It is not needed (in fact, it is discouraged[1]) when all you care about is writing and reading back Lisp objects. -- [0] - Note it's the same reader that actually reads your code when you compile/load file or use a REPL. [1] - The usual eval-on-untrusted-data code execution vulnerability. Note that since the reader is mostly used to process code, by default it allows you to use the #. read-time-value reader macro. If you READ a string like: "(1 2 #.(* 2 2))", you'll get a Lisp list (1 2 4), since #. basically means "pipe the next s-expression to eval, and return that". When you use reader/printer for serialization/deserialization, you usually want to disable #. for those invocation of read function, by setting *READ-EVAL* variable to NIL.
- deleted 9y ago[deleted]