skema dan atur!

Bagaimana cara mengubah nilai variabel melalui fungsi yang menggunakan parameter lambda? Yaitu:

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

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

Ini sepertinya gagal..

Salam


person Hellnar    schedule 10.11.2009    source sumber


Jawaban (2)


Anda tidak bisa -- Skema meneruskan semua nilai "berdasarkan nilai", jadi pada fungsi experiment di atas cukup memodifikasi argumen masukannya sendiri. Agar sesuatu seperti ini berfungsi, Anda dapat menggunakan sebuah kotak, yang merupakan wadah nilai yang secara eksplisit dapat diubah:

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

Jika Anda benar-benar ingin mengubah nilai suatu variabel, Anda dapat menggunakan makro:

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

Ini membuat experiment sebagai makro, yang berarti setiap formulir (experiment foo) ditulis ulang menjadi (set! foo "works"). Hal ini dapat menimbulkan konsekuensi yang tidak kentara, jadi bukanlah ide yang baik untuk menggunakan ini kecuali Anda tahu apa yang Anda lakukan. (Misalnya, (experiment 2) akan gagal dengan cara yang "menarik".) Menulis makro dalam Skema itu mudah, namun menulis makro yang baik masih lebih sulit daripada menulis definisi fungsi baru.

[Perhatikan bahwa saya berasumsi Anda menggunakan Skema PLT dalam jawaban ini. Namun kedua bagian dapat diterjemahkan ke dalam Skema "standar" jika diperlukan -- misalnya, gunakan sel cons yang dapat diubah untuk sel pertama, dan gunakan define-syntax dengan syntax-rules untuk sel kedua.]

person Eli Barzilay    schedule 10.11.2009
comment
Hal ini juga dapat dilakukan dengan parameter: srfi.schemers.org/srfi-39/ srfi-39.html - person Jonathan Arkell; 10.11.2009
comment
Ya, parameter adalah jenis wadah lain yang bisa berubah (dan PLT memiliki beberapa wadah lainnya, seperti thread-cell). Tapi semantiknya bisa sedikit berbeda dari global biasa. Misalnya, sebuah parameter memiliki nilai unik untuk setiap thread (lebih tepatnya, nilai unik untuk setiap kelanjutan). - person Eli Barzilay; 11.11.2009

Mungkin akan lebih masuk akal jika Anda mempertimbangkan kode yang sama dengan Python:

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

>>> test
'fails'
>>> experiment(test)
>>> test
'fails'
person newacct    schedule 10.11.2009
comment
Bagaimana ini menjawab pertanyaan tersebut? - person Vijay Mathew; 11.11.2009