Hellnar
Hellnar

Reputation: 64783

scheme and set!

How can I change the value of a variable via a function that consumes lambda parameter? Ie:

;;definitions
(define test "fails")
(define (experiment input) (set! input "works"))

;;interactions
> test
"fails"
> (experiment test)
> test
"fails"

This seems to fail..

Regards

Upvotes: 2

Views: 2094

Answers (2)

newacct
newacct

Reputation: 122429

Maybe it would make more sense if you consider the same code in Python:

test = "fails"
def experiment(input):
  input = "works"

>>> test
'fails'
>>> experiment(test)
>>> test
'fails'

Upvotes: 0

Eli Barzilay
Eli Barzilay

Reputation: 29546

You cannot -- Scheme passes all values "by value", so in the above the experiment function simply modifies its own input argument. To get something like this working, you can use a box, which is an explicitly mutable value container:

(define test (box "fails"))
(define (experiment input) (set-box! input "works"))
(unbox test)
(experiment test)
(unbox test)

If you really want to change the value of a variable, you can use a macro:

(define-syntax-rule (experiment input) (set! input "works"))

This creates experiment as a macro, which means that every (experiment foo) form is getting rewritten into (set! foo "works"). This can have subtle consequences, so it's not a good idea to use this unless you know what you're doing. (For example, (experiment 2) will fail in an "interesting" way.) Writing macros in Scheme is easy, but writing good macros is still more difficult than writing a new function definition.

[Note that I'm assuming you're using PLT Scheme in this answer. But both parts can be translated into "standard" Scheme if needed -- for example, use a mutable cons cell for the first, and use define-syntax with syntax-rules for the second.]

Upvotes: 9

Related Questions