Remove ads
штучна мова, створена для передачі команд машинам, зокрема комп'ютерам З Вікіпедії, вільної енциклопедії
Мо́ва програмува́ння (англ. Programming language) — це штучна мова, створена для передачі команд машинам, зокрема комп'ютерам. Мови програмування використовуються для створення програм, які контролюють поведінку машин, та для запису алгоритмів.
Суворіше визначення: мова програмування — це система позначень для опису алгоритмів і структур даних[1], певна штучна формальна система, засобами якої можна виражати алгоритми[2]. Мову програмування визначає набір лексичних, синтаксичних і семантичних правил, що задають зовнішній вигляд програми та дії, які виконує виконавець (комп'ютер) під її управлінням.[3]
З часу створення перших програмованих машин було створено понад дві з половиною тисячі мов програмування[4]. Щороку до них додаються нові. Деякими мовами вміє користуватись тільки невелике число їхніх розробників, інші стають відомі мільйонам людей. Професійні програмісти зазвичай застосовують у своїй роботі декілька мов програмування.
Мова програмування — це нотація для запису програм, які є специфікаціями якогось обчислення або алгоритму[5].
Перші мови програмування з'явилися задовго до появи перших комп'ютерів. Ще в XIX столітті існували «програмовані» ткацькі верстати та піаніно-програвачі, спосіб програмування яких нагадує так звані предметно-орієнтовані мови програмування. На початку XX століття починають використовувати перфокарти та механічну обробку даних. У 1930—1940 рр. виникає лямбда-числення та машина Тюринга, які застосовували математичну абстракцію для опису алгоритмів. Лямбда-числення згодом здійснило вплив на проєктування мов програмування[6].
У 1940 роках створюються перші електричні двійкові комп'ютери. Вважається, що першу мову програмування високого рівня — Планкалькюль (нім. Plankalkül) розробив німець Конрад Цузе в період 1943—1945 років, але в той час вона не була реалізована і нею не зацікавилися. Реалізацією мови зайнялися і здійснили її лише в 1998—2000 роках[7].
Наприкінці 1940-х — початку 1950-х років застосовували інтерпретовані системи кодування, коли певні команди мови програмування кодували числами, які вже інтерпретувалися машинним кодом. Ці системи називалися «автоматичним програмуванням» і були простішими для програмування, ніж машинні коди, але могли мати значно меншу (до 50 разів) швидкодію, через що перевагу часто надавали машинним кодам. До таких систем належали — Short Code для BINAC (1949) і UNIVAC I (1952), Speedcoding[en] для IBM 701, розроблена Джоном Бекусом у 1954 році.
Першою багатоконцептуальною (імперативною та декларативною) мовою програмування високого рівня була Адресна мова програмування (реалізована 1955 року на ЕОМ «Київ»). Мова має опосередковану адресацію вищих рангів (вказівники є аналогом). В ЕОМ «Київ» апаратно була реалізована «штрих-операція», аналогом якої є розіменування вказівників. Операція багаторазового розіменування вказівників (Multiple indirection) була реалізована груповими операціями модернізації адрес задля прискорення обробки деревоподібних форматів (Абстрактні типи даних є частковим випадком, оскільки деревоподібні формати припускають наявність у вузлах «дерева» процедур обробки даних, як в ООП). Адресна мова програмування має вичерпні засоби декларативного програмування. До найпотужнішого декларативного засобу належить «мінус штрих-операція», яка є оберненою до розіменування вказівника. Використання «мінус штрих-операції» нагадує використання первинних і зовнішніх ключів в реляційних базах даних: по заданому первинному ключу визначити місце розташування (адреси) в іншій таблиці, зовнішні ключі яких збігаються з заданим первинним ключем[8].
Першою широковживаною компільованою мовою став розроблений групою Джона Бекуса Фортран, анонсований 1954 року та випущений 1957 року для IBM 704. Основним призначенням Фортрану були швидкі наукові обчислення, оголошувалося, що швидкодія згенерованого компілятором коду майже не відрізнятиметься від написаного вручну машинного коду. Уже у квітні 1958 року близько половини програм для IBM 704 були написані на Фортрані. Випущений 1958 року Фортран II дозволяв незалежну компіляцію підпрограм, що давало змогу створювати більші програми, оскільки через низьку надійність IBM 704 не можна було скомпілювати без збоїв велику програму (понад 300—400 рядків) одразу. Розроблений у 1960—1962 роках Фортран IV був однією з найпоширеніших мов того часу і лишався стандартною версією Фортрану до появи 1978 року Фортрану 77.
1958 року в MIT розробили LISP — першу функційну мову, яка понад чверть століття домінувала у програмуванні задач штучного інтелекту.
Наприкінці 1950-х років почали розробляти різні мови програмування. 1958 року декілька значних груп комп'ютерних користувачів у США, включаючи SHARE — групу науковців-користувачів IBM і USE (UNIVAC Scientific Exchange, група науковців-користувачів UNIVAC) запропонували ACM заснувати робочу групу зі створення універсальної мови програмування. Також ще 1955 року німецьке Товариство прикладної математики й механіки (GAMM) заснувало комітет зі створення універсальної мови програмування. У кінці травня 1958 року було проведено зустріч у Цюриху між ACM і GAMM, на матеріалах якої у грудні опубліковано ALGOL 58 Report. На його основі було створено 3 значні реалізації — MAD (1961), NELIAC (1963), JOVIAL (1963). З них лише JOVIAL отримав поширення, ставши на чверть століття офіційною мовою програмування у Військово-морських силах США. SHARE та IBM почали створення власної реалізації ALGOL, але припинили, врахувавши витрати на створення і просування Фортрану.
Упродовж 1959 року ALGOL 58 широко обговорювався, була запропонована нотація для опису синтаксису мов програмування — форма Бекуса — Наура. 1960 року проведено чергову зустріч і опубліковано ALGOL 60 Report. ALGOL вплинув на багато мов програмування і став стандартною мовою для публікації алгоритмів, але через ряд причин не одержав широкого розповсюдження — він був заскладним, і не було реалізацій, які підтримували його повністю, відсутність стандартного введення-виведення зумовила появу різних несумісних реалізацій, деякі неоднозначності опису мови так і не були розв'язані. Окрім того, широкого вжитку уже набув Фортран, і IBM не підтримала ALGOL.
1959 року було проведено зустріч у Пентагоні для створення мови CBL (Common Business Language), засновано комітет з її створення, і 1960 року опубліковано початкову специфікацію COBOL 60, який невдовзі став першою мовою, ухваленою у Міністерстві оборони США. 1968 року COBOL було стандартизовано ANSI.
У 1964 році було створено спрощену мову BASIC (Beginners All-purpose Symbolic Instruction Code) для навчання програмуванню студентів, які переважно спеціалізувалися у вільних мистецтвах, а не технічних науках.
Тоді як науковці переважно використовували Фортран, а бізнес — COBOL, 1963 року в IBM вирішили створити універсальну платформу IBM/360 і мову програмування. У стислі терміни до 1965 року було розроблено мову PL/I, яка поєднувала можливості Фортрану, ALGOL і COBOL, і виявилась заскладною, хоча і була у широкому вжитку в 1970-х у наукових і бізнес-задачах, також її підмножини (PL/C, PL/CS) використовувалися для навчання програмуванню.
На початку 1960-х років було створено перші мови із динамічною типізацією — APL і SNOBOL.
SIMULA 67 була першою об'єктно-орієнтованою мовою програмування.
1965 року Ніклаус Вірт і Тоні Гоар запропонували комітету з розвитку мови ALGOL свою версію, яку згодом назвали ALGOL-W і застосовували для навчання в деяких університетах. Пропозиція була відхилена через незначну кількість змін на користь значно складнішого ALGOL 68. У ALGOL 68 з'явилися визначення структур даних і динамічні масиви. ALGOL 68 став першою мовою із формальною специфікацією, яка, однак, була складною для розуміння.
1971 року Вірт опублікував опис мови Pascal, яка у 1970-х стала загальновживаною для навчання студентів.
1972 року Деніс Річі розробив у Bell Labs мову C. Тоді ж у Марселі створено інтерпретатор мови Пролог — першої і найвідомішої мови логічного програмування. Алан Кей у Xerox PARC розробив першу широко вживану об'єктно-орієнтовану мову — Smalltalk.
1973 року Робін Мілнер в Единбурзькому університеті створив ML.
1975 року в Массачусетському технологічному інституті описано спрощений діалект мови Лісп — Scheme.
1976 року випущено мову для статистичного програмування S, на базі якої 1993 року створено R.
1977 року випущено Bourne shell і awk.
1975 року Міністерство оборони США утворило міжнародну групу для створення нової мови програмування для власних потреб, конкурс 1979 року виграла мова Ада.
1981 року випущено dBASE II.
1984 року з метою об'єднання різних діалектів Ліспу створено Common Lisp. Випущено MATLAB
1985 року Б'ярн Страуструп опублікував реалізацію мови C++.
1986 року опубліковано мову Objective-C і створено Erlang. Тоді ж Borland і Apple незалежно створили об'єктно-орієнтоване розширення мови Pascal — Object Pascal.
1987 року створено Perl.
1990 року опубліковано Standard ML і Haskell.
1991 року створено Visual Basic і опубліковано Python.
1992 року випущено Oracle 7 з підтримкою PL/SQL
1993 року створено Lua.
1995 року Sun Microsystems випустила Java, Netscape — JavaScript, тоді ж створено PHP і Ruby.
1996 року створено OCaml.
2001 року створено C#.
2002 року створено F#.
2003 року створено Scala.
2009 року створено Go.
2010 року створено Kotlin.
2010 року була офіційно представлена мова програмування Rust на Mozilla Summit 2010[9]. Роботу над мовою Грейдон Гоар розпочав ще 2006 року.
2012 року створено Elm.
2012 року створено Elixir.
2014 року на конференції розробників WWDC 2014 було представлено мову Swift.
2014 року презентовано перший офіційний реліз мови програмування Crystal[10].
Синтаксис мови програмування визначає те, як буде виглядати програма цією мовою, зокрема, як пишуться оператори, оголошення й інші мовні конструкції[11]. Наприклад, оголошення масиву V з десяти елементів у форматі цілих чисел у мові С буде виглядати так:
int V[10];
На мові Pascal:
V: array[0..9] of integer;
Термін семантика стосується значення мови, на відміну від її форми (синтаксису). Наприклад, термін «семантика оператора» означає дію, яку виконує оператор під час виконання програми. Таким чином, семантика мови програмування — це сукупність семантик окремих елементів, дозволених синтаксисом мови.
Статична семантика описує обмеження на структуру текстів мови які важко або неможливо виразити звичайними структурними формалізмами[5]. Для компільованих мов, статична семантика, по суті, це правила які можуть бути перевіреними на етапі компіляції. Наприклад перевірка того що кожен ідентифікатор задекларований до того як використовується (в мовах які потребують таких декларацій) або що варіанти в операторі switch різні[12]. Багато важливих обмежень цього типу, такі як перевірка використання ідентифікатора в правильному контексті (наприклад заборона додавання чисел до функцій), або що виклики підпрограма мають правильну кількість і типи аргументів можуть бути забезпеченні визначенням їх як правил логіки яка називається системою типізації. Інші форми статичного аналізу, такі як аналіз потоку даних[en] також можуть бути частиною статичної семантики. Такі мови програмування як Java та С# мають як частину своєї статичної семантики definite assignment analysis[en] — форму аналізу потоку даних.
Коли дані описані, комп'ютер має отримати інструкції щось робити з даними. Наприклад, семантика може описувати стратегії обчислення за якими отримуються значення виразів, або спосіб яким інструкції визначають потік керування. Динамічна семантика мови (також відома як семантика виконання, англ. execution semantics) визначає як і коли різні конструкції мови повинні задавати поведінку програми. Існує багато способів задання семантики виконання. Для опису семантики виконання мов, які часто застосовуються на практиці, використовується природна мова. Велика частина досліджень мов програмування стосується формальної семантики мов програмування.
Область зберігання даних в апаратній частині комп'ютера (пам'ять, регістри та зовнішні запам'ятовувальні пристрої) зазвичай мають доволі просту структуру в вигляді послідовності бітів, згрупованих в байти або слова. Проте в віртуальному комп'ютері, як правило, організовано складнішим чином — в різні моменти виконання програми використовуються такі форми зберігання даних, як стеки, масиви, числа, символьні рядки та інші. Один або декілька однотипних елементів даних, об'єднаних в одне ціле в віртуальному комп'ютері в певний момент виконання програми, заведено називати об'єктом даних. При виконанні програми існує багато об'єктів даних різних типів. Тип даних — це деякий клас об'єктів даних разом з набором операцій для створення і роботи з ним[13]. В кожній мові програмування є певний набір вбудованих примітивних типів даних. Додатково в мові можуть бути передбачені засоби, що дозволяють програмісту визначати нові типи даних.
Мови класифікують за такими критеріями[джерело?]:
Імперативні мови ґрунтуються на ідеї змінної, значення якої змінюється присвоєнням. Вони називаються імперативними (лат. imperative — наказовий), оскільки складаються із послідовностей команд, які звичайно містять присвоєння змінних <code><назва_змінної> = <[[вираз]]></code>, де вираз може посилатися на значення змінних присвоєних попередніми командами.
Мови програмування можуть бути реалізовані як компільовані та інтерпретовані.
Програма компільованою мовою за допомогою компілятора (особливої програми) (компілюється) в машинний код (набір інструкцій) для даного типу процесора, що записується у об'єктний модуль. З одного або кількох об'єктних файлів компонувальник формує виконуваний файл, який може бути запущений на виконання як окрема програма. Іншими словами, компілятор переводить вихідний текст програми з мови програмування високого рівня в двійкові коди інструкцій процесора.
Якщо програма написана скриптовою мовою, то інтерпретатор безпосередньо виконує (інтерпретує) вихідний текст без попереднього перекладу. При цьому програма залишається мовою оригіналу і не може бути запущена без інтерпретатора. Процесор комп'ютера, у зв'язку з цим, можна назвати інтерпретатором для машинного коду.
Поділ на компільовані і інтерпретовані мови є умовним. Так, для будь-якої традиційно компіляційної мови, як, наприклад, Паскаль, можна написати інтерпретатор. Крім того, більшість сучасних «чистих» інтерпретаторів не виконують конструкції мови безпосередньо, а компілюють їх в деяке високорівневе проміжне представлення (наприклад, з розіменуванням змінних і розкриттям макросів).
Для будь-якої інтерпретувальної мови можна створити компілятор — наприклад, мова Лісп, початково інтерпретована, може компілюватися без обмежень. Створюваний під час виконання програми код може так само динамічно компілюватися під час виконання.
Як правило, скомпільовані програми виконуються швидше і не вимагають для виконання додаткових програм, оскільки вже переведені на машинну мову. Разом з тим, при кожній зміні тексту програми потрібно її перекомпіляція, що уповільнює процес розробки. Крім того, скомпільована програма може виконуватися тільки на тому ж типі комп'ютерів і, як правило, під тією ж операційною системою, на яку був розрахований компілятор. Щоб створити виконуваний файл для машини іншого типу, потрібна нова компіляція.
Інтерпретовані мови володіють деякими специфічними додатковими можливостями (див. вище), крім того, програми на них можна запускати відразу ж після зміни, що полегшує розробку. Програма скриптовою мовою може бути найчастіше запущена на різних типах машин та операційних систем без додаткових зусиль.
Однак інтерпретовані програми виконуються помітно повільніше, ніж компільовані, крім того, вони не можуть виконуватися без програми-інтерпретатора.
Деякі мови, наприклад, Java та C#, перебувають між компільованими і інтерпретованими. А саме, програма компілюється не в машинну мову, а в машинно-незалежний код низького рівня, байт-код. Далі байт-код виконується віртуальною машиною. Для виконання байт-коду зазвичай використовується інтерпретація, хоча окремі його частини для прискорення роботи програми можуть бути трансльовані в машинний код безпосередньо під час виконання програми за технологією компіляції «на льоту» (Just-in-time compilation, JIT). Для Java байт-код виконується віртуальною машиною Java (Java Virtual Machine, JVM), для C# — Common Language Runtime.
Подібний підхід у деякому сенсі дозволяє використовувати плюси як інтерпретаторів, так і компіляторів. Слід згадати, що є мови, які мають і інтерпретатор, і компілятор (Форт (Forth)).
Підпрограми діляться на процедури та функції: Синтаксично процедури та функції складаються з заголовка (що містить ключове слово procedure
або function
, ім'ям, за яким може слідувати опис передаваних параметрів в дужках, тип повертаного значення через символ двокрапки для функцій і крапки з комою для процедур), після заголовка слідує 'тіло', після якого ставиться символ ;
.
program mine(output);
var i : integer;
procedure print(var j: integer);
function next(k: integer): integer;
begin
next := k + 1
end;
begin
writeln('Всього: ', j);
j := next(j)
end;
begin
i := 1;
while i <= 10 do
print(i)
end.
Тіло процедури, як і програми, своєю чергою може містити описи процедур і функцій. Таким чином, процедури і функції можуть бути вкладені один в одного як завгодно глибоко, при цьому тіло програми — саме верхнє в ланцюжку.
Причому вміст секцій опису змінних, типів, констант, зовнішнього тіла (процедури, функції, програми), розташованих перед описом процедури/функції, доступні усередині неї. Також, в більшості діалектів з процедури можна звертатися до параметрів зовнішньої процедури.
Услід за заголовком процедур/функцій замість тіла може поміщатися ключове слово forward
, це робиться в тому випадку, якщо опис процедури/функції розташовується в програмі після її виклику, і пов'язано з підтримуваною в Паскалі можливістю компіляції програми за один прохід.
Процедури відрізняються від функцій тим, що функції повертають якесь значення, а процедури — ні.
Об'єктно-орієнтоване програмування (ООП) — це технологія створення складного програмного забезпечення, яке засноване на представленні програми у вигляді сукупності об'єктів, кожен з яких є екземпляром певного класу, а класи утворюють ієрархію зі спадкоємством властивостей.
Основна перевага ООП — це значне спрощення процесів створення та модифікації програмних систем. Набагато легше маніпулювати 100 об'єктами, кожен з яких сам відповідає за свою поведінку і обробку даних пов'язаних з ним, ніж тисячами функцій розкиданих по різних модулях.
Основні недоліки в ООП — це деяке зниження швидкодії через складнішу організацію програмної системи, а також, як правило, помітне збільшення об'єму бінарного коду (особливо при використанні стандартних бібліотек класів в невеликих програмах) через те, що більшість сучасних компіляторів і компонувальників не здатні виявити і видалити весь код, що доводиться на невживані класи, віртуальні методи і інші елементи ООП.
Існує кілька підходів до визначення семантики мов програмування.
Найбільш широко поширені наступні три різновиди семантик: операційна, дериваційна (аксіоматична) і денотаційна (математична)[джерело?].
Перші комп'ютери доводилось програмувати двійковими машинними кодами. Проте програмувати таким чином — доволі трудомістке і важке завдання[14]. Для спрощення цього завдання почали з'являтися мови програмування низького рівня, які дозволяли задавати машинні команди в зрозумілішому для людини вигляді. Для перетворення їх у двійковий код були створені спеціальні програми — асемблери.
Прикладом мови низького рівня є мова асемблера. Мови низького рівня орієнтовані на конкретний тип процесора і враховують його особливості, тому для перенесення програми на асемблері на іншу апаратну платформу її потрібно майже цілком переписати. Певні відмінності є і в синтаксисі програм під різні компілятори. Щоправда, центральні процесори для комп'ютерів фірм AMD та Intel практично сумісні й відрізняються лише деякими специфічними командами. А ось спеціалізовані процесори для інших пристроїв, наприклад, відеокарт, телефонів містять суттєві відмінності.
За допомогою мов низького рівня створюють ефективні й компактні програми, оскільки розробник отримує доступ до всіх можливостей процесора.
Мови низького рівня, як правило, використовують для написання невеликих системних програм, драйверів пристроїв, модулів стиків з нестандартним обладнанням, програмування спеціалізованих мікропроцесорів, коли найважливішими вимогами є компактність, швидкодія і можливість прямого доступу до апаратних ресурсів.
Транслятори[16] поділяються на:
Можна сказати є зрозумілішими людині, ніж комп'ютеру. Особливості конкретних комп'ютерних архітектур в них не враховуються, тому створені програми легко переносяться з комп'ютера на комп'ютер. Здебільшого достатньо просто перекомпілювати програму під певну комп'ютерну архітектурну та операційну систему. Розробляти програми на таких мовах значно простіше і помилок допускається менше. Значно скорочується час розробки програми, що особливо важливо при роботі над великими програмними проєктами.
Наразі у середовищі розробників вважається, що мови програмування, які мають прямий доступ до пам'яті та регістрів або мають асемблерні вставки, потрібно вважати мовами програмування з низьким рівнем абстракції. Тому більшість мов, які вважалися мовами високого рівня до 2000-го року зараз вже такими не вважаються.
Недоліком мов високого рівня є більший розмір програм у порівнянні з програмами мовою низького рівня. Сам текст програм мовою високого рівня менший, проте, якщо взяти у байтах, то код початково писаний на асемблері буде компактніший. Тому в основному мови високого рівня використовуються для розробок програмного забезпечення комп'ютерів, і пристроїв, які мають великий обсяг пам'яті. А різні підвиди асемблеру застосовуються для програмування інших пристроїв, де критичним є розмір програми.
Інколи в літературі та в інтернеті згадують про п'ять поколінь мов програмування[17][18][19][20], щоправда, даний поділ є спірним і суперечним. В професійній літературі з програмування доволі рідко згадують про покоління мов програмування, а більше зосереджуються на функціональній класифікації мов програмування. Крім того, саме віднесення певних мов до різних поколінь різниться у різних авторів.
Поділ на покоління мов програмування почав поширюватись з появою високорівневих мов програмування і до того не застосовувався. Високорівневі мови програмування почали вважатися третім поколінням, асемблерні мови — другим, а машинний код — першим поколінням. Сучасні спроби класифікація мов на четверте і п'яте покоління проводяться різними авторами по різному по різних ознаках і різниця між мовами третього, четвертого та п'ятого покоління часто доволі нечітка. Крім того, багато компаній розробники мов програмування та середовищ програмування для них використовують маркетинговий хід проголошуючи певну мову (мову та інтегроване середовище розробки для неї) п'ятим поколінням.
Seamless Wikipedia browsing. On steroids.
Every time you click a link to Wikipedia, Wiktionary or Wikiquote in your browser's search results, it will show the modern Wikiwand interface.
Wikiwand extension is a five stars, simple, with minimum permission required to keep your browsing private, safe and transparent.