Мови програмування – це системи символів і правил їх поєднання, призначені для взаємодії людини зі складними машинами. Існують сотні таких організованих систем, що виконують різні функції. Щоб зорієнтуватися в цьому різноманітті, фахівці створюють загальні класифікації мов програмування, засновані на тому чи іншому характерній ознаці.
Взаємодія людини і машини
Важливо зрозуміти, як відбувається спілкування людей з розумними механізмами, перш ніж переходити до класифікації мов програмування.
Одного разу чоловік подумав, що машина може виконувати фізичну роботу за нього. Так з’явився паровий двигун. Потім підприємливий чоловік вирішив перекласти на машину ще і розумову роботу. Так з’явилися ЕОМ.
Щоб досягти якогось результату, необхідно розуміти, як це зробити. У програмуванні можна виділити кілька етапів вирішення будь-якої задачі:
Це ієрархічна структура, у якій вищі рівні базуються на нижчих. Без чіткої задачі і грамотної опрацювання алгоритму неможливо створити якісну програму.
Структура мов програмування
Пристрій всіх систем взаємодії схоже і багато в чому визначає класифікацію мов програмування.
Основні об’єкти мови програмування постійні і нагадують компоненти людських мовних систем:
- синтаксис, який визначає формальні правила запису програми, допустимі види і регістр символів;
- лексика, що включає в себе весь словниковий запас мови: імена змінних і функцій, константи, рядки, оператори;
- граматика, що вказує, як правильно поєднувати одиниці мови для утворення словосполучень і речень.
Лексика і граматика разом визначають семантику мови. На цьому рівні конкретні послідовності знаків набувають особливий сенс, зрозумілий людині і комп’ютера. Наприклад, слово while у багатьох системах програмування трактується як початок циклічної операції.
Звичайно, комп’ютери не розуміють звичайних слів, саме по собі поєднання латинських літер нічого для них не означає. Машини мають справу з машинним кодом – нулями та одиницями, що описують примітивні стану наявності або відсутності сигналу. Тому мови програмування встановлюють чіткі відповідності певних слів і послідовностей нативних машинних команд.
Перші примітивні системи управління машинами – перфокарти – використовувалися для ткацьких верстатів Жаккарда, які переносили на шовк візерунок будь-якої складності. Таким же способом програмувалися самоиграющие піаніно.
Існують сотні систем програмування, і кожен рік з’являються нові. Деякі з них принципово відрізняються один від одного, інші дуже схожі і мають лише дрібні особливості. Кожна призначена для вирішення свого завдання, широкої або вузькоспеціалізованої.
Огляд класифікацій
Мови програмування можуть бути згруповані по десятках різних ознак. Вони є принципово важливими або мають прикладне значення.
Спостерігається сильна залежність класифікації мов програмування від історії розвитку. З роками технології ускладнювалися і кардинально змінювалися, на перший план виходило зручність програміста, з’являлися ефективні алгоритми, складні команди і нові рівні абстракції.
Основні класифікації мов програмування за видами і механізму роботи базуються на наступних параметрах:
- Особливості лексики та граматики в сукупності з рівнем абстракції і ступенем зручності для людини.
- Базова концепція і методологія складання алгоритмів.
- Спосіб подання даних.
- Організація процесу взаємодії з машиною, механізм виконання програм.
- Сфера життя, в якій застосовується мову.
- Історична епоха, в яку мовна система була сформована.
Скласти чітку класифікацію мов і систем програмування не можна, але можливо розділити і систематизувати їх за принципово важливим ознаками.
Зручність для людини
Інструкції, написані на машинній мові, зрозумілі комп’ютера, але вкрай незручні для людини. У них важко розібратися, їх практично неможливо швидко змінити або скласти з їх допомогою складний алгоритм. Для підвищення ефективності програмісти піднялися на нові рівні абстракції і навчили машину приймати більш людинозрозумілі інструкції і самостійно переводити їх у машинний код. Розглянемо класифікацію та особливості мов програмування різного рівня:
- Машинний код. Це теж мова програмування, на якому при належній підготовці можна написати інструкцію.
- Низький рівень. По-справжньому низькорівневими є мови асемблера, які використовують нативні машинні команди, закодовані за допомогою мнемонічних кодів.
- Середній рівень. Системи програмування цієї групи можуть вважатися і низько – і високорівневими, в залежності від конкретних уявлень про ступінь абстракції. Сюди можна віднести C і C++.
- Високий рівень. Ці мови дозволяють створювати складні алгоритми, але вимагають додаткової обробки перед виконанням, тому згенерований код ними менш ефективний і виконується повільніше.
- Надвисокий рівень. Ця нечисленна група характеризується появою надпотужних команд і операторів. Сюди можна віднести Алгол-68.
Особливістю мов низького рівня є їх машинозависимость. Вони тісно прив’язані до особливостей організації конкретного типу ЕОМ, але в цілому схожі один на одного. Вони забезпечують:
- високу швидкість виконання і максимальну компактність створюваних програм;
- пряма взаємодія з апаратними ресурсами;
- повний контроль над пам’яттю.
Основні недоліки низькорівневих мов:
- для кожного типу ЕОМ необхідно використовувати певну систему команд, залежну від особливостей функціонування машини;
- складність і низька швидкість процесу програмування;
- висока ймовірність появи помилок, які складно відстежити;
- відсутність мобільності програм, неможливість запустити їх на ЕОМ іншого типу.
Високорівневі системи програмування не прив’язані до певної машинною системою команд і можуть виконуватися на будь-якому комп’ютері. Завдяки високому рівню абстракції вони можуть собі дозволити використовувати різноманітні концепції і методології в складанні інструкцій. Тому класифікація мов програмування високого рівня дуже обширна і складна.
Обробка програми машиною
Щоб виконати складну інструкцію, комп’ютер насамперед повинен знизити її абстрактність і перекласти на зрозумілу для себе мову. Спосіб, яким це робиться, називається моделлю виконання. Виділяють дві основні моделі і одну гібридну:
- Компіляція – одноразовий переклад всієї програми в машинний код.
- Інтерпретація – послідовне виконання кожного виразу.
- Транскомпиляция – переклад на мову більш низького рівня, наприклад C або асемблер, і його подальша компіляція.
Для перекладу необхідна спеціальна програма-транслятор – компілятор або інтерпретатор, без якої робота з мовою неможлива.
Інтерпретатор працює з кожним рядком програми окремо, аналізуючи її і відразу ж виконуючи. Його присутність необхідно від початку і до самого кінця роботи програми.
Основні недоліки інтерпретаційної моделі:
- постійне знаходження транслятора в пам’яті ЕОМ;
- повторна обробка повторюваних команд.
Незважаючи на це, інтерпретовані мови дуже зручні для циклічної розробки та налагодження, так як дозволяють швидко вносити зміни в програму.
Компілятор ж працює тільки один раз, відразу перетворюючи всю інструкцію в зрозумілу для комп’ютера вид – машинний код або якийсь проміжний байт-код, а потім залишає пам’ять ЕОМ. Тут виконання відокремлене від процесу трансляції, що є більш ефективною моделлю.
Основні недоліки компиляционной моделі:
- велика складність.
Перш ніж перевести програму на зрозумілий машині мову, транслятор багато разів проходить по вихідній інструкції, аналізуючи і перевіряючи її.
Чіткого розмежування систем не існує, так як традиційно інтерпретовані мови можуть бути скомпільовані і навпаки.
Класифікація мов програмування високого рівня по моделі виконання:
- Інтерпретовані – Python, Haskell, PHP, JavaScript.
- Компилируемые відразу в машинний код: C, C++, Fortran, ASM.
- Компилируемые в байт-код: Python, Java.
- Транскомпилируемые: Haskell, Fortran, C, C++.
Обробка даних
Будь-яка мова програмування працює з інформацією, якої потрібно якимось чином маніпулювати, перевіряти коректність, змінювати. Дані можуть бути самими різноманітними – числами, рядками або складними структурами. Зрозуміло, що з кожним типом необхідно працювати по-різному, але щоб визначити, як саме, спочатку необхідно зрозуміти, з якими саме даними ЕОМ має справу.
На основі методу визначення різновиди даних побудована класифікація мов програмування за системою типів.
- Нетипизированные мови.
- Типізовані мови різного ступеня строгості.
Нетипізованими є мови асемблера, які здатні обробляти безпосередньо двійкові дані. Тип даних при цьому не має ніякого значення.
Для типізованих мов важливо, з якою різновидом даних вони працюють. Деякі операції визначені тільки для чисел, наприклад поділ, інші – тільки для рядків. При цьому деякі системи дозволяють програмісту певні вольності. Наприклад, вони можуть самостійно визначати і “неявні” конвертувати один тип даних в інший, виходячи з семантики команди. Це дуже зручно, але ускладнює налагодження, так як може призвести до непомітною помилку. Яскравим прикладом строгою типізацією є JavaScript.
Строго типізовані мови, наприклад, Java, такої свободи не допускають і вимагають вказівки типів і їх явної конверсії, якщо вона необхідна.
Існує також класифікація мов програмування високого рівня з моменту перевірки типів даних:
- статичні мови зазвичай є компилируемыми. Перевірка типів відбувається при аналізі програми перед її трансляцією на машинну мову.
- динамічні мови перевіряють типи даних при виконанні.
Принциповий спосіб взаємодії
Высокоабстрактные мови можуть бути розділені за основною парадигмою програмування. Існують десятки методологій складання програм, деякі з яких дуже схожі один на одного, тому створити чітку систему відмінностей неможливо. Коротко класифікація мов програмування виглядає так:
- алгоритмічні, імперативні, процедурні. Вимагають явного послідовного опису алгоритму рішення задачі. Оператори при цьому об’єднуються в процедурні групи, відокремлені від самих даних. Приклади процедурних мов – Pascal, Basic;
- логічні, декларативні. Максимально формалізовано описують саму задачу і необхідний результат. Рішення при цьому має логічно випливати з цього опису;
- об’єктно-орієнтовані, структуровані. Мають в основі концепцію об’єкта, що поєднує у собі дані і методи їх обробки.
Об’єкти в програмуванні
Мови останньої групи описують всі сутності у вигляді незалежних об’єктів, що приховують в собі складні механіки. Основними концепціями ООП (об’єктно-орієнтованого програмування) є:
- інкапсуляція – приховування функціоналу всередині об’єкта;
- спадкування одними об’єктами методів інших;
- поліморфізм – зміна суті із збереженням зовнішнього інтерфейсу.
Можна також скласти класифікацію мов об’єктно-орієнтованого програмування за способом реалізації основних концепцій цього підходу – наслідування, інкапсуляції і поліморфізму. Крім класичних механізмів існують інші, наприклад прототипный, використовуваний в JavaScript.
Методологія ООП вважається найбільш прогресивною, ефективної і в деякому сенсі модною. Однак у ряді випадків для розв’язання конкретної задачі більш ефективними можуть бути інші підходи, наприклад функціональний.
Покоління мов програмування
Класифікація мов програмування з історії їх появи вважається умовною, так як не враховує особливості конкретних систем. Однак вона дозволяє простежити, як змінювалися з часом концепції та ускладнювалися завдання, що стоять перед програмістами.
Спроби зв’язати класифікацію та еволюцію мов програмування виділилися кілька великих груп, названих поколіннями:
- Перше покоління – машинні мови низького рівня, прив’язані до реалізації конкретної ЕОМ. “Програми” на цих мовах виглядали як ряди перемикачів, наведених в потрібне положення, або перфокарти (перфострічки). Таким чином, всі команди представляли собою послідовність нулів і одиниць – бінарний код. Приклад: мова ARM-процесора.
- У другому поколінні мови стали трохи зрозуміліше для людини, але відв’язати їх від конкретного апарату так і не вдалося. Це час мов асемблера з його мнемоническими кодами і однозначної складанням в машиночитаемую форму. Приклад: Макроассемблер.
- Мови третього покоління зняли з програміста турботу про непринципових деталях складання інструкцій, таких як переведення програми в машинний код. Тепер комп’ютер навчився робити це самостійно. Синтаксис і лексика наблизилися до людських, стали зрозумілішими. В цьому поколінні зародилися практично всі сучасні мови високого рівня з широкою областю застосування, незалежно від їх парадигми: PHP, Fortran.
- В четвертому поколінні рівень абстракції зріс ще більше, різко звужуючи область використання. До цієї групи відносяться такі специфічні мови, як FoxPro, Simulink, SQL. З’явилися мови візуального програмування: CAD-пакети, системи RAD.
- Нарешті, мови п’ятого покоління повинні були самі писати програми, отримуючи лише опис від програміста. Ця задумка так і не була реалізована повністю, так як для складання ефективного алгоритму іноді недостатньо прямої машинної логіки, а потрібно ще людська інтуїція і кмітливість. Прикладами мов п’ятого покоління є MathCAD, Prolog і Mercury.
По суті, покоління мов в точності відповідають етапам програмування, розглянутих на початку статті, переліченим у зворотному порядку. Спочатку програміст всі операції брав на себе, а машина лише виконувала задану послідовність дій. Тепер же ЕОМ здатна видавати результат за формализованному опису завдання.
Полегшення праці програміста супроводжується збільшенням навантаження на машину, програма виконується повільніше і вимагає великих ресурсів.
Незважаючи на те, що технічний прогрес рухається семимильними кроками, мови перших поколінь зовсім не зникли. Вони застосовуються в областях, що вимагають максимальної простоти й ефективності.
Область застосування
Кожна мова програмування гарний у своїй галузі, для якої він створювався. Так, для програмування мікроконтролерів використовуються ассемблеры, а з Java там робити нічого. Низькорівневе програмування драйверів ефективно з C, що дозволяє строго контролювати ресурси пам’яті. Для веб-програмування варто вибрати скриптові мови PHP і JavaScript, інтерпретатор якого вбудований в кожен сучасний браузер. Важливі банківські програми написані на Java, що забезпечує контроль помилок. Аерокосмічні – теж на Java або на Паскалі, який навіть прибирання сміття віддає на контроль програмісту.
Усі мови гарні, треба лише підібрати відповідний задачі.
Важливість класифікації
Складно розділити сотні існуючих систем взаємодії людини і ЕОМ на кілька чітких груп. І все ж огляд класифікацій мов програмування коротко простежує історію їх еволюції і глибше розкриває закладені в них ідеї.
Кожна мова одночасно належить до кількох з перелічених груп – він може бути строго типізованих, компилируемым і об’єктно-орієнтованим одночасно. Тому не можна розглядати різноманіття систем програмування через призму якоїсь однієї класифікації.