Так как я веду несколько технических групп и чатов, то часто сталкивался с вопросом от подписчиков о том, с какого же языка лучше начать изучать программирование и информатику. Очень часто кто-то советует именно Python. Я в корне не согласен с этим советом. Мне нравится этот язык, и я ничего не имею против него, он прост и удобен. Но есть кое-какие аргументы против того, чтобы поставить его на место вашего первого языка программирования. Оговорюсь, что всё сказанное далее является субъективным мнением автора и не претендует на истину.
Итак, почему…
Ниже на картинке я привел пример, как можно с помощью маленькой функции обработать матрицу и вернуть структуру, соответствующую транспонированной матрице.
Транспонирование матрицы — это операция над матрицей, при которой ее строки и столбцы меняются местами. Кто уже начинал изучать аналитическую геометрию (линейную алгебру), тот сталкивался с этой простейшей задачей. Иногда это задание дают на уроках информатики в качестве сложных задач на обработку двумерных массивов, которые мы и называем матрицами. Что ж, кому-то может показаться и вовсе несложным. Однако, для большинства начинающих и людей, не сталкивающихся с программированием, понять, что такое двумерный/многомерный массив — это непростая задача. Вы можете не поверить, но есть много очень замудренных задач на обработку многомерных массивов, над которыми придется подумать даже опытному разработчику.
Но вернемся к нашей (более-менее легкой ?) задачке про транспонирование. Как вы видите, в Python задачу можно решить буквально за пару строчек кода. И всё это благодаря сложным встроенным функциям и методам, которые очень сильно облегчают ваш мыслительный процесс. В результате программируя на Python в качестве первого своего языка, вы надеваете на себя розовые очки и начинаете считать, что программирование — это просто. В этом есть и доля правды, и в этом есть огромный подвох.
Есть другие языки, более низкого уровня, которые помогут вам понять глубину, понять базу, понять структуру, снять розовые очки, убрать синтаксический сахар и как следует подумать над теми вещами, которые ранее вы принимали как должное. Какой из этого вывод? Если вы хотите научиться думать, по-настоящему понимать как работает железо, то лучше начать с низкого уровня. Поэтому полезнее будет начать с Assembler или C.
Во-первых, это даст вам лучшее представление о том, как работает процессор и периферийная электроника в вашем ПК.
Во-вторых, вы начнете понимать сообщения об ошибках в операционной системе.
В-третьих, последующие языки высокого уровня, базирующиеся на крепком фундаменте низкоуровневых основ, покажутся вам более прозрачными и понятными в обращении.
Думаю, что можно еще привести кучу плюсов к тому, чтобы начать с низкого уровня. Зачастую, люди, изучающие Python, по привычке подключают в свой код кучу библиотек ради реализации каких-то простейших функций. Логично предположить, что это сильно утяжеляет код и делает его медленным. А если еще вспомнить, что даже эффективно написанный python-код примерно в 1000 раз медленнее аналогичного кода на C/C++, то представьте себе какая производительность в итоге получится. Конечно же не всем разработчикам нужно писать ПО, которое работает в режиме реального времени и требует мгновенных реакций с минимальными задержками. Не всем нужно писать ААА-игры.
Тем не менее, обратите внимание на текущую ситуацию в программном обеспечении. Если раньше нужно было 8-битный процессор, чтобы запустить спутник в космос, то сейчас у нас тормозит несколько вкладок в браузере при 2-4 ядерном 64-битном CPU. Так может быть причина как раз в разработчиках, а не в «слабом» железе?
Самый ранний из найденных космических аппаратов, в которых стояли не микросхемы средней степени интеграции, а именно монолитный микропроцессор (8-битный RCA 1802) – это спутник Magsat, запущенный 30 октября 1979 года.В завершении хотелось бы сказать, что все языки программирования — это великие достижения в IT-области. Но чтобы нам стать настоящими профессионалами и экспертами, всё равно придется узнать то, с чего всё начиналось, вспомнить об истоках, математике, алгоритмах, ассемблере и даже об электронике и физике. Все знания должны сплетаться в вашей голове в единую картину, в крепкую логическую цепочку. Последнюю получится построить только тогда, когда мы начнем от корня технологий, начнем с самого нижнего уровня.
Напишите в комментариях, согласны ли вы с такой идеей? Или же вы придерживайтесь другого подхода?
uliana_offshore
а какой выбирать?
Impressive_i Автор
К примеру, язык C сможет дать вам больше пользы. Он и не является самым «низким и рутинным», он по-прежнему актуален, он дает лучшее понимание работы компьютера и после него остальные языки учатся лучше. Почему бы не начать с него?
Опять таки, это моё личное мнение, не хочется его навязывать, а хочется просто поделиться мыслями.
Есть разные люди. Кому-то интересно понимание, а кто-то стремится использовать язык программирования как инструмент для решения своих основных задач или просто для быстрого заработка денег. Поэтому от цели человека тоже многое зависит.
edo1h
у меня си был, наверное, третьим языком (после бейсика и ассемблера).
если знаешь ассемблер, то классическая книга k&r отлично «заходит», си видится как такой продвинутый супер-ассемблер. а вот на роль первого языка… сомневаюсь.
speshuric
Я тут пару месяцев назад объяснял неглупым студентам, знающим Java, но не знающим C некоторые моменты из C. Да мне банально стыдно было объяснять, что в C массив не массив, что строки не строки, что "*" надо читать не как часть типа, а как часть объявления переменной, что в C есть разница медлу объявлением и определением. Понимание этого нормально для разработчика ОС, но забивать этой ерундой голову на первом ЯП — абсолютно лишнее.
Python самое то, для начала. Мой сын в неполные 8 лет пишет простые штуки на Python. Потому что я смог объяснить, что такое условие, что такое переменная, что такое цикл, что такое метод, что такое параметр метода, что такое тип. Если бы мне пришлось попытаться объяснить указатели и подобную ересь, он бы не смог.
alfos
Только вот в Python нет переменных.
masai
Что такое
x
, если не переменная?lz961
x ссылка на иммутабельный объект класса 'int'. Только если в С++ ссылка всегда привязана к одному и тому же объекту в пределах области видимости и времени жизни, в Python можно переназначать ссылки, из-за чего возникает иллюзия переменных.
speshuric
Ну эти ссылки даже в language reference (например тут) и называют переменными (variables).
lz961
сама ссылка variable, а не то, на что она ссылается.
habr.com/ru/company/mailru/blog/454324
speshuric
Да, сама ссылка и есть variable. Я же не спорю о том, что понятие переменных немного отличается от С++. Просто там выше было "в python переменных нет" — слегка максималистское утверждение, которое не вполне соответствует документации.
lz961
Извините, но ваши слова — форменное начетничество. Для большинства переменная — изменяемый объект имеющий два неизменных атрибута: имя и тип, и изменяемое значение. Конечно, с формальной точки зрения указатель и переназначаемая ссылка являются переменными. Но когда говорят о них, их так и называют, не используя термин «переменная».
Это замечание также является ответом на ваш комментарий habr.com/ru/post/516070/#comment_21985010
UPD: разовью мысль. В Python есть объекты, изменяемые либо нет, с раз и навсегда заданным типом, но не имеющими имени. В этом смысле они не являются переменными. И есть изменяемые ссылки, которые авторы языка, на правах демиургов окрестили «переменными». Но для этих «переменных» разрешены ровно две операции: переназначение и обращение посредством них. А привычных переменных, которые можно складывать, вычитать, сравнивать, и т.п. присваивать им значение, брать их адрес и привязывать к ним ссылки в Python нет.
masai
Про большинство — это сильное утверждение, которое следовало бы подкрепить какими-то авторитетными источниками.
Например, в Википедии переменная определяется как область памяти, связанная с некоторым идентификатором. Если Википедия недостаточно авторитетна, то подобное определение можно найти и в классической книге «Компиляторы: построение и анализ» Ахо и др. (раздел 1.6.2).
Давайте оставим споры о том, чьё определение лучше и более общепринято, и на минутку примем то, определение, которой я привёл выше (переменная — область памяти, связанная с идентификатором). Вы согласны, что в Python переменные всё же есть?
Вот, скажем, открываю я раздел об указателях в C++ и читаю, что «указатель — это тип переменной, который...». Более того, ниже написано, что «pointers… are variables themselves», и используется словосочетание «pointer variable». Выходит, что говорят. Уверен, что можно найти массу других примеров, когда указатель называют переменной.
И если с формальной точки зрения ссылки — это переменные, что вы сами и написали, то почему вообще этот спор возник? Раз формально ссылки — это переменные, то почему вы говорите, что переменных нет? Они есть.
Так почему мы должны им отказывать в этом праве? Это общепринятый среди программистов на Python термин, а значит, когда мы говорим о Python, то и называть
x
нам следует переменной. Разве нет?lz961
Возьмем файл. Лежит в области памяти? Да, пусть и не оперативной. А может закеширован и именно там и лежит. Идентификатор есть? Есть — его имя. Но файлы переменными почему то не называют.
Далее, рассмотрим UNIX-подобные ос. В них у одного файла может быть несколько имен и файл будет существовать до тех пор, пока с ним будет хотя бы одно имя. Ничего не напоминает? Может объекты в Python файлами назовем? Нет не будем, потому что у файлов есть дополнительные свойства, которых нет у объектов Питон.
Я же пишу, вы ударяетесь в начетничество и формалистику. Это же касается и следующего за этой фразой абзаца.
Можно рассмотреть еще «переменные» в Wolfram Language с его двумя формами «присваивания». Там вообще чудеса можно творить. Фактически речь идет о записях, указывающих на связь между литералом и выражением. В одной форме присваивания выражение вычисляется (простите редуцируется), а в другой оставляется как есть.
Так вот результат последовательности операций
x = a+b
y = x
z := x
x = c+d
для кого то результат может оказаться неожиданным. (Хотя проверить не могу, Mathematica у меня нет уже довольно давно).
нужно всё-таки разделять программистов на Питоне и пользователей Питона. Кого сейчас больше — вопрос, но это оффтоп.
masai
Так что насчёт определения из книги Ахо, согласны с ним? И как вы прокомментируете то, что указатели всё же называют переменными в документации C++?
Ха-ха! Так этот пример работает и против вашего определения («изменяемый объект имеющий два неизменных атрибута: имя и тип, и изменяемое значение»). Имя есть, тип есть, содержимое файла может меняться. Вполне можно считать типом тип содержимого, который отражён в расширении. Или, если хотите, можно делить файлы на обычные, символические ссылки, блочные устройства и т.д. :)
По-моему, формалистика — это надуманное разделение переменных на подвиды. Просто приведите ссылки на авторитетные источники, подтверждающие вашу точку зрения.
А кто такие пользователи Python и чем они отличаются от программистов? И зачем их разделять?
lz961
По поводу определения понятий переменных и указателей я кратко, но надеюсь исчерпывающее ответил к другому вашему комментарию habr.com/ru/post/516070/#comment_21987278
По поводу файлов и переменных. У переменной есть еще один важный, но не упомянутой мною атрибут — программа, в которой она существует. Файл как таковой существует сам по себе.
По поводу ссылок на авторитетные источники. Ссылаясь на кого-то, ссылающийся берет на себя всю ответственность за написанное другим автором в рамках цитирования и дополнительных оговорок. Авторитет здесь не причем. Авторитет — тот, кого прочитают первым, а не тот, на кого сошлются неглядя. Большинство из тех, кто сейчас на чем либо программирует начинали с чего-то вроде Бейсика или Паскаля. И там с понятием переменной все было четко — именованная ячейка памяти.
Возвращаясь к Питону. Можно дать четкое и понятное описание его грамматики не прибегая к понятию переменной, используя, при этом, термины «ссылка», «объект», «класс», «тип» и т.п. не переопределяя их.
Программист пишет ПО согласно ТЗ для использования автором ТЗ или третьими лицами. Пользователь использует языки программирования для создания собственных инструментов для решения стоящих перед ним задач. Пример — Датасаентист.
speshuric
Файлы — плохая аналогия. Под файлами чаще всего понимаю что-то похожее на posix-файлы. И в этом случае аналогия становится сильно сложнее. Для переменной возможно обойтись только очень небольшим количеством операций, которые действуют на всю переменную (ну например, это могут быть инициализация, присвоение, получение ссылки), для файла набор операций заметно отличается. На эту тему был неплохой обзорный доклад.
Но в любом случае предлагаю прекратить бессмысленный спор. В первом ЯП мне лично проще описать, как работает Python с его переменными-ссылками, чем С. Есть и другие языки, достаточно простые, которые не требуют таких усилий, как С, но у них у всех есть недостаток — малая кодовая база. А тут я на Minecraft'е могу показать простые приёмы и ребёнку интересно (например, он может быстро делать в Python то, что задолбается делать руками). Если захочет быть программистом, то всё равно освоит не меньше 5-6 ЯП. Если не захочет, то Python хватит по жизни. Ну не с MSX Basic же начинать в 2020 году.
masai
Ну вот я пишу:
Это разве не присваивание значений и не сложение? Да, под капотом там более сложный механизм, чем в C++. Но по-моему, отрицание того, что в приведённом коде есть присваивание и сложение — это уже казуистика.
lz961
Говоря о языке как таковом, я считаю, лезть под капот вообще не нужно, можно оперировать только его описаниями и фактическими свойствами реализаций. Везде выше я писал примеры на чистом Python, которые должны работать одинаково в любых его реализациях.
Пока идет работа с иммутабельными (с точки зрения Python) объектами, «переменные» ведут себя привычным образом, по крайней мере до тех пор, пока не начинаем сравнивать их id. Как только объекты становятся сложнее «переменные» сразу превращаются в ссылки.
masai
Так я ж не спорю, что там ссылки. Мне непонятно, почему ссылку нельзя назвать переменной. Это переменная и есть. И когда вы ссылаетесь на мнение большинства, это вызывает лишь недоумение. Я программирую уже лет 25 в том числе и на Python, и впервые сталкиваюсь с утверждением, что в Python нет переменных (это не аргумент, конечно, просто объясняю своё удивление).
Разделение переменных на собственно переменные и ссылки не только излишне, оно вдобавок всё сильно запутывает. Это разделение просто излишне.
Например, вы приводили C++ в качестве примера языка, в котором переменные определённо есть.
Вот, скажем, такой кусочек кода:
Здесь
b
— это, очевидно, не указатель и не ссылка. Это видно просто из объявления. Звёздочки нет же. Значит это переменная. Но внутри v содержит указатель, который может меняться. Значит это, по-вашему, не переменная. Что же это?Если же вы всё же согласитесь, что
b
— это переменная, то что мешает назвать переменными объекты в Python, ведь там практически такая же ситуация?lz961
Есть в Python переменные — исключительно ссылки, только по почкам не бейте.
St_one
Это называется "переменная ссылочного типа".
lz961
Есть в Python переменные — исключительно ссылочного типа, только по почкам не бейте.
alfos
x = 5
y = x
x = 'spam'
Что выведет print(y)
masai
Выведет
5
.Признаться, не очень понимаю, как это отвечает на вопрос, как следует называть
x
.speshuric
Странно. В language reference, во всей документации и PEPах есть, а у вас нет.
eandr_67
Да, Python (как и любой другой язык с динамической типизацией) — очень плохой выбор для начального обучения. Но и C не лучше. Любой новичок совершает ошибки. Но есть языки, в которых достаточно много логических ошибок выявляется на этапе компиляции, а есть языки, которые безо всяких замечаний скомпилируют любой бред. Программируя на C или ассемблере, учащийся даже не поймёт, что допустил ошибку.
Идеальным для обучения является предельно маленький язык (без синтаксического сахара, особых случаев и выполнения работы за программиста) с предельно сильной статической типизацией. Это, прежде всего, языки, созданные Виртом (от Pascal до Oberon-07), и, с оговорками, Go.
А вот после изучения основ алгоритмики на языке высокого уровня (ЯВУ) уже переходить к ассемблеру — чтобы понимать, как написанный код выполняется процессором и сколько «сто?ит» каждый оператор ЯВУ.
P.S. И, да: С намного проще изучать после знакомства с ассемблером.
lz961
ИМХО «Роботландия» с целым набором исполнителей (структурное программирование, функциональное программирование, машина Тьюринга) родом из конца 80-х-середины 90-х была шикарна. Для школьных задачек, опять таки ИМХО, подходит Паскаль, который именно для школьников/студентов был создан.
saag
ну вот была у меня, можно сказать классическая тройка Basic-Pascal-C