#lang racket/base
(module x scribble/text
@(display 123))
似乎#lang语句在嵌套子模块中无效,并且上面扩展的模块版本缺少一些东西:
错误:模块:没有#%module-begin以模块的语言开始绑定
看起来或多或少都有效,但还有更好的方法吗? scribble用输出端口做一些没有被处理的东西吗?
#lang racket/base
(module x scribble/text/lang
(#%module-begin
#reader scribble/reader @list{
hi
@(+ 1 456)
}))
答案 0 :(得分:4)
首先,您的代码有一个可以删除的冗余#%module-begin
。
#lang
做了几件事 - 一个是控制文件的语义
通过确定最初导入的绑定集,那就是
在module
出现之前#lang
表单已完成的内容。同
子模块,也可以将module
用于文件的各个部分。
但是,#lang
也可以确定解析文件的读者,以及
这是不可能的子模块,所以你只有一个
toplevel #lang
为整个文件设置解析器。
(旁注:有一个技术原因。#lang
读者读到
文件的其余部分,直到达到eof
值,因此嵌套
#lang
需要在结束之前获得eof
值
该文件,或添加一种新的类似eof的值。这意味着它
应该谨慎进行的改变 - 这是可能的
当然,但需求并没有经常出现。希望它会,在
未来。)
但是在你的情况下,你不需要一个全新的具体语法
s表达式的扩展 - 以及被选择的扩展名
对常规代码影响最小。所以在几乎所有情况下都很好
只为整个文件启用@ -form语法,然后使用
@ -forms你想要它。因为它只是一种替代方式
阅读sexprs,您甚至可以使用module
,导致这一点
代码不需要使用#reader
:
#lang at-exp racket/base
@module[x scribble/text/lang]{
hi
@(+ 1 456)
}
(require 'x)
这里有点奇怪的是使用scribble/text/lang
和
不只是scribble/text
。通常,#lang foo
与...完全相同
用(module x foo ...)
读者阅读代码后foo
。但在
scribble/text
语言的情况还有另一个区别:
使用它作为#lang
使模块体的语义成为“输出
每一件事“。这个想法是,作为一种语言,你会想要吐出来
主要是文本文件,但作为库,您需要在其中编写代码
并自己做打印输出。
由于此代码使用module
,因此使用scribble/text
意味着您
没有得到吐出全部功能,这就是你需要的原因
明确切换到scribble/text/lang
。但你可以改为
只是使用语言output
进行随地吐痰
给你这个代码:
#lang at-exp racket/base
(module x racket/base
(require scribble/text)
(output @list{
hi
@(+ 1 456)}))
(require 'x)
请注意,scribble/text
此处未用作语言,因为它
在使用时(#lang
之外)没有提供足够的东西。
(您已经找到了,导致多余的#%module-begin
...)
这个版本稍微冗长一点,但我猜这是有道理的 在你的情况下更有意义,因为在代码的某些部分使用它意味着 您希望将其用作库。
最后,如果你真的不想用@
读取整个文件
语法,只有一些部分,然后是你找到的#reader
非常好。 (scribble/text
这简单易懂
将列表视为连接输出,因此您只需要一个包装器
每一块文字。)