在 Guile 中对列表进行排序时项目消失

Items disapear when `sort!`'ing a list in 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")

如您所见,排序后的列表丢失了一半的项目。

我在 Scheme 源代码中做错了什么?

更新

因此,通过反复试验,我偶然发现了似乎可以解决的问题。当我将 (sort! files string-ci<?) 更改为 (set! files (sort! files string<?)) 时,我得到了想要的结果。但是我很困惑,为什么就地排序没有像我预期的那样工作。

来自手册:

Sort the sequence items, which may be a list or a vector. less is used for comparing the sequence elements. The sorting is destructive, that means that the input sequence is modified to produce the sorted result. This is not a stable sort.

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

该程序具有破坏性,但不保证输入序列可用。所以你总是需要使用返回值作为排序序列。