Ini kode R saya. Fungsi didefinisikan sebagai:
f <- function(x, T) {
10 * sin(0.3 * x) * sin(1.3 * x ^ 2) + 0.001 * x ^ 3 + 0.2 * x + 80
}
g <- function(x, T, f=f) {
exp(-f(x) / T)
}
test <- function(g=g, T=1) {
g(1, T)
}
Kesalahan yang berjalan adalah:
> test ()
Kesalahan dalam pengujian ():
janji sudah dalam evaluasi: referensi argumen default rekursif atau masalah sebelumnya?
Jika saya mengganti definisi dari f
itu g
, maka kesalahan hilang.
Saya bertanya-tanya apa kesalahannya? Bagaimana cara memperbaikinya jika tidak mengganti definisi f
di dalam dari itu g
? Terima kasih!
Memperbarui:
Terima kasih! Dua pertanyaan:
(1) jika fungsi test
lebih lanjut membutuhkan argumen f
, apakah Anda akan menambahkan sesuatu seperti test <- function(g.=g, T=1, f..=f){ g.(1,T, f.=f..) }
? Dalam kasus dengan lebih banyak rekursi, apakah ini praktik yang baik dan aman menambahkan lebih banyak . ?
(2) jika f
argumen non-fungsi, misalnya g <- function(x, T, f=f){ exp(-f*x/T) }
dan test <- function(g.=g, T=1, f=f){ g.(1,T, f=f.) }
, akan menggunakan nama yang sama untuk argumen non-fungsional formal dan aktual merupakan praktik yang baik dan aman atau dapat menyebabkan beberapa potensi masalah?
.....cumbersome
. :)...
atau daftar untuk meneruskan argumen ke rantai fungsi. Ini jauh lebih fleksibel (baik dan buruk) daripada menentukan segalanya sebelumnya. Anda mungkin akhirnya perlu menambahkan beberapa cek untuk memastikan argumen asli Anda di elips (atau daftar) masuk akal.get("f", envir = parent.frame())
.Jika Anda menetapkan konteks evaluasi argumen, Anda menghindari masalah dengan nama yang sama:
sumber
Saya suka jawaban G. Grothendieck , tapi saya bertanya-tanya itu lebih sederhana dalam kasus Anda untuk tidak memasukkan nama fungsi dalam parameter fungsi, seperti ini:
sumber
Seperti yang telah disebutkan, masalahnya berasal dari memiliki argumen fungsi yang didefinisikan sebagai dirinya sendiri. Namun, saya ingin menambahkan penjelasan mengapa ini merupakan masalah karena pemahaman yang mengarahkan saya ke cara yang lebih mudah (bagi saya) untuk menghindari masalah: cukup tentukan argumen dalam panggilan alih-alih definisi.
Ini tidak bekerja:
tetapi ini berhasil:
Argumen fungsi ada di lingkungan lokal mereka sendiri.
R mencari variabel terlebih dahulu di lingkungan lokal, lalu di lingkungan global. Ini seperti bagaimana di dalam suatu fungsi suatu variabel dapat memiliki nama yang sama dengan variabel di lingkungan global, dan R akan menggunakan definisi lokal.
Memiliki definisi argumen fungsi dari lingkungan lokal mereka sendiri adalah mengapa Anda dapat memiliki nilai argumen default berdasarkan nilai argumen lainnya, seperti
Jadi inilah mengapa Anda tidak dapat mendefinisikan fungsi sebagai
my.function <- function(x = x){}
tetapi Anda dapat memanggil fungsi menggunakanmy.function(x = x)
. Ketika Anda mendefinisikan fungsi, R menjadi bingung karena menemukan argumenx =
sebagai nilai lokalx
, tetapi ketika Anda memanggil fungsi R menemukanx = 4
di lingkungan lokal tempat Anda menelepon.Jadi selain memperbaiki kesalahan dengan mengubah nama argumen atau secara eksplisit menentukan lingkungan seperti yang disebutkan dalam jawaban lain, Anda juga bisa menentukan bahwa
x=x
ketika Anda memanggil fungsi alih-alih ketika Anda mendefinisikannya. Bagi saya, menetapkan bahwax=x
dalam panggilan adalah solusi terbaik, karena tidak melibatkan sintaks tambahan atau mengakumulasi lebih banyak dan lebih banyak nama variabel.sumber