Newsgroup: it.comp.lang.c++
Titolo: Standard Template Library

Le STL sono state create per essere efficienti e di conseguenza sono 
meno user-friendly di quanto sarebbero potute esserlo.
Ne è valsa la pena? Forse, ma non capisco alcune scelte.
Per es. le STL mettono a disposizione funzioni generiche che possono 
funzionare con ogni contenitore, ma per efficienza, si raccomanda di 
preferire sempre le eventuali funzioni membro dei contenitori (quando 
presenti).
L'unico svantaggio è che in questo modo il codice non è più generico.
Sinceramente, mi sarei aspettato qualcosa di meglio. Il problema è che 
l'implementazione della libreria non è completamente distinta dalla sua 
interfaccia e quindi bisogna essere profondi conoscitori anche solo per 
usare qualche funzionalità.
Domanda: perché non si è scelto di (richiedere di) creare 
specializzazioni per le funzioni generiche?
Come si può cioè godere appieno della genericità con la costante paura 
d'incorrere in penalità legate all'efficienza o altro?
Ovviamente sono aperto a ragguagli e sono qui per discutere. Del resto 
sto ancora studiando, ma ho già visto cose che non mi piacciono affatto.
Kiuhnm


Diversi fattori concorrono alle scelte sulle quali obietti. Sarai
d'accordo che molti algoritmi si possono implementare piu'
efficacemente conoscendo la struttura dati alla quale vengono
applicati. Nel caso delle liste e' piu' efficente spostare i nodi che
non scambiare per copia gli elementi; la ricerca per chiave in una
mappa e' piu' efficace se effettuata attraversando l'albero
sottostante.
Le funzioni membro specifiche sono quindi inevitabili, a meno di non
utilizzare pensantemente il meccanismo di friendship. Tieni presente
pero' che l'"amicizia" tra template e' stata per diversi anni
problematica per molti compilatori.
Altro problema e' che non e' possibile specializzare parzialmente una
funzione, quindi implementare questi algoritmi ad hoc avrebbe richiesto
l'uso di classi funzionali, complicando notevolmente la libreria e
rischiando di incappare in limiti degli ottimizzatori.
Penso che quello che abbiamo oggi sia il risultato di un compromesso
tra eleganza, efficienza, effettiva implementabilita' coi compilatori
disponibili all'epoca, indisponibilita' a modificare pesantemente il
linguaggio per supportare meglio la libreria standard.
Tratto distintivo dei compromessi riusciti e' che non soddisfano
nessuno :-)
Ciao,
Nicola

 nessuno :-)
Il problema è che secondo me il compromesso non è riuscito tanto bene.
Costruttori e distruttori sono paradossalmente la fonte principale di 
inefficienza. E' inutile rendere efficiente solo una parte del C++ e 
chiudere un occhio sulle altre. Cosa succede se inserisci delle stringhe 
in un array? La versione NTL è nettamente più veloce di quella STL. Il 
vantaggio cresce esponenzialmente di mano mano che crei strutture più 
complesse.
Kiuhnm

 in un array?
Alla fine della fiera le strutture dati vanno definite in funzione di
quello che ci devi fare. Quelle della libreria standard sono piu' che
sufficienti nella maggioranza dei casi, dove non bastano non c'e' che
costruire strutture ad hoc.
Ciao,
Nicola

 Non mi e' chiaro cosa intendi.
http://www.ntllib.org/benchmark.html
Kiuhnm

 
http://www.ntllib.org/benchmark.html
Sei al corrente dell'attivita' in corso su move semantics, rvalue
references e argomenti correlati?
Ciao,
Nicola

Kiuhnm wrote:
Non c'entra nulla ma leggendo sto newsgroup la curiosità è grande.... 
kium ma come mai studi c++ cosi in profondità ?
Complimenti tra l'altro :) io lo uso per lavoro ma come tanti lo uso 
poco e spesso con la metodologia " a cazzo" purtroppo :)
ciao
Pier Paolo

 references e argomenti correlati?
No. Meglio aspettare allora :)
Kiuhnm

 poco e spesso con la metodologia " a cazzo" purtroppo :)
Il motivo principale è che la programmazione per me è hobby + lavoro. 
Tra qualche settimana però dirò stop a questo studio intensivo e 
inizierò a sfruttare quanto ho appreso, altrimenti tutto si riduce a 
puro fanatismo ;)
Kiuhnm


