Можно ли использовать extract-struct-info вне макроса? - PullRequest
3 голосов
/ 12 апреля 2019

Рассмотрим следующий код ракетки, чтобы получить список accessor с заданной структуры:

#lang racket

(require (for-syntax syntax/parse racket/struct-info racket/list))

(struct point [x y])

;; get the list of accessors from a struct
;; ex. (get point) = '(point-x point-y)
(define-syntax (get stx)
  (syntax-parse stx
    [(_ struct)

     (define struct-info (extract-struct-info (syntax-local-value #'struct)))
     (define accessors-list (map syntax-e  (fourth struct-info)))

     #``(#,@accessors-list)]))

(get point)

Используя syntax-local-value, мы можемизвлечь значение идентификатора, связанного с переменной шаблона struct.

Используя extract-struct-info, мы можем извлечь информацию о типе структуры в виде списка (он имеет 6 элементов).Отсюда можно извлечь список методов доступа (это четвертый элемент в списке).

Вопрос

Как получить доступ к информации о структуре (как показано на Привязка трансформатора типа конструкции ) на немакроуровне?Две вышеупомянутые функции не могут быть использованы непосредственно на структурах вне трансформатора, потому что структура в этот момент является процедурой (а extract-struct-info принимает struct-info).

1 Ответ

4 голосов
/ 12 апреля 2019

Вы не можете использовать syntax-local-value и extract-struct-info во время выполнения. Вместо этого вы должны использовать внутреннюю структуру struct introspection.

Если вы сделаете вашу структуру прозрачной, как это:

(struct point [x y] #:transparent)

затем вы можете получить аналогичные значения из точечного экземпляра, используя struct-info и struct-type-info:

(define a-point (point 3 4))
(define-values (type skipped?) (struct-info a-point))
;; type = #<struct-type:point>, skipped = #f
(define-values (name inits autos acc mut imms super super-skipped?)
  (struct-type-info type))
(acc a-point 0) ;; => 3

Значение type выше совпадает с struct:point (неявно определенным определением структуры), поэтому, если вы знаете, что имеете дело именно с точечной структурой, вы можете использовать ее вместо этого. Вам все еще нужен #:transparent (или вам нужен достаточно мощный инспектор), чтобы использовать struct-type-info.

...