LINUX.ORG.RU

Не учите Common Lisp!

 ,


1

7

Хочу предостеречь форумчан от изучения Common Lisp. Возьмите самую лучшую имплементацию — SBCL и скомпилируйте следуюущие лямбды:

;; Взятие элемента по индексу x из массива x
(lambda (x) (aref x x))
;; Взятие элемента по индексу y из массива x и прибавление к x
(lambda (x y) (+ x (aref x y)))
;; Один из путей выполнения: прибавление X к NIL
(lambda (x y) (+ x (funcall (lambda (x) (if x 0 x)) y)))

Ни на одной из этих бессмысленных функций компилятор не ругнётся. Вы скажете: «А что такого? Это же язык с динамической типизацией!» А то, что если вы хотите хоть насколько нибудь быстрого кода, вам нужно делать какие-то утверждения о типах, производя только лишь статический анализ кода.

Минус коммон лиспа как языка — слишком разрешательский стандарт. Почти сплошь и рядом там фразы вроде «Эффект, производимый объявлением inline, определяется реализацией» или «Реализация вольна игнорировать то-то и вместо этого делать то-то». Из-за этого разработчики того же SBCL будут игнорировать твои баг репорты, где из-за неправильного поведения компилятора (с точки других опубликованных алгоритмов) твой код будет работать раза в 2 или 3 медленнее, чем должен бы.

Написали бы в стандарте «реализация ДОЛЖНА поступать так-то и так-то», и можно было бы тыкать разрабов носом в это место и требовать корректного поведения. А раз написали «реализация может делать, что ей захочется», то и прижучить их нельзя. В итоге все занимаются чем хотят, кроме починки багов.

Короче, учите языки с хорошей теоретической базой и статической типизацией. Байкам @lovesan не верьте ни одной.



Последнее исправление: dura4ok11 (всего исправлений: 1)
Ответ на: комментарий от monk

То. Пишу car, работает, пишу cdr, работает. Пишу, length, не работает.

Странно. У меня length работает.

Я перевёл твой странный код с лиспа на хачкель и всё. Идея целиком твоя.

Не было в моей идее никакого Either. Он там лишний.

В твоём лисповом коде именно это и было – проверка на конец списка специальным тегом. Я её закодировал для тебя в типы, потому что ты это сделать не осилил.

Ну нету в Хаскеле ни диапазонных типов, ни ограниченных списков (в смысле, «строка до 50 символов»),

Есть. Смотри refined types.

Полдюжины библиотек для работы с вариантными типами намекают.

Ичо? Тебя смущает, что на хаскелле можно библиотеку написать, что ли? Или на что они тебе намекают-то?

hateyoufeel ★★★★★
()
Ответ на: комментарий от monk

Зачем для алгоритма, вычисляющего длину списка тип значения элемента списка?

Всё ещё не понимаю вот этого аргумента. length из стандартной библиотеки работает со списками любых типов, но ты мне тут пытаешься доказать что не работает. Дядя, ты чего? Что за херню ты тут несёшь-то вообще?

hateyoufeel ★★★★★
()
Последнее исправление: hateyoufeel (всего исправлений: 1)
Ответ на: комментарий от hateyoufeel

моя последняя коммерческая программа на Лиспе - интерфейс для работы с одной кастомной нейроннной сетью с приложением. 3 года назад попросили переписать хотя бы на Go тк те кто продолжают заниматься этим говорят что лисп там оверкил и разработка идёт медленно. Ниасилили, бывает. Переписал им все на Go и дело пошло.

Это не реклама го, тут скорее антиреклама текущего уровня разрабов которые лучше будут ковырять тайпскрипт и гошечку тк это «изи мани».

Хотя, я сам не без греха, пишу часть работы на PHP как типичная макака и довольно урчу.

Obezyan
()
Последнее исправление: Obezyan (всего исправлений: 1)
Ответ на: комментарий от Obezyan