Nel frattempo:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1690.html
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1377.htm
Ciao,
Nicola

 Ne è valsa la pena? Forse, ma non capisco alcune scelte.
Ho cominciato a usare massicciamente la STL e i template solo da poco, 
quindi il mio punto di vista è limitato, ma da quando la uso mi pare di 
aver cambiato linguaggio di programmazione.
Forse il punto è questo: hanno inserito le STL nel C++, ma forse sarebbe 
stato meglio (più coerente, più efficiente, più semplice) se avessero 
creato "il linguaggio di programmazione STL" da zero.
Il fatto di separare tra loro in modo ortogonale gli algoritmi, i tipi 
primitivi e le strutture dati in modo da poter usare indifferentemente 
"tutto con tutto" è una grande idea, ma IMHO richiederebbe un maggior 
supporto nativo dal linguaggio: un concetto simile implica un nuovo 
paradigma di programmazione. Così come stanno le cose, STL e C++ mi 
paiono due oggetti incastrati fra loro a forza... boh.

 paiono due oggetti incastrati fra loro a forza... boh.
- Con le STL puoi fare praticamente tutto in quanto puoi combinare tra 
loro algoritmi, inserter, e altro.
- Allora posso fare anche questo?
- ...no, quello no perché internamente le STL sono implementate in 
questo modo quindi si può avere...
- Perché remove lascia gli elementi in fondo alla lista?
- Beh, perché l'algoritmo è generico e gli iteratori offrono 
un'interfaccia generica, ma limitata.
- Ma allora se scrivo codice generico rischio di scrivere codice 
inefficiente? Ma l'STL non nasce proprio per motivi di efficienza?
- No, basta che ti ricordi che:
     1) usa sempre le funzioni messe a disposizione dai contenitori 
stessi, quando disponibili;
     2) .....
     .
     .
     .
     999) .....
- Wow, quindi l'STL è marginalmente più efficiente delle altre se usata 
correttamente, cioè da un "guru", e non di poco meno efficiente se usata 
senza accortezza (cioè "intuitivamente").
- No, non è così, ci vuole solo un po' di esperienza. Il C++ non è 
linguaggio giocattolo come i linguaggi di oggi. In C++ devi sapere cosa 
fa una libreria e come lo fa per poterla usare efficientemente.
- Vabbe', sarà...
Kiuhnm

 fa una libreria e come lo fa per poterla usare efficientemente.
Ecco, queste frasi riflettono un atteggiamento che trovo profondamente 
sbagliato. I "linguaggi di oggi"? Garbage collection, lexical closures e 
altre cosettine "di oggi" nacquero con il LISP nel 1962, e qualcuna 
ancora prima. Se un linguaggio è facile allora è "un giocattolo"? Ma non 
è per facilitare la programmazione e renderla più semplice che si usano 
linguaggi ad alto livello?
Discorsi così mi ricordano i vecchi programmatori ASM anni 70, quando 
ancora i linguaggi macchina delle CPU contenevano istruzioni fatte 
apposta per gli umani che scrivevano in ASM... insomma "puzzano di 
dinosauro".
IMHO questo linguaggio è un pò prigioniero del "Mito del Vero 
Programmatore" per cui se una cosa non è difficile e non nasconde 
trucchi allora non vale la pena nè di farla nè di impararla. E' il 
motivo per cui non mi fido più di tanto di quello che si scrive sul C++...

 motivo per cui non mi fido più di tanto di quello che si scrive sul C++...
Non esagerare! Se usiamo il C++ un motivo ci sarà, no?
Quando ho dovuto cercare alternative valide, per quello che devo fare, 
ho trovato solo il linguaggio D (che per sfortuna è allo stadio larvale) 
e l'Eiffel (che per sfortuna è inguardabile!).
Se riesco a produrre un compilatore di Scheme che riesce a raggiungere 
il C++ (profiling più ottimizzazione mirata) su questo ng non mi vedete 
più :)
Si già cosa stai pensando, ma tentar non nuoce. Tanto l'interprete base 
devo realizzarlo comunque.
Kiuhnm

 digressione.
