在下面的代码中,我定义了自己的a-hl
,我的意思是用它来替换直接调用我的代码中的append
。它并没有真正取代它,因为它在引擎盖下使用了append(见评论):
#!/usr/bin/env racket
#lang racket/base
(require racket/file)
(define (a-hl l e) (append l (list e)))
(define content (list "https://youtu.be/FVaVLpSHw38 Road to the Arnold" "https://www.youtube.com/watch?v=hlTfA42b_uI MIT Bitcoin Expo 2022: Breaking Through - Lightning Panel"))
(define arr (list))
(for ((l content))
;(set! arr (append arr (list (regexp-replace* #rx" .*" l "")))))
(set! arr (a-hl arr (regexp-replace* #rx" .*" l "")))); works just as well but it is shorter
(for ((e arr)) (display e))
代码运行良好。但当我试图定义我自己的append
、(define (append l e) (append l (list e)))
并使用它时,
(for ((l content))
(set! arr (append arr (regexp-replace* #rx" .*" l ""))))
(for ((e arr)) (display e))
Racket结冰。用我的同名自定义函数替换Racket的函数是否可行?
您可以使用Racket的require
的only-in
子句为来自模块的绑定指定自己的名称,并使用它:
#lang racket
(require (only-in racket/base [append builtin-append]))
(define (append l e) (builtin-append l (list e)))
(writeln (append '(1 2 3) 4)) ; (1 2 3 4)
或者使用local-require
仅在您的函数内部导入:
(define (append l e)
(local-require (only-in racket/base [append builtin-append]))
(builtin-append l (list e)))
您可以定义自己版本的函数,这样做只会影响模块中require
中定义的代码。
对于append
这样的定义,是否应该这样做是另一个问题:这样做是为粗心者设置陷阱和陷阱的好方法。也许只有当你真正理解这样做的后果,并且你正在构建一种在语义上与标准Racket语言非常不同的语言时,才有可能这样做。
在这种情况下,看起来落入陷阱的那个不小心的人就是你。您对append
的定义是:
(define (append l e)
(append l (list e)))
这一定义显然既不会终止,也会在不终止的过程中使用无限内存。
您的问题似乎是,您认为append
的定义称为的版本是Racket的版本。事实并非如此:define
不是这样工作的,在这种情况下不会,也永远不会。以类似的形式
(define (<name> ...)
... <name> ...)
或等效
(define <name>
(lambda (...) ... <name> ...))
然后(假设没有<name>
的中间绑定),<name>
指的是您正在定义的东西。