Search code examples
functionschemeracketmetaprogramming

Can I replace a Racket's function with my custom function of the same name? Doable?


In the following code I defined my own a-hl with which I mean to replace the direct call of append in my code. It does not really replace it as it uses append under the hood (see the comment):

#!/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))

The code works fine. But when I attempt to define my own append, (define (append l e) (append l (list e))) and that use it,

(for ((l content)) 
  (set! arr (append arr (regexp-replace* #rx" .*" l ""))))
  
(for ((e arr)) (display e))

Racket freezes. Is it at all doable to replace a Racket's function with my custom function of the same name?


Solution

  • You can use Racket's require's only-in clause to give your own name to a binding from a module, and use that:

    #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)
    

    or use local-require to import it only inside your function:

    (define (append l e)
      (local-require (only-in racket/base [append builtin-append]))
      (builtin-append l (list e)))