LINUX.ORG.RU

Python VS Java

 ,


0

8

Всем привет. Ковыряю backend-сервис на Java, и вот появились такие мысли - зачем в web'e нужен Python, если есть множество фреймворков на тех же Java, C#, Erlang, NodeJS, Golang, Rust... Иным словами - я понимаю зачем в web-development нужны такие языки как Rust/C++ (скорость исполнения, математика), Java и Erlang (большие нагрузки ага), Golang и NodeJS (возможность дёшево сделать асинхронный сервис)... Для быстрого клепания уже *дцать лет как существует Smalltalk/Seaside, подобные же штуки для Perl и TCL.

Для любителей наркомании в конце концов есть Haskell, OCaml, Lisp.

Отсюда резонный вопрос - зачем современному миру web-development Python с его кривой архитектурой, GIL и python-way головного мозга большей части программистов?

З.Ы.: если что, сам ранее занимался разработкой на змеюке (пять лет) под веб. Сам на свои вопросы заданные выше ответа не нашел, о питоне вспоминаю как о страшном сне. Особенно о Django

Ответ на: комментарий от crutch_master

Да и если не чекать типы, можно сделать такую херню, которую не сразу заметишь и код будет то работать то нет или падать, но где-то в другом месте.

А можно сделать такую херню даже если ты будешь чекать типы. А нужно тупо не делать такой херни и всё будет работать. Не поверишь, но люди на сях целые ядра пишут, хотя за void* любая неведомая хрень может быть.

anonymous
()
Ответ на: комментарий от DonkeyHot

При том, что он за тебя что-то проверит, и ты можешь расслабиться.

Что он за тебя проверит? Что ты кастишь из String или Object? Оттуда всё что угодно можно кастить. СТ в яве гарантирует, что если у тебя есть Integer, то там или null или какое-то целое, а не всё, что угодно.

Никто же и не говорил, что в питонах всё лучше.

Никто и не требует, чтобы в питонах хоть что-то было лучше, раз уж на то пошло.

Впрочем, в имя аргумента инфу засунуть даже проще, чем в объявление типа

И как ты засунешь в имя переменной сложную структуру и инфу о том, что там должно быть? В доках её запишешь?

crutch_master ★★★★★
()
Ответ на: комментарий от anonymous

А можно сделать такую херню даже если ты будешь чекать типы. А нужно тупо не делать такой херни и всё будет работать.

Если откуда-то приходит запрос я обязан чекать что там пришло хотя бы затем, чтобы он не свалил мне приложение. Да у меня себя внутри я могу забить и всё делать через void*, потому что я _знаю_ что может быть в этом void*. А когда я получаю параметры с сети я без понятия что там может прийти.

crutch_master ★★★★★
()
Последнее исправление: crutch_master (всего исправлений: 1)
Ответ на: комментарий от mimico

А в твоих двух экземплярах ноды, ты постоянно будешь копировать данные.

Да какая разница? Дедлоков нет? Нет. Гонок нет? Нет. И что это за многопоток?

crutch_master ★★★★★
()
Ответ на: комментарий от crutch_master

Когда я получаю параметры с сети я без понятия что там может прийти.

Что ты мне мозги компостируешь? Когда ты получаешь параметры откуда-то из сети, ты в любом типизированном или не типизированном языке должен их проверить.

anonymous
()
Ответ на: комментарий от crutch_master

Да какая разница? Дедлоков нет? Нет. Гонок нет? Нет. И что это за многопоток?

Как это нет? SharedArrayBuffer тебе на что? Не используй Atomics и будут тебе гонки.

mimico
()
Ответ на: комментарий от anonymous

Кто? я? Я говорю:

я обязан чекать

Мне Донкихот отвечает:

Нет. «Ты» обязан вести себя предсказуемо, если тебя вызвали правильно.
Я отвечаю, что тогда надо весь код перерывать, чтобы понять как что правильно вызывать.

Ты мне говоришь что-то про доку и что можно ничего не чекать. Ок. У меня либа и функция, которая дёргает функцию другой либы. Я должен вызвать ту другую либу правильно, а следовательно чекать что мне передали. Вот и получается, что я всё и везде обязан чекать, кроме своего говнокода с void*