Figurati... io ho avuto una breve e illuminante esperienza con il 
Prolog, che mi ha mostrato un modo interamente nuovo di concepire la 
programmazione, e lo considero un modello di linguaggio estremamente 
interessante (un editor VI-style fatto con otto, diconsi OTTO sole 
istruzioni!!!). So che di recente è stato sviluppato Mercury, un 
linguaggio logico derivato più potente ed efficiente.
Più in generale sto vedendo che alcune caratteristiche del Lisp e del 
Prolog, come le due che ho nominato, cominciano a fare capolino anche 
nei linguaggi "mainstream", C++ compreso. Se tanto mi dà tanto, mi 
conviene andarmi a rivedere i vecchi appunti sulla ricorsione :-)

 conviene andarmi a rivedere i vecchi appunti sulla ricorsione :-)
Nella programmazione con i template (Boost, Loki) trovi tutto. I 
template sono considerati una forma di static duck-typing.
Kiuhnm

 devo realizzarlo comunque.
Per certe cose dovresti in realtà battere il C++ in efficienza. Pensa 
solo al vantaggio che in certi casi ti da un garbage collector. Per 
altre cose ... può essere più difficile.
E comunque stai puntando in alto. Non posso che farti i miei auguri (e 
complimenti).

 interessante 
Come ho detto spesso in passato e continuo a ripetere: conoscere i 4 
paradigmi principali è ciò che veramente ti fa fare un passo avanti.
Poi finirai con l'usare principalmente uno o due linguaggi. Ma se "sei 
passato" dallo studio, per esempio, di Pascal, Smaltalk, Lisp e Prolog 
(sostituzione libera di altri linguaggi equivalenti) puoi anche 
programmare in assembler: resterai un programmatore in grado di "vedere" 
le cose in maniera più "aperta".
Difficile da spiegare. Ma se giudichi "illuminante" l'esperienza con 
prolog, sai cosa intendo.

 complimenti).
Grazie.
Kiuhnm

 le cose in maniera più "aperta".
Concordo, pur con qualche riserva: dopotutto, l'OO è comunque 
imperativa, per cui non è un "vero" paradigma di programmazione.
Il lisp... mi fanno ORRORE le schiere infinite di parentesi di quel 
linguaggio!! O_O
C'è una alternativa con meno parentesi?

 linguaggio!! O_O
Questione di abitudine. Se un linguaggio è come lo vuoi tu, allora 
sicuramente non è lisp.
Fatti un grande favore e studiati "Structure and Interpretation of 
Computer Programs" (2a ed., by Abelson & Sussman). Fa riferimento al 
linguaggio Scheme che è un dialetto /veramente/ sintetico di Lisp. Lo 
standard di Scheme ha 50 pagine, mentre quello di Lisp (Common Lisp) 
1300. Fai un po tu...
Comunque il trucco sta nel non contare le parentesi, ma nel seguire 
l'indentazione e il quadro d'insieme.
Kiuhnm

 istruzioni!!!).
Sono curioso... Potresti indicare dove trovarlo e dove trovare qualche info?
Grazie,
Danilo

 Sono curioso... Potresti indicare dove trovarlo e dove trovare qualche info?
Ti passo il link al progetto Mercury, che è l'incarnazione più recente 
(e più efficiente) del Prolog.
http://www.cs.mu.oz.au/research/mercury/
Per il linguaggio (Prolog classico) puoi leggere questo tutorial:
http://cs.wwc.edu/KU/PR/Prolog.html
mentre questo è un tutorial su Mercury, che diversamente dal prolog 
specifica un pò di cose su come il programma è strutturato e su come 
funziona:
http://www.cs.mu.oz.au/research/mercury/tutorial/index.html

 i profiler. La parte da ottimizzare è spesso molto piccola.
Verissimo. Il codice deve nascere leggibile e manutenibile.
E poi diventare veloce se e solo se è necessario.
E "necessario" non è una cosa che il progrmmatore deve decidere, ma 
qualche cosa che deve MISURARE.

 funzione, .....
ti riferisci alle STL e non in generale...
Voglio dire questo si può fare (riferendomi all'esempio di kiuhnm) :
// funzione template.
template <class T, class U>
void f(T, U, int)
{
    std::cout << "f(T, U, int)" << std::endl;
}
// Specializzazione parziale.
template <class T, class U>
void f(T*, U*, int)
{
    std::cout << "f(T*, U*, int)" << std::endl;
}
Una specializzazione di una funzione template è tale
perchè davanti al nome della funzione ha "template<>" sbaglio ?
come si distingue una specializzazione da un overload ?
dal fatto che davanti al nome della funzione c'è template<> ?
ciao a tutti.
Nicola Musatti ha scritto:
