LINUX.ORG.RU
ФорумTalks

лямбды в новых язычках - PR или реальные полезняшки?

 , ,


7

7

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

Ну что есть lambda в каком-нибудь lisp я представляю и даже понимаю зачем оно и как им пользоваться. В lisp'е. А что имеется ввиду под «лямбдой» например, в C#?

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

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

perl -e 'print sub{ $_[0] + $_[1]; }->(1,2)."\n";'
ибо в этом никаких новшеств и преимуществ нету.

Просто сдаётся мне что «лямбда» в нынешних сишарпах это пиарное название допотопных безымянных функций которые даже в перле есть и никаких новшеств в этом на самом деле нету.

★★★★★
Ответ на: комментарий от Ritmik

Чтобы не повторять одну и ту же реализацию много раз.

Всем же известно, что скопипащенные куски кода не содержат ошибок и никогда, _никогда_ не изменяются!

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

самое смешное, что ВНЕЗАПНО - может. Эти господа таки как-то пытаются. Вот только IRL эффект естественно намного хуже, чем у константного кода.

Да ладно. Как оно может-то? Если только за много проходов сообразит что тут вместо foo по-любому будет нечто выносимое из цикла, но это будет работать только если все возможные варианты того, что может быть присвоено foo - это функции из текущего исходника. Если в foo сунуть адрес функции из другого файла или либы - то хрен оно сумеет соптимизировать что-то. По идее даже не должно пытаться.

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

Это зависит от цели проекта, на самом деле. Например, какой-нибудь низкоуровневый LTE стек должен быть быстрым и маложрущим. Это большой проект, но скорость тут гораздо важнее сложности.
Конечно можно этот стек написать и на языке ФП, но из-за того, что ФП следует своим догмам, такое поделие, будь оно сколь угодно прекраным в разрезе догмы упомянутой выше, никому не будет нужно по причине той же самой догмы. Написать-то написали, а о том как и где оно должно работать - не думали вообще.

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

А было бы в ФП чуть меньше матана и догм, и чуть побольше мыслей о железках и объёмах памяти - наверняка уже существовал бы ФП годный для таких задач.

А мужики то не знают.

Можно вопрос? Вы все, что не понимаете, называете матаном и догмами? Вы в вузе матан не осилили и теперь у вас фобия на все, что сложнее второго курса программирования техникума?

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

называете матаном

в данном контексте матан — аналог рекетной науки

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

это _учебник_ если что.

Не понял. «Функциональное Программирование» - учебник? Учебник чего?

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

А если ФП имеет практическое применение и пользу - зачем тогда искусственно его маргинализировать?

Ты же не предлагаешь заниматься преждевременной оптимизацией?

В таком проекте годится любая оптимизация.

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

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

Судя по всему, эти массы от этого не сильно страдали.

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

Вы считаете, что в мире без C# было мало фп программистов?

Я считаю что без С# в мире бало бы мало людей использующих его.
Ведь даже Эльф заинтересовался ФП по причине наличия его в ненавистном ему C# и начал искать аналоги в других языках.

Java и C++ ввели и будут расшираять(в Java он в сугубо зачаточном состоянии но в 8 обещали точно) лямбда калкулс именно потому что C# показал что это нужно в ПОПУЛЯРНОМ ОО ЯП.

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

Программист общается прежде всего с людьми

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

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

Мда. Clojure спроектированный язык, который взял от лиспа лучшее и привнес дополнительно вещи.

Т.е. таки понавносили нового.
Не устроили их возможности первого драфта 1963 года.

АйАйАй!

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

Сразу видно - Специалист!

Спасибо. Твое мнение очень важно для меня.

Да, этой фразой ты чотко закрыл тему, а мне остается только плакать от горя.

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

Он (Ritmik) выше привел два варианта списка значений факториала. И я, хоть попенял ему на N^2, вполне допускаю такое увеличение вычислительной сложности во многих случаях.

Ну я же исправился лямбды в новых язычках - PR или реальные полезняшки? (комментарий)

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

«выразительнее»

Ну да, взять любой язык в абстрактном синтаксисе которого есть letrec или аналог.

понятие «локальная функция» не имеет смысла в C/C++.

Если ты это отменишь, то C/C++ попросту рухнут.

