Comments 192
y, x = x, y
Интересно, как часто это используется? Мне не приходилось менять местами значение переменных, что со мной не так?
Ну чесно говоря, причин писать сортировку руками я тоже особо придумать не могу. Параметров key
и cmp
вполне достаточно для описания любой сортировки.
Разве что это какие-то экзотические ситуации, типа данных, не влезающих в память и требующих сортировки слиянием или каких-то специфических данных, требующих сортировки без сравнений (подсчетом/поразрядной). Но мне кажется, для большинства таких ситуаций python все равно не тот язык, который будет использоваться.
Чаще приходится делать что-то такое:
x, y, *rest = some_tuple
Но и в приведённом виде тоже приходится использовать, хотя чаще не с отдельными переменными, а с элементами списка:
a[i], a[j] = a[j], a[i]
d, self.deferred = self.deferred, None
«А вот в случае Java ничего такого не нужно — разработчики работают лишь с Java.» — то-то под тот же андроед широко используется нативный код…
Это говорит только о профиле вашей работы. Как только начинаете с железками работать — так сразу и пишете. Производительность тут может быть вообще не при чем (если мы не говорим про условный GPU, где тоже native очевидно зачем).
Но основной плюс Clojure в том, что те, кто пытается писать в ОО парадигме, но на самом деле не понимает её (99% выпускников вузов, которые не слишком интенсивно занимались самообразованием и им не повезло узнать кто такой Алан Кей, что такое Smalltalk, как расшифровывается SOLID), про Clojure даже не слышали, а даже если слышали, не смогут на нём писать. А смогут на нём писать, когда выучат и поймут такие вещи, которые сделают их более просветлёнными.
Могу и дальше продолжить, но суть проста: у любой технологии есть плюсы и минусы, выбор — за человеком. И не существует тьюринг-полных языков, абсолютно защищённых от стрельбы по ногам и на которых невозможно написать неподдерживаемый код.
И кстати, слово ВСЕМИ тут лишнее. У вас. Работа поверх JVM тоже может быть достоинством, которого Lisp на другой платформе лишен. Недостатком тоже может.
Что у JVM есть недостатки — не вопрос (хотя в чем может быть " бесконечный источник фрустрации" лично мне не понять).
Который обладает ВСЕМИ вышеперечисленными достоинствами Clojure
Не обладает и близко. Нет персистентных коллекций, нет крутых и простых примитивов параллелизма, нет библиотек Java на все случаи жизни, нет такой качественной поддержки паралелизма и оптимизаций как у JVM, нет спец синтаксиа для коллекций и т.д. Clojure это следующая ступень развития Lisp'a.
у любой технологии есть плюсы и минусы, выбор — за человеком
И что значит языки нельзя объективно сравнить по определенным характеристикам, и нужно все считать в итоге одинаково полезными для программиста практика?
бесконечного источника фрустрации
Какие конкретно фрустрации?
И что значит языки нельзя объективно сравнить по определенным характеристикам, и нужно все считать в итоге одинаково полезными для программиста практика?Объективно — можно. Заявлять о перенятых преимуществах базовой технологии строчными буквами, не упоминая о унаследованных недостатках — объективностью не пахнет.
Это я понял.)
Можете теперь перечислить конкретные недостатки JVM и Clojure?
Может быть автор исходного комментария и я не видят недостатков или что-то не считают недостатком, а вы видите. Поэтому стоит их перечислить, а не требовать от других.
Может быть тогда я соглашусь что ваш комментарий уместен.
Python содержит гораздо меньше Boilerplate code, чем Java, что упрощает разработку. Java, где много Boilerplate code из-за многословности языка, иногда ставит в тупик новичков (да и не только их), поскольку для решения простой проблемы требуется приложить значительное количество усилий.грамотно написанный на java код размером в 10..50 строк, гораздо лучше подходит под понятие «самодокументированный» код, нежели чем 5..10 строк на Питоне, которые к тому же в большинстве случаев являются вызовом каких-либо библиотек.
PS: Когда передо мной встал вопрос «какой язык (помимо java) использовать для быстрого написания простеньких тестовых утилит, прототипов и тп», я опять же выбрал golang, а не Питон и доволен аки слон.
грамотно написанный на java код размером в 10..50 строк, гораздо лучше подходит под понятие «самодокументированный» код, нежели чем 5..10 строк на Питоне, которые к тому же в большинстве случаев являются вызовом каких-либо библиотек.
Лично мне так не кажется. Возможно дело в том, что и там, и там можно писать немного запутано?
Я бы добавил, Питон сейчас занимает нишу, как Бейсик в 80-90-е, — низкий порог вхождения, чтобы начать кодить и быстро получать результат типа лабы и т.д.
Паскаль не подходит, он и компилируемый и со статической типизацией, а если вспомнить использование библиотек от borland то он ещё больше похожим на java чем на python будет.
При этом для многих языков существует различие в производительности между компилируемой и интерпретируемой реализацией.
Большое количество языков, включая BASIC, C, Lisp, Pascal и Python, имеют обе реализации
ru.wikipedia.org/wiki/Интерпретируемый_язык_программирования
p.s. это если не вспоминать про версии delphi, в их интерпретируемость я не верю :)
ru.wikipedia.org/wiki/Visible_Pascal
p.s. По сути ведь С# и Java компилируются в промежуточный byte-код который далее может быть интерпретирован, но это не делает их интерпретируемыми языками в общем случае.
В принципе и адресную арифметику можно реализовать в интерпретаторе (точно так-же как сейчас реализовано разделение адресных пространств для запускаемого кода), просто это, на мой взгляд, не имеет смысла в большинстве случаев.
Насколько я знаю, C# scripting вполне имеет место, включая и REPL. И там вроде как интерпретатор.
Смысл? Ну например в том, чтобы построить JIT на базе анализа того что происходит. Ну или отладка.
Очень часто бывает неудобно искать начало блока
Но ведь отступы для того и придуманы, чтобы блоки было сразу видно. Как они могут в этом мешать?
отсутствие классического switch case
elif его прекрасно заменяет при нормальном программировании, а при ненормальном… Ну,
def case_0(): ...
def case_1(): ...
def default(): ...
switch = {0: case_0, 1: case_1}
switch.get(x, default)()
например.
Аппеляция к нормальному программированию так себе аргумент, честно. Примерно как переход на личности.
Не переход на личности, а предупреждение о том, что приведенный пример — не самый читаемый код, и от такого надо по-возможности воздерживаться, если нужен именно switch-case. Но возможность в принципе есть.
Но ведь отступы для того и придуманы, чтобы блоки было сразу видно. Как они могут в этом мешать?
В крупных портянках — запросто.
def чтототам():
строка1
if условие2:
строка3
while условие4:
строка5
иещё100строк
строка6
нуигде(искать,начало,этого+блока)

