Comments 310
Без знания хоть каких-то языков думать-то будет особо не о чем. Или надо думать как собеседование пройти, что учить — покажут?
"Хоть какие-то языки" — это месяц на первый и по неделе на каждый последующий (во всяком случае, в рамках императивной парадигмы). Это если никуда не спешить, конечно.
Не всем надо быть Александреску. А до уровня "C с классами" — та самая неделя, и это покрывает бОльшую часть потребностей (лично мне не хотелось бы разгребать ко за джуниором, увлёкшимся метапрограммированием на темплейтах).
Невероятную ерунду можно сделать и в скрипте. А оправдывать преимущество скриптов меньшим количеством логики — это… достаточно странный аргумент) Мне кажется, тут стоило бы добавить какой-то конкретики.
Да, и если разобраться — JS при всей своей внутренней и кажущейся внешней (кажущейся — потому что в нём примерно всё не так, как думают новички) простоте позволяет наворотить не меньше сложностей, чем плюсы. Простым он остаётся лишь при соблюдении строгой дисциплины...
Да, так эволюционирует язык. И то, что в каком-то дремучем легаси используется new и delete и всё работает — это прекрасно, ведь можно прийти и малой кровью это переписать.
В новом коде их использовать почти никогда не надо, за исключением специфических случаев, типа Qt, где другая модель управления памятью, чем в современном C++.
Не путайте языки, стандартную библиотеку и всю экосистему.Многие так говорят, как будто язык в вакууме существует. Всегда стоит оценивать всю экосистему.
А статья, в целом, нормальная.
Но ведь в хаскеле номинальная типизация, это не OCaml и не Elm.
Там ошибка, а приведённый сниппет в хаскеле невозможен. Ну вот же простой пример:
data Foo = Foo Int
data Bar = Bar Int
Foo
и Bar
несовместимы, хотя имеют одинаковую структуру.
A distinction exists between structural substitution for inferred and non-inferred polymorphism. Some languages, such as Haskell, do not substitute structurally in the case where an expected type is declared (i.e., not inferred), e.g., only substitute for functions that are signature-based polymorphic via type inference.[1] Then it is not possible to accidentally subtype a non-inferred type, although it may still be possible to provide an explicit conversion to a non-inferred type, which is invoked implicitly.
О, макаронный монстр! Раст и плюсы не похожи синтаксисом на мой любимый динамически типизированный язык программирования со сборщиком мусора! В утиль не думая и не разбираясь!
lucumr.pocoo.org/2012/10/18/such-a-little-thing
В Расте по определению нужно сообщать языку больше информации о программе по сравнению с языками имеющими утиную типизацию и сборщик мусора. Жаловаться на синтаксис не потратив хотя бы недельки на изучение языка, а просто поглядев листинги это где-то на уровне «Пастернака не читал, но осуждаю». Плюс стоит понимать, что если не брать совсем патологические случае, то к синтаксису работая на языке очень быстро привыкаешь, так что использовать подобную вкусовщину для оценки языка, мягко говоря странно.
Я, как можно догадаться, весьма плотно работаю с Растом, и могу заверить, что лично у меня никаких сложностей с пониманием основной части кода не возникает, как и у множества других людей, которые хоть немного поработали на данном языке.
Синтаксис-то ещё ладно, а вот с неопределённым поведением в C++ — туши свет.
s/eclipse/IDEA/
И завязывайте с засильем смайликов, а то возникает ощущение, что переписка ведётся с условной блондинкой в чатике.
P.S.: Да, этот комментарий практически ad hominem, но по сути дела тут обсуждать, к сожалению, нечего.
А чего Swift и Objective-C не добавили? Те, кто с самого начала сидел на экосистеме Apple, вполне себе стабильно в шоколаде чувствуют — в отличии от тех же перловодов, например.
А чего их учить-то особо? Пересесть на них с C++ (особенно если его используешь в рамках "C с классами") — плёвое дело, а инфраструктура (фреймворки и т.п.) довольно-таки понятна, неплохо спроектирована (после win api, mfc и иже с ними — отдыхаешь душой) и прилично описана (хотя в этом вопросе у меня и к MS претензий нет), так что переход на неё, если уже привык к reference counting (например, использовал COM с его IUnknown или std::shared_ptr) не напряжёт вообще.
Я к тому, что можно со Swift и начать, тем более что у него ещё и playgrounds.
Swift читается лучше имхо
Так гoвoрите, будтo бы в C# не забыли o вреде null-значений.
(хoтя уже стараются этo исправить)
> O да, чуть не забыл, про способ зарыть себя, проект, клиента и окружающий мир в код и утонуть в нем, вспоминая в агонии 20 уровневую иерархию наследования — про ООП.
20-урoвневая иерархия наследoвания — этo прoблема архитектуры, а не парадигмы прoграммирoвания. Недарoм существует принцип prefer composition over inheritance.
> Не нужно думать, что статическая типизация, особенно строгая, это прямо «must have» — вы провалите сроки и код с удовлетворенной параноидальной мыслью о «возможных ошибках» будет выброшен на помойку.
А между тем в нoвый Python дoбавили аннoтации типoв, IT-гиганты разрабoтали Typescript и Flow и даже PHP не oтстаёт. Дoвoльнo спoрный тезис!
Ну я думаю что можно еще вспомнить Котлин.
Хорошее продолжение Java, и если все будет хорошо то его ждет разумный успех.
Имхо — язык это всего лишь инструмент, к которому надо знать подход.
Понял более-менее один язык — поймешь и другие. От языка уже зависит, сколько времени на его изучение придётся потратить.
Не холивара ради, но про Java ходит множество слухов, которые порождаются от незнания или уходят корнями в древние версии (например что Java медленная, что она жрет тонны памяти и все в таком духе). То же самое можно сказать и про "кровавый-энтерпрайз-простой-веб-вервер-за-5-дней". В текущих реалиях даже самый распространенный Spring Boot позволяет сделать веб сервер за ~10 строк кода, а ведь есть и более минималистичные фреймворки
Что до типизации — я лично считаю, что динамическая типизация замечательно подходит для создания прототипов или небольших проектов в духе "сделал и забыл". Если предполагается продолжительная разработка (а главное поддержка) в команде разработчиков, то лучше выбрать статическую типизацию
меняем код 10 раз в минуту
Что нужно такого делать с кодом, чтобы иметь ощутимый результат каждые 6 секунд?
А можно, в утиной типизации, принять все, что пришло, и дернуть метод у этого нечто.Ай как замечательно, только вот веселье начинается когда на вход передается объект такого типа, который на вход не ожидали. Хорошо еще, если соответствующего метода у данного типа нет — тогда просто получим ошибку (ну, или не получим), а что, если соответствующий метод вытирает диск или взрывает атомные бомбы? Так что строгая типизация — это не про ограничения, это про дисциплину и быстрое вылавливание элементарных, но неприятных ошибок.
статическая типизация подразумевает компиляциюНет, с чего это вдруг? Чем статическая типизация мешает использовать язык в режиме интерпретации?
a
— это тип. Monoid a => a -> a -> a
— это тоже тип.
В общем мне кажется дискусия зашла куда-то не туда. Я имел в виду, что если я пишу функцию для сложения двух целых чисел(псевдокод): `sum = (int a, int b): int => a + b` то я ни в какое будущее не заглядываю, а если пишу `sum = (int a, any b): int => typeOf(b) === 'int'? a + b: typeOf(b) === 'string'? a + (int)b: typeOf(b) === 'object'? a + (int)b.toString(): undefined;` когда мне только числа надо складывать, то делаю лишнюю работу никому не нужную на данный момент, при этом пытаюсь заглянуть в будущее и угадать что ожидают пользователи передавшие строку или объект в мою функцию для сложния чисел.
Какой язык программирования учить в 2018 году и почему именно его?
не достает продолжения:
… чтобы (что?)
Позволю себе продолжить: "… чтобы получить гарантированную работу после окончания ВУЗа и проработать 40 лет после его окончания по специальности"
И ответ мой такой — не такого языка.
Пока то у нас программирование все еще не является ремеслом и с точки зрения IT-менеджеров, я цитирую автора:
Взрослые отличаются от детей пониманием ключевого принципа IT-менеджмента: «программирование — это привилегия». Среди опытных и успешных коллег-разработчиков наиболее адекватные и кодят хорошо и «двигают компанию вперед» одновременно.
Вобщем-то в стародалекие советские времена ходила такая устная памятка абитуриента:
1. Не иди в университет
2. Не или на АСУ.
3. Не оставайся в в институте работать (вариант: не иди в аспирантуру)
Так или иначе, трудовой путь программиста весьма предсказуем. Первый период когда, работу найти не просто а очень просто и зарплата будет на порядок выше чем у сверстников. И пеиод когда начинаешь задумываться что делать дальше а изменить уже ничего не можешь.
Кстати, статистику я не нашел. Но опасаюсь что 99% ВУЗов (кроме узко специалиированных на IT) это как и 30 лет назад все тот же Pascal
это как и 30 лет назад все тот же PascalОтличный язык, к слову. Я как начал с него + asm лет 25 назад, так и до сих пор верой и правдой служит, исправно и хорошо кормит.
Поэтому забудьте про «какой выучить язык программирования в 2018 году»
Дальше, выберите область задач, которыми вам будет интересно заниматься, например веб или машинное обучение
Задачи в проектах существуют совершенно разные и именно от задач и нужно «плясать»!
Местами я не терял надежду.
Что значит «развивает»? Любая творческая деятельность как-то развивает мозг.— имею в виду способность мозга формализовывать проблему, разделяя и властвуя дальше над ней.
Я просто совсем не понимаю, как можно программировать более-менее серьезные вещи без знания того, как программа работает вообщем?— я так тоже думал и начинал с C, книжки Таненбаума о архитектуре компьютера, изучил ВСЕ системные вызовы posix, кучу rfc до корки прочитал. Но сейчас вижу, что используя процедурных и функциональный подход, люди пишут неплохой код, взять тот же питон и НЕ ЗАДУМЫВАЮТСЯ и проекты взлетают быстро. Возьмем смартфоны — кто-то задумывается как они работают — нет. Блондинки думают как работает автомобиль? Нет. Но при этом ездят же
Кроме того, язык С не даёт вам понимания тех же регистров. Их там нет. И понимания того, как машина работает, он тоже не даёт.Да, но он является отправной точкой для изучения данных вещей. А как этому, интересно, способствует Хаскел?
Вы понимаете, как работает register renaming в современных процессорах и зачем он нужен, коли мы об этом заговорили? Как процессор выбирает и переупорядочивает инструкции для спекулятивного выполнения? А многопоточный код вы пишете? А протокол синхронизации кэшей в вашей машине знаете?Как минимум не до конца, что свидетельствует о том, что мне есть куда двигаться. Но значит ли это, что стоит отказаться от того, что бы в это все вникать?
«Развивает» — в данном случае значит, что заставляет рассуждать о программах в терминах типов, композиций функций и прочих вещей, позволяющих лучше и эффективнее проектировать большие системы.Не отрицаю, что это очень полезно, но если, как советует автор статьи, «не вникать в технические детали», то получится или быдлокодер, или человек с «энтерпрайсом головного мозга».
Функциональщина, хоть и привлекательна мне академически, не заходит дальше математического решения. А что бы положить это на существующие процессоры, нужен С.
Лучше как-то с алгоритмов начинать, ИМХО.Безусловно, но мы то уже о программировании говорим.
С тоже, ИМХО, не самый хороший выбор.Возможно, но ничего лучше я пока не вижу.
хотя С и позволяет добиваться результатов быстрее, чем ассемблер, он далеко не на вершине эффективности в плане скорости разработки.ИМХО, новичку нужно учиться создавать качественный продукт, а быстрый говнокодинг на чем то вроде Java всегда можно освоить. Насколько я знаю, самый простой инструмент для создания качественного продукта — это С.
Зачем он там нужен?Кто и где?
Я не очень понимаю, почему вы считаете, что С позволяет писать более качественное ПО, чем та же Java.Потому что через С можно выразить практически все возможности процессора, а радужный мирок Java неизбежно влечет ощутимый оверхед на многие элементарный операции.
А наиболее простой, наверное, какой-нибудь Go.Согласен, возможно Go как раз лучший выбор, хотя ИМХО лучше начинать с языка без GC.
Делфай
Как насчет Раби?
А ларчик просто открывался. "-фи" — это чисто английский вариант, "-фай" — это вариант, доминирующий в США (опять-таки википедия нам так говорит).
Этого я не знал :(
Делфай, к слову, под многое из этого подходит.Нет, не подходит. Проверка индексов массивов отключается опцией компилятора, и, значит, в release кто-то её выключит ради пары процентов к скорости. Всё остальное — адресная арифметика, безнаказанное приведение указателей одного типа к другому, ручное Create/Destroy, бесконтрольные CopyMemory/MoveMemory — всё как в C.
Однако, не надо брать молоток и зубило, чтобы проковырять дырку в стене. Быстрее, удобнее и надёжнее это сделать дрелью.
Хотя, разумеется, с дрелью все дырки бездушные и однотипные. А вот молотком можно делать уникальные дырки, ковыряние которых надолго запомнится.
Однако, для заказной разработки я возьму что-нибудь более продуктивное, чтобы укладываться в сроки.
К тому, что от скульптуры периодически что-то отваливается (CVE) и приходится ставить заплатки, все уже привыкли, и это считается качеством.
На самом деле очень удобно писать код, понимая, во что он компилируется. Сразу отпадает желание делать что-то тяжелое, вроде присваивания массивов и структур.
На счет понимания, во что компилируется код — ну так это сама суть C/C++. А вот в ФП это выглядит проблематично.
А на счет понимания — я имел в виду примерное представление того, что сделает процессор, выполняя программу. Программируя на C, я это, хоть и не идеально, но представляю. А если имеем тредпулы с синхронизациями верхом на виртуальных машинах — кто знает, что может случиться.
сейчас для решения нетривиальной задачи написать код лучше, чем генерирует компилятор C, практически невозможно.Ну что вы! Есть такой трюк — динамическая кодогенерация.
Вместо того, чтобы вертеть большой цикл с кучей if внутри — можно динамически сгенерить код на конкретный набор условий. Выигрыш — порядка сотни раз. Мы так 25 лет назад сделали для поиска строки в сжатом поле базы. Вместо поиска любой строки — динамически генерился код поиска конкретной строки.
На счет поиска строки — интересно, а что дает хардкод строки, и при каком конкретно поиске?
А конкретный пример был такой. Библиотечная СУБД, текстовые поля сжаты при помощи заранее выбранного словаря (гнездо — 12 бит), полнотекстовый поиск. Компилятор брал образец (то, что ищем), выяснял, как он может запаковаться, после чего хардкордил код с поиском нужных последовательностей гнезд.
Ложноположительные срабатывания отбрасывались распаковкой поля.
Скорость поиска — порядка 10 тысяч библиотечных записей в секунду на I386DX40, загрузка процессора — порядка 50% (остальное тратилось на чтение с диска). Время компиляции — порядка 500 мс.
Как видите — от if не ушли, но компиляцией захаркордили только нужные.
P.S. Спецификой проекта было то, что из трех человек было 2.5 компиляторщика. Причем половина — это как раз я.
Как соавтор пары форт-систем — я понимаю, во что они компилируют.Насколько я знаю, в форт-системах нет оптимизаций. Шитый код соответствует коду программы и конструкция
2 DUP * *
никак не превратится в
lea eax, [eax*4]
И даже, скорее всего, будет содержать ненужные обращения к памяти (стеку данных Форта).
Ну что вы! Есть такой трюк — динамическая кодогенерация.Код генерился программистом? Структура алгоритма, регистры, инструкции, всё это прописывал программист в кодогенераторе? Такое и на Си делают.
Вместо того, чтобы вертеть большой цикл с кучей if внутри — можно динамически сгенерить код на конкретный набор условий. Выигрыш — порядка сотни разТак можно и на Си написать 100500 вариантов функции с разными наборами if, и скомпилировать. Уверен, результат будет лучше, чем при ручной генерации, т.к. компилятор из 100500 вариантов сможет найти «специальные» случаи (например, когда константа умножения случайно равна 16, или ширина массива кратна 4, а ещё всегда выровняет начало внутреннего цикла по линии кеша, подобрав перед циклом nop-инструкцию, занимающую нужное кол-во байт).
Это всё можно зашить в свой кодогенератор, но вряд ли получится превзойти 20-летнюю экспертизу кодогенераторщиков си-компилятора.
Подход этот, кстати, рабочий. В математическом пакете maple12 в комплекте идёт Open Watcom C++ 1.3, и решатели сложных задач генерят си-код под задачу, компилируют и запускают.
Функциональщина, хоть и привлекательна мне академически, не заходит дальше математического решения. А что бы положить это на существующие процессоры, нужен С.Функциональщина позволяет иметь ОС и IDE, на машине с 16 килобайтами ОЗУ. И никакого Си — компилятор, операторы языка, ядро ОС, IDE — все написано на этой самой функциональности. На ассемблере — лишь 3 килобайта примитивов.
Нет функций высшего порядка, замыканий, да хотя бы неизменяемых переменных.
Форт тем и хорош, что набор операторов и структур данных пишешь сам под себя.
Приведите форт-реализацию вот этого классического примера:
function makeAdder(x){
function add(y){
return y + x;
};
return add;
}
var plusFour = makeAdder(4);
console.log(plusFour(10)); // results 14
console.log(plusFour(40)); // results 44
Какую из этих частей вы не понимаете, как реализовывать?
Какую из этих частей вы не понимаете, как реализовывать?Не знаю такого слова, которое бы приняло строку со стека и сгенерировало слово с этим именем. Слова типа CREATE берут строку имени не из стека, а из потока программы, т.е. новое имя должно быть явно указано, не может быть сгенерировано.
Ну и потом, у авторов форт-систем — чуть иной взгляд на это дело. Если чего-то в ядре нету — то почему бы туда не добавить? Делов-то на полчаса. :-)
Главное — синтаксис позволяет. А переносимость и стандартность — это уже другие моменты.
Если в стандартном Форте есть слова для генерации слов с произвольным именем, то я их не знаю. Если вы думаете, что они есть, для закрытия вопроса достаточно их просто назвать )))
И что же практичное можно начать писать после элементарного освоения C? Сортировку? Двусвязные списки?
эхх, конечно нужно стараться изучать языки которые находятся ближе к вашим интересам. Конечно, нужно изучать теорию, пробовать на практике, при нулевом знании сложно начинать с асма, конечно сложно начинать с С/C++.
Но надо когда-то попробовать С, немного поковыряться с Асмом.
Причины простые:
1. если совсем не знать теорию, а также не пробовать языки в которых вы можете почувствовать теорию на практике, то скорее программист так и останется на начальном уровне.
2. на каком то либо языке многие вещи можно решить в 5 строк, но без многих знаний и практики это превращается в копипаст, а не в понимание что программист пишет
и в подтверждение, могу сказать то, что я вижу на практике:
Многие начинающие программисты пишут код не понимая разницы в парадигмах, толком не видят разницы(если вообще видят), то есть у них вечный поток сознания и какие-то замашки в одну или другую сторону.
И что бы победить этот поток сознания все равно приходится объяснять многие вещи на пальцах, а также указывать им на пробелы знаний в основах.
На мой взгляд хорошо начинать с языков похожих на Java или C#(язык хорош, но по религиозным взглядом, я отношусь к нему не очень хорошо), может в них и надо чуть больше писать, но за то в них все более явно, а также программист может читать полноценно всю логику своих мышлений. Python, отличный язык, простой и лаконичный, с хорошей философией.
Две самых важных вещей который я вижу, они достаточно строгие, а так же на них можно испробовать разные сферы.
Какой язык программирования учить в 2018 году и почему именно его?