crutch_master ★★★★★
()
Ответ на: комментарий от mimico

Да всё равно это какое-то, я не знаю, тепличное что-ли. Тред можно на паузу поставить каким-нибудь wait, пока его другой тред не дёрнет?

crutch_master ★★★★★
()
Ответ на: комментарий от crutch_master

Чекать нужно входные данные программы: файлы, сеть, ввод пользователя.

Всё остальное чекать не нужно, оно просто работает.

anonymous
()
Ответ на: комментарий от crutch_master

Да всё равно это какое-то, я не знаю, тепличное что-ли.

Это повышение абстракций. То, что ты в других языках делаешь руками постоянно - синхронизация, атомарность - тут уже из коробки.

Тред можно на паузу поставить каким-нибудь wait, пока его другой тред не дёрнет?

Его можно полностью прервать. В остальном он и так просыпается по событиям. Еще в ноде любую функцию можно ограничить квантом времени. Но, если ты пишешь код, не придерживающийся событийно-ориентированной модели, то конечно у тебя будут проблемы. Не нужно тащить в язык принципы построения из других мест. Иначе это уровня - си говно, потому что там нет JSON'a и DOM API из коробки.

mimico
()
Ответ на: комментарий от RazrFalcon

А first class функции туда завезли? Как насчёт дженериков? И вообще синтаксис этого вашего rust придумывали явно дизайнеры или люди, желавшие выебнуться на тему «мы не такие как все».

LongLiveUbuntu ★★★★★
()
Ответ на: комментарий от mimico

Еще в ноде любую функцию можно ограничить квантом времени.

Это еще что такое и как, первый раз слышу.

Не нужно тащить в язык принципы построения из других мест.

Но так можно было бы делать нормальный синхронный код а не костыли с async/await.

Иначе это уровня - си говно

Дело в возможностях, а не в говно/конфетка.

crutch_master ★★★★★
()
Последнее исправление: crutch_master (всего исправлений: 2)
Ответ на: комментарий от anonymous

Всё остальное чекать не нужно, оно просто работает.

Я написал либу, которая получает массив чисел и возвращает сумму. Для её работы использую либу, которая складывает 2 числа. Мне в либу сунули массив строк в перемешку с числами и объектами. Как она будет просто работать?

crutch_master ★★★★★
()

Для быстрого клепания уже *дцать лет как существует Smalltalk/Seaside, подобные же штуки для Perl и TCL.

python и ruby из этой же нише, просто они народу нравятся, и задавать вопрос «почему используют Б, когда уже есть аналогичный А» некорректно, это определяется вкусовщиной и (В коммерческих проектах) реалиями рынка

annulen ★★★★★
()
Ответ на: комментарий от slovazap

Не представляю даже как подступиться к этой задаче на java.

Почему бы не спросить, если не представляешь?

Модулей в системном репозитории нет. Весь софт что я видел бандлил jar'ы зависимостей, это детский сад.

Что имеется в виду?

Но я понимаю что наверняка они ничего не знают о языке на котором пишут и есть замечательная система сборки.

Популярных систем сборки в Java две, это Gradle и Maven. Осваивать их не надо. Копипастишь

plugins {
    id 'java'
}

repositories {
    jcenter()
}

dependencies {
}

В build.gradle, вот тебе и всё освоение. В dependencies копипастишь либы, от которых хочешь зависеть.

которая скорее всего тянет зависимости бинарниками из интернета. Это тоже no-go.

Почему?

какая-то муть с версиями жавы

Что за муть?

и на 500MB VPS это потом просто не взлетит

У меня на 256 MB VPS прекрасно летает. Почему у тебя на 500 не взлетит? Небольшой сервер легко укладывается в 64 MB и этого хватит для серьёзной нагрузки, если только тебе специально не потребуется много оперативной памяти для какого-то алгоритма.

Я это просто видел два раза, не отрицию что те кто это писал тоже ничего не знают о жаве, но пробовать не хочу.

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

Legioner ★★★★★
()
Ответ на: комментарий от crutch_master

