Важко відповісти на запитання на кшталт «є X Y », якщо учасники використовують дебати різних визначень X і Y . Можливо, для деяких визначень відповідь - «так», а для деяких визначень - «ні». Особливо, якщо відповідь залежить від технічних деталей, де різні визначення відрізняються. Також ця дискусія містить деяку дезінформацію, тому, будь ласка, потерпіть довшу відповідь.
Що ми маємо на увазі під « мовою програмування »?
Проста відповідь може бути "мовою, що використовується для створення програм". Звичайно, але: які програми? Що з мовою, яку можна використовувати для створення деяких видів програм, але не інших програм? Ось два конкретні приклади для ілюстрації крайніх випадків:
1) Уявна мова під назвою M працює так: Якщо програма містить одну букву "m", вона створює гру Міночистача. Все інше - синтаксична помилка.
Інтуїтивно це не те, що ми маємо на увазі під «мовою програмування». Але відділ маркетингу M може стверджувати, що технічно він відповідає визначенню, оскільки може бути використаний для створення програми. Звичайно, компілятор робить для вас критичні частини, але це те, що роблять компілятори, чи не так? Компілятор мови С також перекладає кілька простих слів у десятки інструкцій процесора. Компілятор M просто йде далі і робить вашу роботу ще простішою.
2) Якщо ви встановите оригінальну версію знаменитого Turbo Pascal, ви можете писати багато видів програм. Але ви не можете написати гру, яка працює у веб-браузері, оскільки потрібного API просто немає.
Отже, що саме є тим, що робить Turbo Pascal мовою програмування, а M не має? Простіше кажучи, ви можете зробити більше в Pascal, ніж у M. Але, уявіть, у нас є M.NET, який створює гру Minesweeper, що працює в веб-браузері. Отже, зараз у нас є щось, що може зробити Pascal, а M.NET не може, але ми також можемо зробити що, що M.NET може зробити, а Pascal не може. Чому слід вважати переваги Паскаля важливими, а переваги M.NET - неістотними?
Відповідь полягає в тому, що ви можете писати всі види алгоритмів на Pascal, але ви не можете писати алгоритми в M або M.NET. Звичайно, M компілює вашу команду "m", а C складає вашу команду "strcmp". Але ви можете поставити "strcmp" у більш широкому контексті, наприклад порівняти два файли по черзі, або прочитати тисячі рядків і сортувати їх за алфавітом, або ... ну, мільйони інших речей. І саме ця здатність використовувати задані команди в будь-якому алгоритмі складає суть мови програмування.
Що саме таке алгоритм, і що ще важливіше, що таке "будь-який алгоритм"? У інформатиці ми використовуємо слова Тьюрінга-завершені . Ідея полягає в тому, що існує набір комп'ютерних мов, де кожна з них здатна імітувати їх усіх. Однією з таких мов є машина Тюрінга, і тому їх називають так. Pascal є, C є, Java є, Python є, Lisp є, Smalltalk є, навіть XSLT є. Наш гіпотетичний M і M.NET є НЕ існує. Ви можете дізнатися про це більше в будь-якому університеті, який пропонує гідний курс інформатики, але ідея полягає в тому, що мова, якою володіє Тюрінг, може робити всещо може зробити інша мова Тюрінга, якщо ви надаєте їм мінімально необхідний API. (Якщо ви надаєте Pascal якийсь API для веб-браузера, ви можете створювати всі види ігор у веб-браузері. Якщо ви надаєте API веб-браузера M, ви все ще можете створити Мережу.) Ми можемо метафорично сказати, що якщо ви видалите всі API з мови програмування, важливим є те, що залишається.
Що ми маємо на увазі під " регулярними виразами "?
Різні мови програмування реалізують їх дещо по-різному. Але первісна ідея полягала в тому, що регулярні вирази виражають так звані регулярні мови . Зауважте, що ми говоримо не тут про мови програмування, а про (псевдо-) людські мови. Уявіть, що ви знайдете якесь екзотичне плем'я, яке розмовляє мовою, що складається лише зі слів «ба», «баба», «бабаба» тощо. Ви можете описати цю мову словесно як "склад" ba ", повторений один або кілька разів" або використовуючи регулярний вираз як "(ba) +".
Регулярні вирази повинні виражати: "нічого", "ця буква", "це, за цим", "те чи інше", "це, повторене один чи кілька разів", і "не це". - Це математичне визначення. Все інше - це лише зручний ярлик, побудований з попередніх компонентів. Наприклад, "це, повторне два-три рази" можна перекласти як "це, за ним слідує, за цим (це чи нічого)", але було б зручніше написати "ба {2,3}", ніж "баба (ба)? ".
У реальному житті типова реалізація "регулярних виразів" реалізує більше, ніж це. Наприклад, використовуючи математичне визначення, мова "аба", "аабаа", "ааабаа" і так далі - будь-яке число "а", за яким слідує "б", а за ним те саме число "а" "s - не є звичайною мовою. Однак багато "регулярних виразів", що використовуються сьогодні, могли його виявити, використовуючи додаткове поняття "те саме, що ми знайшли раніше", написане як "(a +) b \ 1". Використовуючи цю додаткову концепцію, ми можемо зробити кілька цікавих речей, наприклад виявити слова, що складаються з простої кількості літер. Проте ми не можемо виконати жодного алгоритму ... для пояснення чому,
Отже, повертаємось до початкової теми: чи регулярні вирази (визначені як: вирази, що описують регулярні мови в ієрархії Хомського, або як: колишня, плюс операція \ 1), мова програмування (визначена як: Turing-завершена)? Відповідь - ні . Ні, ви не можете реалізувати жоден алгоритм, використовуючи регулярні вирази, а можливість реалізації будь-якого алгоритму - це те, що люди, які вивчають інформатику, зазвичай розуміють як суть мови програмування.
Звичайно, кожен може змінити відповідь, наполягаючи на іншому визначенні . Як я писав на початку, тут важливі технічні деталі. Якщо ви їх неправильно отримаєте, ви отримаєте неправильну відповідь.
І якщо вас не цікавлять технічні деталі, відповідь може бути: Чи можете ви використовувати регулярні вирази (і більше нічого) для створення програми? Ні. То чому б це називати мовою програмування? (Однак така відповідь була завантажена і видалена тут, саме тому я написав цю довшу версію.)
EDIT: Також кожен може створити бібліотеку, реалізуючи свій власний новий варіант "регулярних виразів" з деякими додатковими новими можливостями. В якийсь момент нових функцій може бути достатньо для того, щоб вся система набула статусу Тьюрінга. Тривіальним прикладом може бути вбудовування мови Тюрінга, використовуючи новий синтаксис; але це теж може статися менш очевидно. Можливо, це вже сталося.