LINUX.ORG.RU

Lisp: Где применимы cons?

 cons,


1

6

Для начала небольшой «бенчмарк», С без всех оптимизаций в 7406000 раз быстрее.

(defun main ()
  (declare (optimize (speed 3)))
  (let ((n 99999) (l '()) (sum 0))
    (loop for i from 0 to n
	  do (setq l (append l (list i))))
    (setq sum 0)
    (loop for i from 0 to n
	  do (setq sum (+ sum (nth i l))))
    (format t "~d~%" sum)))
#include <stdlib.h>
#include <stdio.h>

int main(int argc, char **argv)
{
	long n = 99999, *l = NULL, count = 0, sum = 0;
	for (long i = 0; i <= n; i++) {
		l = realloc(l, (count + 1) * sizeof(long)); 
		l[count++] = i;
	}
	for (long i = n; i >= 0; i--) sum += l[i];
	printf("%ld\n", sum);
}

Для чего же нужны cons? В качестве универсального строительного блока, я считаю это одна из самых худших структур. Все ее преимущества заканчиваются на быстром добавлении в начало. Добавление в конец уже нежелательно, разрез в произвольном месте тоже, так как нету даже быстрого доступа к случайному элементу. Она медленная и неудобная, можно придумать кучу более быстрых и удобных структур. Даже JS на световые годы опережает Lisp со своим JSON, и его частое использование лишь подтверждает его удобство.

Так почему же cons из языка-ассемблера IPL 1956 года считается важным? Да, это неплохая структура для AST, если ваша машина имеет 16 кб памяти, но она распространилась по языку слишком широко.

★★★★★

Последнее исправление: MOPKOBKA (всего исправлений: 3)

в отсутсвии Destructive place-modifying operators всё так

cons + Destructive place-modifying operators == произвольные графы и их быстрые мутации

т.е произвольные сети адаптирующиеся во мере поступления новых входов

т.е очередная Тьюринга машинка универсальная

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

лисп 60ых не был чистым

ибо rpla ? rplr ?

более того там был динамический резолвинг имён - что тот ещё ад кутежа

schame более воздушен

и на реальной практике если нужен был индекс массив то его прикручивали - лисп силён именно тем что можно перегрузить почти всё

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

лисп не запрещает использовать B+ деревья али какую реляционую таблицу в своих потрохах

ибо лисп реально очень низко-высоко-низко-уровневый можно же кусками jitиться а кусками быть глубокоинтерпретируемым

не случайно что и smolltock и prolog это расширенные до потери узнаваемости lisp

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

раскурись структуры [хранения] данных

деревья cons это просто достаточное

если нужен индекс это либо прихручиваешь хэш либо делаешь 2-3 дерево на основе cons сканировать постояно список это привозить o(n2) так можно в песочнице а lisp вполне HPC был на больших машинах - не так числодробилен как фортран - но вполне в символьных вычислениях всегда

память достаточно подешевела вот и не помнят что в lisp полно структур данных высопроизводельных тока они не в стандарте :)

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

Конс даёт возможность реализовать многоверсионную ассоциативную память на (полу-) иммутабельных структурах данных.

Например, как сделать биндинги переменных? Сначала в функции main создаём окружение (базу данных значений переменных),

окружение1 = ((моя-переменная . 1)), т.е. моя переменная равна 1.

Потом вызываем другую функцию и она временно связывает мою переменную в 2. Тогда окружение, хранящее значения переменных, будет в активации функции callee, вызываемой из main, выглядеть так:

((моя-переменная . 2) . окружение1) - т.е. мы ставим старое окружение (ссылку на него) как хвост уже существующего. При поиске текущего значения среда выполнения идёт по списку с головы и ищет конс-ячейку, в которой голова совпадает с именем переменной. Эта конс-ячейка и является хранилищем текущего значения переменной. Мутабельна она или нет - это другой вопрос, но изменения остаются в функции callee. Функция main не знает, что мы сослались на окружение1, и в ней моя-переменная будет равна 1, т.к. когда мы вернёмся из callee, мы просто забудем значение окружения, которое в ней было.

Таким способом можно реализовать специальные переменные - они как бы глобальные, но их можно локально связать с значением внутри функции и при выходе из функции будет восстановлено старое. Такая вот особая разновидность переменных, между локальными и глобальными, я встречал её только в лиспе и на самом деле она очень удобна, хотя сейчас считалась бы, наверное, дурным тоном.

Но общая идея такова - чистое ФП, многоверсионные базы данных. Слово «многоверсионное» тут главное. Новая версия базы данных создаётся путём добавления слоя изменений к уже существующей. Ты же вроде Хасклеист, должно быть тебе понятно. Ну или не ты Хаскелист, но не суть. В любом случае, тут не оптимизируешь как ты хочешь. Большой вектор копировать будет O(размер базы), а здесь содержание версии обходится в O(размер разницы между базами)

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

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

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

А вообще в лиспе есть cdr-coding - это примерно то, что ты хочешь. Но поскольку семантика другая, это, кажется, может сломаться. Но я глубоко в этом не разбирался. Как минимум, это не только оптимизация, но и деоптимизация, т.к. представление конса становится неоднозначным, и надо хранить какой-нибудь бит, говорящий о способе представления, а дальше во всех обработках иметь ветки - это имеет свою цену. Насколько я понимаю, в современных реализациях CL этого нет (я не встречал).

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

В 2025 году лиспосрач нужно воспринимать как праздник - кто-то про язык вспомнил - уже отлично.

В условиях напряженной международной обстановки и возможности 3МВ, видится мне, что Лисп и человеческий абакус из Трёх тел - самые оптимальные технологии для сохранения вычислительных возможностей у человечества :)