Нормальный код это асинхронный. А синхронный код - это костыли.

Это еще что такое и как, первый раз слышу.

https://nodejs.org/dist/latest-v11.x/docs/api/vm.html

Дело в возможностях, а не в говно/конфетка.

Ты можешь подцепить в ноду возможности на любой вкус написав нативный модуль, если тебе охота поизвращаться. В том числе модули для создания потоков, с wait в том числе, были с почти первых версий ноды. Просто они не нужны.

mimico
()
Ответ на: комментарий от mimico

Нормальный код это асинхронный. А синхронный код - это костыли.

Иксперды в треде!

annulen ★★★★★
()
Ответ на: комментарий от mimico

Нормальный код это асинхронный. А синхронный код - это костыли.

Лапша из колбеков или написать 10 функций вместо 10-и строчек - это не костыли, это красиво и прогрессивно.

В том числе модули для создания потоков, с wait в том числе, были с почти первых версий ноды. Просто они не нужны.

Конечно не нужны, если они кривые и не работают как надо.

crutch_master ★★★★★
()
Ответ на: комментарий от crutch_master
def sum(x, y):
    return x + y

def sum_array(a):
    result = 0
    for number in a:
        result = sum(result, number)
    return result

> sum_array([1, 2, 3, 4])
> 10

> sum_array([1, 'a', object()])
> TypeError: unsupported operand type(s) for +: 'int' and 'str'

В чём проблема?

Перестань думать за того, кто суёт параметры в твою функцию, он без твоего мнения разберётся, что ему надо.

anonymous
()
Ответ на: комментарий от anonymous

Перестань думать за того, кто суёт параметры в твою функцию, он без твоего мнения разберётся, что ему надо.

Мне надо чтобы система выдала вменяемый ответ, а не свалилась где-то хз где. Тебе похрену как ей будут пользоваться, мне нет.

crutch_master ★★★★★
()
Ответ на: комментарий от crutch_master

В том что никак.

Всё как. Ввёл херню — получил исключение.

И ты этого никак не узнаешь, пока не запустишь.

Ещё раз, в чём проблема? Ты не запускаешь свой код, когда пишешь? Считаешь, что тот, кто будет использовать твою библиотеку не тестирует свой?

Мне надо чтобы система выдала вменяемый ответ, а не свалилась где-то хз где.

Что невменяемого в исключении?

Тебе похрену как ей будут пользоваться, мне нет.

Ты не знаешь, как ей будут пользоваться. Ты не узнаешь как ей будут пользоваться.

Всё что ты можешь сделать — это быть мудаком и вставлять палки в колёса тому, кто будет её использовать не так, как ты планировал.

anonymous
()
Ответ на: комментарий от anonymous

Всё как. Ввёл херню — получил исключение.

Чтобы его получить надо обработать то, что ты ввёл. Т.е. прочекать что там за типы. И мы уходим в начало срача СТ vs ДТ.

Ещё раз, в чём проблема?

Да не в чём. Всё надо чекать, а мне говорят, что чекать ничего не надо.

Всё что ты можешь сделать — это быть мудаком и вставлять палки в колёса тому, кто будет её использовать не так, как ты планировал.

У меня есть параметр дата и я хочу получить там дату или структуру ид из какой-то таблицы и дату. Как я там вставлю палки в колёса, если прочекаю это поле и выплюну сообщение о том что там не так, объясни?

crutch_master ★★★★★
()

mimico где ты там? У меня зуб болит хоть на голове стой. Async код - костыль поверх синхронного. Пока в ноде не придумали async/await была дичь из колбеков и промисов с a.then(b) b.then(c) c.then(d) ...

crutch_master ★★★★★
()
Ответ на: комментарий от crutch_master

Чтобы его получить надо обработать то, что ты ввёл. Т.е. прочекать что там за типы.

В коде выше где что прочекано?

Да не в чём. Всё надо чекать, а мне говорят, что чекать ничего не надо.

Говорят. Куча софта написана на слаботипизированых языках и работает. Можешь свалить на жабу, если охота, но это ты должен принять как данность.

