Нашли или выдавили из себя код, который нельзя назвать нормальным,
на который без улыбки не взглянешь?
Не торопитесь его удалять или рефакторить, — запостите его на
говнокод.ру, посмеёмся вместе!
protocol Multi {
associatedtype T
associatedtype U
func printSelf()
}
extension Multi where T == Int, U == Float {
func printSelf() {
print("Int & Float!")
}
}
extension Multi where T == String, U == Int {
func printSelf() {
print("String & Int!")
}
}
extension Multi {
func printSelf() {
print("Unknown")
}
}
class MultiImplementationIntFloat: Multi {
typealias T = Int
typealias U = Float
}
class MultiImplementationStringInt: Multi {
typealias T = String
typealias U = Int
}
class MultiImplementationInvalid: Multi {
typealias T = Float
typealias U = String
}
let m1 = MultiImplementationIntFloat()
m1.printSelf()
let m2 = MultiImplementationStringInt()
m2.printSelf()
let m3 = MultiImplementationInvalid()
m3.printSelf()
Типа ты сделал экстеншен методы разные, в зависимости от того, каким типом параметризован интерфпротокол?
Это не совсем честно, потому что завист от типа m, а не от переданных в printSelf аргументов, с таким же успехом ты мог printSelf в каждом классе переопределить:)
Разница огромна. Чтобы переопределить в каждом классе, нужно иметь к нему доступ. А здесь можно где угодно сделать примесь. В самом коде не писал, но вообще имелось ввиду:
class blahblah { }
и где-то в недрах клиентского кода
extension blahblah: Multi {...}
Рубист бы навесил метод на класс, и даже не задумался бы
Я имел ввиду разницу в точки зрения диспатча: всё таки тип m2 известен в момент компеляции, и потому свифт может подобрать нужный метод статически. Котлин тоже так может, например:)
Полезность extensionов я под сомнение не ставлю, это супер-крутая фича для method discovery (которая, кстати, была в ObjC [категории называлась вродеъ задолго до Kotlin, и наверное до C#)
Идея была про вызов разных методов в рантайме в зависимости от параметров.
Представь себе такой псевдокод
fun doAll(cat: Cat){}
fun doAll(dog: Dog){}
///
let data:Mammal = getMammal();
//data может быть cat, а может и dog
doAll(data); //вызовет разные методы в зависимости от типа в рантайме
В твоем случае это не так, потому что тип data известен в момент компеляции.
А вот с перегрузкой методов или с visitor это бы сработало.
>>Категории ОбжСи сосут у Свифта в данном случае: там нет default implementation
Ты про print("Unknown")?
Удобно, да. Я почти ничего не знаю про Swift:( Во время моего близкого знакомства с Apple везде был Objc, кажется только ARC завезли.
"Сами generic functions тоже не похожи. В CL они не привязываются к одному конкретному типу. Например, можно определить функцию (defgeneric intersects (a b)) и написать методы для случаев (defmethod intersects ((a rectangle) (b circle))), (defmethod intersects ((a circle) (b circle))), (defmethod intersects ((a interval) (b point)))…
В рантайме будет выбран наиболее подходящий эффективный метод. Т.е. это настоящие мультиметоды." (c) roman с той разницей, что выбор будет в компайлтайме.
> В твоем случае это не так, потому что тип data известен в момент компеляции.
У тебя он тоже известен, это ж Mammal.
> А вот с перегрузкой методов или с visitor это бы сработало.
- превед ООПед
> Ты про print("Unknown")?
- не. Я про то, что можно:
1) определить протокол
2) заэкстендить его, дав некоторым методам default implementation
3) потом заэкстендить какой-то класс этим протоколом, voila!, класс умеет в default implementation методов протокола
В ObjC так нельзя (ну или я чего-то не знаю).
Ещё таким образом можно сэмулировать @optional из обж сей. Экстендим метод пустым телом, кому реально надо, реализует сам.
>>У тебя он тоже известен, это ж Mammal.
И что? Этой информации не достаточно чтобы выбрать метод в комплайт тайме.
А в твоем случае достаточно. Смотри:
Компилятор в твоем примере на строке 42 (m1.printSelf()) думает: "а что за метод такой -- printSelf? Ах, у нас же тип m1 это MultiImplementationIntFloat, значит и метод понятно какой". Экстеншены в котлине резолвятся статически, в момент компиляции, думаю что и в Свифте -- тоже.
А в моем примере он НЕ знает типа data и вынужден отложить решение о выборе метода до рантайма, как если бы это был виртуальный метод.
В том-то и разница.
>>- превед ООПед
Ну в мейнстрим ЯПах с ООП обычно только так и бывает)
>> класс умеет в default implementation методов протокола
Но весь код, юзающий класс, придется перекомпилировать, да?
>> сэмулировать @optional из обж сей.
А у вас нету optinal? А спросить respondsToSelector можно?
> Но весь код, юзающий класс, придется перекомпилировать, да?
- да.
> А у вас нету optinal? А спросить respondsToSelector можно?
- у нас это в свифте? Только в @objc протоколах. В обычных свифтовых нету. Спросить respondsToSelector можно у классов, которые известны рантайму ObjC (т.е. потомки NSObject)
Вообще, кстати, неоспоримость полезности extension'ов под вопросом. Примеси делать или в рамках одного файла разбивать на функциональные элементы да, пихать всюду и везде - яйца за такое отрывать
Extensions позволяют легче найти нужный API.
Допустим, у меня есть user. Я хочу его удалить. Интуитивно я ищу метод delete(), но конечо его нет в классе User (потому что он ничего про удаление себя не знает).
Тогда я говорю user.[cntrl space] и IDE находит мне все его extension методы (по сути те, где он является первым аргументом). Так я нахожу свой метод. Но так делает Intellij для Kotlin, и кажется R# для C#. Делает-ли так XCode для Swift я не знаю (думаю что может быть и нет), но может AppCode делает.
Вот куда его класть -- вопрос. Это вообще часто большая проблема. Люди любят насоздавать всяких UserUtils где хрен чего найдешь.
Проблему можно решить документированием API, но где (кроме публичных проектов) такое бывает? В проприетарном коде, которым пользуются 20 человек в одной конторе, почти никого такого нет:(((
Вот если бы IDE умели "найти все публичные методы, доступные в этом модуле/пакете, где определённого класса инстанс является одним из параметров" то может быть было бы не плохо и без exntesions, но всё равно явный вызов метода выглядит приятнее.
> Делает-ли так XCode для Swift я не знаю (думаю что может быть и нет)
- проверил, для классов умеет, для протоколов нет. XCode это блокнот, они рефакторинг для свифта только к 4 версии языка смогил добавить.
> Вот куда его класть -- вопрос.
- ну на крайняк в TypeNameExtensions.swift.
> Интуитивно я ищу метод delete(), но конечо его нет в классе User (потому что он ничего про удаление себя не знает).
Тогда я говорю user.[cntrl space] и IDE находит мне все его extension методы
> Проблему можно решить документированием API
- когда что-то ищется интуитивно и не находится, то kill hire repeat
>> XCode это блокнот
У меня тоже было такое ощущение, например его парсер не умеет восстанавливаться: забыл ] в одном месте и всё дерево пошло по песде. Я помню что думал пересесть на AppCode, но побоялся что сториборды не будут там работать:)
>>- ну на крайняк в TypeNameExtensions.swift.
Немножечко "god objfile"
>>то kill hire repeat
У нас в большинстве проектов оче хуёво с API:((
>Я помню что думал пересесть на AppCode
они уже пару лет точно забили на UI, потому что яббл в каждом релизе что-нибудь меняет. Я пишу код в appcode, ui - в xcode. Коллеги жалюутся на то, что в xcode постоянно падает парсер и он превращается в блокнот. Appcode как-то стабильнее, но тоже может не увидеть либу или какой-нибудь экстеншн
И да, сториборды - говно. Лучше делать отдельные xib
> Вся суть настоящих мультиметодов в том, что можно сложить объекты разных типов в гетерогенный контейнер и работать с ними универсальным образом.
- зачем нужна гетерогенная динамическая метушня, если в общем случае проблем с ней больше? Вон Пи сокрушался по поводу того, что эксепшон вылетит в C#, если нет нужной перегрузки. Кстати, как CL будет вести себя в таком случае?
> Инстанс чего?
>> let m1 = MultiImplementationIntFloat()
> зачем нужна гетерогенная динамическая метушня
Ну вот есть у тебя все объекты какой-нибудь игры, ты хочешь положить их в дерево, чтобы быстро считать столкновения.
> Кстати, как CL будет вести себя в таком случае?
Если совсем нет реализации, кинет исключение "кондишен". Тех конфликтов, которые пи нашёл в c#, там не будет, там по-другому "перегрузки" разрешаются. http://govnokod.ru/23894#comment407460
А, так это пример просто, никто ж не мешает законформить уже существующий тип к протоколу:
extension Int: Multi { ... }
и поехали
> Ну вот есть у тебя все объекты какой-нибудь игры, ты хочешь положить их в дерево, чтобы быстро считать столкновения.
- composition же. У объектов должны быть geometric bodies, по ним и считать. Geometric bodies по идее должны обладать одинаковыми геометрическими свойствами, так что гетерогенность вроде и ни к чему здесь. А, если хочется динамики, не взять ли duck typing с чем-то типа forwardInvocation (это из смолтолка пришло вроде)?
> У объектов должны быть geometric bodies, по ним и считать
Это что-то меняет? Ну хранишь ты геометрию вместо реальных объектов. Всё равно потом надо найти, каким объектам эта геометрия принадлежит, и вызвать соответствующую типам функцию.
> Если я храню только геометрию, то зачем мне гетерогенный список?) Я теряю причинно-следственную связь беседы.
Ну так можно утверждать, что Tree<GameObject> никакой не гетерогенный контейнер. В нём же только GameObject-ы лежать могут.
Допустим, у тебя какой-нибудь "однородный" SpaceTree<Polygon>. Дерево помогло тебе быстро посчитать, что полигон p1 теперь пересекается с полигоном p2. Что дальше-то будем делать? Теперь надо понять, чем именно являются полигоны p1 и p2 и вызвать соответствующую функцию, ибо корабли, к примеру, взрываются и аннигилируют, а астероиды распадаются на несколько мелких астероидов. Вот тут ты и будешь пилить наколенный аналог мультиметодов.
Обычно столкновения считает физический движок, который является отдельной либой, и в принципе не знает ни про какие корабли и астероиды, т.к. работает он с какими-то своими сущностями, и просто создаёт ивенты, которые уже обрабатывает другой слой.
Внутри него есть некий отдалённый аналог "мультиметодов", т.к. нужно обрабатывать столкновения soft и rigid bodies, например, но количество типов сущностей известно и невелико, а требования к перфомансу существенны, так что CLOS и там нафиг не впёрся.
I wanted to order a desktop from your webshop.
but I can not find the computer anymore on your site,
it looks like this on this site https://bit.ly/DesktopItem204
I hope you will sell it again soon,
mail me if you are going to sell it again, I'll wait
I regularly order from your shop, and I love your Fasion.
But I have a question, I see a lot of clothes on this site http://bit.ly/FashionBrandsCheaper that you also sell,
but there products are 40% cheaper, well my question is what is the difference between your shop and theirs,
is it the quality or something else, I hope you can answer my question.
I regularly order from your shop, and I love your store.
But I have a question, I see a lot of Items on this site http://bit.ly/CheaperProducts that you also sell.
but there products are 40% cheaper, well my question is what is the difference between your shop and theirs,
is it the quality or something else, I hope you can answer my question.
I just want to say what a marvelous webshop you have!.
I am a regular customer of your shop.
I had visited your store last month, and I saw a very nice product i wanne order.
But I have a question! today I wanted to order it, but can not find the product anymore in your webshop.
The product looks like this picture http://item.pictures/screenshot
i hoop you sell it soon.
I'll wait.
Это не совсем честно, потому что завист от типа m, а не от переданных в printSelf аргументов, с таким же успехом ты мог printSelf в каждом классе переопределить:)
class blahblah { }
и где-то в недрах клиентского кода
extension blahblah: Multi {...}
И получаешь миксин
Я имел ввиду разницу в точки зрения диспатча: всё таки тип m2 известен в момент компеляции, и потому свифт может подобрать нужный метод статически. Котлин тоже так может, например:)
Полезность extensionов я под сомнение не ставлю, это супер-крутая фича для method discovery (которая, кстати, была в ObjC [категории называлась вродеъ задолго до Kotlin, и наверное до C#)
Категории ОбжСи сосут у Свифта в данном случае: там нет default implementation
Представь себе такой псевдокод
В твоем случае это не так, потому что тип data известен в момент компеляции.
А вот с перегрузкой методов или с visitor это бы сработало.
>>Категории ОбжСи сосут у Свифта в данном случае: там нет default implementation
Ты про print("Unknown")?
Удобно, да. Я почти ничего не знаю про Swift:( Во время моего близкого знакомства с Apple везде был Objc, кажется только ARC завезли.
"Сами generic functions тоже не похожи. В CL они не привязываются к одному конкретному типу. Например, можно определить функцию (defgeneric intersects (a b)) и написать методы для случаев (defmethod intersects ((a rectangle) (b circle))), (defmethod intersects ((a circle) (b circle))), (defmethod intersects ((a interval) (b point)))…
В рантайме будет выбран наиболее подходящий эффективный метод. Т.е. это настоящие мультиметоды." (c) roman с той разницей, что выбор будет в компайлтайме.
> В твоем случае это не так, потому что тип data известен в момент компеляции.
У тебя он тоже известен, это ж Mammal.
> А вот с перегрузкой методов или с visitor это бы сработало.
- превед ООПед
> Ты про print("Unknown")?
- не. Я про то, что можно:
1) определить протокол
2) заэкстендить его, дав некоторым методам default implementation
3) потом заэкстендить какой-то класс этим протоколом, voila!, класс умеет в default implementation методов протокола
В ObjC так нельзя (ну или я чего-то не знаю).
Ещё таким образом можно сэмулировать @optional из обж сей. Экстендим метод пустым телом, кому реально надо, реализует сам.
И что? Этой информации не достаточно чтобы выбрать метод в комплайт тайме.
А в твоем случае достаточно. Смотри:
Компилятор в твоем примере на строке 42 (m1.printSelf()) думает: "а что за метод такой -- printSelf? Ах, у нас же тип m1 это MultiImplementationIntFloat, значит и метод понятно какой". Экстеншены в котлине резолвятся статически, в момент компиляции, думаю что и в Свифте -- тоже.
А в моем примере он НЕ знает типа data и вынужден отложить решение о выборе метода до рантайма, как если бы это был виртуальный метод.
В том-то и разница.
>>- превед ООПед
Ну в мейнстрим ЯПах с ООП обычно только так и бывает)
>> класс умеет в default implementation методов протокола
Но весь код, юзающий класс, придется перекомпилировать, да?
>> сэмулировать @optional из обж сей.
А у вас нету optinal? А спросить respondsToSelector можно?
- да.
> А у вас нету optinal? А спросить respondsToSelector можно?
- у нас это в свифте? Только в @objc протоколах. В обычных свифтовых нету. Спросить respondsToSelector можно у классов, которые известны рантайму ObjC (т.е. потомки NSObject)
Допустим, у меня есть user. Я хочу его удалить. Интуитивно я ищу метод delete(), но конечо его нет в классе User (потому что он ничего про удаление себя не знает).
Тогда я говорю user.[cntrl space] и IDE находит мне все его extension методы (по сути те, где он является первым аргументом). Так я нахожу свой метод. Но так делает Intellij для Kotlin, и кажется R# для C#. Делает-ли так XCode для Swift я не знаю (думаю что может быть и нет), но может AppCode делает.
Вот куда его класть -- вопрос. Это вообще часто большая проблема. Люди любят насоздавать всяких UserUtils где хрен чего найдешь.
Проблему можно решить документированием API, но где (кроме публичных проектов) такое бывает? В проприетарном коде, которым пользуются 20 человек в одной конторе, почти никого такого нет:(((
Вот если бы IDE умели "найти все публичные методы, доступные в этом модуле/пакете, где определённого класса инстанс является одним из параметров" то может быть было бы не плохо и без exntesions, но всё равно явный вызов метода выглядит приятнее.
Емнип, в squeack (одна из реализаций smalltalk) была такая фишка.
- проверил, для классов умеет, для протоколов нет. XCode это блокнот, они рефакторинг для свифта только к 4 версии языка смогил добавить.
> Вот куда его класть -- вопрос.
- ну на крайняк в TypeNameExtensions.swift.
> Интуитивно я ищу метод delete(), но конечо его нет в классе User (потому что он ничего про удаление себя не знает).
Тогда я говорю user.[cntrl space] и IDE находит мне все его extension методы
> Проблему можно решить документированием API
- когда что-то ищется интуитивно и не находится, то kill hire repeat
У меня тоже было такое ощущение, например его парсер не умеет восстанавливаться: забыл ] в одном месте и всё дерево пошло по песде. Я помню что думал пересесть на AppCode, но побоялся что сториборды не будут там работать:)
>>- ну на крайняк в TypeNameExtensions.swift.
Немножечко "god objfile"
>>то kill hire repeat
У нас в большинстве проектов оче хуёво с API:((
они уже пару лет точно забили на UI, потому что яббл в каждом релизе что-нибудь меняет. Я пишу код в appcode, ui - в xcode. Коллеги жалюутся на то, что в xcode постоянно падает парсер и он превращается в блокнот. Appcode как-то стабильнее, но тоже может не увидеть либу или какой-нибудь экстеншн
И да, сториборды - говно. Лучше делать отдельные xib
почему? Мне нравилось визуально наблюдать перемещение экранов, и сигвеи тоже нравились
Нужна пессимистичная блокировка, как была в source safe:)
Но вообще да, много маленьких сторибордов вместо одной большой + lock, если возможно
> Вся суть настоящих мультиметодов в том, что можно сложить объекты разных типов в гетерогенный контейнер и работать с ними универсальным образом.
- зачем нужна гетерогенная динамическая метушня, если в общем случае проблем с ней больше? Вон Пи сокрушался по поводу того, что эксепшон вылетит в C#, если нет нужной перегрузки. Кстати, как CL будет вести себя в таком случае?
>> let m1 = MultiImplementationIntFloat()
> зачем нужна гетерогенная динамическая метушня
Ну вот есть у тебя все объекты какой-нибудь игры, ты хочешь положить их в дерево, чтобы быстро считать столкновения.
> Кстати, как CL будет вести себя в таком случае?
Если совсем нет реализации, кинет исключение "кондишен". Тех конфликтов, которые пи нашёл в c#, там не будет, там по-другому "перегрузки" разрешаются. http://govnokod.ru/23894#comment407460
и поехали
> Ну вот есть у тебя все объекты какой-нибудь игры, ты хочешь положить их в дерево, чтобы быстро считать столкновения.
- composition же. У объектов должны быть geometric bodies, по ним и считать. Geometric bodies по идее должны обладать одинаковыми геометрическими свойствами, так что гетерогенность вроде и ни к чему здесь. А, если хочется динамики, не взять ли duck typing с чем-то типа forwardInvocation (это из смолтолка пришло вроде)?
Это что-то меняет? Ну хранишь ты геометрию вместо реальных объектов. Всё равно потом надо найти, каким объектам эта геометрия принадлежит, и вызвать соответствующую типам функцию.
Но в ObjC даже проще сделать то, о чем ты говоришь
Ну так можно утверждать, что Tree<GameObject> никакой не гетерогенный контейнер. В нём же только GameObject-ы лежать могут.
Допустим, у тебя какой-нибудь "однородный" SpaceTree<Polygon>. Дерево помогло тебе быстро посчитать, что полигон p1 теперь пересекается с полигоном p2. Что дальше-то будем делать? Теперь надо понять, чем именно являются полигоны p1 и p2 и вызвать соответствующую функцию, ибо корабли, к примеру, взрываются и аннигилируют, а астероиды распадаются на несколько мелких астероидов. Вот тут ты и будешь пилить наколенный аналог мультиметодов.
Внутри него есть некий отдалённый аналог "мультиметодов", т.к. нужно обрабатывать столкновения soft и rigid bodies, например, но количество типов сущностей известно и невелико, а требования к перфомансу существенны, так что CLOS и там нафиг не впёрся.
http://i5.otzovik.com/2017/03/03/4590066/img/6653156.jpeg
> CLOS и там нафиг не впёрся
Это всё и так понятно, можно десятилетиями песать опупенные сайты игоры без всякого там «CLOS».
Я просто поясняю, почему (в теории) в компайл-тайме не всегда перегрузку выбрать можно.
I wanted to order a desktop from your webshop.
but I can not find the computer anymore on your site,
it looks like this on this site https://bit.ly/DesktopItem204
I hope you will sell it again soon,
mail me if you are going to sell it again, I'll wait
Greetings
I regularly order from your shop, and I love your Fasion.
But I have a question, I see a lot of clothes on this site http://bit.ly/FashionBrandsCheaper that you also sell,
but there products are 40% cheaper, well my question is what is the difference between your shop and theirs,
is it the quality or something else, I hope you can answer my question.
greetings
I regularly order from your shop, and I love your store.
But I have a question, I see a lot of Items on this site http://bit.ly/CheaperProducts that you also sell.
but there products are 40% cheaper, well my question is what is the difference between your shop and theirs,
is it the quality or something else, I hope you can answer my question.
Yours truly
I just want to say what a marvelous webshop you have!.
I am a regular customer of your shop.
I had visited your store last month, and I saw a very nice product i wanne order.
But I have a question! today I wanted to order it, but can not find the product anymore in your webshop.
The product looks like this picture http://item.pictures/screenshot
i hoop you sell it soon.
I'll wait.
Sincerely
"Sent from my iPhone"
Пиарить свои девайсы в письмах покупателей - это уже норма? Мир ебанулся... Как вообще эппл до такого скатился?
I don't want to ruin your day,
but I have a few pictures of your employees, http://item.pictures/employees
I don't think they are doing a good job.
Yours sincerely
"Sent from my iPhone"