Лисп хорош тем, что даже если отключат возможность получать дистрибутивы из апстрима, то не сильно трудно запилить свою реализацию. Имхо Лисп реализовать проще чем какую-нибудь Java с JVM.

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

выше уже намекали на cdr-сжатие

если без ныряния в железку то logN что хуже чем o(1) при регистро-индексах

но по факту в лиспе можно иметь массивы - но лучше сразу B(+\*)дерево али какой скип0лист

зы на парах трудно на тройках 2-3дерево(самое худое из B+ :) )

всяко это хуже O(1)

поэтому теже хэши - недостаток вот этих структур не на сons - «досрочная компиляция» потеря динамичности

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

я бы сказал, что многоверсионную CAM-память про которую пишет den73 можно реализовать и на first class objects,first class environments лиспе который есть например в kernel vau-expressions by John Schutt, частично в functional objects ^W ^W Harlequin ^W LispWorks лиспах типа Dylan, goo

а на схеме метациклический first class environments был в какой-то книжке в качестве примера на самих гигиеничных макрах и без особых костылей

еще про метациклический лисп и башню метацикличных лиспов где-то было

curl который веб-язык для RIA по сути это тоже такой лисп в котором дефолтный синтаксис это литературно-грамотно-подобное DSL в духе данные внутри контейнеров + код внутри {curly-based} тегов + динамические GUI переменные типа tcl/tk виджетов + конпеляция через сишку в first class bindings, first class environments для безопасной песочницы в которой «лексикон программирования» перекрыт с опасными методами в безопасную реализацию внутри песочницы

там можно было бы и с функциональными объектами заморочиться, но ЕМПИП сильно не стали, ООП модель в духе обычной типа C++ а не CLOS или first class environments.

по крайней мере в итоге в CURL RTE примерно к этому пришли ибо проще и нагляднее массовым программерам с обычным ООП – кстати, обычный help этого CURL IDE вполне себе неплохой питоноутбук только с гаджетами и виждетами которые можно dynamic let переменными невозбранно настраивать в ноутбуке

хотя изначально в paper 1996-1998 года была tk без tcl реализация + конпеляция через сишку, вроде те исходники все еще доступны

опять же, подобное можно сделать и в какой-то схеме синтаксическими макросами

о!!! вот, кстати про веб который мы потеряли (даже ничего не зная об этом, лолъ).

