Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.97.9.168] |
|
Сообщ.
#1
,
|
|
|
У нас в команде молодой парень , по образвованию не програмист, соображает неплохо,
в гугле искать умеет, терминала не боиться, но он не умеет присать код(ну все мы не умели поначалу ) ), выяснилось что не понимает что такое single tone и думает что анотация наследуеться, и чем отличаеться generic и polymorphism. Я как бы могу его научить, но мне свою работу делать надо, а он может а это время написать криво, есть еще одна такое, team lead скороее манажер чем програмист, Вроде я не должен лезть не в свое дело, пускай дерьмокодет, писать за него я могу но не хочу, this is not my business, но у меня "душа стонет", из него можно сделать классного SE, кто в такой ситуации был ? |
Сообщ.
#2
,
|
|
|
Что с ним делать нужно было решать еще до того, как брать
А так - обучать и ревьювить. Можно и менторить (на что время выделить). Из более экзотических вещей, можно попробовать парное программирование, хорошо помогает в таких случаях. |
Сообщ.
#3
,
|
|
|
Цитата D_KEY @ Что с ним делать нужно было решать еще до того, как брать Берут не по приципу знает/не знает, главное чтоб хороший парень был, научиться, со временем, Ты представть шофера взяли, водить не умеет,а его в рейс, ну убьет десяток людей, научиться, |
Сообщ.
#4
,
|
|
|
Цитата sergioK @ Берут не по приципу знает/не знает, главное чтоб хороший парень был, научиться, со временем Ну это нормально, если понимать, что делаешь и рассчитывать на то, что кто-то будет обучать. Если не ты брал, то соответственно переадресуй свои вопросы тем, кто брал к тебе такого человека |
Сообщ.
#5
,
|
|
|
Учить. Бери у начальника таску и пусть оплачивает. Он же брал работника, не ты. Это его вложение.
|
Сообщ.
#6
,
|
|
|
Цитата Qraizer @ Учить. Бери у начальника таску и пусть оплачивает. Он же брал работника, не ты. Это его вложение. Начальник знает, напарник над ним шефствует, меня другое не понятно, Мы когда начинали мы умели писать, да мы не знали как насроить винду,или проконфигить сервер,и т,д, сегодня с точностью наоборот джуны realloc свой написать не могу, у меня как-то из 15 студентов только один смог, готовое говорят есть, ну возьми в сети и разберись, так что это сложно? а linked List для них как полет на Марс, хорошо бы если бы только жуны, млять люди по 10лет код пишут а про FTP не слышали, мой мозг это не может принять, Я один такой cool guy ? |
Сообщ.
#7
,
|
|
|
Цитата sergioK @ джуны realloc свой написать не могу, А зачем писать системные функции, если Вы не разработчик ядра или ЯП? Linked List я как-то попробовал использовать в тестовом задании на собеседовании (не свой, а библиотечный) — попросили обосновать, почему не Array List. Возможность добавления элементов без realloc не прокатила, работу не приняли, вписав использование Linked List в один из минусов. |
Сообщ.
#8
,
|
|
|
Цитата sergioK @ про FTP не слышали И не рассказывайте им, пусть scp/SFTP используют |
Сообщ.
#9
,
|
|
|
Сообщ.
#10
,
|
|
|
Если бы строители строили здание так как програмисты пишут программы то первый залетевий дрозд разрушил бы нашу цивилизацию. korvin Дрозд уже стартанул или еще думает ? |
Сообщ.
#11
,
|
|
|
Если бы некоторые люди занимались бы полезным делом вместо выдумывания/цитирования глупых некорректных аналогий, мир стал бы чуточку лучше.
sergioK, ты уже сделал мир чуточку лучше? |
Сообщ.
#12
,
|
|
|
Там, где залетевший дрозд может обрушить здание, код пишется с учётом заблудившихся колибри. И сто́ит он немеряно, какой-нибудь MSWord стоил бы около $миллиона за копию.
У среднестатистических же строителей водопровод построен из жидкого пластика с мониторингом пробоев и их самоустранением, газовые трубы помещены в герметичные изоляционные каналы с углекислотой между стенками, а входные двери на пару с домофоном организуют двухфакторную идентификацию посетителей с выдачей разовых ключей ограниченного срока действия. Конечно, от дебила с перфоратором и болгаркой это не спасёт, но и стоит такой дом соразмерно самокату. |
Сообщ.
#13
,
|
|
|
Цитата korvin @ Если бы некоторые люди занимались бы полезным делом вместо выдумывания/цитирования глупых некорректных аналогий, мир стал бы чуточку лучше. sergioK, ты уже сделал мир чуточку лучше? да, Добавлено Цитата Qraizer @ Там, где залетевший дрозд может обрушить здание, код пишется с учётом заблудившихся колибри. незнаю что такое болгарка но вот делаешь ты сыну операцию, а врач говорить подождите сбой компа, и ты видишь краем глаза,segmentation fault, то есть какой то поц забыл память выделить, а QA хз куда смотрел, и какая реакция будет? это реальный случай, Когда ботинки новые руться это же нонсенс, а вот програма падает, по незнанию или глупости/пофигизму, это нормально, ну запихнули там string в long, так тебе сбой сердца ошибочно определили, ну полежал дня четыре пока не выяснили , не работал ну потерял контракт, приятно ? учли там калибри или не очень ? Добавлено Цитата Qraizer @ Там, где залетевший дрозд может обрушить здание, код пишется с учётом заблудившихся колибри. И сто́ит он немеряно, какой-нибудь MSWord стоил бы около $миллиона за копию. Мало что ли качественных, хороших програм за разумную цену? |
Сообщ.
#14
,
|
|
|
Цитата sergioK @ да, Пока что не заметно. Цитата sergioK @ незнаю что такое болгарка но вот делаешь ты сыну операцию, а врач говорить подождите сбой компа, и ты видишь краем глаза,segmentation fault, то есть какой то поц забыл память выделить, а QA хз куда смотрел, и какая реакция будет? это реальный случай, Кто ж виноват, что вы критический софт пишете как клиент для инстаграма? Как вы сертификацию прошли? Цитата sergioK @ Когда ботинки новые руться это же нонсенс Да нет, вполне бывает, если покупать дешёвые некачественные ботинки в каком-нибудь «Рога и Копыта, а также обувь». Цитата sergioK @ Мало что ли качественных, хороших програм за разумную цену? Мало. Ну, «Hello, World»'ов, наверное, много. Но пользы от них не много. Добавлено Цитата sergioK @ незнаю что такое болгарка https://www.vseinstrumenti.ru/instrument/sh.../bolgarka_ushm/ |
Сообщ.
#15
,
|
|
|
Цитата korvin @ Кто ж виноват, что вы критический софт пишете как клиент для инстаграма? Как вы сертификацию прошли? Мы то причем? Про других не знаю, но я не умею писать криво, ума не хватает, |
Сообщ.
#16
,
|
|
|
Цитата sergioK @ но я не умею писать криво Ты себе льстишь. |
Сообщ.
#17
,
|
|
|
Цитата sergioK @ но я не умею писать криво Подобные загоны мешают развиваться. А так же воспринимать конструктивную критику. А так же вредят командной работе (если таковая у тебя есть). |
Сообщ.
#18
,
|
|
|
Цитата D_KEY @ Цитата sergioK @ но я не умею писать криво Подобные загоны мешают развиваться. А так же воспринимать конструктивную критику. А так же вредят командной работе (если таковая у тебя есть). Мне начать применять антипатерны или перестать применять нужные структуры данный, или перестать следить ворнингами? Начать применять оверхед? И тогда Я стану быстро развиваться |
Сообщ.
#19
,
|
|
|
sergioK, нет, нужно перестать думать, что ты не умеешь криво писать. Идеальный код недостижим, каждому есть куда расти.
Добавлено Цитата sergioK @ или перестать следить ворнингами? Лучше фейлить сборку по ворнингам, чем руками следить за ними. |
Сообщ.
#20
,
|
|
|
Ну вот мы, к примеру, буквально сегодня отклонили ответ разработчиков на дефект. У них 2-хбитное поле в структуре int, в него пишется 3, дефект в неравенстве этого поля 3 после такого присваивания, ибо там -1 выходит. Ответили, мол, мы знаем, так и задумано, битовое представление совпадает. Аха, счас, разбежались.
А насколько часто ты сталкиваешься с арифметическим переполнением, sergioK? Добавлено Если серьёзно... Цитата sergioK @ Если ПО относится к высококритичному, ты заманаешься его писать, тестировать и сертифицировать. В прошлый наш проект на одну из функциональностей на ~475Кб сырцов (с комментами и пустыми строками, шапками трассировкой на требования итп) мы только по завершению этапа тестирования отгрузили тестов с их результатами на 187Мб, а общий объём отчётов по этапу верификации составил чуть меньше 2Гб. И это только наша сторона процесса без планов, аудита, анализов и рассмотрения, ревью итп, а сколько туда добавили подрядчики, я без понятия.но вот делаешь ты сыну операцию, а врач говорить подождите сбой компа, и ты видишь краем глаза,segmentation fault, то есть какой то поц забыл память выделить, а QA хз куда смотрел К тому же у любого такого ПО есть чёткие требования к программно-аппаратному окружению. На первом попавшемся ноуте с АЛИшки под свежайшей Убунтой его запустить обычно беспроблем, вот только первый попавшийся ноут со свежайшей Убунтой 100пудово не будет соответствовать правилам эксплуатации этого ПО. И в этом случае все вопросы к врачу или его начальникам, по тех.обеспечению в частности. И не дай бог там внезапно обнаружится когда-то вставлявшаяся флешка или некогда активный клиент телеги. Обычно такое делают просто невозможным, но если вдруг врач хакер... Но вообще, если такие вылеты допустимы, значит некритично. Оценка критичности лежит на заказчике и прописывается в ТЗ, и чёрта с два он её укажет занижено или сертификат будет получен без следования отраслевым стандартам. Даже у нас, ибо никто не захочет садиться на пожизненно, это эму не ведро алмазов с рудников стырить. Цитата sergioK @ Кроме нас, его верифицировать имеют право только ещё несколько контор в Москве. Даже за Питер не скажу, не слышал. Разрабатывать же... скажем так: в начальную разработку можно взять кого угодно, но вытянуть весь жизненный цикл смогут лишь единицы. ...ну запихнули там string в long, так тебе сбой сердца ошибочно определили, ну полежал дня четыре пока не выяснили , не работал ну потерял контракт, приятно ? Цитата sergioK @ ... И дело тут не в качестве кода и навыках программеров, а в правилах, диктуемых стандартами. Ты просто не представляешь себе, что такое высококритичное ПО. Твой опыт качественного программирования там будет играть очень небольшую роль. Мало что ли качественных, хороших програм за разумную цену? |
Сообщ.
#21
,
|
|
|
ФП-шники используют связные списки постоянно. |
Сообщ.
#22
,
|
|
|
Цитата D_KEY @ sergioK, нет, нужно перестать думать, что ты не умеешь криво писать. Идеальный код недостижим, каждому есть куда расти. Криво и не идеальный код это разные вещи, как говорят в шахматах, без ошибочных партий не бывает, есть разная степень ошибочности, Добавлено Цитата Qraizer @ А насколько часто ты сталкиваешься с арифметическим переполнением, sergioK? Добавлено Если серьёзно... Цитата sergioK @ Если ПО относится к высококритичному, ты заманаешься его писать, тестировать и сертифицировать. В прошлый наш проект на одну из функциональностей на ~475Кб сырцов (с комментами и пустыми строками, шапками трассировкой на требования итп) мы только по завершению этапа тестирования отгрузили тестов с их результатами на 187Мб, а общий объём отчётов по этапу верификации составил чуть меньше 2Гб. И это только наша сторона процесса без планов, аудита, анализов и рассмотрения, ревью итп, а сколько туда добавили подрядчики, я без понятия.но вот делаешь ты сыну операцию, а врач говорить подождите сбой компа, и ты видишь краем глаза,segmentation fault, то есть какой то поц забыл память выделить, а QA хз куда смотрел К тому же у любого такого ПО есть чёткие требования к программно-аппаратному окружению. На первом попавшемся ноуте с АЛИшки под свежайшей Убунтой его запустить обычно беспроблем, вот только первый попавшийся ноут со свежайшей Убунтой 100пудово не будет соответствовать правилам эксплуатации этого ПО. И в этом случае все вопросы к врачу или его начальникам, по тех.обеспечению в частности. И не дай бог там внезапно обнаружится когда-то вставлявшаяся флешка или некогда активный клиент телеги. Обычно такое делают просто невозможным, но если вдруг врач хакер... Но вообще, если такие вылеты допустимы, значит некритично. Оценка критичности лежит на заказчике и прописывается в ТЗ, и чёрта с два он её укажет занижено или сертификат будет получен без следования отраслевым стандартам. Даже у нас, ибо никто не захочет садиться на пожизненно, это эму не ведро алмазов с рудников стырить. Цитата sergioK @ Кроме нас, его верифицировать имеют право только ещё несколько контор в Москве. Даже за Питер не скажу, не слышал. Разрабатывать же... скажем так: в начальную разработку можно взять кого угодно, но вытянуть весь жизненный цикл смогут лишь единицы. ...ну запихнули там string в long, так тебе сбой сердца ошибочно определили, ну полежал дня четыре пока не выяснили , не работал ну потерял контракт, приятно ? Цитата sergioK @ ... И дело тут не в качестве кода и навыках программеров, а в правилах, диктуемых стандартами. Ты просто не представляешь себе, что такое высококритичное ПО. Твой опыт качественного программирования там будет играть очень небольшую роль.Мало что ли качественных, хороших програм за разумную цену? Вообще не сталкиваюсь, нету у меня таких задач, когда задача встанет начну думать, читать маны, особенности языка , компилятора и т,д, Добавлено Цитата Qraizer @ И дело тут не в качестве кода и навыках программеров, а в правилах, диктуемых стандартами. Ты просто не представляешь себе, что такое высококритичное ПО. Твой опыт качественного программирования там будет играть очень небольшую роль. для меня качественное программирования это и есть следование правилам диктуемых стандартами, у нас есть выражение - баг в дизайне зыбь в дебаге зыбь по-арабски, это слово нецензурное из трех букв Добавлено Цитата Qraizer @ Разрабатывать же... скажем так: в начальную разработку можно взять кого угодно, но вытянуть весь жизненный цикл смогут лишь единицы. ... Ну я вытягиваю, в тех задачах что мне надо, конечно с неточностями, я же не супермер, Вот тебе живой пример, буквально два месяца назад, решили на passwowd regex добавить, Я первое что попросил у VPR&D это день на мануалы DB, не дали сказали не надо, а там центральное место в системе, пришлось кучу тестов писать, неделю, а надо было в DB поле поставить типа regex, перегрусить стандартный метод фраймворка кинуть exception в методе, все кто вызвывают обязаны будут его обработать,компайлер заставит, работы на день ну два, ну три с учетом изучения, три программера на проэкте были еще двое до меня ушли, и шеф, так ни один не думал об этом, неделю с лишним возился, и БД в облаке, каждый вызов 10-12 секунд ждешь, нет чтобы локально поставить, один по образованию психолог-математик, другая экономист , третий физик, мозги и них в порядке но их никто не учил писать грамотно, взяли RDBMS а там 4Т ограничение и никто не думал, как ты думаешь качественный продукт выйдет у них ? Если вообще выйдет, Мой же джун написал скрипт для винды а потом для Мэка потребовался, вот теперь две версии, нк он ладно не знал, он хотел писать на Питоне но ему сказали что в Винде нет Питона версии 3,0, ну ландо допустим не знали, но прочитать то можно , потратив по-часа времени, И как вот такое коментировать без мата ? Добавлено Цитата applegame @ ФП-шники используют связные списки постоянно. Цитата linked lists seen to be of more interest in functional languages, eg the default seq implementation in Scala is a linked list. Это юмор такой? и кто это ФП-шники? |
Сообщ.
#23
,
|
|
|
applegame, там речь не про связные списки вообще, а про java.util.LinkedList
https://twitter.com/joshbloch/status/584272581320052736?s=21 Цитата Don't get me wrong; I love linked lists. They're as useful in C as they are in Scheme. But LinkedList is another matter entirely. |
Сообщ.
#24
,
|
|
|
Цитата korvin @ applegame, там речь не про связные списки вообще, а про java.util.LinkedList https://twitter.com/joshbloch/status/584272581320052736?s=21 Цитата Don't get me wrong; I love linked lists. They're as useful in C as they are in Scheme. But LinkedList is another matter entirely. Ну, я бу не сказал, что двусвязные списки это "another matter entirely". Или я что-то недопонял? Они конечно реже используются чем односвязные, но тоже хороши, и их использовал для оптимизации обхода бинарного дерева. |
Сообщ.
#25
,
|
|
|
Цитата sergioK @ И слава богу, что нет. Желаю тебе, чтоб никогда и не было. Это очень скучное и неблагодарное дело. Если когда-либо сталкивался с продуктами с требованиями работоспособности 24/7, то это ерунда по сравнению с требованиями к высококритичному ПО. Вообще не сталкиваюсь, нету у меня таких задач, когда задача встанет начну думать, читать маны, особенности языка , компилятора и т,д, Добавлено Просто для оценки планок. Когда-нибудь приходилось выкладывать в систему контроля версий объектный код и ассемблерные листинги с трассировкой на сырцы? Благо многие компиляторы это почти умеют сами. Почти. Учитывал ли реакцию твоего кода на INF и NaN? И вообще, приходилось ли обеспечивать сохранение работоспособности кода при любых невалидных воздействиях извне и немедленно возвращать свои выходы в номинальные диапазоны по прекращению невалидных воздействий? Приходилось ли собирать 100% структурное покрытие кода по MC/DC? Всего кода, не только твоего авторства. Объектного, не исходного. (Последнее, правда, обязательно только для уровня критичности level A.) Приходилось ли отказываться от стандартных библиотек и писать свои аналоги? Ради как раз 100% покрытия. Приходилось ли отказываться от некоторых возможностей языка, которые как раз и введены в основном ради отказоустойчивости? И всё из-за пресловутых 100%. Использовались ли методы доказательства корректности кода с опорой на тесты как доказательную базу? Именно доказательную, а не вероятностную. Общая алгебра, теория групп. Использовались ли математические методы доказательства правильности разработанных алгоритмов? Использовались ли методы доказательства корректности реализаций этих алгоритмов? Даташиты, официальные мануалы, стандарты языков и стандарты кодирования + теория множеств и формальная логика. Не превышал ли суммарный объём работ по документированию продукта на два порядка работы по разработке и тестированию этого кода? Тесты писаны вручную и без использования любых средств автоматизации, основанных на изучении кода? Тесты, созданные на основе задокументированного поведения кода, которое в свою очередь выполнено на человеческом языке, исполнялись и получали результаты на основе реального поведения объектного кода, из системы контроля версий который? Подвергались ли любые инструменты, как собственной разработки, так и сторонние, включая компиляторы, загрузчики, генераторы отчётности итп, процедурам квалификации, на основе результатов которых на них выдавалось заключение о том, что они подходящи для применения в сфере высококритичного ПО, и полученным с их помощью результатам можно доверять при условии невыхода условий их эксплуатации за указанные в заявке на квалификацию рамки? На закуску: приходилось ли проектировать системы с учётом возможных неизвестных аппаратных багов в процессорах? Добавлено Я ж говорю, колибри не полетит. А что за дроздов... уверен, sergioK, и непротекающий водопровод ты сумеешь спроектировать с логгированием всех подозрительных событий, и безопасный к взрывам газопровод в квартиру проведёшь, и отказоустойчивую аутентификацию наладишь. Почти уверен. И стоить это будет $49.95 за копию. Нехрен ни к селу ни к городу троллей цитировать, ты ж и сам знаешь, что это всё враки. |
Сообщ.
#26
,
|
|
|
Цитата Qraizer @ Учитывал ли реакцию твоего кода на INF и NaN? И вообще, приходилось ли обеспечивать сохранение работоспособности кода при любых невалидных воздействиях извне и немедленно возвращать свои выходы в номинальные диапазоны по прекращению невалидных воздействий? я не пишу на low level, мне это зачем, будет надо разберусь, Добавлено Цитата Qraizer @ Учитывал ли реакцию твоего кода на INF и NaN? И вообще, приходилось ли обеспечивать сохранение работоспособности кода при любых невалидных воздействиях извне и немедленно возвращать свои выходы в номинальные диапазоны по прекращению невалидных воздействий? Я с железом не пишу, в ранках своих задач да приходилось, Что ты хочешь сказать? Качественный код можно не писать? Можно так более менее или хуже? Я уже рассказвывл историю с операцией сыну, как бы ты среагировал в такой систуации? Будешь думать про волопровод 49,5$ ? Ты ответь, без бабы мансов потом про дрозда, продолжим |
Сообщ.
#27
,
|
|
|
Цитата applegame @ Ну, я бы не сказал, что двусвязные списки это "another matter entirely" Ну я бы не сказал, что фразу "But LinkedList is another matter entirely" стоит продолжать пытаться читать как-то по-другому, чем "But LinkedList is another matter entirely". "You're probably better off with ArrayDeque. Measure and find out " https://twitter.com/joshbloch/status/756538672724533248?s=20 "Resizable-array implementation of the Deque interface. Array deques have no capacity restrictions; they grow as necessary to support usage. They are not thread-safe; in the absence of external synchronization, they do not support concurrent access by multiple threads. Null elements are prohibited. This class is likely to be faster than Stack when used as a stack, and faster than LinkedList when used as a queue." doc Насчёт двусвязных списков не скажу, но как минимум их, например, нельзя просто сделать иммутабельными и/или ленивыми, в отличие от односвязных. |
Сообщ.
#28
,
|
|
|
Цитата korvin @ Там фраза чуть длиннее:Ну я бы не сказал, что фразу "But LinkedList is another matter entirely" стоит продолжать пытаться читать как-то по-другому, чем "But LinkedList is another matter entirely". Цитата Лично я полагаю, что "LinkedList" отличается от "linked list", которые "I love", только тем, что первые двусвязные, а вторые односвязные. Тут и не пахнет "another matter entirely", так как эти списки весьма похожи.Don't get me wrong; I love linked lists. They're as useful in C as they are in Scheme. But LinkedList is another matter entirely. Цитата Наверняка. Но есть серьезное подозрение, что внутри этого ArrayDeque используется, сюрприз-сюрприз, двусвязный список массивов Может даже тот самый LinkedList. Если же там просто массив, то при большом количестве элементов ArrayDeque будет медленнее LinkedList.This class is likely to be faster than Stack when used as a stack, and faster than LinkedList when used as a queue. Цитата korvin @ Можно и то и другое. Двусвязные списки нельзя сделать эффективно персистентными (Persistent data structure), как, собственно, и обычные масивы. Только CoW. Поэтому они бесполезны в ФП. Насчёт двусвязных списков не скажу, но как минимум их, например, нельзя просто сделать иммутабельными и/или ленивыми, в отличие от односвязных. Добавлено Почитал про ArrayList и ArrayDeque, внутри обычные массивы. А значит существуют случаи, когда LinkedList будет быстрее. Например если у нас миллион элементов в списке/очереди. |
Сообщ.
#29
,
|
|
|
Цитата sergioK @ Первая стадия пошла. А если серьёзно, кто тебя будет спрашивать-то? Или ты считаешь, что с датчиков приходят классы с инвариантами?я не пишу на low level, мне это зачем, будет надо разберусь, Цитата sergioK @ Что корректность твоего кода не должна зависеть от корректности окружения, с которым он взаимодействует. Пришла тебе от термодатчика температура пациента 1180,8° (нарушение единичного события) или там пульс INT_MIN (по IEEE это вполне себе целочисленная неопределённость). Причина – плохой контакт на разъёме. Ну как, вторая стадия уже на подходе?Что ты хочешь сказать? Качественный код можно не писать? Можно так более менее или хуже? Цитата sergioK @ Поинтересовался, правда ли, что этот софт не относится к высококритичному и при утвердительном ответе попросил бы сертификат. В любом случае уже б в уме сочинял заявление. А что? Я уже рассказвывл историю с операцией сыну, как бы ты среагировал в такой систуации? Добавлено Если ты к тому, что а вдруг тебе бы пришлось этот софт писать, беги от подобных заказов. Стадии ещё не кончились, впереди ещё три. И сесть может быть и не сядешь, но как себя поведут твои начальники и заказчики, предсказывать не берусь. Добавлено Цитата sergioK @ Стоимость цикла разработки от ТЗ до выдачи в эксплуатацию высококритичного ПО оценивается в полтора миллиона человеко-часов на мегабайт сырцов. Помножишь на свою зарплату сам. Будешь думать про волопровод 49,5$? |
Сообщ.
#30
,
|
|
|
Цитата Qraizer @ Или ты считаешь, что с датчиков приходят классы с инвариантами? Да понятия не имеею как они приходят, наверно есть способы как с этим работать Я с вебом работаю у меня все приходит как надо, Добавлено Цитата Qraizer @ Поинтересовался, правда ли, что этот софт не относится к высококритичному и при утвердительном ответе попросил бы сертификат. В любом случае уже б в уме сочинял заявление. А что? Я про наличие сертификата у софту слышу впервые в жизни, ISO никаких гарантий на надежность не требует, ну даже если он есть у них, крупная больница все таки, то что ? Куда бы ты писал и что ? А кто вообще решает критичный ли софт, если кого то убили то да, а если поцарапали то нет ? ISO гарантий не требует, |
Сообщ.
#31
,
|
|
|
Цитата applegame @ Лично я полагаю, что "LinkedList" отличается от "linked list", которые "I love", только тем, что первые двусвязные, а вторые односвязные. Если бы речь была про двусвязные списки, автор поста так бы и написал. Цитата applegame @ Можно и то и другое. Пример, приведи. Цитата applegame @ как, собственно, и обычные масивы. Обычные массивы нельзя, но их можно достаточно эффективно эмулировать деревом из массивов, как это сделано в Scala, например. Цитата applegame @ А значит существуют случаи, когда LinkedList будет быстрее. Например если у нас миллион элементов в списке/очереди. За счёт чего LinkedList будет быстрее на большом количестве элементов? |
Сообщ.
#32
,
|
|
|
Цитата korvin @ Ну я почитал о жабовском LinkedList, обычный двусвязный список с его профитами и недостаткаками.Если бы речь была про двусвязные списки, автор поста так бы и написал. Цитата korvin @ Если двусвязный список сделать встроенным в язык типом, то он вполне может быть персистентным, а при добавлении новых элементов просто копировать его целиком. Бесполезно, но возможно.Пример, приведи. Цитата korvin @ "Достаточно" понятие растяжимое. Доступ по индексу у такого "массива" будет не константный.Обычные массивы нельзя, но их можно достаточно эффективно эмулировать деревом из массивов, как это сделано в Scala, например. Цитата korvin @ Не на всех операциях, но добавление элемента у LinkedList всегда O(1), а у ArrayList/ArrayDeque в худшем случае O(n). За счёт чего LinkedList будет быстрее на большом количестве элементов? |
Сообщ.
#33
,
|
|
|
Цитата applegame @ Не на всех операциях, но добавление элемента у LinkedList всегда O(1), а у ArrayList/ArrayDeque в худшем случае O(n). Да, я примерно этот аргумент и использовал… Цитата korvin @ Если бы речь была про двусвязные списки, автор поста так бы и написал. О, эти рассуждения вида «что хотел сказать / имел ввиду автор» Цитата sergioK @ я не пишу на low level, мне это зачем, а теперь возващаемся к моему вопросу: если не пишешь на low level, зачем писать системные функции, вроде realloc? |
Сообщ.
#34
,
|
|
|
Цитата kopilov @ Автор, судя по всему, просто некомпетентный лопух. Односвязные списки в скале он видите ли любит, а LinkedList в жава это "совсем другое дело". О, эти рассуждения вида «что хотел сказать / имел ввиду автор» Односвязные списки в ФП - вынужденная мера из-за требования иммутабельности, а в плане производительности они полное говно. Даже сраную Deque в ФП приходится городить на паре односвязных списков, из-за чего удаление элемента с хвоста может встать в O(n), а у обычного двусвязного списка эта операция всегда занимает O(1). Лично я не люблю односвязные списки, я мирюсь с ними. |
Сообщ.
#35
,
|
|
|
Цитата applegame @ Если двусвязный список сделать встроенным в язык типом То что? Его всё равно нужно как-то реализовать. Цитата applegame @ при добавлении новых элементов просто копировать его целиком Цитата applegame @ Бесполезно ЧТД Цитата applegame @ "Достаточно" понятие растяжимое. Доступ по индексу у такого "массива" будет не константный. Но близкий к константному: logbase. Для дефолтного base=32 и массива из миллиона элементов доступ будет стоить 4. Цитата applegame @ Не на всех операциях, но добавление элемента у LinkedList всегда O(1), а у ArrayList/ArrayDeque в худшем случае O(n). Ты ещё пойди поймай этот худший случай. И ты не учитываешь, что у LinkedList по сравнению с ArrayDeque: 1) создаётся объект ноды на каждый элемент, что нагружает GC; 2) каждая нода хранит 3 указателя, что увеличивает потребление памяти в 3 раза независимо от количества элементов (в случае с AD зависит от size/capacity, заполненный даже наполовину AD имеет меньший оверхед по памяти); 3) ноды могут распологаться в памяти где попало, что отменяет возможную векторизацию при доступе. Цитата applegame @ Автор, судя по всему, просто некомпетентный лопух. Joshua Bloch — некомпетентный лопух? Ну-ну. ) |
Сообщ.
#36
,
|
|
|
sergioK, предлагаю тебе выйти из беседы. не надо рассуждать о материях, о которых ты слышал лишь краем уха в паре постов.
Добавлено P.S. ISO можешь сразу в топку, имеющиеся у тебя сертификаты на стенку для историй на пенсии. Не с этими стандартами в высококритичность, они подходят не более чем для бизнеса или максимум военки. |
Сообщ.
#37
,
|
|
|
Цитата korvin @ А в чем проблема его реализовать? Нет никакой проблемы его реализовать.То что? Его всё равно нужно как-то реализовать. Цитата korvin @ Какое из твоих утверждений ЧТД?ЧТД Цитата korvin @ Это для чтения, а если надо перезаписать элемент, то придется часть этого дерева пересоздать, это будет стоить намного дороже.Но близкий к константному: logbase. Для дефолтного base=32 и массива из миллиона элементов доступ будет стоить 4. Цитата korvin @ Возможно, что LinkedList - просто корявая реализация двусвязного списка, тут спорить не буду ибо не знаю. Мои двусвязные списки (не на жабе, конечно) используют пулы, и добавляют по два указателя к каждой ноде.Ты ещё пойди поймай этот худший случай. И ты не учитываешь, что у LinkedList по сравнению с ArrayDeque: Цитата korvin @ Да мне все равно кто он там такой. Я сделал предположение по этому его высказыванию (других я не знаю). А он явно сморозил чушь. Возможно он имел в виду что-то другое, но сказал то что сказал. Joshua Bloch — некомпетентный лопух? Ну-ну. ) |
Сообщ.
#38
,
|
|
|
Цитата applegame @ Да мне все равно кто он там такой. Я сделал предположение по этому его высказыванию (других я не знаю). А он явно сморозил чушь. Возможно он имел в виду что-то другое, но сказал то что сказал. Да приколист, он взявший имя автора известной книги по Яве, IMHO Добавлено Цитата applegame @ Возможно, что LinkedList - просто корявая реализация двусвязного списка, тут спорить не буду ибо не знаю. Мои двусвязные списки (не на жабе, конечно) используют пулы, и добавляют по два указателя к каждой ноде. Стандартный класс, который использует полмира уже лет 20, не нравиться наследуй и пиши свою реализацию пулами или без, хотя я не понимаю зачем, Добавлено Цитата Qraizer @ sergioK, предлагаю тебе выйти из беседы. не надо рассуждать о материях, о которых ты слышал лишь краем уха в паре постов. Ну да именно о материях причем абстактных, как ты любишь, если бы еще понятным языком писал Я бы может и понял о чем речь, я не критичных систем не пишу уже лет 10, хотя некоторые считают что их пишут только на С/C++, Добавлено Цитата Qraizer @ Не с этими стандартами в высококритичность, они подходят не более чем для бизнеса или максимум военки. В военке как раз и самые высокие стандрты, Добавлено Цитата Qraizer @ Кроме нас, его верифицировать имеют право только ещё несколько контор в Москве. Вас это кого? И кто сказал что правы имеено вы, а не тот кто задумал некий код под свою конкретную задачу? |
Сообщ.
#39
,
|
|
|
Цитата sergioK @ Ты их и не писал никогда. И – да, только на C/C++. Ещё немного на ассемблере, но совсем чуть-чуть, когда надо кристалл инициализировать, например. Ещё Аду кое-где пытаются использовать, но там считанные проценты проектов: немного экономят в разработке, жутко теряют в эксплуатации.Я бы может и понял о чем речь, я не критичных систем не пишу уже лет 10, хотя некоторые считают что их пишут только на С/C++, Цитата sergioK @ Ты будешь удивлён...В военке как раз и самые высокие стандрты, Цитата sergioK @ Тот, кто задумал, не выбирает, ему указывают. На того, у кого есть разрешение на работу в этой сфере. Разрешением является наличие сертификата. Ничего необычного, всё как у всех, сертификаты вот только разные. У кого есть подходящие, известно, и список небольшой; кому оно надо, знает куда смотреть, чтоб выйти с предложением контракта. Так на нас и вышли, например. Кто – не скажу, он под санкциями, мы туда не хотим, а гугл, паразит, быстро индексирует. Заказчик же в свою очередь тоже подрядчик своего заказчика, а он хорошо известен в Росавиации.Вас это кого? И кто сказал что правы имеено вы, а не тот кто задумал некий код под свою конкретную задачу? Цитата sergioK @ Вот с этого и надо было начинать. если бы еще понятным языком писал |
Сообщ.
#40
,
|
|
|
Цитата Qraizer @ Цитата sergioK @ Ты их и не писал никогда. И – да, только на C/C++.Я бы может и понял о чем речь, я не критичных систем не пишу уже лет 10, хотя некоторые считают что их пишут только на С/C++, Я счас такую строю, внесешь неверный параметр и больной из ряда критичных перейдет в легкие, и лечение нужное не получит, результат сам понимаешь может быть критичный, Сертификат дает FDA или EMA, только это называеться approval, Цитата Safety-critical systems are those systems whose failure could result in loss of life, significant property damage, or damage to the environment. https://smallbusinessprogramming.com/safety...er-should-know/ Система распознавания графика работы сердца может быть написана хоть на VB, или распознавания рака, баг в такой система может стоить жизни, система управления биржей тоже не всегда на С/С++, сбой может привести с банкротсву, или поиска криминальних деятелей через их мобильники, сделал баг, он за это время грабанул кого или по хуже еще, А 24/7 полно систем не на С/С++, не говоря уже о готовый решениях типо облака, Никогда не слышал чтобы на софт был нужен сертификат, спросил друга он 25лет в RT + embedded + networking + security, он тоже не слышал, требования ставит заказчик Причем тут кристал или датчик, то что ты говоришь называеться интеграция в твоем случае Software and hardware или firmware. Ты мне про какую то другую реальность рассказываешь, тебе очевидную а мне нет, Добавлено Цитата Qraizer @ Тот, кто задумал, не выбирает, ему указывают. На того, у кого есть разрешение на работу в этой сфере. Разрешением является наличие сертификата. ничо не понял кто указывает? Указать может только гос-во, а вы по сути гараж, кторый проверяет исправна ли машина, согласно страндарту установленному мин промом, тогда по логике у програмистов должнва быть лицензия, как у врачей или адвокатов, работу то ты делаешь, ты решение принимешь, а не фирма, то есть ты должен был пройти некий экзамен, как электрик или там инструктор вождения, Добавлено Цитата Qraizer @ Ты будешь удивлён...В военке как раз и самые высокие стандрты, Цитата sergioK @ Тем что они не высокие ? То есть ракета может сбит мирный Боинг, и ничего страшного? |
Сообщ.
#41
,
|
|
|
Цитата sergioK @ Значит это не высококритичный софт. Без обид. Как вариант – это он такой до первого судебного разбирательства, но это вряд ли. Если в вашей деятельности нет хотя бы одной из выше мной перечисленной активити, у вас обычный бизнес. И я перечислил отнюдь не все характерные отличия модели высококритичной разработки от всем хорошо известной бизнес-разработки, только наиболее характерные. Вообще-то в отраслевых стандартах около 170-и пунктов, напротив каждого из которых аудиторы должны будут поставить галку, и по каждому пункту выпускается документация, которую аудит тоже проверяет перед расстановкой галок. Хотя бы одной галки нет, сертификата не будет. Наших пунктов тут около 60. Прицепом ещё 30, 20 из которых мы, выполнив, по контракту сняли с себя и дальше их ведёт заказчик. + на нас лежит часть ещё 10-и пунктов, потому что они неотъемлемы от всего процесса в целом. Количество документации я выше приводил, на её выпуск уходит на 2 порядка больше ресурсов проекта, чем на код и железки. И это первый шлагбаум на пути тех, кто погонится за рублём и вдруг возомнит, что потянет эту сферу.Я счас такую строю, внесешь неверный параметр и больной из ряда критичных перейдет в легкие ... ... Система распознавания графика работы сердца может быть написана хоть на VB, или распознавания рака ... Цитата sergioK @ Ты идёшь в правильном направлении, за государство вот в частности, но вообще-то это просто совпадение. Просто обычно ни у кого, кроме государства, денег нет на софт такой категории. И в целом ты, конечно, в чём-то прав. Отсутствие денег у нашей медицины не секрет, и вполне объясняет не отнесение сферы медицины к области высококритичной ИТ-разработки. Неунас с этим куда прозрачнее.Указать может только гос-во, а вы по сути гараж, кторый проверяет исправна ли машина, согласно страндарту установленному мин промом, тогда по логике у програмистов должнва быть лицензия, как у врачей или адвокатов, работу то ты делаешь, ты решение принимешь, а не фирма, то есть ты должен был пройти некий экзамен, как электрик или там инструктор вождения Но во всём остальном мимо. ... Цитата sergioK @ ... Мы не проверяем, как работает машина, мы проверяем, как она проектируется и разрабатывается. Это как раз и отличает методы работы в высококритичной области от методов бизнеса: сертифицируется не продукт, а жизненный цикл его разработки. Сертифицируется не продукт, а процесс его создания. Весь. Вообще весь. С момента, как вообще у кого-то возникла идея о том, что неплохо было бы изобрести этот новый продукт с вот такими уникальными (а иначе зачем? дорогие "велосипеды" никому не нужны) качествами и вплоть до момента схода с конвейера первой модели серийного его производства. Это абсолютно отличная от подходов бизнеса модель. Есть даже такие документы, как описывающий процесс планирования цикла проектирования изделия, например. Прикинь.Никогда не слышал чтобы на софт был нужен сертификат А вот проверкой "исправна ли машина" действительно занимаются специально обученные люди. Но занимаются они уже готовыми серийными изделиями и тратят куда меньше денег и времени. Процесс разработки может идти лет десять, и вовлечены в него оказываются тысячи людей, проверкой изделия занимается человек 10 в течение суток. Фактически это просто регулярные СТО, просто техника чуток посложнее. И когда до них доходит очередь, все причастные к сертифицированию процесса уже давно закончили все свои этапы, ибо первый образец просто не выпустят без наличия такого сертификата. Добавлено Цитата sergioK @ Тем, что они свои собственные. Хоть и похожие, но им начхать. В сбитом Боинге виноват будет человеческий фактор, который нажал кнопку. Техника тут в общем-то не бессильна, но её туда просто никто из военных не пустит. Не ИИ ума дело такие решения принимать, и это, увы, правильно, как бы цинично это не звучало. Тем что они не высокие ? То есть ракета может сбит мирный Боинг, и ничего страшного? |
Сообщ.
#42
,
|
|
|
Цитата Qraizer @ Значит это не высококритичный софт. Без обид. Как вариант – это он такой до первого судебного разбирательства, но это вряд ли. Это же очень субьетивно, Кто решает что критично а что нет, светофор не сработал авария трое погибщих, закурил на бензоколонке датчик не сработал, из-за ошибке в программе или сигнализация, это крититично или нет ? Добавлено Цитата Qraizer @ Если в вашей деятельности нет хотя бы одной из выше мной перечисленной активити, у вас обычный бизнес. И я перечислил отнюдь не все характерные отличия модели высококритичной разработки от всем хорошо известной бизнес-разработки, только наиболее характерные. Я что-то пропустил, где перечислил и что? Я не адвокат, но я знаю что критичный продукт это тот где могут пострадать люди или ущерб большой, какая разница не чем его писали то ? У нас случай был банк поменял Вино версию XP на 2000, произошел сбой, вернули версию, подлатые вроде заплатили банку, но это по слухам, адвокаты вроде договорились, больше ни очем подобном я не слышал, |
Сообщ.
#43
,
|
|
|
Вы просто используете разную терминологию.
|
Сообщ.
#44
,
|
|
|
Цитата D_KEY @ Вы просто используете разную терминологию. Вот мне тоже так показалось, это как на Аляске life stats after 40, все думают что речть про возраст, а там про температуру речь, |
Сообщ.
#45
,
|
|
|
Цитата sergioK @ Я что-то пропустил, где перечислил и что? Цитата Qraizer @ Просто для оценки планок. Когда-нибудь приходилось выкладывать в систему контроля версий объектный код и ассемблерные листинги с трассировкой на сырцы? Благо многие компиляторы это почти умеют сами. Почти. Учитывал ли реакцию твоего кода на INF и NaN? И вообще, приходилось ли обеспечивать сохранение работоспособности кода при любых невалидных воздействиях извне и немедленно возвращать свои выходы в номинальные диапазоны по прекращению невалидных воздействий? Приходилось ли собирать 100% структурное покрытие кода по MC/DC? Всего кода, не только твоего авторства. Объектного, не исходного. (Последнее, правда, обязательно только для уровня критичности level A.) Приходилось ли отказываться от стандартных библиотек и писать свои аналоги? Ради как раз 100% покрытия. Приходилось ли отказываться от некоторых возможностей языка, которые как раз и введены в основном ради отказоустойчивости? И всё из-за пресловутых 100%. Использовались ли методы доказательства корректности кода с опорой на тесты как доказательную базу? Именно доказательную, а не вероятностную. Общая алгебра, теория групп. Использовались ли математические методы доказательства правильности разработанных алгоритмов? Использовались ли методы доказательства корректности реализаций этих алгоритмов? Даташиты, официальные мануалы, стандарты языков и стандарты кодирования + теория множеств и формальная логика. Не превышал ли суммарный объём работ по документированию продукта на два порядка работы по разработке и тестированию этого кода? Тесты писаны вручную и без использования любых средств автоматизации, основанных на изучении кода? Тесты, созданные на основе задокументированного поведения кода, которое в свою очередь выполнено на человеческом языке, исполнялись и получали результаты на основе реального поведения объектного кода, из системы контроля версий который? Подвергались ли любые инструменты, как собственной разработки, так и сторонние, включая компиляторы, загрузчики, генераторы отчётности итп, процедурам квалификации, на основе результатов которых на них выдавалось заключение о том, что они подходящи для применения в сфере высококритичного ПО, и полученным с их помощью результатам можно доверять при условии невыхода условий их эксплуатации за указанные в заявке на квалификацию рамки? На закуску: приходилось ли проектировать системы с учётом возможных неизвестных аппаратных багов в процессорах? Qraizer, а можно я присоединюсь к вопросу: вы — это кто? Ну или где можно посмотреть список контор, которые выдают сертификаты на высококритичный софт |
Сообщ.
#46
,
|
|
|
Цитата sergioK @ Есть сферы, где критично всё. Хотя и с разными уровнями. Там просто не бывает невысококритичного ПО. За остальные случаи я уже говорил: это решает заказчик, исходя из своих соображений эксплуатации целевого продукта. И дай ему бог не ошибиться.Кто решает что критично а что нет Цитата sergioK @ Не пропустил. Ты оттуда цитировал.Я что-то пропустил, где перечислил и что? Цитата sergioK @ Это верно, но это не обязательно высококритичный продукт. Кроме того, возможные жертвы – это не единственный критерий. У нас как-то был проект от некоего оператора, не буду называть три большие буквы, которые хотели от нас полный цикл верификации виндового стека криптографии по упрощённой модели, ибо объём документации, понятное дело, ограничен. Кстати, тестирование должно выполняться без доступа к исходным кодам. Обычно его-таки дают, так дешевле, да и верификация в общем без анализа и рассмотрения многих аспектов требований и кода нереальна, но нужно всегда быть готовым к тому, что подсмотреть в коде ничего нельзя, есть только документация на него. Не уверен, я в нём не участвовал, хотя и консультировал по части архитектуры кода, работающего у винды на уровне ядра, но вроде бы это требовалось как часть процесса сертификации их банковских сервисов. С POSIX-ом им было проще, там открытый код. И да, это было давно, лет 10 как. Я не адвокат, но я знаю что критичный продукт это тот где могут пострадать люди или ущерб большой, какая разница не чем его писали то ? Добавлено Цитата kopilov @ https://checko.ru/company/aviaok-1036154001289 Информация в источниках может быть не вполне актуальной, сейчас мы из ООО кастуемся к АО. Спектр деятельности широкий, но помимо легко угадываемых по разделу дополнительной информации тут, они практически неактивны, поставщиков таких услуг и без нас хватает. Там просто все лицензии перечислены.вы — это кто? Цитата kopilov @ Конкретно в нашей сфере он один и хорошо известен. Возможно не обману, если упомяну РосАтом в сфере ядерной и атомной энергетики, но это неточно. Больше не знаю. Хотя Минздрав хотелось бы упомянуть, но ИМХО «это утопия» ©. Ну или где можно посмотреть список контор, которые выдают сертификаты на высококритичный софт Добавлено Цитата Qraizer @ Кстати, уже постил куда-то, сбаяню. Мой любимый пример.... но нужно всегда быть готовым к тому, что подсмотреть в коде ничего нельзя, есть только документация на него В документации сказано: «функция void sort(int *vec, size_t size) должна выполнять сортировку массива vec, размером size. Сортировка осуществляется по возрастанию, результат замещает исходный vec.» Требуется разработать набор тестовых сценариев для проверки этого требования. Естественно так, чтобы их можно было рассматривать как доказательную базу корректности реализации sort() согласно описанию её поведения. Если кому интересно, могут попробовать. Пример, конечно искусственный, но он хорошо демонстрирует разницу в подходах к тестированию у нас и у бизнеса. |
Сообщ.
#47
,
|
|
|
Цитата Qraizer @ Цитата sergioK @ Есть сферы, где критично всё. Хотя и с разными уровнями. Там просто не бывает невысококритичного ПО. За остальные случаи я уже говорил: это решает заказчик, исходя из своих соображений эксплуатации целевого продукта. И дай ему бог не ошибиться.Кто решает что критично а что нет Цитата sergioK @ Не пропустил. Ты оттуда цитировал.Я что-то пропустил, где перечислил и что? Цитата sergioK @ Это верно, но это не обязательно высококритичный продукт. Кроме того, возможные жертвы – это не единственный критерий. У нас как-то был проект от некоего оператора, не буду называть три большие буквы, которые хотели от нас полный цикл верификации виндового стека криптографии по упрощённой модели, ибо объём документации, понятное дело, ограничен. Кстати, тестирование должно выполняться без доступа к исходным кодам. Обычно его-таки дают, так дешевле, да и верификация в общем без анализа и рассмотрения многих аспектов требований и кода нереальна, но нужно всегда быть готовым к тому, что подсмотреть в коде ничего нельзя, есть только документация на него. Не уверен, я в нём не участвовал, хотя и консультировал по части архитектуры кода, работающего у винды на уровне ядра, но вроде бы это требовалось как часть процесса сертификации их банковских сервисов. С POSIX-ом им было проще, там открытый код. И да, это было давно, лет 10 как. Я не адвокат, но я знаю что критичный продукт это тот где могут пострадать люди или ущерб большой, какая разница не чем его писали то ? Добавлено Цитата kopilov @ https://checko.ru/company/aviaok-1036154001289 Информация в источниках может быть не вполне актуальной, сейчас мы из ООО кастуемся к АО. Спектр деятельности широкий, но помимо легко угадываемых по разделу дополнительной информации тут, они практически неактивны, поставщиков таких услуг и без нас хватает. Там просто все лицензии перечислены.вы — это кто? Цитата kopilov @ Конкретно в нашей сфере он один и хорошо известен. Возможно не обману, если упомяну РосАтом в сфере ядерной и атомной энергетики, но это неточно. Больше не знаю. Хотя Минздрав хотелось бы упомянуть, но ИМХО «это утопия» ©. Ну или где можно посмотреть список контор, которые выдают сертификаты на высококритичный софт Добавлено Цитата Qraizer @ Кстати, уже постил куда-то, сбаяню. Мой любимый пример.... но нужно всегда быть готовым к тому, что подсмотреть в коде ничего нельзя, есть только документация на него В документации сказано: «функция void sort(int *vec, size_t size) должна выполнять сортировку массива vec, размером size. Сортировка осуществляется по возрастанию, результат замещает исходный vec.» Требуется разработать набор тестовых сценариев для проверки этого требования. Естественно так, чтобы их можно было рассматривать как доказательную базу корректности реализации sort() согласно описанию её поведения. Если кому интересно, могут попробовать. Пример, конечно искусственный, но он хорошо демонстрирует разницу в подходах к тестированию у нас и у бизнеса. У нас был курс алгоритмов учили такому, у нас таким математики занимаються, при унивеситетах, но никак не в коммерческих компаниях, С сайта Цитата Крупный поставщик Организация поставила товаров или оказала услуг на сумму более 50 636 687 руб. Я опять что-то не понимаю ? это меньше 1 миилиона долларов, так ? , за 18лет работы ? но у нас это называеться киоск, У нас ларек пивной в год больше дает, ничего личного Цитата Не входит в реестр недобросовестных поставщиков Опять не понимаю, у нас такое в голову не придет писать, зачем ? А это что значит ? Цитата По данным ФНС, среднесписочная численность работников: 111 В фирме 111 работников ? Цитата 1Разработка, производство, испытание, установка, монтаж, техническое обслуживание, ремонт, утилизация и реализация вооружения и военной техники И тут я тебе понять не могу, ну ясно, что все это требует лицензиий, только софт то причем тут ? |
Сообщ.
#48
,
|
|
|
Цитата sergioK @ А у нас вчерашние студенты. Что делать, статус ИТ-столицы обязывает У нас был курс алгоритмов учили такому, у нас таким математики занимаються, при унивеситетах Цитата sergioK @ А он платит при этом миллионы человеко-часов 111-и работникам при белой бухгалтерии? А он использует при этом исключительно лицензионное ПО, потому как в противном случае ни один квалификационный сертификат не будет действительным? Документ, описывающий процесс развёртывания инструмента и полную методику работы с ним в наших процессах с приложенной лицензией на него как гарантом его подлинности, является хоть и далеко ещё не достаточным, но как ни крути неотъемлемым условием для получения квалификационного заключения по нему. И лицензии на подобного рода продукты из-за их малого рыночного спроса стоят нихрена себе. Просто для оценки вложений: в этом году нами была приобретена ещё одна лицензия на Rational Test Realtime за 2000000₱, а общий ордер на специализированное ПО, потраченный нами, нашим заказчиком и его головным распорядителем, за прошлый год составили около 125000000.У нас ларек пивной в год больше дает, ничего личного Цитата sergioK @ sergioK, ничего личного, но я был лучшего мнения о твоих аналитических способностях. К тому же это независимый источник, это его выводы о нас, а не наша реклама. ... |
Сообщ.
#49
,
|
|
|
Цитата Qraizer @ Цитата sergioK @ А он платит при этом миллионы человеко-часов 111-и работникам при белой бухгалтерии? А он использует при этом исключительно лицензионное ПО, потому как в противном случае ни один квалификационный сертификат не будет действительным?У нас ларек пивной в год больше дает, ничего личного У нас нет не белой бугалтерии и не лицензионного ПО, во-первых законы работают, во вторых можно систему обмануть можно только себе дороже, а в третих за ПО получают возврат, налогов и поддержку на случай сбоя, за пиратское по можешь штраф около 300,000$ или срок, а если вдруг сбой дасть то бизнес понесет убытки, Какой смысл стелять себе в ногу то ? А теперь название темы посмотри , может не надо уходить так далеко, можно новую тему открыть , если есть желание Добавлено Цитата Qraizer @ sergioK, ничего личного, но я был лучшего мнения о твоих аналитических способностях. К тому же это независимый источник, это его выводы о нас, а не наша реклама. Ну анализ можно проводит, когда реальность понимаешь, Я реально не понимаю зачем фирме на сайте писать что они честно работают, ясно что фирма существует много лет, то она работает кошерно, иначе б закрылась давно, вообще то ты ушел от темы, разговор был о софте и лицензиях не него, и цены на эти личензии вообще космические, даже по западным понятиям, Монтаж и все что написано на сайте к софту отношения не имеет. Добавлено Цитата Qraizer @ А он платит при этом миллионы человеко-часов 111-и работникам при белой бухгалтерии? У нас человеко-часов при дейсвующем бизнесе никто не считает, ну мне не известно, в одном из 111 в другом бизнесе 11, не факт что первый круче, да и не математика это считать можно по разному, полно всяких трюков(законных), |
Сообщ.
#50
,
|
|
|
sergioK, а кто первым ушёл от темы? Qraizer по нашей с тобой просьбе («вы — это кто?») дал ссылку на компанию, опосредованную (на независимый каталог — видимо, потому, что гугл, паразит, быстро индексирует). А ты уже начал выводы строить.
Ну и, раз такая пьянка, я тоже немного карты раскрою Добавлено Цитата sergioK @ У нас ларек пивной в год больше дает, ничего личного Ага, это не личное, это общественное: бухать наш народ любит |
Сообщ.
#51
,
|
|
|
Цитата sergioK @ В нашей сфере как раз принято контракты заключать под объёмы работ, которые измеряются именно что в человеко-часах. И они не с потолка берутся, есть стандартные таксы на ту или иную деятельность. Если кто работает быстрее, ему только плюс, больше денег в прибыль, но качество результатов естественно не должно страдать, если медленнее, то за свои, ибо зарплаты и налоги платить надо каждый месяц.У нас человеко-часов при дейсвующем бизнесе никто не считает, ну мне не известно Цитата sergioK @ Давай только без тролльства. Я ж не за вас, а за пресловутый ларёк, который ты упомянул.У нас нет не белой бугалтерии и не лицензионного ПО, во-первых законы работают И я не говорил, что наши прибыли баснословны. Это вообще к предмету высококритичности не имеет отношения, государственные кампании вообще на это могут положить и сосать бюджет, пока дают. Пока у государства Добавлено Цитата kopilov @ Ну как бы у нас нет страницы. Была, но в связи с реорганизацей тоже под редизайном. Давно уже, к слову, ответственный за это человек счас сильно другими вещами занят....на независимый каталог — видимо, потому, что гугл, паразит, быстро индексирует... Вообще, мне интересно, когда ж sergioK заметит, что он пытается оспорить свой же тезис. Ну не свой, а вон тот, про дроздов и строителей. Почему б не помочь хорошему человеку, если есть время, я после второй прививки немного свободен. Добавлено Ну так как насчёт задачки? Никто тестированием не занимался, что ли? Если сложно, можно попробовать попроще: "функция int sqeq(float a, float b, float c, float *x1, float *x2) должна решать квадратное уравнение с коэффициентами a, b и c. Выходные параметры x1 и x2 заполняются корнями уравнения, возвращаемое значение 1, если x1 и x2 успешно рассчитаны, или 0 в противном случае." С этой задачи у нас обычно начинается обучение джунов. |
Сообщ.
#52
,
|
|
|
Цитата Qraizer @ Ну не свой, а вон тот, про дроздов и строителей. про дроздов это когда программа дает сбой из-за поца, который не закрыл ресурс,естесно я упрощаю, и результат с десяток умерших, татаму что он физик а наниматель его друг детсва, или там брат подруги жены, добавь любое, а в строительсве если у ниженера нет лицензии то это не поможет, сотни, программист сделавший глупость юридически никак за это не отвечает, в отличии ои электрика , монтажника, механика и т,д, и количество этих багов зависит от его личной ответсвенности, желание сделать хорошо, воспитания, влияние окружение, желания быстро заработать и ,т,д, Вот и придумали шутку про дроздов, а в каждой шутке доля правды, as smaller as better Добавлено Цитата Qraizer @ В нашей сфере как раз принято контракты заключать под объёмы работ, которые измеряются именно что в человеко-часах. И они не с потолка берутся, есть стандартные таксы на ту или иную деятельность. В вашей это в какой ? ты же програмист или нет ? Добавлено Цитата Qraizer @ я после второй прививки немного свободен. И какая связь ? после второй прививки нельзя работать? Добавлено Цитата Qraizer @ Что делать, статус ИТ-столицы обязывает Таганрог это столица IT ? Или это была ирония ? |
Сообщ.
#53
,
|
|
|
Цитата applegame @ А в чем проблема его реализовать? Нет никакой проблемы его реализовать. В том, что любая операция добавления/изменения приводит к созданию полной копии списка. Цитата applegame @ Какое из твоих утверждений ЧТД? Оно было одно: Цитата их, например, нельзя просто сделать иммутабельными и/или ленивыми, в отличие от односвязных. Цитата applegame @ Это для чтения, а если надо перезаписать элемент, то придется часть этого дерева пересоздать, это будет стоить намного дороже. Не намного. Цитата applegame @ Возможно, что LinkedList - просто корявая реализация двусвязного списка 1) то что я перечислил, не особенности реализации LinkedList, а особенности двусвязных списков как структуры данных в принципе. 2) я тебе с самого начала говорил, что в твитте речь про LinkedList, но ты продолжил что-то додумывать. Цитата applegame @ Мои двусвязные списки (не на жабе, конечно) используют пулы Пулы чего? Цитата applegame @ и добавляют по два указателя к каждой ноде. Вот и получается x3: (указатель на объект + prev + next) вместо одного указателя на объект. Цитата applegame @ Я сделал предположение по этому его высказыванию (других я не знаю). А он явно сморозил чушь. Ты сделал предположение по каким-то своим фантазиям, которые упорно продолжаешь фантазировать. |
Сообщ.
#54
,
|
|
|
Цитата korvin @ И что? Любая операция добавления/изменения кортежа в эрланге приводят к созданию полной копии, и это совершенно не мешает быть кортежам иммутабельными.В том, что любая операция добавления/изменения приводит к созданию полной копии списка. Цитата korvin @ И оно неверное. И конечно же моя фраза про бесполезность никак не доказывает это твое утверждение. Ленивость - это вообще ортогональное явление. Сами списки не могут быть ленивыми - это бессмыслица. Ленивыми могут быть операции над самими списками или их элементами. И тут никакой разницы между односвязными и двусвязными списками нет вообще.Оно было одно: Цитата их, например, нельзя просто сделать иммутабельными и/или ленивыми, в отличие от односвязных. Цитата korvin @ Достаточно много, чтобы люди парились с хеш-таблицами и прочими алгоритмами с амортизированной константной сложностью.Не намного. Цитата korvin @ В твите речь не только о LinkedList, но ты продолжаешь игнорировать половину твита.1) то что я перечислил, не особенности реализации LinkedList, а особенности двусвязных списков как структуры данных в принципе. 2) я тебе с самого начала говорил, что в твитте речь про LinkedList, но ты продолжил что-то додумывать. Цитата korvin @ Пулы нод, для минимизации времени аллокации/освобождения памяти под ноду.Пулы чего? Цитата korvin @ Указатель на объект в любом случае есть. Поэтому получается +2*sizeof(size_t) на элемент, а не x3. В C/C++/D часто можно хранить в ноде сам объект, а не указатель на него, что позволяет сэкономить еще один указатель.Вот и получается x3: (указатель на объект + prev + next) вместо одного указателя на объект. Цитата korvin @ Какие фантазии? Автор прямо заявил, что любит односвязные списки, а LinkedList - это что-то совершенно другое. На мой вопрос, что именно "это совершенно другое" ты, видимо, ответить не в состоянии. Java мутабельный язык и в нём не прокатывает аргумент о проблемах персистентности. А в остальном получается, что LinkedList и односвязные списки - близнецы братья. Поэтому я и делаю вывод, что автор сморозил ерунду. Ты сделал предположение по каким-то своим фантазиям, которые упорно продолжаешь фантазировать. |
Сообщ.
#55
,
|
|
|
Цитата applegame @ Любая операция добавления/изменения кортежа в эрланге приводят к созданию полной копии, и это совершенно не мешает быть кортежам иммутабельными. При чём тут кортежи? Если ты используешь кортежи вместо массивов/списков, то ты используешь их неправильно. Цитата applegame @ Ленивость - это вообще ортогональное явление. Сами списки не могут быть ленивыми - это бессмыслица. Ленивыми могут быть операции над самими списками или их элементами ll = [ print 1 , print 2 , print 3 ] Какие операции тут ленивые? https://ideone.com/L5Toq1 Ленивые списки на Scheme (define-syntax lazy-cons (syntax-rules () ((_ head tail) (cons (delay head) (delay tail))))) (define (lazy-head ll) (force (car ll))) (define (lazy-tail ll) (force (cdr ll))) (define-syntax lazy-list (syntax-rules () ((_ x) (lazy-cons x '())) ((_ x . xs) (lazy-cons x (lazy-list . xs))))) ;;; ---------------------------------------------------------------- (define ll (lazy-list (print 1) (print 2) (print 3))) (lazy-head (lazy-tail ll)) https://ideone.com/BexV68 и на Java. Синтаксического сахара только не хватает import java.util.function.Supplier; /* Name of the class has to be "Main" only if the class is public. */ class Ideone { public static void main (String[] args) throws java.lang.Exception { var ll = Lazy.list( () -> print(1), () -> print(2), () -> print(3) ); ll.tail().head(); } private static Unit print(Object o) { System.out.println(o); return Unit.UNIT; } } final class Lazy { public static <T> Promise<T> delay(Supplier<T> expr) { return new Promise<>(expr); } public static <T> List<T> cons(Supplier<T> headExpr, Supplier<List<T>> tailExpr) { return new List<>(new Promise<>(headExpr), new Promise<>(tailExpr)); } public static <T> List<T> nil() { @SuppressWarnings("unchecked") var nil = (List<T>) List.NIL; return nil; } @SafeVarargs public static <T> List<T> list(Supplier<T>... values) { if (values == null || values.length == 0) { return nil(); } return list(values, 0); } private static <T> List<T> list(Supplier<T>[] values, int headCursor) { if (headCursor == values.length) { return nil(); } return new List<>(new Promise<>(values[headCursor]), new Promise<>(() -> list(values, headCursor+1))); } private Lazy() { throw new UnsupportedOperationException("utility class"); } } final class List<T> { static final List<?> NIL = new List<>(null, null); private final Promise<T> head; private final Promise<List<T>> tail; List(Promise<T> head, Promise<List<T>>tail) { this.head = head; this.tail = tail; } public T head() { return head.force(); } public List<T> tail() { return tail.force(); } } final class Promise<T> { private static final Object undefined = new Object(); private final Supplier<T> delayedExpression; @SuppressWarnings("unchecked") private T value = (T) undefined; Promise(Supplier<T> expr) { this.delayedExpression = expr; } public T force() { if (value == undefined) { value = delayedExpression.get(); } return value; } } final class Unit { public static final Unit UNIT = new Unit(); private Unit() {} } https://ideone.com/r0ttxo Цитата applegame @ Достаточно много, чтобы люди парились с хеш-таблицами и прочими алгоритмами с амортизированной константной сложностью. Ты путаешь тёплое с мягким. 1) никто в ФП не парится с хеш-таблицами 2) чистые функциональные хеш-таблицы реализуются точно также, как и функциональные массивы — с использованием деревьев и частичным копированием — и имеют точно такую же сложность. Цитата applegame @ В твите речь не только о LinkedList, но ты продолжаешь игнорировать половину твита. Но речи о single-linked-list vs double-linked-list там нет, так что нет, не игнорирую. Цитата applegame @ Пулы нод, для минимизации времени аллокации/освобождения памяти под ноду. Т.е. ты 1) практически делаешь работу аллокатора 2) никак не решаешь отсутствие векторизации 3) усложняешь структуру данных / её использование, вместо того, чтобы попробовать другую структуру, не имеющую таких проблем отличное решение, молодец. Цитата applegame @ Указатель на объект в любом случае есть. Поэтому получается +2*sizeof(size_t) на элемент, а не x3. 1(указатель на объект) + 2 = 3, поэтому x3. Если ты почему-то думал, что x3 = 1+3, то нет. Цитата applegame @ Автор прямо заявил, что любит односвязные списки Нет, он написал Цитата Don't get me wrong; I love linked lists. They're as useful in C as they are in Scheme. Ладно Scheme, но с чего ты взял, что «linked lists ... in C» означает «односвязные списки»? В C нет двусвязных? Может, ему, например, нравятся интрузивные двусвязные списки в Си? Цитата applegame @ Java мутабельный язык Ты теперь ещё и терминологию какую-то выдумываешь. В Java нельзя описывать иммутабельные объекты? Это запрещено на уровне JVM? Как же Scala и Clojure работают? Может их не рекомендуют к использованию? Да нет, наоборот, рекомендуют. Вот и в стандартной библиотеке давно появилось StreamAPI для работы с коллекциями в функциональном стиле, а неизменяемые обёртки для стандартных коллекций в JDK существуют с незапамятных времён. Добавлено Цитата sergioK @ Да приколист, он взявший имя автора известной книги по Яве, IMHO Это и есть автор известной книги по Яве, а также части JDK, в том числе и LinkedList. Цитата sergioK @ Стандартный класс, который использует полмира уже лет 20, не нравиться Какие полмира? Кто его использует? Все хоть сколько-нибудь адекватные люди если и используют его, то крайне редко. Ты тоже любишь пофантазировать? https://discuss.kotlinlang.org/t/why-kotlin...ntation/15991/2 Цитата sergioK @ наследуй и пиши свою реализацию пулами или без, хотя я не понимаю зачем, И я не понимаю, зачем, если есть замечательные ArrayList и ArrayDeque. Добавлено ArrayList vs LinkedList benchmark |
Сообщ.
#56
,
|
|
|
Цитата korvin @ Какие полмира? Кто его использует? Все хоть сколько-нибудь адекватные люди если и используют его, то крайне редко. Ты тоже любишь пофантазировать? Не прнимающие направо и на лево используют ArrayList, исторический курьез языка, А LinkedList нужен когда ды ты считываешь данные неопередельной длины, особенно большие обьемы, необходимось зависит от задачи, зачем он двойной нужен это разговор отдельный, Добавлено Цитата korvin @ И я не понимаю, зачем, если есть замечательные ArrayList и ArrayDeque. Ты на втором курсе data structure изучал ? Array имеет фиксированный размер памяти, LL нет, кто применять и где зависить от тебя и понимания задачи, все разговоры о ом что LL устарел чистой воды тролинг, или не понимание. |
Сообщ.
#57
,
|
|
|
Цитата sergioK @ А LinkedList нужен когда ды ты считываешь данные неопередельной длины, особенно большие обьемы, Нет, не нужен. Цитата sergioK @ Ты на втором курсе data structure изучал ? А ты data structures только на уровне базового курса университета знаешь? Цитата sergioK @ Array имеет фиксированный размер памяти, LL нет, Ты вообще, в курсе, что такое ArrayList? Цитата sergioK @ что применять и где зависить от тебя и понимания задачи, все разговоры Не только от этого, но и от характеристик самой структуры данных. Цитата sergioK @ о ом что LL устарел чистой воды тролинг, или не понимание. Это у тебя полное непонимание того, как работает JVM, память и процессор. |
Сообщ.
#58
,
|
|
|
Цитата korvin @ При том, что твой аргумент, что двусвязный список нельзя сделать иммутабельным, потому что надо его целиком копировать при, например, добавлении элемента несостоятелен. Двусвязный список можно сделать иммутабельным. Для того же эрланга можно как нефиг делать написать NIF реализующий иммутабельный двусвязный список.При чём тут кортежи? Если ты используешь кортежи вместо массивов/списков, то ты используешь их неправильно. Цитата korvin @ Очевидно print. Словосочетание "ленивый список" - это по сути жаргонизм обозначающий список с поддержкой ленивых вычислений над элементами. Но суть-то не в терминах. Суть в том, что двусвязный список тоже можно сделать с поддержкой ленивых вычислений (или просто ленивым, если тебе так хочется), не вижу никаких препятствий.Какие операции тут ленивые? Цитата korvin @ Не путаю. Просто ты в каждом ответе норовишь съехать куда-то в сторону.Ты путаешь тёплое с мягким. 1) никто в ФП не парится с хеш-таблицами 2) чистые функциональные хеш-таблицы реализуются точно также, как и функциональные массивы — с использованием деревьев и частичным копированием — и имеют точно такую же сложность. 1) Не парятся потому что выбора у них нет. А в языках с поддержкой мутабельности еще как парятся. 2) См. ответ на пункт 1. Вывод: иммитация массива на деревьях в ФП - вынужденная мера, это лучшее, что там можно сделать. Это слабое место иммутабельного ФП. И памяти оно ест больше и к кэшу процессора недружелюбно и доступ неконстантный. И-за этого в узких местах приходится городить костыли на языках с поддержкой мутабельности. Цитата korvin @ Я думаю, ты просто некомпетентен в этой области. Почитай про мемори пулы и вообще про низкоуровневую оптимизацию работы с памятью, инфа на эту тему есть.Т.е. ты 1) практически делаешь работу аллокатора 2) никак не решаешь отсутствие векторизации 3) усложняешь структуру данных / её использование, вместо того, чтобы попробовать другую структуру, не имеющую таких проблем отличное решение, молодец. Цитата korvin @ Ну а о чем там тогда речь? Почему "LinkedList is another matter entirely"? Раз ты процитировал этот кусок, то хотелось бы услышать твое понимание слов автора.Но речи о single-linked-list vs double-linked-list там нет, так что нет, не игнорирую. Цитата korvin @ Ну в общем-то из-за Scheme я так и понял. Ну и как из фразы "They're as useful in C as they are in Scheme" можно вообще сделать вывод, что в C автор имел ввиду не те же списки, что и в Scheme? Альтернативный английский? Ну и если эти linked list так полезны в C, а LinkedList это "another matter entirely", то вероятно в Java должен существовать правильный linked list, аналогичный таковому в C и Scheme. Он существует?Ладно Scheme, но с чего ты взял, что «linked lists ... in C» означает «односвязные списки»? В C нет двусвязных? Может, ему, например, нравятся интрузивные двусвязные списки в Си? Цитата korvin @ А ты типа не понял о чем речь? Или таки сделал вид, что не понял? Ок, разъясняю: "мутабельным языком" я назвал язык имеющий встроенную поддержку мутабельных переменных. Так понятнее? Ну и как обычно ты сворачиваешь с основной темы. Давай уже назад к "иммутабельным/ленивым" двусвязным спискам. По твоему мнению их можно сделать таковыми или нет? Если нет, то что именно мешает?Ты теперь ещё и терминологию какую-то выдумываешь. Цитата korvin @ Ну это вообще из серии "сам придумал - сам опровергнул". В Java нельзя описывать иммутабельные объекты? Это запрещено на уровне JVM? Как же Scala и Clojure работают? Может их не рекомендуют к использованию? Да нет, наоборот, рекомендуют. Вот и в стандартной библиотеке давно появилось StreamAPI для работы с коллекциями в функциональном стиле, а неизменяемые обёртки для стандартных коллекций в JDK существуют с незапамятных времён. |
Сообщ.
#59
,
|
|
|
Цитата applegame @ При том, что твой аргумент, что двусвязный список нельзя сделать иммутабельным, потому что надо его целиком копировать при, например, добавлении элемента несостоятелен. Состоятелен, потому что юз-кейсы у списка и кортежа принципиально разные. Цитата applegame @ Двусвязный список можно сделать иммутабельным. Для того же эрланга можно как нефиг делать написать NIF реализующий иммутабельный двусвязный список. Без копирования? Ну-ну. Цитата applegame @ Очевидно print. Очевидно, 1) print здесь элемент списка, а не «операция» над элементом списка, 2) в примерах на Scheme и Java print не является ленивой функцией. Цитата applegame @ Суть в том, что двусвязный список тоже можно сделать с поддержкой ленивых вычислений (или просто ленивым, если тебе так хочется), не вижу никаких препятствий. Нельзя, из-за обратной ссылки на предыдущий элемент. Ты не сможешь даже сконструировать такой список. Цитата applegame @ Просто ты в каждом ответе норовишь съехать куда-то в сторону. Вообще-то съезжать в сторону начал ты с самого начала. Цитата applegame @ Я думаю, ты просто некомпетентен в этой области. Почитай про мемори пулы и вообще про низкоуровневую оптимизацию работы с памятью, инфа на эту тему есть. Я думаю, что ты некомпетентен, но думаешь, будто компетентен. Вот и скинь ссылку на «правильную» с твоей точки зрения инфу. А лучше сразу свой связный список с мемори пулом и примером юз-кейса для тестирования/замера. Цитата applegame @ Ну а о чем там тогда речь? Речь о том, что класс LinkedList оказался на практике почти бесполезен. Цитата applegame @ Ну в общем-то из-за Scheme я так и понял. Я так и подумал, что ты выборочно прочитал то, что захотел прочитать и триггернулся. Цитата applegame @ Ну и как из фразы "They're as useful in C as they are in Scheme" можно вообще сделать вывод, что в C автор имел ввиду не те же списки, что и в Scheme? Вопрос другой: как из этой фразы можно было сделать вывод, что автор имел в виду совершенно одинаковые структуры данных в двух сильно разных языках? Цитата applegame @ Ну и если эти linked list так полезны в C, а LinkedList это "another matter entirely", то вероятно в Java должен существовать правильный linked list, аналогичный таковому в C и Scheme. Он существует? В JDK — нет. В сторонних библиотеках коллекций — возможно. Вот, например, в org.apache.commons есть двусвязный список с этим твои кэшированием нод Цитата applegame @ А ты типа не понял о чем речь? Я-то понял, только зачем ты терминологию выдумываешь? Цитата applegame @ По твоему мнению их можно сделать таковыми или нет? Если нет, то что именно мешает? Нет. Что мешает, написал выше. Ты, конечно, можешь просто взять мой пример ленивого односвязного списка для Java и сделать двусвязный. Ну или с нуля на твоём любимом языке. Цитата applegame @ Ну это вообще из серии "сам придумал - сам опровергнул". Кто ж разберёт твои фантазии. |
Сообщ.
#60
,
|
|
|
Цитата korvin @ Цитата sergioK @ Ты на втором курсе data structure изучал ? А ты data structures только на уровне базового курса университета знаешь? Нет, не только Добавлено Цитата korvin @ Ты вообще, в курсе, что такое ArrayList? Я таких ArrayList не один десяток написал , разных имплементаций , ArrayList умножает память на 3/2 и перегрузить это нельзя в отличии от вектора, и это одна имлементация интерфэйса java.util.List другая это Linked List, пользуешь когда не знаешь сколько элементов будет. |
Сообщ.
#61
,
|
|
|
Цитата korvin @ Кортеж это пример иммутабельной структуры требующей полного копирования для изменения. Кейсы тут вообще не в тему, ты же ни о каких кейсах не упоминал, когда заявил:Состоятелен, потому что юз-кейсы у списка и кортежа принципиально разные. Цитата korvin @ В том, что любая операция добавления/изменения приводит к созданию полной копии списка. Цитата korvin @ Память у тебя как у рыбки:Без копирования? Ну-ну. Цитата applegame @ Ты таки согласен, что иммутабельный двусвязный список может быть реализован, с полным копированием при добавлении/изменении? Ответь прямо без юления.Если двусвязный список сделать встроенным в язык типом, то он вполне может быть персистентным, а при добавлении новых элементов просто копировать его целиком. Бесполезно, но возможно. Цитата korvin @ Ну если уж доёбываться, то элемент списка не сам print а результат каррирования print. Можно переделать твой пример, чтобы была операция над элементами: https://ideone.com/hPXX7oОчевидно, 1) print здесь элемент списка, а не «операция» над элементом списка, 2) в примерах на Scheme и Java print не является ленивой функцией. Суть не меняется, ленивый не список, а вычисления. Цитата korvin @ Вот сам придумываешь какие-то странные термины, что такое "ленивая функция"? Чем она отличается от "неленивой"?2) в примерах на Scheme и Java print не является ленивой функцией. Цитата korvin @ Ну давай вернемся. Я с самого начала пытаюсь выяснить почему LinkedList, по словам жаба-селебрити, "совсем другое дело". Но пока от тебя так и не услышал ответа. Ты говооришь о чем угодно, кроме сути. Может таки ответишь вместо переливания в из пустого в порожнее?Вообще-то съезжать в сторону начал ты с самого начала. Цитата korvin @ Ты явно путаешь принципиальную возможность создать такой список и возможность создать его средствами самого иммутабельного ФП-языка. Повторю еще раз: двусвязный список при желании можно встроить в любой иммутабельный ФП язык. В Erlang это можно сделать например при помощи NIF: создаем сначала мутабельный список, заполняем ноды данными, после чего делаем иммутабельным. В общем-то аналогично кортежам, которые в том же эрланге являются, по сути, иммутабельными массивами.Нельзя, из-за обратной ссылки на предыдущий элемент. Ты не сможешь даже сконструировать такой список. Ленивость же, как я говорил, вообще ортогональна всему этому. В том же D, я могу сделать тебе ленивый рендж, хоть односвязный (ForwardRange), хоть двусвязный (BidirectionalRange), хоть вообще массив (RandomAccessRange). Хошь мутабельный, хошь иммутабельный. Цитата korvin @ Интересует почему. Какое принципиальное отличие от односвязных списков в Scheme или сферических в вакууме списков в C?Речь о том, что класс LinkedList оказался на практике почти бесполезен. Цитата korvin @ Односвязный список и в Африке односвязный, какая разница это C или Scheme? Можно еще говорить о разных степенях оптимизации, но автор явно абстрагировался от этого, так как упомянул C, в котором вообще не существует какой-либо стандартной реализации списка. Если бы он скажем заявил, что-то вроде "не поймите неправильно, мне нравятся связные списки, они могут быть полезны, но вот LinkedList сделан через жопу, поэтому не используйте его", то это было бы логично. Возможно автор именно это и имел в виду, но сказал нечто совершенно иное.Вопрос другой: как из этой фразы можно было сделать вывод, что автор имел в виду совершенно одинаковые структуры данных в двух сильно разных языках? Цитата korvin @ Молодец, просвещайся дальше. Даю подсказку: ноды еще можно не по одной аллоцировать, а сразу непрерывными блоками по несколько штук, причем можно сразу и место для данных аллоцировать внутри ноды (интрузивные списки, о которых я писал ранее, а после и ты). Особо упоротые оптимизаторы, длину этих блоков еще и с размером строки кэша процессора норовят выровнять.Вот, например, в org.apache.commons есть двусвязный список с этим твои кэшированием нод Цитата korvin @ А в чем проблема? Не нравится мой термин, предложи свой. Тем более если ты понял, то зачем цепляться? Лишь бы что-нибудь возразить? Я-то понял, только зачем ты терминологию выдумываешь? |
Сообщ.
#62
,
|
|
|
Цитата korvin @ Сделал на D. И синтаксический сахар есть.Нет. Что мешает, написал выше. Ты, конечно, можешь просто взять мой пример ленивого односвязного списка для Java и сделать двусвязный. Ну или с нуля на твоём любимом языке. 1. Вместо head - front, вместо tail - popFront. Также есть back и popBack - аналоги для другого конца списка. Список иммутабелен. Добавление элементов (append) создает копию списка, popFront и popBack не создают копию. Для демонстрации иммутабельности, добавляю не сразу все элементы к списку, а за два раза. Обратите внимание, что все переменные в main константные, кастов в программе нет, так что они реально иммутабельные. Элементы вычисляются лениво. Для подтверждения этого создал структуру Int, иммитирующую обычное целое, с перегруженным оператором сложения, который печатает в консоль текст подтверждающий, что сложение реально произошло. В данной программе вычисляется только второй элемент списка, так как именно он выводится на экран. Тестировал мало, возможны ошибки. Играться тут: https://glot.io/snippets/fxwh6ktfxg Код: Скрытый текст import std.stdio; struct Int { int value; Int opBinary(string op: "+")(Int other) const { writefln("%s + %s = %s", value, other.value, value + other.value); return Int(value + other.value); } } void main() { const l0 = DList!Int(); const l1 = l0.append( Int(1) + Int(1), ); const l2 = l1.append( Int(2) + Int(2), Int(3) + Int(3), Int(4) + Int(4) ); writeln(l2.popFront().front); } struct DList(T) { struct Node { T delegate() payload; Node* prev, next; } private Node* m_first, m_last; bool empty() const { return m_first == null; } T front() const { assert(!empty); return m_first.payload(); } T back() const { assert(!empty); return m_last.payload(); } const(DList) popFront() const { assert(!empty); return m_first == m_last ? const DList() : const DList(m_first.next, m_last); } const(DList) popBack() const { assert(!empty); return m_first == m_last ? const DList() : const DList(m_first, m_last.prev); } const(DList) append(ARGS...)(lazy ARGS args) const { auto list = dup(); static foreach(arg; args) { if(empty) { list.m_first = list.m_last = new Node(&arg); } else { list.m_last.next = new Node(&arg, list.m_last); list.m_last = list.m_last.next; } } return list; } private DList dup() const { auto list = DList(); if(!empty) { auto prev = new Node(m_first.payload); list.m_first = prev; const(Node)* cur = m_first.next; while(cur != m_last.next) { auto node = new Node(cur.payload, prev); prev.next = node; prev = node; cur = cur.next; } list.m_last = prev; } return list; } } Полагаю, на этом вопрос возможности создания иммутабельных ленивых двусвязных списков будет закрыт. |
Сообщ.
#63
,
|
|
|
Цитата sergioK @ Я таких ArrayList не один десяток написал , разных имплементаций , Зачем? Руки чесались? ) Цитата sergioK @ ArrayList умножает память на 3/2 и перегрузить это нельзя в отличии от вектора, А LinkedList умножает память на 3. Цитата sergioK @ и это одна имлементация интерфэйса java.util.List другая это Linked List, пользуешь когда не знаешь сколько элементов будет. Вот тебе бенчмарк на добавление «не знаешь сколько элементов»: Скрытый текст import org.openjdk.jmh.annotations.*; import org.openjdk.jmh.infra.Blackhole; import ru.sources.collections.Collections; import java.util.Collection; import java.util.concurrent.TimeUnit; import java.util.function.IntFunction; @BenchmarkMode(Mode.AverageTime) @Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) @Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) @OutputTimeUnit(TimeUnit.MICROSECONDS) @Fork( value = 3, jvm = "/Library/Java/JavaVirtualMachines/adoptopenjdk-15.jdk/Contents/Home/bin/java", jvmArgsAppend = { "-server", "-disablesystemassertions", //"-XX:+UseSerialGC", //"-XX:+UseParallelGC", //"-XX:+UseZGC", "-XX:+UseShenandoahGC", "-Xms8g", "-Xmx8g" }) @State(Scope.Thread) public class CollectionsBenchmark { private static final String LINKED_LIST = "LinkedList"; private static final String ARRAY_LIST = "ArrayList"; //@Param({"10", "100"}) //@Param({"100", "10000", "1000000"}) @Param({"1000", "100000", "10000000"}) private int itemsToAdd; @Param({LINKED_LIST, ARRAY_LIST}) private String type; private IntFunction<Collection<?>> subject; @Setup public void setup() { switch (type) { case LINKED_LIST -> subject = Collections::linkedList; case ARRAY_LIST -> subject = Collections::arrayList; } } @Benchmark public void addMany(Blackhole blackhole) { blackhole.consume(subject.apply(itemsToAdd)); } } subjects import java.util.ArrayList; import java.util.Collection; import java.util.LinkedList; public final class Collections { public static Collection<?> linkedList(int items) { final var c = new LinkedList<>(); for (int i = 0; i < items; i++) { c.add(i); } return c; } public static Collection<?> arrayList(int items) { final var c = new ArrayList<>(); for (int i = 0; i < items; i++) { c.add(i); } return c; } } Вот результаты с разными GC (меньше — лучше): Serial: Benchmark (itemsToAdd) (type) Mode Cnt Score Error Units CollectionsBenchmark.addMany 1000 LinkedList avgt 15 5.210 ± 0.053 us/op CollectionsBenchmark.addMany 1000 ArrayList avgt 15 3.530 ± 0.028 us/op CollectionsBenchmark.addMany 100000 LinkedList avgt 15 487.786 ± 7.153 us/op CollectionsBenchmark.addMany 100000 ArrayList avgt 15 361.776 ± 3.407 us/op CollectionsBenchmark.addMany 10000000 LinkedList avgt 15 114308.717 ± 24496.008 us/op CollectionsBenchmark.addMany 10000000 ArrayList avgt 15 74059.694 ± 1124.293 us/op Parallel: Benchmark (itemsToAdd) (type) Mode Cnt Score Error Units CollectionsBenchmark.addMany 1000 LinkedList avgt 15 5.191 ± 0.038 us/op CollectionsBenchmark.addMany 1000 ArrayList avgt 15 3.524 ± 0.042 us/op CollectionsBenchmark.addMany 100000 LinkedList avgt 15 490.742 ± 7.725 us/op CollectionsBenchmark.addMany 100000 ArrayList avgt 15 364.297 ± 7.221 us/op CollectionsBenchmark.addMany 10000000 LinkedList avgt 15 145307.026 ± 35319.645 us/op CollectionsBenchmark.addMany 10000000 ArrayList avgt 15 71625.532 ± 3860.046 us/op ZGC: Benchmark (itemsToAdd) (type) Mode Cnt Score Error Units CollectionsBenchmark.addMany 1000 LinkedList avgt 15 5.714 ± 0.548 us/op CollectionsBenchmark.addMany 1000 ArrayList avgt 15 5.573 ± 0.298 us/op CollectionsBenchmark.addMany 100000 LinkedList avgt 15 553.497 ± 38.279 us/op CollectionsBenchmark.addMany 100000 ArrayList avgt 15 583.829 ± 33.537 us/op CollectionsBenchmark.addMany 10000000 LinkedList avgt 15 136561.101 ± 62714.469 us/op CollectionsBenchmark.addMany 10000000 ArrayList avgt 15 147221.840 ± 65372.420 us/op Senandoah: Benchmark (itemsToAdd) (type) Mode Cnt Score Error Units CollectionsBenchmark.addMany 1000 LinkedList avgt 15 4.516 ± 0.100 us/op CollectionsBenchmark.addMany 1000 ArrayList avgt 15 3.904 ± 0.123 us/op CollectionsBenchmark.addMany 100000 LinkedList avgt 15 453.895 ± 6.612 us/op CollectionsBenchmark.addMany 100000 ArrayList avgt 15 359.160 ± 7.098 us/op CollectionsBenchmark.addMany 10000000 LinkedList avgt 15 59037.699 ± 9332.316 us/op CollectionsBenchmark.addMany 10000000 ArrayList avgt 15 56993.428 ± 3011.366 us/op Ну и где тут преимущества LinkedList на добавление неизвестного заранее количества элементов? С первыми двумя GC LinkedList заметно сливает, со вторыми ± одинаково получается. Добавлено Цитата applegame @ Кортеж это пример иммутабельной структуры требующей полного копирования для изменения. Кейсы тут вообще не в тему, ты же ни о каких кейсах не упоминал, когда заявил: А по-твоему, списки они сферические в вакууме? Цитата applegame @ Память у тебя как у рыбки: Наоборот же, у тебя, не говоря уж, о твоих проблемах с чтением: Цитата Насчёт двусвязных списков не скажу, но как минимум их, например, нельзя просто сделать иммутабельными и/или ленивыми, в отличие от односвязных. на второй странице. Цитата applegame @ Ты таки согласен, что иммутабельный двусвязный список может быть реализован, с полным копированием при добавлении/изменении? Ответь прямо без юления. С полным копированием можно что угодно сделать иммутабельным, только это не «просто». Тебе же не нужно показывать, как делается иммутабельный односвязный список? Цитата applegame @ Вот сам придумываешь какие-то странные термины, что такое "ленивая функция"? Чем она отличается от "неленивой"? Э-э… у тебя раздвоение личности? Я тебя спросил, какая операция там ленивая, ты ответил «print». print — это функция, т.е. ты же и назвал её ленивой Цитата applegame @ Ну давай вернемся. Я с самого начала пытаюсь выяснить почему LinkedList, по словам жаба-селебрити, "совсем другое дело". Но пока от тебя так и не услышал ответа. Ты говооришь о чем угодно, кроме сути. Может таки ответишь вместо переливания в из пустого в порожнее? Я тебе уже давно ответил, даже три пункта перечислил, с которыми ты же согласился, написав, что «Возможно, что LinkedList - просто корявая реализация двусвязного списка, тут спорить не буду ибо не знаю. Мои двусвязные списки (не на жабе, конечно) используют пулы, и добавляют по два указателя к каждой ноде.» (3-я страница). проверь память, я серьёзно. Причём, вот ещё, например, кейс, вроде бы подходящий для двусвязного списка: LRU-кэш, но там нужно иметь ссылки на ноды, чтобы эффективно переставлять их в начало списка, но LinkedList не предоставляет возможности иметь ссылку на ноду, т.е. для этого кейса не подходит. Цитата applegame @ Ты явно путаешь принципиальную возможность создать такой список и возможность создать его средствами самого иммутабельного ФП-языка. Я нигде не писал про «принципиальную невозможность». Цитата applegame @ Какое принципиальное отличие от односвязных списков в Scheme двусвязность и закрытость для тебя не достаточно принципиальные отличия? Не знаю тогда. Может для тебя вообще все динамические структуры «на одно лицо»? Цитата applegame @ сферических в вакууме списков в C? Такая же сферическая в вакууме. Мне как-то не интересно гадать. Цитата applegame @ Односвязный список и в Африке односвязный, какая разница это C или Scheme? Во-первых, односвязный список можно реализовать по-разному: – интрузивный или не интрузивный – закрытый (объект-контейнер с внутренним приватным списком нод и предоставляющий доступ к элементов только описанными методами, инкапсулирующий манипуляции над нодами) или открытый (просто создаются сразу сами объекты нод) Цитата applegame @ "не поймите неправильно, мне нравятся связные списки, они могут быть полезны, но вот LinkedList сделан через жопу, поэтому не используйте его" Он именно так и написал, но ты предпочёл поСПГСить. Цитата applegame @ Даю подсказку: ноды еще можно не по одной аллоцировать, а сразу непрерывными блоками по несколько штук, причем можно сразу и место для данных аллоцировать внутри ноды (интрузивные списки, о которых я писал ранее, а после и ты) Вопрос: если ты не манипулируешь нодами, переставляя их, то нафига тебе связный список? Используй массив. А если манипулируешь, то вся эта изначальная локальность пойдёт лесом на хоть сколько-нибудь большом списке. Цитата applegame @ А в чем проблема? Не нравится мой термин, предложи свой. Тем более если ты понял, то зачем цепляться? Лишь бы что-нибудь возразить? Зачем я буду придумывать какой-то свой, если такие языки называют императивными? |
Сообщ.
#64
,
|
|
|
DEL (опечатался там)
|
Сообщ.
#65
,
|
|
|
Цитата sergioK @ ArrayList умножает память на 3/2 и перегрузить это нельзя в отличии от вектора, Только вектор 1) растёт на константное значение, что при большом количестве операций добавления требует больше реаллокаций и мене эффективно, чем ArrayList 2) synchronized, а значит ещё и имеет оверхед на lock/unlock на каждую операцию, даже если это не нужно, т.е. в большинстве юз-кейсов. Цитата sergioK @ ArrayList умножает память на 3/2 Ах да, ты ещё забыл, что у объекта Node в LinkedList'е помимо 3-х ссылок (elem, prev, next) есть ещё и object header, который в Java довольно жирный. Например, для 64bit JVM без сжатия указателей получим на каждый элемент: objectHeader.classRef = 8 + objectHeader.mark = 8 + object.element = 8 + object.previous = 8 + object.next = 8 = 40 bytes per node / object.element = 8 = 5x В пять раз больше памяти на ссылки по сравнению с ArrayList, Карл! – LinkedList на 1млн элементов будет иметь оверхед 32 мегабайта. – ArrayList на 1млн элементов, с capacity, увеличенной в полтора раза, будет иметь оверхед в 4 мегабайта. Для 64bit JVM с включённым сжатием указателей получим на каждый элемент: objectHeader.classRef = 4 + objectHeader.mark = 8 // это поле всё равно будет 8 байт на 64bit JVM + object.element = 4 + object.previous = 4 + object.next = 4 = 24 bytes per node / object.element = 4 = 6x — уже в шесть раз больше. Вот так сжали… ) Понятно, что в абсолютных значения оверхед будет меньше: – LinkedList на 1млн элементов будет иметь оверхед 20 мегабайт. – ArrayList на 1млн элементов, с capacity, увеличенной в полтора раза, будет иметь оверхед 2 мегабайта. А ты собрался много данных в LinkedList загружать. 1млрд элементов: LL — +20 гигабайт с сжатием, а фактически, думаю, хип перевалит за 32 гига (ведь у нас ещё есть сами элементы и данные в них), и JVM отключит сжатие указателей и мы получим 32 гига на одни только ноды LinkedList'а, не считая ещё самих элементов и данных в них. AL — +2 гига с сжатием. Даже под реаллокации ещё достаточно места до 32-хгигабайтного порога отключения сжатия. Удачи тебе с LinkedList'ом в этом деле. |
Сообщ.
#66
,
|
|
|
applegame, не понимаю, почему у тебя front и back возвращают payload, а не next и prev соответственно.
И как пройти по такому списку вперёд-назад и наоборот? Типа void forward(const DList!Int l) { writeln("-- forward"); if (l.empty()) { return; } writeln(l.front); forward(l.popFront()); } void backward(const DList!Int l) { writeln("-- backward"); if (l.empty()) { return; } writeln(l.back); backward(l.popBack()); } void forwardBackward(const DList!Int l) { writeln("-- forwardBackward"); if (l.empty()) { return; } writeln(l.front); const next = l.popFront(); if (next.empty()) { backward(l); } else { forwardBackward(next); } } void backwardForward(const DList!Int l) { writeln("-- backwardForward"); if (l.empty()) { return; } writeln(l.back); const prev = l.popBack(); if (prev.empty()) { forward(l); } else { backwardForward(prev); } } вызов forwardBackward должен напечатать (условно) 1 2 3 4 3 2 1 через pop*-методы так не работает. И вот ещё важный момент: в односвязном ленивом списке суть не в ленивости элементов, а в ленивости построения самого списка (т.е. хвоста), поэтому возможно задать бесконечный список и работать с ним, используя как генератор/inputstream. Каноничный бесконечный ленивый список чисел фибоначчи на Хаскелле задаётся так: fibs = 0 : 1 : zipWith (+) fibs (tail fibs) Напечатать первые 10 чисел: print $ take 10 fibs https://ideone.com/bB92Nu На Scheme моя реализация работает также, без модификаций: https://ideone.com/ysmTzd На Java чуть сложнее из-за более статических пространств имён, поэтому приходится использовать небольшой костыль Cell, но никаких модификаций самой реализации списка не требуется, и все дополнительные функции (zip, take) реализуются также, как в Haskell и Scheme и всё работает: https://ideone.com/K4Z9QW Хотя, можно обойтись и без Cell, используя просто саму функцию: https://ideone.com/DDjz1i Соответственно ленивым у тебя должен быть не столько payload, сколько next и prev. |
Сообщ.
#67
,
|
|
|
Цитата korvin @ Это у тебя полное непонимание того, как работает JVM, память и процессор. Linked List никуда не умер и нужен для вполне конкретный целей, хватит тут теории разводить,с умным видом, JVM тут ыообще не причем, он и в STL есть, Добавлено Цитата korvin @ Ах да, ты ещё забыл, что у объекта Node в LinkedList'е помимо 3-х ссылок (elem, prev, next) есть ещё и object header, который в Java довольно жирный. Я ничего не забыл, лишних 24 байта, не надо меня тут учить data structure , Добавлено Цитата korvin @ 1) растёт на константное значение, что при большом количестве операций добавления требует больше реаллокаций и мене эффективно, чем ArrayList 2) synchronized, а значит ещё и имеет оверхед на lock/unlock на каждую операцию, даже если это не нужно, т.е. в большинстве юз-кейсов. 1) Ты сам реализуешь так как тебе нужно, теоретик млин 2) Если не подходит для данной задачи не используй, то что в ArrayList insureCapacity private - чистой воды косяк, |
Сообщ.
#68
,
|
|
|
Цитата sergioK @ Linked List никуда не умер и нужен для вполне конкретный целей, Я ничего не забыл, лишних 24 байта, не надо меня тут учить data structure Это прекрасно, а как с джунами в итоге поступили? И один ли ты кул гай д`Артаньян? |
Сообщ.
#69
,
|
|
|
Цитата sergioK @ хватит тут теории разводить,с умным видом Какие теории, болезный? Я тебе вон бенчмарк скинул с твоим «практическим» примером, загрузить большое, неизвестное число объектов, где по-твоему нужно LinkedList использовать, а оказалось — не нужно. Цитата sergioK @ JVM тут ыообще не причем, он и в STL есть, 1) во-первых, JVM тут при том, что с неё начался разговор. 2) во-вторых: https://www.youtube.com/watch?v=YQs6IC-vgmo Цитата sergioK @ Я ничего не забыл, лишних 24 байта, не надо меня тут учить data structure , Ты прав, тут — не надо. Тебе бы в университет вернуться, знания подтянуть. А потом на работу нормальную устроиться джуном, практического опыта набраться. А то поназагружают миллиарды объектов в LinkedList, а потом в OutOfMemory долбятся, псевдопрактики, блин. Цитата sergioK @ 1) Ты сам реализуешь так как тебе нужно А на практике никак не нужно. Ни при каких обстоятельствах. Цитата sergioK @ 2) Если не подходит для данной задачи не используй Спасибо, капитан. Только он ни для какой задачи не нужен. Цитата sergioK @ в ArrayList insureCapacity private - чистой воды косяк, Чё, серьёзно? https://docs.oracle.com/javase/8/docs/api/j...reCapacity-int- Цитата public void ensureCapacity(int minCapacity) |
Сообщ.
#70
,
|
|
|
Цитата korvin @ Несколько дней споришь, а когда загнали в угол, ты внезапно нашел лазейку: оказывается ты имел ввиду, что нельзя "просто" создать. А "сложно" можно? А 100 строк это "просто" или "сложно"? на второй странице. Ну ладно, главное, что согласился в конце-концов. Цитата korvin @ ЧТД. С полным копированием можно что угодно сделать иммутабельным Цитата korvin @ У тебя что-то с логикой. Никаких о каких ленивых функциях я не говорил. Функция не бывает ленивой, бывает ленивое выполнение функции. И в твоем примере на хаскеле, выполнение функции print как раз таки ленивое, о чем я и говорил. Согласен с претензией, что я неточно выразился говоря о ленивых операциях над элементами списка. Точнее было сказать: ленивое вычисление значений элементов списка, которое, в свою очередь, может быть, а может и не быть операцией над элементами другого списка.Э-э… у тебя раздвоение личности? Я тебя спросил, какая операция там ленивая, ты ответил «print». print — это функция, т.е. ты же и назвал её ленивой Цитата korvin @ Конечно недостаточно. Двусвязные списки по производительности не будут отличаться от односвязных на операциях добавления/удаления в начало списка и итерации, при прочих равных. Потому что двусвязный список, по сути, включает в себя односвязный. Разве что памяти требует больше. Впрочем, XOR-списки никто не отменял.двусвязность и закрытость для тебя не достаточно принципиальные отличия? Порывшись немного в интернетах на тему почему же LinkedList в Java умудряется сливать ArrayList и даже ArrayDeque на операциях добавления миллионов элементов, я прихожу к выводу, что это связано с какой-то наивной реализацией этого списка и особенностями работы JVM. И есть все основания полагать, что односвязный список реализованный также наивно, будут работать точно также плохо. Цитата korvin @ Ну и какой же из вариантов имел в ввиду автор говоря о списках полезных в C? О чем ты вообще тут толкуешь? Автор ни словом ни обмолвился ни о деталях реализации, даже просто оптимизацию не упомянул. Может он вообще не разбирается в этом? Кстати, интересно, в Java (JVM) возможны интрузивные списки? Ну и что там "во-вторых"?Во-первых, односвязный список можно реализовать по-разному: – интрузивный или не интрузивный – закрытый (объект-контейнер с внутренним приватным списком нод и предоставляющий доступ к элементов только описанными методами, инкапсулирующий манипуляции над нодами) или открытый (просто создаются сразу сами объекты нод) Цитата korvin @ По мне так наоборот, чтобы прийти к выводу, что "он именно так и написал" приходится СПГСить.Он именно так и написал, но ты предпочёл поСПГСить. Цитата korvin @ Все случаи (не считая программирования в Elixir) когда лично я задействовал связный список (односвязный или двусвязный, не важно) были связаны с необходимостью удалять ноды из середины списка или с участием ноды одновременно в нескольких структурах данных. То есть я "манипулировал нодами". В общем и целом трудно сказать, слишком много факторов. С одной стороны при переполнении массива, нужно реаллоцировать и копировать все элементы (или указатели на них) в новое место. С другой стороны, когда список "разогрелся", то максимальное количество элементов перестает расти и болтается внутри массива не требуя никаких реаллокаций и копирований.Вопрос: если ты не манипулируешь нодами, переставляя их, то нафига тебе связный список? Используй массив. А если манипулируешь, то вся эта изначальная локальность пойдёт лесом на хоть сколько-нибудь большом списке. Так что, пожалуй соглашусь, если не нужны "манипуляции нодами" внутри списка, то особого смысла в связных списках (опять же неважно одно- или двусвязных) нет. Но допускаю, что грамотно написанный связный список может уделывать список на массиве при массовом добавлении элементов. Без бенча не поймешь, а серьезный бенч с суровыми оптимизациями писать лениво. Цитата korvin @ Я говорил именно о поддержке мутабельности, а не о поддержке императивности. Мутабельность и императивность - ортогональные сущности. F# - императивный язык? А OCaml? А Erlang/Elixir? Тема для отдельного холивара. Зачем я буду придумывать какой-то свой, если такие языки называют императивными? |
Сообщ.
#71
,
|
|
|
Цитата applegame @ ЧТД. Доказать, что можно реализовать любую бесполезную фигню? Ну, молодец, важное доказательство. Цитата applegame @ Впрочем, XOR-списки никто не отменял. Цитата Используется довольно редко, так как существуют хорошие альтернативы, как, например, развёрнутый связный список. Ясно-понятно. Цитата applegame @ что это связано с какой-то наивной реализацией А у двусвязного списка реализация бывает наивной и не наивной? Интересно, какая реализация наивная, а какая — нет? Цитата applegame @ Автор ни словом ни обмолвился ни о деталях реализации Наконец-то до тебя дошло. Может, теперь ты прекратишь что-то додумывать? Цитата applegame @ Кстати, интересно, в Java (JVM) возможны интрузивные списки? Конечно. Пример нужен? Цитата applegame @ По мне так наоборот, чтобы прийти к выводу, что "он именно так и написал" приходится СПГСить. К вывод «он именно так и написал» не нужно приходить, это не вывод, а значение-по-умолчанию, как синие занавески. Бритва Оккама же. Цитата applegame @ Все случаи (не считая программирования в Elixir) когда лично я задействовал связный список (односвязный или двусвязный, не важно) были связаны с необходимостью удалять ноды из середины списка или с участием ноды одновременно в нескольких структурах данных. То есть я "манипулировал нодами". В общем и целом трудно сказать, слишком много факторов. С одной стороны при переполнении массива, нужно реаллоцировать и копировать все элементы (или указатели на них) в новое место. С другой стороны, когда список "разогрелся", то максимальное количество элементов перестает расти и болтается внутри массива не требуя никаких реаллокаций и копирований. Ну вот, а LL прямой доступ к ноде не даёт, только линейный поиск с начала, что в итоге намного дороже, чем реаллокация в AL: https://www.youtube.com/watch?v=Y4XkWSAm2XU Цитата applegame @ Но допускаю, что грамотно написанный связный список может уделывать список на массиве при массовом добавлении элементов. Без бенча не поймешь, а серьезный бенч с суровыми оптимизациями писать лениво. Ну, я могу добавить такую реализацию в свой бенч, а также интрузивный список. Цитата applegame @ Мутабельность и императивность - ортогональные сущности Э, нет. Вся суть императивного программирования в прямом и явном изменении (мутировании) состояния. Это оно и есть, то, что ты хочешь сказать. Цитата applegame @ F# - императивный язык? А OCaml? Это «мультипарадигмальные» языки, поддерживающие ФП, ООП, ИП. В общем-то как и многие современные/популярные ЯП. |
Сообщ.
#72
,
|
|
|
Цитата korvin @ Потому что front - это head. Он возвращает значение первого элемента в списке. back - тоже самое с конца.applegame, не понимаю, почему у тебя front и back возвращают payload, а не next и prev соответственно. Цитата korvin @ У меня была ошибка в коде, вот исправленная версия: https://glot.io/snippets/fxx0z9kiamчерез pop*-методы так не работает. Скрытый текст import std.stdio; struct Int { int value; Int opBinary(string op: "+")(Int other) const { writefln("%s + %s = %s", value, other.value, value + other.value); return Int(value + other.value); } } void main() { const l0 = DList!Int(); const l1 = l0.append( Int(1) + Int(1), ); const l2 = l1.append( Int(2) + Int(2), Int(3) + Int(3), Int(4) + Int(4) ); writeln(l2.popFront().front); } struct DList(T) { struct Node { T delegate() payload; Node* prev, next; } private Node* m_first, m_last; bool empty() const { return m_first == null; } T front() const { assert(!empty); return m_first.payload(); } T back() const { assert(!empty); return m_last.payload(); } const(DList) popFront() const { assert(!empty); return m_first == m_last ? const DList() : const DList(m_first.next, m_last); } const(DList) popBack() const { assert(!empty); return m_first == m_last ? const DList() : const DList(m_first, m_last.prev); } const(DList) append(ARGS...)(lazy ARGS args) const { auto list = dup(); static foreach(arg; args) { if(list.empty) { list.m_first = list.m_last = new Node(&arg); } else { list.m_last.next = new Node(&arg, list.m_last); list.m_last = list.m_last.next; } } return list; } private DList dup() const { auto list = DList(); if(!empty) { auto prev = new Node(m_first.payload); list.m_first = prev; const(Node)* cur = m_first.next; while(cur != null && cur != m_last) { auto node = new Node(cur.payload, prev); prev.next = node; prev = node; cur = cur.next; } list.m_last = prev; } return list; } } Цитата korvin @ Вот так? https://glot.io/snippets/fxx116i54yИ как пройти по такому списку вперёд-назад и наоборот? Скрытый текст import std.stdio; void forward(const DList!int l) { if (l.empty()) return; writeln(l.front); forward(l.popFront()); } void backward(const DList!int l) { if (l.empty()) return; writeln(l.back); backward(l.popBack()); } void forwardBackward(const DList!int l) { forward(l); backward(l.popBack()); } void backwardForward(const DList!int l) { backward(l); forward(l.popFront()); } void main() { const list = DList!int().append(1, 2, 3, 4); writeln("forwardBackward"); forwardBackward(list); writeln("backwardForward"); backwardForward(list); } struct DList(T) { struct Node { T delegate() payload; Node* prev, next; } private Node* m_first, m_last; bool empty() const { return m_first == null; } T front() const { assert(!empty); return m_first.payload(); } T back() const { assert(!empty); return m_last.payload(); } const(DList) popFront() const { assert(!empty); return m_first == m_last ? const DList() : const DList(m_first.next, m_last); } const(DList) popBack() const { assert(!empty); return m_first == m_last ? const DList() : const DList(m_first, m_last.prev); } const(DList) append(ARGS...)(lazy ARGS args) const { auto list = dup(); static foreach(arg; args) { if(list.empty) { list.m_first = list.m_last = new Node(&arg); } else { list.m_last.next = new Node(&arg, list.m_last); list.m_last = list.m_last.next; } } return list; } private DList dup() const { auto list = DList(); if(!empty) { auto prev = new Node(m_first.payload); list.m_first = prev; const(Node)* cur = m_first.next; while(cur != null && cur != m_last) { auto node = new Node(cur.payload, prev); prev.next = node; prev = node; cur = cur.next; } list.m_last = prev; } return list; } } |
Сообщ.
#73
,
|
|
|
Цитата korvin @ А что поделаешь? В холиварах только и делаем, что занимаемся "важными" доказательствами. Доказать, что можно реализовать любую бесполезную фигню? Ну, молодец, важное доказательство. Цитата korvin @ Да, хорошая альтернатива. Я даже полагал, что ArrayDeque как раз и реализован как unrolled list, поэтому и уделывает LinkedList аки тузик грелку даже на массовом добавлении элементов:Используется довольно редко, так как существуют хорошие альтернативы, как, например, развёрнутый связный список. Цитата applegame @ Но реальность оказалась гораздо хуже Но есть серьезное подозрение, что внутри этого ArrayDeque используется, сюрприз-сюрприз, двусвязный список массивов Может даже тот самый LinkedList. Цитата korvin @ Прямая, в лоб, без каких-либо оптимизаций, вроде кеширования нод или списка массивов (unrolled list). То есть тупо аллоцируем ноды по одной с двумя указателями.А у двусвязного списка реализация бывает наивной и не наивной? Интересно, какая реализация наивная, а какая — нет? Цитата korvin @ Короче, эта ветка бессмысленна и неинтересна. Я считаю, что автор сморозил ерунду, ты нет. Предлагаю на этом остановиться.Наконец-то до тебя дошло. Может, теперь ты прекратишь что-то додумывать? Цитата korvin @ Не нужен. Я подозревал, что все объекты в Java (кроме примитивных типов конечно), всегда имеют ссылочную семантику, но, видимо, это не совсем так.Конечно. Пример нужен? Цитата korvin @ Не согласен. Совсем. Тот же Elixir тотально иммутабелен, но содержит изрядную долю императивщины. Я считаю, что фундаментальный признак императивности - последовательное выполнение списка действий. Википедия похоже считает также Императивное программирование. ИП часто сопровождается мутабельностью, но это не является обязательным признаком.Э, нет. Вся суть императивного программирования в прямом и явном изменении (мутировании) состояния. Это оно и есть, то, что ты хочешь сказать. Если уж совсем уйти в абстрактную философию, то можно сказать, что главное отличие ФП от ИП - это течение времени. В ФП - течение времени не является чем-то особенным, просто еще одна координатная ось. А в ИП направление движения времени фундаментально: вот эта команда выполнится ПОСЛЕ вот этой. Мы живем в мире, в котором время постоянно течет в одном направлении. Именно поэтому человеческое мышление императивно, именно поэтому база наших компьютеров императивна, именно поэтому ФП ломает мозг среднестатистическому человеку, и именно поэтому люди придумывают всякие монады, чтобы увязать свои розовые ФП-мечты с реальным императивным миром. |
Сообщ.
#74
,
|
|
|
Цитата applegame @ Я даже полагал, что ArrayDeque как раз и реализован как unrolled list, поэтому и уделывает LinkedList аки тузик грелку даже на массовом добавлении элементов: Ну, он не уделывает прям как тузик, чуть хуже ArrayList'а вроде получается, я уже удалил результаты с ArrayDeque, могу восстановить, но не думаю, что это настолько интересно. Цитата applegame @ Не нужен. Я подозревал, что все объекты в Java (кроме примитивных типов конечно), всегда имеют ссылочную семантику, но, видимо, это не совсем так. Это именно так, просто можно ж написать абстрактный класс и наследоваться от него, поля объекта родительского класса же встраиваются в объект дочернего, а не создаётся полноценный дочерний объект, это была бы композиция. ) Цитата applegame @ Википедия похоже считает также Императивное программирование. Цитата … – данные, полученные при выполнении инструкции, могут записываться в память. … – использование именованных переменных; – использование оператора присваивания; … https://en.wikipedia.org/wiki/Imperative_programming : Цитата In computer science, imperative programming is a programming paradigm that uses statements that change a program's state. Цитата applegame @ Именно поэтому человеческое мышление императивно, именно поэтому база наших компьютеров императивна, именно поэтому ФП ломает мозг среднестатистическому человеку, и именно поэтому люди придумывают всякие монады, чтобы увязать свои розовые ФП-мечты с реальным императивным миром. Чушь, но это уже точно отдельный холивар. Вот, собственно, добавил в бэнчмарк «сырой» открытый двусвязный список: Скрытый текст public final class OpenLinkedList<T> { public static <T> OpenLinkedList<T> node(T data) { return new OpenLinkedList<>(data, null, null); } private T data; private OpenLinkedList<T> prev; private OpenLinkedList<T> next; private OpenLinkedList(T data, OpenLinkedList<T> prev, OpenLinkedList<T> next) { this.data = data; this.prev = prev; this.next = next; } public T data() { return data; } public OpenLinkedList<T> prev() { return prev; } public OpenLinkedList<T> next() { return next; } public void setPrev(OpenLinkedList<T> list) { this.prev = list; } public void setNext(OpenLinkedList<T> list) { this.next = list; } } Тестируемый код: public static Object openLinkedList(int items) { if (items <= 0) { return null; } var list = OpenLinkedList.node(0); for (int i = 1; i < items; i++) { final var node = OpenLinkedList.node(i); list.setNext(node); node.setPrev(list); list = node; } return list; } Результат: Benchmark (itemsToAdd) (type) Mode Cnt Score Error Units CollectionsBenchmark.addMany 1000 LinkedList avgt 15 4.823 ± 0.935 us/op CollectionsBenchmark.addMany 1000 ArrayList avgt 15 3.642 ± 0.095 us/op CollectionsBenchmark.addMany 1000 OpenLinkedList avgt 15 4.012 ± 0.072 us/op CollectionsBenchmark.addMany 100000 LinkedList avgt 15 638.813 ± 409.703 us/op CollectionsBenchmark.addMany 100000 ArrayList avgt 15 350.063 ± 10.558 us/op CollectionsBenchmark.addMany 100000 OpenLinkedList avgt 15 599.069 ± 331.634 us/op CollectionsBenchmark.addMany 10000000 LinkedList avgt 15 61113.971 ± 16824.651 us/op CollectionsBenchmark.addMany 10000000 ArrayList avgt 15 56662.442 ± 2182.296 us/op CollectionsBenchmark.addMany 10000000 OpenLinkedList avgt 15 65001.029 ± 15023.551 us/op Как видно, связный список можно использовать только если ты [MODE=Петросян] разрабатываешь серьёзный банковский софт для Société Générale [/MODE] |
Сообщ.
#75
,
|
|
|
Цитата korvin @ Ну я бы не назвал это односвязными списками. Строго говоря, это вообще не списки. ЕМНИП, каноническое определение списка в computer science включает в себя его конечность. А то, о чем ты говоришь это stream или infinite sequence. Коллекция элементов отсутствует как таковая. Связный список - это просто одна из реализаций списков, а не внешний интерфейс.И вот ещё важный момент: в односвязном ленивом списке суть не в ленивости элементов, а в ленивости построения самого списка (т.е. хвоста), поэтому возможно задать бесконечный список и работать с ним, используя как генератор/inputstream. Цитата korvin @ Это просто реккурентная функция обернутая в интерфейс списка, а не связный список. В D такое пишется, на мой взгляд, понятнее:Каноничный бесконечный ленивый список чисел фибоначчи на Хаскелле задаётся так: fibs = 0 : 1 : zipWith (+) fibs (tail fibs) Напечатать первые 10 чисел: print $ take 10 fibs https://glot.io/snippets/fxx3k64atg auto fibs = recurrence!((a, n) => a[n-1] + a[n-2])(1, 1); writeln(fibs.take(10)); Цитата korvin @ Ну что значит "должен"? Ленивые вычисления - это всего лишь вычисления отложенные на потом. Никакой магии. Я пошел по самому очевидному для меня пути. Соответственно ленивым у тебя должен быть не столько payload, сколько next и prev. |
Сообщ.
#76
,
|
|
|
Вот с интрузивным списком совсем другой разговор:
Benchmark (itemsToAdd) (type) Mode Cnt Score Error Units CollectionsBenchmark.addMany 1000 LinkedList avgt 15 14.542 ± 17.000 us/op CollectionsBenchmark.addMany 1000 ArrayList avgt 15 3.680 ± 0.089 us/op CollectionsBenchmark.addMany 1000 OpenLinkedList avgt 15 4.068 ± 0.175 us/op CollectionsBenchmark.addMany 1000 IntrusiveLinkedList avgt 15 2.561 ± 0.027 us/op CollectionsBenchmark.addMany 100000 LinkedList avgt 15 471.286 ± 13.920 us/op CollectionsBenchmark.addMany 100000 ArrayList avgt 15 362.478 ± 9.120 us/op CollectionsBenchmark.addMany 100000 OpenLinkedList avgt 15 443.950 ± 11.291 us/op CollectionsBenchmark.addMany 100000 IntrusiveLinkedList avgt 15 255.955 ± 3.964 us/op CollectionsBenchmark.addMany 10000000 LinkedList avgt 15 61587.330 ± 22176.828 us/op CollectionsBenchmark.addMany 10000000 ArrayList avgt 15 56342.958 ± 2432.139 us/op CollectionsBenchmark.addMany 10000000 OpenLinkedList avgt 15 73251.613 ± 21086.066 us/op CollectionsBenchmark.addMany 10000000 IntrusiveLinkedList avgt 15 28434.662 ± 2616.126 us/op Добавлено Цитата applegame @ Ну я бы не назвал это односвязными списками. Строго говоря, это вообще не списки. Почему? Обычные односвязные списки, строящиеся по мере итерации по ним. Цитата applegame @ ЕМНИП, каноническое определение списка в computer science включает в себя его конечность. Не думаю, что там есть такое ограничение, но не видел этого определения. Цитата applegame @ Коллекция элементов отсутствует как таковая. Она присутствует, просто строится по мере необходимости, а не сразу. Цитата applegame @ Это просто реккурентная функция обернутая в интерфейс списка, а не связный список. Обычный ленивый связный список )) Цитата applegame @ Ну что значит "должен"? То и значит. Буквально. |
Сообщ.
#77
,
|
|
|
Цитата korvin @ Дык все это есть и в ФП языках. Например Elixir. Можно конечно долго разглагольствовать, что дескать вот это вот на самом деле не присваивание, но выглядит оно именно как присваивание:… – данные, полученные при выполнении инструкции, могут записываться в память. … – использование именованных переменных; – использование оператора присваивания; … a = foo(a) b = foo(b) {a, b} = {b, a} Цитата korvin @ Ну, по мне так это какой-то булшит. Если программа (на любом языке) не меняет свое состояние, то оптимизатор может смело заменить ее на пустую функцию. Собсно продвинутые компиляторы так и делают, херя бенчмарки In computer science, imperative programming is a programming paradigm that uses statements that change a program's state. Хошь покажу имеративную программу без единой мутабельной переменной? Держи : import std.stdio; void main() { foreach(const i; 0..10) writeln(i); } |
Сообщ.
#78
,
|
|
|
Я предлагаю немного усложнить бенчмарк: сделать не только формирование коллекции, но и какое-то её использование.
Например: создавать упорядоченный набор значений (для простоты — числа по возрастанию), т.е. при добавлении каждого нового элемента, добавлять его не в конец, а в такую позицию, чтобы итоговый список/массив оставался упорядоченным. А в конце Для AL: используем бинарный поиск, потом add(index, item), который будет всегда требовать сдвига элементов и в некоторых случаях — реаллокации Для LL: сначала проверяем первый и последний элементы, для быстрой вставки в начало и конец, иначе используем ListIterator для нахождения нужно места и вставки «во внутрь» Для OpenLL: в целом, повторяет LL, но можно, например, отдельно хранить ноду середины, чтобы уменьшить количество проходов. Для IntrusiveLL: повторяем алгоритм OpenLL. Бэнчи запускаем для трёх кейсов: – все генерируемые элементы изначально правильно упорядочены, т.е. вставка всегда идёт в начало — тут, по логике AL должен быть хуже всех. – все генерируемые элементы изначально обратно упорядочены, т.е. вставка всегда идёт в конец. – все элементы генерируются псевдослучайно, будем задавать одинаковый seed для ГСЧ. Как вам такой кейс? Всё ли справедливо? Будет ли интересно? Напишу на Java, кто захочет — напишет на своём любимом языке. Аналогичные коллекции можно взять стандартные или из библиотек, можно написать свои. ) Добавлено Цитата applegame @ Иммутабельная императивщина. Не знаком с Elixir, где тут иммутабельность? Цитата applegame @ не меняет свое состояние, то оптимизатор может смело заменить ее на пустую функцию. Собсно продвинутые компиляторы так и делают, херя бенчмарки Может. В чём тут проблема/противоречие? Цитата applegame @ Хошь покажу имеративную программу без единой мутабельной переменной? Держи И что это должно показать? Что состояние std.stdio не меняется? |
Сообщ.
#79
,
|
|
|
Цитата korvin @ Ну если хочется так называть, окай. Не будем впадать в терминологический спор. Но если исключить бесконечность, то ничего не мешает создать в том же D такой же ленивый BidirectionalRange, который будет лениво генерить, допустим, четные числа в заданном интервале и назвать его "обычным ленивым двусвязным списком". Пример такого ренджа, надеюсь, не надо писать? Обычный ленивый связный список )) Добавлено Цитата korvin @ Везде. Просто в эликсире можно, так сказать, "ребиндить" имена переменных. То есть в одной строке переменная указывает на одни данные, в другой ее можно перебиндить и она будет указывать уже на другие данные. А сами данные строго иммутабельны. В хаскеле и окамле похожее через let можно сделать, ЕМПИН.Не знаком с Elixir, где тут иммутабельность? Цитата korvin @ Не противоречие, а бессмыслица. Изменение состояние программы - это не признак императивного программирования. Это признак программирования вообще, в том числе и ФП. Даже генератор чисел фибоначчи написанный на Хаскеле (самый ФП язык из всех ФП языков) меняет свое состояние по мере вывода чисел на экран. Банальная функция с хвостовой рекурсией тоже меняет свое состояние (привет ген_серверам эрланга).Может. В чём тут проблема/противоречие? Цитата korvin @ Это показывает, что мутабельность/иммутабельность - не обязательный признак императивности. Если изменение stdio считать за признак императивности, то и хаскельный генератор фибоначчи императивен. И что это должно показать? Что состояние std.stdio не меняется? Добавлено Цитата korvin @ Кстати можно же на том же хацкеле кортеж из двух "встречных" списков замутить и сделать соответствующие операции над ним. Получится "обычный ленивый двусвязный список" Обычный ленивый связный список )) |
Сообщ.
#80
,
|
|
|
Цитата applegame @ Просто в эликсире можно, так сказать, "ребиндить" имена переменных. То есть в одной строке переменная указывает на одни данные, в другой ее можно перебиндить и она будет указывать уже на другие данные. А сами данные строго иммутабельны. Т.е. это "другие" a и b? Тогда не понимаю, в чем проблема. Добавлено Цитата applegame @ Изменение состояние программы - это не признак императивного программирования. Это признак программирования вообще, в том числе и ФП. А мне вот кажется, ты ошибаешься Добавлено applegame, ещё ты почему-то смешиваешь языки и парадигмы. То, что в каком-то языке с поддержкой ФП, есть поддержка ИП, не делает фичи ИП фичами ФП. |
Сообщ.
#81
,
|
|
|
applegame, так, пажди, ёмана, это просто создание нового скоупа, тут нет ничего императивного, то что оно записывается линейно, а не вложено — это просто синтаксический сахар, чтобы не было больших лестниц, а по сути это:
let a = 1 in let b = 2 in let (b, a) = (a, b) in .... что в свою очередь тривиально преобразуется в лямбда-выражение. Никакой императивщины тут нет. Вот, например, в Go похожее выражение: var a, b int a = 1 b = 2 a, b = b, a выглядит практически так же, а смысл имеет другой. Вот это императивный код, потому что меняет состояние, а не создаёт новое. Это и есть ключевой момент. |
Сообщ.
#82
,
|
|
|
Цитата D_KEY @ Да нет, тебе показалось. Вот главные вопросы:applegame, ещё ты почему-то смешиваешь языки и парадигмы. То, что в каком-то языке с поддержкой ФП, есть поддержка ИП, не делает фичи ИП фичами ФП. Что является главным отличием ИП от ФП? Является ли иммутабельность/мутабельность этим главным отличием? Ну и как бонус: Может ли ИП существовать без мутабельности? Добавлено Цитата korvin @ Ага, это был прикол. Но таки в моем примере запросто может появиться императивщина. В Elixir/Erlang функции запросто могут быть грязными с сайд эффектами, а в моем коде идет вызов функции foo(), причем два раза и в определенной ПОСЛЕДОВАТЕЛЬНОСТИ.applegame, так, пажди, ёмана, это просто создание нового скоупа, тут нет ничего императивного, то что оно записывается линейно, а не вложено — это просто синтаксический сахар, чтобы не было больших лестниц, а по сути это: Я в целом считаю, что даже в хацкеле как только ты задействовал do-нотацию, считай начал писать императивно. |
Сообщ.
#83
,
|
|
|
Цитата applegame @ Но таки в моем примере запросто может появиться императивщина. В Elixir/Erlang функции запросто могут быть грязными с сайд эффектами, а в моем коде идет вызов функции foo(), причем два раза и в определенной ПОСЛЕДОВАТЕЛЬНОСТИ. Вложенный вызов чистых функций в «чистом» функциональном языке x = foo (bar (gee (qux 42))) — тоже некоторая «последовательность», и что? Функциональный код не перестаёт таковым быть. А наличие побочных эффектов — да, делает код императивным, а побочные эффекты — это изменение состояния. Снова приходим к тому, что это ключевое отличие. Цитата applegame @ Я в целом считаю, что даже в хацкеле как только ты задействовал do-нотацию, считай начал писать императивно. Ну, ты, конечно, можешь считать что угодно, только действительность от этого не меняется. Потому и не рекомендуют новичкам объяснять монады вообще и монаду IO в частности с демонстрации do-нотации, т.к. это создаёт у них такое вот ложное впечатление. |
Сообщ.
#84
,
|
|
|
Цитата korvin @ Это не последовательность, это композиция функций. ФП абстрагируется от порядка выполнения максимально, пока не придется столкнуться с реальным императивным миром и тут-то волшебные замки рушатся. Вот тебе — тоже некоторая «последовательность», и что? другой пример: foo(bar(), baz()) Что выполнится раньше: bar() или baz()? Цитата korvin @ Это ФП или ИП? И есть ли тут мутабельное состояние?Снова приходим к тому, что это ключевое отличие. bool contains(T)(const T[] arr, const T e) pure { foreach(const x; arr) if(x == e) return true; return false; } Цитата korvin @ Ох уж эта высокомерная надменность. Полная уверенность, что именно твое определение "действительность", а оппонент новичок с ложным впечатлением. При этом выпад содержит ноль аргументов. Ну, ты, конечно, можешь считать что угодно, только действительность от этого не меняется. Потому и не рекомендуют новичкам объяснять монады вообще и монаду IO в частности с демонстрации do-нотации, т.к. это создаёт у них такое вот ложное впечатление. |
Сообщ.
#85
,
|
|
|
Цитата applegame @ Что является главным отличием ИП от ФП? Если кратко, то ИП - это подход с последовательным выполнением инструкций, которые модифицируют данные(состояние), теоретическая модель - машина Тьюринга. ФП - это подход с вычислением функций, теоретическая модель - лямбда исчисления Черча. Добавлено Цитата applegame @ Является ли иммутабельность/мутабельность этим главным отличием? Одним из. Главным или нет - не понимаю вопроса. Цитата Может ли ИП существовать без мутабельности? Думаю, что нет Добавлено Цитата applegame @ Вот тебе другой пример: foo(bar(), baz()) Что выполнится раньше: bar() или baz()? В ФП вопрос не имеет смысла, в ИП зависит от языка или даже компилятора. Добавлено Цитата applegame @ Это ФП или ИП? Это функция. Судя по всему, чистая. Значит могла бы быть и в ФП. Правда если всматриваться в тело функции, то можно увидеть инструкции, т.е. формально, наверное, не чистое ФП. Такой подход свойственнен гибридным языкам |
Сообщ.
#86
,
|
|
|
Цитата D_KEY @ А я вот останавливаюсь на последовательном выполнении инструкций. Мутабельное состояние мне представляется необязательным.ИП - это подход с последовательным выполнением инструкций, которые модифицируют данные(состояние), теоретическая модель - машина Тьюринга. Цитата D_KEY @ Именно. В ФП вопрос не имеет смысла Цитата D_KEY @ Ну а мутабельное состояние-то есть? Это функция. Судя по всему, чистая. Значит могла бы быть и в ФП. Правда если всматриваться в тело функции, то можно увидеть инструкции, т.е. формально, наверное, не чистое ФП. Такой подход свойственнен гибридным языкам |
Сообщ.
#87
,
|
|
|
Цитата sergioK @ Это потому что в лицензии так написано. А не приняв оферту лицензии, не имеешь права использовать (потенциально багованное) ПО. Ты всерьёз думаешь, что лицензия поможет программисту – хотя скорее исцом будет компания, в которой программист работает, но не суть, внутренние корпоративные разборки тоже бывают по-разному оканчиваются – уйти от уголовной ответственности, если дело примет такой оборот? Сочувствую, но ты плохо себе представляешь, как работает закон и каким образом лицензии с ним взаимодействуют....программист сделавший глупость юридически никак за это не отвечает Цитата sergioK @ Это потому что никто в суды не подавал. А если и подавал, то всё обычно решалось в досудебном порядке, чтоб никто ничего никому внешне не попортил, ни в репутации, ни на физиономии. Нынче другие времена, и суды вполне себе, бывает, выигрываются. И – да, мы о бизнесе. В области высококритичного ПО понятия лицензий просто нет. Там никто не будет просить прочитать и согласиться. Там всё куда проще: спасибо за деньги, вот вам копия, циркулярный №XXX-YYY, документация во вложении; и там чёрным по-человеческому все-все-все планы, методики, правила, мануалы итд итп — всё, что касается эксплуатации такого ПО и в рамках чего поставщик отвечает за качество.Вот и придумали шутку про дроздов, а в каждой шутке доля правды, as smaller as better Когда-то, не спорю, программы были маленькими и простыми. Потому что компьютеры обладали малыми ресурсами, а у программистов были в использовании простые инструменты. Увы, приходилось многое перекладывать на плечи юзеров. Нынче ситуация далеко не та, время дроздов в контексте той поговорки ушло где-то уже на рубеже веков, а с тех пор ещё 20 лет прошло. Цитата sergioK @ Авионика. По должности да, более подходящих в ЕТКС нет. По сфере деятельности нет. Самое короткое описание – "технический специалист". И список длиною в пол-листа в должностной инструкции. Хотя программированием занимаюсь, но не высококритичного кода как такового, а различного инструментария для его верификации и сертификации. Включая проектирование, создание и саппорт испытательных стендов с исходным аппаратным и исполнительным окружением flight-кода under inspection, тестового окружения на базе ПК и различных инструментов статистического анализа, генерации итоговой документации, управления артефактами, автоматизации процессов итп. В вашей это в какой ? ты же програмист или нет ? Добавлено Цитата sergioK @ Можно. Но не хочется, хочется кофе и спать.И какая связь ? после второй прививки нельзя работать? Цитата sergioK @ В какой-то мере да. Видосик не смотрел? Посмотри, меня тоже улыбало. Таганрог это столица IT ? Или это была ирония ? |
Сообщ.
#88
,
|
|
|
Цитата applegame @ Вот тебе другой пример: foo(bar(), baz()) Что выполнится раньше: bar() или baz()? Странный вопрос. Для чистого ФП разницы нет (разве что одна из функций bar, baz значительно дольше вычисляется, чем другая). Для императивного зависит от порядка вычисления аргументов функции и стратегии вычисления (call-by-value vs call-by-name). Цитата applegame @ Это ФП или ИП? И есть ли тут мутабельное состояние? bool contains(T)(const T[] arr, const T e) pure { foreach(const x; arr) if(x == e) return true; return false; } Это может быть как ФП, так и ИП, внезапно. Вот тебе другой пример: public static void main(String[] args) { System.out.println(foo(1)); } private static int foo(int i) { return bar(gee(++i)); } private static int bar(int x) { return ++x+1; } private static int gee(int x) { return ++x*2; } — это композиция функций? ФП, значит? Цитата applegame @ Ох уж эта высокомерная надменность. Никакой надменности, простая констатация фактов. Цитата applegame @ Полная уверенность, что именно твое определение "действительность", а оппонент новичок с ложным впечатлением. Это общепринятое определение. ---------------------------------------------------------------- Сделал немного бенчей, за отсутствие багов не ручаюсь, возможно как-нибудь позже проведу тестирование. Процесс такой: составление упорядоченного набора чисел, потом фильтрация по (x < max/2), потом суммирование. Вариантов распределения входных значений 5: – по возрастанию – по убыванию – по возрастанию до середины, потом по убыванию (например: 1 2 3 4 5 4 3 2 1) – по убыванию до середины, потом по возрастанию (например: 5 4 3 2 1 2 3 4 5) – псевдослучайное ожидаемо ArrayList слил во всех кейсах, кроме первого (добавление в конец): Benchmark (itemMapperType) (itemsToAdd) (type) Mode Cnt Score Error Units CollectionsBenchmark2.addMany ascending 100000 LinkedList avgt 10 1998.600 ± 825.551 us/op CollectionsBenchmark2.addMany ascending 100000 ArrayList avgt 10 1158.352 ± 630.132 us/op CollectionsBenchmark2.addMany descending 100000 LinkedList avgt 10 1984.810 ± 819.924 us/op CollectionsBenchmark2.addMany descending 100000 ArrayList avgt 10 380804.497 ± 4571.318 us/op CollectionsBenchmark2.addMany asc->desc 100000 LinkedList avgt 10 2121.230 ± 736.523 us/op CollectionsBenchmark2.addMany asc->desc 100000 ArrayList avgt 10 191833.039 ± 3449.825 us/op CollectionsBenchmark2.addMany desc->asc 100000 LinkedList avgt 10 1876.418 ± 727.067 us/op CollectionsBenchmark2.addMany desc->asc 100000 ArrayList avgt 10 168997.600 ± 4365.277 us/op CollectionsBenchmark2.addMany random 100000 LinkedList avgt 10 3463.063 ± 908.374 us/op CollectionsBenchmark2.addMany random 100000 ArrayList avgt 10 195038.198 ± 3059.551 us/op Однако, если поменять алгоритм наполнения ArrayList на добавление всегда в конец с сортировкой в финале, то сливает уже LinkedList, кроме последнего метода: Benchmark (itemMapperType) (itemsToAdd) (type) Mode Cnt Score Error Units CollectionsBenchmark2.addMany ascending 100000 LinkedList avgt 10 1998.600 ± 825.551 us/op CollectionsBenchmark2.addMany ascending 100000 ArrayList.Sort avgt 10 1167.463 ± 521.571 us/op CollectionsBenchmark2.addMany descending 100000 LinkedList avgt 10 1984.810 ± 819.924 us/op CollectionsBenchmark2.addMany descending 100000 ArrayList.Sort avgt 10 1348.757 ± 585.568 us/op CollectionsBenchmark2.addMany asc->desc 100000 LinkedList avgt 10 2121.230 ± 736.523 us/op CollectionsBenchmark2.addMany asc->desc 100000 ArrayList.Sort avgt 10 1791.563 ± 622.418 us/op CollectionsBenchmark2.addMany desc->asc 100000 LinkedList avgt 10 1876.418 ± 727.067 us/op CollectionsBenchmark2.addMany desc->asc 100000 ArrayList.Sort avgt 10 1348.264 ± 629.691 us/op CollectionsBenchmark2.addMany random 100000 LinkedList avgt 10 3463.063 ± 908.374 us/op CollectionsBenchmark2.addMany random 100000 ArrayList.Sort avgt 10 19608.787 ± 316.377 us/op Почему AL сливается именно на случайных элементах, мне не очень понятно, с ходу не вижу логического объяснения. Возможно, какие-то баги в коде. И как бонус, сравнение LL с OpenLL, IntrusiveLL и TreeMap (SortedMap): Benchmark (itemMapperType) (itemsToAdd) (type) Mode Cnt Score Error Units CollectionsBenchmark2.addMany ascending 100000 LinkedList avgt 10 1998.600 ± 825.551 us/op CollectionsBenchmark2.addMany ascending 100000 OpenLinkedList avgt 10 1590.634 ± 771.149 us/op CollectionsBenchmark2.addMany ascending 100000 TreeMap avgt 10 16178.317 ± 352.460 us/op CollectionsBenchmark2.addMany ascending 100000 IntrusiveLinkedList avgt 10 958.116 ± 459.509 us/op CollectionsBenchmark2.addMany descending 100000 LinkedList avgt 10 1984.810 ± 819.924 us/op CollectionsBenchmark2.addMany descending 100000 OpenLinkedList avgt 10 1560.737 ± 783.328 us/op CollectionsBenchmark2.addMany descending 100000 TreeMap avgt 10 15963.631 ± 658.773 us/op CollectionsBenchmark2.addMany descending 100000 IntrusiveLinkedList avgt 10 940.864 ± 433.400 us/op CollectionsBenchmark2.addMany asc->desc 100000 LinkedList avgt 10 2121.230 ± 736.523 us/op CollectionsBenchmark2.addMany asc->desc 100000 OpenLinkedList avgt 10 1584.023 ± 841.150 us/op CollectionsBenchmark2.addMany asc->desc 100000 TreeMap avgt 10 11919.388 ± 287.896 us/op CollectionsBenchmark2.addMany asc->desc 100000 IntrusiveLinkedList avgt 10 947.756 ± 473.614 us/op CollectionsBenchmark2.addMany desc->asc 100000 LinkedList avgt 10 1876.418 ± 727.067 us/op CollectionsBenchmark2.addMany desc->asc 100000 OpenLinkedList avgt 10 1503.495 ± 891.668 us/op CollectionsBenchmark2.addMany desc->asc 100000 TreeMap avgt 10 8444.099 ± 744.990 us/op CollectionsBenchmark2.addMany desc->asc 100000 IntrusiveLinkedList avgt 10 917.276 ± 511.321 us/op CollectionsBenchmark2.addMany random 100000 LinkedList avgt 10 3463.063 ± 908.374 us/op CollectionsBenchmark2.addMany random 100000 OpenLinkedList avgt 10 1700.960 ± 795.577 us/op CollectionsBenchmark2.addMany random 100000 TreeMap avgt 10 33226.797 ± 1511.600 us/op CollectionsBenchmark2.addMany random 100000 IntrusiveLinkedList avgt 10 1301.572 ± 462.545 us/op Видно, что 1) LL сливает двум «кустарным» спискам. 2) TreeMap сливает всем, что может выглядеть немного неожиданно, ведь для задачи «собрать упорядоченную коллекцию» она выглядит весьма подходящей структурой. segioK, я, конечно, не специалист по бенчмаркам и всё такое, но если ты всё ещё считаешь, что java.util.LinkedList для чего-то будет лучшим выбором, предлагай кейс, а иначе прекрати нести чушь. |
Сообщ.
#89
,
|
|
|
Цитата applegame @ А я вот останавливаюсь на последовательном выполнении инструкций. А почему? И какой толк от последовательности инструкций, если мы убираем изменение состояния? Цитата Ну а мутабельное состояние-то есть? Насколько я вижу, нет. Но это просто функция. Программу-то полноценную если ты начнешь писать без мутабельности, то не скатишься ли ты к функциональному стилю, по сути? |
Сообщ.
#90
,
|
|
|
Цитата D_KEY @ А почему? И какой толк от последовательности инструкций, если мы убираем изменение состояния? Присоединяюсь к вопросу. applegame, чем это: bool contains(T)(const T[] arr, const T e) pure { foreach(const x; arr) if(x == e) return true; return false; } отличается от contains [] e = False contains (x:xs) e = x == e || contains xs e ? |
Сообщ.
#91
,
|
|
|
Цитата korvin @ Какие теории, болезный? Я тебе вон бенчмарк скинул с твоим «практическим» примером, загрузить большое, неизвестное число объектов, где по-твоему нужно LinkedList использовать, а оказалось — не нужно. Да плевал я на твой бенчмарк, и таких же выкскпертов из интернета, теоретики млин, все это 20лет назад известно, insert и delete будет 0(1) у массива не будет, queue когда в минуту приходит 15-20 тыс обьетов, массивом не сделаешь. |
Сообщ.
#92
,
|
|
|
Цитата sergioK @ Да плевал я на твой бенчмарк, и таких же выкскпертов из интернета, теоретики млин, Бьорн Страуструп — «выксперт из интернета, теоретик»? Хаха Цитата sergioK @ queue когда в минуту приходит 15-20 тыс обьетов, массивом не сделаешь. Чё, серьёзно? )) Да ты хуже джуна. Нормальный джун хотя бы понимает, что он джун. |
Сообщ.
#93
,
|
|
|
Цитата korvin @ Чё, серьёзно? Посмотри что она делает, и сравни с вектором Добавлено Цитата Qraizer @ Ты всерьёз думаешь, что лицензия поможет программисту – хотя скорее исцом будет компания, в которой программист работает, но не суть, внутренние корпоративные разборки тоже бывают по-разному оканчиваются – уйти от уголовной ответственности, если дело примет такой оборот? Сочувствую, но ты плохо себе представляешь, как работает закон и каким образом лицензии с ним взаимодействуют. Когда в постоенном доме падает балкон, созывают комисиию и инженера за прококол могут посадить ибо он подписал что все надежно, а сам прозевал, когда из-за сбоя программы столкнулись два поезда никаких комисий никто не создавал, Если програмисты будут сдавать тесты на получение лицензии, то дерьмо кода будет куда меньше, и пока какой нидь шлемзал сможет написать hello word и считать себя програмистом, ситуация не улучшиться. Что за ролик то про столицу IT ? |
Сообщ.
#94
,
|
|
|
sergioK, кто тебя вообще на работу взял? Джуны, видимо
Benchmark (itemsToAdd) (type) Mode Cnt Score Error Units Queues.addMany 1000000 LinkedList avgt 15 10204.559 ± 1692.646 us/op Queues.addMany 1000000 ArrayQueue avgt 15 5026.365 ± 609.288 us/op LinkedList в два раза менее производительный, чем ArrayDeque в качестве очереди. Ты не «практик», ты — практикант. Максимум. Добавлено Цитата sergioK @ и сравни с вектором Нахер с этим говном сравнивать? Его никакой адекватный человек использовать не станет. |
Сообщ.
#95
,
|
|
|
Цитата korvin @ LinkedList в два раза менее производительный, чем ArrayDeque в качестве очереди. Ты не «практик», ты — практикант. Максимум. Ты не хами для начала, Это если не надо память реалацировать, и машина мощная , и частота входа/выхода данные большая, Добавлено Цитата korvin @ А LinkedList умножает память на 3. на размер обьекта + 24байта изучай |
Сообщ.
#96
,
|
|
|
Цитата korvin @ Внутри функции махровое ИП: цикл + ранний return. И никакого мутабельного состояния. Вывод: ИП без мутабельности возможно и полезно.Это может быть как ФП, так и ИП, внезапно. Цитата korvin @ Если забить на грязность main, то да: вполне себе ФП.— это композиция функций? ФП, значит? Цитата korvin @ Ага, настолько же общепринятое как определение ООП с тремя китами. По мне так это определение императивности безнадежно устарело. Иммутабельность уже давно успешно живет в языках с поддержкой императивности. В некоторых иммутабельность вообще сделана по умолчанию.Это общепринятое определение. Цитата D_KEY @ Такой же как и в ФП: получение результата.А почему? И какой толк от последовательности инструкций, если мы убираем изменение состояния? Цитата D_KEY @ И что? Программа на C/С++/D это тоже просто функция. Она даже может быть чистой, просто возвращая int в качестве результата.Но это просто функция. Цитата D_KEY @ Я обычно пишу в гибридном стиле и избегаю ненужной мутабельности. В моих программах часто встречаются императивные куски без мутабельности. Elixir вообще не поддерживает мутабельность, но в нем полно императивщины.Программу-то полноценную если ты начнешь писать без мутабельности, то не скатишься ли ты к функциональному стилю, по сути? Цитата korvin @ Тем, что в первом случае явно прописана последовательность действий. Очередной элемент будет проверен после предыдущего, и как только элемент будет найден последующие элементы не будут проверяться.applegame, чем это: bool contains(T)(const T[] arr, const T e) pure { foreach(const x; arr) if(x == e) return true; return false; } отличается от contains [] e = False contains (x:xs) e = x == e || contains xs e ? А в хаскельном примере никакой последовательности действий нет. Сравнение может проводиться как угодно, хоть по отдельному потоку на каждый элемент. Порядок действий никак не прописан в этом примере и не имеет никакого значения. В этом главное и единственное отличие. В ФП порядок действий как таковой отсутствует. Это хорошо иллюстрирует Excel: на листе у нас есть какие-то ячейки и формулы вычисляющие значения одних ячеек в зависимости от других. Порядок выполнения этих функций нам вообще не важен. Важно, что на входе есть данные и на выходе есть результат. Можно попытаться представить себе что функции выполняются за нулевое время, то бишь течение времени отсутствует как явление. Получится идеальный мир ФП. |
Сообщ.
#97
,
|
|
|
Цитата korvin @ При всем уважении, Страуструп придумал такое говно как С++. А в комитете выступает как тормоз прогресса, блокируя современные тенденции ЯП. Так что я бы на твоем месте перестал аппелировать к авторитетам, и к Страуструпу в частности. По крайней мере в области программирования, где утверждения можно относительно легко проверить и доказать.Бьорн Страуструп — «выксперт из интернета, теоретик»? Хаха Это, конечно, никак не отменяет того, что Сирожа несет ересь и отрицает очевидное. |
Сообщ.
#98
,
|
|
|
Цитата applegame @ Такой же как и в ФП: получение результата. Так смысл-то какой в таком определении ИП? Цитата Программа на C/С++/D это тоже просто функция. Она даже может быть чистой, просто возвращая int в качестве результата. И что? Ты опять пытаешь языки и парадигмы? Цитата Я обычно пишу в гибридном стиле и избегаю ненужной мутабельности Ну это ты молодец. Но это ничего не говорит о верности твоей демаркации. Цитата В моих программах часто встречаются императивные куски без мутабельности. Вообще строго говоря это бесполезно. Если твои инструкции не меняют память и не имеют побочных эффектов, то каким образом происходят вычисления и передаются результаты? Добавлено Цитата applegame @ Тем, что в первом случае явно прописана последовательность действий. Очередной элемент будет проверен после предыдущего, и как только элемент будет найден последующие элементы не будут проверяться. Проблема в том, что это не имеет значения для данного кода. И если ты считаешь это последовательностью инструкций, а не абстрагируешься от этого, тогда тебе придется считать, что return занимается модификацией памяти для результата своего выполнения, например. В общем, мне кажется, что ты путаешь языки и парадигмы, подходы и реализации. |
Сообщ.
#99
,
|
|
|
Цитата D_KEY @ Это не определение ИП, это ответ на твой бесмыссленный вопрос о смысле. Так смысл-то какой в таком определении ИП? Цитата D_KEY @ Что "и что?"? Это ответ на "это просто функция". Как то, что "это просто функция" опровергает сказаное мной? Вся программа может быть просто функцией, что дальше-то? Может ты уже перестанешь вешать ярлыки, а приступишь непосредственно к аргументации? И что? Ты опять пытаешь языки и парадигмы? Цитата D_KEY @ Это был не аргумент в пользу демаркации, это было опровержение. Ты сделал предположение, что я скачусь к ФП если буду писать без мутабельности. Я опровергаю твое предположение примером выше и своей собственной практикой.Ну это ты молодец. Но это ничего не говорит о верности твоей демаркации. Цитата D_KEY @ ФП тоже получается, по-твоему, бесполезно? Ты явно путаешь инструкции с исполнителем этих инструкций.Вообще строго говоря это бесполезно. Если твои инструкции не меняют память и не имеют побочных эффектов, то каким образом происходят вычисления и передаются результаты? Цитата D_KEY @ Это имеет значение для парадигмы. И после этого ты меня обвиняешь в путании. Может ты считаешь что мой пример на D и корвиновский на Haskell написаны в одной и той же парадигме (ФП или ИП)?Проблема в том, что это не имеет значения для данного кода. Цитата D_KEY @ Что ты хочешь этим сказать? Что мой пример не императивен? Или может он бесполезен? Или может он имеет мутабельный стейт? Ты вроде на все три вопроса отвечаешь отрицательно, но продолжаешь с чем-то спорить. Давай уже аргументы, а не просто мутную демагогию.И если ты считаешь это последовательностью инструкций, а не абстрагируешься от этого, тогда тебе придется считать, что return занимается модификацией памяти для результата своего выполнения, например. Цитата D_KEY @ Тебе явно кажется. Все строго наоборот, ты пытаешься смешать парадигмы, программы и исполнителей этих программ. Я же как раз таки пытаюсь абстрагироваться от всего, кроме непосредственно парадигмы. В общем, мне кажется, что ты путаешь языки и парадигмы, подходы и реализации. |
Сообщ.
#100
,
|
|
|
Цитата applegame @ И на этом говне работает всё ныне используемое. Не исключая Эликсиров, ДжаваМашин, ВебКитов, Андроидов и даже, о ужас, инди и триплА игр. При всем уважении, Страуструп придумал такое говно как С++. Добавлено Цитата applegame @ Кстати, а какие? Мне известны лишь обратные примеры. А в комитете выступает как тормоз прогресса, блокируя современные тенденции ЯП. |
Сообщ.
#101
,
|
|
|
Цитата Qraizer @ И на этом говне работает всё ныне используемое. Просто оно перешло стадию компоста и приближается к стадии чернозёма |
Сообщ.
#102
,
|
|
|
Цитата Qraizer @ Возможно ошибаюсь, но вроде именно он зарубил нормальный static if. Кстати, а какие? Мне известны лишь обратные примеры. |
Сообщ.
#103
,
|
|
|
Цитата applegame @ Цитата D_KEY @ Это не определение ИП, это ответ на твой бесмыссленный вопрос о смысле. Так смысл-то какой в таком определении ИП? Так я к тому, что не ответ Цитата а приступишь непосредственно к аргументации? Аргументации чего? Ты выкинул из конвенционально принятого определения ИП половину, а аргументы какие-то должен приводить я? Определения любые можно давать. Вопрос лишь в их пользе. Цитата ФП тоже получается, по-твоему, бесполезно? В ФП используется модель вычисления функций, в ИП - выполнение инструкций, читающих/модифицирующих память. Если инструкции этого не делают, то они бесполезны. Цитата Цитата D_KEY @ Это имеет значение для парадигмыПроблема в том, что это не имеет значения для данного кода. Так в том и дело, что по коду твоему парадигму строго определить нельзя. В общепринятой терминологии. Цитата Может ты считаешь что мой пример на D и корвиновский на Haskell написаны в одной и той же парадигме (ФП или ИП)? Мне кажется, что их можно так интерпретировать. Цитата Что мой пример не императивен? Смотри, это зависит от определения императивности. Ты же пытаешься наоборот , из примера вывести определение. Или я тебя не понимаю. Цитата ты пытаешься смешать парадигмы, программы и исполнителей этих программ Не думаю, что это так. Цитата Я же как раз таки пытаюсь абстрагироваться от всего, кроме непосредственно парадигмы. По-моему ты просто дал своё определение ИП. А я не могу понять для чего Добавлено Цитата applegame @ Цитата D_KEY @ Это имеет значение для парадигмы.Проблема в том, что это не имеет значения для данного кода. Для парадигмы имеет. Поэтому если там будет зависимость от порядка (выполнения, а не вычисления), то это будет ИП. |
Сообщ.
#104
,
|
|
|
Цитата sergioK @ Ты не хами для начала Где ты хамство увидел? Может, вот тут: Цитата sergioK @ хватит тут теории разводить,с умным видом ? или тут: Цитата sergioK @ 1) Ты сам реализуешь так как тебе нужно, теоретик млин ? Цитата sergioK @ Это если не надо память реалацировать В бэнчмарке ArrayDeque инициализируется дефолтным capacity и память реалоцируется. Цитата sergioK @ и машина мощная , Мощная --- это какая? Цитата sergioK @ на размер обьекта + 24байта изучай Что там изучать? Так ты миллиард объектов уже загрузил в LinkedList? Цитата applegame @ Так что я бы на твоем месте перестал аппелировать к авторитетам, и к Страуструпу в частности. Никакой аппеляции к аргументам. Сразу видно, кто посмотрел видео, послушал, а кто --- только прочитал заголовок и имя докладчика. Цитата applegame @ Если забить на грязность main, то да: вполне себе ФП. А если б у бабушки... Цитата applegame @ Иммутабельность уже давно успешно живет в языках с поддержкой императивности. В некоторых иммутабельность вообще сделана по умолчанию. Так как бы языки перестают быть "монопарадигмальными". А популярные языки никогда такими и не были. Иммутабельность была в Си, Паскале и практически любом другом языке с самого начала, не понимаю, что эта твоя фраза должна означать. Цитата applegame @ Тем, что в первом случае явно прописана последовательность действий. Очередной элемент будет проверен после предыдущего, и как только элемент будет найден последующие элементы не будут проверяться. А в хаскельном примере никакой последовательности действий нет. Есть и она точно такая же: очередной элемент будет проверен после предыдущего. Цитата applegame @ Порядок действий никак не прописан в этом примере и не имеет никакого значения. Прописан, через ||, и имеет значение. Ровно такое же, причём. Цитата applegame @ В ФП порядок действий как таковой отсутствует. Присутствует: нельзя вычислить значение функции, не вычислив её аргумента. Добавлено Цитата applegame @ Так что я бы на твоем месте перестал аппелировать к авторитетам, и к Страуструпу в частности. Кроме того, дело же не в авторитетах, про Бьорна известно, что он сделал, можно найти его публикации, выступления, да даже, наверное, код на гихабе и оценить уровень его компетентности (это, конечно, не значит, что он не может ошибаться, но всё же). Про sergioK известно лишь то, что он часто несёт чушь, не умеет читать документацию, не может самостоятельно разобраться с REST, Hibernate и IDEA, высказывает утверждения уровня студента начальных курсов университета, но при этом мнит себя крутым специалистом. Даже рандомный чел на ютубе, без какой-либо авторитетности, вызывает больше доверия к своим словам наличием хоть какого-то им подтверждения. |
Сообщ.
#105
,
|
|
|
Цитата sergioK @ изучай Ты лучше вот это поизучай: Benchmark (itemMapperType) (itemsToAdd) (type) Mode Cnt Score Error Units CollectionsBenchmark2.addMany ascending 100000 LinkedList avgt 30 2220.032 ± 406.027 us/op CollectionsBenchmark2.addMany ascending 100000 ArrayList.Sort avgt 30 1376.964 ± 263.260 us/op CollectionsBenchmark2.addMany ascending 100000 IntrusiveLinkedList avgt 30 903.436 ± 189.932 us/op CollectionsBenchmark2.addMany ascending 100000 IntArrayList avgt 30 410.626 ± 101.004 us/op CollectionsBenchmark2.addMany descending 100000 LinkedList avgt 30 1969.813 ± 341.063 us/op CollectionsBenchmark2.addMany descending 100000 ArrayList.Sort avgt 30 1323.195 ± 235.250 us/op CollectionsBenchmark2.addMany descending 100000 IntrusiveLinkedList avgt 30 858.479 ± 178.213 us/op CollectionsBenchmark2.addMany descending 100000 IntArrayList avgt 30 557.475 ± 110.512 us/op CollectionsBenchmark2.addMany asc->desc 100000 LinkedList avgt 30 2206.215 ± 343.007 us/op CollectionsBenchmark2.addMany asc->desc 100000 ArrayList.Sort avgt 30 1747.033 ± 267.812 us/op CollectionsBenchmark2.addMany asc->desc 100000 IntrusiveLinkedList avgt 30 850.826 ± 189.609 us/op CollectionsBenchmark2.addMany asc->desc 100000 IntArrayList avgt 30 776.621 ± 159.228 us/op CollectionsBenchmark2.addMany desc->asc 100000 LinkedList avgt 30 1929.114 ± 346.647 us/op CollectionsBenchmark2.addMany desc->asc 100000 ArrayList.Sort avgt 30 1311.586 ± 286.175 us/op CollectionsBenchmark2.addMany desc->asc 100000 IntrusiveLinkedList avgt 30 712.091 ± 151.001 us/op CollectionsBenchmark2.addMany desc->asc 100000 IntArrayList avgt 30 590.441 ± 125.438 us/op IntArrayList — com.carrotsearch.hppc.IntArrayList — в четыре раза лучше LinkedList'а. |
Сообщ.
#106
,
|
|
|
Цитата sergioK @ хватит тут теории разводить,с умным видом, JVM тут ыообще не причем, он и в STL есть, И вот это поизучай: ❯❯❯ g++ -O2 -std=c++17 -o lists main.cpp ❯❯❯ time ./lists 100000000 stdlist Result: 3749999975000000 ./lists 100000000 stdlist 14.97s user 0.91s system 99% cpu 15.892 total ❯❯❯ time ./lists 100000000 stdvector Result: 3749999975000000 ./lists 100000000 stdvector 0.61s user 0.42s system 99% cpu 1.040 total src #include <iostream> #include <list> #include <string> #include <vector> void usage(std::string, std::string); int64_t std_list(int64_t); int64_t std_vector(int64_t); int main(int argc, char** argv) { if (argc != 3) { usage(std::string(argv[0]), "invalid arguments"); return 1; } const int64_t n = std::stoi(std::string(argv[1])); if (n < 1) { usage(std::string(argv[0]), "invalid nitems"); return 2; } std::string type(argv[2]); int64_t result; if (type == "stdlist") { result = std_list(n); } else if (type == "stdvector") { result = std_vector(n); } else { usage(std::string(argv[0]), "unsupported type"); return 3; } std::cout << "Result: " << result << std::endl; } void usage(std::string app, std::string err) { std::cerr << err << std::endl; std::cerr << "Usage: " << app << " <nitems> <type>" << std::endl; std::cerr << "nitems: positive integer" << std::endl; std::cerr << "type:" << std::endl; std::cerr << "\tstdlist" << std::endl; std::cerr << "\tstdvector" << std::endl; } int64_t std_list(int64_t n) { std::list<int64_t> xs; for (auto i = 0; i < n; ++i) { xs.push_back(i); } xs.remove_if([n](int x) { return x < n/2; }); int64_t sum = 0; for (auto x : xs) { sum += x; } return sum; } int64_t std_vector(int64_t n) { std::vector<int64_t> xs; for (auto i = 0; i < n; ++i) { xs.push_back(i); } auto filter = std::remove_if(xs.begin(), xs.end(), [n](int x) { return x < n/2; }); xs.erase(filter, xs.end()); int64_t sum = 0; for (auto x : xs) { sum += x; } return sum; } Так что там с загрузкой неизвестного большого количества данных в linked list? |
Сообщ.
#107
,
|
|
|
Цитата korvin @ Цитата sergioK @ хватит тут теории разводить,с умным видом, JVM тут ыообще не причем, он и в STL есть, И вот это поизучай: ❯❯❯ g++ -O2 -std=c++17 -o lists main.cpp ❯❯❯ time ./lists 100000000 stdlist Result: 3749999975000000 ./lists 100000000 stdlist 14.97s user 0.91s system 99% cpu 15.892 total ❯❯❯ time ./lists 100000000 stdvector Result: 3749999975000000 ./lists 100000000 stdvector 0.61s user 0.42s system 99% cpu 1.040 total src #include <iostream> #include <list> #include <string> #include <vector> void usage(std::string, std::string); int64_t std_list(int64_t); int64_t std_vector(int64_t); int main(int argc, char** argv) { if (argc != 3) { usage(std::string(argv[0]), "invalid arguments"); return 1; } const int64_t n = std::stoi(std::string(argv[1])); if (n < 1) { usage(std::string(argv[0]), "invalid nitems"); return 2; } std::string type(argv[2]); int64_t result; if (type == "stdlist") { result = std_list(n); } else if (type == "stdvector") { result = std_vector(n); } else { usage(std::string(argv[0]), "unsupported type"); return 3; } std::cout << "Result: " << result << std::endl; } void usage(std::string app, std::string err) { std::cerr << err << std::endl; std::cerr << "Usage: " << app << " <nitems> <type>" << std::endl; std::cerr << "nitems: positive integer" << std::endl; std::cerr << "type:" << std::endl; std::cerr << "\tstdlist" << std::endl; std::cerr << "\tstdvector" << std::endl; } int64_t std_list(int64_t n) { std::list<int64_t> xs; for (auto i = 0; i < n; ++i) { xs.push_back(i); } xs.remove_if([n](int x) { return x < n/2; }); int64_t sum = 0; for (auto x : xs) { sum += x; } return sum; } int64_t std_vector(int64_t n) { std::vector<int64_t> xs; for (auto i = 0; i < n; ++i) { xs.push_back(i); } auto filter = std::remove_if(xs.begin(), xs.end(), [n](int x) { return x < n/2; }); xs.erase(filter, xs.end()); int64_t sum = 0; for (auto x : xs) { sum += x; } return sum; } Так что там с загрузкой неизвестного большого количества данных в linked list? Ты применяешь std_list не по месту, https://www.geeksforgeeks.org/advantages-an...of-linked-list/ больше я бесплатно обьяснять не буду , |
Сообщ.
#108
,
|
|
|
Цитата sergioK @ Ты применяешь std_list не по месту Цитата sergioK @ А LinkedList нужен когда ды ты считываешь данные неопередельной длины, особенно большие обьемы, а свои джуновские статейки лучше забудь. |
Сообщ.
#109
,
|
|
|
Цитата D_KEY @ Ну какой был вопрос такой и ответ. Я не знаю чего ты ожидал.Так я к тому, что не ответ Цитата D_KEY @ Скажем так. Спор сводится фактически к одному моему утверждению: Можно ли писать императивно не используя мутабельных переменных?.Аргументации чего? Ты выкинул из конвенционально принятого определения ИП половину, а аргументы какие-то должен приводить я? Причем не синтетические примеры, а реальный полезный код. Можно, конечно скатываться в терминологическую демагогию, как это делаешь ты: ну типа раз в определении ИП написано "мутабельный", значит ответ очевиден: низзя. А на остальное насрать. В таком случае можешь просто не участвовать в данном споре, потому что мне интересна оправданность необходимости мутабельности в ИП. Действительно ли иммутабельность кардинально меняет парадигму и код, внезапно, превращается в функциональный? Рассуждения о пользе этого спора вообще смехотворны, мы тут не поиском истины занимаемся, а делимся мыслями и точками зрения. Ведь вне зависимости от того согласитесь ли вы со мной или нет, ничего не поменяется вообще Беседа, по-сути, философская. Хотя некоторые аспекты диалога с korvin, уже ближе к реальности. Цитата D_KEY @ Я рассуждаю так. Вот код, в нем есть последовательность инструкций, но нет мутабельности. Получается, что код не подходит под "конвенционально принятое" определение ФП (не должно быть последовательности инструкций). И не подходит под "конвенционально принятое" определение ИП (должна быть мутабельность).Смотри, это зависит от определения императивности. Ты же пытаешься наоборот , из примера вывести определение. Или я тебя не понимаю. Подумав я решил, что иммутабельность в ФП - это не какая-то самоцель, а следствие из самой сущности ФП. Нет необходимости где-то держать промежуточные результаты, потому что их попросту не существует, а что тогда мутировать? Получается, что иммутабельность не должна входить в определение ФП вообще, она автоматически следует из отсутствия промежуточных результатов. Далее, рассматривая ИП, я пришел к выводу, что промежуточные результаты совсем не обязательно должны быть мутабельными. Что мешает на очередном шаге создавать новую иммутабельную переменную, вместо мутации старой? Ничего не мешает, более того, я постоянно так делаю, и при этом код не превращается в функциональный, так как последовательность иструкций никуда не девается. Получается, что обязательность мутабельности как бы "искусственно" прицеплена к определению, без каких либо логических причин. А как же эта мутабельность вообще попала в определение ИП? Ведь вряд ли кто-то действительно беспричинно ее туда запихал. Но это можно объяснить просто историей императивного программирования. Отсюда делаю. вывод: "конвенционально принятое" определение ИП устарело. Ключевое - это последовательность инструкций. А, если подняться еще выше по уровню абстракции, то ИП тесно связано с течением времени. Время - это не просто очередная координата пространства, а фундаментальная особая составляющая ИП. В отличие от ФП. Цитата korvin @ Ну так не выводи в консоль, а просто возвращай результат и получится чистое ФП. Не понимаю, что ты хотел сказать этим примером.А если б у бабушки... Цитата korvin @ Ты ошибаешься, возможно путаешь иммутабельность и возможность объявлять константы. const в том же Си появилась, внезапно, в C89, благодаря тому самому Страуструпу, который добавил его сначала в свой Си с классами. Я помню времена, когда строковые литералы в сяшке имели тип char*. В школьном бейсике вообще не было никаких константных переменных. В php нормальной иммутабельности не было ни в 4-ой, ни в 5-ой версии, сейчсас не знаю. В JS const появился в ES6. Интересно, что даже сейчас const ни в C, ни в C++, ни в JS не является полноценной поддержкой иммутабельности, так как const не гарантирует иммутабельность (в отличие от immutable в D). Короче, о иммутабельности в прикладном программировании серъезно начали задумываться сравнительно недавно. ФП, конечно, возникло давно, но оно едва-едва начало выползать из академических кругов.Так как бы языки перестают быть "монопарадигмальными". А популярные языки никогда такими и не были. Иммутабельность была в Си, Паскале и практически любом другом языке с самого начала, не понимаю, что эта твоя фраза должна означать. Цитата korvin @ Вообще-то нет. Этож одна из фишек этого вашего ФП, типа смотрите, компилятор может все нафиг распараллелить. Представь, что операция сравнения очень тяжелая. В ФП можно раздербанить список на элементы и запустить кучу потоков, которые будут параллельно выполнять сравнение. При этом твой код никак не изменится.Есть и она точно такая же: очередной элемент будет проверен после предыдущего. Цитата korvin @ Нет не присутствует. Сравни императивную версию:Присутствует: нельзя вычислить значение функции, не вычислив её аргумента. a = foo(x) bar(a) с функциональной bar(foo(x)) На первый взгляд кажется, что разницы нет, но на самом деле есть. В императивном варианте функция foo будет выполнена до начала выполнения функции bar. В функциональной же версии foo может быть выполнена уже после начала выполнения bar (например в середине или даже паралелльно), да и вообще пофиг когда она выполнится. Мысли абстрактней, в ФП композиция функций - это просто новая функция, а не последовательность вызовов функций. В реальности, конечно, последовательность будет, потому что исполнитель любой ФП-программы императивен и любая задача все равно так или иначе будет разбитна на шаги компилятором/интерпретатором. Этот эффект используется в Haskell, там, где нужна императивность, например в некоторых монадах. Но это не относится к самой парадигме ФП, это несовершенство реализации. |
Сообщ.
#110
,
|
|
|
Цитата applegame @ Отсюда делаю. вывод: "конвенционально принятое" определение ИП устарело. Я бы сделал другой вывод. Применение термина ИП к практике современного программирования потеряло актуальность. Ну и подходов-то не два Да и в чистом виде мало кто применяет только какой-то один. |
Сообщ.
#111
,
|
|
|
Цитата korvin @ Да не, там отличные, на мой взгляд, статейки. Там прекрасно описаны достоинства и недостатки связных списков в том числе по сравнению с массивам. И вообще, рассмотрена туева хуча всяких видов списков, включая xor и unrolled варианты, на доступном английском языке с картинками. Даже дебил осилит. Инфа представленная там никак не противоречит твоим бенчам, скорее наоборот, объясняет почему так может происходить. а свои джуновские статейки лучше забудь. |
Сообщ.
#112
,
|
|
|
Цитата applegame @ Ты ошибаешься, возможно путаешь иммутабельность и возможность объявлять константы. const в том же Си появилась, внезапно, в C89, благодаря тому самому Страуструпу, который добавил его сначала в свой Си с классами. Я помню времена, когда строковые литералы в сяшке имели тип char*. В школьном бейсике вообще не было никаких константных переменных. Нет, не ошибаюсь. Но раз ты не понял, о чём я, то подскажу: opaque struct + функции чтения. Цитата applegame @ Вообще-то нет. Вообще-то да. Цитата applegame @ Этож одна из фишек этого вашего ФП, типа смотрите, компилятор может все нафиг распараллелить. Параллельность к этому примеру вообще не в тему. Цитата applegame @ В ФП можно раздербанить список на элементы и запустить кучу потоков, которые будут параллельно выполнять сравнение. При этом твой код никак не изменится. В моём примере нет списка. Цитата applegame @ a = foo(x) bar(a) bar(foo(x)) На первый взгляд кажется, что разницы нет, но на самом деле есть. В императивном варианте функция foo будет выполнена до начала выполнения функции bar. В функциональной же версии foo может быть выполнена уже после начала выполнения bar (например в середине или даже паралелльно), да и вообще пофиг когда она выполнится. Мысли абстрактней, в ФП композиция функций - это просто новая функция, а не последовательность вызовов функций. И вот ты снова путаешь синтаксис и семантику. Чисто функциональный код на Хаскелле: do a <- foo x bar a do-нотация является ни чем иным, как синтаксическим сахаром для монадной функции bind (оператор '>>=' и '>>' ): foo x >>= \a -> bar a который в свою очередь является просто композицией функций, определённой в используемой монаде: (\a -> bar a) (unwrap (foo x)) При этом bar(foo(x)) foo вычислится гарантировано до вызова bar при аппликативном порядке вычислений (а это все неленивые ФП языки, F#, Ocaml, Clojure и т.д.) а a = foo(x) bar(a) может вычислиться в другом порядке при нормальном порядке вычислений или просто отложенных вычислениях, например, в Си/Паскале foo может вернуть какой-то объект Promise. Цитата applegame @ Да не, там отличные, на мой взгляд, статейки. Там прекрасно описаны достоинства и недостатки связных списков в том числе по сравнению с массивам. И вообще, рассмотрена туева хуча всяких видов списков, включая xor и unrolled варианты, на доступном английском языке с картинками. Даже дебил осилит. Инфа представленная там никак не противоречит твоим бенчам, скорее наоборот, объясняет почему так может происходить. Значит, sergioK и вправду джун, раз не понимает даже статей, на которые сам ссылается. ) |
Сообщ.
#113
,
|
|
|
Цитата korvin @ Это ты называешь поддержкой иммутабельности в языке? Я вообще никогда не встречал, чтобы кто-то использовал opaque типы ради иммутабельности. Это же трешовый костыль вроде immutable.js. Ты бы еще просто запрет программисту менять объект назвал поддержкой иммутабельности в языке.Нет, не ошибаюсь. Но раз ты не понял, о чём я, то подскажу: opaque struct + функции чтения. Цитата korvin @ Тут нет списка?В моём примере нет списка. Цитата korvin @ Что касается оператора ||, то хотя в конкретной реализации (например GHC) сначала действительно будет вычислено значение левого операнда, надо понимать, что это просто деталь реализации. || - это ведь просто функция двух аргументов и ты сам совершенно правильно говорил, что порядок вычисления этих аргументов не имеет значения в ФП:contains [] e = False contains (x:xs) e = x == e || contains xs e Цитата korvin @ Судя по тому, что я нашел в интернетах, Haskell не запрещает реализации вычисляющие операнды в любом порядке.Странный вопрос. Для чистого ФП разницы нет (разве что одна из функций bar, baz значительно дольше вычисляется, чем другая). Цитата korvin @ То что do-нотация является сахаром к монаде - это не семантика, это детали реализации. Семантика же заключается в последовательном выполнении. И do-нотация, кмк, отходит от ФП в сторону ИП.И вот ты снова путаешь синтаксис и семантику. Цитата korvin @ Это опять же деталь реализации. Мы же не о конкретном языке говорим. ФП подразумевает нестрогую модель вычислений: порядок выполнения функций неважен.foo вычислится гарантировано до вызова bar при аппликативном порядке вычислений (а это все неленивые ФП языки, F#, Ocaml, Clojure и т.д.) Цитата korvin @ Пример с Promise неудачен, функция foo-то все равно выполнена до начала выполнения функции bar. Что касается нормального порядка вычислений, то это опять же деталь реализации. Компилятор может сделать редукцию, свертку констант и так далее, а может и не сделать. Результат гарантированно будет таким же как и при реально последовательном выполнении, иначе это неправильный компилятор.может вычислиться в другом порядке при нормальном порядке вычислений или просто отложенных вычислениях, например, в Си/Паскале foo может вернуть какой-то объект Promise. В общем, ты везде ссылаешься на конкретные реализации, причем разные в разных ФП-языках. |
Сообщ.
#114
,
|
|
|
Цитата korvin @ Значит, sergioK и вправду джун, раз не понимает даже статей, на которые сам ссылается. ) Не не понимаю, я ничего кроме hello world никогда не писал |
Сообщ.
#115
,
|
|
|
Цитата applegame @ Я вообще никогда не встречал, чтобы кто-то использовал opaque типы ради иммутабельности. Мало ли что ты не встречал. Цитата applegame @ Это же трешовый костыль В чём тут трешевость и костыльность? Цитата applegame @ Ты бы еще просто запрет программисту менять объект назвал поддержкой иммутабельности в языке. WUT? Цитата applegame @ надо понимать, что это просто деталь реализации И что, что это деталь реализации? Порядок задан? Задан. Цитата applegame @ Судя по тому, что я нашел в интернетах, Haskell не запрещает реализации вычисляющие операнды в любом порядке. И что? Calling conventions тоже разные бывают. Цитата applegame @ То что do-нотация является сахаром к монаде - это не семантика, это детали реализации Нет, это то, чем она является. Цитата applegame @ Семантика же заключается в последовательном выполнении Нет, не заключается. Цитата applegame @ И do-нотация, кмк, отходит от ФП в сторону ИП. Не отходит. Что, по-твоему, означает эта запись: do a <- foo x b <- bar y return $ gee a b ? Цитата applegame @ Пример с Promise неудачен, функция foo-то все равно выполнена до начала выполнения функции bar. И что, что она выполнена до? Что будет, если поменять их местами? Чем по-твоему это отличается от Хаскелла, например? Чем это отличается от ФП, если реальное вычисление может быть выполнено в любом порядке? Цитата applegame @ Результат гарантированно будет таким же как и при реально последовательном выполнении, иначе это неправильный компилятор. В общем, ты везде ссылаешься на конкретные реализации, причем разные в разных ФП-языках. Что ты вообще несёшь? Ответь лучше на вопрос: почему в ИП порядок имеет значение? Что будет, если в a = foo(x) b = bar(y) gee(a, b) поменять местами вызовы foo и bar: b = bar(y) a = foo(x) gee(a, b) ? Добавлено И ещё вопрос: для ФПшной композиции порядок важен? foo x = x + x bar x = (x, x) foo . bar и bar . foo — одно и то же или нет? А тут: foo x = x + 1 bar x = x * 2 foo . bar bar . foo ? |
Сообщ.
#116
,
|
|
|
И кроме всего прочего, как компилятор, так и процессор могут переставлять инструкции при необходимости, если это не нарушает связи между данными и не изменяет наблюдаемый результат, поэтому порядок инструкций языка может не везде совпадать с реальным порядком выполнения.
Например http://csg.csail.mit.edu/pubs/memos/Memo-493/memo-493.pdf |
Сообщ.
#117
,
|
|
|
Цитата Qraizer @ Использовались ли математические методы доказательства правильности разработанных алгоритмов? На закуску: приходилось ли проектировать системы с учётом возможных неизвестных аппаратных багов в процессорах? Математически доказано, что невозможно проверить зависнет программа или нет. На этом можно остановиться. Программа должна работать на компьютере, который не умеет считать? |
Сообщ.
#118
,
|
|
|
Цитата korvin @ А ты встречал чтобы кто-нибудь в C/С++ задействовал opaque типы ради иммутабельности? Пруфы пожалуйста.Мало ли что ты не встречал. Цитата korvin @ В том, что гарантиии иммутабельности дает не язык, а код, то бишь программист. Например те же функции чтения могут из-за ошибки программиста изменить opaque данные, и компилятор возражать не будет.В чём тут трешевость и костыльность? Цитата korvin @ В GHC задан, в другом компиляторе может быть не задан. Ты же надеюсь понимаешь, что мы обсуждаем не конкретные реализации, а ФП в целом? Ты же сам признал, что порядок вычисления аргументов функции в ФП не имеет значения.И что, что это деталь реализации? Порядок задан? Задан. Цитата korvin @ Ну тогда она является императивными машинными кодами, а реального ФП не существует.Нет, это то, чем она является. Цитата korvin @ Как минимум она означает, что foo будет выполнена раньше чем bar. Вся эта ваша монада IO для этого и предназначена: дать возможность в Haskell выполнять код последовательно, потому что IO - это связь с внешним миром, который императивен.Что, по-твоему, означает эта запись: Цитата korvin @ Если поменять местами строчки, оно просто не скомпилируется. Тем что во всякой императивщине отложенность прописывается явно, то есть программист сам решает в каком порядке делать вычисления, а в Хаскелле програмисту пофиг (до тех пор пока не столкнется с императивной реальностью) в каком порядке оно будет считаться. От ФП отличается тем, что в ИП программист точно знает, что конечный результат будет как при последовательном выполнении. А в ФП наплевать на порядок выполнения вообще, компилятор может выполнять функции в любом нужном ему порядке.И что, что она выполнена до? Что будет, если поменять их местами? Чем по-твоему это отличается от Хаскелла, например? Чем это отличается от ФП, если реальное вычисление может быть выполнено в любом порядке? Цитата korvin @ Результат может измениться. А вот в чистом ФП (например Хаскеле) ничего измениться не может.Ответь лучше на вопрос: почему в ИП порядок имеет значение? Что будет, если в a = foo(x) b = bar(y) gee(a, b) b = bar(y) a = foo(x) gee(a, b) Цитата korvin @ Порядок чего? Порядок записи конечно важен, могут же получиться в итоге разные функции. Примерно как спросить, поменяется ли что-нибудь если в числе 42 поменять местами 2 и 4.И ещё вопрос: для ФПшной композиции порядок важен? Цитата korvin @ Ключевое тут "не изменяет наблюдаемый результат". Более того, наблюдаемый результат обязан быть таким же как при последовательном выполнении инструкций. То есть компилятор может делать все что угодно (детали реализации), но выглядеть все должно так, как будто инструкции выполняются одна за другой. И кроме всего прочего, как компилятор, так и процессор могут переставлять инструкции при необходимости, если это не нарушает связи между данными и не изменяет наблюдаемый результат, поэтому порядок инструкций языка может не везде совпадать с реальным порядком выполнения. |
Сообщ.
#119
,
|
|
|
Цитата applegame @ А ты встречал чтобы кто-нибудь в C/С++ задействовал opaque типы ради иммутабельности? Пруфы пожалуйста. А если не встречал, то что это доказывает? Я так-то на Си не пишу. Цитата applegame @ В GHC задан, в другом компиляторе может быть не задан. Ты же надеюсь понимаешь, что мы обсуждаем не конкретные реализации, а ФП в целом? Ты же сам признал, что порядок вычисления аргументов функции в ФП не имеет значения. "Не имеет значения" и "отсутствует" --- не одно и то же Цитата applegame @ Как минимум она означает, что foo будет выполнена раньше чем bar. Вся эта ваша монада IO для этого и предназначена: дать возможность в Haskell выполнять код последовательно, потому что IO - это связь с внешним миром, который императивен. Не обязательно. И do-нотация не завязана на монаду IO, она работает с любой монадой, например монадой списков: import Data.Char foo = map chr . map (+ ord 'a') bar = filter even gee x y = (x, y) main = let x = [1,2,3] y = [4,5,6] in print $ do a <- foo x b <- bar y return $ gee a b https://ideone.com/0wW9IY [('b',4),('b',6),('c',4),('c',6),('d',4),('d',6)] Порядок определяется реализацией монады для конкретного типа, а не do-выражением. Цитата applegame @ Результат может измениться. А вот в чистом ФП (например Хаскеле) ничего измениться не может. За счёт чего же результат может измениться? ) Цитата applegame @ Ключевое тут "не изменяет наблюдаемый результат" А за счёт чего наблюдаемый результат может измениться? Цитата applegame @ Если поменять местами строчки, оно просто не скомпилируется. Это в первом случае, где у функций разные типы. А во втором? Там всё прекрасно скомпилируется. А результат поменяется? |
Сообщ.
#120
,
|
|
|
Цитата korvin @ Я писал много и на Си и на C++. Никто на парится иммутабельностью вообще. Раньше даже const-ом не заморачивались, сейчас юзают const, который тоже не является полноценной заменой иммутабельности. В общем никакой поддержки иммутабельности в самих языках C/С++/JS/PHP и многих других нет. Есть только попытки эмулировать ее теми или иными способами, и эти эмуляции мало кого интересуют. В Rust есть полноценная иммутабельность, в D тоже есть.А если не встречал, то что это доказывает? Я так-то на Си не пишу. Цитата korvin @ А ты не противопоставляй эти тезисы. Последовательность отсутствует в ФП-коде, потому что не она не имеет значения. То бишь сам ФП-код не задает никакой последовательности действий. Это уже реализация имеет какую-то последовательность, которая тоже может быть любой."Не имеет значения" и "отсутствует" --- не одно и то же Цитата korvin @ Честно говоря лень уже дальше разбираться. Мое знание Хаскеля достаточно базовое и довольно тяжело копаться даже в несложных кусках.Не обязательно. И do-нотация не завязана на монаду IO, она работает с любой монадой, например монадой списков: Погуглив по словам "haskell do imperative" обнаружил кучу упоминаний о том, что на хаскеле можно (но не нужно) писать имеративно, применяя монады, что do-нотация является псевдоимперативной или imperative style и так далее. Цитата korvin @ За счёт чего же результат может измениться? ) Цитата korvin @ За счет побочных эффектов, очевидно. Причем побочных эффектов в реальности может и не быть, но если компилятор об этом не знает, то он не будет переставлять местами инструкции.А за счёт чего наблюдаемый результат может измениться? Цитата korvin @ Ты похоже потерял нить, проследи эту ветку немного назад. Речь вроде шла об этом куске:Это в первом случае, где у функций разные типы. А во втором? Там всё прекрасно скомпилируется. А результат поменяется? a = foo(x) bar(a) |
Сообщ.
#121
,
|
|
|
Цитата applegame @ В Rust есть полноценная иммутабельность В расте нет, там в этом плане всё точно так же. |
Сообщ.
#122
,
|
|
|
Цитата applegame @ Честно говоря лень уже дальше разбираться. Мое знание Хаскеля достаточно базовое и довольно тяжело копаться даже в несложных кусках. Погуглив по словам "haskell do imperative" обнаружил кучу упоминаний о том, что на хаскеле можно (но не нужно) писать имеративно, применяя монады, что do-нотация является псевдоимперативной или imperative style и так далее. Отлично, "не читал, но мнение имею", "слышал звон, но не знаю где он". Как-то так. Цитата applegame @ За счет побочных эффектов, очевидно. А если б не было побочных эффектов? Цитата applegame @ Ты похоже потерял нить, проследи эту ветку немного назад. Речь вроде шла об этом куске: Не потерял, я тебе специально такой кусок привёл, где можно поменять порядок композиции, чтоб ты подумал: foo x = x + 1 bar x = x * 2 gee = foo . bar qux = bar . foo gee и qux --- это одинаковые функции или разные? Впрочем, давай рассмотрим твой кусок: a = foo(x) bar(a) заменим a на сам вызов: bar(foo(x)) программа из императивной сразу стала функциональной? Добавлено Цитата applegame @ Я писал много и на Си и на C++. Никто на парится иммутабельностью вообще. Про никто довольно смелое заявление. И даже если действительно не существует ни одного человека/проекта, использующего такую возможность, это не означает отсутствие самой возможности. |
Сообщ.
#123
,
|
|
|
Цитата applegame @ Цитата korvin @ За счет побочных эффектов, очевидно. Причем побочных эффектов в реальности может и не быть, но если компилятор об этом не знает, то он не будет переставлять местами инструкции.А за счёт чего наблюдаемый результат может измениться? Так ты же выше отказался от общепринятого определения ИП, убрав оттуда изменение состояния. Откуда тогда побочные эффекты? До сих пор не понимаю, чем тебе не нравится "обычное" определение ИП. Добавлено Цитата applegame @ Я писал много и на Си и на C++. Никто на парится иммутабельностью вообще. Почему первое предложение про тебя, а второе про всех? Вот ты и не парился, когда писал За const парятся в обязательном порядке. По поводу иммутабельности в узком смысле обычно задумываются в контексте структур данных и многопоточности. Зачастую что-то используют. Да даже на системном уровне попадается что-то в духе RCU, например |
Сообщ.
#124
,
|
|
|
Цитата applegame @ Честно говоря лень уже дальше разбираться. Мое знание Хаскеля достаточно базовое и довольно тяжело копаться даже в несложных кусках. Погуглив по словам "haskell do imperative" обнаружил кучу упоминаний о том, что на хаскеле можно (но не нужно) писать имеративно, применяя монады, что do-нотация является псевдоимперативной или imperative style и так далее. А ещё есть шутка, что Хаскелл --- это лучший императивный язык. https://wiki.haskell.org/Do_notation_considered_harmful Цитата Criticism Haskell's do notation is popular and ubiquitous. However we shall not ignore that there are several problems. Here we like to shed some light on aspects you may not have thought about, so far. Didactics The do notation hides functional details. This is wanted in order to simplify writing imperative style code fragments. The downsides are that: - Since do notation is used almost everywhere IO takes place, newcomers quickly believe that the do notation is necessary for doing IO, - Newcomers might think that IO is somehow special and non-functional, in contrast to the advertisement for Haskell being purely functional, - Newcomers might think that the order of statements determines the order of execution. Обрати внимание на последний пункт. Да и остальные. Ну и там далее в статье примеры "misunderstanding" |
Сообщ.
#125
,
|
|
|
А всё-таки, какое имеет отношение opaque struct к иммутабельности?
|
Сообщ.
#126
,
|
|
|
Цитата OpenGL @ Да ладно? Раст позволяет такие вот фокусы?В расте нет, там в этом плане всё точно так же. https://glot.io/snippets/fy2i5lgz8g import std.stdio; struct Foo { int a; this(int x) { a = x; } } struct Bar { Foo* foo; this(Foo* f) { foo = f; } void print() const { writeln(foo.a); } } void main() { auto foo = new Foo(10); const bar = const Bar(foo); bar.print(); //bar.foo.a = 11; // ошибка компиляции, bar иммутабелен? foo.a = 11; // опаньки, bar мутировал, компилятор не возражает bar.print(); } |
Сообщ.
#127
,
|
|
|
Именно в таком виде нет, т.к. если бы было можно, то легко было бы нарушить правило BC "на объект есть только одна mut ссылка". Но тем не менее это не иммутабельность, т.к. ничто не мешает менять объект, на котором нет mut, посредством Cell:
use std::cell::Cell; struct Foo { field: Cell<i32>, } impl Foo { fn new() -> Self { Foo{field: Cell::new(42)} } } fn main() { // Иммутабельный объект let f = Foo::new(); println!("{:?}", f.field.get()); f.field.set(-42); // Упс, он поменялся println!("{:?}", f.field.get()); } Вывод: 42 -42 |
Сообщ.
#128
,
|
|
|
Цитата korvin @ Я твой последний код не читал и никакого мнения по нему не высказал. Я давно изучал Хаскель и мне приходится прилагать усилия для расшифровки его закорючек если код чуть сложнее тривиального. Я просто не хочу это делать потому что, полностью уверен, что из анализа твоего примера не будет добавлено к уже сказанному ничего нового.Отлично, "не читал, но мнение имею", "слышал звон, но не знаю где он". Как-то так. Цитата korvin @ Я читал эту статью. Первый раз лет пять назад, когда изучал Хаскель, второй раз позавчера А ещё есть шутка, что Хаскелл --- это лучший императивный язык. https://wiki.haskell.org/Do_notation_considered_harmful То что там написано не опровергает того что пишу я. Результат выполнения инструкций в do-нотации будет таким же как если бы они выполнялись последовательно, вне зависимости от того чистые там функции или грязные. Согласен? В точности как в ИП. Статья большая, а ты выбрал одну фразу и выдрал ее из контекста. Молодец, чо. В шутке про лучший императивный язык, как обычно только доля шутки. На Хаскеле можно извратиться и писать императивно, я видел даже эквивалент обычных циклов, сделанный на монадах. Правда Хаскель скорее все же худший императивный язык Цитата korvin @ Без побочных результат не изменится. Но в ИП мы не знаем есть ли там побочные эффекты или нет. Компилятор может знать, а может и не знать об этих эффектах.А если б не было побочных эффектов? Поэтому в ИП последовательность инструкций важна, а в ФП нет. Нужели ты оспариваешь даже этот тезис? Он жн полностью согласуется как с моим определением, так и с общепринятым. Повторю вопрос, у тебя какое-то свое определение? Цитата korvin @ Я ответил на этот вопрос, ты правда никак не отреагировал.Не потерял, я тебе специально такой кусок привёл, где можно поменять порядок композиции, чтоб ты подумал: Цитата korvin @ И ты мне предлагаешь проверить память после этого. Обсуждали же уже этот кусок и этот вопрос. Смотри конец поста: Что делать с жунами (сообщение #3846765)Впрочем, давай рассмотрим твой кусок: Цитата D_KEY @ То что в моем определении нет необходимости в мутабельных переменных, не означает, что ИП не может иметь побочных эффектов. В общепринятом определении наличие последовательности инструкций - это необходимое, но недостаточное условие для ИП, а в моем это необходимое и достаточное условие.Так ты же выше отказался от общепринятого определения ИП, убрав оттуда изменение состояния. Откуда тогда побочные эффекты? До сих пор не понимаю, чем тебе не нравится "обычное" определение ИП. Почему мне не нравится общепринятое определение, я тебе уже объяснял, но ты игнорируешь мои объяснения. Еще примеры: Это императивщина? int a = foo(x) if(a == 0) return 1; a = a + bar(a); if(a == 1) return 2; return 3; Теперь добавим иммутабельности. immutable a = foo(x) if(a == 0) return 1; immutable a1 = a + bar(a); if(a1 == 1) return 2; return 3; Опять начнешь растекаться мыслью по древу, что тут нельзя точно сказать, что это смесь разных парадигм и так далее? Цитата D_KEY @ Ты похоже один из тех, кто думает, что const в C/C++ - это и есть иммутабельность. Почему первое предложение про тебя, а второе про всех? Вот ты и не парился, когда писал За const парятся в обязательном порядке. За const в мейнстриме начали парится с появлением его в C++ и C, то бишь в начале 90-х. С иммутабельностью мало кто парится и по сей день. Что касается лично меня. Я начал париться за const с 1994-го когда мне в инстутуте объяснили зачем он нужен. На иммутабельность я обратил внимание когда начал писать на D (лет 7 назад), а окончательно уверовал в ее полезность, когда начал изучать ФП на примере Хаскеля (лет 5 назад). Цитата D_KEY @ RCU прямого отношения к иммутабельности не имеет. Имутабельность может форсировать RCU, но не наоборот. Да даже на системном уровне попадается что-то в духе RCU, например Добавлено Цитата OpenGL @ Мде. Похоже и правда полноценную иммутабельность можно сделать только в языках с GC. Именно в таком виде нет, т.к. если бы было можно, то легко было бы нарушить правило BC "на объект есть только одна mut ссылка". Но тем не менее это не иммутабельность, т.к. ничто не мешает менять объект, на котором нет mut, посредством Cell: |
Сообщ.
#129
,
|
|
|
Цитата applegame @ То что в моем определении нет необходимости в мутабельных переменных, не означает, что ИП не может иметь побочных эффектов. В общепринятом определении наличие последовательности инструкций - это необходимое, но недостаточное условие для ИП, а в моем это необходимое и достаточное условие. Если это условие достаточное, то может быть такая реализация ИП, где мутабельности нет, а значит, побочным эффектам в приведённом тобой коде неоткуда взяться. |
Сообщ.
#130
,
|
|
|
Цитата applegame @ Почему мне не нравится общепринятое определение, я тебе уже объяснял, но ты игнорируешь мои объяснения. Ты не объясняешь, а приводишь странные примеры, в основном Как и ниже, собственно. Цитата Теперь это функциональщина? Зависит от наличия побочных эффектов Ты приводишь очень маленькие куски кода. Цитата Опять начнешь растекаться мыслью по древу, что тут нельзя точно сказать, что это смесь разных парадигм и так далее? Так если оно так и есть? Цитата Ты похоже один из тех, кто думает, что const в C/C++ - это и есть иммутабельность. Нет. А ты похоже из тех, кто думает что иммутабельность - это про языки. |
Сообщ.
#131
,
|
|
|
Цитата D_KEY @ Видимо ты имеешь в виду такой вариант ИП-кода (по моему определению ИП), в котором нет мутабельных переменных и все функции чистые. Ты совершенно прав. Но ИП позволяет нам не думать о чистоте функций. Но даже если они все чистые все равно, последовательность инструкций никуда не девается. Она есть и мы можем на нее полагаться, мы можем думать, что они выполняются последовательно. В чистом ФП нет никакой последовательности инструкций, и ты не только можешь не думать о ней, по-хорошему ты не должен думать о ней. Не знаю как у других, для меня лично понимание этого факта приверо к пониманию сути ФП. А понятие мутабельности/иммутабельности в чистом ФП вообще отсутствует. Там нечему быть мутабельным/иммутабельным.Если это условие достаточное, то может быть такая реализация ИП, где мутабельности нет, а значит, побочным эффектам в приведённом тобой коде неоткуда взяться. Цитата D_KEY @ А в чем их странность? Подобный код встречается сплошь и рядом.Ты не объясняешь, а приводишь странные примеры, в основном Как и ниже, собственно. Цитата D_KEY @ Ха. Хорошо, пусть foo и bar - это чистые функции, этот код написан в ФП-парадигме?Зависит от наличия побочных эффектов immutable a = foo(x) if(a == 0) return 1; immutable a1 = a + bar(a); if(a1 == 1) return 2; return 3; Цитата D_KEY @ Во-первых, речь изначально шла о поддержке иммутабельности в языках, очевидно, что это про языки. Во-вторых, да, без поддержки в языке, иммутабельность, похоже, получается неполноценная. Есть примеры обратного?Нет. А ты похоже из тех, кто думает что иммутабельность - это про языки. Цитата D_KEY @ Поэтому-то я и убираю лишние сущности, чтобы не было так.Так если оно так и есть? Попробуй вдуматься и понять мой ход мыслей еще раз, если конечно есть желание: Сферическое ИП в вакууме, по моему определению, это некая сущность, в котором есть течение времени, то есть у тебя всегда существует время, которое меняется само по себе от инструкции к инструкции. И возникают причинно следственные связи: значение переменной зависит от значения переменной вычисленной ранее и так далее. В сферическом ФП в ваккуме, времени нет вообще, я бы даже сказал что даже нет понятия исполнения кода. Ведь функция это просто некая зависимость выходных данных от входных. В таком ФП даже переменных нет. Я нарочно поднял, так сказать, градус "вакуумной сферичности", чтобы отсеять шелуху и оставить только фундаментальное отличия. В целом, если расширить понятие "мутабельный стейт", то возможно традиционное определение ИП не будет противоречить моему тезису: "можно писать императивно без применения мутабельных переменных". Ведь если вдуматься, то вот этот код: immutable a = foo(x) if(a == 0) return 1; immutable a1 = a + bar(a); if(a1 == 1) return 2; return 3; В русской википедии в статье о ФП (не ИП, ) есть интересная цитата: Цитата Обрати внимание на выделенную часть. Это не то самое о чем я написал выше?Противопоставляется парадигме императивного программирования, которая описывает процесс вычислений как последовательное изменение состояний (в значении, подобном таковому в теории автоматов). В таком смысле получается, что последовательность инструкций и мутабельный стейт являются следствиями друг друга. То есть достаточно включить одну из этих сущностей в определение и другая автоматически будет следовать из нее. |
Сообщ.
#132
,
|
|
|
Цитата applegame @ Но даже если они все чистые все равно, последовательность инструкций никуда не девается. Она есть и мы можем на нее полагаться, мы можем думать, что они выполняются последовательно. Если нет побочных эффектов, то последовательность действий фактически важна лишь с точки зрения корректности вычислений. А тут нет никаких отличий от ФП. |
Сообщ.
#133
,
|
|
|
Цитата OpenGL @ По поводу Rust. А вот этот вот Cell - это же не конструкция языка, а элемент стандратной библиотеки. Он внутри unsafe? Я к тому, что не является ли этот Cell каким-то способом, так сказать обмануть компилятор?Но тем не менее это не иммутабельность, т.к. ничто не мешает менять объект, на котором нет mut, посредством Cell: Ну как скажем в D можно тоже при желании мутировать immutable переменные в unsafe коде через cast. Добавлено Цитата D_KEY @ Есть: в чистом ФП само понятие последовательность вычислений не имеет сымсла. Ты остальное-то читал? Если нет побочных эффектов, то последовательность действий фактически важна лишь с точки зрения корректности вычислений. А тут нет никаких отличий от ФП. |
Сообщ.
#134
,
|
|
|
Цитата applegame @ Есть: в чистом ФП само понятие последовательность вычислений не имеет сымсла. Так и в ИП без побочных эффектов это так же не имеет никакого значения. Можно сделать такую реализацию, которая будет проводить хитрые анализы и менять последовательность выполнения (будет иметь право, т.к. видимый результат не изменится). Добавлено Цитата applegame @ Сферическое ИП в вакууме, по моему определению, это некая сущность, в котором есть течение времени, то есть у тебя всегда существует время, которое меняется само по себе от инструкции к инструкции. И возникают причинно следственные связи: значение переменной зависит от значения переменной вычисленной ранее и так далее. Это имеет значение только если у тебя есть побочные эффекты и изменение состояния или одним вычислениям нужен результат других. Первый случай ты исключаешь по определению, второй присутствует в ФП. Добавлено Цитата applegame @ даже если функции считать чистыми, все равно, в определенном смысле, имеет мутабельный стейт. Условно говоря - это контекст (в лице стека, например). В третьей строке в контексте появилась новая переменная a1 - считай мутировал стейт. Какая по сути разница: в коробке лежал синий кубик, мы вытащили его и положили вместо него красный кубик или лежал синий, а красный мы положили рядом? Один фиг содержимое коробки (стейт) изменилось. Если мы убираем побочные эффекты и изменение состояния (на уровне семантики языка), то это все становится лишь деталью реализации. |
Сообщ.
#135
,
|
|
|
Цитата applegame @ Но даже если они все чистые все равно, последовательность инструкций никуда не девается. Она есть и мы можем на нее полагаться, мы можем думать, что они выполняются последовательно. И какая нам польза в этом знании? |
Сообщ.
#136
,
|
|
|
Цитата applegame @ А чем if constexpr не устраивает? Я, кстати, пока ни разу не пользовался, так что моё мнение может быть необъективным, но-таки заявлю, что коли зарубил, значит были причины. Концепты, вон, тоже зарубили в своё время, зато сейчас они выглядят логичнее и понятнее. Та и std::filesystem нонешный мне нравится куда как сильнее по сравнению с начальной редакцией, слизанной с буста. Зато спешка с принятием std::wstring_convert и std::wbuffer_convert сказалась весьма неприятно. Я поначалу вслед за Wound тоже был разочарован отказом от него, но проведя собственное "расследование", склоняюсь к тому, что буду скорее на стороне отмены. Возможно ошибаюсь, но вроде именно он зарубил нормальный static if. Добавлено Цитата applegame @ Припоминаю спор о видах полиморфизма. Я там топил за то, что неважно, как оно реализовано в объектом коде, и единственно важно, как оно преподносится языком в его грамматике. Правда, уже не помню, чем кончилось. Можно, конечно скатываться в терминологическую демагогию, как это делаешь ты: ну типа раз в определении ИП написано "мутабельный", значит ответ очевиден: низзя. А на остальное насрать. Добавлено Цитата applegame @ Точно? Я бы определил императивность как метод, описывающий однозначную последовательность инструкций по получению результатов из входных данных. В отличие от декларативности, наиболее простым примером чего можно привести язык скриптов make. Одним из синонимом императивности является категоричность. По этому критерию ФП не ортогонально ИП, а является его более частным случаем, с дополнительными ограничительными методиками. Отсюда делаю. вывод: "конвенционально принятое" определение ИП устарело. Ключевое - это последовательность инструкций Добавлено Цитата sergioK @ Предлагаю перейти к решению квадратных уравнений. Не не понимаю, я ничего кроме hello world никогда не писал Добавлено Цитата scrambrella @ Ну вот, а вы на sergioK-а наезжаете. sergioK нормальный парень.Математически доказано, что невозможно проверить зависнет программа или нет. На этом можно остановиться. Цитата scrambrella @ Ужос, правда? Программа должна работать на компьютере, который не умеет считать? Добавлено Цитата D_KEY @ Только его рассматривают не как декларацию иммутабельности, а как утверждение контракта. Как бы есть разница между гарантией и обещанием. За const парятся в обязательном порядке. Добавлено Цитата applegame @ В догонку себе. Это следствие тех дополнительных качеств ФП, а не собственно базовое его отличие от ИП. Оно там просто всегда применимо. Я могу себе представить и в ИП то же самое, но конечно далеко не всегда, а в весьма частных случаях. Хотя тут от компилятора зависит, Intel C++, например, умеет раздербанивать всю программу целиком, и неважно, из скольких единиц трансляции она состоит. Запастись памятью и временем надо лишь. Поэтому в ИП последовательность инструкций важна, а в ФП нет. |
Сообщ.
#137
,
|
|
|
Цитата Qraizer @ Ну вот, а вы на sergioK-а наезжаете. sergioK нормальный парень. Цитата scrambrella @ 26 апреля, 10:41 Программа должна работать на компьютере, который не умеет считать? Ужос, правда? На работающем не могут правильно сделать расчёты. Плохой софт отправил работников почты за решетку https://habr.com/ru/company/itsoft/blog/554404/ Джанет Скиннер рассказывает, что её разлучили с двумя детьми на девять месяцев, в течение которых она находилась в тюрьме, после того, как Horizon показал недостачу в £59,000. Она также сообщает, что потеряла предложение о работе из-за своей судимости. Время, проведенное ею и другими в тюрьме, невозможно вернуть, и это произошло, потому что программе доверяли на слово. |
Сообщ.
#138
,
|
|
|
Цитата Qraizer @ Припоминаю спор о видах полиморфизма. Ссылка есть? Добавлено Цитата applegame @ По поводу Rust. А вот этот вот Cell - это же не конструкция языка, а элемент стандратной библиотеки. Он внутри unsafe? Да, Cell, RefCell и остальное юзают внутри unsafe. |
Сообщ.
#139
,
|
|
|
Сообщ.
#140
,
|
|
|
Цитата OpenGL @ Та где-то тут в Холиварах. Поди найди, при неработающем поиске-то. Ссылка есть? |
Сообщ.
#141
,
|
|
|
Цитата D_KEY @ Так это будут уже детали реализации. А нам важен код, а не реализация исполнителя этого кода.Так и в ИП без побочных эффектов это так же не имеет никакого значения. Можно сделать такую реализацию, которая будет проводить хитрые анализы и менять последовательность выполнения (будет иметь право, т.к. видимый результат не изменится). Цитата D_KEY @ Не исключаю, а делаю необязательным. Не надо искажать. Второй твой тезис неверен. В чистом ФП (идеальном) в коде нет явных промежуточных результататов, даже иммутабельных. Вот кусок программы на Haskell:Это имеет значение только если у тебя есть побочные эффекты и изменение состояния или одним вычислениям нужен результат других. Первый случай ты исключаешь по определению, второй присутствует в ФП. Цитата Может создаться ложное впечатление, что это последовательность из трех инструкций, аналогично, например этому коду в языке D:x = 3 y = x + 1 z = y + 2 const x = 3; const y = x + 1; const z = y + 2; Но тут нет никакой последовательности инструкций, тут даже в общем-то даже инструкций нет. Переменные не хранят промежуточных значений, поэтому можно переставлять строчки как угодно, ничего не меняется: Цитата В императивном коде такой фокус не прокатит.z = y + 2 y = x + 1 x = 3 В D в принципе возможно писать в аналогичном ФП-стиле при помощи лямбд: alias z = () => y() + 2; alias y = () => x() + 1; alias x = () => 3; Забавно, но в C/C++ это можно это сделать, используя макросы. Вот такое ФП (причем полиморфное, все по-взрослому ): #define z (y + 2) #define y (x + 1) #define x 3 Цитата D_KEY @ Не совсем понимаю, что значит "убираем изменение состояния на уровне семантики языка". Пример можно? В ИП промежуточные результяты создаются явно в коде, в виде переменных, в том числе иммутабельных. Если в коде явно не создавать промежуточных результатов, то наверное получится ФП. Если мы убираем побочные эффекты и изменение состояния (на уровне семантики языка), то это все становится лишь деталью реализации. Цитата korvin @ Польза большая: нам не нужно знать чистые эти функции или нет, просто считаем, что инструкции выполняются друг за другом.И какая нам польза в этом знании? Например в том же Erlang/Elixir вообще нет понятия чистоты функций. Они могут быть чистыми или грязными - пофиг. То же самое и в do-нотации Haskell. |
Сообщ.
#142
,
|
|
|
Цитата applegame @ Польза большая: нам не нужно знать чистые эти функции или нет Мы знаем, что они чистые. Цитата applegame @ То же самое и в do-нотации Haskell. В Хаскелле все функции чистые и do-нотация, как и монады, не имеют отношения к чистоте. |
Сообщ.
#143
,
|
|
|
А если так?
auto x = []{ return 3; }; auto y = []{ return x() + 1; }; auto z = []{ return y() + 2; }; |
Сообщ.
#144
,
|
|
|
Цитата korvin @ Если знаем, то ИП можно не применять. ИП полезно тем, что не нужно знать. Ты можешь знать если хочется, но тебе это не нужно, пусть об этом знает компилятор.Мы знаем, что они чистые. От твоего знания чистые это функции или нет ИП не превращается в ФП и наоброт. Парадигма кода зависит от семантики языка, и собственно самого кода. От твоего знания что функции bar и foo чистые, ИП код Цитата не станет внезапно ФП.immutable a = foo(x) if(a == 0) return 1; immutable a1 = a + bar(a); if(a1 == 1) return 2; return 3; Цитата korvin @ Не все. Иначе IO был бы просто невозможен.В Хаскелле все функции чистые Каждая IO-функция получает в качастве параметра, условное состояние внешнего мира, полученное из предыдущей IO-функции, делает IO и возвращает измененное состояние. НО! Если, допустим, функции чтения символа с клавиатуры подсунуть несколько раз одно и то же состояние мира, то она запросто может вернуть разные значения. Чтобы такого не происходило, в Хаскеле IO-функции вместе с сотоянием мира плотно завернуты в монаду, и остальные функции не имеют доступа к этому состоянию и, соответственно, не могут заставить IO-функцию вызваться с одним и тем же состоянием. Получается, что IO-функция как хитрожопый коррупционер: все знают что делишки грязные, но нет никакой возможности доказать это в рамках языка, формально все чисто. А все потому что все коррупционеры (IO-функции) в сговоре и никому, кроме как друг-другу, свои внутренние дела не раскрывают. Но они все равно с побочными эффектами, иначе порядок их вызова был бы не важен. Тем они и отличаются от обычных функций. Цитата korvin @ Да, монады упрощают построение цепочек вызовов функций со скрытым внутренним состоянием.и do-нотация, как и монады, не имеют отношения к чистоте. do-нотация имеет отношение к последовательности инструкций. Об этои говорит название нотации (do) и название её элементов (statements). Некоторые авторы пытаются зачем-то откреститься от этого. Например в пресловутой статье: https://wiki.haskell.org/Do_notation_considered_harmful написано: Цитата Что в общем случае является ложью. В качестве примера там берутся чистые функции. Но ведь если бы там были IO-функции с побочными эффектами, То the order of statements очень даже был бы the criterion for the evaluation order, при том что никаких явных data dependencies может вообще не быть. The order of statements is also not the criterion for the evaluation order. Also here only the data dependencies count. Добавлено Цитата Qraizer @ А если так? auto x = []{ return 3; }; auto y = []{ return x() + 1; }; auto z = []{ return y() + 2; }; Так не нужно. Вот если бы можно было так: auto z = []{ return y() + 2; }; auto y = []{ return x() + 1; }; auto x = []{ return 3; }; |
Сообщ.
#145
,
|
|
|
Цитата applegame @ не станет внезапно ФП. Почему это? Вот этот код тоже императивный: foo() + bar() + gee() + qux() ? А этот: foo() >> bar() >> gee() >> qux() ? Может, этот: foo() ; bar() ; gee() ; qux() ? Какой из этих примеров — чистая композиция функций (например, на Хаскелле), а какой — императивная последовательность statement'ов (например, на Паскале)? Цитата applegame @ Не все. Иначе IO был бы просто невозможен. IO не имеет отношения к языку. Они разделены. Цитата applegame @ do-нотация имеет отношение к последовательности инструкций. Об этои говорит название нотации (do) и название её элементов (statements). Не имеет. Тебе уже пример приводили. Цитата applegame @ Некоторые авторы пытаются зачем-то откреститься от этого. Например в пресловутой статье: https://wiki.haskell.org/Do_notation_considered_harmful написано: всего-то wiki на сайте языка, наполняемая и модерируемая сообществом хаскеллистов. При этом и Haskell Report не пишет ни о какой «последовательности инструкций». Цитата applegame @ Что в общем случае является ложью. Э нет, это чистая правда и просто факт. Но ты скатился до уровня Серёжи, ему тоже тыкали фактами в нос, а он продолжал витать в своих фантазиях. Цитата applegame @ Каждая IO-функция получает в качастве параметра, условное состояние внешнего мира, полученное из предыдущей IO-функции, делает IO и возвращает измененное состояние. НО! Если, допустим, функции чтения символа с клавиатуры подсунуть несколько раз одно и то же состояние мира, то она запросто может вернуть разные значения. Чтобы такого не происходило, в Хаскеле IO-функции вместе с сотоянием мира плотно завернуты в монаду, и остальные функции не имеют доступа к этому состоянию и, соответственно, не могут заставить IO-функцию вызваться с одним и тем же состоянием. Получается, что IO-функция как хитрожопый коррупционер: все знают что делишки грязные, но нет никакой возможности доказать это в рамках языка, формально все чисто. А все потому что все коррупционеры (IO-функции) в сговоре и никому, кроме как друг-другу, свои внутренние дела не раскрывают. Но они все равно с побочными эффектами, иначе порядок их вызова был бы не важен. Тем они и отличаются от обычных функций. а все другие монады, прячущие свои внутренности тоже в каком-то сговоре? Порядок «вызова» IO-функций задаётся обычной чистой функциональной композицией. Добавлено Цитата applegame @ Но ведь если бы там были IO-функции с побочными эффектами, То the order of statements очень даже был бы the criterion for the evaluation order Нет. Критерием вычисления является конкретная монада, используемая в do-выражении. |
Сообщ.
#146
,
|
|
|
Цитата applegame @ Цитата D_KEY @ Так это будут уже детали реализации. А нам важен код, а не реализация исполнителя этого кода.Так и в ИП без побочных эффектов это так же не имеет никакого значения. Можно сделать такую реализацию, которая будет проводить хитрые анализы и менять последовательность выполнения (будет иметь право, т.к. видимый результат не изменится). Так в коде этого и не будет, если исходить из твоего определения. Не понимаю. Если нет побочных эффектов и изменения состояния, то последствательность выполнения инструкций важна лишь в контексте корректности вычислений, а значит, это ничем от ФП не отличается. Добавлено Цитата applegame @ Не исключаю, а делаю необязательным. Не надо искажать. Если ты не считаешь это необходимым условием, то мы его может вообще убрать для простоты рассмотрения. Цитата В чистом ФП (идеальном) в коде нет явных промежуточных результататов, даже иммутабельных Да почему это важно, если видимый результат никак от этого не зависит? Дальше ты опять скатываешься в языки, исходя из ложного предположения, что раз какой-нибудь C++ является императивным, то и любой код на нём отражает императивный стиль. Ну или я ошибаюсь, но тогда я вообще не понимаю, к чему твои примеры Добавлено Цитата applegame @ В императивном коде такой фокус не прокатит. Аналогом того кода на haskell в С++ будет: int x() { return 3; } int y() { return x() + 1 } int z() { return y() + 2; } Для перестановки достаточно заранее объявить функции: int x(); int y(); int z(); И инструкции тут ни при чем, это особенности областей видимости имен. |
Сообщ.
#147
,
|
|
|
Цитата korvin @ Потому что парадигма не может измениться если не меняется код Очевидно же.Почему это? Цитата korvin @ Последний - ИП, первые два ФП.Какой из этих примеров — чистая композиция функций (например, на Хаскелле), а какой — императивная последовательность statement'ов (например, на Паскале)? Цитата korvin @ Это тут причем? Ты сказал, что все функции в Хаскеле чистые. Раз возможно IO, значит возможны функции с побочными эффектами.IO не имеет отношения к языку. Они разделены. Цитата korvin @ Пример чего?Не имеет. Тебе уже пример приводили. Цитата korvin @ Опять апеллирование к авторитету. всего-то wiki на сайте языка, наполняемая и модерируемая сообществом хаскеллистов. При этом и Haskell Report не пишет ни о какой «последовательности инструкций». Цитата korvin @ Понеслась волшебная аргументация. Я не знаю как тебе уже объяснять. Если по-твоему вот тут результат не зависит от порядка стейтментов, то я хз кто тут больше похож на Сирожу Э нет, это чистая правда и просто факт. Но ты скатился до уровня Серёжи, ему тоже тыкали фактами в нос, а он продолжал витать в своих фантазиях. main = do putStrLn "str1" putStrLn "str2" Цитата korvin @ Откуда такой вывод? Почему все, если я говорил о хаскельном IO, в том числе и о монаде IO? а все другие монады, прячущие свои внутренности тоже в каком-то сговоре? Цитата korvin @ В чистой ФП-композиции порядок может быть любым, уже обсуждали и ты вроде согласился. Опять по кругу?Порядок «вызова» IO-функций задаётся обычной чистой функциональной композицией. Цитата korvin @ Ага, а то что эти критерии коррелируют с порядком стейтментов в do-нотации - это просто совпадение? Не думаю. Нет. Критерием вычисления является конкретная монада, используемая в do-выражении. Ладно, походу этот холивор порвался. Лично мне надоело. |
Сообщ.
#148
,
|
|
|
Функциональное и логическое программирование - единственно верные стили. ООП и ИП в топку. На С/С++ легко писать функционально.
|
Сообщ.
#149
,
|
|
|
Цитата D_KEY @ В общем ладно. Если ты тоже как и Корвин, считаешь, что парадигма этого кода зависит от чистоты функций bar и foo:Если ты не считаешь это необходимым условием, то мы его может вообще убрать для простоты рассмотрения. immutable a = foo(x) if(a == 0) return 1; immutable a1 = a + bar(a); if(a1 == 1) return 2; return 3; Делаем функции foo и bar чистыми, и опаньки - это ФП код, делаем с побочными эффектами и снова ИП Ну ок, оставайтесь при своем мнении. |
Сообщ.
#150
,
|
|
|
Цитата applegame @ Если по-твоему вот тут результат не зависит от порядка стейтментов, то я хз кто тут больше похож на Сирожу main = do putStrLn "str1" putStrLn "str2" Так зависит. Но ты убери синтаксический сахар из кода и посмотри, каким образом эта зависимость выражается на самом деле. |
Сообщ.
#151
,
|
|
|
Цитата D_KEY @ Да ваще, код поменялся до неузнаваемости:Но ты убери синтаксический сахар из кода и посмотри, каким образом эта зависимость выражается на самом деле. main = putStrLn "str1" >> putStrLn "str2" Добавлено Кстати в Erlang/Elixir нет мутабельных переменных, но полно функций с побочными эффектами. Значит таки можно писать императивно (по вашему определению) без мутабельных переменных? |
Сообщ.
#152
,
|
|
|
applegame, main = myMain $ do myPutStrLn "first" myPutStrLn "second" myPutStrLn "third" third second first impl import Control.Applicative data MyCoolIO a = MCIO (IO a) instance Functor MyCoolIO where fmap f (MCIO xIO) = MCIO $ fmap f xIO instance Applicative MyCoolIO where pure = MCIO . pure (MCIO fIO) <*> (MCIO xIO) = MCIO $ fIO <*> xIO instance Monad MyCoolIO where return = pure (MCIO xIO) >>= f = MCIO $ xIO >>= \x -> (let (MCIO r) = f x in r) (MCIO xIO) >> (MCIO yIO) = MCIO $ yIO >>= \y -> (xIO >> return y) myPutStrLn :: String -> MyCoolIO () myPutStrLn s = MCIO $ putStrLn s myMain :: MyCoolIO () -> IO () myMain (MCIO io) = io — https://ideone.com/9nbY5V Давай, расскажи ещё про порядок в do-выражении. Добавлено Цитата applegame @ Значит таки можно писать императивно (по вашему определению) без мутабельных переменных? В нашем определении есть изменяемое состояние, а не «мутабельные переменные». Добавлено Цитата |