Давайте скажем ещё проще — нужно сесть и подумать. И результат обязательно будет.
Чем такой вариант хуже вашего? Он точно так же не показывает сложность промежуточных шагов. И точно так же выглядит «просто».
И за одно — градиентный спуск может остановиться в локальном экстремуме. А целевая функция может не соответствовать потребностям всё из-за той же сложности. Ну и вообще аналогии могут увести в такие дебри, что потом не отмоешься.
Надо признать — сложность просто не устраняется. Ну и жить с этим.
Успешных бизнесов «с нуля» и только ради потребления, на мой взгляд, просто нет. От папы с мамой по наследству — это есть, но что бы реально работать — да ни за что. То есть потребление не является достаточным стимулом.
И наоборот — волевой человек, привыкший к скромной жизни, легко может потратить много энергии на дело. Ну и результат, иногда, тоже случается. А вот безвольный потребитель — ну как он может себя заставить? Только от папы с мамой.
если на множестве решений можно задать операцию дифференцирования, то вопрос с поиском наиболее простого решается несложным алгоритмом
Есть одна структура, рядом есть другая. В каждой по 1000 отличающихся от соседа элементов. Эта 1000 = производная. Дайте несложный алгоритм, устраняющий эту сложность.
Оловянный произносится именно с двумя н. Произнесёте с одной — вас примут да деревенщину. И произнесут — смешной. С одной н. А если произнесут с двумя — вы сами над ними посмеётесь.
Поэтому не надо ждать реформы в тех местах, где она, по здравому размышлению, совершенно не нужна.
А вы думали, что сразу разберётесь в мегабайтах документации? Что бы найти нужное место требуется определённый опыт, и по работе с БД и по самой документации.
А вы целиком понимаете, как ваш код на вашем любимом императивном языке программирования исполняется на процессоре?
У меня там не возникало вопросов вроде определения шагов для вычисления ленивого списка. А когда что-то непонятно, то всегда есть довольно простые гипотезы о соответствии моего кода и скомпилированного. Пробуем гипотезу, меряем время/память, выясняем что подходит.
А вот в хаскеле с тем же ленивым списком, если предположить, что вместо списка создаётся структура, содержащая описание вычисления, то тогда получится, что на императивном языке я могу создать в десятки раз больше списков, потому что там нет таких затрат по памяти. То есть неочевидность здесь сложнее выявить и если гипотеза верна — явно имеем большой расход памяти.
Я его вынес вне цикла, и код ускорился условно с 260 мс до 255 мс.
То есть у вас претензии к потере 5мс из 260? Два процента. Это явно излишняя оптимизация (в большинстве случаев). Тратить время на это нехорошо, потому что есть более важные задачи (обычно).
А по ассемблеру — если уж совсем по мелочам важно всё отследить, то лучше ассемблерные вставки делать. Там контроль полный и опять ненужно ничего декомпилировать.
Ну это уже отписка. И нельзя сравнивать документацию по функциям с документацией по алгоритмам, используемым БД. Функции — это лишь малая часть документации по БД.
Например на официальной вики? Про то как работает непосредственно вычисление можно почитать по ссылке WFNF.
Посмотрел, но там же стандартные пояснения про тривиальные случаи. Это и так понятно. Мне же хотелось понять, как конкретно увязаны неизменность списка с ленивостью его заполнения. Из стандартного объяснения про сохранение вычисления и его реальную обработку «когда надо» непонятно как же обрабатывается ленивый список из функции Фибоначчи. То есть «реально надо», когда я прошу дать мне первый элемент, а потом «реально надо», когда прошу дать второй, и т.д. На котором шаге что считается? Где неизменность списка? Где смысл функции, возвращающей всегда один и тот же результат при неизменных аргументах? Как это всё увязывается в реальности?
В императивной программе точно так же надо смотреть на ассемблерные листинги и что там получилось.
В С есть так называемые intrinsics, которые напрямую транслируются в ассемблерный код. Оптимизация выполняется именно с их помощью. И при этом нет никакой необходимости смотреть «что там получилось» в ассемблерных листингах.
В языках с байткодом такая же ситуация, точнее там вообще нельзя посмотреть такой листинг, ну и в том числе поэтому и не смотрят.
А вот хаскель компилируется в машинный код и его тут недавно (была статья) декомпилировали именно для понимания, а что же он там делает.
Если это считать деталями алгоритма, то любой фпшный fmap это тоже «детали алгоритма», которые можно так же посмотреть.
А где вы смотрите детали? По БД есть очень хорошая документация, а вот по хаскелю — надо всё искать (если что-то сложнее основ). Вплоть до изучения кода компилятора.
Как работает ленивость? Автор статьи упомянул ленивое вычисление списка чисел Фибоначчи — как этот список получается (императивно)? Где искать?
Не вижу принципиальной разницы. Смотреть план запроса или в вывод гхц.
Но в обычной программе (императивной) вообще нет необходимости смотреть какие-то планы/выводы. Точнее в большинстве случаев достаточно просто подумать.
Как я понял, там применяется смесь из нейросетей с обработкой на основе различных эвристик. Как-то можно классифицировать эти эвристики? Например был шум на тему semantic web, что-то подобное применяется при переводе? По логике там ему самое место, но по факту там рулит статистика и нейросети. Ну и может что-то ещё.
А если автору не трудно (пусть в виде рекламы своей компании), было бы интересно почитать статью именно про технологическую часть.
И кстати, раз уж статья целится на поиск знатоков NLP, то интересно, а какие задачи они будут решать? Ведь основа давно задана, никакие вольности в виде исследований не позволительны (ограничение по деньгам), и по сути получается, что нужны просто знакомые с используемыми в предметной области терминологией и алгоритмами люди, что бы им поставить задачу, ну и они её пилили как в обычных программистских конторах. Может даже вообще есть смысл иметь лишь одного эксперта, а всё остальное поручать гораздо более дешёвым помощникам, которым просто спускается план действий, может с какими-то пояснениями, мол вот с этого сайта текст надо скормить этой приблуде, она посчитает статистику, потом результат сохранится сюда, а ты выберешь из статистики такие-то части и включишь в программу для Андроида (в её базу данных).
И опять кстати, программа для Андроида имеет всего 1000 установок и непонятно сколько из них активны. Как-то мало.
У нас написано SELECT * FROM A JOIN B ON A.Id = B.EntityId, а там то ли цикл, то ли хэшмапа создалась, то ли сортировка началась.
Цикл или сортировка — внутренние сложности алгоритма нахождения соответствия записей из А и В. Абстрактный же алгоритм очень прост. Но если мне надо, то я легко найду внутренние детали реализации. Вот в этом простота.
Не знаю, что там штурмовать: сказали в курсе, что есть функция a -> m b, и если у тебя есть f a то можешь получить f b. Показали пример со списком, опциональным значением и футурой, всё стало понятно.
У меня был очень простой вопрос — а зачем так? Вы же целую статью на эту тему написали, объясняя зачем. И там много комментариев со спорами.
Ну а поверхностно понять, что «на входе Х, на выходе У» — это конечно легко.
Когда нужно — быстренько выучивают все, что надо
В случае с БД — да, там всё просто. А в случае с хаскелем — я бы так не сказал. Для оптимизации хаскель-программ используют опции, указывающие компилятору, где и как что-то делать, что бы он не нафантазировал чего-то непредвиденного. Но это непредвиденное, и даже место, где оно возникнет, нужно же понимать. Вот это и есть сложность. Она выше сложности БД. В БД может поменяться алгоритм сортировки или джойна, но концептуально это ничего не меняет, а вот в хаскеле указания компилятору меняют смысл программы (с ленивой на неленивую, например).
И что это докажет?
Докажет разницу в сложности. Большинство знающих хаскель легко разберутся с SQL, но большинству знающих SQL придётся нелегко, когда нужно будет разбираться с хаскелем.
Немного холодного душа для тех, кто пишет «ах какая мотивирующая статья!».
Для занятия бизнесом нужно очень хотеть заработать. То есть в обмен на все остальные удовольствия вы должны научиться извлекать приятное из очень затратной по времени и скучной работы по выявлению интересов абстрактного клиента и выбору методов удовлетворения этих интересов на уровне, сравнимом с конкурентами. Ну и без гарантий, разумеется. Точнее даже с гарантией того, что даже просто на самоокупаемость выйти будет трудно (а многим — невозможно).
При этом, разумеется, вы должны забыть о разного рода копании в алгоритмах, создании сложных систем и т.д. Это всё должны делать другие, потому что у вас не будет на это времени. Поэтому ваш путь пройдёт через open-source и прочие готовые/покупные технологии. Сами вы ничего разрабатывать не будете. А если будете — потеряете бизнес.
Но, конечно, пока не попробуешь — не поймёшь, так что — попробуйте, проверьте, ну вдруг вы попадёте в волну (одну на миллион) и вам ничего из указанного делать не придётся. А если не попадёте — вас ждёт довольно скучная (на мой взгляд) работа. Но может вам она покажется ближе, чем мне.
мне кажется, все таки употреблять термин «константа» (лат. constans, родительный падеж constantis — постоянный, неизменный) в таком смысле не правильно. В таком случае main в хаскелле тоже константа. То есть любая программа — константа.
Main общается с монадами, которые прячут внешние эффекты, а значит main не может быть константой из-за этих самых эффектов.
Я понимаю ваше неоднозначное восприятие программы примерно так — раз программа что-то выполняет, значит она не постоянная/неизменная. Но здесь уже получится скорее философский разговор, ведь, например, наличие движения в мире для нас — константа. Движение есть, всё меняется, но это всё присутствует постоянно и неизменно повторяется.
Можно ещё сказать, что константа (условно) даёт постоянный адрес в памяти, где лежит тот самый список. То есть вот вам постоянство и неизменность. А то, что сам список меняется (хотя как конкретно он меняется — не очень понятно, может даже вообще не меняется, а сразу получается путём копирования из стека вычисления всего того, что насчитали к моменту востребования списка) — к константе не имеет отношения, ведь адрес же не меняется.
Но ведь и ваше «императивное» понимание в определенной мере иллюзорно
Да иллюзорно, конечно, я не спорю, ведь регистры процессора я точно себе не представляю во время написания алгоритма, но важно отличать доступную сложность абстракции от условно недоступной. Доступная — это когда мне легко понять, почему вдруг код не работает. А недоступная — это когда я «смотрю в книгу и вижу фигу», то есть долго думаю над произошедшим. Ну и поэтому я предпочитаю понятные абстракции. А понятность как раз и связана с моей возможностью проследить алгоритм, если потребуется, хоть до конкретного регистра процессора. На этом строится вся оптимизация. А если я не знаю, как оно там внутри вертится, то и оптимизировать не смогу.
При программировании в императивном стиле тоже сколько угодно случаев, когда понимание того, как сделать правильно/эффективно подводит.
В данном случае «сколько угодно» меньше, чем это же «сколько угодно», но в случае с функциональным стилем изложения алгоритма. Проверено миллионами программистов, почему-то не пожелавших изучать хаскель, но легко осваивающих какой-нибудь питон.
Абстракции бывают разные. Абстракция SQL, как минимум для меня, очень понятна и я хорошо понимаю, как она ложится на императивно выражаемые алгоритмы. А вот абстракции из хаскеля я не все до такой степени понимаю. Возможно, это следствие отсутствия длительного периода использования хаскеля, ведь я с ним познакомился, поигрался, да и забыл о нём.
Но тем не менее, вспоминая те времена, когда я впервые знакомился с SQL, я отлично помню, что базовые абстракции там дались мне сразу и легко, а вот ту же абстракцию монад мне пришлось штурмовать гораздо дольше.
Ну и если посмотреть на других, то по ним видно, что оптимизацию запросов SQL осиливают далеко не все, что означает и в данном случае наличие заметной сложности. Хотя монады из тех, кто хорошо освоил SQL, так же понимает меньшинство. Правда моя статистика, понятно, субъективна. Но можно спросить на любом форуме по базам данных — кто из вас вообще знает про хаскель? А кто понимает вот этот код… и привести что-то с монадами. Ответ, мне кажется, будет соответствовать моей статистике.
Чем такой вариант хуже вашего? Он точно так же не показывает сложность промежуточных шагов. И точно так же выглядит «просто».
И за одно — градиентный спуск может остановиться в локальном экстремуме. А целевая функция может не соответствовать потребностям всё из-за той же сложности. Ну и вообще аналогии могут увести в такие дебри, что потом не отмоешься.
Надо признать — сложность просто не устраняется. Ну и жить с этим.
И наоборот — волевой человек, привыкший к скромной жизни, легко может потратить много энергии на дело. Ну и результат, иногда, тоже случается. А вот безвольный потребитель — ну как он может себя заставить? Только от папы с мамой.
Есть одна структура, рядом есть другая. В каждой по 1000 отличающихся от соседа элементов. Эта 1000 = производная. Дайте несложный алгоритм, устраняющий эту сложность.
Поручают молодому «гению» что-то бесконтрольно сочинять. Кто виноват? Тот кто поручил.
Требуют по быстрому в бой. Кто виноват? Кто требует по быстрому.
Веруют в зазнавшегося архитектора. Кто виноват? Верующий.
В общем случае — понятия не имеют о способах организации разработки. Кто виноват? Ответ очевиден.
Программист всегда крайний, поэтому на него и валят. А на самом-то деле…
Поэтому не надо ждать реформы в тех местах, где она, по здравому размышлению, совершенно не нужна.
На сколько я помню — везде вставляется признак strict mode.
Попробуйте сделать ленивый список и потом использовать strict mode. Я думаю случится что-то страшное (типа память кончится).
А вы думали, что сразу разберётесь в мегабайтах документации? Что бы найти нужное место требуется определённый опыт, и по работе с БД и по самой документации.
У меня там не возникало вопросов вроде определения шагов для вычисления ленивого списка. А когда что-то непонятно, то всегда есть довольно простые гипотезы о соответствии моего кода и скомпилированного. Пробуем гипотезу, меряем время/память, выясняем что подходит.
А вот в хаскеле с тем же ленивым списком, если предположить, что вместо списка создаётся структура, содержащая описание вычисления, то тогда получится, что на императивном языке я могу создать в десятки раз больше списков, потому что там нет таких затрат по памяти. То есть неочевидность здесь сложнее выявить и если гипотеза верна — явно имеем большой расход памяти.
То есть у вас претензии к потере 5мс из 260? Два процента. Это явно излишняя оптимизация (в большинстве случаев). Тратить время на это нехорошо, потому что есть более важные задачи (обычно).
А по ассемблеру — если уж совсем по мелочам важно всё отследить, то лучше ассемблерные вставки делать. Там контроль полный и опять ненужно ничего декомпилировать.
Ну это уже отписка. И нельзя сравнивать документацию по функциям с документацией по алгоритмам, используемым БД. Функции — это лишь малая часть документации по БД.
Посмотрел, но там же стандартные пояснения про тривиальные случаи. Это и так понятно. Мне же хотелось понять, как конкретно увязаны неизменность списка с ленивостью его заполнения. Из стандартного объяснения про сохранение вычисления и его реальную обработку «когда надо» непонятно как же обрабатывается ленивый список из функции Фибоначчи. То есть «реально надо», когда я прошу дать мне первый элемент, а потом «реально надо», когда прошу дать второй, и т.д. На котором шаге что считается? Где неизменность списка? Где смысл функции, возвращающей всегда один и тот же результат при неизменных аргументах? Как это всё увязывается в реальности?
В С есть так называемые intrinsics, которые напрямую транслируются в ассемблерный код. Оптимизация выполняется именно с их помощью. И при этом нет никакой необходимости смотреть «что там получилось» в ассемблерных листингах.
В языках с байткодом такая же ситуация, точнее там вообще нельзя посмотреть такой листинг, ну и в том числе поэтому и не смотрят.
А вот хаскель компилируется в машинный код и его тут недавно (была статья) декомпилировали именно для понимания, а что же он там делает.
А где вы смотрите детали? По БД есть очень хорошая документация, а вот по хаскелю — надо всё искать (если что-то сложнее основ). Вплоть до изучения кода компилятора.
Как работает ленивость? Автор статьи упомянул ленивое вычисление списка чисел Фибоначчи — как этот список получается (императивно)? Где искать?
Но в обычной программе (императивной) вообще нет необходимости смотреть какие-то планы/выводы. Точнее в большинстве случаев достаточно просто подумать.
Как я понял, там применяется смесь из нейросетей с обработкой на основе различных эвристик. Как-то можно классифицировать эти эвристики? Например был шум на тему semantic web, что-то подобное применяется при переводе? По логике там ему самое место, но по факту там рулит статистика и нейросети. Ну и может что-то ещё.
А если автору не трудно (пусть в виде рекламы своей компании), было бы интересно почитать статью именно про технологическую часть.
И кстати, раз уж статья целится на поиск знатоков NLP, то интересно, а какие задачи они будут решать? Ведь основа давно задана, никакие вольности в виде исследований не позволительны (ограничение по деньгам), и по сути получается, что нужны просто знакомые с используемыми в предметной области терминологией и алгоритмами люди, что бы им поставить задачу, ну и они её пилили как в обычных программистских конторах. Может даже вообще есть смысл иметь лишь одного эксперта, а всё остальное поручать гораздо более дешёвым помощникам, которым просто спускается план действий, может с какими-то пояснениями, мол вот с этого сайта текст надо скормить этой приблуде, она посчитает статистику, потом результат сохранится сюда, а ты выберешь из статистики такие-то части и включишь в программу для Андроида (в её базу данных).
И опять кстати, программа для Андроида имеет всего 1000 установок и непонятно сколько из них активны. Как-то мало.
Цикл или сортировка — внутренние сложности алгоритма нахождения соответствия записей из А и В. Абстрактный же алгоритм очень прост. Но если мне надо, то я легко найду внутренние детали реализации. Вот в этом простота.
У меня был очень простой вопрос — а зачем так? Вы же целую статью на эту тему написали, объясняя зачем. И там много комментариев со спорами.
Ну а поверхностно понять, что «на входе Х, на выходе У» — это конечно легко.
В случае с БД — да, там всё просто. А в случае с хаскелем — я бы так не сказал. Для оптимизации хаскель-программ используют опции, указывающие компилятору, где и как что-то делать, что бы он не нафантазировал чего-то непредвиденного. Но это непредвиденное, и даже место, где оно возникнет, нужно же понимать. Вот это и есть сложность. Она выше сложности БД. В БД может поменяться алгоритм сортировки или джойна, но концептуально это ничего не меняет, а вот в хаскеле указания компилятору меняют смысл программы (с ленивой на неленивую, например).
Докажет разницу в сложности. Большинство знающих хаскель легко разберутся с SQL, но большинству знающих SQL придётся нелегко, когда нужно будет разбираться с хаскелем.
Для занятия бизнесом нужно очень хотеть заработать. То есть в обмен на все остальные удовольствия вы должны научиться извлекать приятное из очень затратной по времени и скучной работы по выявлению интересов абстрактного клиента и выбору методов удовлетворения этих интересов на уровне, сравнимом с конкурентами. Ну и без гарантий, разумеется. Точнее даже с гарантией того, что даже просто на самоокупаемость выйти будет трудно (а многим — невозможно).
При этом, разумеется, вы должны забыть о разного рода копании в алгоритмах, создании сложных систем и т.д. Это всё должны делать другие, потому что у вас не будет на это времени. Поэтому ваш путь пройдёт через open-source и прочие готовые/покупные технологии. Сами вы ничего разрабатывать не будете. А если будете — потеряете бизнес.
Но, конечно, пока не попробуешь — не поймёшь, так что — попробуйте, проверьте, ну вдруг вы попадёте в волну (одну на миллион) и вам ничего из указанного делать не придётся. А если не попадёте — вас ждёт довольно скучная (на мой взгляд) работа. Но может вам она покажется ближе, чем мне.
Main общается с монадами, которые прячут внешние эффекты, а значит main не может быть константой из-за этих самых эффектов.
Я понимаю ваше неоднозначное восприятие программы примерно так — раз программа что-то выполняет, значит она не постоянная/неизменная. Но здесь уже получится скорее философский разговор, ведь, например, наличие движения в мире для нас — константа. Движение есть, всё меняется, но это всё присутствует постоянно и неизменно повторяется.
Можно ещё сказать, что константа (условно) даёт постоянный адрес в памяти, где лежит тот самый список. То есть вот вам постоянство и неизменность. А то, что сам список меняется (хотя как конкретно он меняется — не очень понятно, может даже вообще не меняется, а сразу получается путём копирования из стека вычисления всего того, что насчитали к моменту востребования списка) — к константе не имеет отношения, ведь адрес же не меняется.
Да иллюзорно, конечно, я не спорю, ведь регистры процессора я точно себе не представляю во время написания алгоритма, но важно отличать доступную сложность абстракции от условно недоступной. Доступная — это когда мне легко понять, почему вдруг код не работает. А недоступная — это когда я «смотрю в книгу и вижу фигу», то есть долго думаю над произошедшим. Ну и поэтому я предпочитаю понятные абстракции. А понятность как раз и связана с моей возможностью проследить алгоритм, если потребуется, хоть до конкретного регистра процессора. На этом строится вся оптимизация. А если я не знаю, как оно там внутри вертится, то и оптимизировать не смогу.
В данном случае «сколько угодно» меньше, чем это же «сколько угодно», но в случае с функциональным стилем изложения алгоритма. Проверено миллионами программистов, почему-то не пожелавших изучать хаскель, но легко осваивающих какой-нибудь питон.
Но тем не менее, вспоминая те времена, когда я впервые знакомился с SQL, я отлично помню, что базовые абстракции там дались мне сразу и легко, а вот ту же абстракцию монад мне пришлось штурмовать гораздо дольше.
Ну и если посмотреть на других, то по ним видно, что оптимизацию запросов SQL осиливают далеко не все, что означает и в данном случае наличие заметной сложности. Хотя монады из тех, кто хорошо освоил SQL, так же понимает меньшинство. Правда моя статистика, понятно, субъективна. Но можно спросить на любом форуме по базам данных — кто из вас вообще знает про хаскель? А кто понимает вот этот код… и привести что-то с монадами. Ответ, мне кажется, будет соответствовать моей статистике.