| Author |
expr->string as easy as possible
|
|
| Marco Bakera 2006-03-22, 7:05 pm |
| Hey there
is there any _easy_ way to turn an expression into a string? The only
way that I found was using string ports.
(import srfi-6)
(define (expr->string expr)
(let ((port (open-output-string)))
(write expr port)
(get-output-string port)))
However it there any SRFI or even easier function in R5RS I didn't
recognize to handle this?
Thanks for any help.
Greetings,
Marco.
--
,----[ /X\arco -- www.bakera.de ]----
| (Y F) = (F (Y F))
`----[ www.bulb-publications.de ]----
| |
| Ludovic Courtès 2006-03-22, 7:05 pm |
| Hi,
Marco Bakera <marco.bakera@gmail.com> writes:
> However it there any SRFI or even easier function in R5RS I didn't
> recognize to handle this?
GNU Guile (and probably others) has `with-output-to-string' to do that
sort of thing:
(with-output-to-string (lambda () (write MY-EXPR)))
This is just syntactic sugar that in essence does the same as what you
showed but it looks more ``schemy''.
Thanks,
Ludovic.
| |
| Emilio Lopes 2006-03-22, 7:05 pm |
| Marco Bakera writes:
> Hey there
> is there any _easy_ way to turn an expression into a string? The only
> way that I found was using string ports.
You can use `format' if your Scheme implementation supports it, as
many do. Here an example using Scheme48:
Welcome to Scheme 48 1.3 (made by root on Mon Aug 1 20:34:22 CEST 2005)
Copyright (c) 1993-2005 by Richard Kelsey and Jonathan Rees.
Please report bugs to scheme-48-bugs@s48.org.
Get more information at http://www.s48.org/.
Type ,? (comma question-mark) for help.
> ,open formats
> (format #f "~s" '(my-expr foo "bar"))
"(my-expr foo \"bar\")"
> (format #f "~a" '(my-expr foo "bar"))
"(my-expr foo bar)"
Note the different between the format directives `~a' and `~s'.
--
Emílio C. Lopes
Munich, Germany
| |
| ronaldo 2006-03-22, 7:05 pm |
| ; maybe a macro will do the trick
; this is r5rs and should be portable
; note that some cases are missing!
(define-syntax expr->string
(syntax-rules ()
((expr->string) "")
((expr->string exp) (list->string exp)))
| |
| Shiro Kawai 2006-03-23, 4:11 am |
| Ludovic Court=E8s wrote:
> GNU Guile (and probably others) has `with-output-to-string' to do that
> sort of thing:
>
> (with-output-to-string (lambda () (write MY-EXPR)))
or even (write-to-string MY-EXPR) on some implementations.
http://practical-scheme.net/wiliki/...write-to-string
| |
| Abdulaziz Ghuloum 2006-03-23, 4:11 am |
| ronaldo wrote:
> ; maybe a macro will do the trick
> ; this is r5rs and should be portable
> ; note that some cases are missing!
> (define-syntax expr->string
> (syntax-rules ()
> ((expr->string) "")
> ((expr->string exp) (list->string exp)))
Huh? You're defining (expr->string exp) to be the same as
(list->string exp). Maybe you should re-read what R5RS says
or just check out
http://www.scheme.com/tspl3/objects.html#./objects:s152
And why is this a macro anyways?
Aziz,,,
| |
| Marco Bakera 2006-03-23, 4:11 am |
| Shiro Kawai schrieb am 23.03.2006 06:18:
> Ludovic Courtès wrote:
>
>
>
>
> or even (write-to-string MY-EXPR) on some implementations.
>
> http://practical-scheme.net/wiliki/...write-to-string
>
Yes thats right but both ways are implementation dependent but thats not
what I'm looking for. But thanks anyway for that hints anyway.
--
,----[ /X\arco -- www.bakera.de ]----
| (Y F) = (F (Y F))
`----[ www.bulb-publications.de ]----
| |
| Marco Bakera 2006-03-23, 4:11 am |
| Emilio Lopes schrieb am 22.03.2006 20:04:
>
> You can use `format' if your Scheme implementation supports it, as
> many do. Here an example using Scheme48:
As format is an srfi it's (almost) exactly what I was looking for. Thats
even more natural than misusing string ports for this. :)
Thanks for help and greetings,
Marco.
--
,----[ /X\arco -- www.bakera.de ]----
| (Y F) = (F (Y F))
`----[ www.bulb-publications.de ]----
| |
| Emilio Lopes 2006-03-23, 7:06 pm |
| Marco Bakera writes:
> Emilio Lopes schrieb am 22.03.2006 20:04:
[color=darkred]
> As format is an srfi it's (almost) exactly what I was looking
> for. Thats even more natural than misusing string ports for this. :)
Yes. Just note that `format' from SRFI-28 doesn't accept a port as
argument as in the Scheme48 examples you elided, so the interfaces are
different.
Did you notice that the "standard implementation" of `format' (see the
SRFI document) uses string ports? :-)
--
Emílio C. Lopes
Munich, Germany
| |
| Marco Bakera 2006-03-24, 4:14 am |
|
Emilio Lopes schrieb am 23.03.2006 20:20:
>
> Did you notice that the "standard implementation" of `format' (see the
> SRFI document) uses string ports? :-)
Didn't mention that. :) But even think, that this should not be the
right way to do this. However it's just an implementation lying beyound
my coding view. So they could do whatever they like. :)
Greetings,
Marco.
--
,----[ /X\arco -- www.bakera.de ]----
| (Y F) = (F (Y F))
`----[ www.bulb-publications.de ]----
| |
| Emilio Lopes 2006-03-25, 8:01 am |
| Marco Bakera writes:
> Emilio Lopes schrieb am 23.03.2006 20:20:
[color=darkred]
> Didn't mention that. :) But even think, that this should not be the
> right way to do this. However it's just an implementation lying
> beyound my coding view. So they could do whatever they like. :)
Here is my shot at it, with plenty of room for optimization. I wrote
it in CPS (continuation passing style) with the intention of making it
tail-recursive.
(define (convert thing in-sexp? return)
;; RETURN is the continuation
(cond
((string? thing)
(return (string-append "\"" thing "\"")))
((number? thing)
(return (number->string thing)))
((symbol? thing)
(return (string-append "'" (symbol->string thing))))
((pair? thing)
(convert (car thing)
#f
(let ((rest (cdr thing)))
(lambda (kar)
(return (convert rest
#t
(lambda (kdr)
(string-append (if in-sexp? "" "(")
kar
(cond
((null? rest) "")
((pair? rest) " ")
(else " . "))
kdr
(if (pair? rest) "" ")")))))))))
((null? thing)
(return (if in-sexp? "" "'()")))
(else
(error "Unknown thing"))))
(define (sexp->string sexp)
(convert sexp #f (lambda (x) x)))
;; (sexp->string '(1 foo (42 "bar")))
;; (sexp->string (cons 1 'b))
;; (sexp->string (list 1 'foo (cons 42 "bar")))
;; (sexp->string (list (cons 'a 'b) 1 'foo (cons 42 "bar")))
Just for the records, here is my first try. Much simpler, but doesn't
do exactly what you want:
(define (convert thing return)
;; RETURN is the continuation
(cond
((string? thing)
(return (string-append "\"" thing "\"")))
((number? thing)
(return (number->string thing)))
((symbol? thing)
(return (string-append "'" (symbol->string thing))))
((pair? thing)
(convert (car thing)
(lambda (kar)
(return (convert (cdr thing)
(lambda (kdr)
(string-append "(" kar " . " kdr ")")))))))
((null? thing)
(return "'()"))
(else
(error "Unknown thing"))))
(define (sexp->string sexp)
(convert sexp (lambda (x) x)))
--
Emílio C. Lopes
Munich, Germany
| |
| Jussi Piitulainen 2006-03-25, 8:01 am |
| Marco Bakera writes:
> As format is an srfi it's (almost) exactly what I was looking for.
> Thats even more natural than misusing string ports for this. :)
I would like to hear why this use of string ports would be misuse, or
not the right thing. To me it seems all right.
| |
| Marco Bakera 2006-03-30, 7:04 pm |
| Jussi Piitulainen schrieb am 25.03.2006 14:09:
>
>
>
> I would like to hear why this use of string ports would be misuse, or
> not the right thing. To me it seems all right.
Perhaps I am a little bit pampered from java having a string
representation of any object in a very easy way. Or even python has its
representation thing for all objects. :) So I thought of having a more
direct way of getting string representation of internal scheme "objects".
Greetings,
Marco.
--
,----[ /X\arco -- www.bakera.de ]----
| (Y F) = (F (Y F))
`----[ www.bulb-publications.de ]----
| |
| Lauri Alanko 2006-03-30, 7:04 pm |
| In article <442C1462.6010403@gmail.com>,
Marco Bakera <marco.bakera@gmail.com> wrote:
> Perhaps I am a little bit pampered from java having a string
> representation of any object in a very easy way. Or even python has its
> representation thing for all objects. :) So I thought of having a more
> direct way of getting string representation of internal scheme "objects".
In principle, a to-string operation and a dump-to-stream operation
are definable in terms of each other, so it might seem that we might
choose either one as the primitive:
(define (to-string x)
(define p (open-output-string))
(dump-to-stream x p)
(get-output-string p))
(define (dump-to-stream x p)
(write-string (to-string x) p))
However, consider a large object whose external representation
contains the external representations of numerous subobjects. If we
want to send such a representation to a file or over a network, and
to-string is the primitive, then we need to build a large string by
concatenating it from numerous smaller strings, and only when we have
the whole thing finished in memory can we send it away.
On the other hand, when dump-to-stream is the primitive, we can send
the external representation directly to the stream without requiring
intermediate data structures in memory. This is much more efficient.
So don't worry. The Scheme Way is the Right Way. :)
Lauri
| |
| Marco Bakera 2006-04-01, 4:01 am |
| Jussi Piitulainen schrieb am 31.03.2006 09:11:
>
> Just implement expr->string and forget about the details.
You are absolutely right. I just wondered whether there was something
like expr->string I just overlooked. :)
Greetings,
Marco.
--
,----[ /X\arco -- www.bakera.de ]----
| (Y F) = (F (Y F))
`----[ www.bulb-publications.de ]----
|
|
|
|