знаешь ли ты про такой браузер как CyberDog? «в интернете никто не узнает что бы собака»(с) потому что

а между тем. это было первое работающее OpenDoc приложение в стиле internet suite от самых яблок (когда они там мутили AIM с Pink/Taligent/Copland/Rapsody + Kaleida (тоже кстати интересное типа AppleScript+Dylan+Java^W Dylan Script) + SOM/DSOM/CORBA + OpenDoc реализация от голубых).

в интернетах пишут, что работало все очень быстро. при том, что там были как в Netscape Communicator или в Opera Presto – все в одном : email клиент, FTP клиент, NNTP клиент, !! telnet клиент (и все ждали MUD/MOO клиента плагинами) + собственно компонент браузера HTML

и не удивительно!!! работало очень быстро – потому что тормозить было буквально не чему:

  1. JS не был реализован, а это -10500 основных тормозов современного веба

  2. OpenDoc в качестве компонентной модели примерно как в Netscape/Mozilla/Seamonkey/VirtualBox – используется XPCOM

  3. все было реализовано плагинами OpenDoc – редакторы, просмотрщики, и например вместо закладок были CyberItems – ссылки на NNTP, email, telnet или там HTML или – динамически формируемые CORBA/Bento/OpenDoc документы

  4. почтовый клиент поддерживал произвольное количество ящиков, с поиском за 3 секунды по базе в несколько тысяч писем; типа виртуальных папок или динамических фильтров по содержанию

  5. это технически могли бы быть любые объекты, не обязательно только письма – если бы такое расширение реализовали

  6. плагины и реализация отдельных протоколов через OpenDoc-компоненты.

  7. компилируемые бинарные объекты, динамически формируемые по сети – поверх OpenDoc

  8. WebObjects сервер приложений на Objective C кажется начинал их поддерживать, хотя там с OpenDoc полноценной поддержкой толком не было в ObjectiveC, хотя – SOM объекты на plain C собственно

пункты 7, 8 – убирают основные тормоза современно веб – интерпретируемого.

потому что делают веб-объекты – бинарными, конпелируемыми.

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

в форматах compound document object.

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

Kaleida тоже пыталась делать интересный недоязычок для скриптухи и гипермедии типа hypercard + apple script, но тоже не взлетело.

вроде там сам стив джопс похоронил OpenDoc И все эти apple research проекты включая dylan и BeOS «чемодано-ноутбук» by JLG – лично, когда вернулся из NeXT в яббл. и после этого начали навязывать жабу и JavaBeans «компоненты».

а так вообще интересная картинка вырисовывалась бы если бы так рано не похоронили:

  1. конпелируемые объекты в браузере плагинами на компонентной модели OpenDoc

  2. под которую можно писать конпелируемые SOM объекты из Dylan для плагинов или KaleidaScript для JS-скриптухи (или скорее, лого-подобных лисп-подобных «функциональных объектов»)

  3. конпелируемые WebObjects на Objective C сервере приложений на сервере – к которым можно было написать SOM/OpenDoc привязки

  4. конпелируемые CURL RIA DHTML подобные «приложеньица», только на лиспе и сишке

  5. какой-то агентный акторный лисп типа first class environments с функциональными объектами для всего, да.

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

не случайно что и smolltock и prolog это расширенные до потери узнаваемости lisp

ну почти до полной потери неузнаваемости :) разошлись где-то уже после SECD-машины и LispKit-реализации «механического лямбда-исчисления» как форт-машина с 4мя стеками (тогда да, и форт это тоже лисп, только маленький ещё :)

один это абстрактная WAM-машина, то есть, по сути интерпретатор этого абстрактного исполнителя – который становится императивный а не декларативный.

