Здравствуйте, Кодт, Вы писали: К>Зачем тогда отказались от лисповского nil? Чтобы не путать с пустым списком?
Я так понимаю, #f было введено как универсальное "пустое" значение, которое можно возвращать как признак ошибки/неудачи. Например, при поиске первого подходящего элемента в списке — как еще различить 2 случая "критерию не удовлетворяет ни один элемент" и "первым элементом, удовлетворяющим критерию, является пустой список"?
К>И тут же стали путать списки с #t.
Почему же путать? Для того, чтобы различать объекты разных типов, есть соответствующие предикаты: boolean?, list? и т.п. А if и логические операции различают только #f и "не #f".
Здравствуйте, Mr.Cat, Вы писали: MC>Я так понимаю, #f было введено как универсальное "пустое" значение, которое можно возвращать как признак ошибки/неудачи.
Т.е. я хотел сказать, что пустой список Сассмана/whoever в роли такого значения почему-то не устраивал — потому и ввели новое.
Здравствуйте, Mr.Cat, Вы писали:
К>>Зачем тогда отказались от лисповского nil? Чтобы не путать с пустым списком? MC>Я так понимаю, #f было введено как универсальное "пустое" значение, которое можно возвращать как признак ошибки/неудачи. Например, при поиске первого подходящего элемента в списке — как еще различить 2 случая "критерию не удовлетворяет ни один элемент" и "первым элементом, удовлетворяющим критерию, является пустой список"?
Хе, а если первым элементом, удовлетворяющим критерию, будет элемент "f#"?
Нет уж, тут нужен Maybe или нечто подобное.
Вспомнился анекдот.
— Скажи, как переводится с английского "I don't know"?
— "Я не знаю".
— Ну вот... никто не знает...
К>>И тут же стали путать списки с #t. MC>Почему же путать? Для того, чтобы различать объекты разных типов, есть соответствующие предикаты: boolean?, list? и т.п. А if и логические операции различают только #f и "не #f".
Вот потому и путать: переменная или функция содержит список, а его истолковали как булевское значение. (Только в лиспе и в схеме эта трактовка различается).
В этом плане, скажем, питон дружественнее: там приведение к булю основано на смысле.
Ложью считаются
— нули всех числовых типов
— атом None (нулевой указатель)
— пустые контейнеры (списки, кортежи, строки, словари)
В лиспе смысл был примерно тот же, но он оказался замаскирован дурным минимализмом. То есть непонятно стало — то ли мы приравниваем "пусто" к "ложно", то ли тупо сэкономили на одном атоме (для "истина", однако, ввели атом t).
Кодт,
К>Хе, а если первым элементом, удовлетворяющим критерию, будет элемент "f#"? К>Нет уж, тут нужен Maybe или нечто подобное.
В реализации монад (гы-гы) на Схеме мне встретился даже такой изврат:
(define fail (vector 'fail))
Такое значение будет не eq? любому другому. Ну конечно до тех пор, пока кто-нибудь не переопределит eq? подходящим образом
К>Вспомнился анекдот. К>- Скажи, как переводится с английского "I don't know"? К>- "Я не знаю". К>- Ну вот... никто не знает...
English variation:
(We take you now to the Oval Office.)
George: Condi! Nice to see you. What's happening?
Condi: Sir, I have the report here about the new leader of China.
George: Great. Lay it on me.
Condi: Hu is the new leader of China.
George: That's what I want to know.
Condi: That's what I'm telling you.
George: That's what I'm asking you. Who is the new leader of China?
Condi: Yes.
George: I mean the fellow's name.
Condi: Hu.
George: The guy in China.
Condi: Hu.
George: The new leader of China.
Condi: Hu.
George: The Chinaman!
Condi: Hu is leading China.
George: Now whaddya' asking me for?
Condi: I'm telling you Hu is leading China.
George: Well, I'm asking you. Who is leading China?
Condi: That's the man's name.
George: That's who's name?
Condi: Yes.
George: Will you or will you not tell me the name of the new leader of China?
Condi: Yes, sir.
George: Yassir? Yassir Arafat is in China? I thought he was in the Middle East.
Condi: That's correct.
George: Then who is in China?
Condi: Yes, sir.
George: Yassir is in China?
Condi: No, sir.
George: Then who is?
Condi: Yes, sir.
George: Yassir?
Condi: No, sir.
George: Look, Condi. I need to know the name of the new leader of China. Get me the Secretary General of the U.N. on the phone.
Condi: Kofi?
George: No, thanks.
Condi: You want Kofi?
George: No.
Condi: You don't want Kofi.
George: No. But now that you mention it, I could use a glass of milk. And then get me the U.N.
Condi: Yes, sir.
George: Not Yassir! The guy at the U.N.
Condi: Kofi?
George: Milk! Will you please make the call?
Condi: And call who?
George: Who is the guy at the U.N?
Condi: Hu is the guy in China.
George: Will you stay out of China?!
Condi: Yes, sir.
George: And stay out of the Middle East! Just get me the guy at the U.N.
Condi: Kofi.
George: All right! With cream and two sugars. Now get on the phone.
(Condi picks up the phone.)
Condi: Rice, here.
George: Rice? Good idea. And a couple of egg rolls, too. Maybe we should send some to the guy in China. And the Middle East. Can you get Chinese food in the Middle East?
К>>>И тут же стали путать списки с #t. MC>>Почему же путать? Для того, чтобы различать объекты разных типов, есть соответствующие предикаты: boolean?, list? и т.п. А if и логические операции различают только #f и "не #f".
К>Вот потому и путать: переменная или функция содержит список, а его истолковали как булевское значение. (Только в лиспе и в схеме эта трактовка различается).
К>В этом плане, скажем, питон дружественнее: там приведение к булю основано на смысле. К>Ложью считаются К>- нули всех числовых типов К>- атом None (нулевой указатель) К>- пустые контейнеры (списки, кортежи, строки, словари)
К>В лиспе смысл был примерно тот же, но он оказался замаскирован дурным минимализмом. То есть непонятно стало — то ли мы приравниваем "пусто" к "ложно", то ли тупо сэкономили на одном атоме (для "истина", однако, ввели атом t).
Я категорически против того, чтобы считать пустой список за #f. Приведу пример: мы читаем из xml
и формируем список '(42292 42298 42300), если xml будет просто <UnreadMessages/>, то сформируется пустой список. В любом случае список на выходе — это сигнал о том, что чтение было успешно, а вот если чего-то обвалилось, то пожалуйста на этот счёт есть #f.
Здравствуйте, Кодт, Вы писали: К>Хе, а если первым элементом, удовлетворяющим критерию, будет элемент "f#"?
Ну вот почему-то Сассман (или кто там) решил, что #f можно сделать козлом отпущения.
К>Нет уж, тут нужен Maybe или нечто подобное.
Ну так пожалуйста — можно возвращать этот самый Maybe — пару "#t, значение", либо "#f, диагностика-ошибки". Но вот надо ли?
К>Вот потому и путать: переменная или функция содержит список, а его истолковали как булевское значение. (Только в лиспе и в схеме эта трактовка различается). К>В этом плане, скажем, питон дружественнее: там приведение к булю основано на смысле.
Честно говоря, меня устраивают оба варианта.
Здравствуйте, Lazy Cjow Rhrr, Вы писали:
К>>Нет уж, тут нужен Maybe или нечто подобное.
LCR>В реализации монад (гы-гы) на Схеме мне встретился даже такой изврат: LCR>
LCR>(define fail (vector 'fail))
LCR>
LCR>Такое значение будет не eq? любому другому. Ну конечно до тех пор, пока кто-нибудь не переопределит eq? подходящим образом
И как его диагностировать? Типа, уж послала так послала?
Впрочем, элементарно-ватсон! Где-то недавно проскакивала тема — как проверять на равенство NaN, при том, что на нём равенство тоже сломано.
(define fail? (x) (not (eq? x x)))
LCR>Я категорически против того, чтобы считать пустой список за #f. Приведу пример: мы читаем из xml LCR>
LCR>и формируем список '(42292 42298 42300), если xml будет просто <UnreadMessages/>, то сформируется пустой список. В любом случае список на выходе — это сигнал о том, что чтение было успешно, а вот если чего-то обвалилось, то пожалуйста на этот счёт есть #f.
И снова Maybe. Не надо валить в одну кучу значения и сигналы.
По той же самой причине, если неаккуратно кодировать, можно нарваться на проблемы с русской буквой 'я' в Си.
char c;
while(true)
{
c = getchar(); // прочитали символ либо признак конца/ошибки - int getchar(void)if(c == EOF) break; // EOF - это (int)-1
printf("<%02X>", (unsigned char)c); // вывели в hex-формате, например
}
Правда, в Си возвращаемый тип заведомо шире и позволяет выразить и то и другое.
Что касается твоего списка, то напрашивается очень простой ответ. Нужно возвращать список списков.
<Messages><int>1</int><int>2</int></Messages> ---> '((1 2))
<Messages></Messages> ---> '(())
<Messages><int>1</int></Messages><Messages><int>2</int></Messages> ---> '((1) (2)) - если это в принципе допустимо
пусто/облом ---> '() - он же nil
Здравствуйте, Кодт, Вы писали: К>И как его диагностировать? Типа, уж послала так послала? К>Впрочем, элементарно-ватсон! Где-то недавно проскакивала тема — как проверять на равенство NaN, при том, что на нём равенство тоже сломано. К>
К>(define fail? (x) (not (eq? x x)))
К>
Да eq? (eqv? и equal?) по-моему, сломаны by design.
Здравствуйте, Mr.Cat, Вы писали:
MC>Да eq? (eqv? и equal?) по-моему, сломаны by design.
Я не про nan, я про fail говорил. Если для fail не выполняется eq? сам себе, то... "если фортуна повернулась к вам задом, не расстраивайтесь, а воспользуйтесь".
Здравствуйте, Кодт, Вы писали:
К>И как его диагностировать? Типа, уж послала так послала? К>Впрочем, элементарно-ватсон! Где-то недавно проскакивала тема — как проверять на равенство NaN, при том, что на нём равенство тоже сломано. К>
Кодт,
К>Что касается твоего списка, то напрашивается очень простой ответ. Нужно возвращать список списков. К>
К><Messages><int>1</int><int>2</int></Messages> ---> '((1 2))
К><Messages></Messages> ---> '(())
К><Messages><int>1</int></Messages>
К><Messages><int>2</int></Messages> ---> '((1) (2)) - если это в принципе допустимо
К>пусто/облом ---> '() - он же nil
К>
К>Вполне себе maybe.
Ну конечно, ты решаешь проблему выше введением дополнительного слоя абстракции. Любую проблему можно так решить (за некоторым исключением). Просто получается чуть менее удобно — потом придётся выковыривать само значение:
(let ((l (parse xml))
(if l ; типа рассматривает пустой список как ложь
(do-stuff-with (car l)) ; фи!
(display "try again"))))
Хаскель спасает то, что такие слова как let, in, data и т.п. являются зарезервированными, и поэтому никто не может ничего изменить, и поэтому Maybe кажется таким незыблемым — Nothing — это Nothing, Just — это Just, и паттерн-матчинг работает как всегда работал. А вот в условиях "повышенной гибкости" ничего такого нет, поэтому любое предопределённое поведение можно изменить:
(define if (lambda (x y z) 'omg))
(display (if 1 2 3)) ; выведет omg
Следоветельно и любое определение Maybe не железобетонно. Конечно, никто специально не отстреливает себе выступающие части тела, переопределяя ради прикола стандартные формы, однако лисперам/схемерам нравится само существование возможности переопределить всё нахрен.
LCR>Хаскель спасает то, что такие слова как let, in, data и т.п. являются зарезервированными, и поэтому никто не может ничего изменить, и поэтому Maybe кажется таким незыблемым — Nothing — это Nothing, Just — это Just, и паттерн-матчинг работает как всегда работал. А вот в условиях "повышенной гибкости" ничего такого нет, поэтому любое предопределённое поведение можно изменить: LCR>
LCR> (define if (lambda (x y z) 'omg))
LCR> (display (if 1 2 3)) ; выведет omg
LCR>
LCR>Следоветельно и любое определение Maybe не железобетонно. Конечно, никто специально не отстреливает себе выступающие части тела, переопределяя ради прикола стандартные формы, однако лисперам/схемерам нравится само существование возможности переопределить всё нахрен.