Pull to refresh
1
0
Юрий Муравьёв @y_mur

User

Send message

С этого момента Алиса перестаёт быть единственным автором программы, а это значит, что теперь она не может сменить лицензию проекта как угодно и сама должна соблюдать GPL (если проект под GPL) при распространении программы. 

А разве не так: Если Алиса хочет распространять программу изменённую Бобом, то она должна соблюдать GPL, но у неё остаётся право распространять свою исходную версию как угодно?

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

Спасибо! Интересная статья.

Я не понимаю: GNU п.5a:

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

Т.е. Боб должен подробно расписать в лицензии что именно сделал он, а что осталось от Алисы?

А если авторов много и они много раз что то добавляли, то лицензия станет больше дистрибутива?

Идея отличная, но материал устарел, многие ссылки уже не работают.
А поиск банального набора иконок для GUI в одном стиле оказался крайне нетривиальной задачей. Так и не нашёл где такие водятся, только Tango без альтернатив.

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

Ага, а то я не вижу что они делают по факту.

Почему проигнорирован момент что ИИ не создаёт а комбинирует то что скопипастил?

По моему ключевой момент в том что сейчас ИИ нагло тырит авторские материалы и выдает это за свою работу.

Ага и ИИ будет брать авторскую работу, на которой он типа обучался, ставить на ней малюсенькую точку и тарам пам пам авторская работа сразу станет общественным достоянием. Почему то в этой заметке этот момент проигнорирован. А по мне так это ключевой вопрос в теме.

Опять же, доказывать утверждения о рекурсии проще, чем о циклах. Вплоть до того, что у нас есть много пруверов вроде coq/agda/etc, основанных на индуктивно-рекурсивных рассуждениях, и около ноля аналогичных пруверов на мутабельных циклах.

Согласен что в Математике (из которой она и пришла) рекурсия восхитительно прекрасна! Проблемы с ней возникают когда её переносят в программирование, особенно если делают это математически формально, без трассировки того что при этом происходит в программе.

любой алгоритм на циклах выражается через рекурсию. И обратно, конечно — это эквивалентные по выразительной силе (но не по простоте рассуждений, хоть мы и не согласны с вами, в какую сторону) формализмы.

Чисто формально - да, а вот на практике проблема в том что:

  • рекурсия это не один, а всегда несколько условных взаимосвязанных циклов;

  • у программиста нет прямого доступа к этим внутренним циклам (в отличии от программы на комбинации циклов, где всё максимально прозрачно);

  • иногда можно заменить мозгодробительно сложную комбинацию циклов на простую и элегантную рекурсию, но для этого "звёзды должны сойтись в правильный знак на небе". Найти подходящую рекурсию для такой замены можно исключительно редко, а зачастую ещё эффективнее просто взять другую комбинацию циклов (см. мой пример: формальный определитель vs Гаусс).

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

Вот я управляемо взял и переписал ваш факториал так, чтобы он гарантированно был «одноцикловым» в ФП.

Да в отдельных случаях можно научить компилятор нормально превращать рекурсию в цикл. Только помимо вопроса "а зачем тогда с рекурсией то заморачивались?" это очень частный случай для очень простых задач начального уровня (факториал как раз такая). А вы попробуйте научить компилятор превращать рекурентный определитель в метод Гаусса с повышением быстродействия не в разы, а на порядки! Причём достигается это как раз алгоритмически!

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

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

Если посмотреть на это через призму трассировки то масштаб проблемы будет на насколько порядков меньше чем в теме рекурсии. А вот плюсы от этой "странной идеи" реально есть и они в большинстве случаев перевешивают минусы, а если вдруг не перевешивают, то есть "кривой костыль" :).

Я понял - мы говорим и мыслим на разных языках программирования.
И я зря всё свалил в одну кучу - нужно чётко разделить.
Практически всё что я написал выше про компиляторы относится к С\С++ и ему подобным.
Они никогда не превращают рекурсию в циклы. Потому что это задача программиста.

