27 сентября исполняется 68 лет Ларри Уоллу — программисту, разработавшему популярный клиент rn — newsreader для групп новостей Usenet, во многом благодаря которому спустя десяток лет на свет появилась ОС Linux. Но широкую известность он получил после создания языка Perl, который нашел применение на заре Интернета в качестве инструмента для сборки интерактивных и динамических сайтов. Однако изначально Perl был придуман совсем не для этого. Язык отличается богатыми возможностями по обработке текста и регулярных выражений, что, впрочем, не удивительно: по образованию Ларри Уолл является дипломированным лингвистом. Путь специалиста по языкознанию в профессиональные программисты оказался тернист, но весьма интересен.
Ларри Арнольд Уолл родился в 1954 году Лос-Анжелесе в семье протестантского священника. Вскоре семья переехала в небольшой город Брементон, штат Вашингтон. В юности Ларри мечтал стать священнослужителем, как его отец, и по мнению ближайших родственников был абсолютным гуманитарием. Наверное, поэтому Уолл поступил в Тихоокеанский университет Сиэтла на специальность «химия», однако позже он перевелся на факультет естественных языков, где и получил степень бакалавра в 1976 году.
Еще в студенческие годы Ларри Уолл женился, и у них с супругой появилась одна мечта на двоих: найти где-нибудь на просторах Африки бесписьменный язык, и создать для него систему письма, над которой он тогда трудился. Однако запланированная им экспедиция в Африку была отменена: состояние здоровья Уолла не позволило ему покинуть Соединенные Штаты.
После краха идеи стать африканским Кириллом и Мефодием в одном лице, Ларри решил немного сменить приоритеты. Параллельно с учебой Уолл подрабатывал в университетском вычислительном центре, и там он решил совместить свое увлечение лингвистикой с религиозным воспитанием, полученным в семье. В качестве хобби он вместе с женой стал переводить Библию на разные языки мира, и для ускорения этого процесса решил использовать современные компьютерные технологии. А именно, применить придуманную им систему письма для ввода в компьютер, обработки и перевода текстов Библии. Именно так и зародился Perl. Язык понемногу совершенствовался, разработчик добавлял в него все новые возможности, и окончательно Perl сформировался уже после окончания Уоллом аспирантуры, в 1987 году, когда он устроился на работу в System Development Corporation, фирму, которая позже стала частью корпорации Unisys.
Perl принято расшифровывать как Practical Extraction and Report Language («практический язык для извлечения данных и составления отчётов»), хотя многие современники именовали его не иначе, как Pathologically Eclectic Rubbish Lister («патологически эклектичный перечислитель мусора»). Впрочем, сам Ларри Уолл неоднократно утверждал, что название языка не является акронимом: оно пришло ему в голову, как отсылка к Евангелию от Матфея, стих 13:46: «Еще подобно Царство Небесное купцу, ищущему хороших жемчужин, который, найдя одну драгоценную жемчужину, пошел и продал все, что имел, и купил ее».
В этом есть определенный символизм: если верить многочисленным интервью, Уолл трудился над собственным языком не ради заработка — он вообще не планировал делать на этом деньги. Ларри посвятил этому проекту все свое свободное время ради популяризации христианства, а также для того, чтобы помочь другим программистам решать насущные задачи по обработке больших массивов структурированных текстовых данных. Он сделал исходники Perl общедоступными и распространяемыми на основе бесплатной лицензии, за что удостоился первой награды Free Software Foundation за продвижение свободного программного обеспечения. Тем не менее Perl стал основой бизнеса для множества успешных стартапов и интернет-компаний: именно на этом языке был написан движок первой версии портала Yahoo и интернет-магазина Amazon. Благодаря Perl интернет-предприниматели в начале 90-х и в эпоху «бума доткомов» заработали миллиарды долларов.
Символом созданного им языка Уолл сделал верблюда — удивительное животное, которое
BEFOREHAND: close door, each window & exit; wait until time.
open spellbook, study, read (scan, select, tell us);
write it, print the hex while each watches,
reverse its length, write again;
kill spiders, pop them, chop, split, kill them.
unlink arms, shift, wait & listen (listening, wait),
sort the flock (then, warn the "goats" & kill the "sheep");
kill them, dump qualms, shift moralities,
values aside, each one;
die sheep! die to reverse the system
you accept (reject, respect);
next step,
kill the next sacrifice, each sacrifice,
wait, redo ritual until "all the spirits are pleased";
do it ("as they say").
do it(*everyone***must***participate***in***forbidden**s*e*x*).
return last victim; package body;
exit crypt (time, times & "half a time") & close it,
select (quickly) & warn your next victim;
AFTERWORDS: tell nobody.
wait, wait until time;
wait until next year, next decade;
sleep, sleep, die yourself,
die at last
В целях популяризации языка в 1995 году Уолл написал вместе с соавтором Рейнольдом Шварцем быстро ставшую бестселлером книгу «Programming Perl» (также известную под неофициальным названием “The Camel Book” из-за изображенного на обложке верблюда), и вскоре перешел на работу в издательство O’Reilly Media в качестве редактора, где продолжил издавать книги, посвященные Perl. В 2004 году Ларри Уолл занял пост старшего научного сотрудника в компании NetLabs, и продолжает сотрудничество с O’Reilly. Вместе с супругой и детьми он живет в самом сердце Кремниевой долины — городе Маунтин-Вью, Калифорния.
Несмотря на то, что в наши дни в интернет-индустрии и сфере разработки сайтов на смену Perl пришли языки PHP и Python, Perl по-прежнему используется для создания скриптов в UNIX-подобных системах, особенно, если эти сценарии применяются для синтаксического разбора и обработки текстовых данных.
Комментарии (29)
mitya_k
27.09.2022 10:34Мой первый язык программирования) Там много было интересных подходов, которые перетекли в другие языки. Жаль Perl 6 убил развитие Perl 5, на котором все писали...
AlexandreFrolov
27.09.2022 10:40+6Постоянно появляются новые версии Perl 5
https://github.com/Perl/perl5Версия v5.37.4 была добавлена 6 дней назад.
Cheater
27.09.2022 13:00+2До сих пор пишу на нём клей и прототипы и скрипты, Python не знаю, стимула переходить на Python как-то особо и нет. ООП/ФП нет, язык напрочь императивный, но дело делает лучше шелла.
Типобезопасность в нём конечно ужасна (гм хотя как может быть ужасно то, чего нет) и по рукам он не бьёт почти никогда. Сигнатуры функций например (т.е. тупо объявить аргументы функции) появились в нём только в 5.20 и считаются офигеть какой инновацией.
AlexandreFrolov
27.09.2022 13:08+2В некоторых проектах, которые нормально работают, не вижу особого смысла переходить на какие-то другие инструменты, так как не видно ни тактических, ни стратегических преимуществ. При этом затраты на переход значительны.
Интересно было бы узнать у тех кто мигрировал сайты интернет-магазинов и аналогичные проекты с Perl, что они теперь решили использовать, почему, и насколько затратен и сложен оказался переход.
staticmain
27.09.2022 21:36+5Мы мигрировали часть нашей инфраструктуры с perl на С - старый вариант стало вообще невозможно поддерживать из-за каши, макарон и write-only языка. Мигрировали болезненно (до сих пор мигрируем). Но зато веб-страницы, которые грузились несколько секунд на Mojo стали работать мгновенно, потребление памяти упало с нескольких сотен мегабайт до единиц метров, про скорость работы бека вообще молчу.
ИМХО на Perl можно делать склейки (как на bash или python), делать минимальные обвязки. Но делать на нем большие проекты категорически противопоказано.
sappience
27.09.2022 22:04-2старый вариант стало вообще невозможно поддерживать из-за каши, макарон и write-only языка
А причем тут Perl? Это у вас в голове спагетти. И C вас не спасет, сейчас все хорошо не из-за отказа от Perl, а от вынужденного рефакторинга. Но через какое-то время при таком подходе вы накопите спагетти и в C (кстати, странный выбор для веб-приложений, вы б еще на ассемблере писали). И будете вспоминать с ностальгией как в Perl медленно, но работало, и память не текла (в C за ней самому следить надо) и с Segmentation Fault не падало. И как регулярное выражение к текстовой строке применить занимало одну строчку, а не две страницы текста и подключение еще одной библиотеки при компиляции.
F0iL
27.09.2022 23:44+1Тем не менее, репутация языка, на котором пишут write-only code, именно у Perl появилась видимо не просто так.
AlexandreFrolov
28.09.2022 08:44Могу сказать, что непонятно можно писать на любом языке. Вот знаю одного программиста, который в памяти собирал слова из отдельных бит, в одних местах программы их менял, а в других - проверял. Комментариев к этим битам не было, конечно)
Кстати, писал он на Паскале.
staticmain
28.09.2022 00:10И будете вспоминать с ностальгией как в Perl медленно, но работало, и память не текла
Простите, у кого не течет память? У perl? Вы писали на Perl что-то сложнее hello world? Он жрет как не в себя, при этом НЕ отдавая память обратно в систему считая, что она пригодится в будущем. У Perl есть критический недостаток в отсутствии изкоробочных threads, (зачатки которых появились в 2.27, что выше чем та версия, на которую всё было завязано) из-за чего просто пропинговать ряд устройств занимало 25 секунд из-за того, что многопоток был недоступен. Fork дублировал всю память, которую perl нажирал из-за Mojo, MySQL и тонны других библиотек. В итоге обычный пингер который пишет результат в базу работал 25 секунд и жрал 100+ метров. Сишный аналог выполняется за 2 секунды и ест на уровне погрешности дефолтного аллокейта стека.
Но через какое-то время при таком подходе вы накопите спагетти и в C (кстати, странный выбор для веб-приложений, вы б еще на ассемблере писали).
в C за ней самому следить надо) и с Segmentation Fault не падало.
У вас нет нужной компетенции в С чтобы так говорить. Правильно написанный код не падает с SegFault и при его написании никак не мешает использовать освобождение памяти. Наш код проверяется статическими и динамическими анализаторами, часть из которых встроена в автоматический CI/CD.
кстати, странный выбор для веб-приложений, вы б еще на ассемблере писали
На ассемблере у нас подсчет хешей. А веб приложения по причине ограниченной памяти на конечных узлах. Поверьте, то что это С никак не влияет на скорость разработки, мы API планируем дольше чем его пишем. Любой другой бекенд будет жрать больше, чем там есть памяти в 10 раз. У нас есть другой бек на Scala, который именно такие аппетиты и имеет.
g_server_instance = fen_server_create( pls_port_webgui, NULL ); <...> fen_handler_add( g_server_instance, NULL, NULL, edd_request_process ); <...> for (i = 0; i < BXI_ARRAY_SIZE(requestables); i++) { if (bxi_strcmp(path_relative, requestables[i].resource) == 0) { edd_resource_add( requestables[i].method, requestables[i].uri, (const char *)file->data, file->size, requestables[i].json, NULL ); frs_inf(" + \"%s\"", path_relative); added = true; } }
Ой, кажется я только что поднял веб-сервер и добавил туда ресурсы из списка. Сложно то как....
sappience
28.09.2022 03:14У вас нет нужной компетенции в С чтобы так говорить.
Вы со мной знакомы чтобы это утверждать?
staticmain
28.09.2022 03:48+1Я это понял по вашим заявлениям про сегфолты и тродности написания кода. Это стереотип.
0xd34df00d
28.09.2022 05:05+3Правильно написанный код не падает с SegFault и при его написании никак не мешает использовать освобождение памяти.
Жаль, что правильные люди, способные писать правильный код без сегфолтов, утечек, UB и прочего, настолько редки, что лично я с ними не встречался вообще никогда (даже за большие деньги), да и во всяких гуглах, линукс-кернелах, openssh с ними проблема.
Правда, у меня опыт плюсовый.
Ой, кажется я только что поднял веб-сервер и добавил туда ресурсы из списка.
Из какого списка, если вы добавляете только
path_relative
, который внутри цикла не меняется? По крайней мере, я надеюсь, что не меняется, но в C и C++ никогда в этом нельзя быть уверенным без взгляда на кишкиbxi_strcmp
.Кстати, ради интереса, а сколько обычно записей в
requestables
?Как мне, глядя только на
edd_resource_add
, понять, какие аргументы вообще могут бытьNULL
?Как мне понять, передаётся владение у третьего параметра или нет, и что с ним вообще происходит? Могу ли я закрывать файл после
edd_resource_add
?Ну это так, просто вопросы сходу.
staticmain
28.09.2022 11:03+1На эти вопросы есть ответы в документации к функциям. path_relative - относительное имя файла, на который сейчас указывает итератор по каталогу. Записей может быть сколь угодно много. strcmp почти идентичен за исключением защиты от падения при NULL, файл закрывать можно, библиотека сделает копию
0xd34df00d
28.09.2022 21:00+1На эти вопросы есть ответы в документации к функциям.
Документация не проверяется компилятором.
Записей может быть сколь угодно много.
Точно ли тогда O(n)-скан списка оптимален? Не лучше ли сформировать хеш
path_relative
↦requestable
? Насколько быстро вам в C будет проверить эту гипотезу?файл закрывать можно, библиотека сделает копию
А если я не хочу копию? Если я работаю на железке, где памяти мало (вы сами писали, что там памяти мало), но есть нормальный линукс, скажем, и я сделал
mmap
большому ресурсу, чтобы ядро там само управляло страницами с этим ресурсом, то я не хочу ничего никуда копировать, я хочу просто отдать указатель заммапленную память. Как это сделать в вашем фреймворке?staticmain
28.09.2022 22:12Документация не проверяется компилятором.
Несоответствие входящих типов проверится компилятором + рантайм анализаторами (valgrind, memcheck) + адекватностью работы (тестирование важно, да. Даже если для него нужно написать отдельный сервис-эмулятор). Ну и PR-Review
Точно ли тогда O(n)-скан списка оптимален?
А там просто рекурсивный проход по директории - защита от взлома путем подстановки путей типа "../../../passwd" - если есть только readonly список доступных ресурсов, сформированный на этапе компиляции\инициализации, то система более надежна. Функционал сервисов, что мы запускаем обычно укладывается в несколько страниц html (формируемых по шаблону и данных), c полдесятка *.css, и такого же количества *.js. Плюс картинки, плюс шрифты и проч. Нет смысла особо оптимизировать проход по списку, когда он выполняется за <10 ms.
А если я не хочу копию? Если я работаю на железке, где памяти мало (вы сами писали, что там памяти мало), но есть нормальный линукс
Памяти мало, но не настолько. Последний такой сервис поднимали для 2GB Raspberry, потребление не превышает 3 MB + сумма размеров отдаваемых ресурсов (храним в памяти чтобы не тыкать лишний раз SD).
Как это сделать в вашем фреймворке?
Сейчас такой задачи не стояло. Будет такая потребность - сделаем расширение функционала, чтение с ФС при каждом запросе с кешированием на N секунд. Раньше оно, кстати, копию не делало - это недавнее изменение связанное с тем что раньше мы все ресурсы компоновали в бинарь и они всегда были доступны по константной ссылке. Сейчас (чтобы дать возможность фронтам редактировать файлы без рекомпиляции) вынесли наружу.
0xd34df00d
28.09.2022 22:22+1Несоответствие входящих типов проверится компилятором
null где не надо компилятор не найдёт. Перепутанный method и uri тоже, тащем.
рантайм анализаторами (valgrind, memcheck)
Если вы способны дождаться завершения работы кода под valgrind, то вам ещё повезло. Если баги не плавающие и не пропадают под valgrind (asan, etc) — повезло вдвойне.
Плюс, рантайм-анализаторы не способны гарантировать отсутствие багов. В отличие от типов.
- адекватностью работы (тестирование важно, да. Даже если для него нужно написать отдельный сервис-эмулятор). Ну и PR-Review
И всё это — лишь бы не писать на нормально типизированных языках.
А там просто рекурсивный проход по директории — защита от взлома путем подстановки путей типа "../../../passwd" — если есть только readonly список доступных ресурсов, сформированный на этапе компиляции\инициализации, то система более надежна.
Не понял связи с защитой от взлома, ну да ладно, видимо, это слишком контекстно-зависимо.
Эх, был бы какой-то способ выразить в типах отсутствие относительных путей, например…
Нет смысла особо оптимизировать проход по списку, когда он выполняется за <10 ms.
Чтобы под валгриндом сэкономить уже секунду :]
Памяти мало, но не настолько. Последний такой сервис поднимали для 2GB Raspberry, потребление не превышает 3 MB + сумма размеров отдаваемых ресурсов (храним в памяти чтобы не тыкать лишний раз SD).
Да это неважно. Вы ж пишете, какой у вас фреймворк универсальный получился, вот мне и интересно, где эта универсальность заканчивается.
Раньше оно, кстати, копию не делало — это недавнее изменение связанное с тем что раньше мы все ресурсы компоновали в бинарь и они всегда были доступны по константной ссылке. Сейчас (чтобы дать возможность фронтам редактировать файлы без рекомпиляции) вынесли наружу.
А прикиньте, как было бы здорово, если бы там как-нибудь сами учитывались времена жизни либо рефкаунт какой-нибудь хотя бы?
staticmain
28.09.2022 22:38И всё это — лишь бы не писать на нормально типизированных языках.
Так вам никто не мешает сгенерировать типов через typedef чтобы анализаторы заметили несоответствие. Но у нас уже есть устаканенный порядок аргументов, поэтому на такие ошибки еще не напарывались.
Плюс у вас страничка работать не будет, если вы перепутаете method и uri, первое же тестирование и придет тестировщик и побьет вас палкой.
Если вы способны дождаться завершения работы кода под valgrind, то вам ещё повезло.
Мы разбиваем большие демоны на микросервисы, поэтому проблем с долгой отладкой обычно нет. Например перенастройка сетевых настроек на узле состоит из трех демонов - веб-интерфейса который умеет отдавать странички с POST-формами для изменения, демона который такие запросы обрабатывает и умеет менять сетевые конфиги и демон, который умеет детектировать провалы тоннеля и отдавать данные во второй, чтобы тот, например, перезагрузил тоннель. Из-за того, что по факту изменения применяет ровно одна точка - то есть адекватный lock/unlock а cloc при этом 1400, 1100, 400 соответственно (без учета библиотек).
А прикиньте, как было бы здорово, если бы там как-нибудь сами учитывались времена жизни либо рефкаунт какой-нибудь хотя бы?
У нас есть библиотека для подсчета ссылок, кое-где используется :D
0xd34df00d
28.09.2022 22:45+1Так вам никто не мешает сгенерировать типов через typedef чтобы анализаторы заметили несоответствие.
Это какой анализатор показывает несоответствие между
myint
иint
дляtypedef int myint;
?
Я уж не говорю о том, что через тайпдефы всё не выразишь.
Плюс у вас страничка работать не будет, если вы перепутаете method и uri, первое же тестирование и придет тестировщик и побьет вас палкой.
Я хочу, чтобы меня бил палкой редактор кода и сразу, а не тестировщик и через два дня.
staticmain
28.09.2022 22:49Между myint и int не покажет, но если делать struct, то даже дефолтные опции сборки скажут "Форзихт!": https://onlinegdb.com/5n3Sbk5hy
Понятно, что это извращения, но это вообще не самая популярная ошибка и если вы так беспокоитесь за них - вам нужен другой язык.
0xd34df00d
30.09.2022 03:00Ну так
struct
— это неtypedef
, это вы не можете написатьMyInt s1, s2; s3 = s1 + s2;
, потому что у вас больше плюсика нет. Это не C++, где есть хотя бы перегрузка операторов, и уж тем более не хаскель, где можно просто написатьnewtype MyInt = MyInt Int deriving (Eq, Ord, Hashable, Num, Integral, ...)
но это вообще не самая популярная ошибка
Кстати, чисто из интереса — что вы бы у себя назвали популярными ошибками?
если вы так беспокоитесь за них — вам нужен другой язык.
Ну так :]
RTFM13
29.09.2022 13:51+1На сях легко писать код который не ликает и не падает и читается легко, выполняя небольшой набор простых правил. Вопрос не квалификации а дисциплины, скорее. Но при этом многократно теряется гибкость языка и слегка вырастает прожорливость.
Второй минус такого подхода - все используемые библиотеки сами должны быть написаны аналогично.
Впрочем, у меня, как у эмбедера, кроме сей и выбора-то никакого нет.
AlexandreFrolov
28.09.2022 08:43Наверное при переходе с Perl на C вам и команду программистов пришлось менять?
Или перловиков переучивали?staticmain
28.09.2022 11:03Там сменилось три поколения перловиков, оригинальной команды 10+ лет как уже нет.
radioxoma
27.09.2022 21:07+2был абсолютным гуманитарием.
Наверное, поэтому Уолл поступил в Тихоокеанский университет Сиэтла на специальность «химия»
Химия, конечно, предмет для истинных гуманитариев. Даже калькулятор на экзамен разрешают брать.
coder_ept
мой первый язык....эх вспоминаю ночи которые провел за книгой
CyberPaul Автор
Я тоже на нем кодил немножко.