Больше бесит вечная проблема Tabulation versus 4 Spaces, когда в одном файле смешаны табы и пробелы, то начинаются проблемы.
А tab vs 4 spaces проблема надуманная, решается либо следованием общепринятым стандартам (PEP-8 для Python, PSR-2 для PHP, etc), либо соблюдением code style guide в конкретной компании, ежели таковой отличается от PEP/PSR/etc.
2. Уплотнение кода: чтобы как можно больше смысла помещалось на квадратный пиксель (отдельная строка на закрывающуюся скобку не нужна), при этом без деградации в ASCII-art на Perl – блоки придется делать многострочными, а не однострочниками.
отдельная строка на закрывающуюся скобку не нужна
есть два стиля, скобка на новой строке и скобка на той же строке
try {
} catch() {
}
1 try {
2 if condition {
3 return 0
4 }
5 do_work()
6 } catch() {
7 handle_error()
8 }
1 try:
2 if condition:
3 return 0
4 do_work()
5 except:
6 handle_error()
Например, связка отступов и ограничения в 80(120) символов на длину строки дает индикатор сильной вложенности кода. Если программисту уже тесно вблизи 120 символов, что-то пошло не так. И надо выносить куски кода в отдельные методы/функции, что дает бОльшую гибкость при развитии проекта.
Кмк, жесткое требование форматирования кода подталкивает к написанию чистого кода.
ИМХО данный пример очень короткий, поэтому проблем "почти" нет, почти потому-что выделяя скобочками (или, как вариант, begin… end-ами) я сам выбираю как мне удобно видеть код (от варианта python-а до варианта отлаженные повторяющиеся на 95% блоки одной строкой (мы же не про большие проекты на python а про небольшие куски логики для прототипирования?), а в python у нас вариантов особо нет.
p.s. про длину портянок, я понимаю что это неправильно и т.д. но когда люди пишут простые утилиты они редко разбивают тело на функции и т.п., что может приводить к зашкаливанию "ширины" кода на python из-за отступов, также многие, даже текстовые, редакторы умеют сворачивать блоки в скобках но не умеют сворачивать блоки в python коде (и стандартный редактор под linux (idle) тоже не умеет), что в сумме делает редактирование "часто не удобным".
а в python у нас вариантов особо нет.Вам никто не запрещает в питоне в одну строку писать блок через ";". Так что варианты есть и в питоне.
не умеют сворачивать блоки в python кодеКроме собственно idle и каких-нибудь nano, vi я даже и не вспомню кто еще не умеет сворачивать блоки в питоне. Все нормальные IDE его поддерживающие (то есть все кроме idle) — умеют. Notepad++ и sublime — тоже умеют причем из коробки. Блокнот не умеет конечно, но он и скобки не умеет. У вас есть пример редактора который знает про скобки, но не знает про питон?
При этом одними скобками обойтись нельзя, а одними отступами — можно.

В случае с питоном нет необходимости считать открывающиеся/закрывающиеся скобки походу, а потому и подсветка парных скобок не нужна.
Почти все редакторы которыми пользуюсь умеют их сворачивать, кроме idle, плюс бывают ещё комментарии.
А что делать если по факту такой алгоритм, нет на питоне мне такое делать не приходилось, только на sql :) (справочники не предлагать, и так в терадате не быстро работает ;) )
Просто это был пример из жизни, который может быть неудобен в случае использования подхода с отступами (выносил из sql запроса в функцию разбор данных по двум параметрам (строкам), банальный парсинг текста с сотней масок, он реально занимает 100+ строк case when.., в два уровня. ).
если инвертировать и сделать return, то -1 ступенька «лесенки»
Это был фрагмент кода, там внизу может быть ещё пара таких же операторов.
попробуйте рефакторинг «Extract method»
… а потом попробуйте придумать новому методу имя :-)
Если серьезно, то такие портянки обычно возникают при совмещении нескольких алгоритмов в одном. И далеко не всегда их можно взять и разделить методом «Extract method», часто нужен «Extract generator», которого IDE делать не умеют...
"А вот Java — статически типизированный язык. Все типы переменных здесь должны быть объявлены. Если допустить ошибку, то программа работать не будет или будет, но с проблемами."
Программа скорее всего не скомпилится.
А вот если допустить ошибку в Python, то как раз таки" программа работать не будет или будет работать с ошибками"
Программа скорее всего не скомпилится.
Слышали ли вы о NullPointerException?
Это к тому, что вам ничего не мешает передать в типизированную функцию null
и она абсолютно так же упадет в рантайме, если проверка на null
не была добавлена.
«А вот Java — статически типизированный язык. Все типы переменных здесь должны быть объявлены. Если допустить ошибку, то программа работать не будет или будет, но с проблемами.»
Если допустить ошибку в python — то программа тоже либо работать не будет, либо будет работать с проблемами, это не особенность статической типизации.
Но при этом, в Java большАя часть ошибок на этапе компиляции отпадёт.
А вообще вы сравниваете тёплое с мягким, 'Почему люди едят апельсины, если можно забивать гвозди молотком'
catch(CCE e){throw new NPE();}
Котлин только добавил разнообразия в этом смысле, это уже вишенка на торте, если угодно.
У кого какие наблюдения насчёт разницы в скорости разработки?Не знаю как у других, но в Java я постоянно пишу с автодополнением, и в написании одной строки порой нажимаю Enter несколько раз.
И часто пользуюсь intension'ами, когда вместо
for (String s: someList) {
}
набирается просто someList.for
и нажимается Enter.String r= f!=null?f==g?g:f:g;
Хотел написать, а почему вы умалчиваете про Tcl?
Но когда прочитал внимательно вашу аргументацию про Java в сравнении с Python (а Python и Tck ягоды отного поля), все стало понятно. Возразить тяжело. И статья понравилась.
Одна из основных причин того, что Python — более продуктивный язык, — динамическая типизация.Пфф,

