Во многих современных языках сейчас есть такая штука — "placehodler" _ (подчеркивание),
которая работает например так
_ = 100; // ничего не происходит
(_, x, _) = (1, 2, 3); // x = 2;
Вопрос — а эта конструкция как-то формализована? Какой тип у "_" ? (зачем нужен тип — например чтобы передать его в шаблон и посмотреть что получится). Если названия типа нет — как бы вы назвали этот тип? (желательно одним коротким словом 3..5 символов)
Здравствуйте, x-code, Вы писали:
XC>Вопрос — а эта конструкция как-то формализована? Какой тип у "_" ? (зачем нужен тип — например чтобы передать его в шаблон и посмотреть что получится). Если названия типа нет — как бы вы назвали этот тип? (желательно одним коротким словом 3..5 символов)
Кмк, никакого типа у placeholder нет. Это просто конструкция языка. По-аналогии — какой тип у "if"?
Здравствуйте, Буравчик, Вы писали:
Б>Кмк, никакого типа у placeholder нет. Это просто конструкция языка. По-аналогии — какой тип у "if"?
Нет никакого сомнения что это конструкция языка
но мне интересно, можно ли рассматривать ее как объект некоторого экзотического типа?
вот например void — конструкция языка или тип?
в некоторых языках есть еще unit — аналог void, с одним единственным значением
или еще never — тоже как-бы тип, указывающий что функция не возвращает управление.
x-code:
XC>Вопрос — а эта конструкция как-то формализована? Какой тип у "_" ? (зачем нужен тип — например чтобы передать его в шаблон и посмотреть что получится). Если названия типа нет — как бы вы назвали этот тип? (желательно одним коротким словом 3..5 символов)
Безымянные переменные, для каждого вхождения "_" разные.
Какой тут может быть общий тип?
Модератор-националист Kerk преследует оппонентов по политическим мотивам.
Здравствуйте, x-code, Вы писали:
XC>но мне интересно, можно ли рассматривать ее как объект некоторого экзотического типа?
XC>вот например void — конструкция языка или тип? XC>в некоторых языках есть еще unit — аналог void, с одним единственным значением XC>или еще never — тоже как-бы тип, указывающий что функция не возвращает управление.
Зачем? Только если в самом языке такая возможность отсутствует (any, x, any).
В с/с++ void это тип без конструктора, и таким образом
Например в Kotlin подходящий тип был бы Any? (предок всех типов). Т.е. в системе типов должен быть тип, от которого унаследованы все остальные типы.
А вообще, имхо, разумней назначать каждому placeholder-у свой тип (выведенный из выражения) и всё. Почему у всех должен быть один тип? Они же концептуально разные, несмотря на одинаковое имя.
Здравствуйте, x-code, Вы писали:
XC>Здравствуйте, Буравчик, Вы писали:
Б>>Кмк, никакого типа у placeholder нет. Это просто конструкция языка. По-аналогии — какой тип у "if"?
XC>Нет никакого сомнения что это конструкция языка XC>но мне интересно, можно ли рассматривать ее как объект некоторого экзотического типа?
Нет, ниже
XC>вот например void — конструкция языка или тип?
От языка зависит. XC>в некоторых языках есть еще unit — аналог void, с одним единственным значением
если речь об F#, то там unit — совершенно точно тип, и он не аналог void, а ровно наоборот. От плейсхолдера его отличает то, что можно объявить значение типа unit, получить значение, передать его параметром.
Плесхолдер же, хоть и конструкция языка, но не поддается никакому взаимодействю со стороны языка до тех пор, пока мы не обнаружим язык, который явно это позволяет. XC>или еще never — тоже как-бы тип, указывающий что функция не возвращает управление.
не сталкивался.
Плейсхолдер можно считать объявлением переменной без имени. Однако, можно указать тип этой переменной, например
let (_: int, x, _) = (1, 2, 3)
Отсюда можно вывести что сам плейсхолдер как конструкция языка тип не имеет, но переменную, которую он как бы замещает, тип иметь может. И указание этого типа не есть плейсхолдер. Таким образом, плейсхолдер — это всего лишь имя, которое не используется далее в коде.
Здравствуйте, Lazytech, Вы писали:
L>Здравствуйте, x-code, Вы писали:
XC>>Во многих современных языках сейчас есть такая штука — "placehodler" _ (подчеркивание),
L>Вообще-то это underscore.
underscore — это название символа.
Символ может обозначать разные конструкции и разные конструкции можут обозначаться разными символами.
Например, = — знак равенства. Но в C-подобных языках он играет роль оператора присваивания, а оператор равенства в них записываться совсем иначе: ==.
Ну в python как раз нет никакого выделенного плейсхолдера. В нём _ — это обычное имя переменной. Ничем не хуже i, j, k, или например foo.
Все типичные конструкции, например, по распаковке точно также будут работать и с другими вариантами:
a, *_, b = range(100) # a = 0, b = 99
a, *ignore, b = range(100) # a = 0, b = 99
Тут просто стиль сложился, что в переменную _ можно записывать то, что дальше использовать не планируется, чтобы не выдумывать каждый раз новое имя или не писать вариации ignore.
Соотвественно, в C++ точно также встречается код
for (const auto& [_, value] : some_map) {
// use value
}
Точно так же тут _ — просто имя, призванное показать, что дальше это использовать не планируется.
Но ни в python, ни в с++ не возникает вопроса о типе _ — раз это обычное имя переменной, то оно подчиняется всем правилам для остальных переменных.
Здравствуйте, Bill Baklushi, Вы писали:
BB>YuriV:
YV>>В с/с++ void это тип без конструктора, и таким образом
void foo() { return void(); } // is ill-formed
В хаскеле void это тип без значения.
BB>Между прочим, такой код не ill-formed, нормально компилируется.
Да, конечно, мой косяк, void это incomplete type который нельзя сделать complete и поэтому не может быть объектов этого типа, массивов и ссылок.
Здравствуйте, x-code, Вы писали:
XC>Во многих современных языках сейчас есть такая штука — "placehodler" _ (подчеркивание), XC>которая работает например так XC>
_ = 100; // ничего не происходит
XC>(_, x, _) = (1, 2, 3); // x = 2;
XC>
XC>Вопрос — а эта конструкция как-то формализована? Какой тип у "_" ? (зачем нужен тип — например чтобы передать его в шаблон и посмотреть что получится). Если названия типа нет — как бы вы назвали этот тип? (желательно одним коротким словом 3..5 символов)
В говноязыках (а 99% языков — это говноязыки) эта конструкция не формализована. Но формализовать ее можно. Это переменная, тип которой — экзистенциальный тип. То есть "существует некоторый тип, такой, что".
В ц-подобном синтаксисе могло было бы быть что-то вроде:
([some type T] T _, int x) = (1, 2); // x = 2, _ = 1, T = int
Здравствуйте, watchmaker, Вы писали:
W>Точно так же тут _ — просто имя, призванное показать, что дальше это использовать не планируется.
Вопрос в том, разрешено ли множественное использование этого имени.
W>Но ни в python, ни в с++ не возникает вопроса о типе _ — раз это обычное имя переменной, то оно подчиняется всем правилам для остальных переменных.
for (const auto& [_, _, value] : some_map) {
// use value
}
Ага, верно. Всё потому, что в этом примере в C# это не переменная, а именно отдельная сущность с семантикой discard с особой поддержкой компилятором.
Собственно, в этом и был поинт, что язык python для демонстрации какой-то особой семантики placeholder'a с именем '_' не подходит, так как в нём такой поддержки нет.
S>Вопрос в том, разрешено ли множественное использование этого имени.
В Python — можно, но это не означает что этот как то специально трактуется или поддерживается интерпретатором. Просто [a, b, a, b] = sequence приводит к тому, что одной переменной значение присваивается дважды (и она принимает значение последнего присваивания).
Ну а в С++ через синтаксис с auto так сделать, очевидно, нельзя. Так как одновременно происходит не только присваивание, но определение имени, а нельзя определить две переменные с одним именем в одном блоке. Но при этом можно сделать так: std::tie(_, a, _) = expr() . Хотя, конечно, так никто не пишет, а пишут std::tie(std::ignore, a, std::ignore) = expr() (тут правда сразу видна проблема с многословностью, из-за которой в плюсах такая конструкция не пользуется популярностью).