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

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

Спасибо большое за пост. Он пропитан Вашим опытом и написан с уважением ко всем языкам программирования.

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

А тут всё очень хорошо и мысли правильные написаны. Позволяет поразмыслить над программированием в целом, а не думать в разрезе кодирования на языке Х.

Не все мысли автора правильные

Что же тогда делать начинающему программисту?

Ответ — научиться быстро осваивать новые языки.

Не надо начинающему учиться быстро осваивать новые языки - быстро не получится. Синтаксис языка - это еще не все, дальше есть инструментарий ide, сборка, тесты и фреймворки, которые потребуются для написания проекта сложнее "hello world". И на это все уйдет время - куча времени на каждый язык и умножить на N изученных языков. Куча времени, просто для того, чтобы наработать практику освоения нового языка, даже без его применения хотя бы в одном рабочем проекте.

… Обычно изучение нового языка занимает несколько дней, иногда недель, но C# я выучил за двадцать минут.

просто магия, хотя нет, не магия, а всего-лишь есть нюанс

Я много лет писал на C++, потом неплохо освоил Java и оказалось, что все основные концепции C# были мне знакомы. Знатокам C# напомню, что речь идёт про 2003 год, когда в языке не было ни LINQ, ни async/await, ни даже обобщённого программирования.

Раскрываю секрет фокуса. За 20 минут не язык выучил, а просто выяснилась огромная схожесть Java / C#, что и сыграло на руку. Попробуйте этот же фокус - «изучение» нового языка за 20 минут - проделать в несколько другой ситуации. Исходные условия практически те же самые, даже несколько лучше - вам известны несколько ЯВУ, причем в идеале. Список ЯВУ могу расширить - c# / java / delphi / c / c++ . Вам надо изучить за 20 минут один из следующих языков - javascript, python, lisp, ruby или возьмите любой другой не сильно похожий на известные c# / java. Справитесь, за 20-то минут или за 1 час хотя бы? А код, который напишете, даже если рабочим будет, не вызовет ли на ревью реплику "да, можно и так написать, но на нашем %языке% так не пишут" - и вас заставят, если сроки не горят, код переписать более привычным для проектного языка способом.

Я открыл MSDN, прочитал несколько страниц, и написал первый код, который сразу ушёл в прод.

Похвально. Но те 20 минут, которые потратились на изучение MSDN по конкретной тематике - все же не весь язык и даже не бОльшая его часть, достаточная чтобы потом писать самостоятельно, не прибегая ежедневно обратно к помощи MSDN. Да автор и сам раскрывает секрет фокуса:

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

То есть с одной стороны потребовалось время для выяснения концепции делегатов (заглянуть в MSDN), а с другой стороны дополнительное время, чтобы уложить в голове всё, что связано с новинкой. И это будет не 20 минут, не час и даже не один день. Просто время, требуемое на обучение, размазалось по дням. И да, первые код в прод ушел через 20 минут, но это сработает только там, где ситуация вот прямо сейчас надо, а потом дадим тебе неделю времени разобраться с делегатами. В противном случае это будет 20 минут на написание кода (кстати, без тестов вообще?), затем ревью и переделка - и тут вам придется потратить несколько часов на изучение как правильно, если на ревью не покажут "вот так должно быть". А сегодня на собеседовании без знания делегатов соискателя не завернут разве что с позиции джуниора.

Вот вы придираетесь-то.

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

Нет тут никакого фокуса. Я даже после нескольких лет ежедневного программирования на одном языке не могу сказать, что я его «выучил», если рассматривать это слово только как конечную остановку вида «всё, я знаю все 100%».

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

ИМХО - уровень знания «не знаю всех концепций и конструкций языка, но могу быстро написать prod-ready код, который решает поставленную задачу» можно назвать словом «выучил». Так же, как этим словом можно назвать тот уровень, который описываете вы, с детальным погружением в концепции, специфичные именно для этого языка. Или даже более глубокий уровень, с пониманием нюансов компилятора/транслятора/интерпретатора и эффектов, которые они оказывают на производительность полученной программы при обработке немного по-разному состряпанных фрагментов кода.

Всё зависит от конкретной задачи, которую необходимо решить.

Даже принимая во внимания ваши аргументы, автор лукавит. Думаю, что за 20 минут ему не удалось разобраться, например, в нюансах работы моделей памяти JMM и CLR, хотя бы потому что последняя очень скудно специфицирована. Думаю, что ключевое слово dynamic автор тоже обошел стороной. Быть может даже не использовал typeof(T) первое время. За 20 минут он открыл IDE и стал писать Java-код на C#, благо синтаксис позволяет.

В свое время, осваивал, в качестве хобби, Rust после обширной практики на питоне. Ушло два месяца на то, чтобы разобраться с растбуком. Просто - много концепций, которые, при работы с высокоуровневым ЯП, не используются.

дальше есть инструментарий ide,

Visual Studio или Inteli Idea поддерживают уйму языков. есть примерно 80% вероятности, что сменив язык не придется менять IDE

сборка, тесты и фреймворки

Освоить maven после make проще будет, и это явно не те знания, которые надо долго изучать. Это простые инструменты.

Да, 20 минут на язык это конечно единичный случай. Так же можно вообще не зная язык поправить какой-нить простой баг (или даже более сложны с помощью SO), но если ты сеньор в одном языке, у тебя будет ощущение правильности решения и в другом языке. Особенно если ты в принципе знаком с несколькими языками и подходами - а это уже важно, исправить код костылем, велосипедом, или чем-то похожим на дело и понимать это.

Соглашусь, что джуну хотя бы один язык выучить, а потом уже двигаться дальше. Не соглашусь, что у автора "фокусы" — он просто рассказал историю из жизни. С другими языками 20 минут не вышло бы, вышло бы скажем пару недель/месяцев, но в той ситуации вот так совпало.

Священная война между Pascal и C, которая шла все восьмидесятые, как-то обыденно закончилась победой C

Добавил бы к посту еще что люди участвовашие в "священных войнах" просто повзрослели, как и индустрия в целом.

Иногда даже скучно что и на Хабре сейчас холиваров стало меньше =)

Давайте обсудим, кто победит в энтерпрайзе, Java или C#?

Священная война между Pascal и C, которая шла все восьмидесятые, как-то обыденно закончилась победой…
третьего ЯП ))))

Вопрос особенно ироничен, учитывая существование Kotlin

Есть подозрение, что после того, как комитет по джаве очнулся и начал делать нормальные новые версии языка котлин потеряет свою актуальность. Поживем-увидим, конечно.


Та же история с F# же произошла.

Боюсь F# ещё многому сможет научить C#. А вот CoffeeScript действительно пнул js и умер.

Спасибо, написано качественно, читается легко, НО не соглашусь что высокие зарплаты обязательно там где что-то популярное, часто наоборот если что-то редкое то на него сложно найти человека и иногда пытаются высокой зарплатой приманить. Ну и для написания сайтов на С++ есть готовые фреймворк, даже я один видел, хоть и не пишу на c++.

Java уже давно победил в энтерпрайзе, потому что он был кроссплатформенным задолго до того, как C# начал двигаться в сторону кроссплатформенности.

Это не единственный аргумент.

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

Написать приложение на C# + WPF довольно просто и быстро, а вот сколько я не задавал вопрос гуглу java desctop. Так много ответов было в духе, что java это не про десктоп вообще сейчас.

НЛО прилетело и опубликовало эту надпись здесь
Для десктопа истинная кроссплатформенность, как она есть в Java — это как раз зло. Т.к. добиться реально «нативного» UX можно будет только на одной платформе — на других будет в лучшем случае чужеродный интерфейс, в худшем — куча странно работающих костылей.
В энтерпрайзе единый (пусть и чужеродный) интерфейс — ещё нормально (один раз обучил бабушку — работает везде). А вот для обычных прикладных приложений — не удобно.

С netcore, кстати такая же проблема есть — годик назад писал кроссплатформенную кастомную печатолку всяких форм на специализированных принтерах linux+win (именно в таком порядке). Так и не получилось сделать нормальный виндовый интерфейс на винде простыми методами(не то что бы я сильно заморачивался).

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

добиться реально «нативного» UX можно будет только на одной платформе — на других будет в лучшем случае чужеродный интерфейс

Было бы желание. Да, оно, конечно, не pure-java на самом нижнем уровне, но само приложение вполне себе java.

