Есть командная игра, которую сделали все, кто работает с детьми. В этой игре один человек назначается «производителем бутербродов» и получает буханку хлеба (нарезанную, если лидеры игры хорошие, и не нарезанную, если нет), один или два ножа и приспособления для изготовления какого-либо вида хлеба. сэндвич, традиционно арахисовое масло и желе или версия, не вызывающая аллергию. Изготовитель сэндвичей делает вид, что понятия не имеет, как приготовить сэндвич, и задача остальных членов группы — проинструктировать их. Есть два нюанса: «инструкторы» не могут видеть, как готовится сэндвич, а сэндвичмейкер должен выполнять все инструкции на 100% буквально без каких-либо предположений. Например, если инструктор начинает с указания намазать хлеб арахисовым маслом, производитель бутербродов может взять банку с арахисовым маслом и положить ее на буханку. За этим следуют махинации, и каждый усваивает урок о том, как быть внимательным и давать четкие инструкции.

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

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

Использование языка низкого уровня похоже на то, что вы рассказываете кому-то, как сделать бутерброд в игре, в то время как язык высокого уровня похож на то, что вы спрашиваете друга. Мы видим разницу в том, как два языка, C++ и Ruby, выводят данные на консоль.

В C++ строка кода, которая выводится на консоль, выглядит так:

std::cout << "Hello, World!\n";

Распаковываем эту строку. std::cout сообщает программе, что мы выводим какое-то значение. Проблема в том, что C++ сам по себе не знает, как это сделать, поэтому мы должны указать компьютеру искать в стандартном пространстве имен, которое представляет собой библиотеку функций. Программе должно быть явно указано, где найти функции, которые вы хотите использовать, если вы не определяете их самостоятельно. Затем мы заключаем желаемый вывод в двойные кавычки, чтобы сообщить компьютеру, что это строка. Яркая часть строки, которая может показаться самой странной, — это \n в конце строки. Помните, компьютер все воспринимает буквально? Без предупреждения он продолжит вывод в той же строке терминала. \n явно указывает компьютеру перейти к следующей строке. Наконец, точка с запятой сообщает компьютеру, что мы закончили писать эту строку кода, и он может выполнять следующую инструкцию.

Сравните это с той же функцией в Ruby:

puts "Hello, World!"

И это все. puts — это команда, встроенная в Ruby, которая говорит компьютеру вывести следующее значение на терминал и добавить после него новую строку. Если вам НЕ нужна новая строка, используйте print вместо puts. Язык имеет полностью встроенные команды, без необходимости в дополнительной библиотеке, и он может интуитивно определять, следует ли добавлять новую строку на основе команды, которую вы используете. Легкий. Точки с запятой необязательны, но их легко пропустить, поэтому Ruby позволяет их пропустить. Он просто знает или может обоснованно догадаться, когда вы закончите и хотите, чтобы он выполнил что-то новое.

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

С языком низкого уровня у нас есть более детальный контроль над тем, что происходит. В случае C++ мы можем сэкономить время, направив компьютер именно туда, где нужно найти определение cout. Мы можем очень четко указать, где заканчивается линия, и устранить любую двусмысленность со стороны компьютера в отношении того, что мы хотим. Если наша цель — невероятно быстрая и оптимизированная программа, это идеально. В более сложной программе мы можем явно управлять памятью, чтобы освободить место и сократить время выполнения, или иметь явный контроль над тем, как мы перебираем массив с помощью цикла for. Языки высокого уровня могут позволить такой контроль, но языки низкого уровня требуют этого.

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