Элементы исчезают при сортировке списка в Guile

Кажется, у меня есть случай исчезновения элементов после вызова sort! в списке строк:

(Я получил этот код из шаблона Autogen, над которым работал.)

(use-modules (ice-9 pretty-print))

(let ((files '("log4cplus/socketappender.h"
              "log4cplus/qt4debugappender.h"
              "log4cplus/nteventlogappender.h"
              "log4cplus/ndc.h"
              "log4cplus/msttsappender.h"
              "log4cplus/mdc.h"
              "log4cplus/loglevel.h"
              "log4cplus/loggingmacros.h"
              "log4cplus/logger.h"
              "log4cplus/log4judpappender.h"
              "log4cplus/log4cplus.h"
              "log4cplus/layout.h"
              "log4cplus/hierarchylocker.h"
              "log4cplus/hierarchy.h"
              "log4cplus/fstreams.h"
              "log4cplus/clogger.h"
              "log4cplus/asyncappender.h"
              "log4cplus/version.h"
              "log4cplus/tstring.h"
              "log4cplus/qt5debugappender.h"
              "log4cplus/nullappender.h"
              "log4cplus/fileappender.h"
              "log4cplus/consoleappender.h"
              "log4cplus/clfsappender.h"
              "log4cplus/appender.h"
              "log4cplus/win32debugappender.h"
              "log4cplus/win32consoleappender.h"
              "log4cplus/tracelogger.h"
              "log4cplus/tchar.h"
              "log4cplus/syslogappender.h"
              "log4cplus/initializer.h"
              "log4cplus/configurator.h"
              "log4cplus/config.hxx"
              "log4cplus/thread/threads.h"
              "log4cplus/thread/syncprims.h"
              "log4cplus/thread/syncprims-pub-impl.h"
              "log4cplus/thread/impl/tls.h"
              "log4cplus/thread/impl/threads-impl.h"
              "log4cplus/thread/impl/syncprims-pmsm.h"
              "log4cplus/thread/impl/syncprims-impl.h"
              "log4cplus/thread/impl/syncprims-cxx11.h"
              "log4cplus/spi/rootlogger.h"
              "log4cplus/spi/objectregistry.h"
              "log4cplus/spi/loggingevent.h"
              "log4cplus/spi/loggerimpl.h"
              "log4cplus/spi/loggerfactory.h"
              "log4cplus/spi/filter.h"
              "log4cplus/spi/factory.h"
              "log4cplus/spi/appenderattachable.h"
              "log4cplus/streams.h"
              "log4cplus/internal/socket.h"
              "log4cplus/internal/internal.h"
              "log4cplus/internal/env.h"
              "log4cplus/internal/cygwin-win32.h"
              "log4cplus/helpers/thread-config.h"
              "log4cplus/helpers/socket.h"
              "log4cplus/helpers/pointer.h"
              "log4cplus/helpers/lockfile.h"
              "log4cplus/helpers/connectorthread.h"
              "log4cplus/helpers/timehelper.h"
              "log4cplus/helpers/stringhelper.h"
              "log4cplus/helpers/socketbuffer.h"
              "log4cplus/helpers/snprintf.h"
              "log4cplus/helpers/queue.h"
              "log4cplus/helpers/property.h"
              "log4cplus/helpers/loglog.h"
              "log4cplus/helpers/fileinfo.h"
              "log4cplus/helpers/appenderattachableimpl.h"
              "log4cplus/config/windowsh-inc.h"
              "log4cplus/config/win32.h"
              "log4cplus/config/macosx.h"
              "log4cplus/boost/deviceappender.hxx")))
  (begin
    ;; Add the generated header as it will not be found by file search.
    (append! files (list "log4cplus/config/defines.hxx"))
    (display "before sort:\n")
    (pretty-print files)
    (sort! files string<?)
    (display "after sort:\n")
    (pretty-print files)))

Результат, который я вижу, таков:

