reading s-expressions from a file

69 views
Skip to first unread message

Hendrik Boom

unread,
Jul 17, 2020, 8:19:12 PM7/17/20
to Racket Users
Yes, I know the functino for reading s-expressions seems to be (read [in]).

I want a loop that reads S-expressions and does something to each one, until there are no more to be found in a file.

Now of course that's absurdly easy to do with a tail-recursice loop.

But I's like it to look like a loop, with (for ...) or (while ...) or
(loop ...) or something like that.

But I fail to fine any iterators that process a file, such as (in-file
...)

There's a long list of iterators in
https://docs.racket-lang.org/reference/for.html
and in
https://docs.racket-lang.org/guide/for.html

An I just looking in the wrong place, or are there really no iterators
for reading a stream of s-expressions from a file.

-- hendrik

Sorawee Porncharoenwase

unread,
Jul 17, 2020, 8:30:54 PM7/17/20
to Racket Users
(with-input-from-file "abc" (thunk (sequence->list (in-port))))

Note that you need to “read” in the dynamic extent of with-input-from-file. Outside it, the port is closed.


--
You received this message because you are subscribed to the Google Groups "Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to racket-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/20200718001905.elzyuu42gje45j7t%40topoi.pooq.com.

George Neuner

unread,
Jul 17, 2020, 9:23:46 PM7/17/20
to Hendrik Boom, racket users
This should work if you're reading the sexprs for value:

(with-input-from-file filename

  (lambda ()
    (for [(expr (read))]
      :
    )))

If your intent is to read/parse the sexprs as text, there isn't a simple way to do that.  Regex is problematic for nested expressions ... you could try "read-syntax" if you are familiar with macros, or "match" if you know what patterns to look for. 

There's no "in-match" sequence, so if you want a loop that *appears* simple [match in the "for-clause"], you'll have to write some glue: a helper that returns one match result at a time so as to plug nicely into a loop.

George

gfb

unread,
Jul 17, 2020, 10:42:26 PM7/17/20
to Racket Users
Shouldn't the for be (for ([expr (in-producer read eof)] ⋯). One could also specify the input port there, as shown in reference for in-producer , possibly inside call-with-input-file (although that vs with-input-from-file is probably a matter of taste).
Reply all
Reply to author
Forward
0 new messages