(Прошу прощения за каламбур, речь пойдет не о труде Кнута).
Предлагаю поделиться мыслями об эстетическом аспекте программирования. Что я имею в виду? Программирование — это выражение алгоритма в некоторой произвольной (одной из бесчисленно возможных) форме, и его результат — программа — может быть объектом эстетической оценки, т.е. может вызывать определенного рода переживание, сходное с тем, когда мы воспринимаем объекты традиционного искусства, и это переживание можно адекватно выразить в тех же терминах, что использует художественный критик. (Сам по себе алгоритм, скорее всего, красивым или некрасивым быть не может, так как не является формой выражения).
Возьмем, к примеру, FizzBuzz. Ниже — типовые варианты его реализации:
Haskell:
main = mapM_ (putStrLn . fizzbuzz) [1..100]
fizzbuzz x
| x `mod` 15 == 0 = "FizzBuzz"
| x `mod` 3 == 0 = "Fizz"
| x `mod` 5 == 0 = "Buzz"
| otherwise = show x
Perl:
say 'Fizz'x $_ %% 3 ~ 'Buzz'x $_ %% 5 || $_ for 1 .. 100;
Что мы (т.е. я ) видим? Вариант на Хаскелле — это то, что приходит на ум первым, т.е. банальность. Решение на перле — самое короткое, но при этом запутанное, неряшливое — все принесено в жертву краткости. А вот вариант на пиколиспе — ясный, элегантный, небанальный — можно сказать, красивый. Заключительная программа приведена для контраста.
Что это означает на практике? Что есть языки программирование более и менее красивые. Например, можно предположить, что С просто-напросто красивее С++, и т.д... Уфф... Надеюсь, что читать этот пост было легче, чем его писать.
Здравствуйте, Basil B, Вы писали:
BB>Возьмем, к примеру, FizzBuzz. Ниже — типовые варианты его реализации:
BB>Что это означает на практике? Что есть языки программирование более и менее красивые. Например, можно предположить, что С просто-напросто красивее С++, и т.д...
По моему мнению, красивость кода больше зависит от программиста, чем от языка программирования.
Здравствуйте, Basil B, Вы писали:
BB>Возьмем, к примеру, FizzBuzz. Ниже — типовые варианты его реализации.
Ок. А теперь возьмём код установки перехвата в нативный код на платформе ARMv7. И чтобы поддерживал все 4 варианта ARM/THUMB <-> ARM/THUMB, имел минимально возможную длину врезки, учитывал 32 битные инструкции THUMB-2, правильно делал interworking, а также анализировал переносимые инструкции, и в случае relative PC адресации переносил и адресуемые константы вслед за ними, формируя свою собственную таблицу констант, при этом учитывая что выравнивание команд в THUMB может отличаться от выравнивания смещений...
Если совсем угореть — пусть ещё при вызове перехвата доп. параметром добавляет адрес "псевдно-оригинальной" функции. Чтобы из перехвата можно было вызвать "неперехваченный" оригинал ДО своего кода, ПОСЛЕ своего кода, вообще не вызывать или вызвать несколько раз. Не обращаясь к глобальным переменным, ведь они — ЗЛО! Конечно для >= 4 параметров придётся двигать стек, а как без этого ?
Здравствуйте, Ziaw, Вы писали:
BB>>А вот вариант на пиколиспе — ясный, элегантный, небанальный — можно сказать, красивый. Заключительная программа приведена для контраста. Z>Что-то он не сильно читабельнее перла, на мой взгляд.
Здравствуйте, Ops, Вы писали:
Ops>Здравствуйте, AleksandrN, Вы писали:
AN>>По моему мнению, красивость кода больше зависит от программиста, чем от языка программирования.
Ops>А можно пример красивого на перле? Желательно из реального проекта.
Можешь посмотреть на библиотеки на cpan.org. В них, как правило, неплохой код. Например — Net::SMTP.
Возможности Перла позволяют написать совершенно нечитабельный код, но так делать не обязательно.
Здравствуйте, Basil B, Вы писали: BB>Что мы (т.е. я ) видим? Вариант на Хаскелле — это то, что приходит на ум первым, т.е. банальность. Решение на перле — самое короткое, но при этом запутанное, неряшливое — все принесено в жертву краткости. А вот вариант на пиколиспе — ясный, элегантный, небанальный — можно сказать, красивый. Заключительная программа приведена для контраста.
На самом деле мы видим код, который не пригоден к использованию. Всё остальное вторично.
Как только дело доходит до реальных задач, сценарий внезапно™ оказывается сложнее чем "вывести в консоль".
Скажем, FizzBuzz используется не только при выводе, да ещё и данные не факт что всегда корректными будут.
Вот тут и начинается искусство. Ну, или FizzBuzzEnterpriseEdition, тут уж как пойдёт
Так вот, как насчёт чуть усложнить задачу?
Скрытый текст
public static class FBApp
{
[NotNull]
private static string ToFizzBuzz(this int value)
{
Code.InRange(value, nameof(value), 0, int.MaxValue);
string result;
if (value % 15 == 0)
result = "FizzBuzz";
else if (value % 3 == 0)
result = "Fizz";
else if (value % 5 == 0)
result = "Buzz";
else
result = value.ToString();
return result;
}
public static void Main()
{
foreach (var value in Enumerable.Range(1, 100))
{
Console.WriteLine(value.ToFizzBuzz());
}
Console.WriteLine("Done.");
Console.ReadKey();
}
[TestCase(0, "FizzBuzz")]
[TestCase(122, "122")]
[TestCase(123, "Fizz")]
[TestCase(125, "Buzz")]
[TestCase(int.MaxValue, "2147483647")]
public static void Proofs(int value, string expected) =>
Assert.AreEqual(value.ToFizzBuzz(), expected);
[TestCase(int.MinValue, false)]
[TestCase(-1, false)]
[TestCase(0, true)]
[TestCase(1, true)]
[TestCase(int.MaxValue, true)]
public static void ProofsBadInput(int value, bool ok)
{
if (ok)
Assert.DoesNotThrow(()=>value.ToFizzBuzz());
else
Assert.Throws<ArgumentOutOfRangeException>(() => value.ToFizzBuzz());
}
}
Что-то мне подсказывает, что где-то к этому моменту критерии "красивости" немножко поменяются
UPD Хороший аргумент про "проблема в руках, а не в языке": 1000 и 1 способ doing it wrong