Являются ли следующие два примерно одинаковыми?
Конечно, но я бы с осторожностью относился к изучению Scheme или любого Lisp, возвращаясь к Python .
Обратите внимание, что в схеме R6RS имеются таблицы процедур ha sh и ha sh как часть стандартных библиотек; это было не так со схемой R5RS. Следовательно, более ранние реализации Scheme обычно имели свои собственные реализации таблиц ha sh. Guile Scheme поддерживает R6RS ha sh таблицы и процедуры, но, похоже, поддерживает и более старые процедуры. Это также относится к Схеме, с которой я больше всего знаком, к Схеме Chez. В руководстве пользователя Chez Scheme говорится, что процедуры старого стиля включены в первую очередь ради совместимости со старыми реализациями Chez Scheme, но поддержка их может быть прекращена в будущем выпуске. Я не знаю, какова позиция Guile по этому вопросу, но я бы предложил, по возможности, использовать процедуры стандартной схемы для максимальной переносимости и для предотвращения таких будущих изменений в вашей реализации.
Guile до v3.0.2 в время написания этой статьи; OP версия v2.0.9, которой, насколько я могу судить, около 5 лет. Guile 2.0.14 поддерживает хеш-таблицы R6RS , поэтому я подозреваю, что Guile 2.0.9 также делает это. В любом случае я отвечу по стандартной схеме R6RS; адаптация к старой реализации Guile должна быть тривиальной, если необходимо.
Стандартная библиотека R6RS не имеет make-hash-table
, но вместо этого имеет make-hashtable
, make-eq-hashtable
и make-eqv-hashtable
, Процедура make-hashtable
требует процедуры проверки эквивалентности ключей, тогда как make-eq-hashtable
проверяет эквивалентность с eq?
и make-eqv-hashtable
проверяет eqv?
.
Вместо hash-set!
, Стандарт Библиотека имеет hashtable-set!
, которая принимает те же аргументы, что и OP для hash-set!
.
Вместо hash-ref
, Стандартная библиотека имеет hashtable-ref
. Это отличается от OP hash-ref
тем, что для указания значения по умолчанию, когда ключ не найден, требуется третий аргумент.
По шагам OP можно создать и запросить таблицу ha sh. :
Chez Scheme Version 9.5
Copyright 1984-2017 Cisco Systems, Inc.
> (define my-dict (make-eq-hashtable))
> (hashtable-set! my-dict 'a 1)
> (hashtable-set! my-dict 'b 2)
> (hashtable-set! my-dict 'c 3)
> (hashtable-set! my-dict 'd 5)
> (hashtable-set! my-dict 'e 7)
> (hashtable-set! my-dict 'f 11)
> (hashtable-set! my-dict 'g 13)
> (hashtable-ref my-dict 'e #f)
7
> (hashtable-ref my-dict 'h #f)
#f
> my-dict
#<eq hashtable>
Как мне увидеть, что моя схема содержит в схеме?
Возможно, самое простое, что можно сделать, это создать список ассоциаций из таблицы ha sh. В R6RS нет стандартной процедуры, которая бы это делала, но был старый SRFI ( SRFI-69 ), который включал именно такую процедуру: hash-table->alist
, Возможно, что OP-реализация Guile включает в себя такую процедуру, но ее легко реализовать с использованием стандартной схемы R6RS:
(define (hashtable->alist ht)
(let-values (((ks vs) (hashtable-entries ht)))
(vector->list (vector-map cons ks vs))))
Здесь процедура hashtable-entries
принимает таблицу ha sh и возвращает два значения: вектор ключей и вектор соответствующих значений; let-values
используется для связывания двух возвращаемых значений, чтобы их можно было использовать. vector-map
возвращает вектор, образованный объединением элементов ks
и vs
с cons
, а vector->list
создает список из этого вектора.
> (hashtable->alist my-dict)
((f . 11) (e . 7) (c . 3) (b . 2) (a . 1) (g . 13) (d . 5))
Guile: Ради всего мира Полнота
Приведенное выше решение будет работать в Guile, но многие процедуры R6RS по умолчанию не распознаются в Guile. Чтобы вышеуказанное решение работало в Guile, сначала нужно что-то вроде:
(import (rnrs hashtables (6)) ; for R6RS hash tables
(rnrs base (6))) ; for R6RS let-values
После просмотра справочного руководства Guile 2.0.14 очевидно еще одно непортативное решение. Процедура hash-table->alist
, описанная в руководстве, отсутствует, но в документации описано , как создать список ассоциаций из таблицы ha sh с помощью процедуры hash-map->list
:
(hash-map->list cons my-dict)
Ожидается, что это сработает только для таблиц ha sh, созданных с помощью спецификаций реализации Guile c ha sh (например, make-hash-table
), и может не работать с таблицами ha sh, созданными с помощью Конструкторы R6RS (например, make-eq-hashtable
). Еще раз обратите внимание, что это решение должно работать в Guile (без импорта), но не переносимо.