Их просто нет. Если добавить, то ничего не рухнет. От объектов C++ же не рухает, хотя они эквивалентны по поведению замыканиям.

значит только имитация ФП и остаётся.

Есть требование (не у меня, а вообще) «дайте мне настоящие ФВП». А как их реализовывать в энергичном языке без GC это вполне однозначно.

это демонстрирует факт возможности передачи контекста одной функции в другую.

Но, нужно заметить, не контекста как такового, а его куска, просто указателя на стек, по сути, причём ручной его передачи. А то так - вернул замыкание и всё, поставил там [=], [&] или что нужно, если говорить про C++.

Кстати, ответ на вопрос «зачем нужны функции вида lambda (int x) { return x > 5; }» - затем, что можно писать код состоящий из комбинаторов, частичных применений, лямбд и секций чуть более, чем полностью. Ты же не захочешь расписывать сложное арифметическое выражение в SSA? Вот и тут так же.

:) А неконстантный указатель у меня вызывает зубную боль. (:

(: 0_o :) Но иногда же удобно, например, возвращается флаг состояния а реальный результат аргументом по ссылке (как у memmove, без флага, или у getline с ним).

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

Намекну, что вместе с лиспами в больших проектах часто используют Си

О да, и этих больших проектов так много.... :)

Можно вопрос? Вы все, что не понимаете, называете матаном и догмами?

Кто вам сказал, что я не понимаю то, что я называю матаном? Вы вообще поняли, что именно я называю матаном?

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

Вы в вузе матан не осилили и теперь у вас фобия на все, что сложнее второго курса программирования техникума?

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

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

Я даже привёл пример изготовления матана на пустом месте для похапэ. Что непонятно?

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

У вас в цикле в fact_max/fact_count для каждого i/c факториал заново вычисляется

да, я уже писал про константы:

Какие константы? У вас в обоих функциях в каждой итерации цикла вычисляется fact(...)

int fact_count( int m ) {
    int c=0; for( ; fact(c+1)<m ; ++c ); 
    return c;
}

int fact_max( int m ) {
    int r=0; for( int i=1 ; fact(i)<m ; r=fact(i), ++i ); 
    return r;
}

С последовательностями не получилось?

там аналогично - можешь сам проверить

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

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

Какие константы? У вас в обоих функциях в каждой итерации цикла вычисляется fact(...)

ничего там не вычиляется, точнее вычисляется только в первый раз, смотри на static

Там не аналогично, т.к. есть создается массив

аналонично - есть функция для получения массива и она же везде используется

то вам наверно не сложно скинуть пример?

не сложно, но уже надоело - сам полистай назад и скопипасть сюда

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

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

