…живые программы?

Широко известный в узких кругах Steve Yegge изволит толковать о программах, не требующих ребута. Де, программа может жить вечно, и останавливать ее не надо. Надо двигатель на ходу перебирать. Сложнее, конечно — кто-то должен рулить, а кто-то в это время под капот лезть — но зато программа живет. А то ведь рестартом мы ее убиваем, бедненькую.

Это я поерничал немножко, конечно. Впрочем, обратитесь к первоисточнику. Там букв много, и статья явно провокационная, но почитать стоит. Феномен самоосознания там затрагивается, да. Собаки с кошками. Микрософт Эксель. Линукс. Прочие самоосознающие зверюшки. (Люди думающие скорее предпочтут пенроузовские “Shadows of the Mind”.)

Опустив всю воду, резюмирую основные моменты:

  1. …systems must be able to grow without rebooting. A system that can’t grow over time is static, so it really isn’t a system at all; it’s a function. It might be a very complex function with lots of possible inputs and outputs. It might be a very useful function, and it might live for a long time. But functions are always either replaced or subsumed by systems that can grow. And I’ve come to believe, over nearly two decades of thinking about this, that systems that can grow and change without rebooting can live forever.
  2. …my first argument against rebooting is that in nature it doesn’t happen. Or, more accurately, when it does happen it’s pretty catastrophic. If you don’t like the way a person works, you don’t kill them, fix their DNA, and then regrow them. If you don’t like the way a government works, you don’t shut it down, figure out what’s wrong, and start it back up again. Why, then, do we almost always develop software that way?
  3. Because most programmers nowadays prefer to build marionettes rather than scary real children, most programming is oriented towards building layer upon layer of hardware. C++ and Java programmers (and I’d be willing to bet, C# programmers) are by default baking every line of code they write into hardware by modeling everything in the type system up front.

Комментарий к первому пункту: bullshit.

Опубликовано в 8пп 02/17/07 | Комментарии (77) | Рубрики: философия, архитектура читать

On LISP

Как правило, знакомство с LISPом (не имею в виду какую-то конкретную реализацию) начинается с представления s-expressions как “особой записи привычных по другим языкам вызовов функций”. Это не очень точно и скучно. На мой взгляд, куда интереснее проследить рост лисп-программы с самых ее корней, от простейшей структуры данных.

Для тех, кто совсем-совсем не в теме — лисп-машина это полная по Тьюрингу система, состоящая из вложенных друг в друга вызовов eval(). Ну примерно так. Лисп (для краткости буду так дальше сию машину именовать) очень прост в синтаксисе. Что придает ему особую уникальность — одна из его главных selling points — код и данные представляются единообразно и зачастую друг от друга неотличимы. Это позволяет, например, написать программу, оптимизирующую саму себя.

Какая же базовая структура данных (и кода) в лиспе? Это т. н. cons: кортеж из двух элементов, первый из которых называется car/кар, а второй cdr/кедер (записывается как car . cdr). Над такой структурой определены одноименные операции: car[x . xs] = x; cdr[x . xs] = xs.

Через эту структуру можно легко определить список — это конс, кедер которого — список или символ. В лиспе списки представляются при помощи s-expressions; так, список, записанный в виде консов как a . [b . [c . d]] в лиспе выглядит как (a b c d). В приведенном выше случае car вернет a, cdr — (b c d).

Очевидно, консом можно сделать и кар. Конс, и кар и кедер которого — консы или символы — это, по сути, несортированное 1-2-B+ дерево. Дерево, записанное консами как [a . b] . [c . d] выглядит в лиспе как ((a b) c d). Понятно, что car возвращает левую ветвь дерева, а cdr — правую.

Опубликовано в 11пп 02/08/07 | Комментарии (1045) | Рубрики: архитектура, lisp читать

Архивы по месяцам