tags:

views:

62

answers:

3

rt. I want to redefine a function at run time so that i can change the behavior of the system at run time. thanks.

+5  A: 
(define (foo x) ...stuff...)
(set! foo (lambda (x) ...different stuff...))
Eli Barzilay
Eli, Set! works. but only for the function which i define after that.What i really want is that. I have a function A which use another function B.In runtime i want to redefine B to different behavior. So that A also get a new behavior. Is it possible?
gstar2002
Yes, that should work fine. Again, if you're using Racket, then the `set!` should be in the same module -- for example, you can define a `set-foo` function that will do the mutation. Alternatively, you can use a parameter instead -- that's the more common way to encapsulate such global state.
Eli Barzilay
A: 

Assuming you want to overload a function you defined earlier, simply define it again. This also works for redefining functions such as car and cdr, e.g. to make car into cdr:

(define (car x) (cdr x))

However, I think you won't be able to affect other already defined functions with such a redefinition, so a system function which uses car will still use the original system car and not yours:

(define (test x) (car x))

(define (car x) (cdr x))

(test '(1 2 3))

1

I guess the reason for this is that internally the symbols disappear once a function gets read or evaluated and the symbols are replaced by what they're bound to; in this case, the actual code of the function. So rebinding a symbol to a different function won't affect the rest of your already defined code. This is usually a good thing because it helps uphold referential transparency.

If you want to redefine scheme keywords such as lambda or cond, use let-syntax (see http://community.schemewiki.org/?scheme-faq-language)

JeSuisse
Using `define` a second time is bad habit, and the fact that the above returns 1 is due to related reasons.
Eli Barzilay
Bad habit: okay. But as to the "related reasons": I don't think so. (test '(1 2 3)) also returns 1 and not (2 3) when you redefine car using the (set! ... ) syntax, and as I said, I think this makes perfect sense when you think about how binding works. Agreed?
JeSuisse
Sorry, disregard my last comment and my answer. Seems I was using a non-standard scheme implementation to test this. MIT scheme works as you say, which makes my answer wrong.
JeSuisse
Even a single implementation can produce different results based on actual settings that are used. For example, you're seeing a result of inlining values for known primitives (`car`), which can be disabled.
Eli Barzilay
+1  A: 

It might be advisable to use let to do this locally, this can also apply to keywords in this sense:

(let ((define +))
   (define 2 3)) ; ===> 5

Or even redefine them to constants, remember, Scheme is a lisp-1:

(let ((define 2) (+ 4))
   (- define +)) ; ===> -2

Or even:

(let ((quote /))
   '3) ===> 1/3

Doing it only locally preserves the functional style.

Lajla