попытка это расширять, например скрестить с сишкой выродилась в:

  1. контуперы 5-го поколения FGCS японские где по сути пролог+си типа Mercury, только с линейной масштабируемостью, системными ос интерфейсами типа транспьютеров и реализацией СУБД Quixote с запросами на естественном языке через DCG-грамматики, атрибутивные грамматики типа ANN для парсинга ЕЯ и языка запросов на всем этом;

  2. собственно, Mercury как конпелируемый в сишку пролог в котором можно было указать где входы а где выходы аннотациями а не декларативно так;

  3. собственно, Visual Prolog под венду визуал студию где можно было накидать формочки мышкою словно в дельфях, отнаследовать от «функционально-логических объектов» и забуриться в свое вендовозное API через конпеляцию msvc cl.exe; по сути Visual Prolog = ОО-пролог с WinAPI и объектами

  4. собственно, LogTalk := Prolog + SmallTalk как открытая реализация предыдущего пункта

из смоллтоков если взять дельфиподобное например Dolphin SmallTalk – тоже можно увидеть CURL IDE-подобные юпитероноутбуки в REPL или в отладчике или в Refactoring браузере. где-то в бложике у них было обучающее видео про компоненты MVP = Model-View-Presenter а не контроллер, и про то что почти как мышкой формочки в дельфях – только над моделью и View думать надо, это тебе не TComponent а сразу MVP объект - как компонент.

опять же мини мета язык метакода смоллтоковых методов-сообщений зато синтаксис в 20 строчек и реализация строчек в 40 в исходниках factor/examples/smalltalk через PEG-грамматики.

но опять же думать надо про метакод и сообщения – методы каких объектов или метаобъектов или метаметаметамета(ad infinum) Объектов.

опять же, например в Dolphin SmallTalk – есть пакеты и системы и смоллток объект системы который умеет подгружать и конпелировать.

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

и это я еще толком про лиспы с транспьютерами не говорил.

например, есть Helios ос – транспьютерная ос, ныне открытая в исходниках на гитхабе. со средой программирования на occam. с микроядром загружающим через IO процессор на ноды и настраивающая линки между SEQ/PAR секциями с #include оккама

который невозбранно конпелируется в сишку или апм-подобный ассемблер (например, раскладка переменных в памяти, прерывания и т.п. а не только CSP каналы и сообщения)

в котором невозбранно была «литературно-грамотная IDE» со сворачивающимися абзацами кодоблоков и блоков документации.

любопытно про нее почитать, сейчас читаю книжку hbk.pdf про устройство ОС.

лисп тут при том, что Elate OS/TaoOS/intent DE/AmigaDE/VP virtual processor выродился в объектно-ориентированный ChrysaLisp в котором все это реализовано в лиспе в объектно-компонентых почти функциональных (но нет) объектах, компонентах tool.

собственно, поверх него можно реализовать нечто kernel/vau-expr/fexpr подобное с first class environments и далее например, нечто похожее на тот же curl.

только с OpenDoc и SOM - объектами кажется засада, с исходниками непонятки. может OCTAGRAM собирал, надо бы распросить подробнее его про OpenSOM+OpenDoc насколько оно там доделанное вообще.

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

внезапно, эта helios os чем-то plan9 напоминает, только более оккамоподобной бритвой близкое к железу чем все это файл и даже сервер и даже линк и даже Plan9FS styx == General Server Protocol.

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

Forth проще реализовать, особенно так, что бы он был быстрым.

А для тех кто привык к s-exp выражениям, можно набрать пару байтов:

