Програмски језици

Језик представља скуп правила за комуникацију. Помоћу језика представљају се и преносе информације. Природни језик се користи за комуникацију између људи у говорној или писаној форми.

Програмски језик служи за комуникацију између програмера и рачунара. Програмер уноси текст (програмски кôд) у рачунар на програмском језику, са циљем да рачунар изврши инструкције задате у том тексту.

Програмски језик се може дефинисати као скуп речи и правила за писање рачунарских програма који описују послове које треба да обави рачунар.

Књижевна или слична ауторска дела написана у неком од природних језика обично се објављују у штампаном или електронском формату. Нека од њих се преводе и на друге природне језике, али увек остају непромењена, односно верна оригиналу.

С друге стране, оригинална верзија програмског кода у одређеном програмском језику, након објављивања, засигурно ће се у будућности мењати у циљу исправљања грешака (багова) или унапређивања функционалности. У тренутку писања програма, програмеру су сигурно јасне инструкције у програму које је написао. Међутим, ако програм није написан јасно и читљиво, чланови тима са којима програмер ради имаће потешкоћа да га разумеју. Чак се ни сâм аутор програмер, након одређеног времена и рада на другим пројектима, неће снаћи са сопственим нејасним и нечитким програмским кодом. Зато је важно да програме пишеш јасно и читљиво.

Поделе програмских језика

До данас је креирано више хиљада програмских језика, али нису сви једнако важни и заступљени.

Поред важности и заступљености, програмски језици могу се поделити на много начина и у много категорија у зависности од критеријума на основу којих се врши подела.

Подела према степену блискости са архитектуром процесора

Из предмета Рачунарство и информатика научио си да је централна процесорска јединица (енгл. Central Processing Unit - CPU), скраћено процесор, електронска компонента која извршава инструкције програма и изводи операције над подацима. Према типу инструкција које извршавају, процесори се могу грубо поделити на процесоре имплементиране у RISC (енгл. Reduced Instruction Set Computer) технологији и процесоре имплементиране у CISC технологији (енгл. Complex Instruction Set Computer). На пример, у свом мобилном телефону или таблету вероватно имаш ARM процесор у RISC технологији, док у свом лаптоп или десктоп рачунару вероватно имаш x86/x64 процесор у CISC технологији.

Тако се, према степену блискости са архитектуром процесора, програмски језици деле на језике ниског нивоа (машински и асемблерски) и језике високог нивоа (C, C++, C#, Java…). Језици ниског нивоа подразумевају блискост са одређеном процесорском архитектуром, док се језици високог нивоа, захваљујући компајлерима, могу користити на рачунарима са различитим архитектурама процесора.

То значи да ће асемблерски програм написан за процесор у CISC технологији бити неупотребљив за процесор у RISC технологији и обрнуто. Врло је вероватно и да ће асемблерски програм написан за процесор у одређеној технологији одређене генерације бити неупотребљив за процесор исте технологије много новије или много старије генерације. С друге стране, програм написан у програмском језику високог нивоа може да буде функционалан за процесор било које технологије и било које генерације.

Машински програм извршава се директно у процесору, где процесор тумачи машинске кодове, и овакви програми су потпуно неразумљиви човеку. Асемблерски програми састоје се из наредби којима се више или мање придружују машинске наредбе. Наредбе асемблерских програма пишу се у виду мнемоничких скраћеница речи на енглеском језику. Наредбе програмских језика високог нивоа су блиске енглеском језику и структуриране су тако да одговарају начину размишљања програмера.

Почнимо са језицима високог нивоа и једноставним примером који у конзоли треба да испише текст Hello, World!. У програмском језику C тај програм изгледао би овако:

#include <stdio.h>

int main(void)
{
    printf("Hello, World!");
    return 0;
}

Чак и ако не знаш ништа о програмирању и програмским језицима, а знаш енглески језик, можеш да претпоставиш да се на почетку програма нешто укључује (include), па нешто штампа (print) и на крају нешто враћа (return). У програмском језику C++ програм са истом функционалношћу изгледао би овако:

#include <iostream>

int main(void)
{
    std::cout << "Hello, World!";
    return 0;
}

односно, у програмском језику C# овако:

using System;

namespace HelloWorld
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Console.Write("Hello, World!");
        }
    }
}

Најједноставнија би била варијанта у програмском језику Python који си учио у основној школи:

print("Hello, World!")

С друге стране, исти програм у знатно комплекснијем асемблерском језику за испис текста Hello, World! у конзоли изгледа овако:

printf      proto
includelib  msvcrt.lib
includelib  legacy_stdio_definitions.lib

.data
        msg db 'Hello, World!', 0

.code
main    proc
        sub rsp, 40h
        mov rcx, offset msg
        call printf
        add rsp, 40h
        ret
main    endp
        end