Это не реклама го, тут скорее антиреклама текущего уровня разрабов которые лучше будут ковырять тайпскрипт и гошечку тк это «изи мани».

А что плохого-то? Если с лиспом работу днём с огнём не сыщешь, ясен хер его трогать будут только аутисты, которым это по фану. Вообще ничего удивительного.

Другой вопрос, что, конечно же, говнокод у них получается тот ещё, доказано 50-мегабайтовыми блобами на JS, скачиваемыми моим браузером с некоторых сцайтов (jira хехехе). Но я не уверен, что те же самые люди родили бы на лиспе что-то приличнее.

hateyoufeel ★★★★★
()
Последнее исправление: hateyoufeel (всего исправлений: 1)
Ответ на: комментарий от hateyoufeel

Я имел ввиду что лисп не используется в работе не из-за его сложности (он простой как бейсик практически), а из-за сложности его восприятия новыми поколениям программистов. С ним думать надо глубже, что ли, это сейчас не очень в почете.

Это же причина расцвета js/ts и go.

Obezyan
()
Последнее исправление: Obezyan (всего исправлений: 1)
Ответ на: комментарий от hateyoufeel

Странно. У меня length работает.

Только с дополнительным ограничением на тип первого поля.

Я её закодировал для тебя в типы, потому что ты это сделать не осилил.

Он в лиспе отдельным типом. В окончательной реализации на Хаскелл тоже.

Есть. Смотри refined types.

А его кто-то использует?

https://hackage.haskell.org/package/network-3.2.7.0/docs/Network-Socket.html : порт строкой, количество отправляемых байт может быть отрицательным, getAddrInfo throws an IO exception, но в примере обработки ошибки нет.

И это пример документации одной из системных библиотек…

P.S. Смотрю https://hackage.haskell.org/package/refined-0.8.2/docs/Refined.html . Похоже, что на каждое уточнение типа надо делать перепроверку.

type Type100 =
  Refined (Not (GreaterThan 100)) Integer
type Type200 =
  Refined (Not (GreaterThan 200)) Integer

g :: Type200 -> Int
...

f :: Type100 -> Int
f x = g (refine (unrefine x))

-- так нельзя, хоть очевидно, что все, что меньше 100 уже меньеш 200
f x = g x

То есть это даже не Typed Racket.

monk ★★★★★
()
Ответ на: комментарий от hateyoufeel

length из стандартной библиотеки работает со списками любых типов

Только все значения списка обязаны быть одного типа, в отличие от Cons/MyList/len.

И твой алгоритм на Cons ограничивал все элементы списка одним типом. len $ Cons 5 $ Cons "ok" $ Cons 2.5 End не работало.

monk ★★★★★
()
Ответ на: комментарий от Obezyan

Я имел ввиду что лисп не используется в работе не из-за его сложности (он простой как бейсик практически), а из-за сложности его восприятия новыми поколениям программистов. С ним думать надо глубже, что ли, это сейчас не очень в почете.

На самом деле, нет. И на лиспе можно писать прямолинейно не выпендриваясь, и на Си++ Александреску такие пируэты выписывал, что никакому лиспу не снилось. Хаскель и Раст тоже сложно воспринимаются, но они пока в моде.

Всё проще: программистов на лиспе мало, поэтому мало проектов, проектов мало, поэтому новые программисты не изучают лисп. Это относится не только к лиспу, но и к любому языку программирования, за которым не стоит корпорация и который занимает меньше 5% рынка. Плюс влияние моды.

monk ★★★★★
()
Ответ на: комментарий от monk

Только все значения списка обязаны быть одного типа, в отличие от Cons/MyList/len.

Ну, да. И? Ещё раз, это не является проблемой вообще ни для кого.

Он в лиспе отдельным типом. В окончательной реализации на Хаскелл тоже.

И зачем так делать-то? Ну кроме того, чтобы сделать через жоп^W^Wкак в лиспе.

