views:

174

answers:

1

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.

+3  A: 

I'm not sure what you're trying to do. Specifically, trying to produce a file with eval-able code seems like a strange choice. In any case, creating a serialization of random values is a problem when you're dealing with structs -- since there could be different structs with the same name. Some points that might be relevant for you:

  • There is an undocumented library scheme/fasl that can read and write values in binary format (useful for large data).

  • There is also mzlib/pconvert -- a library that DrScheme uses to print values as expressions that can be evaluated (but this won't work on all kinds of data).

  • If you want to use structs that are very easy to write in a readable form, then you can use "prefab" structs.

(For more details it's probably best to ask on the mailing list.)

Eli Barzilay
pconvert works beautifully for answer D! As for *why*... It might be best not to think about it. I tried to write it out as literally as I could without writing a novel :)
Jesse Millikan
Well, it's hard to tell without more details, but I think that the prefab option can work pretty well. (I tried your thing -- the graphics is impressive, but I couldn't figure out the interface. I'm not a juggler though...)
Eli Barzilay
Thanks for looking! The interface really isn't very good yet. I'm still thinking about it.
Jesse Millikan
If you're still curious about what it can do, I finally left some instructions and examples on the Wiki page on github.
Jesse Millikan