я сделаю. Вот прям как ты мне расскажешь, как на ноль делить (:

А что значит «UB в ФП - фича»? Где в OCaml или Haskell UB-фичи?

ub бывает разное. есть ub поведения, и ub данных. Если данные и код разделены, то ub данных приведёт ТОЛЬКО к неверному результату. Мусор на входе, мусор на выходе (гуглить GIGO). Однако, в ФП данные by design НЕ отделены от кода, потому ситуация GIGO приводит не только к бредовому результату, но и к бредовому ПОВЕДЕНИЮ. Что и является уязвимостью (не всякое GIGO является уязвимостью, но всякая уязвимость является GIGO). Следует особо отметить, что GIGO это не свойство ЯП, а свойство алгоритма. Любой алгоритм выдаст мусор, если его кормить мусором. Я надеюсь это очевидно. Но мусор на выходе можно пережить, в отличие от UB. Я согласен терпеть калькулятор, который выдаёт 2*2=5, но не согласен иметь калькулятор, который при делении на ноль уничтожает все мои файлы.

И да. Не надо про виртуальные машины - это полумера.

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

Когда программист принимает аспект программизьма, то английский ему важнее.

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

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

Я считаю что без С# в мире бало бы мало людей использующих его.

Мало для чего? В том то и дело, что все, кто хотел пользоваться, пользовались.

Ведь даже Эльф заинтересовался ФП по причине наличия его в ненавистном ему C# и начал искать аналоги в других языках.

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

Java и C++ ввели и будут расшираять(в Java он в сугубо зачаточном состоянии но в 8 обещали точно) лямбда калкулс именно потому что C# показал что это нужно в ПОПУЛЯРНОМ ОО ЯП.

Я слабо верю в это, но буду надеятся. А то вон лямбдами только гвозди^W в колбаках и в фильтрах и пользуются. А про вариант на шарпе SICP-кого «picture language» (на который я давал ссылку) я пока не заикаюсь.

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

Да ты неплохо устроился! Обсуждаем пхп — ты срешь «сишечкой», дали лиспокод — «перейду на пхп». Фокусник прям!

ага. Шурупы отвёрткой закручиваю, а гвозди молотком забиваю. ЧЯДНТ?

Глазами эльфа, да. А вложенный цикл — вообще пушка, не забудь упомянуть в резюме.

это пример. да и компилятор тоже кормить надо (он должен развернуть ваще-то).

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

в ФП? любопытно глянуть и проверить.

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

Про массы: Это тайна, покрытая мраком — выбора-то не было.

Про техники: На самом деле их _элементы_ были, например в том же пхп с хрензнам каких пор есть функции «array_[map, reduce, filter]», но пока в нем не сделали условно-нормальных лямбд, передать в них можно было либо именованную функцию, либо извращаться с crate_function, которая одним из аргументов принимала текст функции в виде _строки_(!) Метафора «дрочить вприсядку» тут будет иметь значение «легко и непринужденно».

Кстати, это одна из причин, почему тут я привел пример на пхп.

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

Мда. Clojure спроектированный язык, который взял от лиспа лучшее и привнес дополнительно вещи.

Т.е. таки понавносили нового.Не устроили их возможности первого драфта 1963 года.

Конечно, драфт одного языка не устраивает другого.

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

Намекну, что вместе с лиспами в больших проектах часто используют Си

О да, и этих больших проектов так много.... :)

В смысле, вам нужно много? Зачем?

Кто вам сказал, что я не понимаю то, что я называю матаном?

Ну, и что вы называете матаном в лиспе?

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

Приведете конкретный пример?

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

- H. Abelson and G. Sussman (in «The Structure and Interpretation of Computer Programs)

Результат следования этой догме - налицо. ФП является уделом академической науки и маргиналов

это _учебник_ если что.

Не понял. „Функциональное Программирование“ - учебник? Учебник чего?

ты вообще как на сях пишешь? там же сплошные „указатель на указатель на указатель“

В таком проекте годится любая оптимизация.

у меня для тебя плохие новости

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

Однако, в ФП данные by design НЕ отделены от кода, потому ситуация GIGO приводит не только к бредовому результату, но и к бредовому ПОВЕДЕНИЮ

Как всё запущено O_o

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

Ведь даже Эльф заинтересовался ФП по причине наличия его в ненавистном ему C# и начал искать аналоги в других языках.

Ололошеньки. Я на лиспе программы писал, когда C# ещё и в страшных снах Баллмера не было. При этом ФП в виде «a monad is a monoid object in a category of endofunctors» меня не интересовало, не интересует и интересовать никогда не будет.

А те же «лямбды» в перле вообще постоянно пользую.

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

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

я видел. Кстати, в итоге получилось неплохо — наглядная демонстрация тезиса «На грабли наступить можно независимо от модели обуви».

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