А его кто-то использует?

Да.

https://hackage.haskell.org/package/network-3.2.7.0/docs/Network-Socket.html : порт строкой, количество отправляемых байт может быть отрицательным, getAddrInfo throws an IO exception, но в примере обработки ошибки нет.

И это пример документации одной из системных библиотек…

ичо? В лиспе количество отправляемых байт может быть строкой, объектом, бананом и функцией, но тебя это почему-то не смущает.

То, что в хачкеле напихали Int вместо Word повсюду, ни для кого не секрет. Не чинят исключительно потому что легаси.

hateyoufeel ★★★★★
()
Последнее исправление: hateyoufeel (всего исправлений: 1)
Ответ на: комментарий от Obezyan

Я имел ввиду что лисп не используется в работе не из-за его сложности (он простой как бейсик практически), а из-за сложности его восприятия новыми поколениям программистов.

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

С другой стороны, любой нуб сразу же убежит из-за наличия в CL пяти разных предикатов равенства и необходимости помнить какой из них для чего. И я их понимаю.

С ним думать надо глубже, что ли, это сейчас не очень в почете.

Судя по лисперам, думать там не то что не надо, а даже и вредно. Я отказываюсь верить в эту вот исключительность лиспа, хоть и сам писал на нём в универе. Если бы он был таким офигенным, софта на нём было бы куда больше. Даже на нишевых хачкелоокамлах кода больше, чем на CL, хотя вот их нишевость и высокий порог вхождения вообще никто не отрицает.

Что характерно, самый популярный лишп сейчас – это Clojure, и НаСТояЩЩие лисперы его люто ненавидят.

hateyoufeel ★★★★★
()
Ответ на: комментарий от hateyoufeel

Ну вот в том то и дело что лисп в чистом виде абстрагирован от всего кроме простой работы со списком. Любое практическое применение требует ПОДУМАТЬ как его применить.

Гораздо проще для конкретной практической задачи использовать язык который уже заточен под неё, имеет библиотеки, фреймворк и готовый набор рамок (ограничений) в пределах которых предлагает механизм решения задачи.

Именно в этом разница - в других ЯП (в большинстве) эти моменты уже продумали за программиста - добавили эдакий слой абстракции, а в Лиспе сам, все сам.

Вот в Кложе добавили свой слой и заточили все под данные. Все данные, даже код.

Вот этим кложа и «предала» истинный лисп (и слава богу).

То же Ловсан делает свой интероп велосипед без сиденья по той же причине - чтобы использовать готовый функционал другого языка (библиотеки) ведь в лисп этот функционал не завезли.

Obezyan
()
Ответ на: комментарий от Obezyan

Ну вот в том то и дело что лисп в чистом виде абстрагирован от всего кроме простой работы со списком.

ээээ… очень странное утверждение.

Любое практическое применение требует ПОДУМАТЬ как его применить.

Это верно для вообще любого языка.

Именно в этом разница - в других ЯП (в большинстве) эти моменты уже продумали за программиста - добавили эдакий слой абстракции, а в Лиспе сам, все сам.

Я боюсь, здесь проблема в возрасте CL. Потому что в тех же C и C++ много чего тоже нет. Например, строк (в первом) или модулей (в обоих). Поэтому сишники так любят писать, что на их любимом языке надо думать а не только говнокодить. Код их лучше от этого не становится.

Вообще, лисперы очень похоже на секту аутистов, для которых скобочки имеют первоочередную ценность. Мне CL больше нравится как язык-мем из декораций к аниме чем как что-то, на чём можно код писать.

hateyoufeel ★★★★★
()
Ответ на: комментарий от hateyoufeel

ээээ… очень странное утверждение.

простой пример: массивы

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

Пока терпимо.

Усложняем: многомерные ассоциативное массивы с ключами и значениями произвольных типов.