0 variable n : r+ r@> 1+ >r@ ; 
: (: r+ >r@ 0 >r@ ; : ( ' literal ['] (: compile ; immediate 
: ) r@> n ! n @ srev n @ 1- 1 max for n @ 1 > if swap then rdup r@> execute next rdrop ;
: print . ; : >literal, ['] r+ compile ;
После чего можно писать как в лишпе.
( print ( - 2 3 ( + 4 5 6 7 ) ) )
И даже включать несколько переменных со стека!
: two-values 10 10 ;
( print ( - 2 3 ( + two-values ) ) )

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

Все именно так как ты написал, ведь append работает не с cons в любом виде, а с чистой манямировой материей которая черпается из разума no-such-file. А вот вызов cons это уже совсем другое дело. И можно просто закрыть глаза, и не читать тред, где я рассказываю про случайный доступ. Просто игнорируем неудобные слова, и пишем совсем другую программу, что бы доказать что лисп не тормоз.

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

лисп не запрещает использовать B+ деревья али какую реляционую таблицу в своих потрохах

А были ли базы данных где все представленно в виде виртуальных cons ячеек?

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

не знаю насчет cons ячеек, тут надо посмотреть под OpenGENERA какую-то АСУ ТП на лиспе, может там и СУБД какая-то была.

кстати, в picolisp есть встроенная btree кажется – см. radical approach to erp/web development или как-то так про relation daemon, prefix classes, генерацию динамическим picolisp нужных HTML форм и прочих физических моделей данных из логической и концептуальной ER модели.

а вообще B+Tree – почти готовый MUMPS, см. например libmumps.cpp из книги Kevin O’Kane про реализацию. там он зачем-то эти btree в postresql хранит, ну да ладно его, в более других мумпсах, например, YottaDB/GT.M/FreeM так не делают.

как язык M – это почти focal, соответственно есть реализации фокала на паскале и си, какие-то. интерпретатор там простой, но строчный.

попытки использовать хранилище глобалов с более другими языками были, собственно структурированные S-выражения или еще какие тоже напрашиваются. например, в YottaDB есть через C API привязки к чему угодно, например, Perl/PHP/Python/Rust/Go.

собственно, если считать что листья btree это битовые строки произвольной длины, в котором либо 1)все хранится как строки, даже числа как в MUMPS 2)либо тайптеги +контент либо 3)длина битовой строки+тайптег+контент

то можно условно битовые строки в глобалах мумпса считать такими «виртуальными cons-ячейками».

в Cache например (и еще в некоторых реализациях) есть List-функции чтобы хранить сразу списки, и вообще CacheObjectScript – это объектно-ориентированный M.

а сетевая модель данных – это CODASYL и COBOL соответственно, может там можно реализовать в виде таблиц кобола и таким образом подобных кобол-ячеек типа cons ячеек :)

еще cons ячейки и S-выражения – это двоичное дерево. а например термы пролога или рефал-выражения, R-выражения – это сразу N-арные деревья.

соответственно, базы данных на прологе или рефале тоже интересны.

пролог был например arity в котором были btree готовыми предикатами. то есть assert можно было факты заносить сразу в btree и сохранять в отдельные персистентные файлы-деревья. и еще несколько реализаций пролога.

еще есть такая публикация.

«Автоматизация проектирования процедур работы с базами данных» про САП БД (систему автоматизации проектирования БД) и СУБД ОКА, СУБД СЕТОР : «универсальный макрогенератор для генерации процедур работы с БД»,«генерация описания физической, логической базы данных и блоков связи прикладной программы»,«Универсальный макрогенератор из операторов подъязыка данных BETA в СУБД ОКА порождает наборы операторов, реализующих манипуляции с БД. Подъязык данных BETA является надстройкой над одним из базовых языков (ПЛ/1, кобол, или ассемблер) и представляет собой набор условных операторов и генерируется этим универсальным макрогенератором» с примерами структуры базы данных типа дерева, сетевой модели данных на CODASYL + исходниками на ПЛ/1.

публикация 03.02.1981

думаю, в качестве подобного макрогенератора можно взять и МЛ/1 или M4. или лисп, например.

picolisp посмотри например со встроенной реализацией btree и статью про демона отношений, префиксные классы миксины и рефлексию и интроспекцию на всем этом.

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

Cons это строительный блок лиспа, в JS строительным блоком я бы назвал JSON, потому что там нету более общего блока.

тогда сравнивай сразу подобное с подобным: JSON и SXML представление XML-подобного в виде S-выражений.

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

И даже в первом лиспе уже были массивы! Потому что нельзя терпеть cons даже в языке-эксперименте, а могли бы вообще от них избавиться.

в исходной публикации recursive.pdf Джона Маккарти и где-то рядом приводится пример линейной памяти и реализации под тот мейнфрейм с 36-битными регистрами которые назывались CAR и CDR. там приводится пример как пытались избавиться от лишних консов, а вообще это в регион анализ и линейные типы вырождается, если по умному.

