Как печатать символы, отличные от ascii, в SBCL Common Lisp

Предполагая, что такой символ хранится в переменной character, как мне его напечатать? Например GREEK_SMALL_LETTER_XI с кодом 958.

(format t "~a" character) просто дал бы ?


person Community    schedule 03.02.2017    source источник
comment
Символ печатается правильно (ξ) как в emacs+slime с CCL, так и в терминале с SBCL, как в Linux, так и в Mac OS X. Какая у вас среда (операционная система, реализация Lisp, терминал/редактор)?   -  person Renzo    schedule 04.02.2017
comment
Windows 8.1, SBCL. После вашего комментария я написал (let ((character (code-char 958)))(format t "~a" character)) в REPL (открытый sbcl.exe), и он вернул ? новую строку NIL   -  person    schedule 04.02.2017
comment
Я думаю, что это проблема с вашим терминалом, а не обычная проблема с шепелявостью. Может ли ваш терминал печатать греческие буквы, когда вы вводите в Windows эквивалент cat file-with-greek-letters.txt?   -  person tsikov    schedule 04.02.2017
comment
Вы, кажется, правы. Я попробовал type PATH-TO-FILE, и на выходе была строка каких-то странных символов. Возможно, я просто установлю линукс.   -  person    schedule 04.02.2017
comment
@PrzemysławP Возможно, эта ветка может вам помочь: stackoverflow.com/questions/388490/ Удачи :)   -  person tsikov    schedule 05.02.2017
comment
Спасибо всем за ваши ответы.   -  person    schedule 06.02.2017


Ответы (1)


ОП упомянул в комментарии, что он переходит на Linux. В SBCL 1.4.15.Debian (и я предполагаю, что в других Linux) символы Unicode печатаются только как символы (в отличие от кодов) функцией (формат), а не (печать).

Пример:

(print (code-char 26159)) produces "#\U662F"

который является юникодным индексом символа.

пока

(format T "~a" (code-char 26159)) produces "是"
person freeB    schedule 13.01.2019
comment
Это потому, что print здесь печатает символ и делает это читаемым (читателем Лиспа) по умолчанию. С другой стороны, формат производит вывод в соответствии с заданным строковым шаблоном. Оба примера верны. - person Svante; 15.01.2019
comment
ТАК остановил меня от редактирования моего комментария. Я попробую еще раз. Print не печатает китайские (и я предполагаю, что другие Unicode) символы правильно (он печатает код, а не символ). Однако он правильно печатает символы, попадающие в западноевропейский блок ASCII (для них он печатает символ). Это не имеет большого значения, так как lisp предоставляет функцию (format). Тем не менее, я изменил ответ, поскольку все, что важно, это то, что читатели знают, какую функцию использовать, а определение «правильного» может вызвать споры о том, «что такое символ». - person freeB; 15.01.2019
comment
Нет. Вывод print для символа представляет собой печатное представление этого символа, так что read будет читать его как тот же самый символ. Если бы print вывел строку 是, то read прочитал бы из нее символ с именем 是. Символ не является строкой и не является символом. Во всяком случае, вы можете ожидать, что print выведет #\是, но это зависит от прямой поддержки юникода на стороне чтения. См. CLHS для print, *print-escape*, *print-readably* и раздел 22.1.3.2 (Печать символов) и дополнительную информацию, связанную оттуда. - person Svante; 16.01.2019
comment
Нет, не в этом дело. Дело в том, что print производит вывод для read, а format производит вывод для людей (для которых различие между символами и строками часто не очень важно). Read не заботится об эстетике. Экранирование просто делает вывод независимым от проблем с кодированием, и read не заботится о внешнем виде. - person Svante; 16.01.2019
comment
@Svante Я думаю, что это уже было сделано и принято. Я думаю, что немного глупо говорить, что «write предназначен для машин для read, а format используется для людей», потому что люди часто читают вывод write в repl, в отладчике и т. д., так что это, вероятно, плохо для него. не быть легко читаемым человеком. @freeB sbcl решает напечатать символ либо с Unicode, либо с формой имени, если это не standard-char-p и graphic-char-p, что в основном означает печатный ascii. Я думаю, было бы неплохо, если бы был переключатель, разрешающий печатать Unicode. - person Dan Robertson; 21.01.2019
comment
@DanRobertson: я написал о print, а не о write. Print явно настроен для создания readтекста. Теперь представьте, что он выводит символ в кодировке UTF-8, который затем получает read реализацией, работающей в Windows и ожидающей кодировку Cp-1272. облом. - person Svante; 21.01.2019
comment
@Дэн Робертсон. Переключатель, определяющий формат оператора печати, — отличная идея, и он был бы очень полезен, по крайней мере, для некоторых пользователей. Unicode — это движущаяся цель, и я предполагаю, что его реализация и обработка требуют сложных дизайнерских решений на языке общего назначения, таком как Lisp. Я ценю комментарии от вас и Сванте, которые меня кое-чему научили. - person freeB; 21.01.2019
comment
@Svante, конечно, но print по сути такой же, как write, но с *print-readably* установленным на t, новой строкой перед и пробелом после. Я ценю, что печать в ascii была выбрана, потому что некоторые системы (например, выполнение fileio на консоли в Windows вместо consoleio) борются с Unicode, а также есть проблемы с кодировкой (например, utf-8 и подобные), но уже есть проблемы с переносимостью внутри ascii из разных концов строк. Я не думаю, что совместимость со сломанными системами является веской причиной для того, чтобы repl/debugger полностью скрывал символы, которые у него есть. - person Dan Robertson; 21.01.2019
comment
@DanRobertson: Точно, print — это ярлык для выполнения write readграмотно. Я вижу в этом очень явное намерение и считаю, что этому намерению следует следовать как можно точнее. - person Svante; 21.01.2019