Вот прям как ты мне расскажешь, как на ноль делить (:

Дели в тривиальном кольце. Ещё, говорят, в wheels можно, а они включают все коммутативные кольца, так что...

...

Кажется, у тебя какое-то своё особое ФП, я такого не встречал.

Может это текст про слабую динамическую типизацию, дурацкую реализацию с кучей багов и «выразительных средств» (типа eval, да)? Тогда всё встанет на свои места.

Любой алгоритм выдаст мусор, если его кормить мусором. Я надеюсь это очевидно.

Нет.

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

Я не против матана как такового. Я против элитаризации этого матана через маргинализацию и изобретение новояза.

это не совсем «маргинализация».

Ведь можно про lisp рассказать доступно и просто. Чорт побери, lisp _ПРОЩЕ_ похапэ на порядок, а то и на два.

SICP есть в свободном доступе. там всё рассказано. и довольно таки просто. Да, много букв. Я когда-то осилил, и понял, что оно на самом деле МНЕ не нужно.

Вон, пришёл человек действительно разбирающийся в ФП и просто и понятно изложил на доступном любому программисту языке что такое лямбда и как она работает в lisp и прочем. При этом никакого новояза ФПшного не понадобилось вообще. Матан при этом есть? Есть. Но новояз с маргинальщиной отсутствует.

а ты ещё не понял? Дык всё просто - есть C#, типа бейсика. Ну только когда я бэйсик изучал, мне СРАЗУ сказали, что это язык для болванов, и практической ценности он НЕ представляет. А вот нынешних школьников учат C#, с тем понтом, что оно - Ынтэрпрайз. А когда в этом бэйсике появляется ФП, они на это фапают, так, как будто это Святая Истина, ибо надо для её понимания даже ненадолго мозги включить. Почему-то не понимая, что для многих это старая и избитая ерунда, по типу бинома Ньютона.

drBatty ★★
()
Ответ на: комментарий от wota
int fact( int n ) {
    static int r[ MAX_F ];
    if( !*r ) for( int i=0 ; i<MAX_F ; r[i] = i ? r[i-1]*(i+1) : 1, ++i );
    return r[n-1];
}

Почему ты обращаешься к «*r» в выражениях

if( !*r )

и

r[i] = i ?...

Ты же не инициализировал место памяти, на которое указывает r.

ничего там не вычиляется, точнее вычисляется только в первый раз, смотри на static

Так и запишем: «многопоточно код использовать нельзя».

то вам наверно не сложно скинуть пример?

не сложно, но уже надоело - сам полистай назад и скопипасть сюда

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

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

охренеть! а еще в пхп есть eval, который выполняет вообще любой код

eval выполняет конечно любой код... Дело то не в этом. Беда в том, что e это тоже eval, только выполняется он не над тем, что ввёл программист, а над тем, что ввёл КЛИЕНТ. Я понимаю, что такого бреда никто не задумывал, я понимаю, что ССЗБ, но IRL оно обстоит именно так.

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

В смысле, вам нужно много? Зачем?

Мне не нужно много низачем. Их могло бы быть много.

Ну, и что вы называете матаном в лиспе?

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

Приведете конкретный пример?

Ну вот, например, чтоб далеко от темы не ходить: http://en.wikipedia.org/wiki/Lambda_calculus

Возьмём студента-программиста, который уже побаловался ассемблером, чего-то наковырял работающего на С и даже немного осилил плюсы. Не дурак, и потенциально может быть полезен как хороший программист. Что он сходу сможет понять из статьи в википедии про лямбду? По-моему, с 99% вероятностью он пошлёт все эти лиспы в далёкую и глубокую сраку и скорее всего кинется в объятия похапэ или питона какого.

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

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

Ты же не инициализировал место памяти, на которое указывает r.

Ты прогуливал лекции по Си? static подразумевает инициализацию.

ничего там не вычиляется, точнее вычисляется только в первый раз, смотри на static

Так и запишем: «многопоточно код использовать нельзя».

Можно. В худшем случае некоторые факториалы будут вычислены дважды.

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

Мне не нужно много низачем. Их могло бы быть много.

Повторюсь: зачем?

Возьмём студента-программиста, который уже побаловался ассемблером, чего-то наковырял работающего на С и даже немного осилил плюсы. Не дурак, и потенциально может быть полезен как хороший программист. Что он сходу сможет понять из статьи в википедии про лямбду? По-моему, с 99% вероятностью он пошлёт все эти лиспы в далёкую и глубокую сраку и скорее всего кинется в объятия похапэ или питона какого.

И совершенно правильно сделает. И здесь вы ответьте, ему лиспы зачем?

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

Дай бог.

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

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

не надо забывать, что есть ещё и компилятор. Ты пишешь не на ассемблере. И не под какой-то конкретный CPU. Ну и ещё - ты пишешь ни на один раз. Потом же самому переписывать, когда клиенту что-то там не понравилось (что он ЧСХ сам просил). Кроме этого, ты обязан обеспечить нормальную работу для ВСЕХ допустимых наборов данных, и уметь доказать, что вызвавший сбой набор данных недопустим по ТЗ. С ИП это сложнее, чем с ФП.

А было бы в ФП чуть меньше матана и догм, и чуть побольше мыслей о железках и объёмах памяти - наверняка уже существовал бы ФП годный для таких задач.

ты не понял СУТИ ФП - там всё просто - «давай выбросим ВСЁ, и оставим только функцию! Этого мало? Авот йух! Я гарантирую это, и сейчас докажу!». Ну и доказали собственно. См. CL

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

SICP есть в свободном доступе. там всё рассказано. и довольно таки просто.

Оно, возможно, подходит для математика, который никогда не программировал. Для него SICP прокатит.

А для человека, знакомого с архитектурой процессоров, опытом программирования на императивных языках и пр. (а это 100% студентов изучающих в той или иной степени программирование) это будет чем-то достаточно странным и нудным.

Я, кстати, SICP так и не дочитал до конца :)

