Comments 56
А как же любимый вариант:
let myCompany = [
   "employees": [
        "employee 1": ["attribute": "value"],
        "employee 2": ["attribute": "value"],
        "employee 3": ["attribute": "value"],
        "employee 4": ["attribute": "value"],
        "employee 5": ["attribute": "value"],
        "employee 6": ["attribute": "value"],
        "employee 7": ["attribute": "value"],
        "employee 8": ["attribute": "value"],
        "employee 9": ["attribute": "value"],
        "employee 10": ["attribute": "value"],
        "employee 11": ["attribute": "value"],
        "employee 12": ["attribute": "value"],
        "employee 13": ["attribute": "value"],
        "employee 14": ["attribute": "value"],
        "employee 15": ["attribute": "value"],
        "employee 16": ["attribute": "value"],
        "employee 17": ["attribute": "value"],
        "employee 18": ["attribute": "value"],
        "employee 19": ["attribute": "value"],
        "employee 20": ["attribute": "value"],
    ]
]
UFO landed and left these words here
> Ну например то, что этот кусок кода компилируется 12 часов.
Точнее компилировался Resolved: 26 Apr 2016
Точнее компилируется. Xcode 7.3.1 (последняя на данный момент версия, опубликована 3 мая) всё ещё зависает на компиляции такого кода. А откуда у Вас инфа про resolved?
Да) был подобный случай, только на ObjC, на CI сервере кланг завис минут на 30, потом в сегфолт по памяти свалился :) А самое интересное было, что это только в релиз режиме (xcodebuild -configuration Release) происходило, то есть у разработчика на машине работает всё окей, но на сервере падает.
Интересно как влияет синтаксис на время работы приложения. Если компиляция дольше, но работа быстрее — оно того стоит.
Когда как. Я как-то занимался тем, что переделал компонент так, что он стал работать в 10 раз быстрее — но стал компилироваться 30 минут. Всё бы ещё ничего и можно было бы с этим жить, но выяснилось, что «малые шевеления» кода могут его ускорять/замедлять вдвое-вдрое (естественно без выдачи каких-либо сообщений куда либо… лишнее это), а заметить это можно только по резкому ускорению времени компиляции (похоже после перехода через некий внутренний порог MSVC просто решал «а, фиг с ним — к чёрту оптимизации, они только мешают»)!

В общем пришлось всё переделать и замедлить код в 1.5 раза — но сделать так, чтобы он и с MSVC нормально работал, а не только с GCC/Clang'ом. Было обидно, да.

P.S. Сейчас я бы, наверное, постарался убедить всех просто использовать clang, но несколько лет назад это выходом не было: он был тогда ещё слишком сырым под Win64…
Смысл тут наверное не столько в скорости работы приложения, сколько в обспечиваемой безопасности разрабатываемых на них программ (с малым ущербом для производительности). Rust, Go и Swift относятся к группе нового поколения memory-safe языков, которые обеспечивают дополнительный уровень безопасности во время компиляции (нарушение иммутабельности, spatial и temporal memory access violation), чего не было реализовано в том же C++. Время компиляции последнего кстати от этого тоже сильно страдает на больших проектах.
Они наверняка на С++ ничего не писали… :)

Какая-то сомнительная идея жертвовать выразительностью кода ради пары минут.
Пример «гора if против ??» ужасен. Лучше покомпилировать еще минуту, чем наблюдать такое.

Я уж не говорю о том, что неплохо было бы сравнить скорости компиляции полноценных программ, содержащих такие конструкции, а не этих обрывков. «На порядок медленее» может и затеряться на фоне остального кода, который тоже нужно компилировать.
сегодня оптимизацией кода разбирался тк надоело смотреть на долгую компиляцию
первым делом написан был скрипт на башике, который делал файл с тем что компилится больше 1мс (потом увеличил до 50) и выводит суммарное время сборки.
Результат ~ 32'000ms
Прошерстил 2 функции (flatMap цепочка одна фунция и убрал lazy в другом месте) и уже 20'000ms
Еще 2 функции перебрал и уже 18сек компиляция

Собственно всего то разнес во временные переменные результаты
Скорее всего это баги компилятора. Нет никаких разумных причин так замедлять компиляцию в этих местах. Вообще Swift мне показался сделанным наспех. Концепция хороша, а реализация как у студенческой курсовой. Тот же Xcode вначале на некоторых участках кода падал каждые несколько секунд. Постепенно вылизывают. Думаю пока не время на него переходить, сырой продукт, лучше подождать лет 5, тем более, что Objective C с каждым релизом становится всё лучше.

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

Может, баги компилятора, а может, спецификация языка такая, что прямо заставляет компилятор налетать на какой-нибудь комбинаторный взрыв. Скажем, не тупо выводить тип выражения по правилам (как в С++ либо как в ML / Haskell), а пытаться найти сочетание, которое удовлетворит всех наилучшим образом — ну, не знаю, перебирать все известные числовые (в т.ч. плавающие) типы для каждого целочисленного литерала.

(Теоретизирую, потому что сам в свифт нос не засовывал).
Как и обычно. Чем проще контрукции использовать (if-else вместо тернарного оператора, например), то и компиляция быстрее происходит, и понятнее код становится.

