Mantieni un linguaggio di programmazione retrocompatibile e correggerne i difetti


56

Innanzitutto, alcuni contesti (cose che la maggior parte di voi conosce comunque):

Ogni linguaggio di programmazione popolare ha una chiara evoluzione, il più delle volte segnato dalla sua versione: hai Java 5, 6, 7 ecc., PHP 5.1, 5.2, 5.3 ecc. Il rilascio di una nuova versione rende disponibili nuove API, corregge bug, aggiunge nuove funzionalità, nuovi framework ecc. Quindi, tutto sommato: va bene.

Ma che dire dei problemi della lingua (o della piattaforma)? Se e quando c'è qualcosa che non va in una lingua, gli sviluppatori o la evitano (se possono) o imparano a conviverci.

Ora, gli sviluppatori di queste lingue ricevono molti feedback dai programmatori che li usano. Quindi ha senso che, con il passare del tempo (e dei numeri di versione), i problemi in quelle lingue andranno via lentamente ma sicuramente. Beh, non proprio. Perché? Compatibilità all'indietro, ecco perché. Ma perché è così? Leggi di seguito per una situazione più concreta.


Il modo migliore in cui posso spiegare la mia domanda è usare PHP come esempio:

PHP è amato e odiato da migliaia di persone. Tutte le lingue hanno dei difetti, ma a quanto pare PHP è speciale. Dai un'occhiata a questo post sul blog . Ha un lungo elenco di cosiddetti difetti in PHP. Ora, non sono uno sviluppatore di PHP (non ancora), ma ho letto tutto e sono sicuro che un grosso pezzo di quella lista sono davvero problemi reali. (Non tutto, dal momento che è potenzialmente soggettivo).

Ora, se fossi uno dei ragazzi che sviluppano attivamente PHP, vorrei sicuramente risolvere questi problemi, uno per uno. Tuttavia, se lo faccio, il codice che si basa su un comportamento particolare della lingua si interromperà se viene eseguito sulla nuova versione. Riassumendo in 2 parole: retrocompatibilità.

Quello che non capisco è: perché dovrei mantenere PHP retrocompatibile? Se rilascerò PHP versione 8 con tutti questi problemi risolti, non posso semplicemente mettere un grande avvertimento dicendo: "Non eseguire il vecchio codice su questa versione!"?

C'è una cosa chiamata deprecazione. Lo abbiamo da anni e funziona. Nel contesto di PHP: guarda come in questi giorni le persone scoraggiano attivamente l'uso delle mysql_*funzioni (e invece raccomandano mysqli_*e DOP). La deprecazione funziona. Possiamo usarlo. Dovremmo usarlo. Se funziona per le funzioni, perché non dovrebbe funzionare per intere lingue?

Diciamo che io (lo sviluppatore di PHP) faccio questo:

  • Lancia una nuova versione di PHP (diciamo 8) con tutti quei difetti corretti
  • I nuovi progetti inizieranno a utilizzare quella versione, poiché è molto meglio, più chiaro, più sicuro, ecc.
  • Tuttavia, al fine di non abbandonare le versioni precedenti di PHP, continuo a rilasciare aggiornamenti, correggere problemi di sicurezza, bug ecc. Questo ha senso per motivi che non sto elencando qui. È pratica comune: guarda ad esempio come Oracle ha continuato ad aggiornare la versione 5.1.x di MySQL, anche se si è concentrata principalmente sulla versione 5.5.x.
  • Dopo circa 3 o 4 anni, smetto di aggiornare le vecchie versioni di PHP e le lascio morire. Questo va bene, dato che in quei 3 o 4 anni, la maggior parte dei progetti sarà comunque passata a PHP 8.

La mia domanda è: hanno senso tutti questi passaggi? Sarebbe così difficile da fare? Se può essere fatto, perché non lo è?

Sì, il rovescio della medaglia è che rompi la compatibilità all'indietro. Ma non è un prezzo che vale la pena pagare? Come vantaggio, in 3 o 4 anni avrai una lingua che ha il 90% dei suoi problemi risolti .... una lingua molto più piacevole con cui lavorare. Il suo nome garantirà la sua popolarità.

EDIT : OK, quindi non mi sono espresso correttamente quando ho detto che in 3 o 4 anni le persone passeranno all'ipotetico PHP 8. Quello che intendevo dire era: in 3 o 4 anni, le persone useranno PHP 8 se iniziano un nuovo progetto.


