Здравствуйте, hattab, Вы писали:
H>Ты хочешь сказать, что отсутствие документации по внутренним интерфейсам это проблема нативного кода? Я тебя правильно понял?
Может слышал про рефлектор? Позволяет ходить по управляемому коду без наличия исходников и понять как использовать те или иные интерфейсы при нулевом уровне документации.
H>Возможно у кого то действительно батхерт от сего факта, но лично я тут говорю о гуе, который на WPF лишь частично
Тебе что и говорят — тупо нет ресуров чтобы нафиг все разом на managed-код перевести.
Здравствуйте, hardcase, Вы писали:
h> H>Ты хочешь сказать, что отсутствие документации по внутренним интерфейсам это проблема нативного кода? Я тебя правильно понял?
h> Может слышал про рефлектор? Позволяет ходить по управляемому коду без наличия исходников и понять как использовать те или иные интерфейсы при нулевом уровне документации.
Это теперь является оправданием отсутствия документации что-ли?
h> H>Возможно у кого то действительно батхерт от сего факта, но лично я тут говорю о гуе, который на WPF лишь частично
h> Тебе что и говорят — тупо нет ресуров чтобы нафиг все разом на managed-код перевести.
Так прикол же, Object browser менеджед, а дерево и ричедит в нем нативные . То есть на остальные контролы (в Object browser'е) ресурсов хватило, а на эти два нет
On 20.07.2011 22:26, Курилка wrote:
> MZ>Как бы не понравится сложно: Java уже давно > MZ>плесенью покрылась, и не в один слой. > MZ>Что там у них Гай Стил делает -- не понимаю. > > А ты разве не в курсе? Давно уже Fortress <http://projectfortress.java.net/> делает
Здравствуйте, Cyberax, Вы писали:
C>Авторазвёртывание вполне определено и удобно
Авторазвертывание это грабли. Собственно, nullable-ссылки — это и есть option с авторазвертыванием и первоклассная головная боль.
C>В Kotlin'е сделали всё правильно.
Нет, там сделали какой-то набор ad-hoc подпорок, хотя все это должно решаться средствами языка.
C>А ошибку компиляции здесь сделать трудно, так как equals() обязан работать с объектами разного типа.
Кому он обязан-то? Если в язык вводятся АТД, то и сранение обычно делают структурным, а не ссылочным. В данном случае, разумеется, сравнивать значения разных типов — бессмысленно:
nemerle:
- Some(4) == 4;;
error: comparing values of types option.Some[int-] and int with reference equali
ty
hint: upcast one of the values to object if this is desired
f#:
> Some 4 = 4;;
Some 4 = 4;;
---------^
stdin(1,10): error FS0001: This expression was expected to have type
int option
but here has type
int
Не понятно, о чем авторы scala вообще думали.
Добиться скаловского (добавляем в язык "атд" а потом делаем вид что забыли об этом) поведения в этих языках можно только скастив значения к Object
> (Some 4 :> obj) = (4 :> obj);;
val it : bool = false
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Здравствуйте, Cyberax, Вы писали:
C>Option уродский из-за того, что "Some(4)==4" будет false. Без всяких ошибок во время компиляции.
Да, это они зря от Java унаследовали. Ошибка компиляции, или хотя бы предупреждение здесь не помешали бы. А вот писать авторазвёртывание исключительно для Option — переусложнять язык.
C>>>7) Именованные параметры, в том числе для туплов. M>>Что имеется в виду? C>
C>//Пример 1
C>def getPoint = (x=1,y=2,z=3)
C>val f = getPoint()
C>println(f.x);
C>//Пример 2
C>case class GeoPosition(val degLat : Int, val degLong : Int,
C> val height : Int, val minutesLat : Int, val minutesLong : Int, val ts : Timestamp);
C>x match {
C> case GeoPosition(_, _, _, 11) => println("Высота 11 метров!!");
C>//Упс. Слегка промахнулись. Это не высота, а минуты широты.
C>...
C>}
C>
def getPoint = new {val x = 1; val y = 2; val z = 3}
val f = getPoint
println(f.x)
Это называется не тапл, а structural type.
Вo втором примере ошибка компиляции: кол-во параметров не совпадает. Но смысл ясен: именованные параметры в pattern matching не используются. Разговоры ходили, но будут делать или нет неясно. Пока же вместо case GeoPosition(height=11) писать case _ if x.height == 11. Ну или миллион других столь же уродливых способов, впрочем худо-бедно решающих свою задачу.
PM синтаксически тяжёл в Scala. Эти лишние case просто выносят мозг, потом невозможность сразу писать PM по аргументам, type inference, который подводит в самых неожиданных местах, приходится дописывать типы. Замечательно, если в Kotlin этого не будет.
Здравствуйте, Klapaucius, Вы писали:
C>>В Kotlin'е сделали всё правильно. K>Нет, там сделали какой-то набор ad-hoc подпорок, хотя все это должно решаться средствами языка.
Пофиг, зато удобно и практично.
C>>А ошибку компиляции здесь сделать трудно, так как equals() обязан работать с объектами разного типа. K>Кому он обязан-то? Если в язык вводятся АТД, то и сранение обычно делают структурным, а не ссылочным. В данном случае, разумеется, сравнивать значения разных типов — бессмысленно:
Это не очень подходит для ОО-языков.
Здравствуйте, hattab, Вы писали:
H>Здравствуйте, hardcase, Вы писали:
h>> H>Ты хочешь сказать, что отсутствие документации по внутренним интерфейсам это проблема нативного кода? Я тебя правильно понял?
h>> Может слышал про рефлектор? Позволяет ходить по управляемому коду без наличия исходников и понять как использовать те или иные интерфейсы при нулевом уровне документации.
H>Это теперь является оправданием отсутствия документации что-ли?
Это не является оправданием. Необфусцированный управляемый код вполне способен компенсировать ее отсутствие — ибо легко декомпилируем.
h>> H>Возможно у кого то действительно батхерт от сего факта, но лично я тут говорю о гуе, который на WPF лишь частично
h>> Тебе что и говорят — тупо нет ресуров чтобы нафиг все разом на managed-код перевести.
H>Так прикол же, Object browser менеджед, а дерево и ричедит в нем нативные . То есть на остальные контролы (в Object browser'е) ресурсов хватило, а на эти два нет
Не знаю о чем они там думали и почему так поступили, возможно какой-то внутренний код завязан на этот нативный контрол. Я лично создавал на WPF дерево (визуализация достаточно широкого и глубокого нечта) и косяков с производительностью не замечал.
Здравствуйте, VladD2, Вы писали:
VD>Если все это выбросить и вернуться назад к COM-у и нэйтив-реализации, то это будет огромным шагом назад. Думаю, что на такой глупый шак в МС не пойдут.
VD>Ну, а ГУЙ, особенно какие-то там диалоги настроек — это мелочь на которую лично я даже не обращал внимание. Не они делают погоду. Приделывать же нэйтив-гуй к менеджед-кишкам по меньшей мере странно.
До сентября об этом думать рано — о том что будет с нативом,COM,... У MS сейчас в самом разгаре глобальный проект — переписывание всего WinAPI, WinC++, SLR (System Language Rantime — что то среднее между managed и unmanaged). Текущей реализации WPF больше не будет совсем, хотя сам API может и остаться как обертка над новым. Как это все отразится на новой студии, и успеют ли, сумеют ли это, и сам MS наверно еще не знает.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, hardcase, Вы писали:
H>>Долго? Это гмм скорее вопрос написания конвертера исходников Java -> Kotlin.
VD>А оно надо? Все в итоге в байткод преобурзауется. Будут писать новые модули на новом языке и все. Если старые нужно будет серьезно рефакторить, то тоже самое.
Надо, не надо — это вопрос. Вот вы например написали парсер шарпа чтобы можно было компилить шарповские и немерливские сорцы внутри одной сборки. Нафиг это надо было если всё равно все в итоге в байткод преобразуется? Нет, мне кажется логичным написать конвертер Java=>Kotlin.
Здравствуйте, Jack128, Вы писали:
J>Надо, не надо — это вопрос. Вот вы например написали парсер шарпа чтобы можно было компилить шарповские и немерливские сорцы внутри одной сборки. Нафиг это надо было если всё равно все в итоге в байткод преобразуется?
Тому было много причин. Одна из них — парсер был тестом для генератора парсеров на базе которого планируется делать следующую версию немерла.
J>Нет, мне кажется логичным написать конвертер Java=>Kotlin.
Такой конвертер имеет мало смысла, так как это все равно будет Ява, только с другим синтаксисом. Выигрыша от этого не велик. Было бы намного лучше иметь возможность просто подключать явские файлы к проекту (как это делается в немерел с C#). Тогда миграция проекта могла бы проходить в две стадии. Сначала просто конвертим проект так чтобы он компилировался другим компилятором. А потом уже потихонечку заменяем файлы Явы на файлы Котлина (все время хочется написать — котлеты ).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
S_S>>переписывание всего WinAPI VD>Ты сам то в этот бред веришь?
Ну самое нужное и часто используемое наверно осилят, если еще год до релиза. Все что касается GUI точно перепишут.
В сентябре можно будет узнать как быстро процесс продвигается.
Здравствуйте, Silver_S, Вы писали:
S_S> Ну самое нужное и часто используемое наверно осилят, если еще год до релиза. Все что касается GUI точно перепишут. S_S>В сентябре можно будет узнать как быстро процесс продвигается.
Да причем тут "осилят не осилят"? ВыньАПИ — это платформа. Она обеспечивает обратуню совместимость. Никто его из Винды так быстро не выкинит. Сначала должны вымереть все ВыньАПИ-приложения. А это произойдет еще ой как не скоро.
Никуда в ближайшие 5-10 лет ВыньАПИ не денется. Не выдумывай. И газет советских перед сном не читай.
Про переписывание дотнета в нэйтив — это тоже бред. Может быть создадут облегченный вариант CLR. Но это один фиг не отменяет наличия полного. И это все равно будет безопасный код и GC.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Cyberax, Вы писали:
K>>Нет, там сделали какой-то набор ad-hoc подпорок, хотя все это должно решаться средствами языка. C>Пофиг, зато удобно и практично.
И в чем удобство и практичность заключается? Как, например, сделать "safe call" не только по первому аргументу, а по двум? Т.е. val z = x + y, и чтоб z равнялась x + y если x и y не null и равнялось null в остальных случаях? Почему можно лифтить функции в nullable, а в List, например, нельзя?
K>>Кому он обязан-то? Если в язык вводятся АТД, то и сранение обычно делают структурным, а не ссылочным. В данном случае, разумеется, сравнивать значения разных типов — бессмысленно: C>Это не очень подходит для ОО-языков.
Не то что не очень подходит — это вообще не ОО. Но это проблема ОО-языков, а не сравнения. Или, может быть, "scala" == "scala" в скале тоже false?
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Здравствуйте, Klapaucius, Вы писали:
C>>Пофиг, зато удобно и практично. K>И в чем удобство и практичность заключается? Как, например, сделать "safe call" не только по первому аргументу, а по двум? Т.е. val z = x + y, и чтоб z равнялась x + y если x и y не null и равнялось null в остальных случаях?
z= (x!=null && y!=null) ? x + y : null;
K>Почему можно лифтить функции в nullable, а в List, например, нельзя?
То есть?
Здравствуйте, VladD2, Вы писали:
VD>Да причем тут "осилят не осилят"? ВыньАПИ — это платформа. Она обеспечивает обратуню совместимость. Никто его из Винды так быстро VD>не выкинит. Сначала должны вымереть все ВыньАПИ-приложения. А это произойдет еще ой как не скоро. VD>Никуда в ближайшие 5-10 лет ВыньАПИ не денется. Не выдумывай. И газет советских перед сном не читай.
Ну например, оставят старый API но объявят его deprecated .
С обратной совместимостью MS всегда старался делать все что возможно.
VD>Про переписывание дотнета в нэйтив — это тоже бред. Может быть создадут облегченный вариант CLR. Но это один фиг не отменяет наличия полного. И это все равно будет безопасный код и GC.
Это и не выглядит как отмена .NET, скорее как отмена/замена того что было полностью unmanaged и не было перспектив, что оно когда нибудь станет managed. Когда на компе работает парочка больших .NET приложений overhead незначительный. А если несколько десятков .NET процессов в виде каких-то мелких утилит, то уже оверхед нехороший.
Для .NET'чиков тут уже большой плюс, к новому API, без рукописных оберток, автоматом прилагаются *.WinMD файлы. На них можно делать ссылки из .NET проектов. Это файлы метаданных в формате .NET прямо на код который по эффективности и оверхеду скорее является unmanaged. Но стандарты оформления API скорее из .NET.
Куча проблем снимаются: Не надо ждать когда напишут рукописную обертку для .NET. При работе с голым COM не расчитанным на работу с .NET , через автоматические InteropAssembly, API может оказаться практически не юзабельным.
Здравствуйте, Cyberax, Вы писали:
K>>И в чем удобство и практичность заключается? Как, например, сделать "safe call" не только по первому аргументу, а по двум? Т.е. val z = x + y, и чтоб z равнялась x + y если x и y не null и равнялось null в остальных случаях? C>
C>z= (x!=null && y!=null) ? x + y : null;
C>
У этого вашего "удобства" недетское злое лицо. Обычно такое "удобство" называют неудобством. Выделенный жирным шрифтом код совсем не нужен и писать такой код не нужно. Котлин же заставляет писать ненужный код. Это — практично?
K>>Почему можно лифтить функции в nullable, а в List, например, нельзя? C>То есть?
Ну, оператор ?. "поднимает" U -> V в "контекст" Nullable и мы получаем по факту Nullable<U> -> Nullable<V> ну или сокращенно U? -> V?. Все это, понятно, в кавычках, потому что он ничего такого он разумеется не делает — это ad-hoc костыль, потому что авторы Котлина не читатели и страдают синдромом Уолта Брайта. Но у читателя возникают некоторые ассоциации. И тут сразу возникает вопрос — а почему только Nullable<_>, а не любой другой функтор? Наверное, когда котлиностроители начнут вставлять в язык какое-нибудь асинхронное программирование они возьмут и вцементируют в язык какой-нибудь оператор ||. или что-то наподобие.
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Cyberax,
C>>>5) Множественное наследование. A>>можно сказать, что они в Скале есть через трэйты C>Они кривые. Скажем, для них нет конструкторов и вообще их инициализация неудобна. Diamond-проблему trait'ы в Scala никак не решают, а просто задают детерминированный механизм разрешения конфликта.
C>Так что в Kotlin поступили правильно — взяли обычное множественное наследование, убрав разницу между интерфейсом и классом.
Это как раз случай простого и неправильного решения для сложной проблемы. Вообще, я понимаю, об окончательном решении сейчас рано говорить — язык ещё даже не оформлен, не то что не реализован. Но если эта залепуха (а по другому я это "решение" назвать не могу) останется в релизе, то это будет полнейший фэйспалм. Можно понять Страуструпа — он лепил из того, что было, и опыта хождения по граблям множественного наследования не было никакого. Гослинг (а вслед и Хейлсберг) посмотрели на это, и сказали — нафиг надо и ввели ограничения, так что выразительность упала значительно, но и грабли были убраны. А что мы видим здесь? возврат к старому и злому С++.
Diamond-проблему как раз трейты решают, и это решение модульное, типобезопасное и непротиворечивое (см. статью Scalable component abstractions). Соглашусь, что несколько громоздкое из-за правил линеаризации. И ограничения есть — нетривиальные конструкторы недопустимы. Впрочем, если мы хотим позволить себе конструкторы с параметрами, тогда придётся навернуть систему типов и отношений между классами.
Самый продвинутый известный мне вариант описан в статье CZ:MultipleInheritance Without Diamonds — а именно ввести 2 вида отношений: extends и requires, и разделить понятия subtype и subclass.
Вкратце, любые ромбы запрещены, но чтобы сохранить выразительность и переиспользовать функционал, можно ввести отношение requires: C requires A. Означает это, что C становится абстрактным, будет подтипом A (то есть можно приводить ссылки), и конкретные наследники C должны будут также наследовать и от A.
Таким образом, ромб типа
заменяется на иерархию
Никаких неоднозначностей не осталось, и вместе с тем, конкретные классы заиспользовали все нужные им куски из функционала предков.
А вот то что я вижу в Котлине вызывает ряд вопросов:
open class A(virtual var v : int)
open class B(v : Int) : A(v)
open class C(v : Int) : A(v)
class D(v : Int) : B(v), C(v) {
override var v : Int
get() = this<B>.v
set(value) { this<B>.v = value }
}
1. Требуется ли всегда вручную явно указать как разрешать противоречия? (Если да, то печаль.)
2. Сколько подобъектов A содержится в D (если 2, то это грабли, и тогда эти сопли не нужны, лучше использовать композицию, если 1, то см ниже.)
3. Как будем инициализировать подобъект А если напишем
open class A(virtual var v : int)
open class B(v : Int) : A(100)
open class C(v : Int) : A(200)
class D(v : Int) : B(v), C(v) { ... }
Сколько раз будем вызывать конструктор для A? Я надеюсь, один раз, но тогда с каким аргументом? (Для Скалы пофиг, у всех трейтов одинаковые то бишь дефолтные конструкторы, поэтому выбор очевиден — вызываем один раз единственно имеющийся конструктор).
Плюс, в Скале есть мембер-типы и селфтипы, что позволяет элегантно расправиться с Expression Problem. А Котлин?
Короче, будем смотреть
(Думаю, черкануть пару строчек кому-нибудь из JetBrains, авось заинтересуются идеей из CZ).