Да, много букв. Я когда-то осилил, и понял, что оно на самом деле МНЕ не нужно.

А могло бы быть нужным, кстати.

а ты ещё не понял? Дык всё просто - есть C#, типа бейсика. Ну только когда я бэйсик изучал, мне СРАЗУ сказали, что это язык для болванов, и практической ценности он НЕ представляет.

Да с C# уже всё понятно. Достаточно на любителя C# поглядеть - и больше ничего не надо. Даже необязательно про C# вообще что-то знать, чтобы сделать выводы.

А вот за всякие действительно достойные быть ЯП широкого применения lisp'ы обидно.

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

Повторюсь: зачем?

Вопрос не правильный. Их могло быть много не зачем, а почему. Потому что lisp мог бы занять некоторые ниши в «повседневном» программировании, если бы его не превратили в матан.

И совершенно правильно сделает. И здесь вы ответьте, ему лиспы зачем?

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

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

И я, хоть попенял ему на N^2, вполне допускаю такое увеличение вычислительной сложности во многих случаях.

во многих случаях это допустимо конечно, но ты рекомендуешь МНОГОКРАТНОЕ использование таких ФУНКЦИЙ?

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

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

скопипасть мои примеры со своими и будем говорить дальше, ты их найдешь на предыдущих страницах

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

С ИП это сложнее, чем с ФП.

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

ты не понял СУТИ ФП - там всё просто - «давай выбросим ВСЁ, и оставим только функцию! Этого мало? Авот йух! Я гарантирую это, и сейчас докажу!». Ну и доказали собственно. См. CL

Да понимаю я суть ФП, уж наверно лет 20 как. Просто преследуя задачу «доказательства достаточности функций» наглухо забыли про всё остальное, что должно быть у ЯП.

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

Разве не очевидно? Чтобы не повторять одну и ту же реализацию много раз.

нет. НЕ очевидно. Зачем оборачивать x+y в функцию, если можно записать x+y в цикле? Если завтра понадобиться опять x+y, то почему нельзя записать x+y ещё раз?

Если на простом примере не получилось, то про больший код я уже боюсь спросить.

в БОЛЬШОМ коде объявления функций как занимали ТРИ строки, так и занимают. Твои ФП лямбды интересны только для функций типа x+y.

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

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

Так речь про хорошего программиста или про

Возьмём студента-программиста, который уже побаловался ассемблером, чего-то наковырял работающего на С и даже немного осилил плюсы. Не дурак, и потенциально может быть полезен как хороший программист. Что он сходу сможет понять из статьи в википедии про лямбду? По-моему, с 99% вероятностью он пошлёт все эти лиспы в далёкую и глубокую сраку и скорее всего кинется в объятия похапэ или питона какого.

?

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

Соединим две твои фразы

демагогия:

потому-то я и говорю, что

откуда ты и делаешь какие-то выводы, совершенно игнорируя то, ПОЧЕМУ я так говорю. Тебя это не волнует: твоя цель - нарезать фраз, и скомпоновать из них противоречивое суждение. Если ты хочешь поупражняться в изящной словесности, игнорируя предмет дискуссии, топочему-бы тебе не отправится на другие ресурсы?

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

Теперь можешь вернуться к моему примеру на пхп и прочитать его в этом новом для себя контексте.

это к какому? ЕМНИП пхп вообще не умеет такой оптимизации (в отличие от gcc)

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

Так речь про хорошего программиста или про

А типа студент учится чтобы тусить с дружбанами и бухать?

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

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

Можно. В худшем случае некоторые факториалы будут вычислены дважды.

