Определение своих типов.
Задался тут вопросом создать свой тип, вроде того что для денег, но с разным, зараннее заданым колличеством цифр после запятой, и обнаружил что информации по этой теме почти нет, нашел единичный случай тут http://frank.kank.net/essays/options4.html но там все несколько проще, если у кого-нибудь есть соображения по тому, как это лучше делать, а еще лучше исходники - буду благодарен если поделитесь. В особенности как для своего типа определять стандартные операции +-*/ и т.п.
[#]
В общем-то, достаточно сделать структуру данных и функции, выполняющие операции над этими структурами. Операции CL:+, CL:-, CL:*, CL:/ перегрузить не удастся.
[#]
Меня этот вопрос занимал года три назад, но тогда был в лиспе ещё большим лохом и оставил решение задачи на потом. И вот, время пришло :)
[#] Ответ на комментарий от 1349 26.07.2010 05:59
>В общем-то, достаточно сделать структуру данных и функции, выполняющие операции над этими структурами. Операции CL:+, CL:-, CL:*, CL:/ перегрузить не удастся.
Со структурой в общем-то понятно, жаль что стандартные функции доопределить нельзя, было бы красиво, жаль что лисп не предоставляет ничего сверх deftype.
>Меня этот вопрос занимал года три назад, но тогда был в лиспе ещё большим лохом и оставил решение задачи на потом. И вот, время пришло :)
Интересный вариант с set-macro-character внутри себя, но мне кажется это лишнее, мы ведь когда вводим - уже имеем точность в колличестве знаков после запятой, я тут пытался регулярные выражения применять, но тот еще изврат вышел, думаю надо искать путь проще :)
Вот кстати классы типов, нелюбимого некоторыми хаскеля, тут рулят и педалят. Попробую поломать голову еще денек.
[#] Ответ на комментарий от 1349 26.07.2010 05:59
> И вот, время пришло :)
[#] Ответ на комментарий от cvb 26.07.2010 11:13
> Со структурой в общем-то понятно, жаль что стандартные функции доопределить нельзя, было бы красиво
Не было бы, это же не C++ ;) Собственно, ведь и пресловутая перегрузка операторов в C++ не нашла поклонников за пределами C++, а CL это совсем другой язык, с другой идеологией.
> жаль что лисп не предоставляет ничего сверх deftype.
Хм, а что нужно то? Есть defclass, а deftype я вообще никогда не использую, ибо это скорей нужно для оптимизации, чем для чего-либо ещё.
[#] Ответ на комментарий от archimag 26.07.2010 12:47
>Не было бы, это же не C++ ;) Собственно, ведь и пресловутая перегрузка операторов в C++ не нашла поклонников за пределами C++, а CL это совсем другой язык, с другой идеологией.
Оно понятно, но согласись (+ $1.12 $23.45) выглядит лучше чем (m+ $1.12 $23.45). Да и тут бы с++овый подход сработал, будь + generic функцией, специализировал бы ее нужными типами и все, но наверно тормозило бы.
[#] Ответ на комментарий от cvb 26.07.2010 13:13
> Оно понятно, но согласись (+ $1.12 $23.45) выглядит лучше чем (m+ $1.12 $23.45)
Не согласен. Особенно в случае, когда вместо явных значений фигурируют переменные. Вызов m+ ясно и однозначно показывает, что именно происходит. Кроме достаточно сомнительных соображений Страуструпа о том, что язык должен давать возможность создавать типы, неотличимые от встроенных, другого обоснования у данной идеи (перегрузки в стиле C++) нет. Как ни посмотри, а m+ лучше (ну только назвать лучше как-нибудь более вменяемо). Какого-либо ощутимого профита перегрузка не даёт, а проблем порождает массу.
[#] Ответ на комментарий от archimag 26.07.2010 13:49
Ладно, этот спор философский и ни к чему не ведет. Поковыряв немного я приделал функцию для чтения своего типа без указания точности явно и на этом пока успокоюсь, лучше скажи, сохраненный код у тебя долго хранится, расчитывать на то что когда оно понадобится оно тут будет?
[#] Ответ на комментарий от cvb 26.07.2010 11:13
> Интересный вариант с set-macro-character внутри себя, но мне кажется это
лишнее, мы ведь когда вводим - уже имеем точность в колличестве знаков
после запятой
Мы вводим текстовое представление. Когда парсер его считает и приведёт к внутреннему IEEE754 представлению, то 10.12 из текста программы легко превращается в 10.11999999999 или 10.1200000001.
> Что-то я не уловил смысла финта с затенением (shadow) символов из common-lisp: более менее "естественно" это будет выглядеть только внутри данного пакету, а снаружи будет смотреться несколько странно и сбивать с толку новичков, ибо понять разницу между common-lisp:* и mypackage:* может оказаться не так просто. В общем, здесь нужно просто писать функции типа money+, money* и т.п
s/нужно/можно/, да? :)
> Оно понятно, но согласись (+ $1.12 $23.45) выглядит лучше чем (m+ $1.12 $23.45). Да и тут бы с++овый подход сработал, будь + generic функцией, специализировал бы ее нужными типами и все, но наверно тормозило бы.
Можно + и дженериком сделать.
Мы вводим текстовое представление. Когда парсер его считает и приведёт к внутреннему IEEE754 представлению, то 10.12 из текста программы легко превращается в 10.11999999999 или 10.1200000001.
> Что-то я не уловил смысла финта с затенением (shadow) символов из common-lisp: более менее "естественно" это будет выглядеть только внутри данного пакету, а снаружи будет смотреться несколько странно и сбивать с толку новичков, ибо понять разницу между common-lisp:* и mypackage:* может оказаться не так просто. В общем, здесь нужно просто писать функции типа money+, money* и т.п
s/нужно/можно/, да? :)
> Оно понятно, но согласись (+ $1.12 $23.45) выглядит лучше чем (m+ $1.12 $23.45). Да и тут бы с++овый подход сработал, будь + generic функцией, специализировал бы ее нужными типами и все, но наверно тормозило бы.
Можно + и дженериком сделать.
[#] Ответ на комментарий от cvb 26.07.2010 14:57
> http://lisper.ru/apps/format/150 - сам код
Т.е. для единицы с точностью 8 знаков после запятой придётся вводить 1.00000000?
Т.е. для единицы с точностью 8 знаков после запятой придётся вводить 1.00000000?
[#] Ответ на комментарий от cvb 26.07.2010 14:57
> лучше скажи, сохраненный код у тебя долго хранится
Ну, никакого удаления устаревших записей и т.п. здесь нет. Будет храниться до тех пор, пока храниться :))
> расчитывать на то что когда оно понадобится оно тут будет?
Специально для этого люди придумали системы контроля версий и всякие публичные хостинги для них ;)
[#] Ответ на комментарий от 1349 26.07.2010 15:01
> s/нужно/можно/, да? :)
Нет :) У нас и так избыток толерантности, немного категоричности не помешает...
[#] Ответ на комментарий от 1349 26.07.2010 15:04
>Т.е. для единицы с точностью 8 знаков после запятой придётся вводить 1.00000000?
Ну да, либо прямо создать структуру, зато для 0-4 знаков выглядит вполне. И у нас гарантированно будет тоже самое число, потому как никаких флоатов. А вот в твоем варианте бага)
$0.32345678'8 -> (32345680 . 8)
>Специально для этого люди придумали системы контроля версий и всякие публичные хостинги для них ;)
Не, они не удобны если надо 10 строк сохранить, по хорошему бы надо свой пакет с утилитами заводить и туда все такое сливать, но чего-то мне лень)
[#] Ответ на комментарий от cvb 26.07.2010 15:43
> Не, они не удобны если надо 10 строк сохранить
Да им всё равно, сколько сохранять ;)
> по хорошему бы надо свой пакет с утилитами заводить и туда все такое сливать
Хм, а в каком контексте появился тогда вопрос? Т.е. если есть какой-то проект и где он нужен, то там и сохранять?
> чего-то мне лень)
А с ленью вообще надо бороться всеми доступными методами ;)
[#] Ответ на комментарий от cvb 26.07.2010 15:43
> А вот в твоем варианте бага)
> $0.32345678'8 -> (32345680 . 8)
Ну так вот это и есть то пресловутое зло в виде IEEE754 :) $0.32345678d0'8
Ну так вот это и есть то пресловутое зло в виде IEEE754 :) $0.32345678d0'8
[#] Ответ на комментарий от archimag 26.07.2010 16:02
>Да им всё равно, сколько сохранять ;)
Ну этож проект там заводить, ну или у себя, в общем надо шевелиться.
>Хм, а в каком контексте появился тогда вопрос? Т.е. если есть какой-то проект и где он нужен, то там и сохранять?
Это мне понадобится, но в некотором светлом будущем, я просто кружку мыл и вот чего-то в голову мысль про типы залезла, пришлось писать.
>Ну так вот это и есть то пресловутое зло в виде IEEE754 :) $0.32345678d0'8
Еслиб не это зло и тип такой был бы ненужен считай в волю и не заморачивайся со всякими макросами. Но у меня вот еще вопрос возник, можно ли заставить лисп печатать по человечески твой вариант, имею ввиду аналог :print-function для структур? Я собственно структуру только из-за него и использовал.
[#] Ответ на комментарий от cvb 26.07.2010 16:33
> Но у меня вот еще вопрос возник, можно ли заставить лисп печатать по
человечески твой вариант, имею ввиду аналог :print-function для
структур? Я собственно структуру только из-за него и использовал.
Неа.
Неа.
[#] Ответ на комментарий от cvb 26.07.2010 15:43
>Не, они не удобны если надо 10 строк сохранить
На github есть сервис gist, который предоставляет очень удобные средства хранения маленьких кусочков кода и даже нескольких файлов. Причем сохраняются они в git-репозитории, но с удобным веб-интерфейсом.
[#] Ответ на комментарий от 1349 26.07.2010 05:59
Кстати, давно хотел, да не знаю как, сделать нечто вроде
(let ((*readtable* (copy-readtable)))
(set-macro-character ... )
(set-macro-character ... )
для точки. Ну, то есть: $12.34 - макрочары подчёркнуты. Вообще, сложилось впечатление, что в cl символ #\. занимает некое особое место, потому что (defvar ... 34) - "too many dots".
[#] Ответ на комментарий от dmitry_vk 26.07.2010 21:08
>На github есть сервис gist, который предоставляет очень удобные средства хранения маленьких кусочков кода и даже нескольких файлов. Причем сохраняются они в git-репозитории, но с удобным веб-интерфейсом.
Религия не позволяет, я уже в секте hg, а в храме гуглокода такой фичи нет :) Попробую этой фичей попользоваться, хотя по сути и pastebin бы хватило мне.
>Ну, то есть: $12.34 - макрочары подчёркнуты.
Одна из моих реализаций кода выше делала #\. макрочаром, как в коде 1349 делалась #\' никаких проблем не заметил.
[#] Ответ на комментарий от cvb 27.07.2010 17:27
> Религия не позволяет, я уже в секте hg
Ну, с этим надо что-то делать, ибо в мире CL поклонников hg, слава богу, особо не замечено и git это стандарт де-факто (а darcs тяжёлый пережиток прошлого).
[#] Ответ на комментарий от archimag 27.07.2010 17:35
>Ну, с этим надо что-то делать, ибо в мире CL поклонников hg, слава богу, особо не замечено и git это стандарт де-факто (а darcs тяжёлый пережиток прошлого).
Вот когда появится у gitа убер серебрянная килер фича, тогда я подумаю переводить ли мне на него весь ворох своих репозитариев, а пока посижу на hg.
[#] Ответ на комментарий от cvb 27.07.2010 19:34
> а пока посижу на hg.
Один, а на github или gitorious мог бы сидеть не один, твой код может бы кто ещё увидел ;) Тут дело не в киллер-фичах, а в сообществе.
[#] Ответ на комментарий от archimag 27.07.2010 19:50
Та какая разница, если будут гуглить и там и там найдут. Да и особо полезного кода для сообщества у меня нет)
[#] Ответ на комментарий от 1349 26.07.2010 18:55
>> Но у меня вот еще вопрос возник, можно ли заставить лисп печатать по
человечески твой вариант, имею ввиду аналог :print-function для
структур? Я собственно структуру только из-за него и использовал.
> Неа.
Вообще говоря, можно. Если *print-pretty* t, то можно свой диспатчер на типы вешать:
(defun print-money (s r colon? atsign?)
...)
(setq *print-pprint-dispatch* (copy-pprint-dispatch nil))
(set-pprint-dispatch 'money (formatter "~/print-money/") 1)
> Неа.
Вообще говоря, можно. Если *print-pretty* t, то можно свой диспатчер на типы вешать:
(defun print-money (s r colon? atsign?)
...)
(setq *print-pprint-dispatch* (copy-pprint-dispatch nil))
(set-pprint-dispatch 'money (formatter "~/print-money/") 1)
[#] Ответ на комментарий от 1349 01.08.2010 09:54
Да у меня этот pretty-printer в ccl и так непонятно как работает.
Я тут случайно когда уже почти решился довести сабж до вменяемой библиотеки как-то нагугли аж две похожие либы для лиспа:
одна - cambl http://github.com/jwiegley/cambl она заводится но надо чуть подпилить, работает с деньгами, функционал так себе, но на базе нее можно уже и что-то покруче сделать.
еще одна - древнее как говно мамонта measures http://www.cs.cmu.edu/afs/cs/project/ai-repository/ai/lang/lisp/code/syntax/measures/ с виду она посерьезней, но завести не удалось пока, она еще с тех бородатых времен заброшена, когда clos считалась острием прогресса, судя по всему, но допилить ее интересно.
[#] Ответ на комментарий от cvb 05.08.2010 17:46
В общем как-то так получилось что я написал еще одну либу для денег, тут http://code.google.com/p/cl-money-type/ от тех что я писал выше ее отличает простота кода и его прозрачность, ну и конечно отсутствие вороха фич которыми всеравно непонятно как пользоваться.
[#] Ответ на комментарий от cvb 09.08.2010 18:12
Кстати, что это за фича в hg которая не позволяет юзать git?
[#] Ответ на комментарий от treep 09.08.2010 20:17
>Кстати, что это за фича в hg которая не позволяет юзать git?
Лень :)
Ну и еще отсутствие в git килер фич по отношению к первому, тоесть по мне - они эквивалентны, но hg я уже использую.
[#] Ответ на комментарий от cvb 09.08.2010 20:58
Для меня основная киллер-фича гита в том, что он просто работает, и работает довольно гладко.
Текущий список моих претензий к меркуриалу:
Текущий список моих претензий к меркуриалу:
- Не дружит с юникодом. Нельзя одновременно использовать под виндой и под линуксом - без плясок с бубном на виндовой стороне (которые должны быть проведены на всех машинах заранее, до начала использования) кракозяблики в именах файлов гарантированы
- Нет той безопасности, которая есть с гитом. Любой неправильно сделанный rebase в меркуриале фатален для данных, а в гите всегда есть reflog
- Бранчи не такие, как в гите. Нельзя отбранчеваться по факту, а надо бранчеваться заранее (т.к. информация о бранче прописана в коммите, а не в метке). Все бранчи глобальные и называются везде одинаково => лишняя головная боль при распределенной разработке (т.к. внешние разработчики не могут выбирать такие имена для бранчей, какие захотят).
- Скорость, скорость, еще раз скорость.
- "Легкость" интерфейса позволяет "жонглировать" патчами, изменениями и бранчами, чтобы привести репозиторий в нужный, хороший вид.
[#] Ответ на комментарий от dmitry_vk 09.08.2010 21:45
Ну вот сразу бы так сказали, хотя на своем опыте я ни с одной проблемой из этих пока не столкнулся, небыло условий, но информация к размышлению теперь есть, чего-нибудь следующее попробую сделать под git'ом.
>Нельзя одновременно использовать под виндой и под линуксом - без плясок с бубном на виндовой стороне (которые должны быть проведены на всех машинах заранее, до начала использования) кракозяблики в именах файлов гарантированы
А на лоре говорили что hg на винде беспроблемней gita)