Должен ли я определить отдельный модуль для каждого файла в моем проекте Guile? - PullRequest
0 голосов
/ 07 июля 2019

Позвольте мне объяснить мою проблему сравнением.В Common Lisp я мог разделить определения пакетов на несколько файлов, достаточно было объявить в каждом из них, что это in-package и load их.

Однако в схеме Guile похоже, что я должен define-moduleотдельно для каждого файла?Ну, я все еще могу load некоторые файлы, как в CL, и похоже, что работает, define-modules кажется, не ограничивается одним файлом, в котором он находится, как в CL, но я получаю предупреждения о неопределенных именах (те, которые определены в load ed файлов), так что мне кажется, что это не то, что ожидает Guile.Есть ли (1) какой-то способ разделения модуля на несколько файлов, как в CL, или (2) я должен придерживаться функции use-module автозагрузки и define-module для каждого файла отдельно?

1 Ответ

1 голос
/ 08 июля 2019

Действительно, в Guile вы можете load внутри define-module, но он сообщит о несвязанной переменной во время компиляции.

Идиоматический путь - это define-module в каждом файле:

;; in earth-software-system.scm
(define-module (earth-software-system))

(use-modules (earth-software-system bullet-train))
(use-modules (srfi srfi-9))

(re-export bullet-train) ;; possibly re-exporting imported bindings

...

Тогда в earth-software-system/bullet-train.scm вы можете иметь:

;; in earth-software-system/bullet-train.scm
(define-module (earth-software-system bullet-train))

(use-modules (srfi srfi-9))

(define-public bullet-train 42)

...

Помните, что define-public и один импорт на use-modules не получили широкого распространения. Вот пример из проекта GNU Guix, который использует define-module для импорта и экспорта:

(define-module (guix cpio)
  #:use-module ((guix build utils) #:select (dump-port))
  #:use-module (srfi srfi-9)
  #:use-module (srfi srfi-11)
  #:use-module (rnrs bytevectors)
  #:use-module (rnrs io ports)
  #:use-module (ice-9 match)
  #:export (cpio-header?
            make-cpio-header
            file->cpio-header
            file->cpio-header*
            write-cpio-header
            read-cpio-header

            write-cpio-archive))

Также в настоящее время я предпочитаю форму import, которая более проста для ума, чем use-modules:

;; in earth-software-system.scm
(define-module (earth-software-system))

(import (prefix (earth-software-system bullet-train) 'bt:)
(import (srfi srfi-9))

(re-export bt:bullet-train) ;; possibly re-exporting imported bindings

...

Синтаксис префикса также более прост для ума, чем эквивалент, использующий use-modules. Это основано на форме R6RS library и форме R7RS define-library. Я не рекомендую использовать форму library в Guile, поскольку она неправильно отображает строки.

GNU Guile позволяет импортировать формы, даже если они не экспортируются с использованием, например, синтаксиса @@ для проверки некоторых хитрых действий.

Вы можете заменить load на include, но я никогда не использовал его в Guile

...