Thursday, March 3, 2011

Convert string to code in Scheme

How do I convert a string into the corresponding code in PLT Scheme (which does not contain the string->input-port method)? For example, I want to convert this string:

"(1 (0) 1 (0) 0)"

into this list:

'(1 (0) 1 (0) 0)

Is it possible to do this without opening a file?

From stackoverflow
  • From this similar question on comp.lang.scheme you can save the string to a file then read from it.

    That might go something like this example code:

    (let ((my-port (open-output-file "Foo")))
      (display "(1 (0) 1 (0) 0)" my-port)
      (close-output-port my-port))
    
    (let* ((my-port (open-input-file "Foo"))
           (answer (read my-port)))
      (close-input-port my-port)
      answer)
    
  • Scheme has procedure read for reading s-expressions from input port and you can convert a string to input stream with string->input-port. So, you can read a Scheme object from a string with

    (read (string->input-port "(1 (0) 1 (0) 0)"))
    

    I don't have Scheme installed, so I only read it from reference and didn't actually test it.

  • From PLT Scheme manual:

    (open-input-string string [name-v]) creates an input port that reads bytes from the UTF-8 encoding (see section 1.2.3) of string. The optional name-v argument is used as the name for the returned port; the default is 'string.

    Svante : This looks like abstraction inversion in Scheme. Common Lisp has a `read-from-string` function.
    Anton Nazarov : Yes, it seems - read reads only from input ports, and opening input port for reading from file is in R5RS, but making input port for reading from string is not. So it is the source of question. Mit scheme has string->input-port, PLT - open-input-string.
  • Many schemes have with-input-from-string str thunk that executes thunk in a context where str is the standard input port. For example in gambit scheme:

    (with-input-from-string "(foo bar)" (lambda () (read)))

    evaluates to:

    (foo bar)

    The lambda is necessary because a thunk should be a procedure taking no arguments.

    JBF : And since `read` is a procedure taking no arguments you could shorthen the above example to `(with-input-from-string "(foo bar)" read)` .

0 comments:

Post a Comment