то есть, уже там было написано про лисп который не требует сборщика мусора и лишних аллокаций, но в котором грубо говоря все cons-ячейки хранятся в массивах.

потому что оттуда и повелось CAR и CDR а не эта вот реализация в духе линейных типов раста с борроу чекером которые кажется так и не допилили.

кстати, любопытно – мог ли такой лисп в AST-макросы раста транслироваться чисто во время конпеляции – в духе InteLib Столярова на С++, только на расте макросами в CTFE.

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

в исходной публикации recursive.pdf Джона Маккарти и где-то рядом приводится пример линейной памяти

в смысле recursive.pdf aka «Recursive Functions of Symbolic Expressions and Their Comuptation by Machine, Part I» by John McCarty, April 1960

for IBM 704 про его CAR,CDR регистры тоже было где-то написано, как бы даже не в этой самой статье глава 4 или еще где более подробно.

далее читай главу 5.

5 Another Formalism for Function of Symbolic Expressions

we shall describe one of these variants linear LISP. The L-expressions are defined as follows: tl;dr

еще где-то про лисп в линейной памяти с линейными типами и регионами без GC – было, в другой публикации.

глава 6

6 Flowcharts and Recusion

прямо метапрог эдакий.

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

а дальше?

тю, слабак. вот justine.lol дальше смогло, причем и на сишке и на JS и на питоне.

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

еще евойный sectorlisp посмотри, там сразу в браузере обучающее видео с blinkenlights-отладчиком.

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

на вот, изучай до посинения реализацию cons-ов вон там:

https://justine.lol/sectorlisp2/