У меня есть параметр дата и я хочу получить там дату или структуру ид из какой-то таблицы и дату. Как я там вставлю палки в колёса, если прочекаю это поле и выплюну сообщение о том что там не так, объясни?

Объясняю: В питоне я могу написать свой собственный класс Дата, и использовать его везде вместо datetime.date. И всё будет работать. Кроме тех мест, где какой-то мудило написал if type(d) != datetime.date:

anonymous
()
Ответ на: комментарий от crutch_master

Как он может быть поверх синхронного, когда на самом деле все наоборот. Весь синхронный код - это костыль поверх асинхронного. Стыдно это не знать.

mimico
()
Ответ на: комментарий от LongLiveUbuntu

А first class функции туда завезли? Как насчёт дженериков?

Завезли.

И вообще синтаксис

Понеслась...

RazrFalcon ★★★★★
()
Ответ на: комментарий от crutch_master

там или null или какое-то целое, а не всё, что угодно

В таком случае я вообще не пониамю, зачем там эта статическая типизация.

в питонах хоть что-то было лучше

С ответа на этог вопрос я начал.

как ты засунешь в имя переменной сложную структуру

class PurposefulStructure:
def function(purposeful_structures):

например.

DonkeyHot ★★★★★
()
Ответ на: комментарий от crutch_master

Я должен вызвать ту другую либу правильно, а следовательно чекать что мне передали

Ты опять пытаешься отдуваться за всех.

Тот, кто передал «не то» - передал не то, независимо от того, проверишь ты этот факт, или нет. Т.е. в любом случае программа рухнет(ты же не думаешь, что он настолько умный, что поймает твою ошибку, и настолько глупый, что не посмотрит, что тебе передаёт?).

Ну, если сильно хочешь, чтобы сразу понятно кто есть кто - добавляешь tryexcept вокруг всего что-то типа:

except: raise АвторЭррМудак("какая-то фигня").with_traceback(traceback.extract_stack()[:-1])

DonkeyHot ★★★★★
()
Ответ на: комментарий от next_time

Для бизнеса нужно быстрее и дешевле, это не про жабку.

Остается или python или php.

Go появился совсем недавно. Javascript - бардак в npm.

Rust - смешно.

ggrn ★★★★★
()
Ответ на: комментарий от DonkeyHot

Не удобнее, а спокойнее. Это уже килерфича статически типизированных языков. «Для людей со слабой памятью.»

Как будто что-то плохое. В конце концов, память у человека ограниченная, не хотелось бы её тратить на то, за чем может следить компьютер.

А когда он не прав - просто не лови исключений и это уже будет не твоя проблема.

Вот так мы и получаем километровые стектрейсы. Не говоря уже о том, что есть такое понятие, как exception safety, в которую мало кто умеет.

~~@~~

anonymous
()
Ответ на: комментарий от anonymous

Не поверишь, но люди на сях целые ядра пишут, хотя за void* любая неведомая хрень может быть.

Угу, только почему-то:

1) В линуксе почему-то до сих пор регулярно находят уязвимости. 2) Там же дофига активно используемых макросов для того, чтобы достичь хоть какой-то типобезопасности. 3) В последнем стандарте C зачем-то добавили _Generic

~~@~~

anonymous
()
Ответ на: комментарий от anonymous

Угу, только почему-то:

Угу, только почему-то: 3) Несмотря на то, что «В последнем стандарте C зачем-то добавили _Generic», «В линуксе почему-то до сих пор регулярно находят уязвимости» 2) Несмотря на то, что «Там же дофига активно используемых макросов для того, чтобы достичь хоть какой-то типобезопасности.», «В линуксе почему-то до сих пор регулярно находят уязвимости.» 1) Какой типобезопасный язык не возьми, всё равно будут находить уязвимости.

Не спасают типы, ага.

anonymous
()
Ответ на: комментарий от anonymous

В линуксе почему-то до сих пор регулярно находят уязвимости.

Так в Линуксе или в ядре?
Уязвимости только в твоих pet project'ах не находят, потому что они никому не интересны.

cherry_boy
()
Ответ на: комментарий от anonymous