31
PHP è un cattivo esempio per questa particolare domanda, perché il più delle volte non puoi scegliere la versione con cui lavorerai. La maggior parte dei siti PHP sono distribuiti su server condivisi e il proprietario del server sceglie la versione, non tu. Un sacco di cose vengono riparate con ogni nuova versione (è mysql_*stata deprecata in 5.5, per esempio), ma questo è irrilevante se la maggior parte dei provider di hosting là fuori ha una o due versioni precedenti (5.3 è - purtroppo - ancora ciò che la maggior parte di offerte dei fornitori).
yannis,

5
... Penso anche che tu sottovaluti la quantità di codice che dovrebbe essere trasferito, la quantità di cose che si rompono, la quantità di dipendenze di terze parti da adattare, ecc.
Dagnelies

12
Questo fantastico post sul blog joelonsoftware.com/items/2008/03/17.html di Joel Spolsky su "Cuffie marziane" dovrebbe essere obbligatorio per ogni sviluppatore che sottovaluta l'importanza della compatibilità con le versioni precedenti.
Doc Brown,

3
Inoltre, PHP ha lentamente deprecato la funzionalità con ogni singola versione e di conseguenza un sacco di cose si interrompe. Sfortunatamente, PHP è bloccato in un punto difficile in cui ha difficoltà a produrre avvisi di deprecazione in un modo che gli sviluppatori vedranno che non finirà per interrompere i siti comunque.
soffice

20
python 2.x => python 3.x è un cambiamento sostanziale da un linguaggio ben progettato a un altro, un linguaggio leggermente meglio progettato, che ha il supporto di prima parte per cambiare automaticamente molti costrutti incompatibili. Il trasferimento del codice tra di loro è più semplice di quanto si possa fare per cambiare tra due lingue. Py3k sta ancora guadagnando terreno molto lentamente.
Phoshi,

Risposte:


25

Suona bene, ma raramente funziona in pratica; le persone sono estremamente riluttanti a cambiare il codice in esecuzione e anche per i nuovi progetti green-field sono molto riluttanti a passare da una lingua / versione che già conoscono.

La modifica del codice esistente in esecuzione che "funziona correttamente" non è qualcosa che si colloca in alto nell'elenco di priorità di qualsiasi progetto. Invece di impegnarsi per cose che i manager pensavano fossero già state pagate, solo per essere in grado di passare a una versione più recente di una lingua o piattaforma, decreteranno che gli sviluppatori dovrebbero semplicemente rimanere sulla vecchia versione "per ora". Puoi provare ad attirare i tuoi utenti con grandi funzionalità disponibili solo nella nuova versione, ma è una scommessa in cui rischi di ridurre la tua base di utenti senza ottenere un chiaro guadagno per la lingua; le funzioni moderne e interessanti non possono essere facilmente valutate rispetto al prezzo di una base di installazione frammentata secondo l'opinione pubblica e si corre il rischio di ottenere la reputazione di "tapis roulant di aggiornamento"

(Ovviamente, la maggior parte di questo non si applica ai progetti scritti da hobbisti solo per il loro piacere. Tuttavia (qui si tratta di esca di fiamma ...) PHP è scelto sproporzionalmente raramente dagli hacker perché è un tale piacere scrivere in primo luogo. )


65

Stai sottovalutando l'impatto della retrocompatibilità; la tua stima che tutti i progetti attivi migrerebbero in 3 o 4 anni è troppo ottimista.

Supponiamo che io sia uno sviluppatore di PHP. PHP ha dei difetti, ma so come ovviare a questi difetti - questo è uno dei motivi per cui vengo pagato come sviluppatore di PHP. Supponiamo ora che PHP 8 esca e risolva quei difetti, ma non è compatibile con le versioni precedenti. Di conseguenza:

  • Devo dedicare tempo ad aggiornare il mio codice per PHP 8. Questo è il tempo che potrei impiegare per rispondere alle richieste dei clienti, implementare nuove funzionalità, tenere il passo con la concorrenza.
  • Anche dopo averlo fatto , c'è una buona probabilità che mi sia perso qualche caso angolare o un problema di compatibilità imprevisto, introducendo bug nel mio codice.

Detto questo, c'è un forte incentivo a non migrare mai su PHP 8, anche se è "migliore, più chiaro, più sicuro ecc." Si stima che ci siano ancora miliardi di linee di COBOL (!) - anche se ovviamente ci sono tecnologie molto migliori disponibili, il costo di un aggiornamento, combinato con il rischio di bug, non ne vale la pena.