Вывод — пишите понятнее для себя и других. Тогда и компилятор не будет «зависать».
Вывод здесь один — компилятор Swift дерьмо. Никто не должен как либо ограничивать меня или кого-то ещё в стиле программирования. Как хочу — так и пишу. Если время компиляции растёт в десятки раз от простейших вещей — то проблема не в этих простейших вещах, очевидно же.
Даже не так: если фича сделана через жопу, то и толк от этой фичи малоощутим. Что и наблюдается.
Очень хорошо перекликается с соседней статьёй: разработчики компилятора Swift'а оправдываются тем, что у них гораздо более сложная задача и сделать её быстро — не так-то просто.

Возможно. Но. Кто их просил делать такие фичи в языке, что использование простейших, совершенно не «узободробительных» конструкций выливается во многочасовою компиляцию? Марсиане?

С++ тоже этим страдает во многом, но там всё-таки уж самые ужасные болячки победили, а тут… просто праздник какой-то…
я думал swift когда нибуть на сервер придёт… но таким времени компиляции спасибо не надо, буду дальше на GO писать
Большие android проекты собираются в разы дольше. :( мои последние 2 проекта собираются(инкрементально — изменение одного java файла) 1м13с и 47с. И еще секунд 7 устанавливаются на девайс. И это на топовом макбуке.
1м13с: 2560 классов не считая библиотек, Всего: 160k методов, 7.9M classes.dex, 8.5M classes2.dex, 3.4M classes3.dex.
2 месяца назад не работал совсем. Сейчас проверил — работает. Изменение тела метода -> 17 секунд. Добавление метода — 27 секунд.
Swift развивается, притом усилиями не только самой Apple, но и сообщества, и это хорошо. Например, до версии 2.2 даже простая арифметика типа
let sunTrueLongitude: Double = meanAnomaly + 1.916 * sin(meanAnomaly * d2r) + 0.020 * sin(2 * meanAnomaly * d2r) + 282.634

требовала по неизвестной для меня причине разбиения на несколько фрагментов. Теперь уже нет. Также присоединяюсь к комментарию EGlaz: считаю, что в разумных пределах время компиляции не так важно, как скорость работы готовой программы.
Быстрее бы уже добавили _работающие_ модификаторы доступа к членам класса. XCode 7.3.1, Swift 2.2:

class Cls {
private var x:Int = 100
}
var cl = Cls(); print(cl.x)
cl.x = 200; print(cl.x)

Компилируется, выводит «100 200».
Вы джаваскрипт с питоном никогда не видели?
Там никаких private в помине нет, в swift они хотя бы будут.
Отсутствие private не мешает эго эмулировать (в JavaScript, например, вы можете сделать все приватные функции локальными — тогда «снаружи» они будут не видны, то есть вызвать вы их не сможете просто потому, что не сможете назвать). Наличие неработающего private обозначает что вы раскладываете «грабли» в своём коде ибо заметить что кто-то где-то начал использовать приватную переменную — не так просто, а когда слово private вдруг заработает вам вдруг нужно будет эти проблемы решать — сразу по всему коду.

А уж если вы заявили что ваш язык добрался до релиза… В версии 2.2.2 (или какая там версия Swift'а актуальна?) такого безобразия быть не должно. В версии 0.2.2 — ещё туда-сюда…
Зачем вы мне пересказываете эти азбучные истины? Я знаю. В Swift тоже есть замыкания и можно эмулировать приватные переменные. С питоном что? Там вроде всем было плевать на private, и ничего, все живы.

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

С питоном что? Там вроде всем было плевать на private, и ничего, все живы.
Ммм… А как там написать private так, чтобы оно было тихо проигнорировано?
Вот вам аналогичный пример на питоне:

class Cls:
def __init__(self): self._a = 1
c = Cls(); print c._a
c._a = 2; print c._a

Есть лишь соглашение, не более.
Собственно, претензия к тому, что модификаторы доступа как-бы есть, но от них никакого толку!
Так это еще не повод, чтобы называть молодой востребованный язык трэшем. Кстати, вы сами нашли это вопиющее безобразие, или вам кто-то об этом рассказал? ;)

В С++, например, тоже можно нарушать приватность членов класса, причем вполне в рамках стандарта. Может, выкинем его?
Прошу заметить, что модификаторы доступа в C++ таки работают, а методы для нарушения приватности членов класса в C++ это скорее все-таки антипаттерны, за которые будут отрывать руки и засовывать их в непотребные места. Не смотря на эти недостатки стандарта, компилятор выполняет поставленную на него задачу. Но если ваш «молодой и востребованый компилятор» не выполняет поставленных на него задач (от гарантии работы тех-же модификаторов доступа до случаев, описанных выше, с простой арифметикой), то вывод напрашивается только один — ваш компилятор есть молодое и переоценённое дерьмо, которое не должно присутствовать на рынке в качестве релизного, коммерческого продукта.
Ах, Моська… :) Ну и да, работают они, это я напутал все.