Как будто что-то плохое

Хорошое. Но не удобное.

память у человека ограниченная

Как я понимаю, у человеков также узкий stdout и короткая жизнь. Потому, писать ли то, что не есть абсолютно необходимо - вопрос компромиса. Раньше компы были медленнее, и их попытка догадаться, что же человек имел в виду потребляла больше жизни последнего, чем вывод им подсказок, Но компы разогнались, а stdout - нет(*), теперь выгоднее использовать автоматику (например, вывод типов и даже динамику).

Понятно, что если софт управляет самолётами, ошибки потребляют больше жизни, чем декларации, т.ч. баланс может сместиться обратно. Но «мир web-development"а пока довольно далёк от подобных проблем.

(*) IDE, генерирующая мусор вместо человеков несколько увеличила bandwidth, но это более чем компенсируется большим RTT, IMHO.

Вот так мы и получаем километровые стектрейсы

Не совсем. Длинные стеки порождаются глубокими вызовами. А это означает либо плохую комбинируемость [примитивов] языка(для упрощения жизни спрятанную за переусложнёнными фреймворками/либами), либо злоупотребление наследованием либо рекурсией, Ссылки(выше) на косолапость авторов спринга, стля, буста - проявление первой проблемы, „нормальные“ явские трейсы - второй. Третье в дикой природе не уверен, что встречал.

DonkeyHot ★★★★★
()
Ответ на: комментарий от Shtsh

Функция - это вызывабельный объект. Все в питоне - объект.

Это же не означает «всё вызывабельное в питоне - функция»: Можешь проверить isinstance-ом.

DonkeyHot ★★★★★
()
Ответ на: комментарий от mimico

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

crutch_master ★★★★★
()
Ответ на: комментарий от crutch_master

тоже самое, что делают на ЯП с СТ.

Нет же. «Моя» функция с удовольствием примет любой нужные клиенту данные. И будет работать, если тот адекватен и засунет достаточно похожие объекты. И проблюётся, если не достаточно.

СТ пошлёт меня в первом случае. А во втором, вообще сделает никто не знает что, дай ему SEGV откорковаться — если я каким-то чудом соберу это.

Внезапно получается, что CT код - неженка, которого внешние сущности (компилеры/чекеры/whoeverы) должны оберегать от всяких неожиданностей. ДТ код крепче - оберегается встроенным рвотным рефлексом.

DonkeyHot ★★★★★
()
Последнее исправление: DonkeyHot (всего исправлений: 1)
Ответ на: комментарий от PexuOne

Будто v8 мешает писать лютый нечитаемый говнокод, в котором без тестов не Найти ошибки типов. Зато мощно и гибко...

Shadow ★★★★★
()
Ответ на: комментарий от PexuOne

В жабоскрипте непрограммист быстро теряет контекст, тип переменной и момент выполнения асинхронного чего-либо.

Shadow ★★★★★
()
Ответ на: комментарий от eternal_sorrow

удобство, красота

Серьёзно? Код, в котором логические блоки выделяются отступами — удобный и красивый?

Ведь случайную ошибку форматирования, которая приведёт к нарушению логики программы, крайне тяжело обнаружить. Или как питонокод с книжки/распечатки набирать. (Я не говорю что это вот прям так повседневно нужная вещь — но иногда бывает нужно. Иначе понятие «текст программы» потихоньку теряет смысл...)

hobbit ★★★★★
()
Ответ на: комментарий от ggrn

Для бизнеса нужно быстрее и дешевле, это не про жабку.

рабочий час жаба-прогера обходится дороже, это правда, но

быстрее

слышу часто, а достоверных пруфов, что питон заметно быстрее жабки в разработке, никто не приводит

Rust - смешно.

А мне - нет. То, что питон в разработке быстрее Rust - очевидно. Но сэкономит ли он на проекте в 10000+ строк полезного кода хотя бы лишние сутки в месяц? Предположим, что батарейки используются одинаковые.

Остается или python или php.

ещё Ruby, C#, swift и objc - это как минимум

Javascript - бардак в npm.

в фронтенде он сейчас незаменим никаким питоном

next_time ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.