[racket] graph-structured syntax

From: David Herman (dherman at ccs.neu.edu)
Date: Mon Feb 21 17:35:04 EST 2011

Hi Matthew,

Thanks very much for the response.

> The docs for `datum->syntax' say that graph structure is disallowed,
> and I think the behavior of `eval' below follows from the default eval
> handler's use of `datum->syntax'.

OK, thanks.

> Since `read-syntax' and `datum->syntax' don't support graph structure,
> there's no way to construct cyclic input to the expander --- or, in
> particular, to write a cyclic literal under `quote'. Literals with
> cycles were supported at one point, but they were fragile and almost
> never useful.

Presumably they might be more useful if we didn't have the `shared' notation, right?

But IIUC, cyclic literals are problematic because there's nothing stopping you from embedding arbitrary expressions inside literals, making it perhaps possible to trick the compiler into diverging or even create paradoxical cross-stage cycles. Which suggests that, despite its alluring simplicity, the "#...=" notation should be confined to {de}serialization libraries such as `read', while more restricted notations like `shared' are safer for providing graph-structured literals.

Does that sound like the (rough) rationale behind Racket's approach?

Dave

> 
> At Mon, 21 Feb 2011 08:18:34 -0800, David Herman wrote:
>> Any chance someone has an answer to my question below?
>> 
>> Thanks,
>> Dave
>> 
>> On Feb 14, 2011, at 4:42 PM, David Herman wrote:
>> 
>>> One more data point:
>>> 
>>>> (eval (read (open-input-string "#1=(sin #1#)")))
>>>   datum->syntax: cannot create syntax from cyclic datum: #0='(sin #0#)
>>> 
>>> So that's another clue: it looks like Racket goes to pretty great lengths to 
>> prevent the compiler from receiving cyclic AST's.
>>> 
>>> Anyway, it would be good to know if there's a place in the docs where this is 
>> spelled out.
>>> 
>>> Dave
>>> 
>>> On Feb 14, 2011, at 4:21 PM, David Herman wrote:
>>> 
>>>> I've never been fully acquainted with the graph reader, so I did a little 
>> REPL-experimenting and doc-hunting. It appears Racket is pretty conservative 
>> about where it allows you to use graph syntax:
>>>> 
>>>>> (define x '#0=(foo . #0#))
>>>>  read: #..-expressions not allowed in read-syntax mode
>>>> 
>>>> I imagine this is because cyclic AST's are Really Really Scary:
>>>> 
>>>>  #0=(sin #0#))
>>>> 
>>>> But I can't quite figure out where, if anywhere, graph-structured 
>> S-expressions *are* allowed in the Racket syntax. Certainly, you can use them 
>> for a programmatic read:
>>>> 
>>>>> (read (open-input-string "#0=(foo . #0#)"))
>>>>  #0=(foo . #0#)
>>>> 
>>>> But is there no place in the surface syntax where you can ever use the graph 
>> syntax? Is the `shared' library the only declarative syntax for creating cyclic 
>> data structures?
>>>> 
>>>> Is this a pretty straightforward restriction that was already done in Common 
>> Lisp, or did they allow wild-and-wooly, unrestricted uses of cyclic AST's that 
>> (educated guess...) result in undefined behavior by the compiler?
>>>> 
>>>> Dave
>>>> 
>>>> PS Happy Valentine's Day!
>>>> 
>>>> 
>>>> _________________________________________________
>>>> For list-related administrative tasks:
>>>> http://lists.racket-lang.org/listinfo/users
>>> 
>>> 
>>> _________________________________________________
>>> For list-related administrative tasks:
>>> http://lists.racket-lang.org/listinfo/users
>> 
>> 
>> _________________________________________________
>>  For list-related administrative tasks:
>>  http://lists.racket-lang.org/listinfo/users




Posted on the users mailing list.