Все, приплыли. Лучший язык для работы с подобными структурами данных будет… PHP. С заметным отрывом от него будут идти Js, Python, Go и Java. Про С или Lisp даже не вспоминают при таких задачах, потому что в них придётся написать половину встроенного функционала PHP из раздела массивы, а зачем если PHP уже написан (на С). И так во всем.

Это верно для вообще любого языка.

Нет, при использовании языка заточенного под задачу можно писать код не приходя в сознание, чи то многие и делают. Я не говорю что это хорошо.

Obezyan
()
Последнее исправление: Obezyan (всего исправлений: 1)
Ответ на: комментарий от Obezyan

Усложняем: многомерные ассоциативное массивы с ключами и значениями произвольных типов.

Да нет, это практически любой язычок с нормальным параметрическим полиморфизмом может. Даже C++.

Нет, при использовании языка заточенного под задачу можно писать код не приходя в сознание, чи то многие и делают. Я не говорю что это хорошо.

DSL – это весьма хорошо. Но ты явно не об этом.

Язычков, хорошо подходящих для какой-то конкретной задачи, на самом деле очень мало, и почти во всех случаях это какая-то очень нишевая задача.

В контексте треда, я очень хорошо помню, как лисп продвигался для написания искусственного интеллекта. У меня даже книжка об этом есть! Но как-то так вышло, что в итоге ни одной распространённой системы ИИ на лиспе так и не вышло. А вот на плюсцах и пердоне – вагоны. Как же так-то?

hateyoufeel ★★★★★
()
Ответ на: комментарий от Obezyan

Лучший язык для работы с подобными структурами данных будет… PHP

Apes together… strong!

Nervous ★★★★★
()
Ответ на: комментарий от hateyoufeel

И зачем так делать-то? Ну кроме того, чтобы сделать через жоп^W^Wкак в лиспе.

Чтобы выполнялись все тесты, которые работали в лиспе, а не выкидывалась половина со словами «это никому не надо».

Да.

Можно пару библиотек для примера?

К слову, Liquid Haskell всё равно мощнее: он позволяет делать проверки диапазонов или, например, выполнения монадных законов на этапе компиляции, а не при каждом запуске функции проверять.

monk ★★★★★
()
Ответ на: комментарий от hateyoufeel

То, что в хачкеле напихали Int вместо Word повсюду, ни для кого не секрет. Не чинят исключительно потому что легаси.

Вот в этом и есть основная проблема хаскеля. С одной стороны, нормально сделали целочисленную арифметику и списки. С другой стороны, как попало всё остальное. В результате, «статически проверенный и типизированный» leksah постоянно сыпет ошибками несовпадения типа при вызове функций Gtk.

monk ★★★★★
()
Ответ на: комментарий от Obezyan

простой пример: массивы

А что не так с массивами в Common Lisp? Есть и многомерные и типизированные и безтиповые и с изменяемым размером и размещаемые поверх друг друга. И всё это прямо в стандарте.

Усложняем: многомерные ассоциативное массивы с ключами и значениями произвольных типов.

make-hash-table тоже в стандарте. И тоже даже в стандарте уже указана часть настроек.

Лучший язык для работы с подобными структурами данных будет… PHP.

Как на PHP написать хотя бы

(make-hash-table :rehash-size 1.5 :rehash-threshold 0.7)

?

С заметным отрывом от него будут идти Js, Python, Go и Java.

А в чём разница работы с подобными структурами данных в PHP и Python? Она разве не идентична?

monk ★★★★★
()
Ответ на: комментарий от hateyoufeel

многомерные ассоциативное массивы с ключами и значениями произвольных типов.

Да нет, это практически любой язычок с нормальным параметрическим полиморфизмом может. Даже C++.

Возможно, требуется, чтобы работало

dict["ok"] = 1;
dict[5] = "fail";
dict[[1, 2, 3]] = [3, 2, 1];

Такое в C++ обеспечить достаточно сложно.