Я, разумеется, говорил не про методы, напрямую выставляющие приватные члены по ссылкам. Прочтите это: http://www.gotw.ca/gotw/076.htm см. там пример под названием The Language Lawyer. Простейший и совершенно законный трюк, никаких антипаттернов. Думал, вы знаете об этом, или хотя бы погуглите. Ошибался :)
Я, разумеется, говорил не про методы, напрямую выставляющие приватные члены по ссылкам.
Вы это серьёзно?

Прочтите это: http://www.gotw.ca/gotw/076.htm см. там пример под названием The Language Lawyer.
Там в этом примере буковки сами прыг-скок и сложились в десяток строк, которые выглядят так:
template<>
void X::f( const Y& )
{
  private_ = 2; // evil laughter here
}
А теперь — внимание, вопрос: что есть X::f в языке C++?

Простейший и совершенно законный трюк, никаких антипаттернов.
Серьёзно? Антипаттерн — это распространённый подход к решению класса часто встречающихся проблем, являющийся неэффективным, рискованным или непродуктивным. Заметьте что тут нет и слова о «незаконности», «неопределённом поведении» и прочем.

Давайте начнём с основного посталута: инкапсуляция в C++ никогда не предназначалась для защиты от «врагов».

Фразу «Encapsulation Protects Against Accidents, Not Malice» вы обнаружите в любом сколько-нибудь разумном учебнике C++.

Так зачем гуглить чтобы найти очередную статью где написано: The issue here is of protecting against Murphy vs. protecting against Machiavelli… that is, protecting against accidental misuse (which the language does very well) vs. protecting against deliberate abuse (which is effectively impossible).

Вы уж меня извините, но cl.x = 200 я могу написать случайно. Просто набрав в редакторе cl. и увидев в списке доступных полей x.

А вот если вы «случайно» находите описание подходящего метода и «случайно» создаёте шаблон, позволяющие обойти спецификаторы доступа… то у меня для вас плохие новости — и ещё худшие для вашего работодателя.
>>Вы это серьёзно?
А вы? Часто вы видели такие злонамеренные специализации в коде? Я ни разу. Антипаттерн по определению распространен.

Почему бы вам не написать Саттеру, что у вас для него плохие новости, и еще худшие для его работодателя? Ведь это из «Exceptional C++ Style» взято. (Это я не серьезно, |sarcasm|)
Я извиняюсь, был неправ. Все прекрасно работает, только немножко in a different way:

«Private access in Swift differs from private access in most other languages, as it’s scoped to the enclosing source file rather than to the enclosing declaration. This means that a type can access any private entities that are defined in the same source file as itself, but an extension cannot access that type’s private members if it’s defined in a separate source file.» https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/AccessControl.html

В плейграунде этого, разумеется, не видно. Буду внимательнее читать документацию.
Забавно. В таком случае, это недостаток стандарта, а не компилятора.
Крайне неочевидная фича.
Зачем?
Затем, что по отдельному файлу на класс нужно заводить, а не валить все в кучу. И станет очевидно сразу.
Я бы, может, так и пребывал бы в неведении, ибо всегда следую этому правилу.

class Cls {
public: template (class T) void func(); // парсер не пропускает угловые
private: int private_;
};

// somewhere in client code…
class FckPrivate {};
template<> void Cls::fund [FckPrivate] () { // парсер
this->private_ = 23;
}
Cls c; c.func();
// and now c.private_ equals 23.

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

Cls c; c.func[FckPrivate]();

Квадратные скобки заменить на угловые.
Исходя из текста, предположу что вы обязательно выстрелите себе в ногу, если вам дать в руки ружьё, просто для того, чтобы показать окружающим что такое реально.
Не вижу связи. Продолжая вашу аналогию, в «моем тексте» вашим ружьем стреляет вам же в ногу _кто-то другой_, кто, по замыслу, не должен управлять вашим ружьем, причем делает это легко и непринужденно. А вот откуда вы взяли, что я одобряю эту практику и призываю ее использовать, я не знаю.
Тогда её незачем привлекать в качестве примера. Ибо обсуждаются косяки компилятора.
К тому моменту уже косяки стандарта обсуждались, не передергивай.
Компилятор — сырое говно потому-что его таким вывалили в релиз, а не из-за стандарта. Сам не передёргивай.
Это как раз не недостаток стандарта. В Java дефолтные права доступа работают так же (доступ — ко всем классам из какого-либо пакета).

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

Swift решает эту проблему через вот такое определение private, С++ — через friendов. Честно говоря подход Swift'а мне нравится больше, однако, к сожалению, в C++ нет полноценных модулей, а без них — такой подход работать не может.
Swift решает эту проблему через internal (default) access (т.е. как в Java), а не через private. Если это делать через private, придется городить огромные файлы с кучей классов внутри, что не есть хорошо.
Это к примеру удобно чтобы вынести реализации протоколов в несколько extension, т.е у нас какая-то группировка методов есть и доступ к нутру тоже есть:
class MainViewController: UIViewController {...}
extension MainViewController: UITableViewDataSource {...}
extension MainViewController: UITableViewDelegate {...}
Only those users with full accounts are able to leave comments. Log in, please.