не задавал вопрос гуглу java desctop

А если поискать "java desktop"? Там же полно.

В конце XX века, IBM интегрировал свои дистижения, и, 'родил' Eclipse. ( как это получилось - см. здесь, но там не про desktop: https://vfedorov.info/GEFwiki/Wiki.jsp?page=GEF%20Preface%20%28GEF%29 (user/pwd: anybody/123123) Отжившие свой век AWT/Swing - в Eclipse заменен на SWT/JFace. В основе SWT - нативный код на C (для каждой платформы linux/win/mac|32|64 - надо предоставлять соответствующую сворку. Издержки однако :)

Галопом, по европе - тут: https://betacode.net/10177/ - "Какую платформу я должен выбрать для разработки приложений Java Desktop?", вопрос ведь в этом?

Кстати, после 17 лет 'кувыркания' в кодах от Eclipse-консорциума, мое обращение к C# & WPF - навеяло симбиоз Java & GWT (это ужасней). Конечно, для данной реализации концепции решения, следует отдать должное инструментарию Microsoft. Однако под Linux они его не затащили! ;)

Достаточно сложно вхождение в Eclipse (не в IDE) - без методологии изучения потребуется больше времени. Для относительно 'легкого' знакомства, без блуждания по www - несколько ссылок (спасибо Ларсу Фогелю!!!):

https://www.vogella.com/tutorials/SWT/article.html

https://www.vogella.com/tutorials/EclipseDialogs/article.html

https://www.vogella.com/tutorials/EclipseRCP/article.html - это уже 'тяжелая артиллерия'

https://www.vogella.com/tutorials/EclipseWindowBuilder/article.html - это Window Builder (однозначно к нему кто-то от Borland приложил руку ;) (кстати, одним из 9ти отцов-основателей консорциума Eclipse - является Borland)

Window Builder написали я и ещё три человека из маленького города Липецка. Ни один из нас не работал в Borland. Но мы очень любили их продукты, это правда :-)

Молодцы! (что WB 'родили и пестовали'.)

Успехов.

Давайте обсудим, кто победит в энтерпрайзе, Java или C#?

Это элементарно.
В интерпрайзе всегда побеждает хозяин интерпрайза :)

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

Нас учили, что нужно начинать с изучения семантик. Собственно мы это и делали.

Начинать учиться можно с чего угодно. А вот начинать работать - да, лучше с чего-то строгого.

осталось выяснить, зачем переучиваться обратно

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

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

Python такой приятный после многих лет на плюсах

Не осилил питон после многих лет на плюсах, ушёл на хаскель.

как раз его изучаю сейчас из любопытства - там такое пространство для говнокода… еще и динамическая типизация. После kotlin ощущение что попал на вечеринку подростков :)

Но реализация ввода-вывода понравилась простотой. Понятно почему питончик так любят в автоматизации.

Зато запуск процесса это что-то с чем то, куча вариантов как это можно сделать и все они глючные в том или ином случае.

Ну справедливости ради, на Котлине тоже можно неслабо так наговнокодить :) Если использовать расширения везде, то когнитивная нагрузка сильно возрастает и становится очень сложно понимать что код делает и что откуда вызывается.

Кто ж спорит - было бы желание ) На котлине говнокод даже более забористый чем на Java получается, как раз благодаря расширениям в расширениях через расширения... Ну и вложенные лямбды.

Но в Питоне (на мой вкус) самое зло кроется в динамической типизации, позволяющей легко сунуть стрингу туда, где был int. Ну и синтаксических странностей хватает

На днях решил написать на пробу небольшую поделку для себя на питоне. Спустя пару дней, горы костылей и не менее костыльных библиотек плюнул и написал все на привычном C.
Мне js (node.js) показался как-то внутренне стройнее что-ли.

В противовес моя история началась с Python для решения алгоритмических задачек. Обучаясь дальше питону понять программу с несколькими классами в начале было очень сложно. Перейдя на Java (не такой уж и даунгрейд по классификации) с его обязательным ООП, структура программ и само взаимодействия между объектами стали гораздо более прозрачными и понятными, особенно для новичка

и ручным управлением памятью

Вот не надо, пожалуйста. Учиться программировать и так непросто, не нужно сюда ещё и сложность с ручным управлением добавлять.

Когда я учился программировать единственным вариантом с автоматическим управлением памятью был SmallTalk...

Я любил Modula 2

Т.е. с С или С++?

или Rust

Там можно над низменными деталями сильно не задумываться (разве что в unsafe, но зачем брать unsafe для обучения низкоуровневой разработке).

Все верно написано. У меня примерно такой-же опыт, но развивался я чуть в другом направлении: Си, Delphi, Perl, Ruby, Go. По пути немного Java, Python и C#. Но суть вся та-же. Языки все разные и не стоит зацикливаться именно на них. Шаблоны проектирования, инструменты разработки и интеграции - это то, что однозначно пригодиться при выборе любого языка программирования.

*тся

Про языки непрограммирования тоже не стоит забывать (:

Естественно. Этому меня еще учитель физики в школе научил. :))) Но иногда, в процессе набора текста могу и ошибиться. :)

Почему "непрограммирования"?

С помощью этого языка мы программируем нашего собеседника. Искажение программных конструкций человеческого языка вызывает соответствующую реакцию: программируемый либо вовсе не понимает программирующего (приблизительный аналог: if...ten...else), либо понимает не так (аналог: использование ">" вместо "<").

Так что тщательнЕе нужно относиться к своей речи, други-программеры! И поменьше говнокодить мутный поток сознания :)

А HTML - это тоже «нишевый» язык как SQL? ;) Вроде не императивные и не функциональные… а может, они и не языки программирования вовсе…

А если серьезно, то я бы порекомендовал начинающим войтишникам (и не только) почитать «Структуру и интерпретацию компьютерных программ».

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

Думаете, уже на линейной рекурсии надоест (глава 1.2, страница 49)?

Она не советская :)

Возможно, я деформирован профессионально, но если заявленная цель - научиться быстро разбираться в любом новом языке, то для этого необязательно штудировать много разных учебников или language reference’ов. Может оказаться, что новый синтаксис выражает уже известную концепцию. В SICP их много, и объяснены нескучным языком.

А я бы им рекомендовал оставить это и дальше пылиться на полке, да взять книжку ISBN: 978-5-4461-0587-8 “Теоретический минимум по Computer Science”.

Он не язык программирования вообще, так что вопрос снимается сам собой

Ну, не знаю, не знаю. Поговаривают, на голом HTML удаётся делать конечные автоматы. А в сочетании с CSS он вообще становится Turing complete.

Лучший язык

Я ждал подобного комментария.

Ну и в чем человек не прав?)

На момент моего прочтения статьи упоминания Rust не было. Да и сейчас нет громкого крика.

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

Хаскель конечно самый лучший язык, разве могут быть какие-то сомнения?

Его не сделать консистентным без того, чтобы совсем сломать имеющуюся кодовую базу, увы.

А что в нём поломано сейчас?

Не получится выразить тотальное подмножество языка (с сохранением совместимости, да). А без этого вы не будете уверены, доказали ли вы на самом деле что-либо, когда написали тайпчекающееся тело функции fmap-id-holds :: forall (x :: MyData a). fmap id x = x, или оно там просто внутри где-то неявный боттом использует, которым населён любой тип.

Часто вижу про bottom в разделе «но из-за него не получится». Похоже на «Null References: The Billion Dollar Mistake», но в Java/C# кое-какие подвижки ухода есть, есть ли такие же в Haskell?
с сохранением совместимости
И что поломается без этого bottom?

Без боттомов поломается примерно всё, и, в частности, тьюринг-полнота :]


Избегать боттомов слишком тяжело, куда тяжелее, чем избегать нуллов. В частности, чтобы у вас не было боттомов, нужно, чтобы у вас не было незавершающихся функций (либо очень аккуратно маркировать завершающиеся и незавершающиеся функции, чтобы из различать) — иначе вы любое утверждение можете доказать тривиальным образом, в стиле


stupid :: True = False
stupid = stupid

Кроме того, это означает, например, что вы теперь должны разделять данные и коданные, а те же списки в хаскелевском прелюде — это и обычные данные (когда они конечные), и коданные (когда у вас есть какой-нибудь enumFrom 0, генерирующий бесконечный [0, 1, 2, ..]).


Теоретически, наверное, можно что-то разумное построить, но ИМХО проще воспроизвести хаскелевскую экосистему на идрисе.