monk ★★★★★
()
Ответ на: комментарий от hateyoufeel

Но как-то так вышло, что в итоге ни одной распространённой системы ИИ на лиспе так и не вышло

Психиатр в GNU Emacs.

А вот на плюсцах и пердоне – вагоны.

Это на сегодня. Потому что на лиспе их перестали писать 40 лет назад. Если брать состояние на 1990 год, то почти все ИИ были на лиспе.

monk ★★★★★
()
Ответ на: комментарий от Obezyan

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

Не зависит, на самом деле. Например, если писать обработку списков на лиспе или работу с массивами на APL, всё равно думать очень активно приходится. А если писать почти что угодно на Java, то половину времени будешь не приходя в сознание реализовывать структуру выбранного паттерна, а уже потом начинать думать.

Кстати, Хаскелл в этом смысле хорош тем, что, не приходя в сознание, на нём пишутся только правильно типизированные, небольшие, легко тестируемые функции. А на каком-нибудь PHP, наоборот, не приходя в сознание, легко пишется только портянка-говнокод, которую потом приходится переписывать, чтобы написать тесты (или отдавать в работу со словами «и так сойдёт»).

monk ★★★★★
()
Ответ на: комментарий от Obezyan

говорят что лисп там оверкил

ЛИСП везде похоже оверкилл. Такой вот мощный язык.

no-such-file ★★★★★
()
Ответ на: комментарий от hateyoufeel

в итоге все страдают. Примерно как это со строками в C обстоит

На распространённость Си и крестов это никак не влияет.

любой нуб сразу же убежит из-за наличия в CL пяти разных предикатов равенства

Чёт никто не убегает из крестов из-за 100500 вариантов конструкторов и тех же operator=.

no-such-file ★★★★★
()
Ответ на: комментарий от no-such-file

в итоге все страдают. Примерно как это со строками в C обстоит

На распространённость Си и крестов это никак не влияет.

На распространённость Си это в том числе очень влияет. Новых проектов на нём – только глючное красноглазое говнецо. На Rust, при всём его убожестве, куда больше интересных штук сейчас делают.

любой нуб сразу же убежит из-за наличия в CL пяти разных предикатов равенства

Чёт никто не убегает из крестов из-за 100500 вариантов конструкторов и тех же operator=.

Я должен поздравить фанатов и авторов CL здесь: сделать ещё более всратый и невразумительный язык чем C++ казалось невозможным, но вы все справились! Молодцы!

hateyoufeel ★★★★★
()
Ответ на: комментарий от monk

И зачем так делать-то? Ну кроме того, чтобы сделать через жоп^W^Wкак в лиспе.

Чтобы выполнялись все тесты, которые работали в лиспе, а не выкидывалась половина со словами «это никому не надо».

Ты придумал критерий, которому соответствует только лишп, и жалуешься, что ему соответствует только лишп. Я здаюзь, ты подебил!

В результате, «статически проверенный и типизированный» leksah постоянно сыпет ошибками несовпадения типа при вызове функций Gtk.

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

Но как-то так вышло, что в итоге ни одной распространённой системы ИИ на лиспе так и не вышло

Психиатр в GNU Emacs.

АХАХАХАХАХАХАХАХАХ!!!!!!!!11 Назвать примитивную цепь Маркова искусственным интеллектом – это сильно. Так-то в начале 2000х ведущим языком для разработки ИИ был Tcl, потому что sulci.

Это на сегодня. Потому что на лиспе их перестали писать 40 лет назад. Если брать состояние на 1990 год, то почти все ИИ были на лиспе.

Почти все – это какие? Их кто-то видел, кроме пары чуваков в университетах? Не-а.

hateyoufeel ★★★★★
()
Ответ на: комментарий от hateyoufeel

Ты придумал критерий, которому соответствует только лишп

Не только. При переписывании на Си, Си++, Перл, Питон, ПХП, Паскаль, … данный код работает превосходно. Не работает только в твоей интерпретации на Хаскеле.

