Изменения под капотом:
0. Lang as a service. Подтяни себе компилятор с нюгета
1. IOperation —
a common abstract view on the bound trees of the C# and VB compilers, and extends the analyzers API to include operation actions that operate upon them.
It is now possible to write a single analyzer that works for both C# and VB, so long as the analyzer operates entirely within semantic realms.
Здравствуйте, Sinix, Вы писали:
S>Оставшаяся часть фич не влезла в седьмой шарп и переехала в (внезапно) восьмой.
S>Итак, что мы имеем: S>1. Non-nullable references. Утрируя, слизаны с самого здравого подхода — с решарперовского [NotNull]. Основной тикет — тынц
Вот это обидно, я так надеялся на 7ой... S>2. AOP и codegen. #5561 и #5292.
Угу, верим, надеемся, ждем.. S>4. ref-properties, ref locals (как и говорилось неоднократно, полезли косяки).
Какая то фича не для всех, ИМХО
Здравствуйте, Jack128, Вы писали:
S>>1. Non-nullable references. Утрируя, слизаны с самого здравого подхода — с решарперовского [NotNull]. Основной тикет — тынц J>Вот это обидно, я так надеялся на 7ой...
Не успели, но оно и правильно, кмк. А то оно _пока_ хуже решарперовской диагностики работает. Оно и понятно — с наскоку такую штуку не сделать.
S>>2. AOP и codegen. #5561 и #5292. J>Угу, верим, надеемся, ждем..
А это как раз и не обещали в седьмом. Что тоже в принципе правильно, нынешнее API рослина дружелюбием не отличается.
S>>4. ref-properties, ref locals (как и говорилось неоднократно, полезли косяки). J>Какая то фича не для всех, ИМХО
Если честно, я пока вообще не вижу для этого применения, кроме подпольной магии для компиляторов. Но оно и сейчас работает
Хотя не, вру. Есть просьба сделать ref extension methods, чтобы не копировать тяжёлые структуры. Но, опять-таки, для этого ref locals/ref returns вроде как не нужен.
Здравствуйте, Sinix, Вы писали:
S>Здравствуйте, Jack128, Вы писали:
S>>>1. Non-nullable references. Утрируя, слизаны с самого здравого подхода — с решарперовского [NotNull]. Основной тикет — тынц
Тенденция намечается интересная, так, глядишь, лет через несколько design by types в мейнстриме увидим как модную парадигму программирования.
Здравствуйте, Codechanger, Вы писали:
S>>>>1. Non-nullable references. Утрируя, слизаны с самого здравого подхода — с решарперовского [NotNull]. Основной тикет — тынц
C>Тенденция намечается интересная, так, глядишь, лет через несколько design by types в мейнстриме увидим как модную парадигму программирования.
На мой взгляд не увидим.
Оно работает хуже, чем простокод в более-менее реалььных сценариях.
Если я конечно правильно тебя понял и речь про AOP-хардкор с накидыванием большей части поведения через кучу атрибутов.
Как пример к чему оно приводит:
/// <summary>
/// Assertion for the argument value
/// </summary>
[DebuggerHidden]
[AssertionMethod, StringFormatMethod("messageFormat")]
public static void AssertArgument(
[AssertionCondition(AssertionConditionType.IS_TRUE)] bool condition,
[NotNull] [InvokerParameterName] string argName,
[NotNull] string messageFormat,
[CanBeNull] params object[] args)
{
if (!condition)
throw CodeExceptions.Argument(argName, messageFormat, args);
}
Это ешё не вариант "упороться по максимуму", просто "чтоб работало".
Здравствуйте, Sinix, Вы писали:
S>Здравствуйте, Codechanger, Вы писали:
S>>>>>1. Non-nullable references. Утрируя, слизаны с самого здравого подхода — с решарперовского [NotNull]. Основной тикет — тынц
C>>Тенденция намечается интересная, так, глядишь, лет через несколько design by types в мейнстриме увидим как модную парадигму программирования. S>На мой взгляд не увидим. S>Оно работает хуже, чем простокод в более-менее реалььных сценариях.
S>Если я конечно правильно тебя понял и речь про AOP-хардкор с накидыванием большей части поведения через кучу атрибутов.
Я скорее про подход, используемый в F#, где тип не может принять Null значение.
Для облегчения перехода планируется явная декларация non-nullables через string!.
В метаданных nullability размечается так же, как dynamic — атрибутами.
Здравствуйте, Sinix, Вы писали:
S>Здравствуйте, Codechanger, Вы писали:
C>>Я скорее про подход, используемый в F#, где тип не может принять Null значение.
S>Ну собственно это и ожидается в итоге: помечаешь сборку как non-nullable by default, явно отмечаешь nullable-параметры аля S>
Assertion можно и короче написать, например для переменной value, значение которой null
ContractAnnotation("value:null => halt")
В твоем случае будет выглядеть так:
ContractAnnotation("condition:false => halt")
Отпадает необходимость навешивать атрибут на параметр, что немного уменьшает визуальный шум, да и контракт читается как код, что на мой взгляд проще, чем выискивать глазами навешанные атрибуты
Здравствуйте, Sinix, Вы писали:
S>явно отмечаешь nullable-параметры аля
Это самообман. Таким образом ты только увеличишь себе объем работы. Для того чтобы бороться с NRE надо менять иделогию. В F# это работает только для внутреннего подмножетсва языка, которое рассчитано на полную инициализауию значений. Дотнет же спроектирован так, что неинициализированные значения в нем норма. Мы не может создать инициализированный массив и может создать не инициализированную структуру. Плюс туча общепринятых типов из стандартной библиотеки создают проблемы.
Тут нужно менять сам дотнет. Это концептуальное изменение.
Скажу больше. Банальный переход на правильно спроектированные библиотеки делает NRE несуществнной проблемой. Просто нужно использовать "инициализирующий подход". Функциональное программирование очень этому способствует. В нашем коде на Немерле NRE встречается редко и очень легко выявляется. Мы даже незадумывались над созданием специальных проверок в компиляторе и пренебрегаем option<T>-ми.
Реально насущной проблемой, на мой взгляд, является проблема многопоточной разработки. В современных языках только полная неизменяемость позволяет уберечь код из одного потока от изменений в другом. Вот в этом направлении нужно придумывать новые концепции.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, rameel, Вы писали:
R>Отпадает необходимость навешивать атрибут на параметр, что немного уменьшает визуальный шум, да и контракт читается как код, что на мой взгляд проще, чем выискивать глазами навешанные атрибуты
Все с точностью до наоборот. "Шум" увеличивается, читаемость уменьшается. Но все эти атрибуты — мертвому припарка. Концепцию надо менять. NotNull должно быть по умолчанию. В языке должны быть удобные конструкции инициализации коллекций и структур. Должен быт запрет на неявное создание неинициализированных структур данных. Допустимость Null-значений должна выражаться явно и иметь семантику "отсутствующего значения". Но для этого придется еще написать новые библиотеки и уметь запрещать использование старых. Короче, концептуальные изменения всего дотнета.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Тут просто какой-то перебор. Вместо [NotNull] будет возможность применить "?" к типу принимающему null, а по умолчанию null будет недопустим. А вот так можно пост/пред-условия делать (естественно, Nemerle):
Foo() : void
requires i >= 0 && i < 5
{
def x = array[1,2,3,4];
WriteLine(x[i]);
}
GetFoo(i : int) : int
requires i >= 0 && i < 5 otherwise throw ArgumentOutOfRangeException(i.ToString())
{
def x = array[1, 2, 3, 4];
WriteLine(x[i]);
x [i]
}
Boo(x : int) : void
ensures i >= 0 && i < 5
{
i = x;
WriteLine(x);
}
Как говорится: "все украдено до нас".
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Это самообман. Таким образом ты только увеличишь себе объем работы.
Не, тут путаница какая-то по-моему.
Предлагаю просто ознакомиться с прототипом или хотя бы с доками. Там принцип очень простой — для каждого из членов класса известно, заявил ли разработчик о том, что значения будут not null или нет. Ну и режим "по умолчанию всё not null" есть, ставится для каждой сборки в отдельности, что позволяет плавно переводить весь код.
Т.е. нет нужды в перекрёстном анализе всего кода, достаточно code flow analysis на уровне метода. Уровня того, что уже используется для определения неинициализированных переменных. Цель _гарантировать_ not null не ставится, ибо работает принцип неуловимого Джо. Ну, как с ковариантными массивами. В теории дырищща ж, на практике — хоть раз кто-то с этим сталкивался?
В итоге во время компиляции ловится эдак 99% типовых "забыл проверить на null" без нарушения совместимости с существующим кодом и без каково-либо влияния на перфоманс. Win-win, как есть.
VD>Реально насущной проблемой, на мой взгляд, является проблема многопоточной разработки. В современных языках только полная неизменяемость позволяет уберечь код из одного потока от изменений в другом. Вот в этом направлении нужно придумывать новые концепции.
Неа, это уже пробовали. В недрах MS research было штук 5 подходов к станку, это те, что я сходу вспомнил. В лидерах, понятное дело, midori, в практике тот же подход — любое _разделяемое_ состояние должно быть immutable + cps — вполне себе выстрелил и в шарповском асинке, и в orleans. Вот за этим будущее, да.
А вот как выглядит полный immutable и какие проблемы оно порождает при попытке использовать в реальных масштабах все могут посмотреть на примере рослина. Нафиг-нафиг такое счастье.
Здравствуйте, VladD2, Вы писали:
VD>Тут просто какой-то перебор.
+1.
Этот пример вообще к топику никак не относится, в той ветке обсуждалось
C>Тенденция намечается интересная, так, глядишь, лет через несколько design by types в мейнстриме увидим как модную парадигму программирования.
...
Если я конечно правильно тебя понял и речь про AOP-хардкор с накидыванием большей части поведения через кучу атрибутов.
Как пример к чему оно приводит:
Как выяснилось, под design by types понималось что-то другое
Здравствуйте, Sinix, Вы писали:
S>Т.е. нет нужды в перекрёстном анализе всего кода,
Это еще один самообман. Весь код в солюшене взаимосвязан. Нельзя быть в одном месте беременным, а в другом — нет. Если в одном месте на нее забить, в другом запаришься проверки писать. Такой подход применим только для независимых сборок.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Sinix, Вы писали:
VD>>Реально насущной проблемой, на мой взгляд, является проблема многопоточной разработки. В современных языках только полная неизменяемость позволяет уберечь код из одного потока от изменений в другом. Вот в этом направлении нужно придумывать новые концепции.
S>Неа, это уже пробовали. В недрах MS research было штук 5 подходов к станку, это те, что я сходу вспомнил.
Все что там было, если не брать специализированных ОС — полная лажа. Они даже до Эрланга многолетней давности не доросли.
Тут надо капитально менять язык и парадигму.
S>В лидерах, понятное дело, midori, в практике тот же подход — любое _разделяемое_ состояние должно быть immutable + cps — вполне себе выстрелил и в шарповском асинке, и в orleans. Вот за этим будущее, да.
Это общие лова. На деле же ничего для дотнета нет. Специальные ОС в расчет смысла брать нет, так как вероятность того что мы на них начнем работать крайне низка. МС сам же не даст им пробиться.
Оставляя же контроль за человеком мы неминуемо получаем проблемы.
S>А вот как выглядит полный immutable и какие проблемы оно порождает при попытке использовать в реальных масштабах все могут посмотреть на примере рослина. Нафиг-нафиг такое счастье.
Полная неизменяемость не применима в 100% случаев. И уж что-то, а C# для этого вообще не пригоден. Как я уже сказал для этого нужно менять парадигму и яызк (причем не косметически, а серьезно).
Подходы из Эрланга, Сингулярити и Midori очень правильные, но что-то я не вижу, чтобы МС реально делал в этом напралении хоть что-то. В стане Явы ситуация аналогичная. Кое что есть только в Расте. Но это вещь в себе, пока. И к МС не относится.
Все эти Асинки — это как мертвому припарка. От ошибок связанных с изменением состояния в многопоточном мире это не спасает.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Это еще один самообман. Весь код в солюшене взаимосвязан. Нельзя быть в одном месте беременным, а в другом — нет. Если в одном месте на нее забить, в другом запаришься проверки писать. Такой подход применим только для независимых сборок.
Ну так это только для плавного перевода существующего кода будет использоваться. Дальше весь код помечается как non-nullable by default и понеслась.
S>>Неа, это уже пробовали. В недрах MS research было штук 5 подходов к станку, это те, что я сходу вспомнил. VD>Все что там было, если не брать специализированных ОС — полная лажа. Они даже до Эрланга многолетней давности не доросли.
Ну так там цель не сделать ещё один эрланг, а прикрутить scalable multitasking к мейнстриму. http://thenewstack.io/project-orleans-different-than-erlang-designed-for-a-broad-group-of-developers/
+ http://theburningmonk.com/2014/12/a-look-at-microsoft-orleans-through-erlang-tinted-glasses/
И оно таки работает.
VD>Тут надо капитально менять язык и парадигму.
Судьба любого языка с "нам пофиг на совместимость, зато всё идеально" — не выбираться из дев-лаборатории. Поэтому или работаем с тем, что есть в мейнстриме, или никак.
Насколько вся затея с "правильной" многопоточностью важна для разработчиков сама по себе узнать несложно. Смотрим на популярность эрлангоскалы.
VD>Это общие лова. На деле же ничего для дотнета нет. Специальные ОС в расчет смысла брать нет, так как вероятность того что мы на них начнем работать крайне низка. МС сам же не даст им пробиться.
Такой вопрос — ты материалы по Orleans изучал? Если нет — то что мы обсуждаем?
VD>Все эти Асинки — это как мертвому припарка. От ошибок связанных с изменением состояния в многопоточном мире это не спасает.
Ну вот в наших проектах их практически 0. Особенно если сравнивать с тем, что было до тасков. Просто потому, что можно расписать код в CPS или в reactive-style и не возиться с примитивами. Т.е. нужда в разделяемом состоянии отпадает, вместе с ним — и сами баги