Vasily
Не
Vasily
В теории там с точки зрения execution flow лучше явный матч
Vasily
Но я ленив :(
Dr. Friedrich
А чем тебе питон не нравится то?
А чем тебе нравится? Динамический язык, множество плохо совместимых версий (которые линкуют куда ни попадя и возись потом с ними), неудобное управление пакетами (они ставятся глобально в инстанс интерпретатора, и управлять этим приходится через костыли типа virtualenv, которые не всегда нормально портированы); множество непортабельных пакетов (которые полагаются на крупные неповоротливые элементы окружения типа сишного компилятора), убер сомнительные синтаксические решения (отсутствие многострочных лямбд, странная работа аргументов по умолчанию).
Dr. Friedrich
Я не представляю, как это всё в совокупности может нравиться.
Dr. Friedrich
И это я даже не начал говорить про перформанс, GIL, многопоточность и связанные с ними мифы, рампространённые у разработчиков на этом языке.
Hog
Dr. Friedrich
Ещё скоуп отступами забыл!
Конкретно с этим у меня проблем не было. Но, таки да, волшебные ключевые слова global и nonlocal тоже позволяют супер запутать код со скоупами :)
Hog
Alexey
Alexey
и можно делать свои!
Alexey
ой да ладно
Dr. Friedrich
Но свои можно наделать, да.
Alexey
-> горизонтально
|> вертикально
» сломалась
Alexey
тут кстати Википедия говорит, что поддержку F# выпилили из MSVS
Shub
Hog
Nikolay
А чем тебе нравится? Динамический язык, множество плохо совместимых версий (которые линкуют куда ни попадя и возись потом с ними), неудобное управление пакетами (они ставятся глобально в инстанс интерпретатора, и управлять этим приходится через костыли типа virtualenv, которые не всегда нормально портированы); множество непортабельных пакетов (которые полагаются на крупные неповоротливые элементы окружения типа сишного компилятора), убер сомнительные синтаксические решения (отсутствие многострочных лямбд, странная работа аргументов по умолчанию).
Есть готовые сборки, типа anaconda, где все проблемы с разделением версий пофикшены. Я много работал с этим, и ни одной проблемы не заметил. Писал я тоже только на одной версии - 3.7, и всё ок. Лямбды да, стрёмные, в остальном жить можно, типизация в разы лучше чем у жс. Не нужно ставить 100500 пакетов, много всего есть в стандартной библиотеке.
Dmitry
Анна
Анна
Там на 15-20 минут максимум надо задачку 🤔
Анна
Vladislav
Это английская корона?
Dmitry
В смысле?! Там ж всего то минут 5 работы
Dmitry
Задумка гуд, надо развить соответствующими деталями
Vladislav
k
Анна
Alexey
можно удачно кое-что закрыть или замазать
Anonymous
Dr. Friedrich
Nikolay
Можно ли конвертнуть такую дичь:
Expression<Func<T, LocalizableString>> propertyOrMethod
В такую:
Expression<Func<T, object>> propertyOrMethod
?
Vasily
(object)
Nikolay
Такой вариант не прокатит:
var compiled = exp.Compile();
Expression<Func<T, object>> e = (a) => compiled(a);
Vasily
Явный каст сделай
Nikolay
Alexey
Func контравариантен, Expression инвариантен - нельзя
Nikolay
Щас вот так попробую:
var exp = Expression.Lambda<Func<T, object>>(propertyOrMethod);
Nikolay
Неа, не прокатывает
Vasily
Заверни expression в expression
Nikolay
Alexey
Можно сделать return x => x;
Vasily
Дичь какую- то пишешь
Nikolay
Там специфика такая, что указывается пропертя или поле
Nikolay
И если там будет не пропертя, или поле, тогда бросит эксепшн
Vasily
Ну ты бы подробнее тогда рассказал, что за херь
Vasily
СУдя по героическим попыткам, творится херня
Alexey
Перегрузки не рассматриваются?
Nikolay
Ну я конечно могу сделать на входе Expression object, мне ничего не мешает, но хочется по правильному сделать, чтобы были ошибки в случае чего во время компиляции, а не в рантайме
Nikolay
Ничо не дичь
Nikolay
https://stackoverflow.com/questions/31328693/changing-the-return-type-of-an-expressionfunc
Nikolay
Вот есть такое решение
Vasily
Если начать спрашивать - зачем вот это все, это будет сильно бестактно?
Nikolay
Есть такая библотека для GraphQL, называется HotChocolate. Там типы описываются таким образом:
desc.Field(x => x.Features)
.Description("List of features.")
.Type<NonNullType<ItemFeatureType>>();
Для возвращаемых типов обычно отдельно описывается тип, но у меня возникла задача конвертирования типа в скалярный, по заданному условию. Чтобы одно и то же не писать по 100 раз, я сделал Extension метод:
public static IObjectFieldDescriptor LocalizableString<T>(
this IObjectTypeDescriptor<T> descriptor,
Expression<Func<T, LocalizableString>> propertyOrMethod)
{
var compiled = propertyOrMethod.Compile();
var exp = (Expression<Func<T, object>>)
new ReturnTypeVisitor<T, object>()
.Visit(propertyOrMethod);
return descriptor
.Field(exp)
.Resolver(x =>
{
var context = x.Service<HttpContext>();
var value = compiled(x.Parent<T>());
var language = HttpContextUtility.ExtractLanguage(context);
return value?.GetOrDefault(language) ?? string.Empty;
})
.Type<StringType>();
}
И вызываю его так:
desc.LocalizableString(x => x.Name)
Как ты видишь, метод Field принимает в качестве аргумента Expression<Func<T, object>>, а у меня тип Expression<Func<T, LocalizableString>>.
Nikolay
Как я уже сказал да, я могу в качестве аргумента использовать Expression<Func<T, object>>, но тогда похерится компайл тайм проверка, а это очень плохо.
Alexey
Если кейсов всего 2, то почему бы вместо универсальных портянок не сделать две короткие перегрузки?
Nikolay
Alexey
Ну, тебе нужно отдавать либо свойство, либо поле, верно?
Alexey
Или я не так понял задачу?
Nikolay
Nikolay
Но только с типом LocalizableString
Dr. Friedrich
Dr. Friedrich
У тебя единственная версия питона
Dr. Friedrich
У меня единственная версия питона
Dr. Friedrich
И вон у Василия тоже едиственная версия питона
Dr. Friedrich
Все три — разные
Dr. Friedrich
ebis
Dr. Friedrich
Dr. Friedrich
Dr. Friedrich
Dr. Friedrich
Саблайм одну тащит, анаконда другую, вим третью
Alexey
Wrap(FieldExpression<Func<T, F> > )
Wrap(PropertyExpression<Func<T, P> > )
я вот это имел в виду
Dr. Friedrich
Потом компилишь туда пакет, а он начинает посасывать
Vasily
Я, честно говоря, вообще ценность graphql не понимаю