59332


Guile
Schemeで以下のようなニュートン法のコードを実行しようとしているのですが、エラーが出て実行できません。エラーの原因が分からず、改善ができないのでどなたか改善方法が分かれば教えていただけると助かります。

[code]

    (define (deriv f dx)
      ;;;導関数
      (lambda (x)(exact->inexact(/ (- (f (+ x dx)) (f x)) dx))))
    (define (good-enough? g guess)
      ;;;guessが十分良い値かを確かめる。
      (< (abs (g guess)) 0.0000001))
    (define (improve g guess)
      ;;;guessの値を改善する。
      (- guess (exact->inexact(/ (g guess) ((deriv g 0.0001) guess)))))
    (define (newton-iter2 g guess)
      ;;;ニュートン法
      (if (good-enough? g guess)
          guess
          (newton-iter2 g (improve g guess))))
    (define (square x) (* x x))
    (define (sqrt-base x)
      ;;;誤差を返す関数
      (lambda (t) (- (square t) x)))
    
[/code]

上のような関数をEmacsのスクリプト内で定義しguileに読み込ませた上で、以下のコードをguileに実行させたいのですがエラーが直せません...。  
(2の平方根を求めたい。)

[code]

    (define (sqrt3 x) (newton-iter2 (sqrt-base x) 1.0))
    (sqrt3 2)
    
[/code]

以下のようなエラーが出続けています...。

[code]

    <unnamed port>:11:0: In procedure sqrt3:
    In procedure module-lookup: Unbound variable: newton-iter2
    
[/code]


CC BY-SA 4.0
2019-09-27T10:15:06.777
59323
2019-09-28T17:46:36.217
2019-09-28T17:46:36.217
3510
31249
question
scheme
Guile Schemeでニュートン法を実行しようとしたが、エラーが出て実行できない。


Guileにはモジュールシステムがありますが、`load`した定義ファイルにモジュール指定の記述がないため、REPLのモジュールとは別のモジュールに定義されたのが原因だと思います。

定義時のモジュールと呼び出し時のモジュールを一致させるか、モジュールを指定して呼び出す必要があります。

(なお、`load`でモジュールを何も指定しないと`(ice-9 popen)`モジュールが設定されるようです。)

## REPLのデフォルト`guile-user`モジュールに定義を合わせる

[code]

    ;; 定義ファイル
    (use-modules (guile-user))
    
    (define (deriv f dx) ...
    
[/code]

[code]

    ;; REPL
    scheme@(guile-user)> (load "file.scm")
    scheme@(guile-user)> (define (sqrt3 x) (newton-iter2 (sqrt-base x) 1.0))
    scheme@(guile-user)> (sqrt3 2)
    $1 = 1.4142135624530596
    
[/code]

## ロードするファイルにモジュールを定義し、モジュールの外から呼び出す

[code]

    ;; 定義ファイル
    (define-module (ja.stackoverflow.com/questions/59323)
      #:export (newton-iter2 sqrt-base)) ; newton-iter2 と sqrt-baseを公開
    
    (define (deriv f dx) ...
    
[/code]

[code]

    ;; REPL
    (load "file.scm")
    
    (define (sqrt3 x)
      ((@ (ja.stackoverflow.com/questions/59323) newton-iter2) ;ja.stackoverflow.com/questions/59323モジュールで公開されているnewton-iter2を指定
       ((@ (ja.stackoverflow.com/questions/59323) sqrt-base) x) 1.0))
    scheme@(guile-user)> (sqrt3 2)
    $1 = 1.4142135624530596
    
[/code]

## 参考

  * <https://www.gnu.org/software/guile/manual/html_node/Modules.html>


CC BY-SA 4.0
2019-09-28T13:37:14.517
59332
2019-09-28T13:37:14.517
3510
59323
answer