hasu / emacs-ob-racket

Emacs Org-Mode Babel code block Racket support
https://tero.hasu.is/blog/2011-09-08-on-racket-support-in-emacs-org-mode.html
GNU General Public License v3.0
34 stars 12 forks source link

Cann't use (require ...) in source block #12

Closed zhangshenhua closed 2 weeks ago

zhangshenhua commented 1 month ago

图片

hasu commented 3 weeks ago

That behavior looks correct to me, assuming that the :results collection mode was value in this case, which according to Org documentation means that "Org gets the value by wrapping the code in a function definition in the language of the source block."

By default, ob-racket does something like that by wrapping the code in a let, and the last body form should then be an expression that gives the value of the block. Other expressions and internal definitions may also be included in the body sequence, but not forms like require that are only allowed in "module level or top level."

Therefore the reported syntax error is due to a property of the language (e.g., the Ruby language does allow using require within a function body), and not of the Org Babel language support implementation.

In ob-racket there is support for a custom :require header argument that you may use instead of a require form within the code of the block:

+begin_src racket :results value :require racket/generator

(define g (sequence->generator (in-naturals))) (g) (g)

+end_src

+RESULTS:

: 1

Or, with :results output the code of the block will be at the module level:

+begin_src racket :results output

(require racket/generator) (define g (sequence->generator (in-naturals))) (g) (g)

+end_src

+RESULTS:

: 0 : 1

ZelphirKaltstahl commented 2 weeks ago

@hasu This let-wrapping seems suspicious to me, because it makes some things impossible. What if you (define ...) a variable? This let wrapping, that implicitly and invisibly happens, changes the meaning of code in code blocks. A similar let wrapping caused problems with var header arguments for scheme blocks. For example:

Welcome to Racket v8.13 [cs].
> (let ((a 1))
    (define b 2)
    3)
3
> b
b: undefined;
 cannot reference an identifier before its definition
  in module: top-level
 [,bt for context]
> 

Since the code is wrapped in a let it becomes wrong, while it usually would be perfectly OK.

Similar issue existed with ob-scheme btw. If you want, read the messages in this thread: https://lists.gnu.org/archive/html/emacs-orgmode/2023-03/msg00087.html