Естественно, все эти претензии исходят из пресуппозиции, что вам нужны завтипы. Но как можно из этого не исходить в 2021-м году, я не знаю.

Если в нём засахарить монаду State (как в Kotlin засахарена монада Option), разумеется протаскивать \ снимать признак "где-то в кишках ссылается на mutable type" надо встроенным средством рефакторинга - то может быть.

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

Например? Какого сахара не хватает для State, и зачем нужно часто протаскивать/снимать признак мутабельности?

====================================
Этот пролог был добавлен чуть позднее:
Ну вот смотрите в Scala есть иммутабельность коллекций, но это нетранизитивный признак, т.е. в данные в иммутабельной коллекции могут поменяться "подвержены эффектам" - т.е. List[SomeClass] это совсем не иммутабельная штука.

Но блин мутабельность данных штука-то удобная: начиная с банального "счётчик у дерева - сколько раз посетили", заканчивая честно-мутабельным полем у структуры.
Но тадам: у нас есть хаскель, который умеет управлять эффектами. Надо только вместо монады State ввести нормальный эффект "мутабельная переменная", с которой было бы удобно работать.

Разумеется надо:
- а) помечать мутабельность явно (непосредственную и транзитивную)
- б) с этим надо уметь работать, видимо точно так, как с монадой State, с точки зрения выполнения инвариантов (кода программистом \ работающей программы при оптимизациях компилятором)
-в) безболезненно вносить мутабельное поле в структуру данных, без изменения большого куска кода (или в соответствии с п.а) - пусть много кода меняет средство разработки).

Дальше ответ на ваш вопрос - но он наверное более технический.
==========================================

Сахара - чтобы поддерживать мутабельные структуры а не городить огород, кажый раз через State или городить огород "недо-замену" на иммутабельных структурах
Более того, чтобы поддерживать мутабельные структуры "обычном синтаксисте - ХЗ как его назвать, expression-syntax, без перехода в do-notation).

Зачем компилятору протаскивать \ снимать признак:
Ну вот предположим было:
data Student = Student { name :: String, gender :: Gender }

Вдруг мы осознали, что в современном мире живём и нужно:
data Student = Student { name :: String, mut gender :: Gender }

Компилятор доправит нас здесь (и явно везде вверх по структурам данных \ типам):
data var Student = Student { name :: String, mut gender :: Gender }

В итоге:
- В типах выражены те структуры, которые не immutable - ну и соответственно подсказка для компилятора, что и насколько агрессивно можно параллелить \ менять порядок исполнения - подозреваю что правила для компилятора будут те же, что и с монадой State.

- var (транзитивно мутабельный) отличается от mut (непосредственно мутабельный). При удалении/добавлении mut(вдруг я осознал, что mut gender : :Gender - излишне современно) - можно попросить компилятор "привести в порядок все зависящие от него типы\структуры на предмет var"

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

Ну так просто возьмите и обновите этот счётчик. ghc нередко может это скомпилировать во вполне мутабельный код (если докажет, что других ссылок на этот объект нет, или если вы линейными типами воспользуетесь).


Если таки нужна мутабельность — заверните в MVar/TVar. Система типов скажет, где обращение к этой переменной надо будет завернуть в MonadIO/STM/чего там ещё.


Но автоматизировать такой рефакторинг сложно, потому что не любое обращение к структуре с мутабельной переменной требует этой самой мутабельности, например.


Вдруг мы осознали, что в современном мире живём и нужно:
data Student = Student { name :: String, mut gender :: Gender }

Ну пишете gender :: TVar Gender уже сегодня (хотя не знаю, зачем, если можно просто сделать student' = student { gender = Bale } и выкинуть старого студента).


Компилятор доправит нас здесь (и явно везде вверх по структурам данных \ типам):
data var Student = Student { name :: String, mut gender :: Gender }

Зачем здесь var? var здесь не нужно. Сама структура от этого не поменялась, поменялось только её поле.


Если я считываю только имя структуры, но не её пол, то какое мне вообще дело до самого наличия этого самого пола, не говоря об эффектах его считывания?


В типах выражены те структуры, которые не immutable — ну и соответственно подсказка для компилятора, что и насколько агрессивно можно параллелить \ менять порядок исполнения — подозреваю что правила для компилятора будут те же, что и с монадой State.

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

Добавлю, что пониманию принципов языков программирования в целом очень помогает книга Т. Пратта "Языки программирования. Разработка и реализация".

Очень хорошо сформулировано, респект!

Я ведь не поверил, увидев плюсики под статьей с таким названием, разве так бывает? А почитал, понял, да, бывает. Лучшая статья на эту тему. :)

Кстати, C# легко дался, думаю, не столько из-за Джавы и Си, сколько из-за Делфи, если не ошибаюсь, Майки какого-то крутого мужика, дизайнера библиотек для Дельфи к себе переманили задизайнить дотНет. Мне в начале нулевых библиотеки Java показались какими-то дурацкими и инопланетянскими, а вот на C# очень легко после Delphi перешел.

habr.com/ru/post/314616
Точнее создателя турбо паскаля и дельфи. А потом он еще Тайпскрипт сделал.

Согласен про Delphi полностью, но Java дейсвительно очень похожа.
Они как бы пересекаются разными подмножествами фич и концепций.
Я бы сказал так, делфи - язык, прыгнувший дальше всех от языков с ручным управлением памятью (с/++/paskal) к языком со сборкой мусора (c#/java)

Я тоже бывший дельфи-формошлёп, и мне тоже как-то очень понравился C#. Сейчас я пребываю в уверенности, что лучший язык программирования - это C#. А ведь когда-то я также и про Delphi думал.

Delphi всё же не язык, а среда быстрой разработки (RAD). Язык - диалект Object Pascal, вроде бы. А суть Delphi в её библиотеке форм и классов (VCL), подозреваю.

Имеет такое право говорить, т.к. перестал использовать RAD Delphi как раз в 2002:

"...начиная с Delphi 7[3], в официальных документах компании Borland название Delphi стало использоваться для обозначения языка, ранее известного как Object Pascal."

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

Хе-хе. Описался, надо было написать "Имеете такое право говорить...", не "Имеет...".
Это что-то меняет или наоборот?

Не знаю, у меня полное ощущение что у C# порог входа в разы меньше, чем у джавы, до сих пор. Неважно после каких языков. Просто берешь и пишешь.

А вот как берешь минимальный модуль на java, с его public protected final static (или как там правильно) перед названием каждого метода - и уныние нападает на тебя...

Как говорили раньше: Java - это улучшенный C, а C# - улучшенная Java.

Впрочем мне, начинавшему с Фортрана и C, а Java изучившего позже C#, Java оказалась более приемлемой. Дело вкуса в данном случае. И текущих задач!

А вот как берешь минимальный модуль на java, с его public protected final static (или как там правильно) перед названием каждого метода - и уныние нападает на тебя...

Как будто от C# хоть чем-то отличается... В C# и java практически одинаковые области видимости и все объявления нужны ровно в тех же случаях

у меня полное ощущение что у C# порог входа в разы меньше, чем у джавы, до сих пор.

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

Мне синтаксически шарпы при этом ближе, а вот экосистема джавовая больше нравится

XSLT в свое время изрядно поломал мне голову. Жаль, что про него в статье ни слова. До сих пор использую в проектах с простейшей MVC идеалогией. Трансформация на бекенде.

XSLT как черная дыра, сама закопала себя под своей тяжестью. Слишком монументальный, слишком перемудренный, фактически обогнал свое время и никто его не понял. У меня до сих пор лежит толстенная книга по XSLT, тогда в 2009-ом думал, что за ним будущее )

В 2007-м мы истово верили, что за XSLT будущее, и оно правда было за ним... Просто недолго. Потом наступило другое будущее.

Когда-то C, не говоря уж о C++, считали языком высокого уровня.

Просто на ассемблерах пишут 3,5 человека. Мейнфреймы нынче не те...

А так да, всё, что не ассемблер и не машинный код - высокого уровня.

Учите Rust и Python. Они не просядут через 3-5 лет.

Тогда не было ни Python, ни Ruby, ни C#

Питон с рубями были уже. Рельсы с джанго не было.

Всё верно. Однако, можно пойти дальше - создать 'свой язык'. Конечно, просто так, без причин - это абсурдно. Но, если есть требования, предпосылки, то порой продуктивней работать с кастомизированным, специфичным языком (DSL), чем создавать надстройки на языке 'общего назначения'. (язык может служить только лишь для описания данных, как CSS). Как сделать 'свой' DSL, см. https://vfedorov.info/XtextXtendWiki/

user: anybody

password: 123123

Технологически (есть инструменты, кодовая база), в "нише Eclipse", - можно создать графический DSL, или объединить и графическую нотацию и текстовую (и много другого). На эту тему есть тонны материала, дело за малым - решить вопрос внедрения в массы. (Eclipse - это не IDE)

Согласен что Eclipse это не IDE, это бенчмарк и отопительная система в одном флаконе.

А-а-а, использовать под разработку на android? Да, проблематично. Давненько пробовал пару раз... Бросил. Да и разработка на C/C++ - не нативно и коряво там (не для этого его заточили). Не так 'гладко', как, скажем для Java. Хотя и для Java - строит в памяти AST всех открытых одновременно проектов, и если исходников море - может привести к деградации... А тормоза при первой загрузке IDE - удручают, особенно под Windows, который усугубляет проблему антивирусом (1й старт - 45сек., 2й старт - 5сек.).

В целом, Eclipse - это монстр (на 2018 год, в консорциуме - 465 млн. строк opensource кода различных проектов). Причины появления Eclipse - см. тут: https://vfedorov.info/GEFwiki/Wiki.jsp?page=GEF%20Preface%20%28GEF%29

anybody/123123

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

НЛО прилетело и опубликовало эту надпись здесь

В 2003 году в C# не было фич, даже дженериков, по-сути это был Java-подобный синтаксис и библиотеки Delphi (ну или точнее - развитие библиотек Delphi), так что перейти с Делфи зная Си или Джаву не представляло никаких проблем.

НЛО прилетело и опубликовало эту надпись здесь

Разве в статье было написанно про переключение с одного языка на другой за 20 минут? Там буквально "выучил за 20 минут". Что такое выучить? По-сути - разобраться с синтаксисом и с базовой библиотекой. Речь не идет о мастеринге, тут понятно, нужно намного больше времени, но чтоб начать писать какие-то даже не слишком простые вещи этого достаточно.

А теперь давайте подумаем, возможно ли было это сделать? Понять синтаксис C# из .NET 1.1 уже зная Java тех времен можно гораздо быстрее чем за 20 минут, т.к он был практически одинаковый. Да даже сейчас, можно на литкоде решить задачку на Java потом скопировать решение без изменений в C# и оно зачастую заработает, ну или потребуется минимум изменений, ибо базовый синтаксис и базовые типы данных очень похожи. Ок, а что там с базовой библиотекой? А у .NET 1.1 она была прям до боли знакома тому, кто переходил в C# с Delphi. Даже мастер форм в Визуал Студии тех времен был прям как в Delphi.

переключиться с синтаксиса одного языка на другой занимает больше 20 минут

Смотря для чего. Ивестигейтить какой-нибудь баг лазая одновременно и C# и JavaScript коду - вообще никаких проблем, думаю, многим фуллстак разработчикам так приходится делать время от времени. Кодревью разных языков - да не проблема. Понять, что написанно - тоже. Что-нибудь отрефакторить - тоже. Вот начать какой-нибудь проект с нуля в каком-то одном языке, если только-что плотно работал с другим тут да, проблема, надо переключаться. По крайней мере мой личный опыт такой.

НЛО прилетело и опубликовало эту надпись здесь

Простите, но почему вы не хотите прочитать того, что вам пишут?

Ну ладно, попробую еще раз. Перед тем, как начать учить C# автор уже знал Java и Delphi. C# тех времен это синкансис Java, базовые типы Java + библиотека Delphi. Найдите, пожалуйста, мне на таких условиях язык, чью базовую библиотеку я знаю по одному языку и чей синтаксис я знаю по другому языку и я сделаю вашу задачку на этом языке, даже попытаюсь не заглядывать в документацию по этому языку.

В педагогике, во всяком случае в прикладной педагогике - так как это объясняет преподаватель кружка родителям, есть понятия "знание -> умение -> навык".
Каждый следующий уровень - качественно отличается от предыдущего.

Вы и говорите на разных языках.
Ваш оппонент о "знании", а вы как минимум об "умении".

Учить C# мне надо было, чтобы написать пару-вебчастей для SharePoint. Его первая версия как раз вышла в 2003-м. За 20 минут я написал первую полезную веб-часть, которая попала на портал, и там работала. Дело было действительно в том, что C++, Java и C# были в то время очень похожи.

Добавьте это комментарий в вашу статью (можно p.s.), а то как я понимаю многих раздражает "20 минут на изучения с#"

Спасибо. Думаю, вы правы, надо бы этот момент смягчить, но тогда авторы комментариев окажутся в странном положении — комментарии будут про то, чего в статье нет. Я учту этот момент на будущее, а тут пусть останется, как есть. Новым читателям по крайней мере будет понятно, за что автору "прилетает".

НЛО прилетело и опубликовало эту надпись здесь

Нормально он написал, хватит докапываться до формулировок.

НЛО прилетело и опубликовало эту надпись здесь
Ну хз, на нынешнем месте работы пишу на Scala, при этом программиста с опытом на Scala они даже не пытались искать, потому что на рынке труда их тупо нет. Собеседовали меня именно как плюсовика.

Я бы к списку полезных знаний добавил бы немного мета-языков: UML для того, чтобы находить общий язык с архитекторами, и один из языков описания ЯП. Спасибо за статью!

«C++, Java и C# очень похожи друг на друга не только концептуально, но и синтаксически.»
Не могу сравнить Java и C# друг с другом, т.к. последний — в глаза не видел.
А C++ с Java очень не похожи именно концептуально.
Разве что синтаксис Java явно заимствован из C++.

Самое очевидное — (полу)автоматическое управление памятью в в Java.
Концепция ссылок в этих языках — разная.
Обобщённое программирование — тоже непохоже.
Классы Java вообще не то же самое, что в С++.
В C++ нет рефлексии Java.
В противовес — в Java нет метапрограммирования в том виде, в котором оно есть в C++ (может и слава богу).

В общем, это очень разные языки.

Кстати, декларация о том что «выучил язык за 20 минут» — звучит слишком самоуверенно.
Относительно быстро можно освоить азы синтаксиса, но не «выучить язык».
Даже просто язык! Не говоря уже о его экосистеме!

Хотя соглашусь, что после C++ многие нынешние main stream языки изучить значительно легче.

P.S. Сам программирую 25 лет, 20 из которых — за деньги.
Начинал тоже с C++, тоже упражнялся в Web на Perl.
20 лет назад писал на Java/JSP, по пути освоил node.js, немного python.
Сейчас изучаю современную Java на курсах.
Но основной объём написанного мною кода всё-таки на C++.

Мой путь в IT похож на путь автора (если не рассматривать C#), но самоуверенность в изучении новых языков — я не разделяю совершенно.

переучиться с одного языка на другой до уровня junior можно легко и быстро, только зарплата упадет в 3-4 раза - поэтому толку мало (но есть)

Не обязательно. На проекте возникает срочная потребность в разработчике, вполне могут предложить существующему разработчику переквалифицироваться с сохранением оклада.

Часто есть возможность сместить стек прямо на работе
Появляются задачи по интеграции, взаимодействию с другими командами, доделки другого проекта
Задачи не на фул тайм.

langname developer это и есть уровень джуна, ну мб мидла. Сениор и выше просто реализует функционал, а на чем — да на чем придется. В эпоху микросервисных архитектур есть огромная свобода в выборе.


Я например бекенд разраб с опытом C#, но при этом за 2 дня смог сделать задачку, где нужно было генерировать пдфки для специального принтера который клеет на коробки с доставкой информацию по заказу. 1 день разбирался в express/..., второй день писал логику, разбирался с вебпаком, упаковывал в докер. При том что на жс/тс не писал практически никогда, немного фуллстечил в начале прошлого десятилетия и все, не очень релевантный опыт. А почему жс? А потому что там библиотека бесплатная была для пдфок, а на шарпах везде ценник был, вплоть до 60к вечнозеленых за годовую лицензию.

Интересно, кто-то рискнет выбрать первым языком для изучения Rust?
Язык современный и многообещающий. Концепция подхода к организации памяти на основе понятия "владение" позволяет решить основные проблемы на этапе компиляции.
По быстродействию - номер один из современных компилируемых кроссплатформенных языков. Но изучить его в объеме, достаточном для уверенного создания приложений не просто.

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

Если требуется основательный подход к проекту, то Rust подойдет лучше, чем Go. Но большинство компаний и правда, тратиться на обучение не будут - они просто подождут, пока "человеческий ресурс" сам созреет для них.

Одна из проблем рынка раст разработчиков сейчас в том, что криптостартапы платят 5к+.

Есть ощущение что это скорее будет ребёнок которому родители дали самый интересный на их взгляд вариант, сразу после Scratch :)

Мне нравится JAVA и PHP.

Да чё тут изобретать. Типичный путь програмеров в 80-90 это Бэйсик>Паскаль>си>дэльфи>си++>Ява. Далее уже можно определяться. :)

В списке отсутствует 'язык' для Б3-34, и всеми любимый Fortran ;). Кстати, в стандарте фортрана присутствует полная поддержка ООП (довелось в 2003м писать тесты, для покрытия кода компилятора intel...).

Можно еще Forth вспомнить, кто 34 прошел его хорошо помнят.

Pascal -> C/C++ -> Asm -> Lisp -> Rust, Go, Python, C#, Java, JavaScript, Haskell, ...

Если нужно освоить программирование совсем с нуля, то нужно брать Pascal. Конечно, потом его придется выкинуть, но для начального обучения он подойдет лучше всего: этот язык и создавался для обучения. Тут главное понять, что такое структурное программирование, какие бывают структуры данных и алгоритмы и как ими пользоваться.

Как только почувствуете уверенность и Pascal начнет раздражать - можно переходить к C (или C++ в некотором минимальном его подмножестве).

Дальше, работая с C/C++ обязательно нужно коснуться темы языков ассемблера. Хотя бы в общих чертах понять, как работает процессор, как исполняются команды, что такое регистры и пр. Написать прару-тройку простеньких программ на ASM или сделать оптимизации с ассемблерными вставками.

После того, как закрепитесь на уровне C, нужно обязательно посмотреть Scheme (или вообще любой Lisp), чтобы понять, что можно и по-другому.

Теперь, от этой точки, можно двигаться в любом направлении: Rust, Go, Python, C#, Java, Haskell и т. д. что душе угодно.

C, C++ и уж тем более Rust - это высокоуровневые языки программирования.

Столько текста лишь бы не признавать PHP лучшим языком ;)

Perl. Только Perl. Вот только сегодня с утра разбирался в дремучем легаси одного доморощенного автоматизатора безнесс-процессов, который, судя по всему, до этого программировал только на кондовом деревянном, прибитом к полу бейсике в школе а затем в перепою решил что может писать на Perl.
Perl — бесподобный язык!

(Дань уважения По: sarcasm!)
НЛО прилетело и опубликовало эту надпись здесь

Какой смысл в 2021 использовать в качестве высокоуровнего что-то кроме Хаскеля?

Туда еще завтипы не завезли.

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

В питоне, джаве, до-диезе и других популярных языках джун не может писать код на уровне сеньёра, но он хотя-бы может прочесть и понять код, который писал сеньёр. А в Хаскеле не сможет даже прочесть. Поэтому бизнес не торопится использовать Хаскель несмотря на все его серьёзные преимущества. Более менее, кое где начинают использовать, но процесс идёт очень медленно.

Когда бизнес говорит "мы Хаскель не используем, потому, что Хаскелистов не найдёшь", то это неправда - найдёшь. Просто для Хаскеля нужна команда из сплошных сеньёров. А мало какой бизнес может такое потянуть.

В питоне, джаве, до-диезе и других популярных языках джун не может писать код на уровне сеньёра, но он хотя-бы может прочесть и понять код, который писал сеньёр. А в Хаскеле не сможет даже прочесть. Поэтому бизнес не торопится использовать Хаскель несмотря на все его серьёзные преимущества. Более менее, кое где начинают использовать, но процесс идёт очень медленно.

Спорный вопрос. Понять каждую конкретную строчку он сможет, но если вместо траверса на 5 строчек будет написат фасад итераторов визиторов на 2000, решающий ту же задачу — то вряд ли они будут понятнее.


Когда бизнес говорит "мы Хаскель не используем, потому, что Хаскелистов не найдёшь", то это неправда — найдёшь. Просто для Хаскеля нужна команда из сплошных сеньёров. А мало какой бизнес может такое потянуть.

У меня противоположенный опыт — мало какой бизнес может потянуть джунов)

Я изучал и использовал много языков, но более примечателен один из них, который из самого любимого превратился в самый нелюбимый. Это Python. Раньше меня просто потрясало как гибко в этом языке можно менять объекты, добавлять/удалять методы, менять поведение через дескрипторы и декораторы, а уж что можно было вытворять через метаклассы - вообще молчу. В общем абсолютно потрясающая гибкость, можно было взять пустой объект и создать из него целый мир, чистое творчество, я просто обожал Python.

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

Ну я бы не был так категоричен в отношении Python, если спрос на него есть, значит и какие то преимущества у него есть. Как минимум на нем очень быстро можно написать MVP, а разнообразие библиотек позволяет применять его в самых разных отраслях.
Также мне показалось из вашего комментария, что вы намекали что Python проигрывает из за динамической типизации, однако следует заметить что Python действительно язык с динамической, но сильной типизацией. То есть интерпретатор вам не даст совершить сложение числа 1 и строки '1' как в JS.
Естественно что у Python есть серьезный проигрыш в производительности по сравнению с со многими другими языками, но надо понимать что это скриптовый язык, предназначенный для быстрой разработки.

MVP - веб приложение? Было бы здорово, если бы кто-нибудь более развернуто поднял этот вопрос на Хабре, но вот вкратце моё видение. Где нужен Python? В мобильной разработке он не используется, для десктопа тоже почти, на бэкэнде только и для аналитики и обучения сетей (тоже в основном для бэкэнда)? Если для бэкэнда, я даже не беру производительность в расчёт, странно писать на скриптовом динамически-типизируемом языке для серьезного бэкэнда, к тому же где фреймворков с поддержкой асинхронного программирования раз два и обчёлся для этого языка, и вообще асинхронное программирование - это не стезя пайтона, это вообще не его идея, и даже её реализация далеко не влучшем виде. По поводу MVP, MVC, MVVM и прочее на бэкэнде, тенденция идёт к созданию одностраничных web-приложений react, angular, vue, которые сами поддерживают эти архитектуры, двойной MVC на бэкэнде и фронтенде - тоже та ещё идея. По сути на бэкэнде нужен мощный высокопроизводительный высокораспараллеленный надёжный API, для которого Python крайне слабый выбор в сравнении с тем что вообще есть.

По поводу обучения сетей, сложной аналитики, да - для Python написаны кучи готовых решений, но они все на C++, потому что на самом пайтоне писать сложные вычиселения - идея та ещё из-за его низкой производительности.

Если брать скриптовую автоматизацию на сервере, то для меня это Perl, который, на мой взгляд, отличная более мощная замена Bash, и который кстати идеологически близок к Bash, так что продолжаешь писать в одном ключе. Я одновременно использую и Bash, и Perl, больше Bash.

Если всё же захочешь нечто скриптовое и динамически-типизиуремое на сервере, то лучше JS/CoffeeScript/Node вряд ли что-то найдётся, широчашая экосистема, отличные сборщики и, главное, асинхронное програмиирование на высочайшем уровне. И, кстати, JS в Node так же динамически-типизируемый, как правильно вы сказали, слабо-типизируемый, что ещё хуже влияет на производительность, но как тогда объяснить, что при этом JS в сотню раз производительнее Python?

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

MVP - это минимально жизнеспособный продукт. Хотя по мне, Python вероятно больше годен для прототипирования, чем для создания MVP. MVP нужно создавать на том языке, который планируется и дальше использовать, развивая этот MVP. А прототип - просто выбрасывается и продукт переписывается с нуля.

MVP может быть чем угодно, даже концепт-кар.

По поводу асинхронщины - да, обычный Python (Cython) в нем слабоват, все таки GIL сильно ограничивает возможности настоящей многопоточности. Однако есть варианты асинхронности (Asyncio, Multithreading и Multiprocessing). Надо понимать, что GIL внедрен не просто так, а для легкого встраивания библиотек на C, что в конечном итоге ускорило рост экосистемы Python.

По поводу сложных вычислений - действительно весь код, чуствительный к производительности выносится в бинарники, написанные на низкоуровневых языках. Но прелесть в том, что один раз написанный и отлаженный код на C++ затем не требует высококлассных специалистов для его использования. Попробуйте на языке низкого уровня написать соединение списков произвольных данных, их разворот и взятие среза. У вас выйдет много строчек, тогда когда в Python все ограничится одной строчкой. Просто вы думаете о Python как о языке низкого уровня, но он предназначен для быстрого построения программ, и защищает от тех ошибок, с которыми постоянно сталкиваются разработчики на низкоуровневых языках.

По поводу JS - я не спорю что он быстрее, проблема в том что при написании кода на слабо типизированных языках больше шансов ошибиться, так как они вовремя не сообщают что у вас ошибка в типах данных, а сами проводят неявные приведения типов. И не факт что в итоге он приведет к тому типу что вам надо.

Так а в чем смысл в питоне тогда? Почему бы этот оптимизированный и однажды написанный специалистами код не взывать из Haskell/JS/TS/C#/Go/чегоугодноещё?


Питон неплохой язык для обучения, чтобы заинтересовать человека, что у него что-то получается, такой вот wysiwyg. В моё время этим языком стал vbs который можно было в блокноте писать и сразу исполнять, но и питон хорошо, особенно на линухе где он есть из коробки. Но писать на нем что-то серьезное… Все эти возможность по манкипатчингу объектов в рантайме для меня скорее огромный минус, а не плюс. Впрочем, это проблема практически всей динамики. Но даже среди динамики имхо жс поинтереснее выглядит. А бог мне свидетель — я бы с жс на одной скамеечке бы не сел)

Так а в чем смысл в питоне тогда?

Ну вот тут написаны причины по которым выбирают Python. От себя еще добавлю и наверное повторюсь:
1. Скорость разработки (Развернуть свой сервис API с БД можно буквально за минуты)
2. Простота и лаконичность синтаксиса (Код читается чаще чем пишется)
3. Наличие строгих правил оформления кода (PEP8)
4. Огромная экосистема из библиотек (почти для всего что можно придумать)
5. Сильная типизация (меньше шанс на ошибку)
6. Скриптовый язык (код не нужно компилировать часами)
7. В Python все есть объект, и даже функции - объекты первого класса
8. Генераторы списков и выражений, а также все что связано с коллекциями
9. Микро Python запускается даже на микроконтроллерах с 16Кб памяти

Минусы также напишу, чтобы не думали что я агитирую исключительно за Python:
1. Низкая скорость работы
2. Псевдо-асинхронность из за GIL
3. В Python возможно будет мало функциональщины для любителей реактивного программирования
4. Увлекшись, можно наговнокодить - например написав целую игру "Змейка" в одну строку
5. Для мобильной разработки, прикладных программ с GUI, системного программирования, написания фронта - Python подходит с большим скрипом. Написать если и можно, то разработка будет медленнее и результат не такой хороший как при использовании специализированных языков с нужной обвязкой.

Забавно) С плюсами я не согласен, но с минусами тоже: они незначительны для тех задач, где питон применяют. По пунктам плюсов:


  1. То же самое в практически любом языке. dotnet new --web-db И у вас настроенный хелловорлд апи с бд коннектом. Да и у жс с экспрессом кмк не хуже
  2. Ну тут можно наверное согласиться, но во-первых проблемы с тем, чтобы написать этот легковесный синтаксис не ошибившись. Во-вторых проблема не в том, чтобы прочитать пару строк кода, а например разобраться как работает библиотека. И тут у меня постоянно проблемы с ним. Ну и плюс у меня стойкое убеждение, что код непонятный статическому анализатору зачастую будет непонятный и для человека, его читающего. С этим я в ЖС столкнулся: сначала люди пишут как попало, а когда натягивают типы (чтобы понятно было что куда) всё вылезает, а сделать уже ничего нельзя — библиотекой пользуются. В итоге живут эти HeadersInit франкенштейны и живут.
  3. Во всех распространенных языках оно есть. eslint, rustfmt, gofmt, dotnet-format,…
  4. У жс/жавы не меньше
  5. Наверное можно согласиться, хотя мне лично всё что не дает мне ошибку до запуска программы тяжело отнести к сколько-нибудь хорошей защите от ошибок. Поставил if и так совпало что одна из веток не выполняется — сиди гадай, правильно ли там всё написано или нет.
  6. Не знаю где вы взяли компиляцию часами, но даже раст в дебаг компилируется секунды, а он лоулевел. Компиляция же сишарпов вообще считается в сотнях миллисекунд, мне кажется это даже вспоминать лишнее. ВО времена плюсов и плохой инкременталки — да, вероятно. Сейчас — только если сравнивать с теми же плюсами или сложными проектами на С/Rust.
  7. Функции первого класса везде, не вижу отличий питона от любых других япов. Можно ещё в плюсы записать что можно не знать ISA целевой архитектуры) Автоматически выполняется для практически любых япов из топ20 гитхаба.
  8. Лично я наоборот очень боли получил от питона в этом плане. Ну давайте простой пример, у меня есть коллекция чисел, я хочу получить следующее: если все элементы списка совпадают, то получить это число. Если различаюстя, то упасть с ошибкой. В итоге мне пришлось написать нечто такое:

fair_id = reduce(lambda a, b: (a if a
  == b else raise_(DepersonException('Multiple fairs are not supported'
  ))), fair_ids)

...

def raise_(ex):
    raise ex

тут и безумное форматирование (иначе код не компилируется или пеп ругатся), и супер-хелпер функция raise_ (ведь в питоне raise не является экспрешном), и километровый кейворд lambda. Поэтому в питоне так по-моему не пишут. Не обломаются написать форик проверяющий условие а потом в конце стыдливо напишут fair_id = fair_ids[0] # checked that it all elements are equal to the first one. В общем, мне трудно назвать это хорошей работой с коллекциями, честно говоря.
9. Ну тут ничего не скажу — для кого-то это плюс, наверное. Я для таких случаев взял бы Rust с no_std.

НЛО прилетело и опубликовало эту надпись здесь

Вполне. В одной из книг, возможно Фаулера - есть звонкая цитата: "Научившись писать, мало кто становится писателем". Соответственно, быстрое освоение языка новичками (во всех смыслах IT) - нисколько не прославляет язык.

PS: Ничего против питона не имею. Просто, из-за нехватки ресурсов (бывает, и знаний;) его используют даже как скриптовый язык управления внутри продукта (в том приложении мне пришлось реализовать для питона встроенный отладчик. Это было элементарно).

В давние времена обучался по специальности с очень длинным названием и довольно глубоко изучался С++ и Ассемблер (2006-2009г) . После обучений знания по ЯП не использовались. А работаю я сетевым инженером и иногда пишу на python скрипты. Скрипт к примеру: Залогинится на какую-то железку, что то там выполнить, отпарсить интересующее, преобразовать в csv/json/(записать результат в БД) и т.д. Мой код даже в рамках програмистов-python далек от совершенства, уверен что код даже можно назвать "страшным", но я потратил на обучение и реализацию минимум времени, и все работает как надо, спасибо python. Повторюсь я не программист, "научился писать и пишу, но писателем себя не считаю".

Ура!!! (кроме шуток). Python и был для этого создан. Автор языка-инструмента обслуживал море хостов университета. Его заставила окружающая действительность упростить себе жизнь...

Ну, это немного не python-way

def check_equal(my_list):
    result = all(element == my_list[0] for element in my_list)
    if result:
        return my_list[0]
    else:
        raise Exception('Non equal')

Я так в юности писал на с++. Вернее, использовал подход си, но с cout << )))

Ну так в этом и проблема, в boolean blindness и том что мы явно проверяем my_list[0] и вот этом всем. Фолды призваны решать проблемы с коллекциями, а форик так не может. Кроме того, у нас my_list в первом случае может быть каким-нибудь networkStream у которого нет никакого индекса, по которому можно только итерироваться.


Короче, это в принципе о чем я и говорил: питон-вей это откатиться на императивщину, что имхо слабо вяжется с "крутая поддержка коллекций". В том же шарпе бтв без вопросов можно было бы написать:


vat fairId = fairIds.Aggregate(
  |acc, x| acc == x ? acc : throw new Exception("Something"));