In secondo luogo, anche se decido di migrare il mio codice, qualsiasi app non banale dipende dalle librerie di terze parti e non vi è alcuna garanzia che le librerie di terze parti migreranno. Ad esempio, Python 3 è stato rilasciato nel dicembre 2008, ma Django (probabilmente il principale framework Web Python) non ha avuto supporto stabile e pronto per la produzione Python 3 per quasi cinque anni (vedi qui e qui ).


8
C'è un numero sorprendentemente elevato di posizioni COBOL aperte, in particolare con le compagnie assicurative più anziane Oo
Chad Harrison

1
@Josh Kelley: sono d'accordo con te, ma penso che questi problemi riguardino solo le lingue in cui non puoi separare chiaramente il codice legacy dal nuovo codice, ad esempio Python, PHP perché devi includere librerie e C ++ (template). Le lingue con un modello di compilazione diverso (ad esempio Java, Scala, Clojure) mostrano che è possibile aggiungere un nuovo codice (ad esempio in Clojure) al codice legacy (ad esempio in Java) anche se le due lingue non sono compatibili a livello di codice sorgente.
Giorgio,

2
Non so se dovrei pubblicare questo come domanda separata o come commento. Ma perché non potrebbero creare un linguaggio di programmazione che eleva la migrazione del codice a un concetto di prima classe? In Java, c'è un'annotazione @Deprecated che ti dà solo un avvertimento. Forse un'altra lingua potrebbe effettivamente fornire una macro che sostituisce il vecchio codice con il nuovo codice corretto. Se stai utilizzando l'ultima versione, è un errore chiamare il codice obsoleto, ma il vecchio codice viene convertito per utilizzare un nuovo codice non deprecato. Spitballin '
Daniel Kaplan,

