Racket中能否使用同名自定义函数替换内置原生函数?
Racket是否支持用同名自定义函数替换内置函数
Racket完全支持用同名自定义函数覆盖内置函数,你遇到的程序卡死问题不是语言层面禁止重名操作,是自定义函数的写法触发了无限递归bug。
- 你之前定义的
a-hl函数可以正常运行,是因为定义a-hl时,当前作用域内的append还是Racket提供的内置原始版本,函数内部对append的调用会固定指向这个内置实现,不会被后续的同名绑定影响。 - 直接定义
(define (append l e) (append l (list e)))会导致程序卡死,核心原因是Racket遵循词法作用域的就近绑定规则:当你在当前作用域定义名为append的新函数时,函数体内部出现的append标识符会优先绑定到你正在定义的新函数,而非原始的内置append。
这个写法的实际执行逻辑是:每次调用自定义
append,函数内部第一步就会再次调用自身,永远无法触达内置append的逻辑,形成无终止的自递归。程序会持续消耗栈和内存资源直到耗尽,外在表现就是无响应卡死。
如果确实需要定义同名append覆盖内置版本,同时要在自定义逻辑里调用原始内置实现,可以先把内置函数的引用留存下来再做重定义,可正常运行的参考代码如下:
#!/usr/bin/env racket #lang racket/base (require racket/file) ;; 先保存内置append的引用 (define builtin-append append) ;; 定义同名自定义append (define (append l e) (builtin-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 (regexp-replace* #rx" .*" l "")))) (for ((e arr)) (display e))
补充说明:Racket没有内置函数名不可重定义的限制,只要在对应作用域内通过define做了同名绑定,就会覆盖之前的所有同名绑定(包括语言默认加载的内置绑定),重定义行为本身完全合法。
内容的提问来源于stack exchange,提问作者John Smith
相关产品推荐
相关产品推荐