before sort:
("log4cplus/socketappender.h"
 "log4cplus/qt4debugappender.h"
 "log4cplus/nteventlogappender.h"
 "log4cplus/ndc.h"
 "log4cplus/msttsappender.h"
 "log4cplus/mdc.h"
 "log4cplus/loglevel.h"
 "log4cplus/loggingmacros.h"
 "log4cplus/logger.h"
 "log4cplus/log4judpappender.h"
 "log4cplus/log4cplus.h"
 "log4cplus/layout.h"
 "log4cplus/hierarchylocker.h"
 "log4cplus/hierarchy.h"
 "log4cplus/fstreams.h"
 "log4cplus/clogger.h"
 "log4cplus/asyncappender.h"
 "log4cplus/version.h"
 "log4cplus/tstring.h"
 "log4cplus/qt5debugappender.h"
 "log4cplus/nullappender.h"
 "log4cplus/fileappender.h"
 "log4cplus/consoleappender.h"
 "log4cplus/clfsappender.h"
 "log4cplus/appender.h"
 "log4cplus/win32debugappender.h"
 "log4cplus/win32consoleappender.h"
 "log4cplus/tracelogger.h"
 "log4cplus/tchar.h"
 "log4cplus/syslogappender.h"
 "log4cplus/initializer.h"
 "log4cplus/configurator.h"
 "log4cplus/config.hxx"
 "log4cplus/thread/threads.h"
 "log4cplus/thread/syncprims.h"
 "log4cplus/thread/syncprims-pub-impl.h"
 "log4cplus/thread/impl/tls.h"
 "log4cplus/thread/impl/threads-impl.h"
 "log4cplus/thread/impl/syncprims-pmsm.h"
 "log4cplus/thread/impl/syncprims-impl.h"
 "log4cplus/thread/impl/syncprims-cxx11.h"
 "log4cplus/spi/rootlogger.h"
 "log4cplus/spi/objectregistry.h"
 "log4cplus/spi/loggingevent.h"
 "log4cplus/spi/loggerimpl.h"
 "log4cplus/spi/loggerfactory.h"
 "log4cplus/spi/filter.h"
 "log4cplus/spi/factory.h"
 "log4cplus/spi/appenderattachable.h"
 "log4cplus/streams.h"
 "log4cplus/internal/socket.h"
 "log4cplus/internal/internal.h"
 "log4cplus/internal/env.h"
 "log4cplus/internal/cygwin-win32.h"
 "log4cplus/helpers/thread-config.h"
 "log4cplus/helpers/socket.h"
 "log4cplus/helpers/pointer.h"
 "log4cplus/helpers/lockfile.h"
 "log4cplus/helpers/connectorthread.h"
 "log4cplus/helpers/timehelper.h"
 "log4cplus/helpers/stringhelper.h"
 "log4cplus/helpers/socketbuffer.h"
 "log4cplus/helpers/snprintf.h"
 "log4cplus/helpers/queue.h"
 "log4cplus/helpers/property.h"
 "log4cplus/helpers/loglog.h"
 "log4cplus/helpers/fileinfo.h"
 "log4cplus/helpers/appenderattachableimpl.h"
 "log4cplus/config/windowsh-inc.h"
 "log4cplus/config/win32.h"
 "log4cplus/config/macosx.h"
 "log4cplus/boost/deviceappender.hxx"
 "log4cplus/config/defines.hxx")
after sort:
("log4cplus/qt4debugappender.h"
 "log4cplus/qt5debugappender.h"
 "log4cplus/socketappender.h"
 "log4cplus/spi/appenderattachable.h"
 "log4cplus/spi/factory.h"
 "log4cplus/spi/filter.h"
 "log4cplus/spi/loggerfactory.h"
 "log4cplus/spi/loggerimpl.h"
 "log4cplus/spi/loggingevent.h"
 "log4cplus/spi/objectregistry.h"
 "log4cplus/spi/rootlogger.h"
 "log4cplus/streams.h"
 "log4cplus/syslogappender.h"
 "log4cplus/tchar.h"
 "log4cplus/thread/impl/syncprims-cxx11.h"
 "log4cplus/thread/impl/syncprims-impl.h"
 "log4cplus/thread/impl/syncprims-pmsm.h"
 "log4cplus/thread/impl/threads-impl.h"
 "log4cplus/thread/impl/tls.h"
 "log4cplus/thread/syncprims-pub-impl.h"
 "log4cplus/thread/syncprims.h"
 "log4cplus/thread/threads.h"
 "log4cplus/tracelogger.h"
 "log4cplus/tstring.h"
 "log4cplus/version.h"
 "log4cplus/win32consoleappender.h"
 "log4cplus/win32debugappender.h")

Как видите, в списке после сортировки отсутствует половина элементов.

Что я делаю неправильно в исходнике схемы?

ОБНОВЛЕНИЕ

Итак, методом проб и ошибок я наткнулся на то, что кажется исправлением. Когда я меняю (sort! files string-ci<?) на (set! files (sort! files string<?)), я получаю желаемый результат. Но я в замешательстве, почему сортировка на месте не работает так, как я ожидаю.


person wilx    schedule 10.02.2015    source источник
comment
почему сортировка на месте не работает, как я ожидаю, sort! не выполняет сортировку на месте. Он возвращает отсортированный список. Разрешено изменять структуру списка, которую вы передаете (любым образом).   -  person Joshua Taylor    schedule 10.02.2015
comment
Кроме того, литеральные данные следует рассматривать как неизменяемые. Эффект изменения литеральных данных не определен и часто не такой, как вы ожидаете. В вашем случае вместо использования '("log4cplus/socketappender.h" ...) просто используйте (list "log4cplus/socketappender.h" ...).   -  person Chris Jester-Young    schedule 11.02.2015


Ответы (1)


Из руководства:

Отсортируйте элементы последовательности, которые могут быть списком или вектором. less используется для сравнения элементов последовательности. Сортировка является деструктивной, это означает, что входная последовательность изменяется для получения отсортированного результата. Это не стабильный сорт.

https://www.gnu.org/software/guile/manual/html_node/Sorting.html

Процедура деструктивна, однако она не обещает, что входная последовательность может быть использована. Поэтому вам всегда нужно использовать возвращаемое значение как отсортированную последовательность.

person Takashi Kato    schedule 10.02.2015
comment
ХОРОШО. Я неправильно понял. Я думал, что это также обновит привязку. Спасибо! - person wilx; 10.02.2015