Как стать автором
Обновить

Комментарии 24

Странная тенденция - затаскивать синтаксис из функциональных языков. То что берут семантику - замечательно, полноценный паттерн матчинг давно пора ввести, и очень хорошо что он постепенно проникает во все языки. Но синтаксис... с этой дурацкой вертикальной чертой, в Rust ее затащили, теперь и в Python (хотя мне Python никогда не нравился за его форматно-несвбодный синтаксис).

Вертикальная черта это битовое ИЛИ ! В языках, сколько-то претендующих на мейнстримовый синтаксис, вместо нее в case-паттернах вполне можно было бы использовать обычную запятую.

Кажется, из всех современных языков лучше всех сделано в Swift.

Идею с запятой поддерживаю.

Вообще, есть ощущение, что после моржового оператора Питон идёт куда-то не туда.

«Моржовый оператор» лучше всего использован в Go.
Вообще проблема Python (а также Ruby, Perl, PHP, JavaScript и т.д.) в том, что можно создавать переменные без явного объявления. Вот просто написать «x = 100», и у вас новая переменная. Или не новая, а ранее объявленная… Если имя переменной длинное, то одна случайная опечатка — и программа не работает. Или работает, но не совсем так как задумывалось… В Go придумали идеальное решение: отдельный оператор для объявления переменных.

В js подобное прокатит разве что поиграться в нестрогом режиме. В реальной разработке всё будет объявляться const или в крайнем случае let.

Этому оператору присвоения сто лет в обед. :)

Что касается динамической природы языка, так это достоинство и недостаток одновременно. Зато не надо придумывать название для той же сущности в другом формате или экономить на переменных. А для глупых ошибок есть линтеры.

Зато не надо придумывать название для той же сущности в другом формате или экономить на переменных.

Если в джаве так делать нельзя, то это не значит, что так делать в статически типизированных языках нельзя в принципе:


fn increment(n: &str) -> u32 {
    let n = n.parse().unwrap_or(0);
    n + 1
}
НЛО прилетело и опубликовало эту надпись здесь

1 пример - затенение во многих яп есть, и умение кодить на go включает знание этой особенности. Тут кстати можно линтер наверно сделать на одинаковые имена в скоупе (не точно)

2 пример - все от того что мы вводим короткие имена (читай ленимся), и вместо errFoo используем err - и удивляемся, что неудобно в некоторых местах

Например в Rust сложно представить, как затенить переменную случайно. Для затенения нужно новый байндинг делать с инструкцией let:

let a = 25;
let a = "test";

А модифицируется имеющееся значение так:

let mut a = 25;
a = 42;
В C#10 сделали совмещенную деконструкцию в новые и существующие переменные. Может и в Go подтянутся
string model = string.Empty;
(model, var color) = car;

и это кстати нужная фича для паттерн-матчинга частично определенными паттернами. Типа вот такого (на некотором гипотетическом C-like языке)
match(car) {
case "BMW X5", var color: foo(color); 
case var model, Black: bar(model);
}

В языках, сколько-то претендующих на мейнстримовый синтаксис

Кому он нужен, ваш мейнстримовый синтаксис.

Мне нужен. Это как математическая нотация: в разных разделах математики изучаются совершенно разные вопросы, но нотация на 90% общая. Если бы в каждом случае были бы свои обозначения для арифметических операций, функций и т.д., это был бы полный мрак...

match data_class:
    case User(username) as req:
      print(f"Granted to {req.name}")
    case _:
      print("deny")

Кстати, заметили выражение User(username)? Выглядит как создание экземпляра класса, однако очевидно им не является, хотя бы потому, что у класса два обязательных аргумента, а тут передано только одно значение.

Это конечно вынос мозга. Где там что-то было про "явно лучше неявного"? Если запись User(username) это явное для сопоставления значения поля экземпляра, то я уже ни в чём не уверен.

так как | — это оператор бинарного ИЛИ

Не всегда.

Например dict1 | dict2 объединит два словаря.

Два словаря объединит оператор бинарного ИЛИ, у одного из словаря будет вызван метод __or__, который входит в "binary arithmetic operations".


В случае с pattern matching это не так.

Такой же синтаксис у type hints в 3.10 вместо Union добавлен

Использование вертикальной черты для разделения вариантов вполне логично, ведь она означает "или".

По поводу скобок, вы, в принципе правы, но не вполне понятно, какой мог бы быть альтернативный вариант для биндинга? Угловые скобки?

Ну, а в случае бинарной операции это совсем другое. Куда логичнее было бы использовать ранее используемое or, которое точно ИЛИ.

or не лучше. Для выражения 1 or 2 можно предположить, что будет проверяться только 1, так как or возвращает первое истинное выражение

Тогда and?

Практически о том же говорит Larry Hastings:


I dislike the syntax and semantics expressed in PEP 634. I see the match statement as a DSL contrived to look like Python, and to be used inside of Python, but with very different semantics. When you enter a PEP 634 match statement, the rules of the language change completely, and code that looks like existing Python code does something surprisingly very different. It also adds unprecedented new rules to Python, e.g. you can replace one expression with another in the exact same spot in your code, and if one has dots and the other doesn’t, the semantics of what the statement expresses changes completely. And it changes to yet a third set of semantics if you replace the expression with a single _.

https://discuss.python.org/t/gauging-sentiment-on-pattern-matching/5770/21


Я эту штуку в своём коде точно использовать не буду.

В том же JavaScript принято добавлять в стандарт то, что на практике уже давно широко используется. Поэтому новые фичи проходят долгий путь от нестандартных расширений, по пути избавляясь от ошибок дизайна.

В Python все фантазии влиятельных персонажей сразу вливаются в стандарт, а потом ошибки уже не исправить, т.к. нужно поддерживать обратную совместимость. До второго пришествия Гвидо эта беда касалась, в основном, лишь непомерно разросшейся стандартной библиотеки. Но теперь эта же участь постигла и сам язык.

по пути избавляясь от ошибок дизайна.

JS - один из последних из списка современных языков в котором это заметно

Совершенно справедливое замечание. На мой взгляд введение таких конструкций просто портит язык.

Питоновский вариант без case выглядит более предсказуемым и естественным

if name in {0b001, 0b010}:print(f"Access for {name} granted with access")

elif <Что там синтаксически питоновскoе возвращающее True>:
.....

else: print("Deny")

В принципе вместо if-elif можно было бы использовать case . Но это по сути ничего не меняет в смысле написания кода.

case name in {0b001, 0b010}: print(f"Access for {name} granted with access")

case <Что там синтаксически питоновскoе возвращающее True>: .....

else: print("Deny")

Мне кажется, что python вступил в эпоху архитектурных излишеств. Началось всё с расширения функционала для более строгой поддержки типов.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории