Pull to refresh

Про Swift, и почему мои большие проекты будут на Objective-C еще какое-то (возможно долгое) время

Reading time 4 min
Views 41K
Original author: Artem
От переводчика: C пятницей, дорогие хабровчане! Хочу поделиться сегодня с вами переводом статьи из небольшого блога об опыте работы с языком Swift. Вряд ли она претендует на лавры серьезного и скрупулезного анализа, но, думаю, будет интересна всем, кто задумывался: «а не пора ли отправить на свалку истории этот Objective-C?».

Когда Apple представила нам Swift — это было круто! Наконец-то мы получили next-gen (т. е. модный-скриптоподобный) язык для разработки под яблочные девайсы (но без поддержки приватных членов класса, хм....). Теперь этот [языкДинозавр квадратноскобочный] может отправиться в музей, а мы начнем тыкать эти новые блестящие фичи языка. Безусловно, наивно предполагать, что язык, которому менее года, будет без тараканов. Очевидно, некоторое время нужно дать ему на избавление от детских болячек. Именно поэтому я не бросился переписывать все мои проекты на Swift сразу после анонса.


Заметили, что птица падает вниз?


Через год после выпуска, я наконец решил выучить язык. Для этого я стал писать игрушку про самую ужасную вещь в мире (в мире Windows 3.1, окей) — монстра из игры SkiFree. Вы можете прочесть об этом здесь

Дисклеймер: я пишу о годовалом свифте. Уверен, ребята из Apple починят все эти проблемы, и язык станет очень элегантным инструментом. Ну либо же неповоротливым бегемотом вслед за XCode 7.

Вернемся к Swift. Одна ночь с книгой «The swift programming language» и я готов к свершениям. Язык очаровал меня простотой, прозрачностью конструкций и скрытой мощью, позволяющей писать безопасный код (и да, они добавили приватные члены классов). Я начал писать SripteKit игрушку и…

image

Это что серьезно? Мой проект на Objective-C в 60 тысяч строк собирается всего лишь в два раза дольше, чем мой 600-строчный Hello World на Swift. Внезапно мне вспомнились те славные времена (вообще-то всего несколько месяцев назад это было), когда я работал над огромным проектом, и картинка ниже прекрасно описывала некоторые рабочие дни:



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

В конце концов человек может привыкнуть к чему угодно. Но компилятор снова меня поразил:



Эээ… Не может сложить два float'а… хорошо…

Для тех из вас, кто уже точит свои ножи, чтобы отучить это обезьяну-кодера от работы с захардкоженными значениями и использования одновременного float и double типов в коде хочу сказать: во-первых, CGFloat ко мне пришли из UIKit, а double из стороннего кода. Так что это не слишком экзотическая ситуация, когда вам придется миксовать эти два типа. А вынос захардкоженых значений в константы помог бы коду стать более толковым, но едва ли это спасет от удивительного кульбита, которым нас порадовал компилятор. Кончено, этот мерзавец может сложить два float'а — дело-то в том, что он укрывает от меня настоящую проблему!

Знаете, я всегда воспринимал компилятор как что-то вроде старого мудрого Гендальфа, который обьясняет глупым хоббитам, как мир на самом деле устроен.



Иногда сложно понять, что этот старикан несет. Но если вдуматься, то он действительно указывает на проблему. Продолжая метафору, компилятор Swift'а, рассказывающий мне о проблеме с суммированием двух float'ов, мне больше напоминает этого торчка из фильма Хоббит.



Черный ритуал над кодом, и, наконец, он заработал. Вот зачиненный вариант:



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

Еще одна проблема, связанная с первой — низкая скорость статического анализа в сравнении с Objective-C. Было время, когда я отключал подсветку синтаксических ошибок в ХСode в реальном времени, так как я писал код гораздо быстрее, чем XCode успевал его анализировать (человек против машины: 1:0, хо-хо). Подлагивающие подсказки только раздражали меня. С покупкой нового мака анализ стал почти мгновенным — и я с огромным удовольствием стал использовать эту фичу. Но со Swift я снова встретил ту же проблему (2:1. человек побеждает).

Ну и наконец жемчужина моей коллекции:



Я многое повидал в жизни…
Я видел оптимизации компилятора, рушившие производительность из-за вставленного 'if (0) {… }' выражения
Я видел чудовищные баги, связанные с пропущенным 'volatile' ключевым словом
Я видел, какие жуткие разрушения может привнести неопределенное поведение языка

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

Это сообщение было бы очень полезным, будь оно warning'ом. Но это критическая ошибка. Так что да, вам придется упрощать это выражение. Я бы понял эту ситуацию, если бы эта ошибка вылезла для очень длинной конструкции. Но мое выражение было менее чем 120 символов длинной. Для некоторых разработчиков такая ситуация может показаться нормальной, но я был взращен с волками языков C/C++ и x86 ассемблером. Так что для меня это выглядит странно.

Что же в сухом остатке? Мы получили язык, похожий на модные Python/Go/Ruby. Но есть ли причина начинать большой проект на нем?

Дженерики? Да, это очень хорошо, но и в Objective-C теперь есть поддержка дженериков (да, уродливая, но есть). А ребята из Go вообще говорят, что им без дженериков нормально.

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

Передача обьектов по значению? Если вам нужна производительность — то C/C++ к вашим услугам. Если же вы хотите еще и при этом использовать опциональные значения, то, безусловно, на C/C++ это будет выглядеть несколько уродливо, но, тем не менее, возможно.

Так что эпл. Ну серьезно, выглядит так, будто вы создали язык только потому, что над вами смеялись из-за квадратных скобочек (!(«Пишите код, будто на разговорном английском», хехех) и YES/NO в Boolean. А какова цена? Теперь у нас язык с тормознутой сборкой и, порой, очень странным поведением компилятора.

Итак, старик сказал все, что хотел. Но вы, любители модных-скриптоподобных языков, не должны принимать мои слова слишком близко к сердцу: по сути Swift это хороший язык с неплохим дизайном. Все пробелмы, что я описал, могут быть зачинены без существенных изменений в языке, так что однажды они уйдут. Свифт — прекрасный язык для написания Hello World, но крупные проекты я пока не советую начинать на нем.
Tags:
Hubs:
+34
Comments 70
Comments Comments 70

Articles