Write Scheme data structures so they can be eval-d back in, or alternative

Posted by Jesse Millikan on Stack Overflow See other posts from Stack Overflow or by Jesse Millikan
Published on 2010-02-20T04:48:20Z Indexed on 2010/06/08 2:12 UTC
Read the original article Hit count: 297

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.

© Stack Overflow or respective owner

Related posts about Scheme

Related posts about eval