datalog
datalog copied to clipboard
REPL does not work
I'm new, just installed Racket v8.0, trying to follow tutorial https://docs.racket-lang.org/datalog/Tutorial.html.
I expect REPL to print me same results as when I execute code:
> parent(A, B)?
parent(john, douglas).
parent(bob, john).
parent(ebbon, bob).
but it doesn't happen.
Here is my DrRacket screenshot:

Here is my shell session:
grfork@pisec ~/p/r/datalog> cat test.rkt
#lang datalog
parent(john, douglas).
parent(bob, john).
parent(ebbon, bob).
parent(A, B)?
grfork@pisec ~/p/r/datalog> racket
Welcome to Racket v8.0 [cs].
> ,en "test.rkt"
parent(john, douglas).
parent(bob, john).
parent(ebbon, bob).
"test.rkt"> parent(A, B)?
; <pkgs>/datalog/stx.rkt:64.35: datalog-stmt: bad syntax
; in: (datalog-stmt parent)
; [,bt for context]
; <pkgs>/datalog/stx.rkt:64.35: datalog-stmt: expected one of these
; identifiers: `!', `~', or `?'
; at: A
; in: (datalog-stmt (A (unquote B)))
; [,bt for context]
; <pkgs>/datalog/stx.rkt:64.35: datalog-stmt: bad syntax
; in: (datalog-stmt ?)
; [,bt for context]
"test.rkt"> ^D
This works in DrRacket BC but not in DrRacket CS. Really bizarre.
It's never meant to work in command-line REPL. If you take a look at the error message, you will see that it tries to parse your input as a Racket program. E.g.,
parent(A, B)?
is read as:
parent
(A (unquote B))
?
Working in BC but not CS means it's likely a Racket-level bug. cc @mflatt
Looks like the problem is with char-ready?, which returns differently in BC vs CS.
https://github.com/racket/datalog/blob/master/lang/configure-runtime.rkt#L12
I've pushed a repair for char-ready?, but I'm skeptical that char-ready? is ever appropriate in a parser.
(Really, I'm skeptical of almost any program that uses char-ready?. The CS bug may have gone undetected until now because char-ready? is so rarely useful.)
It is only here:
https://github.com/racket/datalog/blob/057771889eff193e5442a0c95b8c837bac4c241c/lang/configure-runtime.rkt#L10
And I seem to recall putting it in because when DrRacket does parsing, it doesn't give a port that has an EOF, because there might be more, and if you just do the peek-char then it will hang. This happened 8 years ago so I only have a vague memory --- https://github.com/racket/datalog/commit/d7c8cdd938cecc976f049b1dd154ae7c581fe9fd
I think DrRacket's REPL can have multiple EOFs (one per interaction). Maybe that's what you're thinking of?
Perhaps?
FWIW I found this EOF protocol to be:
- difficult to understand in the first place
- tricky to get working when the REPL is connected via stdin/stdout
- and later, more or less "impossible" when connected via TCP ports (which is what Racket Mode does these days, to support multiple REPLs from one back end process connected to Emacs).
TL;DR it was confusing, I got it working(ish), but then had to abandon it.
Is there another possible protocol?
I think this could be one of a few items on a hypothetical roadmap, "Improving the LOP story for non-sexp langs".
Sounds like a nice thing to sort out!
This issue has been mentioned on Racket Discussions. There might be relevant details there:
https://racket.discourse.group/t/current-read-interaction-returning-eof/1032/1