Кмк тут проще и понятнее все. Ну и короче, что не то что важно, но приятно

Признаю, хороший пример, хоть мы начинали с "коллекции чисел" а не с "какого-нибудь networkStream".

Ну и то, что lambda в питоне не может кинуть исключение - так во всех яп есть свои ограничения.

Кроме того, у нас my_list в первом случае может быть каким-нибудь networkStream у которого нет никакого индекса, по которому можно только итерироваться.

Ну мысленно замените my_list[0] на next(iter(my_list)), делов-то.

С пунктом про время компиляции всё-таки соглашусь с @Yuribtr , в остальном с вашими доводами согласен. Сам пишу на Scala, реально долго идёт компиляция. На С++ ситуация со временем компиляции тоже не лучше. На счёт сильной типизации в Python тоже не совсем понятно, как это поможет, ну да, там не сложишь строку с числом как в JS, но вылезет-то это всё равно в рантайме.

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

Пайтону действительно не хватает функционального программирования, даже его там почти нет, почти всюду используются мутабельные данные. Мутабельные данные с распараллеливанием ещё с динамической типизацией, ещё и без компиляции, всё в рантайме - действительно, что может лучше для хорошего бэкэнда. В приведённом фрагменте вообще не стоило бы строить логику на бросании исключения как, например, в Scala + cats

    val allTheSame = ids.zip(ids.tail).forall { case (previous, current) =>
      previous == current
    }

    val result = Either.cond(allTheSame, "All right", new IllegalStateException("All ids must be the same"))

Хотел про скалу отдельно отметить, о потом подумал "да ладно, не так много народу на ней же пишет". И вот зря) Да, на скале с шейплесом можно накрутить такого что время компиляции С++ покажется совсем незначительным)


Но нужно помнить что С++ и обвешанная скала наверное самые долгокомпилирующиеся языки на рынке. У остальных с этим всё куда лучше. Например, при компиляции типового C# сервиса на 50kloc я наблюдаю следующие цифра для холодной/инкрементальной компиляции:


Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:06.38

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:00.92
С пунктом про время компиляции всё-таки соглашусь с Yuribtr, в остальном с вашими доводами согласен. Сам пишу на Scala, реально долго идёт компиляция.

Это всё сильно зависит. Я на хаскеле пишу, в том числе — да, релизные билды очень долгие, но билды без оптимизаций, релоад в репле или, тем более, фидбек от language server'а — моментальные. Да и вообще, когда у вас есть language server с нормальным типизированным языком, то компилятор вы запускать будете сильно реже.

Писать какой-то проект в упрощенном виде на Python, потратить время, потом удалить его к фигам и начать писать уже на нормальном языке заново?

Да, именно так.

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

Обычно на этапе PoC неизвестно не только на каком языке стоит вести разработку, но и стоит ли её вести вообще. Чем быстрее прототип докажет свою непригодность, тем дешевле обойдётся написанный и выкинутый код.

Ну хорошо, ладно) Трудно, правда, представить, но, наверное, это действительно разумно в некоторых случаях.

Я представляю так, сидят на хорошей зарплате штат scala-программистов, тут приходит директор и говорит: "Так, есть идея, но на чём же будем писать... хм... а давайте напишем пробный проект на Python..." ))

Я представляю так, сидят на хорошей зарплате штат scala-программистов

Выше в комментариях PsyHaSTe очень хорошо написал: «langname developer это и есть уровень джуна, ну мб мидла. Сениор и выше просто реализует функционал, а на чем — да на чем придется.»

Обычно планирование идёт не в направлении «вот у нас есть столько-то чуваков с такими-то скиллами, надо загрузить их какой-нибудь работой», а в направлении «вот у нас есть такая-то задача, есть такой-то бюджет, теперь надо подобрать внутри фирмы и/или нанять извне чуваков, которые решат эту задачу в рамках бюджета».
Я представляю так, сидят на хорошей зарплате штат scala-программистов, тут приходит директор и говорит: "Так, есть идея, но на чём же будем писать… хм… а давайте напишем пробный проект на Python..." ))

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

Тоже самое и с ресерчами всякими.

Это только с вычислительной математикой удобно, да и то не всегда.

Моя последняя курсовая была про генерацию формальных грамматик генетическими алгоритмами, вот там тоже было удобно экспериментировать на Python, и переводить на «нормальный язык» только тогда, когда определился с параметрами алгоритма (механизмом «скрещивания» грамматик, набором возможных мутаций, и т.д.) и осталось запустить на несколько суток работы без присмотра.

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

А что там давал Питон, что не могут дать другие современные языки?

Когда говорят про быстрый прототип на Python (или php или js), то часто имеется ввиду не "большая команда на зарплате" а один-два человека делают MVP. Это подразумевает не только код, но и дизайн, верстку (layout), картинки\иконки и пр.

Простые языки хороши тем, что их могут использовать не только истинные программисты (которые драйвер для сетевой карты напишут), но и дизайнеры\верстальщики. И простой (тупой) императивный стиль позволяет достичь нужной задачи. Для меня if\else в несколько строк гораздо нагляднее, чем кидать эксепшен при агрегации в одной строке.

Я много раз писал стартапы, и многие вообще не взлетали. А те что взлетали - оптимизировали и они вполне работали. Ютуб на питоне сначала написали - потом поправили. Фейсбук на php - тоже оптимизировали. А вот Одноклассники сразу на java накодили... что, сильно быстрее или успешнее стали?

Ну вот stackoverflow на net сразу сделали — это самый успешный проект в своей области. Одноклассники — довольно успешный для своей аудитории. Фейсбук соорудил костыль с php, который практически больше нигде не используется.

Вконтакте, насколько я помню, тоже свой PHP написали, который транспилируется в C++.

7. В Python все есть объект, и даже функции - объекты первого класса

Я вот не пойму, что все носятся с этими функциями-объектами?

Есть что-ли хоть один распространенный ЯП где функцию нельзя передать параметром в другую функцию или вернуть из неё?

Где нельзя сложить функции в контейнер?

Что в древнем C это было доступно мне кажется с самого его рождения, что в стильном-модном-молодёжном js.

Все языки которые я хоть немного знаю (c/c++/js/java/python) - везде это есть.

Все языки которые я хоть немного знаю (c/c++/js/java/python) — везде это есть.

Ну и как вы в Java «сложите функции в контейнер»?
Видимо с Java я поторопился.
Признаю, что этот момент языка я знаю не достаточно.

Не разочаровывайтесь ;), ведь в стандарте Java нет понятия 'функция', соответственно и механизма для манипуляции ими. Или есть?

Функция там есть. Но это — шаблонный класс (или как там оно называется в Java).

А то, что можно назвать функцией в контексте нашего обсуждения — в Java называется метод.
Он доступен через reflection API.
docs.oracle.com/javase/8/docs/api/java/lang/reflect/Method.html

Наверное java.lang.reflect.Method можно и из функций возвращать, и передавать в функции.

Можно их считать «объектами первого класса»?
В Java этого нет. Даже в новых версиях, где есть похожее — это не более чем синтаксический сахар (т.к. по сути создаётся объект анонимного класса c методом apply). Это один из краеугольных камней Java, который всё никак не расшатают.

В с/с++ — тоже нет. Да там есть указатель на функцию, но это совсем не тоже самое! Попробуйте с этими указателями организовать каррирование — поймёте.

Со скрипом есть в js (любая функция-класс, любой класс — функция), но это именно со скрипом — в идеале не так должно быть.

Носятся с этим, потому что позволяет без лишних телодвижений писать очень универсальные и очень обобщённые алгоритмы — map/reduce как классический пример. На Java 8 реализовывать его самостоятельно — глаза кровью потекут. А на Пайтоне — напишешь и плачешь от умиления.
Java видимо я знаю действительно «немного».
Мне казалось, что там тоже всё является объектом и функциями можно манипулировать как и другими объектами.
Ну пусть Java стоит особняком в этом списке.

А в c/c++ я именно указатели и имел в виду.
Для решения задачи: «может быть передан аргументом в другую функцию, возвращён из функции» — вполне подходят.

Насчёт всяких каррирований речи не шло :)
Но имея возможность всё-таки хранить (указатель на) функцию — это-таки можно реализовать, даже если в языке этого нет «из коробки».
В с/с++ — тоже нет. Да там есть указатель на функцию, но это совсем не тоже самое! Попробуйте с этими указателями организовать каррирование — поймёте.