Да многоцикловую сущность рекурсии иногда можно применить для того чтобы заменить много циклов на одну рекурсию. Например, в классическом подходе к вычислению определителя матрицы. Я когда то даже игрался с его оптимизацией . https://github.com/wmurw/determinant/tree/master. В этом случае много циклов "закрутки/раскрутки" рекурсии идеально ложатся в математическую суть задачи. А попытка прописать все эти циклы вручную без рекурсии - будет жёстким насилием над мозгом программиста.
Но попробуйте найти этим способом определитель матрицы хотя бы 100х100 и компьютер наглухо зависнет. А основанный на циклах метод Гаусса легко одолеет и матрицу 1000х1000 (и он тоже ещё не самый эффективный).

Вывод: многоцикловая сущность рекурсии - этакая "осьминожка - раскоряка", которая:

  • алгоритмически сложна для понимания и имеет крайне низкую наглядность;

  • предоставляется "как есть" - у программиста нет возможности как то подкорректировать один из этой навороченной комбинации её внутренних условных циклов.

  • если не зацикливаться на логике рекурсии то можно найти гораздо более эффективный алгоритм, основанный на циклах, которые не тупо пытаются скопировать логику рекурсии, а делают шаг в сторону и идут принципиально другим путём. Зацикленность на рекурсивном мышлении мешает программисту находить эти эффективные алгоритмы.

В связи с этим идея ФЯП - заменить вообще все наглядные, логичные, понятные с беглого взгляда циклы на "более универсальные" рекурсии для меня звучит полным бредом. Рекурсия вот ни разу не универсальнее - наоборот она очень узко специализирована. Да иногда одна рекурсия может заменить много сложно связанных циклов, но это не управляемый процесс - либо этот паззл-осьминог встанет на своё место либо нет и никак его не впихнёшь. А вот алгоритмическое мышление программиста при этом корёжится и внимание направляется вот совсем не в ту сторону. Этакая идеологическая диверсия.

А так называемая "хвостовая рекурсия" в моей картине мира выглядит так:

  • разработчики ФЯП повелись на странную идею отказаться от циклов;

  • попробовали с этим жить и осознали что не очень получается;

  • вернули циклы обратно в виде кривого костыля, зато исходную идею вроде как сохранили.

С чего это ему быть одним?
Нет, компилятор (за исключением специальных случаев типа хвостовой рекурсии) не станет выкидывать из рекурсии "лишние" циклы "закрутки" "раскрутки" по той простой причине что они неотъемлемая часть рекурсии как Алгоритма. И не в компетенции компилятора решать когда они выполняют полезную функцию, а когда только "мусорят". Это должен понимать программист.
И да, в ассемблерном коде не будет вообще никаких циклов - там будет та же самая рекурсия (вызов из функции самой себя). Компилятор вообще никогда (кроме вышеупомянутых хвостовых рекурсий) не заменяет рекурсии циклами.
Эквивалентные циклы, про которые я пишу, вы сможете увидеть только выполняя программу пошагово и наблюдая за тем что она вытворяет на самом деле.


Рекурентный факториал:

int factorial(int N)
{
	if (1 == N) 
		return 1;
	return N*factorial(N-1);
};

выглядит однопроходным но на самом деле алгоритмически работает вот так:

int factorial(int n)
{
	std::stack<int> st;

	// цикл «закрутки»
	while (--n >= 1) 
		st.push(n);

	// цикл «раскрутки»
	while (!st.empty())
	{ 
		n *= st.top();
		st.pop();
	}
	return N;
}

Т.е. сначала захламляет стек значениями n-1, n-2, ... 3, 2, 1 (про захламление адресами возврата скромно умалчиваю) и только после этого переходит к этапу вычислений.
Но сообразить это глядя на рекурентную запись совсем не очевидно.
И это самая банальщина.

А вот если взять например так же простенько выглядящую функцию Аккермана, то циклов закрутки и раскрутки будет далеко не два и она будет очень долго по ним бегать.
https://wasm.in/threads/rekursivnaja-funkcija-i-razmer-steka.17617/

