Следующие два примерно одинаковы?
Конечно, но я бы с осторожностью относился к изучению Scheme или любого Lisp, ссылаясь на Python.
Обратите внимание, что Схема R6RS имеет хеш-таблицы и процедуры хеш-таблиц как часть стандартных библиотек; этого не было в случае со схемой R5RS. Следовательно, более ранние реализации Scheme обычно имели свои собственные реализации хеш-таблиц. Guile Scheme поддерживает хеш-таблицы и процедуры R6RS, но, похоже, поддерживает и более старые процедуры. Это также относится к Схеме, с которой я больше всего знаком, Chez Scheme. В Руководстве пользователя Chez Scheme говорится, что процедуры старого стиля включены главным образом для совместимости со старыми реализациями Chez Scheme, но их поддержка может быть прекращена в будущем выпуске. Я не знаю, какова позиция Guile по этому поводу, но я бы предложил использовать процедуры стандартной схемы, когда это возможно, для максимальной переносимости и защиты от таких будущих изменений в вашей реализации.
На момент написания этой статьи Guile имеет версию до версии 3.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, можно создать и запросить хеш-таблицу:
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>
Как я могу увидеть, что моя хэш-карта содержит в схеме?
Возможно, проще всего было бы создать список ассоциаций из хеш-таблицы. В R6RS нет стандартной процедуры для этого, но был старый SRFI (SRFI-69), который включал в себя именно такую процедуру: hash-table->alist
. Возможно, что реализация Guile OP включает в себя такую процедуру, но ее просто реализовать с использованием стандартной схемы R6RS:
(define (hashtable->alist ht)
(let-values (((ks vs) (hashtable-entries ht)))
(vector->list (vector-map cons ks vs))))
Здесь процедура hashtable-entries
берет хеш-таблицу и возвращает два значения: вектор ключей и вектор соответствующих значений; 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, но многие процедуры 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
процедура, но документация описывает, как создать список ассоциаций из хеш-таблицы с помощью процедуры hash-map->list
:
(hash-map->list cons my-dict)
Ожидается, что это будет работать только с хэш-таблицами, созданными с помощью конструкторов хеш-таблиц Guile для конкретной реализации (например, make-hash-table
), и может не работать с хэш-таблицами, созданными с помощью конструкторов R6RS (например, make-eq-hashtable
). Еще раз обратите внимание, что это решение должно работать в Guile (без импорта), но не является переносимым.
person
ad absurdum
schedule
13.04.2020
my_dict
вместоm
. Какая схема используется? В схеме R6RS нет ниhash-set!
, ниhash-ref
; у него естьhashtable-set!
иhashtable-ref
, аhashtable-ref
требует 3-го аргумента, указывающего возвращаемое значение по умолчанию. - person ad absurdum   schedule 13.04.2020