нельзя, надо сначала пробежать от r[1] до конца, а потом только выставить r[0]

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

Да ладно. Как оно может-то?

ну хвостовая рекурсия к примеру. Вот в qsort делится интервал на два куска, потом обрабатываются рекурсивно оба. Первый кусок представляет собой истинную рекурсию, с которой ничего не сделать (потому для оптимизации первым берут меньший кусок), а вот для второго куска рекурсия на самом деле не нужна. Можно просто цикл. Всё равно первый кусок мы уже отсортировали, и он НЕ поменяется. Вроде как CL по какому-то стандарту, обязан такое отлавливать, и действительно делать цикл, а НЕ запускать ещё одну рекурсию. Как оно получается IRL - не знаю.

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

послушать наших лисперов - оно скопирует функцию в стек, и там скомпилирует её по новой (:

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

Нельзя. Вот худший случай — тупо не вычисляет.

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#define MAX_F 10

int
fact( int n ) {
  static int r[ MAX_F ];
  if( !*r )
    for( int i=0 ; i<MAX_F ; r[i] = i ? r[i-1]*(i+1) : 1, ++i ) {
      if (i == 2 && n == 1) {
        // уберёшь слип - всё работает :)
        sleep(2);
      }
    }
  return r[n-1];
}


void *myThread1() {
  printf("fact(1)= %d\n", fact(1));
  return NULL;
}

void *myThread2() {
  printf("fact(10)= %d\n", fact(10));
  return NULL;
}

int main() {
  int y,x;

  pthread_t id1, id2;

  pthread_create(&id1, NULL, myThread1, NULL);
  sleep(1);
  pthread_create(&id2, NULL, myThread2, NULL);
  sleep(3);
  return 0;
}

Этот код - очень хороший дробовик =)

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

ага. Шурупы отвёрткой закручиваю, а гвозди молотком забиваю. ЧЯДНТ?

Отметьте подходящие варианты:

[ ] врешь;

[ ] путаешь отвёртку и молоток;

[ ] путаешь гвозди и шурупы;

в ФП? любопытно глянуть и проверить.

изначальный код (N^2):

(defn fact [n] (reduce * (range 1 (inc n))))
(defn fact-list [n m] (map fact (range n (inc m))))
подстрочник на пхп:
$fact=function($x){return array_reduce(range(1,$x), function($v,$w){$v*=$w;return $v;},1);};
$fact_list=function($x,$f){return array_map($f,range(1,$x));};

echo $fact(5);
echo var_export($fact_list(5,$fact));
императивный код на пхп (N):
$fact=function($x){
  $f=1;
  foreach(range($f,$x) as $i){
    $f*=$i;}
  return $f;};

$fact_list=function($x){
  $f=1;$a=array();
  foreach(range($f,$x) as $i){
    $f*=$i;
    $a[]=$f;}
  return $a;};

echo $fact(5);
echo var_export($fact_list(5));
$fact_list на пхп с элементами ФП (N):
$fact_list=function($x){return(
  $x<0?array():($x==0?array(1):array_map(function($x){
    static $f; $f=$f?$f*$x:1;
    return $f;},
  range(1,$x))));};

echo var_export($fact_list(5));

NB: тут static $f — не настоящее замыкание, это магия

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

послушать наших лисперов - оно скопирует функцию в стек, и там скомпилирует её по новой (:

в том-то и дело, что не скомпилирует, а скопирует уже скомпилённый шаблон.

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

угу, а вот так работает:

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#define MAX_F 10

int
fact( int n ) {
  static int r[ MAX_F ];
  if( !*r ) {
    for( int i=1 ; i<MAX_F ; r[i] = i > 1 ? r[i-1]*(i+1) : 2, ++i )
        if (i == 2 && n == 1) sleep(2);
    *r=1;
  }
  return r[n-1];
}


void *myThread1() {
  printf("fact(1)= %d\n", fact(1));
  return NULL;
}

void *myThread2() {
  printf("fact(10)= %d\n", fact(10));
  return NULL;
}

int main() {
  int y,x;

  pthread_t id1, id2;

  pthread_create(&id1, NULL, myThread1, NULL);
  sleep(1);
  pthread_create(&id2, NULL, myThread2, NULL);
  sleep(3);
  return 0;
}
wota ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.