Если ты хочешь сказать, что на хачкеле можно сделать говнокод, то с этим вообще никто никогда не спорит.

Разве? А мне казалось, что тут половина обсуждения про то как статическая типизация должна защитить от говнокода.

Почти все – это какие? Их кто-то видел, кроме пары чуваков в университетах? Не-а.

MYCIN, INTERNIST-I, CASNET, PIP, E-MYCIN, XCON, PROSPECTOR, DENDRAL, PUFF, R1/XCONNECTION, CASNET, XSEL, …

Использовались в медицине, геологии, химии, …

monk ★★★★★
()
Ответ на: комментарий от Obezyan

С ним думать надо глубже, что ли, это сейчас не очень в почете.

Алгоритмы как-то поменялись? Потому что «думать» в языке программирования не о чем.

gaylord
()
Ответ на: комментарий от monk

При переписывании на Си, Си++, Перл, Питон, ПХП, Паскаль, … данный код работает превосходно.

Ты уже переписал? Особенно типизация на Си меня интересует, учитывая, что система типов в Си фактически отсутствует и вынуждает делать void* на каждый чих.

Не работает только в твоей интерпретации на Хаскеле.

Повторюсь: это была твоя интерпретация.

Разве? А мне казалось, что тут половина обсуждения про то как статическая типизация должна защитить от говнокода.

Ага. Если её использовать. А если её не использовать, то не защитит.

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

MYCIN, INTERNIST-I, CASNET, PIP, E-MYCIN, XCON, PROSPECTOR, DENDRAL, PUFF, R1/XCONNECTION, CASNET, XSEL, …

Названия – это отлично. А кто-то вживую-то ими пользовался? Потому что те истории успеха, что я видел, были достаточно сомнительными.

hateyoufeel ★★★★★
()
Последнее исправление: hateyoufeel (всего исправлений: 1)
Ответ на: комментарий от monk

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

А лисперы, я так понимаю, принципиально игнорируют структуры, массивы, хеш-таблицы и прочие структуры (простите, за тавтологию) данных, и фигачат всё на cons-ячейках?

(defstruct s
  x
  y
  z)
 
(let ((v (make-s :x 5 :y "ok" :z 2.5)))
  (format t "~a~%" (length v)))

...

Unhandled TYPE-ERROR in thread #<SB-THREAD:THREAD "main thread" RUNNING
                                  {10005D05B3}>:
  The value
    #S(S :X 5 :Y "ok" :Z 2.5)
  is not of type
    SEQUENCE