7
@tieTYT - Alcuni linguaggi di programmazione lo fanno - vedi il 2to3 di Python o il gofix di Go ( talks.golang.org/2012/splash.slide#68 ). Sicuramente aiuta a deprecare le vecchie funzionalità, ma ci sono limiti alla capacità del software di comprendere e aggiornare altri software quando cambia la semantica della lingua.
Josh Kelley,

3
@hydroparadise Mia zia lavora come sviluppatore con banche e compagnie assicurative e in questi giorni di crisi alcuni clienti della sua compagnia hanno deciso di tornare a COBOL perché il software costa meno! Quindi anche l'economia può influire sulla velocità con cui le aziende passano a nuove lingue / versioni.
Bakuriu,

17

Stai facendo molte ipotesi sul comportamento umano. Se lo cambi troppo, le persone valuteranno i tuoi concorrenti, dal momento che dovranno comunque impegnarsi in modo significativo per cambiare. Per le lingue open source, le persone berranno semplicemente la vecchia versione.

Guarda python per un esempio. 3.x è disponibile da quattro anni e non è ancora ampiamente adottato. Le persone cercano di usarlo per progetti nuovi di zecca, ma penso che tu stia sottovalutando quanto lavoro di codice è la manutenzione.

Naturalmente, la maggior parte delle persone non ha considerato Python 2.x "imperfetto". Non avevano lamentele come utenti php. Php si trova in una posizione molto più precaria, perché molte persone restano fedeli solo a causa della sua ampia base di codice esistente. Se perdessi la compatibilità con le versioni precedenti, molte persone avrebbero l'opportunità di passare a Python.


Penso che tu abbia un buon punto qui (+1). Penso che la retrocompatibilità sia un falso problema, specialmente per i linguaggi compilati in cui è possibile utilizzare una compilazione separata (vedere come integrare Scala e Clojure con Java o C # con C ++). Ma mantenere la sensazione che la nuova lingua, dopo tutto, sia solo una versione aggiornata di quella precedente è molto importante per evitare un fork o che le persone migrano semplicemente in un'altra lingua. Penso che questi motivi siano molto più forti del trattare con il codice legacy.
Giorgio

1
@Giorgio Falso problema? Dillo a tutti gli scrittori di biblioteche che devono supportare più versioni di una lingua contemporaneamente.
svick,

@svick: con una compilation separata non è necessario supportare versioni diverse di una lingua. Vedi ad esempio come Scala può usare le librerie Java che non sono compilate per Scala.
Giorgio

9

Per qualsiasi lingua diversa da PHP direi, sì, ha assolutamente senso! Questo è esattamente ciò che Python sta facendo con il passaggio a Python 3.

Tuttavia, il problema con PHP è che ci sono troppi difetti nella progettazione del linguaggio stesso, quindi quello che stai chiamando "PHP 8" sarebbe un linguaggio completamente diverso. E se dovessi passare a un'altra lingua, perché dovresti rimanere con il nuovo PHP, piuttosto che con una delle alternative attualmente esistenti e stabili?

Anche la community di PHP è estremamente lenta nell'adattare qualcosa di nuovo. Guarda quanto tempo ci è voluto per sbarazzarsi di register_globals. È noto per essere un rischio per la sicurezza dal 2000. È stato rimosso solo 12 anni dopo. Un altro esempio, quando è stato introdotto PHP5, è stato un enorme miglioramento rispetto a PHP4, ma la community non lo ha adattato. Ho impiegato 4 anni e azioni enormi come GoPHP5 per dare il via all'adozione. E anche questo non ha avuto un numero significativo di modifiche incompatibili all'indietro.


5

Disclaimer: gestisco un gruppo di utenti ColdFusion.

ColdFusion soffre degli stessi problemi: amato da molti, disprezzato da molti. Inoltre, tonnellate e tonnellate di FUD basate su versioni pre-Java. ColdFusion 10 è uscito l'anno scorso, è un grande venditore e la scorsa settimana mi sono registrato per testare la pre-release della versione 11. Inoltre, ci sono due principali alternative open source, una è supportata da JBoss.

Ci sono tonnellate di nuove funzioni in CF10 che mi piacerebbe implementare, ma la migrazione da CF 7 o 8 può essere difficile a seconda delle dimensioni della tua base di codice, del numero di progetti imminenti e delle risorse che devi regredire testare tutto una volta che sei sull'ultima versione. Ho riscontrato una serie di differenze sintattiche minori tra 8 e 9, nonché casi limite in cui il codice non viene compilato allo stesso modo. Una volta trovato, li ho documentati nei nostri standard di codifica in modo che non vengano utilizzati in progetti futuri o da nuovi sviluppatori.

Detto questo, se ColdFusion 11 (o qualsiasi linguaggio di programmazione) dovesse deprecare completamente determinate funzioni e sintassi, il livello di sforzo per trovare e sostituire la funzionalità potrebbe essere enorme. Lo sforzo di test potrebbe essere gigantesco. Le aziende pagheranno i loro sviluppatori, QA e project manager per trovare, sostituire e testare tutte quelle cose deprecate? Dubbioso.

Se l'ultima versione di una lingua è retrocompatibile, ma introduce un aumento delle prestazioni senza modifiche al codice (CF9 è circa il 30% più veloce di CF8 e CF10 è molto più veloce di CF9), a chi importa cambiare le chiamate di funzione se funzionano ancora?

Come azienda, dobbiamo preoccuparci di soddisfare i nostri clienti e soddisfare le loro esigenze al fine di fatturare i servizi, costruire il business e reclutare più clienti.

FWIW, mi piacerebbe portarci sull'ultima versione di jQuery ad un certo punto, ma dal momento che alcune funzioni sono state deprecate alcune versioni dopo quello che usiamo e dato il volume di JavaScript che abbiamo nel sistema, non so come lo faremo.


4

C'è un compromesso qui; alcuni bug DEVONO davvero essere corretti, ma alcune cose non possono essere modificate senza rompere il codice di qualcuno da qualche parte. Mi sembra di ricordare che qualcuno ha affermato come "regola" che ogni correzione di bug interromperà il progetto di qualcuno, non importa quanto oscuro o ovviamente rotto il bug, qualcuno lo userà per qualcosa. Tale è la natura dei programmatori.

Questa è (a mio avviso) la differenza tra versioni principali, versioni secondarie e revisioni. Come principio generale:

  • Si presume che le versioni principali contengano modifiche non significative.
  • Le versioni minori possono cambiare leggermente il comportamento.
  • Le revisioni dovrebbero essere praticamente compatibili tra loro.

Ad esempio, se sto scrivendo qualcosa in v2.3 di una lingua, non mi aspetto di notare alcuna differenza se eseguo l'aggiornamento a v2.3.2. Se aggiorno alla v2.4, alcune cose potrebbero cambiare: piccole modifiche alla sintassi, alcune funzioni si comportano in modo leggermente diverso, quindi devo modificare la logica, ecc. Se aggiorno alla v3.0, non sarei sorpreso se si rompesse interamente - funzioni deprecate o mancanti, operazioni non supportate o modificate così tanto che non riesco a rimetterle in riga, in realtà devo riscrivere alcune funzioni per tenere conto delle nuove modifiche.

Modificare:

L'articolo di Steve Vance Advanced SCM Branching Strategies dice questo:

In genere, ci sono due o tre livelli di rilascio, denominati da numeri collegati con punti (ad es. 1.2.3). [...] In questa struttura il primo numero è associato a una versione principale, indicando che ha caratteristiche e miglioramenti funzionali significativi rispetto al precedente; potrebbero esserci anche incompatibilità significative che richiedono la migrazione. Il secondo numero rappresenta una versione minore, che contiene miglioramenti delle caratteristiche e delle funzioni minori, un numero significativo di correzioni di errori e nessuna incompatibilità. Il terzo numero si riferisce a un livello di patch, indicando quasi esclusivamente una raccolta di correzioni di bug; non sono consentiti miglioramenti di caratteristiche o funzioni e incompatibilità tra i livelli di patch.

L'unica modifica che farei a questo è il suddetto principio secondo cui i programmatori spesso trovano il modo di "usare" i bug, quindi una versione minore con "un numero significativo di correzioni di bug e nessuna incompatibilità" potrebbe essere difficile, perché è probabile che quelli i bug romperanno qualcosa che li ha usati o causeranno inutili soluzioni alternative e inizieranno a causare problemi.


Mi aspetto 2.3-> 2.4 per aggiungere funzionalità, ma non rimuoverlo.
Donal Fellows il

1
Per coincidenza, di recente mi sono imbattuto in una citazione pertinente. È un po 'lungo per un commento, quindi modificherò la mia risposta.
anaximander,

2

Dipende davvero da quale sia il target della lingua - quali tipi di applicazioni sono progettati per essere creati dalla lingua.

Ad esempio, ignorando Android, Java viene utilizzato principalmente in grandi sistemi aziendali e middleware; questi tipi di applicazioni tendono a diventare molto grandi sia nelle dimensioni che nel tempo. Questo ha alcune implicazioni; immaginare un sistema con 500K + LoC su cui lavoratore 50+ ingegneri in fase di sviluppo. In genere questo tipo di sistema entra in manutenzione dopo questo con 10 sviluppatori; ora se la lingua cambia e le modifiche non sono compatibili all'indietro, il progetto non può essere facilmente migrato a una nuova versione perché i programmatori che hanno scritto alcune parti sono spariti e nessuno vuole toccarlo. Questo è il problema più piccolo, il problema più grande consiste nel fatto che è un po 'costoso adattare un'applicazione 500 LoC a nuovi vincoli linguistici. Ad esempio se i generici non sono stati implementati con la cancellazione del tipo eList list = new List(); non compilerebbe milioni di righe di codice che dovrebbero essere riscritte - il che è ad un costo elevato.

D'altra parte PHP tende ad essere usato sul web per applicazioni più semplici; di solito è sviluppato da un singolo programmatore o da una piccola squadra. L'idea è che gli sviluppatori sappiano abbastanza bene che l'intero progetto può integrare più facilmente i cambiamenti di lingua. Inoltre, lo scopo è quello di costruire un sito molto velocemente e tanto più veloce tanto meglio, quindi se una nuova funzionalità linguistica può farlo meglio, allora viene implementata anche con alcuni costi di compatibilità all'indietro.


1

Si può sostenere che Microsoft abbia apportato una modifica simile con ASP.NET (come successore di ASP classico) o con VB.NET (sebbene abbiano fatto così tante concessioni con quest'ultima che la maggior parte dei vantaggi del "riavvio" del linguaggio sono andati persi).

Ad ogni modo, se qualcuno ricorda l'incubo della migrazione del codice VB6 su VB.NET anche con l'assistenza di uno strumento di migrazione, si accorderanno subito sul fatto che gli strumenti di migrazione della lingua non funzionano molto bene per i principali aggiornamenti della lingua.

Potrebbe essere possibile spostare la piattaforma in avanti, ma è comunque necessario fornire supporto per le API "obsolete" attraverso almeno alcune revisioni.


1

Molte delle "imperfezioni" di cui le persone urlano nei linguaggi di programmazione popolari non lo sono, sono cose che il giocattolo preferito dell'urlatore del giorno ha che manca a quel linguaggio, QUINDI che il linguaggio è fondamentalmente imperfetto perché manca.
Il prossimo clamore arriva, la lingua improvvisamente è imperfetta perché non aderisce a quel clamore.

La mancanza di chiusure in Java è un classico esempio. Questo non è affatto un difetto nella lingua e cambiare la lingua (come è purtroppo all'ordine del giorno) per includerli IMO lo paralizzerà fondamentalmente o almeno renderà molto più difficile da leggere e comprendere.

Ciò che troppe persone perdono di vista è che ogni lingua ha i suoi punti di forza e di debolezza e che cercare di creare qualcosa che combini i punti di forza di tutto, evitando ogni debolezza, creerà solo un mostro assolutamente inutilizzabile che è bravo a nulla, incredibilmente ingombrante, impossibile da utilizzare in modo efficace.

Aggiungi, come altri hanno sottolineato, che la compatibilità con le versioni precedenti è fondamentale per mantenere gli utenti esistenti, molti dei quali NON spenderanno le migliaia di ore e milioni di dollari / euro per adeguare i loro milioni di basi di codice a qualsiasi cosa tu pensi sia "migliore" rispetto alla versione del linguaggio che usano da anni, e hai una miriade di ottimi argomenti da lasciare abbastanza bene da solo e se vuoi giocare con qualche nuova idea overhyped che è presumibilmente il prossimo "java killer" tu ' Farebbe meglio a giocare con quel giocattolo piuttosto che urlare che "Java iz ded" a meno che non venga "riparato" per essere un clone di quel giocattolo.


1

Suggerirei che le versioni più recenti di una lingua dovrebbero sforzarsi di garantire che il 99,99999% del codice che viene compilato sia nella vecchia che nella nuova versione funzioni in modo identico in entrambi, a meno che non sia deliberatamente progettato per non farlo, e che la maggior parte delle volte quando la nuova versione rifiuta il codice compilato con la versione precedente, sarà perché il codice era, nella migliore delle ipotesi, ingannevole e avrebbe dovuto essere scritto in un modo diverso che si sarebbe compilato sia nel vecchio che nel nuovo compilatore.

Ad esempio, se progettassi un nuovo linguaggio simile a Java o C #, proibirei conversioni di tipo implicite in alcuni contesti in cui tali lingue lo consentono. Come semplice esempio in C #, dato

int someInt;
double someDouble;

l'espressione someInt.Equals(someDouble)è garantita per restituire false, indipendentemente dal contenuto delle variabili. Si compila perché doublepuò essere convertito in Objecte intha un Equalssovraccarico per quel tipo, quindi il compilatore esegue la conversione ed effettua la chiamata. Se stessi progettando una nuova versione di C # e .NET Framework, avrei vietato la conversione del pugilato poiché non poteva assolutamente fare nulla di utile. È possibile che ci sia qualche programma che faccia un simile confronto in un modo che è inutile ma innocuo, e che il compilatore rifiuti tale codice potrebbe interrompere quel programma, ma correggere o rimuovere tale codice inutile sarebbe un miglioramento.

Come esempio leggermente meno chiaro, supponiamo

float f=16777216f;
int i=16777217;

e considera l'espressione f==i. E 'possibile che un certo codice fa paragoni galleggiante / interi e funziona correttamente, ma il codice deve essere riscritto come sia f==(float)i, (double)f==i;o (double)f==(double)i;[ intper doublela promozione è senza perdita di dati, in modo da questi ultimi due sarebbe equivalente]. Alcuni codice che confronta direttamente floate integervalori possono sempre fare i conti con i numeri che sono sufficientemente piccole che floate doubleconfronti sarebbero comportati in modo identico, ma un compilatore in genere non può sapere che; Il codice dovrebbe chiarire che tipo di confronto è necessario, piuttosto che sperare che le regole della lingua corrispondano alle intenzioni del programmatore.


1

È meglio non rompere mai la compatibilità all'indietro.

Microsoft ha sostituito il linguaggio di programmazione VB6 con un nuovo linguaggio che ha completamente rotto la compatibilità. Quindi anche oggi il 16enne VB6 è ancora più popolare della versione dotNet (indice Tiobe agosto 2014). E Gartner stima che siano ancora in uso 14 miliardi di righe di codice VB6.

Nel 2014 Microsoft ha dovuto nuovamente annunciare che non aggiornerà o open source VB6 nonostante le richieste della comunità di programmazione di Visual Basic. Ma hanno esteso il supporto di VB6 fino al 'almeno' 2024, e funziona benissimo su Windows 7 e 8. Saranno oltre 26 anni di supporto per la stessa versione di VB6.

Perché i software di lavoro esistenti dovrebbero essere riscritti, anche Microsoft non ha mai "aggiornato" Office per usare dotNet?


questo non sembra offrire nulla di sostanziale rispetto alle precedenti 14 risposte
moscerino del

1

Esistono alcuni problemi diversi con la rottura della compatibilità all'indietro. Alcuni dei problemi derivano dal fatto che la maggior parte dei linguaggi di programmazione sono anche piattaforme (interpreti / runtime), altri problemi derivano da un'ipotesi della natura umana.

R. Il codice scritto in versioni precedenti non trarrebbe vantaggio dalle nuove versioni che migliorano le prestazioni, la sicurezza o le funzionalità. È possibile mitigare questo problema supportando più versioni principali del compilatore / interprete, ma si tratta di un enorme consumo di risorse (ovvero è costoso o richiede molto tempo ed è una seccatura).

B. Il codice scritto per le versioni più recenti potrebbe non essere compatibile con il codice scritto nelle versioni precedenti. Potresti aggirare questo problema avendo un interprete / compilatore in grado di gestire più versioni principali del linguaggio, ma questo è più una seccatura nel culo che il supporto di interpreti / compilatori separati (la soluzione alternativa per A).

C. Cambiamenti importanti, se si verificano troppo spesso / rapidamente rendono anche la lingua più difficile da usare, poiché hai più da imparare e da non imparare. Le modifiche a una lingua potrebbero spingere le persone oltre il limite per passare a una nuova lingua o potrebbero far sì che le persone continuino a utilizzare versioni obsolete della lingua e non passino mai alla nuova versione (come è successo con Python). Inoltre, le modifiche possono anche attrarre nuovi utenti ed eccitare quelli vecchi.

D. È necessario conservare e mantenere una nuova documentazione. È sempre un'esperienza piuttosto confusa cercare cose su Google e scoprire che stai leggendo i documenti per una versione diversa da quella attualmente in uso.

In generale, se si crea un linguaggio di programmazione in cui i moduli esterni non devono preoccuparsi della versione in uso, interrompere la compatibilità all'indietro per i motivi giusti (per correggere i principali difetti del linguaggio) è quasi sicuramente la cosa giusta da fare . È probabile che la ragione principale per cui ciò non viene fatto è che i progettisti del linguaggio di programmazione sopravvalutano ( per contraddire la risposta di qualcun altro ) i costi della violazione della compatibilità, soprattutto nelle fasi iniziali. Il fatto è che i problemi di violazione della compatibilità possono essere aggirati o potenziati dagli utenti di quella lingua. E questo non vale solo per i linguaggi di programmazione; questo vale per le API, le interfacce utente - in realtà qualsiasi interfaccia in qualsiasi situazione.

Facebook infastidisce le persone quando cambia l'interfaccia utente o le API degli sviluppatori. In passato, ha reso la piattaforma difficile da lavorare. In alcuni casi, le API hanno semplicemente smesso di funzionare all'improvviso. Ma la gente continuava a usarlo, e ora le API e le UI sono molto più avanti rispetto a 5 anni fa. Le persone si lamenteranno del cambiamento, che sia positivo o negativo per loro, ma che (lamentarsi) non è una buona ragione per rinunciare a quel cambiamento. Sfortunatamente, gli sviluppatori del linguaggio di programmazione usano questo come motivo per mantenere intatti i problemi del loro linguaggio.

Quindi un altro paio di ragioni per cui le lingue non stanno apportando modifiche sostanziali per migliorare se stesse sono:

E. Gli sviluppatori di lingue pensano che i loro utenti temano il cambiamento sia una buona ragione per ristagnare la loro lingua

F. Agli sviluppatori di lingue piaceva il loro linguaggio quando lo hanno realizzato e probabilmente pensano che vada bene con i suoi difetti.

G. Le lingue che invecchiano di solito cessano di avere un piccolo nucleo di sviluppatori e si trasformano in altre bestie create dal comitato. Ciò significa che le decisioni su tali lingue sono lente e spesso conservatrici e non creative.

H. L'ultimo motivo è che alcune modifiche sostanziali richiedono una significativa rivalutazione delle decisioni di progettazione prese per l'interprete / runtime. A volte i miglioramenti della lingua richiedono semplicemente troppo lavoro per essere fattibile. Immagino che questo sia un problema più raro di molti altri.

Spesso i progettisti di linguaggi non sono necessariamente progettisti di utensili, quindi non pensano a buone soluzioni a questo problema o non li eseguono bene. Ecco alcune soluzioni che mi vengono in mente per risolvere il problema dei cambiamenti di rottura:

  1. Deprecare le cose molto prima di quando verranno rimosse.

  2. Fornire un buon strumento di conversione standard. Python ha fornito lo strumento 2to3, ma non era ben pubblicizzato, non era standard con python 3 come ricordo, e non funzionava nemmeno molto bene (ricordo di aver dovuto passare manualmente attraverso i programmi generati da 2to3 per risolvere i problemi. non risolto). Questo strumento di conversione potrebbe anche essere eseguito automaticamente se il compilatore / interprete rileva una versione precedente. Cosa potrebbe essere più facile?


Il problema con l'analogia di Facebook è che non è in uso un lascito di Facebook. Non c'è scelta. O usi la versione corrente di Facebook o non usi affatto Facebook. Nel frattempo, ci sono ancora tonnellate di persone che usano Python 2sette anni dopo il rilascio Python 3perché esiste ancora - se non lo facesse, si lamenterebbero, ma avrebbero portato Python 3.
Kevin,

Non penso che sia un problema con l'analogia, quello era in realtà il mio punto. Facebook ha scelto il percorso di "correzione dei difetti" e ha per lo più evitato il percorso di "compatibilità con le versioni precedenti". Ecco perché non hanno una versione legacy della loro API. È un esempio perfetto di un estremo.
BT,

La rottura della retrocompatibilità con i linguaggi di programmazione porterà solo le persone a continuare a utilizzare e / o a modificare la versione precedente. La vecchia versione di Facebook non esiste più; Suppongo che potresti creare un clone che supporti la vecchia API, ma nessuno la userebbe, perché Facebook è un marchio con una vasta base di utenti.
Kevin,

Facebook ha il vantaggio che, quando si aggiorna, le versioni precedenti essenzialmente non esistono più. I linguaggi di programmazione non sono così, e questa è una differenza rilevante: puoi usare una versione obsoleta di un linguaggio di programmazione, come Python 2, perché esiste ancora.
Kevin,

Vedo il tuo punto. Penso ancora che sia la sua estremità di due estremi. Se i difetti maggiori si manifestano in una versione non supportata di una lingua, potrebbe essere lungo le linee di quella versione che cessa di esistere, perché nessuno vorrà usarla.
BT,

0

Non so se questo sia un problema per il codice PHP, ma in molte lingue il codice legacy non viene mai aggiornato dopo anni o, a volte, persino decenni, perché funziona, è fondamentale per l'azienda che lo esegue ed è troppo grande (diciamo milioni di SLOC), quindi non avrebbe senso riscriverlo. Questo è un motivo per cui java ha reso la retrocompatibilità un problema quasi religioso, nonostante conosca vecchi problemi, specialmente nelle biblioteche (anche se sono più facili da aggiornare). Immagino che un sacco di codice dal kernel Linux non sia stato aggiornato per decenni, nonostante l'adozione di standard come C99 e C11.

Anche in lingue meno "imprenditoriali", la rottura di un vecchio codice funzionale può essere un problema. Questo è quello che è successo con Python 2 -> 3. Un sacco di librerie e script di sistema erano stabili e non mantenuti più, non perché erano abbandonati ma perché erano stabili e facevano il loro lavoro. Adattarli richiede alcuni anni. Quindi, come sviluppatore, non puoi necessariamente passare a Python 3 se la tua libreria preferita non ha ancora fatto la mossa, quindi il tuo codice non funzionerà nemmeno in Python 3, con conseguente frammentazione della comunità.


-1

Il problema risiede nel problema di compatibilità con le versioni precedenti. La maggior parte degli script PHP che eseguo sono in esecuzione su un server RedHat precedente. Se dovessi usare la versione più recente della lingua per gli script futuri, allora dovrei aggiornare PHP su questo server - e correre il rischio di avere i miei script più vecchi rotti / dover impiegare ore per riscrivere tutto il vecchio codice con il nuovo standard. Inoltre, tutti i miei sviluppatori sono abituati a reagire in un certo modo a PHP (indipendentemente dal fatto che sia "rotto" o meno). Se non reagisce più in questo modo, potrebbe essere un grosso ostacolo per la produttività, poiché gli sviluppatori potrebbero dover sostanzialmente insegnare nuovamente a se stessi PHP.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.