Начиная с C++11, есть std::function, есть лямбды, каррируйте на удовольствие.
В Java этого нет. Даже в новых версиях, где есть похожее — это не более чем синтаксический сахар (т.к. по сути создаётся объект анонимного класса c методом apply). Это один из краеугольных камней Java, который всё никак не расшатают.

А в чем разница-то я не пойму? Если вы можете передавать лямбды аргументами то без разницы как под капотом оно там реализовано, через объекты с единственным методом или ещё как. Это деталь реализации уже.

Ну например в том, что во всех остальных языках из списка 5oclock передача функции ничего не стоит (передаётся ссылка на нечто, что уже существует), тогда как в Java ради передачи функции создаётся каждый раз новый объект.

Так а разве перформанс какое-то отношение в фиче имеет? Вон передать функцию в С++ дешевле намного чем в ЖС или лиспе, будем ли мы теперь говорить что в С++ ФП а лисп нет? Какая-то ерунда выходит, если честно.

Это не про перформанс, это про программинг модел: в Java нет смысла сравнивать два «функтора» на равенство, потому что передаётся каждый раз новая обёртка. В остальных языках из списка — две ссылки на одну и ту же функцию будут равны между собой.

И что? Я спокойно могу придумать реализацию лиспа где будет такое же поведение. Он перестанет быть ФП от этого? Адреса функций это ещё более глубокая деталь реализации.


К слову в сишарпе скорее всего у Delegate будет такое же поведение. Иногда, потому что когда может C# кэширует этот "функтор" в статическое поле класса и тогда адрес будет совпадать. А если не смог закешировать то адрес всегда будет отличаться.


Завязываться на это — завязываться на детали реализации и по сути эксплуатировать UB.

В лиспе и C# это действительно UB, зато в остальных языках в списке выше - вполне штатная фича, которая к тому же ничего не стоит в рантайме

Это я понял, это хорошая фича. Я просто не понял, почему это вдруг стало причиной "выписывания" из ФП. Странное деление, не по функционалу а по ничего не значащим цифрам.

А зачем вообще сравнивать два функтора на равенство? Равенство по ссылке вообще не очень интересно, равенство по поведению неразрешимо.

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

Не очень понятно как должны в таком случае идентифицироваться замыкания, замыкающиеся на мутабельное окружени. Должны ли они выдавать одно и то же? или нет?


Звучит весьма хрупко

Ребят, вы спорите ни о чём, нет разницы, в Java или не в Java. Во всех языках для лямбды/замыкания создаётся объект, просто в Java до версии 8 он создавался явно, чтобы эмулировать callback, вы так же могли его кэшировать в переменную, чтобы он не создавался каждый раз заново, где это колбэк нужен, а с Java 8, Scala, Kotlin, C#, да и вообще во всех языках, где есть объекты, для этого есть краткие синтаксические конструкции, но создают они концептуально то же самое, что и в старой яве. Даже в современном C++ лямбды [] () {} неявно создают классы с перегруженным operator()

Даже в современном C++ лямбды [] () {} неявно создают классы с перегруженным operator()

Которые для captureless lambda более чем спокойно вырезаются на любом адекватном уровне оптимизации.


Впрочем, это в любом случае несущественные детали.

Практика показывает, что лучше кешировать функцию на уровне функции (ну, условно, выражаясь псевдокодом, написать memoize : (a -> a) -> a -> a), а не на уровне внешнего мира. Как минимум потому, что тогда ответственность за кеширование лежит в точке передачи функции, а не в точке её использования, что чище и правильнее (так как в джаве, как абсолютно верно рядом заметили, вы чистую функцию от нечистой всё равно не отличите).

Какие трогательные отношения у вас с Пайтоном, что сами вызывают умиление. В ООП языках, и вашем любимом Python в том числе, создаётся объект-обёртка вокруг любой функции, в том числе и лямбды. То есть lambda в Python так же создаёт объект с методом `__call__` . А в C++ всюду, в том числе и в подключаемых библиотеках используется обобщённое определение функции - нечто такое, что можно вызывать через круглый скобки () - это может быть хоть обычная функция, хоть указатель на функцию, хоть объект с определённым методом operator(). И это нормально, больших накладных расходов с объектами-функциями нет, к тому же объекты позволяют захватывать значения переменных из внешнего окружения, превращая функцию в замыкание. Я писал здесь статью об этом в далёком 2012м (https://habr.com/ru/post/149882/), правда я там перемудрил малость, но не важно.

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

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

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

Есть ещё term rewriting категория. Из представителей можно назвать Refal и Maude. Последний применялся NASA для верификации сложных систем. Чтобы доказать, что программа выполняется корректно, нужен анализ объектного терма. Самый популярный язык имеющий структурированное объектное пространство - Haskell, хотя Refal не уступает ему в области символьных вычислений.

Марк, спасибо за статью!

Очень познавательная, пиши еще!

Сегодня востребованы программисты на Python, Go, C#, Java.
а как же JS? Количество работы на нем просто зашкаливает.

JS автор занес в разряд "нишевых" языков. Чем несказанно меня повеселил, к слову.

Ну а что не так?

  • Js используется для машинного обучения?

  • Ну тогда может в банковском секторе (и я не про веб морды)?

  • Может игры на нём пишут?

Для чего используют JS по вашему?

  1. Используется (хотя не так активно, как питон какой-нибудь)
  2. И там
  3. Уу, ещё как пишут. Причем полагаю побольше, чем на том же С++

Но к слову чтобы считаться "не нишевым" языком не обязательно, чтобы на этом языке писали прям абсолютно всё. А то так можно С или С++ занести в нишевые потому что в эппловском аппсторе не залито ни одного приложения на них.

А как тогда отличать нишевый язык от не нишевого? Вот Vala нишевый язык? На нем в основном для Gnome пишут.

Ну это вопрос из разряда "сколько камней кучка". Но если брать нечеткие множества то можно считать процент принадлежности к нишевому как 1 — (кол-во областей где используется япзык)/(общее количество областей). Думаю у Vala показатель принадлежности будет довольно большим, а у язков из топа гитхаба — не очень.

Языки низкого уровня .... К ним относят C, C++, Rust и, в какой-то мере, Go

Я уже совсем с катушек съехал? Всегда считал, что существует только два языка низкого уровня: бинарный и язык ассемблера.

Уважаемый Vladimir, согласен. Про НУ, это да - амбициозное заявление. Даже с 'натяжкой', отнеся C к низкому уровню, остальное - не катит ни в какие ворота. Предположим, если это всё компилируемые языки - значит НУ ;). ('натяжечка' C: 1. это связано с историей его возникновения - для того, чтоб уменьшить мытарства с ассемблерами; 2. на заре, для простеньких наборов машинных команд, и не изощренных компиляторов - легко можно было предсказать итог компиляции кода C в команды CPU).

Деление на низкие/высокие языки сейчас делается условно по принципу "нужно ли думать про аллокации памяти или нет". Если нужно то язык низкий, если "а, за мной как-нибудь приберут" высокий.

Почему все коментаторы докапываются до формулировок — загадка.


Смысла деления на высокий/низкий где в одну категорию попадает всего 1 язык, а в другую — все остальные — нет. Когда мы делим область знания на категории они должны иметь +- равный вес, иначе получается ерунда.


Короче, раньше когда компьютеры были большие а мы — маленькие — да, так и было. Сейчас терминология слегка поменялась. Точно так же никто не называет бухгалтеров "калькуляторами", хотя так "всегда было". А ООП это "как в джаве", а не "акторы обмениваются сообщениями" как Кей завещал. Опять же, смысл термина поменялся.

Определенно, (за себя пишу) - никто не докапывается. Просто у каждого свой тезаурус (карата сопоставлений <слово,понятие>), из-за разной окружающей действительности. Таким образом, каждая ветка комментариев выливается в процесс фиксации смысла, понятного каждому читателю.

PS: приятно было ознакомиться с Вашим мнением (суждением).

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

Мало какой распространенный язык не позволяет строить максимально сложные алгоритмы.

Если вы про первый язык, то согласен что должен быть максимально простым для изучения, если не первый - то с чего бы?

Что значит максимально производительным? Скорость написания программ, простота отладки, наличие библиотек и фреймворков на все случаи жизни, скорость исполнения программ? Это все подбирается под задачу, почему первый язык должен этим обладать?

… и несуществующим.

Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.