Овај програм је функционалан само ако се користи Microsoft асемблер на 64-битној верзији оперативног система Windows на рачунарима са Intel или AMD 64-битним процесорима у CISC технологији. Уколико се користи неки други асемблер на другом оперативном систему, или се користи рачунар са другом архитектуром процесора, програм неће бити функционалан. Исти програм у програмском језику C је функционалан са било којим C компајлером на било ком оперативном систему са било каквом хардверском архитектуром.

Машински језик је неразумљив чак и искусним програмерима. Значење делова машинског кода обично могу да „препознају” програмери који су се баш за то специјализовали. Део машинског програма у хексадекадном запису за испис текста Hello, World! у конзоли изгледа овако:

00: 4d 5a 90 00 03 00 00 00 04 00 00 00 ff ff 00 00
01: b8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00
02: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
03: 00 00 00 00 00 00 00 00 00 00 00 00 f8 00 00 00
04: 0e 1f ba 0e 00 b4 09 cd 21 b8 01 4c cd 21 54 68
05: 69 73 20 70 72 6f 67 72 61 6d 20 63 61 6e 6e 6f
06: 74 20 62 65 20 72 75 6e 20 69 6e 20 44 4f 53 20
07: 6d 6f 64 65 2e 0d 0d 0a 24 00 00 00 00 00 00 00
08: af c0 6f c1 eb a1 01 92 eb a1 01 92 eb a1 01 92
09: 54 dd 00 93 e8 a1 01 92 54 dd 04 93 f3 a1 01 92
0A: 54 dd 05 93 e0 a1 01 92 54 dd 02 93 e8 a1 01 92
0B: ff ca 00 93 ef a1 01 92 eb a1 00 92 ac a1 01 92
0C: 32 dc 05 93 ea a1 01 92 32 dc fe 92 ea a1 01 92
0D: 32 dc 03 93 ea a1 01 92 52 69 63 68 eb a1 01 92
0E: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0F: 00 00 00 00 00 00 00 00 50 45 00 00 64 86 0a 00
10: c3 e8 42 64 00 00 00 00 00 00 00 00 f0 00 22 00

Цео програм био би предугачак за приказ на овом месту.

У одређеној литератури прочитаћеш да је ово подела програмских језика према генерацијама. Тако, машински језик се сматра програмским језиком прве генерације, асемблерски језик програмским језиком друге генерације, а програмски језици високог нивоа (Fortran, Pascal, C и др.) програмским језицима треће генерације. Генерацијска класификација језика на високом нивоу, од треће генерације на даље, никада није била у потпуности прецизирана, а касније је и напуштена.

Подела на компајлере и интерпретере

Програмски језици могу се поделити на компајлерске и интерпретерске. Код компајлерских језика, помоћу компајлера врши се превођење изворног у извршни програм, који се касније може независно извршавати. Код интерпретерских језика, помоћу интерпретера врши се превођење сваке линије програма пре њеног извршења, а програм се не може извршавати независно без постојања интерпретера.

Програмски језици засновани на компајлерима су C, C++, C#, Java и др. Програмски језици засновани на интерпретерима су Python, Ruby, Perl и др.

Подела према начину програмирања

Према начину програмирања, програмски језици могу се сврстати у основне програмске парадигме. Програмска парадигма може да означава: програмски стил, начин/стил програмирања и класификацију међусобно сличних програмских језика.

Програмске парадигме изучавају се како би се боље упознала својства програмских језика који им припадају. Програмске парадигме могу се поделити на:

  • императивне парадигме и

  • декларативне парадигме.

Императивне парадигме подразумевају програмске језике у којима се користе искази/наредбе који мењају стање програма, где се експлицитно задаје начин на који се долази до решења. Основне императивне парадигме су:

  • процедуралне парадигме (програмски језици C, Pascal, Fortran) и

  • објектно-оријентисане парадигме (програмски језици C++, C^#, Java).

Декларативне парадигме подразумевају програмске језике у којима се више изражава логика него искази/наредбе. У њима се прецизно описује проблем који се решава, а сам механизам програмског језика задужен је за проналажење решења. Основне декларативне парадигме су:

  • функционалне парадигме (програмски језици Haskell, F#) и

  • логичке парадигме (програмски језици Prolog и његови деривати).

У савременим програмским језицима увек је помешано више програмских парадигми (енгл. multi-paradigm). На пример, програмски језик C++ јесте објектно-оријентисан, али се може сврстати и у групу процедуралних и у групу функционалних језика. Данас постоји око сто категорија и поткатегорија програмских парадигми.

Шта нису програмски језици

Језици за описивање/структурирање текста нису програмски језици јер се помоћу њих не пишу програми које треба да изврши рачунар. Примери оваквих језика су: HTML, CSS, XML, SGML, JSON и др.