Memory Model
----------
NULL
+0
+2
+4
'N'
2
'I'
4
0
'L'
-2
+2 is IL
+4 is L
+0 is NIL
-0 is ()
+2
-2
-4
+4
-0
-2 is (L)
   or (cons 'L ())
-4 is (IL L)
   or (cons 'IL
       (cons 'L ()))
------------
The most important trick to implementing LISP is to redefine NULL.

function Set(i, x) {
  M[Null + i] = x;
}

function Get(i) {
  return M[Null + i];
}
LISP has two types of memory: atoms and cons cells. We store them in two adjacent stacks that grow outward from NULL.

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

все как ты любишь – вельми наглядно.

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

у него еще https://justine.lol/ про llammafile почитай, тоже прикольно – самодостаточное чятжпт метапроговое в одном файле:

https://hacks.mozilla.org/2023/11/introducing-llamafile/

https://github.com/Mozilla-Ocho/llamafile

ты ему такой:

дорогой чятжпт! пишет тебе метапрог. я джва года жду эту игру, в общем суть такова: есть жгутики и проводочки а еще CAR CDR атомы и консы и там домики набигают и всех нагибают

а оно тебе отвечает, и даже в тему:

«А вчерась мне была выволочка. Хозяин выволок меня за волосья на двор и отчесал шпандырем за то, что я качал ихнего ребятенка в люльке и по нечаянности заснул. А на неделе хозяйка велела мне почистить селедку, а я начал с хвоста, а она взяла селедку и ейной мордой начала меня в харю тыкать. Подмастерья надо мной насмехаются, посылают в кабак за водкой и велят красть у хозяев огурцы, а хозяин бьет чем попадя. А еды нету никакой. Утром дают хлеба, в обед каши и к вечеру тоже хлеба, а чтоб чаю или щей, то хозяева сами трескают. А спать мне велят в сенях, а когда ребятенок ихний плачет, я вовсе не сплю, а качаю люльку. Милый дедушка, сделай божецкую милость, возьми меня отсюда домой, на деревню, нету никакой моей возможности… Кланяюсь тебе в ножки и буду вечно бога молить, увези меня отсюда, а то помру…»

«Я буду тебе табак тереть, — продолжал он, — богу молиться, а если что, то секи меня, как Сидорову козу. А ежели думаешь, должности мне нету, то я Христа ради попрошусь к приказчику сапоги чистить, али заместо Федьки в подпаски пойду. Дедушка милый, нету никакой возможности, просто смерть одна. Хотел было пешком на деревню бежать, да сапогов нету, морозу боюсь. А когда вырасту большой, то за это самое буду тебя кормить и в обиду никому не дам, а помрешь, стану за упокой души молить, всё равно как за мамку Пелагею. А Москва город большой. Дома всё господские и лошадей много, а овец нету и собаки не злые. Со звездой тут ребята не ходят и на клирос петь никого не пущают, а раз я видал в одной лавке на окне крючки продаются прямо с леской и на всякую рыбу, очень стоющие, даже такой есть один крючок, что пудового сома удержит. И видал которые лавки, где ружья всякие на манер бариновых, так что небось рублей сто кажное… А в мясных лавках и тетерева, и рябцы, и зайцы, а в котором месте их стреляют, про то сидельцы не сказывают. Милый дедушка, а когда у господ будет елка с гостинцами, возьми мне золоченный орех и в зеленый сундучок спрячь. Попроси у барышни Ольги Игнатьевны, скажи, для Ваньки».

«Приезжай, милый дедушка, — продолжал Ванька, — Христом богом тебя молю, возьми меня отседа. Пожалей ты меня сироту несчастную, а то меня все колотят и кушать страсть хочется, а скука такая, что и сказать нельзя, всё плачу. А намедни хозяин колодкой по голове ударил, так что упал и насилу очухался. Пропащая моя жизнь, хуже собаки всякой… А еще кланяюсь Алене, кривому Егорке и кучеру, а гармонию мою никому не отдавай. Остаюсь твой внук Иван Жуков, милый дедушка приезжай».

а хотелось бы конпелирующихся кодов.

и чтобы не

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

а с нормальной реализацией

А еды нету никакой.

милый дедушка, чятжпт Константин Макарович. забери ты меня отсюдова. в свою деревню, в свой метапрог.

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

ведь append работает не с cons в любом виде

Тебе уже сказали, что append копирует исходный список. Т.е. делает не cons, а в среднем 50000 cons каждый раз, плюс собственно чтение и запись.

пишем совсем другую программу

Это другое, ага. И не лень же тебе всякой хернёй страдать? Заканчивай эту клоунаду уже, всем всё понятно.

no-such-file ★★★★★
()
Последнее исправление: no-such-file (всего исправлений: 1)
Ответ на: комментарий от anonymous

имхо склад_впечатление что есть активное противодействие слишком быстрой гомогенизации уже оцифрованного - возможно что бы сохранить общую экспансию в ещё не в цифре

т.е всё большее ориентирование на посторонних в ИТ делает не возможными(пока?) технологии предполагающие ценз пользователей

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

Так давай именно cons и сравнивать. То есть, добавление элемента в начало списка

(defun main ()
  (declare (optimize (speed 3)))
  (let ((n 99999) (l '()) (sum 0))
    (loop for i from 0 to n
	  do (setq l (cons i l)))
    (setq sum 0)
    (loop for i in l
	  do (setq sum (+ sum i)))
    (format t "~d~%" sum)))

0.004 seconds of real time

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char **argv)
{
	long n = 99999, *l = NULL, count = 0, sum = 0;
	for (long i = 0; i <= n; i++) {
		l = realloc(l, (count + 1) * sizeof(long));
                memmove(l, l + sizeof(long), count * sizeof(long));
		l[0] = i;
                count++;
	}
	for (long i = n; i >= 0; i--) sum += l[i];
	printf("%ld\n", sum);
}

real 0m2,323s

Вот сишная версия оказалась 580 раз медленнее.

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

Устал от твоих бредней.

Тебе уже сказали, что append копирует исходный список. Т.е. делает не cons, а в среднем 50000 cons каждый раз, плюс собственно чтение и запись.

Хотел поспорить, это же простейшая оптимизация, но пожалуй поверю что set-cdr они не догадались прикрутить...

Ну давай сделаю на cons, все так же тормозит, невероятным образом тормоза сами собой не прошли, может стоило читать мои комментарии? Попробуй. Вдумчиво.

(defun main ()
  (declare (optimize (speed 3)))
  (let ((n 99999) (l '()) (sum 0))
    (loop for i from 0 to n
	  do (setq l (cons i l))) ;; <----- Сделал
    (loop for i from 0 to n
	  do (setq sum (+ sum (nth i l))))
    (format t "~d~%" sum)))

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

Я уже устал от подобных «переделываний». Неужели ты не видел пару штук таких же до тебя? Мне они не интересны.

Я уже писал, что я мог бы подобрать пример где нужен случайный доступ, но вы просто игнорируете, почему?

Жду когда в новом комментарии довольный лиспер покажет (format t «4999950000»), и напишет какой я дурачек, не умею программировать, ведь в программе все числа константые, можно и вручную вычислить результат.

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

Так сам научись считать, тут можно весь пример заменить на (format t «4999950000»), но такому «умнику» как ты, не дано знание математики на уровне школы, иначе бы посчитал уже давно сумму. Иди учись программировать короче, потом будешь в тред отвечать.

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

тут можно весь пример заменить на (format t «4999950000»)

Возможно gcc так и делает, кстати. Но речь не об этом, а о том, что ты опять срёшь себе в тапки и бегаешь по cons-ам 50000 раз на итерацию.

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

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

Во вторых я специально написал что С без оптимизаций, поэтому gcc в один printf ничего не сворачивает, ты даже ОП-пост пропустил?

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

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

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

Отдельный вопрос конечно при чём тут вообще cons?

no-such-file ★★★★★
()
Последнее исправление: no-such-file (всего исправлений: 1)
Ответ на: комментарий от MOPKOBKA

Я уже писал, что я мог бы подобрать пример где нужен случайный доступ, но вы просто игнорируете, почему?

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

Если есть задачи: «Добавлять в коллекцию по одному элементы от 1 до 9999» и «Вычислить сумму элементов коллекции», то они прекрасно решаются на списках. Причём, если добавлять надо в начало коллекции, решаются намного эффективнее, чем на массивах.

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

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

В лиспе каждая функция ограничена скобками. Многие функции имеют заранее известное число параметров и известные их типы. Поэтому при выполнении, если функция получает что-то неожиданное, то будет ошибка (в Common Lisp при этом программа не прерывается, а приостанавливается, можно сразу внести исправления и продолжить).

А в форте есть +, берёт два параметра. Но если поставить лишний, то не будет ошибки, лишний просто останется на стеке (и закроет результат той функции, что была до +). В результате ошибку наблюдаешь не там, где она допущена, а в совсем другом месте.

Как если бы на Си все типы были int (и приводились бы к указателю и обратно автоматически) и все функции описывались с произвольным количеством аргументов (как printf).

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

кста да

для меня лично откровение в :

http://rkka21.ru/docs/turing-award/cb1973r.pdf

Бахман программист навигатор ( не без афторитета)

но как-то калейдоском(али пазл) сложился ибо в тексте и намёк на киберпанк 80ых - т/е очевидно не все(да я ознакомся в 73 этого не увидел бы именно «история истории» <очевидная> post-factum ) увидели но мотив у киберпанка и киберспейка ровно навигация в умопостигаемозрительном пространстве

так и приземление «оторваных» от реальности и хэшей и сортировок на лентах

ну и понимание что же есть корочки :)

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

позвольте позвольте

в форте «очень легко»(и это реальная причина не массовости) добавить слово терминатор которое делает «эфект» закрывающей скобки и из бинарных получаем произвольно-арные - если за аргументе принимаем всё со стека пока не встретим «\0» ( полная аналогия с вариантом либо строка со явным счётчиком длины либо строка с терминатором [ забывают что вариантов больше 2 в частности rope-строки]

ну и постояная «перевнутость» форта - Хотя имхо Хомский считает что это просто дело нашей привычки

форт мог стать мэйстримом случись ядерка и полный дефицит памяти

qulinxao3 ★☆
()