<div class="page">
<div class="cover text-center">
<img class="mx-auto" src=/itb/images/logo_mislata.png alt="logo">
# Llenguatges de programació
<div class="text-end fit-content ms-auto my-3 mt-auto pt-3">
<p><strong>Autor:</strong> Joan Puigcerver Ibáñez</p>
<p><strong>Correu electrònic:</strong> j.puigcerveribanez@edu.gva.es</p>
<p><strong>Curs:</strong> 2024/2025</p>
</div>
<div>
<p>Aquest material és una obra derivada a partir del material de: <strong>Sergio Badal</strong></p>
<p class="fw-bold mb-0">Llicència: BY-NC-SA</p>
<p class="d-none d-md-block">(Reconeixement - No Comercial - Compartir Igual)</p>
<a href="https://creativecommons.org/licenses/by-nc-sa/4.0/deed.ca" target="_blank">
<img class="mx-auto" src="/itb/images/license.png" alt="Licence"/>
</a>
</div><!--license-->
</div><!--cover-->
</div><!--page-->
{:toc}
## Conceptes bàsics
### Informàtica, binari, digital i software
La paraula __informàtica__ ve d'"informació" i "automàtica". La informació és un conjunt de dades,
i automàtic és que funciona per si mateix. D'aquesta manera, la informàtica és la ciència que estudia
el tractament de la informàció d'una mitjançant un sistemà automàtic, com pot ser un ordinador.
La informàtica permet automatitzar el processament de la informació. Tota la informació que utilitza un
"ordinador" ha d'estar representada en una seqüència de zeros i uns (dígits) anomenada __codi binari__.
Això significa que cada unitat bàsica d'informació pot tenir dos estats (0, 1). A aquesta unitat se'l coneix
com a __bit__ o _binary digit_ (b) i al conjunt de huit bits s'anomena __byte__ (B). Un byte pot representar $2^8$
caràcters, és a dir, 256 possibilitats diferents ([Taula ASCII](https://ca.wikipedia.org/wiki/ASCII)).
Quan un dispositiu qualsevol utilitza o emmagatzema informació en forma de bits diem que aquest dispositiu és digital.
Quan el mecanisme que utilitza no és mitjançant aquest codi, com un rellotge clàssic o un termòmetre de mercuri, diem que és analògic.
El __programari (software)__ és la part intangible d'un sistema informàtic, equivalent a
l'equipament lògic. Tot programari està dissenyat per fer una tasca determinada al nostre sistema.
Dins d'aquest programari podem distingir dos tipus diferents.
D'una banda, tenim les __aplicacions__, programari instal·lat sobre el sistema operatiu
amb la funcio de realitzar una tasca en concret (editar document, reproduir música,...)
Per una banda, tenim el __sistema operatiu__, un programari amb la funció de proporcionar una plataforma única
per l'ús de la màquina, independentment del __maquinari (hardware)__ que està present. El sistema operatiu
és l'encarregat de comunicar-se amb el maquinari.
### Programar vs Desenvolupar programari
Es pot definir __programar__ com especificar les ordres (__instruccions__) i dades a un ordinador (__dispositiu__)
que aquest executarà per rebre una sèrie de resultats o provacar un cert comportament.
> És important fer servir la paraula "dispositiu", ja que hui en dia podem programar des d'un
ordinador fins a una nevera, passant per unes sabatilles esportives o, per què no, fins i tot
una catifa si aquests utilitzen informació digital. Cada vegada més elements de la nostra vida
quotidiana accepten ordres en forma de comandes, línies de codi o programes, dins del
que es coneix com a __Internet de les Coses__ (Internet of Things o __IoT__).
En canvi, __desenvolupar software__ va més enllà que programar. És tot el procés d'analitzar,
dissenyar, provar, documentar i mantindre el programari, què és molt major al mateix temps que es dedica
a exclusivament a _escriure línies de codi_.
 {.center}
## Llenguatges de programació
### Segons el nivell d'abstració
Els éssers humans ens comuniquem mitjançant __llenguatges naturals__ que s'han anat originant i han
anat evolucionant mitjançant segles. Aquests llenguatges són molt complexos,
amb molts matisos i ambigüetats. Fins i tot, quan nosaltres ens comuniquem,
podem arribar a malentesos o confondre'ns per culpa del llenguatge.
Per contra, si volem donar instruccions a una màquina, necessitem fer-ho d'una manera
que siga clara, consissa i que sols tinga una única interpretació. Arran d'aquesta necessitat,
s'han creat els __llenguatges de programació__.
El llenguatge de programació més bàsic, però a la vegada més difícil d'utilitzar,
i d'entendre és el __llenguatge màquina__. Aquest llenguatge és un sistema
de còdigs que són directament interpretables per un processador concret que realitzen
diferents operacions (suma, resta, moure dades d'un registre a un altre...).
Aquests codis que el processador entén estan en binari i, per tant, són difícils
d'utilitzar per a els éssers humans. Per facilitar aquesta tasca, existeix el
__llenguatge de baix nivell o assamblador__, que és una relació entre els diferents
còdigs del llenguatge màquina i paraules o valors fàcilment recordables (ADD en compte de 0110).
No obstant això, són igualment difícils d'utilitzar.
 {.center}
Perquè la tasca de desenvolupar codi siga més amigable, fàcil i flexible, s'han anat
creant diferents __llenguatges de programació d'alt nivell__, cadascun amb diferents
característiques, funcionalitats i propòsits. Aquests llenguatges s'assemblen més
al llenguatge natural, però són clars i no permeten ambigüetats. A més, també
tenen una alta abstracció respecte al maquinari de la plataforma on es dessitgen executar.
 {.center}
### Segons el tipus d'execució
Hem comentat que els desenvolupadors prefereixen utilitzar llenguatges d'alt nivell
per desenvolupar programari, però, en canvi, els dispositius sols entenen el
llenguatge màquina dissenyat per a aquest. Per poder executar el codi
desenvolupat mitjançant llenguatges d'alt nivell, cal traduir-lo abans a llenguatge
que el dispositiu siga capaç d'entendre.
Segons com es faça aquesta traducció, podem classificar els llenguatges de programació
en dos tipus:
- __Llenguatges interpretats__: El codi font va traduint-se instrucció per instrucció
a mesura que s'executa el codi. El __intèrpret__ tradueix cada instrucció a llenguatge
màquina i aquest s'executa.
Alguns exemples de llenguatges interpretats són: Python, Ruby, PHP (llenguatges de programació
de scripting i servidors web), JavaScript (client web), Bash, PowerShell (scripting)
o altres com Perl, MATLAB o Mathematica.
- __Llenguatges compilats__: és aquell el codi font del qual, escrit en un llenguatge d'alt nivell,
és traduït per un __compilador__ a un arxiu __executable__ comprensible per a la màquina en determinada
plataforma. Aquest executable pot executar el programa tantes vegades com siga necessari
sense haver de repetir el procés.
Alguns exemples de llenguatges compilats son: C, C++, Objective C, Rust, Pascal, Haskell o VisualBasic.
##### Interpretats vs Compilats
| | Interpretats | Compilats |
| :- | :- | :- |
| Temps execució | Son més lents perquè han de traduir mentre executen el codi | En ser traduïts d'avant mà, són més ràpids en executar-se |
| Detecció errors de sintaxi | Sols poden trobar errors en el codi que s'executa | Poden trobar errors de sintaxi en tot el codi |
| Optimització | No poden aplicar optimitzacions | Poden aplicar optimitzacions en el codi |
| Portabilitat | Es pot executar sempre que hi haja un intèrpret | L'executable sols pot ser executat en l'arquitectura compilada |
| Temps desenvolupament | És més ràpid de provar, no cal compilar-lo sencer | És més lent de provar, ja que cal compilar-lo sencer per poder executar-lo (\*) |
> \(*): Molts llenguatges de programació compilats disposen de intèrprets per agilitzar el procés
de desenvolupament i prova.
##### Llenguatges intermedis o bytecode
Alguns llenguatges de programació més moderns han combinat els dos maneres de traducció
per intentar aprofitar al màxim els avantatges de cada mètode. El __llenguatge intermedi o bytecode__
és un llenguatge més abstracte respecte al màquinari que el codi màquina, però que
ha generat un fitxer __binari__ mitjançant el procés de compilació d'un llenguatge d'alt nivell.
El bytecode és executat en el dispositiu mitjançant un intèrpret.
Els avantatges d'aquests mètodes són:
- El bytecode ha segut compilat, per tant, s'han pogut produir optimitzacions i s'han
trobat errors de sintaxi.
- El bytecode és un arxiu executable i, per tant, no cal recompilar-lo cada vegada.
- El bytecode és portable i no depén de cap arquitectura.
Exemples d'aquest tipus de llenguatge són: Java, Kotlin (compatible amb Java), C#,...
##### Java
Un exemple d'utilització de llenguatges intermedis és __Java__. El procés d'execució
d'un codi font Java és el següent:
 {.center}
- __Codi font__: Conté el programa a executar en llenguatge __Java__ (alt nivell). S'utilitza l'extensió __.java__.
- __Compilador__: Es compila el codi font a bytecode amb el compilador de Java, que s'instal·la mitjançant
el __Java Development Kit (JDK)__.
- __Bytecode__: Conté el programa en llenguatge intermedi en binari. S'utilitza l'extensió __.class__.
- __JVM__: La __Java Virtual Machine__ interpreta el bytecode i el tradueix a llenguatge màquina,
entès pel nostre sistema operatiu. La __JVM__ s'instal·la mitjançant el __Java Runtime Enviorment (JRE)__ (ve inclòs en el JDK).
__Codi font:__

__Compilar:__

__Executar:__

### Segons el paradigma
Els llenguatges de programació també poden ser classificats segons el seu paradigma, és a dir,
la seua manera de treballar i com estan estructurats.
- __Paradigma imperatiu__: Els llenguatges imperatius es basen a conèixer l'estat de la màquina
i modificar-lo mitjançant instruccions. Es diuen imperatius perquè fem servir ordres per dir al dispositiu
què ha de fer i com fer-ho. La majoria d'arquitectures d'ordinadors segueixen una filosofia imperativa,
per tant, la traducció d'un llenguatge imperatiu a codi màquina és més senzilla que la dels llenguatges declaratius.
- Quasi tots els llenguatges són imperatius: C, Java, Python, Javascript, PHP,...
- Dins d'aquesta categoria estan:
- __Llenguatges estructurats__: Que sols permèten tres estructures: Sequència, selecció i iteració.
Això fa innecessari l'ús de salts (_go to_) i es consideren una mala pràctica, ja que empitjoren
la llegibilitat i el manteniment del codi. No obstant això, se segueixen utilitzant salts com el
_break_ en alguns casos.
- Exemples: Fortan, Algol, Cobol, Basic, Pascal, C, Ada,...
- __Llenguatges orientats a objectes__: És una estratègia de construcció de programes basada en una abstracció
del món real. Els objectes són combinació de dades (_atributs_) i mètodes que ens permeten interactuar amb ell.
Aquest paradigma es basa en: abstracció, encapsulació, modularitat, jerarquia i polimorfisme.
- Exemples: Java, C++, Python, C#,...
- __Paradigma declaratiu__: Els llenguatges declaratius fixen un objectiu però no el camí per arribar-hi. S'indica
quin valor es dessitja obtindre i el dispositiu troba la solució seguint una lògica interna. Són llenguatges més
propers a les matemàtiques.
- Exemples: SQL, Prolog, LISP,...
### Com triar llenguatge de programació?
Resoldre aquesta pregunta ens podria portar dies sencers divagant entre tots els possibles paradigmes
i tipus de llenguatges i arribaríem a la conclusió de: __DEPÈN__.
Cada llenguatge de programació té unes característiques determinades que el fan més o menys apropiat
per al context on el faces servir, podent ser determinants aquests factors:
1. El sector productiu al qual va adreçada la teva aplicació: Medicina, acadèmic, videojocs, data mining,...
- Existeixen llibreries que et faciliten la tasca?
2. El tipus de dispositiu on s'executarà: mòbils, escriptori, IoT, web,...
3. El sistema operatiu sobre la qual s'executarà: Linux, Windows, Android, Ios,...