p.s. люблю java, но в данный момент пишу на питоне (и печалюсь)
забавно начинать спорить что лучше паскаль или бейсик для обучения программированию в 2019 году :) такие доводы странные люди выдумывают (лишь бы современный язык не брать)
Этим скриншотом вы выдаете в себе дилетанта. У питона как раз сильная типизация, но динамическая:
Сильная и слабая типизация
Динамическая типизация
Под строгой типизацией как раз имеется ввиду статическая
Кем имеется в виду? Лично вами? Тогда об этом стоило написать под картинкой (если вы не ее автор. Если вы автор, то стоило разобраться с матчастью и использовать на картинке термины в общепринятом смысле). Потому что характеристика "строгая" в отношении типизация всегда была синонимом характеристики "сильная". Никак не "статическая".
С другой стороны Oracle Number (который 38), и как с ним нормально работать через jdbc (дв хоть и не с java а с c#, но там удобная библиотека от oracle есть)?
Одна из основных причин того, что Python — более продуктивный язык, — динамическая типизация. Это значит, что нам не нужно ничего объявлять — мы просто задаем переменной имя и присваиваем значение. Python самостоятельно определяет ее тип согласно присвоенному значению.Нет. Это значит что тип переменой может поменяться во время выполнения. Питон самостоятельно определяет тип потому что он питон, а не потому что динамически типизирован.
А вот Java — статически типизированный язык. Все типы переменных здесь должны быть объявлены. Если допустить ошибку, то программа работать не будет или будет, но с проблемами.При программировании на любых языках лучше не допускать ошибок, типизация и здесь ни при чем.
связывание переменной с типом в момент присваивания не имеет никакого отношения к динамической типизации?В статически типизированных языках это тоже есть. Называется вывод типов.
Статическая типизация позволяет успешно избежать определенного круга ошибок, что дает существенный выигрыш в скорости разработки и стабильности ПО.Ну да. И в мыслях не было с этим спорить. Мне показалось что автор писал о том что на питоне можно где-то сделать ошибку и с этим жить. Оно то можно, и оно иногда даже сразу не заметно. Но это халтура какая-то а не программирование.
let s = "hello"; // тип &str
let s = s.to_owned(); // тип String
let s = 5; // тип i32
fn foo(i: i32) -> Bar { ... }
let temp = (0..5).map(foo).collect::<Vec<_>>(); // тип Vec<Bar>
Типизация все равно статическая потому что каждый новый биндинг затеняет предыдущий. То есть у нас тип переменной не меняется, но каждый раз меняется сама переменная, прошлый биндинг затеняется и вместо него в скоупе появляется новый с таким же именем.
Я не до конца понял что вы хотите, но похоже что что-то такое.
То есть по-вашему связывание переменной с типом в момент присваивания не имеет никакого отношения к динамической типизации?
Ага, такая штука называется "вывод типов".
Нет. Это значит что тип переменой может поменяться во время выполнения. Питон самостоятельно определяет тип потому что он питон, а не потому что динамически типизирован.
[sarcasm]PHP самостоятельно определяет тип, потому что это PHP, а не потому что динамически типизирован.[/sarcasm]
Ну и по второму вашему утверждению — не допускать ошибок это конечно хорошо. Только вот динамическая типизация очень легко помогает допускать эти ошибки.
На самом деле каждой задаче — свой инструмент, холиварить смысла нет, есть смысл учиться выбирать нужный инструмент, при необходимости изучать новый инструмент, тем самым развиваясь как специалист. Где-то лучше использовать Java, где-то возможно выиграет python, php, *sh-скрипты, etc. Где-то динамическая типизация может быть полезной, где-то наоборот только вредить будет.
Хаскель вон тоже может вывести тип, но он статически типизирован. А в java не завезли. Это не зависит от типизации же.
Псле освня слпго дстпльцвго мтда лкнчнсть трят свй шрм.
Если посмотреть пример:

То в Java для выражения одной и той же простой концепции надо 10 раз его повторять, соответственно читатель не уверен, что код полностью следует какому-то паттерну и ему надо это перепроверять.
class Person{String name;} printName(person.name).
ну или lombok: data class Person{private String name;}
Про lombok я в курсе в общих чертах. Это стандартизировано? Насколько инструменты это поддерживают? (например rename refactoring поймет, что надо переименовать getName и все, что его использует?)
rename норм, ломбок при компиляции дописывает эти методы,
тык в этом — то и проблема — для этого надо чтобы весь джавовский тулчейн знал про то, что ломбок генерирует эти методы — я поискал — нашел старые эклипсовые баги на эту тему.
Сегодня как раз вышла хорошая статья про стоимость лаконичности питона
"Проведенный эксперимент показывает интересные результаты. С одной стороны, при таком подходе производительность выровнялась, но с другой — пропала лаконичность"
Примеры в статье хорошо показывают подводные камни использования питона именно для спарка, но они вообще ничего не говорят про питон сам по себе.
И еще статья хорошо показывает лаконичность питона в сравнении со скалой — и там видно, что это точно миф, скала как минимум настолько же выразительна, или лучше.
Неужели тот факт, что питоновский код нужно отдельно переделывать под спарк, действительно как-то характеризует питон сам по себе? И неужели противоположное мнение действительно нужно наказывать минусами в карму?
В статье сравнивается со Скалой, а не с джавой.
Например, переведите это на джаву:
case class AucAccumulator(height: Int, area: Int, negatives: Int)
Вас не смущает, что для использования например nympy нужно сделать pip install? То есть, установить что-то (для случай кластера это особо актуально, потому что это нужно накатить на каждый его узел).
А мне для использования скалы или груви в общем случае и этого не нужно. Если мне в экосистеме JVM нужна лаконичность — у меня ее сколько угодно, и очень давно. Есть обширный выбор лаконичных языков, и многие из них лучше питона (опять же — на мой личный вкус, но мы вполне можем это обсудить, и я это утверждение могу легко подтвердить фактами).
>Например, динамической типизации?
А это не следствие одно другого? В смысле — лаконичность же она в том числе от того, что не нужно типы указывать, например.
Дело в том, что основная ошибка автора (не переводчика) состоит в том, что он считает скалу (груви, кложу, котлин) чем-то отдельным от java.
Если для вас все языки на jvm называются "java" то какой термин вы используете для обозначения самого языка java?
А это не следствие одно другого?
В некоторых языках со статической типизацией можно указывать типы гораздо меньше чем в java. А в питоне надо при каждом использовании полей объекта писать self.
>В некоторых языках со статической типизацией можно указывать типы гораздо меньше чем в java.
Это щас было про var? ;) В смысле, еще меньше чем ничего?
Я стараюсь не путать экосистему и язык. И пишу я под экосистему по большей части. И да, это иногда путает, когда именем языка обзывают экосистему.
Например, динамической типизации?
Равно как и то и другое может играть эту роль. Если задаться целью, то можно провести исследование и выяснить это более точно
Например, переведите это на джаву:я только в общих чертах представляю себе scala, но насколько понимаю, речь идет про «сравнение по содержимому», другими словами есть некий метод, который использует аргументы конструктора, чтобы построить некий hash и сравнить по нему. Если бы такое потребовалось бы, то я бы реализовал бы нужные hashCode, equals и тп и сравнивал бы, хоть по образцу, хоть динамически возникшие инстансы. Вы же не думаете, что это автоматом +50% к коду по всему проекту?
Если у вас есть опыт питона, и нет Node.js — то почему нет?
А если абстрагироваться от этих дополнительных переменных типа опыта, рынка вакансий и т.д.? Меня сейчас интересует только возможности инструмента.
Допустим, формируется новая компания с новым проектом, предстоит выбор стека и создание команды. Какое технологическое преимущество может предложить питон в такой ситуации? В каких типах проектов, кроме датасайенс, питон может быть полезнее других инструментов?
Можно сказать, что язык 1 лучше по таким-то критериям (да и то, они вполне возможно будут не технические, а типа «лучшее сообщество»), а язык 2 — по другим. Но вам же не это нужно для выбора.
даже спрошу по другому:
А как вы думаете, на чем сейчас пишут проекты?
А учитывая что ИТ вообще штука дорогая, а в мире не особо много богатых людей и стран.
и дело тут не в университете что там преподают, а в том на чем разработчиков больше и они дешевле. а остальное уже демагогия… правильно/неправильно — неважно, важно то что нужно бизнесу и что это работает.
Я работаю в крупной ИТ-компании. У нас питон — один из основных языков. Хотя нет особых проблем с тем, чтобы нанимать/обучать людей для работы с C++ и джавой (и эти два языка активно используются тоже, просто в других проектах).
В команде, где я работаю, есть по крайней мере несколько людей, которые в универе учились программированию на C++, но никто из них не считает, что питон — не подходящий язык.
Почему программисты продолжают использовать многословный Java, хотя есть лаконичный Python