Между прочим, для малых фиксированных значений n для функции Аккермана есть простые формулы:A(0,m) = m+1A(1,m) = m+2A(2,m) = 2m+3A(3,m) = 2^(m+3)-3а при больших она просто слишком быстро растёт: уже N(4,2) = 2^65536-3, N(4,3) = 2^(2^65536)-3, что ни в какую память не влезет, так что вычислять значения невозможно.

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

Это я рассмотрел достаточно полярные случаи - предельно простой и с высокой степенью алгоритмического коварства и непредсказуемости.


Ну про захламление стека и так много написано. Поэтому я про избыточную и трудно предсказуемую сложность рекурсивных алгоритмов. Чуть подробнее в моём соседнем ответе выше.

Суть в том что рекурсивный алгоритм, даже кажущийся однопроходным, на самом деле содержит как минимум два цикла "цикл закрутки" и "цикл раскрутки" (названия мои, возможно у них уже есть другие названия, просто я не встречал раскрытия этой темы).
При этом даже в тривиальных случаях (типа факториала) один из этих циклов явно лишний. И это не "особенности двоичного кода", а алгоритмически лишний цикл.
Но в общем случае этих циклов ни разу не два, а больше и одна из проблем рекурсивных алгоритмов в том что сложно на глазок определить сколько именно, да и не на глазок надо изрядно мозг поломать. Но насколько я понимаю поклонники рекурсии просто предпочитают "не видеть этих сусликов". Ну или они все гении и это для меня рекурсия выглядит айсбергом скрывающим настоящую алгоритмическую сложность, а они её "видят насквозь" и "просекают в момент". Подробнее без примеров сложно, а с примерами это уже статья выходит.

Я не специалист по рекламе, просто интересующийся мимокрокодил. Поясните пожалуйста на пальцах - как в телеграмме люди могут узнать про мои продукты и услуги, если они на меня не подписаны?

В моём понимании телеграмм это не самостоятельный аналог остальных площадок, а инструмент для дожимания теплых клиентов.

Т.е. сначала надо где-то на других площадках набрать клиентов и привести их на свой канал.

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

В чем я не прав?

Эх давно хочу но руки не доходят написать серию статей с названием Антирекурсия. Разумеется с большим набором конкретных примеров. Суть в том что если вы видите "лаконичный" код с использованием рекурсии, то на самом деле внутри него всегда скрывается мозгодоробительнейшая логика, которую никто в здравом уме не будет использовать (если будет её видеть). Меня всегда удивляют люди, которые восхищаются рекурсией. Мне кажется что они просто не понимают как она работает на самом деле, хотя они думают с точностью до наоборот, что не понимают те кто не используют рекурсию :)

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

Знаю пару не мелких предприятий, которые установили рабочий день с 7 до 16 как раз из этих соображений. Так что сейчас на уровне бизнеса это как минимум возможно.

Заметка зацепила - спасибо!
На готовую "мудрость" или "инструкцию" она конечно не тянет, но зато тянет за множество моих личных "хвостиков" с которыми мне актуально разобраться.

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

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

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

А так в современном обществе есть чёткое разделение на:

  • практиков, которые редко занимаются обучением;

  • методистов, которые наблюдают за практиками, достают их отвлекающими вопросами и создают учебные программы;

  • преподавателей, которые учат по готовым методикам, и в 99% случаев бесконечно далеки от практического применения своего предмета обучения.

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

Главный навык преподавателей - вовлекать и мотивировать учеников и это реально сложный и нужный навык. Быть ещё и методистом или тем более практиком от преподавателей не требуется.

Сочетание всего этого в одном человеке нынче встречается крайне редко и главное не востребовано в системе основанной на узких специализациях. Поэтому такой человек даже если изредка появляется, то не вписывается в существующую систему.

Зато по принципу действия она была турбиной, т.е. да вполне сойдёт за лабораторный прототип современных паровых турбин, который дождался развития остальных компонентов.

Information

Rating
Does not participate
Location
Саратов, Саратовская обл., Россия
Date of birth
Registered
Activity