我可以用同名的自定义函数替换球拍的功能吗?可做的?



在下面的代码中,我定义了自己的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的requireonly-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>指的是您正在定义的东西。

最新更新