Backtrace for: #<SB-THREAD:THREAD "main thread" RUNNING {10005D05B3}>
0: (LENGTH #S(S :X 5 :Y "ok" :Z 2.5))
1: (SB-FASL::LOAD-FASL-GROUP #S(SB-FASL::FASL-INPUT :STREAM #<SB-SYS:FD-STREAM for "file /home/vvLa1f/prog.fasl" {1001B74D23}> :TABLE #(233 #<PACKAGE "SB-KERNEL"> SB-KERNEL::%DEFSTRUCT-PACKAGE-LOCKS #<PACKAGE "COMMON-LISP-USER"> S "S-" MAKE-S :DEFAULT #1=(MAKE-S . :DEFAULT) (#1#) COPY-S S-P ...) :STACK #(3 FORMAT T "~a~%" LENGTH #S(S :X 5 :Y "ok" :Z 2.5) :Z 2.5 NIL #(#(7 0 145 1 49 55 41 20 54 60 64 38 ...)) (:Z T) T ...) :NAME-BUFFER #("" "LENGTHT-DEFSTRUCTN-MORERNAL") :DEPRECATED-STUFF NIL :SKIP-UNTIL NIL) NIL)
...

korvin_ ★★★★★
()
Ответ на: комментарий от hateyoufeel

Особенно типизация на Си меня интересует, учитывая, что система типов в Си фактически отсутствует и вынуждает делать void* на каждый чих.

Именно так. При этом

int len(struct cons *c)
{
   if (c == end) return 0;
   return 1 + len(c->cdr);
}

не ругается, что так делать нельзя и не требует типизировать cons.car.

А кто-то вживую-то ими пользовался? Потому что те истории успеха, что я видел, были достаточно сомнительными.

Я же написал: медики, геологи, химики. Работало лучше, чем если без ИИ. Основной недостаток тогда был — долгое ожидание ответа (около получаса).

monk ★★★★★
()
Ответ на: комментарий от korvin_

Ещё раз. В лиспе я пишу

(defstruct my-cons car cdr)

И могу использовать её в любых алгоритмах. На Хаскеле мой оппонент говорит, что для того, чтобы посчитать длину списка из этих структур, я обязан принудительно ограничить тип car (который этот алгоритм даже не читает), чтобы он был одинаков у всех ячеек. Другой мой оппонент предлагал сделать список, у которого можно только узнавать длину, но не читать элементы. Оба утверждали, что для программистов на Хаскеле их поведение нормально.

monk ★★★★★
()
Ответ на: комментарий от monk

И могу использовать её в любых алгоритмах.

Главное, не забывать периодически проверять, что это proper list.

(let ((v (cons 1 (cons "a" 2.5))))
  (format t "~a~%" (length v)))

...

Unhandled TYPE-ERROR in thread #<SB-THREAD:THREAD "main thread" RUNNING
                                  {10005D05B3}>:
  The value
    2.5
  is not of type
    LIST

Backtrace for: #<SB-THREAD:THREAD "main thread" RUNNING {10005D05B3}>
0: (LENGTH (1 "a" . 2.5))
...

А так да, в любых.

На Хаскеле мой оппонент говорит, что для того, чтобы посчитать длину списка из этих структур, я обязан принудительно ограничить тип car (который этот алгоритм даже не читает), чтобы он был одинаков у всех ячеек.

Не помню, когда мне в последний раз нужны были гетерогенные списки. И даже не в Хаскелле. Практически никогда. Впрочем, тут же дело не в самих списких, а в отсутствии в Хаскелле субтипирования. А гарантия структуры (что это proper list), а не какое-то безумное дерево cons'ов, как будто постоянно удобна.

korvin_ ★★★★★
()
Ответ на: комментарий от korvin_

Вот ещё один «любой алгоритм»:

(let ((v (cons 1 (cons 2 3))))
  (format t "~a~%" (reduce #'+ v)))
(let ((v (cons 1 (cons (cons 2 3) nil))))
  (format t "~a~%" (reduce #'+ v)))

выдал ошибку, оказался неприменим.

korvin_ ★★★★★
()
Последнее исправление: korvin_ (всего исправлений: 2)
Ответ на: комментарий от Obezyan

Я имел ввиду что лисп не используется в работе не из-за его сложности (он простой как бейсик практически), а из-за сложности его восприятия новыми поколениям программистов. С ним думать надо глубже, что ли, это сейчас не очень в почете.

Звиздешь. Зеленое поколение ничего не решает и его никто не спрашивает. Скажут зубрить лишп, будут зубрить и никуда не денутся и радоваться будут. А вот старперы, которые сейчас в лидах и архитехтурах торчат, вот они как раз решают, и вот они как раз выбирают. А выбирают они то, с чем меньше всего тра*ться нужно. Чтоб было максимально просто и дешево. Желание повыпендриваться у этого контингента пропало лет 15 назад, а сейчас дом, всякие жены с детьми, которых нужно куда-что водить и выгуливать, и прочие кучи хомячковых делишек. Задротить некогда и нет ни малейшего желания. Вот поэтому все эти гошки, пыхи, бидоны и все подобное царит в индустрии. Это рассказываю про то, что вижу вокруг себя, смотря по сторонам (про лидов и архитехтуров)

slew
()
Ответ на: комментарий от monk

я имел ввиду конструкции вида:

$data = array(
    0 => array( 
        123 => $val, 
        'executed' => true, 
        'info' => array(
            'code' => 200,
            'message' => 'ок' 
        )
    ), 
    1 => 'test' 
);

с произвольной вложенностью и типами.

Obezyan
()
Ответ на: комментарий от Obezyan

с произвольной вложенностью и типами.

В лиспе так тоже можно. В стандартной библиотеке так красиво не будет:

(defvar *data* (make-hash-table))

(let ((inner (make-hash-table))
      (code200 (make-hash-table)))
  (setf (gethash "code" code200) 200)
  (setf (gethash "message" code200) "ok")
  (setf (gethash 123 inner) val
        (gethash "executed" inner) t
        (gethash "info" inner) code200)
  (setf (gethash 0 *data*) inner)
  (setf (gethash 1 *data*) "test"))

Если же использовать крохотную библиотеку cl-hash-util, то

(defvar *data*
  (hash 0 (hash (123 val)
                ("executed" #t)
                ("info" (hash ("code" 200) ("message" "ok"))))
        1 "test"))
monk ★★★★★
()
Последнее исправление: monk (всего исправлений: 1)
Ответ на: комментарий от monk

Отлично, а теперь давайте реализуем работу с этим массивом. Вот список основных функций который нам понадобится :)

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

Obezyan
()
Ответ на: комментарий от monk

sethash gethash hash hash hash

Что только люди не делают, на какие только ухищрения не идут, лишь бы не

(let [val  12
      data [{1         "test"
             123       val
             :executed true
             :info     {:code    200
                        :message "OK"}}]]
  (println data))

;; => [{1 test, 123 12, :executed true, :info {:code 200, :message OK}}]
Nervous ★★★★★
()
Последнее исправление: Nervous (всего исправлений: 1)
Ответ на: комментарий от Nervous

О, а вы на кложе тот же список функций сделайте?

Два моих любимых зайчика на форуме в одной сети, разве это не прекрасно?

Obezyan
()
Ответ на: комментарий от Nervous

Разные скобочки хорошо, до тех пор, пока их не надо в макросе разбирать. В кложе ведь тоже есть макросы?

И неясно, как сделать

(setf a '(1 (2 "ok"))) 

(setf b (hash (a 4) :test #'equal))

(setf c (hash (a 4) :test #'eq))
monk ★★★★★
()
Последнее исправление: monk (всего исправлений: 2)
Ответ на: комментарий от monk

Разные скобочки хорошо, до тех пор, пока их не надо в макросе разбирать

Нет никаких проблем, в стандартной библиотеке есть функции для работы с любыми коллекциями — индексированными, последовательными, ассоциативными.

неясно, как сделать setf

Neeqaque. assoc & update ваши друзья %)

Nervous ★★★★★
()
Ответ на: комментарий от Nervous

assoc & update ваши друзья

Вопрос не про это. У меня два хеша. В b при поиске по любому списку с значением ’(1 (2 «ok»)) будет возвращено 4. В c при поиске по значению, которое в переменной a, будет возвращено 4, для любого другого ключа будет отсутствие значения.

(setf a '(1 (2 "ok"))) 

(setf b (hash (a 4) :test #'equal))

(setf c (hash (a 4) :test #'eq))

(setf k (list 1 '(2 "ok")))

(assert-eql (gethash k b) 4)
(assert-eql (gethash k c) nil)

А как сделать b и c на скобочках?

monk ★★★★★
()
Ответ на: комментарий от Nervous
Ответ на: комментарий от Obezyan

Я, пожалуй, пока обратно на дерево залезу, чтобы палки и камни не доставали :)

Про С отдельно улыбнуло учитывая что массивы имеют динамические типы в ключах и значениях.

Obezyan
()
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.