Racket:在函数中使用 "csv-reading" 包
Racket: Using "csv-reading" package within a function
我正在使用 csv-reading
读取 csv 文件并将其转换为列表。
当我在顶层调用时,像这样
> (call-with-input-file "to-be-asked.csv" csv->list)
我能够读取 csv 文件并将其转换为列表列表。
但是,如果我在一个函数中调用相同的东西,就会出现错误。
> (read-from-file "to-be-asked.csv")
csv->list: undefined;
cannot reference an identifier before its definition
in module: top-level
我不明白哪里出了问题。我在函数调用之前添加了 (require csv-reading)
。
我的read-from-file
代码是:
(define (read-from-file file-name)
(call-with-input-file file-name csv->list))
编辑
我在 emacs
中使用 racket
使用 Geiser
。当我 (exit)
缓冲区并键入 C-c C-z
时,它显示错误。
当我终止缓冲区并再次启动 Geiser
时,它工作正常。
是不是Geiser
和emacs
的错误?
您遇到了我称之为常驻编程环境的经典问题(当时我不知道合适的词)。 常驻编程环境 是您与语言的 运行 实例对话并连续修改其状态的环境。
这些环境的问题是 运行 语言实例的状态是 more-or-less 不透明的,特别是它可能与您在文件或缓冲区中看到的状态不同步。这意味着事情发生的原因可能会变得模糊不清,更糟糕的是,您可能会进入这样一种状态,即您从常驻环境中获得的结果以后基本上无法重现。这对于像 Jupyter notebooks 这样的东西来说非常重要,人们从事科学工作可能会得到他们无法重现的结果,因为 notebook 的评估顺序是乱序的,或者其中一些根本没有被评估。
另一方面,这些环境使用起来非常愉快,这就是我使用它们的原因。这对我来说比问题更重要:你只需要小心你可以重新创建会话并愿意偶尔这样做。
在这种情况下,您可能在 buffer/file:
中有类似的内容
(require csv-reading)
(define (read-from-file file-name)
(call-with-input-file file-name csv->list))
但是您要么根本没有评估第一个表格,要么(更糟!)您评估表格的顺序不正确。如果您在 Common Lisp 或任何传统 Lisp 中执行此操作,一切都很好:评估第一种形式将使第二种形式起作用。但是球拍一劳永逸地决定 csv->list
在定义 read-from-file
时意味着什么(或不意味着什么),后来的 provide
不会解决这个问题。然后你最终会遇到你定义的函数不起作用的神秘情况,但是如果你定义一个使用 csv->list
的 new 函数,它 将 工作。这是因为它的语义比 CL 聪明得多,但据我所知,它的语义也不是为这种交互式开发设计的(当然 DrRacket 强烈反对它)。
我正在使用 csv-reading
读取 csv 文件并将其转换为列表。
当我在顶层调用时,像这样
> (call-with-input-file "to-be-asked.csv" csv->list)
我能够读取 csv 文件并将其转换为列表列表。
但是,如果我在一个函数中调用相同的东西,就会出现错误。
> (read-from-file "to-be-asked.csv")
csv->list: undefined;
cannot reference an identifier before its definition
in module: top-level
我不明白哪里出了问题。我在函数调用之前添加了 (require csv-reading)
。
我的read-from-file
代码是:
(define (read-from-file file-name)
(call-with-input-file file-name csv->list))
编辑
我在 emacs
中使用 racket
使用 Geiser
。当我 (exit)
缓冲区并键入 C-c C-z
时,它显示错误。
当我终止缓冲区并再次启动 Geiser
时,它工作正常。
是不是Geiser
和emacs
的错误?
您遇到了我称之为常驻编程环境的经典问题(当时我不知道合适的词)。 常驻编程环境 是您与语言的 运行 实例对话并连续修改其状态的环境。
这些环境的问题是 运行 语言实例的状态是 more-or-less 不透明的,特别是它可能与您在文件或缓冲区中看到的状态不同步。这意味着事情发生的原因可能会变得模糊不清,更糟糕的是,您可能会进入这样一种状态,即您从常驻环境中获得的结果以后基本上无法重现。这对于像 Jupyter notebooks 这样的东西来说非常重要,人们从事科学工作可能会得到他们无法重现的结果,因为 notebook 的评估顺序是乱序的,或者其中一些根本没有被评估。
另一方面,这些环境使用起来非常愉快,这就是我使用它们的原因。这对我来说比问题更重要:你只需要小心你可以重新创建会话并愿意偶尔这样做。
在这种情况下,您可能在 buffer/file:
中有类似的内容(require csv-reading)
(define (read-from-file file-name)
(call-with-input-file file-name csv->list))
但是您要么根本没有评估第一个表格,要么(更糟!)您评估表格的顺序不正确。如果您在 Common Lisp 或任何传统 Lisp 中执行此操作,一切都很好:评估第一种形式将使第二种形式起作用。但是球拍一劳永逸地决定 csv->list
在定义 read-from-file
时意味着什么(或不意味着什么),后来的 provide
不会解决这个问题。然后你最终会遇到你定义的函数不起作用的神秘情况,但是如果你定义一个使用 csv->list
的 new 函数,它 将 工作。这是因为它的语义比 CL 聪明得多,但据我所知,它的语义也不是为这种交互式开发设计的(当然 DrRacket 强烈反对它)。