Write Scheme data structures so they can be eval-d back in, or alternative
- by Jesse Millikan
I'm writing an application (A juggling pattern animator) in PLT Scheme that accepts Scheme expressions as values for some fields. I'm attempting to write a small text editor that will let me "explode" expressions into expressions that can still be eval'd but contain the data as literals for manual tweaking.
For example,
(4hss->sexp "747")
is a function call that generates a legitimate pattern. If I eval and print that, it becomes
(((7 3) - - -) (- - (4 2) -) (- (7 2) - -) (- - - (7 1)) ((4 0) - - -) (- - (7 0) -) (- (7 2) - -) (- - - (4 3)) ((7 3) - - -) (- - (7 0) -) (- (4 1) - -) (- - - (7 1)))
which can be "read" as a string, but will not "eval" the same as the function. For this statement, of course, what I need would be as simple as
(quote (((7 3...
but other examples are non-trivial. This one, for example, contains structs which print as vectors:
pair-of-jugglers
; -->
(#(struct:hand #(struct:position -0.35 2.0 1.0) #(struct:position -0.6 2.05 1.1) 1.832595714594046) #(struct:hand #(struct:position 0.35 2.0 1.0) #(struct:position 0.6 2.0500000000000003 1.1) 1.308996938995747) #(struct:hand #(struct:position 0.35 -2.0 1.0) #(struct:position 0.6 -2.05 1.1) -1.3089969389957472) #(struct:hand #(struct:position -0.35 -2.0 1.0) #(struct:position -0.6 -2.05 1.1) -1.8325957145940461))
I've thought of at least three possible solutions, none of which I like very much.
Solution A is to write a recursive eval-able output function myself for a reasonably large subset of the values that I might be using. There (probably...) won't be any circular references by the nature of the data structures used, so that wouldn't be such a long job. The output would end up looking like
`(((3 0) (... ; ex 1
`(,(make-hand (make-position ... ; ex 2
Or even worse if I could't figure out how to do it properly with quasiquoting.
Solution B would be to write out everything as
(read (open-input-string "(big-long-s-expression)"))
which, technically, solves the problem I'm bringing up but is... ugly.
Solution C might be a different approach of giving up eval and using only read for parsing input, or an uglier approach where the s-expression is used as directly data if eval fails, but those both seem unpleasant compared to using scheme values directly.
Undiscovered Solution D would be a PLT Scheme option, function or library I haven't located that would match Solution A.
Help me out before I start having bad recursion dreams again.