Представь себе: ты только что получил в наследство кодовую базу, где каждая функция выглядит так, будто по клавиатуре прогулялась кошка. Переменные с именами x1, a_ и p0lyg0n смотрят на тебя, как загадочные руны. Когда твой взгляд становится стеклянным, ты понимаешь — кто-то решил поиграть в «Кодовый гольф для разработчиков». Давай поговорим о том, почему нам нужно отобрать у них клюшки.
Что такое кодовый гольф?
Кодовый гольф — это искусство решения задач с использованием наименьшего количества символов, как будто пишешь произведения Шекспира с помощью эмодзи. Простой калькулятор факториала может превратиться из:
def factorial(n):
if n == 0:
return 1
else:
return n * factorial(n-1)
В этот странный ужас:
f=lambda n:n<1or n*f(n-1)
Хотя это может принести тебе интернет-очки на сайтах с задачами по кодированию, такой код примерно так же готов к продакшну, как шоколадный заварочный чайник. Однажды я потратил три часа на отладку кода, в котором кто-то использовал _ в качестве имени переменной… в 14 разных областях видимости. Правда.
Почему умные люди пишут глупый код
Мы все были соблазнены песней сирен об умении. Есть извращённая гордость в написании кода, который выглядит как:
cons=a=>b=>f=>f(a,b)
car=c=>c(x=>y=>x)
cdr=c=>c(x=>y=>y)
Эта элегантная реализация лямбда-исчисления прекрасна… если ты математик 1930-х годов. Для всех остальных? Это всё равно что пытаться разобрать инструкции IKEA, написанные на древнем шумерском языке. Интеллектуальные затраты накапливаются:
- Налог на отладку в 3 часа ночи: Код, который ты написал после трёх энергетиков? Даже ты не поймёшь его завтра.
- Коэффициент автобуса: Если твой код имеет смысл только в полнолуние, стоя на одной ноге, что будет, когда ты выиграешь в лотерею?
- Ловушка абстракции: Вложенные тернарные операторы могут казаться умными, пока тебе не понадобится добавить четвёртое условие.
От гольфа до горя: путешествие по рефакторингу
Давайте возьмём реальный пример из архивов плохих идей™. Рассмотрим эту проверку простых чисел:
p=lambda n:all(n%i for i in range(2,n))if n>1 else 0
Теперь давайте превратим это во что-то, что могут понять люди: Шаг 1: Добавьте настоящие имена
def is_prime(number):
if number <= 1:
return False
for divisor in range(2, number):
if number % divisor == 0:
return False
return True
Шаг 2: Добавьте защитные блоки
def is_prime(number):
if number <= 1:
return False
if number == 2:
return True
if number % 2 == 0:
return False
Шаг 3: Оптимизируйте для читабельности
def is_prime(number):
if number <= 1:
return False
if number in (2, 3):
return True
if number % 2 == 0:
return False
for divisor in range(3, int(number**0.5) + 1, 2):
if number % divisor == 0:
return False
return True
Теперь у нас есть код, который проходит тест «разработчика после бессонной ночи». Оригинальный? Он проваливает тест «автор вспомнит его в следующий вторник».
Когда умный код атакует: руководство по выживанию
- Правило резиновой утки: Если ты не можешь объяснить это игрушке для ванной, это слишком сложно.
- 24-часовой тест: Напиши умный код сегодня? Пересмотри его завтра, прежде чем коммитить.
- Порог команды: Код должен быть понятен твоему младшему разработчику, а не только твоему эго.
Парадокс чистого кода
Вот грязный секрет: написать простой код сложнее, чем написать умный код. Легче создать машину Рубе Голдберга, чем бесшовный лифт. Истинное мастерство заключается в том, чтобы сделать сложные вещи простыми, а не наоборот. Как сказал великий Брайан Керниган: «Отладка в два раза сложнее, чем написание кода с самого начала. Поэтому, если вы пишете код настолько умно, насколько это возможно, вы, по определению, недостаточно умны, чтобы его отладить». Так что в следующий раз, когда у тебя возникнет искушение написать эту 100-символьную лямбду, спроси себя: «Это код или заявка на конкурс Obfuscated C?» Твоё будущее «я» и твои коллеги будут тебе благодарны. А теперь, если ты меня извинишь, мне нужно пойти переписать код 2018 года, где я думал, что a = (b ? c : d) был читаемым… Пожелай мне удачи.