Anni fa, ma anche anni dopo la fondazione di Lokad, mi sono reso conto che nessuna singola app avrebbe mai potuto offrire qualcosa di simile all’eccellenza per quanto riguarda l’ottimizzazione della supply chain. Abbiamo fatto del nostro meglio, ma non è stato sufficiente. Non importa quanti funzionalità abbiamo inserito nelle prime versioni di Lokad, ogni nuovo cliente sembrava disperatamente diverso da tutti quelli precedenti che eravamo riusciti a gestire fino a quel momento. Le sfide della supply chain sono semplicemente troppo diverse e troppo caotiche per essere incasellate in un “numero ragionevole” di menu, pulsanti e opzioni.

Un serpente python, non correlato a Python, il linguaggio di programmazione.

Di fatto, la maggior parte dei nostri concorrenti riconosce questa situazione ed è passata alla creazione di prodotti software con un “numero folle” di menu, pulsanti e opzioni, tutto ciò come un tentativo disperato di far fronte a “tutte” le sfide della supply chain. Purtroppo, questa strada porta a mostri di software che si trasformano in fallimenti spettacolari quando vengono implementati su larga scala. Mi riferisco a questo antipattern come l’“Orrore Non-Euclideo”.

Pertanto, di fronte a una classe di problemi - ovvero le sfide della supply chain - che semplicemente non potevano essere risolti con una singola app, abbiamo iniziato, in parte accidentalmente1, ad affrontare il “meta-problema”: come fornire “app personalizzate” in cui ogni app sarebbe stata dedicata alla risoluzione di un singolo problema per una determinata situazione, ad esempio l’ottimizzazione del riapprovvigionamento per una specifica azienda.

Fornire software personalizzato per le aziende non è nulla di nuovo. L’industria del software è iniziata in questo modo negli anni ‘60 e successivamente si è evoluta negli anni ‘80 verso il dominante modello “shrinkwrap” che conosciamo oggi. Come regola generale, il software personalizzato tende ad avere molte proprietà indesiderabili rispetto al “shrinkwrap”: maggiori investimenti iniziali, configurazioni lunghe, costi di manutenzione più elevati, rischi maggiori, ecc.

Tuttavia, l’esperienza che avevo acquisito durante i primi anni di Lokad indicava che, per quanto riguarda l’ottimizzazione della supply chain, il software personalizzato aveva “un” vantaggio chiave: forniva effettivamente risultati “eccellenti”. Infatti, mentre la nostra app originale forniva al massimo risultati “sufficienti”2 indipendentemente dalla precisione delle previsioni, quei prototipi facevano frequentemente cose “straordinarie”. Inoltre, l’unico trucco era la “specializzazione estrema” del pezzo di software destinato al problema in questione.

Dopo aver esaurito ciò che sembravano essere tutte le alternative, abbiamo concluso che fornire app personalizzate era l’unico modo per procedere. Tuttavia, “scalabilità”; come fornire molte app, e “manutenibilità”; come mantenere sotto controllo i costi di manutenzione, erano due preoccupazioni fondamentali. Prima di tutto, dovevamo scegliere un “linguaggio di programmazione”. All’epoca, abbiamo considerato molte opzioni: R, Python, JavaScript, Lua, C#, … e sviluppare il nostro linguaggio di programmazione specifico del dominio (DSL), che sarebbe poi diventato noto come Envision. Discutere i pro e i contro di tutte queste opzioni sarebbe stato un po’ noioso3, quindi per chiarezza, la discussione doveva riguardare la scelta tra Python ed Envision; con Python come il concorrente più forte rispetto allo sviluppo del nostro DSL.

Python era interessante per la sua semplicità e per tutto il suo ricco ecosistema di librerie di terze parti, soprattutto nell’ambito del machine learning4. Era anche un’opzione a “basso costo” per Lokad: poiché Python, e praticamente tutte le sue librerie popolari, sono open source, avremmo semplicemente confezionato un sottoinsieme ristretto di Python, mettendo in whitelist alcune decine di pacchetti selezionati, e saremmo stati a posto. La maggior parte del lavoro per Lokad sarebbe stata incentrata sulla fornitura di un’esperienza PaaS basata su Python, il più possibile personalizzata per le sfide della supply chain.

Eppure, ecco un test decisivo che abbiamo considerato: era ragionevole aspettarsi che un analista aziendale - successivamente conosciuto come un supply chain scientist - lavorando 1 giorno alla settimana per 6 mesi avrebbe fornito un’app di produzione per risolvere una sfida critica per la supply chain, come il rifornimento, per un’azienda da 10 milioni di dollari? Guardando all’opzione Python, era chiaro che non avremmo mai potuto avvicinarci nemmeno a un livello di efficienza operativa del genere.

In primo luogo, Python richiede ingegneri del software. Infatti, Python, come qualsiasi linguaggio di programmazione completo, espone tonnellate di complessità tecnica a chiunque scriva codice in Python. Sebbene il ruolo del supply chain scientist sia stato formalizzato solo in seguito, abbiamo avuto l’intuizione fin dall’inizio che anche considerando persone intelligenti e talentuose, aspettarsi che fossero esperti sia di ingegneria della supply chain che di ingegneria del software fosse troppo. Avevamo bisogno di capacità di programmazione accessibili a un ampio spettro di persone tecnicamente orientate, non solo a ingegneri del software professionisti.

Pertanto, abbiamo creato Envision come un linguaggio per eliminare intere classi di problemi tecnici che sono inevitabili con Python. Ad esempio:

  • Gli oggetti possono essere “nulli”, le date possono essere assurdamente lontane nel passato o nel futuro, NaN può propagarsi felicemente attraverso il tuo flusso di dati, le stringhe possono diventare assurdamente grandi… Nella supply chain, queste “caratteristiche” non sono altro che problemi in attesa di accadere.
  • Gli elementi orientati agli oggetti (ad esempio le classi) sono garantiti di essere utilizzati in modo errato5, e lo stesso si può dire delle eccezioni personalizzate o delle espressioni regolari. La semplice presenza di questi elementi è, nella migliore delle ipotesi, una distrazione poco salutare.
  • Diverse operazioni di base come il parsing di file tabulari disparati (incluse le tabelle di Excel) non fanno parte del linguaggio e richiedono di gestire molti pacchetti disparati, ognuno con le proprie complessità tecniche.

Nessuna di queste classi di problemi tecnici può essere rimossa da Python senza compromettere il linguaggio stesso. Envision, come linguaggio di programmazione, è accessibile a “specialisti della supply chain” (rispetto a “specialisti del software”) solo grazie al suo focus estremamente preciso sui “problemi di ottimizzazione predittiva della supply chain”.

Pensa all’ultima volta che hai dovuto effettuare calcoli con un foglio di calcolo Excel e immagina di dettare tutti i cambiamenti che hai apportato a questo foglio di calcolo al telefono senza poterlo vedere. È così che si presenta un’iniziativa di ottimizzazione della supply chain guidata dai professionisti, ma implementata dagli ingegneri del software (non specialisti della supply chain). Le aziende spendono un’enorme quantità di tempo per comunicare ciò che desiderano all’IT; e l’IT spende un’enorme quantità di tempo cercando di capire cosa vuole l’azienda. Dopo un decennio di esperienza presso Lokad, osservo che fare affidamento su sviluppatori di software, che non sono specialisti della supply chain, per realizzare un’iniziativa di ottimizzazione della supply chain quantitativa moltiplica i costi almeno per un fattore 5, indipendentemente da quanto agili e talentuose possano essere le squadre di sviluppo del software.

In secondo luogo, i costi di manutenzione dei prototipi Python frettolosi aumentano vertiginosamente. Fuori dall’industria del software, poche persone si rendono conto che l’ingegneria del software[^ingegneria] riguarda principalmente il controllo dei costi di manutenzione. Tuttavia, risolvere i problemi di ottimizzazione della supply chain è un processo caotico: i dati provenienti da molti sistemi (poco) affidabili devono essere trasferiti in modo affidabile, i processi imperfetti e in continua evoluzione devono essere documentati e modellizzati, le metriche di ottimizzazione riflettono una strategia aziendale in uno stato di costante cambiamento, ecc. Di conseguenza, qualsiasi pezzo di software scritto per fornire l’ottimizzazione della supply chain incorpora sempre una massiccia dose di complessità specifica del dominio, semplicemente per far fronte a ciò che il mondo ci sta lanciando.

Tuttavia, il tempo è essenziale. Non ha senso avere il piano perfetto per il piano di produzione dell’anno scorso. Come regola generale, è sicuro supporre che il giorno in cui il prototipo software inizia a funzionare, verrà spostato in produzione in poche settimane, indipendentemente dal fatto che il prototipo sia ben o male scritto.

Aspettarsi che la dirigenza superiore approvi un ritardo di 6 mesi per riscrivere il prototipo in modo da renderlo adatto alla produzione dal punto di vista della manutenzione è un’illusione. Tuttavia, mettere in produzione un prototipo Python frettoloso è la ricetta per costi di manutenzione epici, combattendo una battaglia in salita con un flusso incessante di bug che dovranno essere sistemati con il nastro adesivo 24/7.

Pertanto, l’unico modo pratico per mantenere la produzione sana è scrivere il prototipo con un linguaggio di programmazione che garantisca un alto grado di correttezza per design. Ad esempio, a differenza di Python, Envision offre:

  • Tempo di esecuzione finito garantito in fase di compilazione: quando si elaborano più terabyte di dati, diventa molto noioso aspettare ore prima di rendersi conto che un calcolo non terminerà mai. Consumo di memoria limitato garantito in fase di compilazione: lottare con errori di memoria esaurita nel batch di produzione notturno è tutto tranne che divertente e, nella pratica, interrompe gravemente le operazioni.
  • Lettura e scrittura atomiche: Envision impedisce, per design, letture e scritture concorrenti all’interno del file system, anche quando i file vengono spinti tramite FTP mentre gli script vengono eseguiti. Il file system che supporta Envision è praticamente un Git su misura per file piatti giganteschi. Senza una corretta versione dei dati, molti bug diventano heisenbug: quando qualcuno si addentra nel problema, i dati sono stati aggiornati e il problema non può più essere replicato.
  • Esecuzione scalabile ambientale del programma su un cloud di risorse di calcolo, eliminando tutti gli ostacoli alla parallelizzazione che sono inevitabili non appena i dati superano alcune decine di gigabyte.

I linguaggi di programmazione generici offrono poca correttezza per design; e Python, che si spinge molto verso lo spettro del late binding, offre estremamente poco in questo ambito. Anche considerando alternative migliori - dal punto di vista della correttezza per design - come Rust, queste alternative non sono affatto soddisfacenti per l’ottimizzazione della supply chain.

Ecco alcune altre aree in cui Envision brilla in modi semplicemente non accessibili a Python:

Difesa in profondità: Non appena qualcuno inizia a scrivere codice nella tua organizzazione, a meno che non vengano prese precauzioni molto speciali6, il loro codice diventa immediatamente un rischio dal punto di vista della sicurezza informatica. Attraverso Python, è praticamente possibile fare qualsiasi cosa sulla macchina in cui viene eseguito lo script Python. Isolare correttamente Python nella pratica è un problema diabolicoamente complicato. In particolare, qualsiasi stringa prodotta dallo script Python è un potenziale vettore di iniezione. Mentre le iniezioni SQL sono famose, (troppo) poche persone si rendono conto che anche semplici file di testo piatti come CSV sono vulnerabili agli attacchi di iniezione. Envision offre un grado di sicurezza che semplicemente non può essere replicato con Python. Le violazioni dei dati sono in aumento, spargere pezzi di Python ovunque non farà bene alla sicurezza informatica.

Prestazioni trasparenti: Se un programma è troppo lento da eseguire, allora questo programma non dovrebbe nemmeno compilare in primo luogo7. Se un programma viene reso di una riga più corto, allora il programma dovrebbe essere eseguito più velocemente. Se viene modificata solo una singola riga, solo questa riga dovrebbe essere ricalcolata8 durante la nuova esecuzione del programma sugli stessi dati. Durante la compilazione, il compilatore dovrebbe puntare non a una macchina specifica ma a un cloud di risorse di calcolo, offrendo una parallelizzazione automatica basata sui dati. Envision fa molto per offrire tutte queste proprietà per impostazione predefinita senza alcuno sforzo di codifica. Al contrario, richiede un uso massiccio di librerie specializzate in Python per iniziare anche ad avvicinarsi a tali proprietà.

Aggiornamento trasparente: Lo stato dell’arte è un obiettivo in continua evoluzione per quanto riguarda il software. Nel 2010, il miglior toolkit di machine learning era SciPy (argomentabile). Nel 2013, era scikit. Nel 2016, era Tensorflow. Nel 2017, era Keras. Nel 2019, era PyTorch. C’è un detto nell’ingegneria del software che si può datare l’anno di nascita di qualsiasi progetto software guardando la sua pila software e le sue dipendenze. Infatti, non appena distribuisci i tuoi script Python personalizzati, introdurranno molteplici dipendenze che potrebbero non invecchiare bene. Al contrario, con Envision, stiamo sfruttando ampiamente riscritture automatiche del codice9, per mantenere gli script “legacy” aggiornati con un linguaggio in continua evoluzione.

Stack confezionato: Gli script Python non possono vivere isolati10. Il codice deve essere versionato (ad esempio con Git) con diritti di accesso (ad esempio GitHub). Hanno bisogno di un ambiente in cui eseguire che non sia la tua macchina (ad esempio una VM Linux nel cloud). È necessario uno scheduler per orchestrare il flusso di dati (ad esempio AirFlow). È necessario uno strato di archiviazione colonnare distribuito per la preparazione dei dati (ad esempio Spark). È necessario un toolkit di machine learning per l’analisi predittiva (ad esempio TensorFlow). È necessario un toolkit di ottimizzazione per affrontare i problemi combinatori della supply chain (ad esempio GLPK). I risultati grezzi devono essere esposti da qualche parte per un consumo successivo (ad esempio un server SFTP). I colleghi praticanti della supply chain devono essere in grado di monitorare ciò che sta accadendo (ad esempio un’interfaccia utente web). I diritti di accesso devono essere applicati (ad esempio Active Directory), ecc. Envision semplifica tutto ciò in un’unica meta-app, eliminando l’onere di assemblare decine di componenti software per fornire anche l’app più semplice.

Quindi, anche se è un ottimo linguaggio, Python non è al di sopra delle critiche:

  • Le prestazioni di calcolo sono scarse ed è una battaglia in salita indirizzare ogni singolo calcolo attraverso la libreria giusta (ad esempio NumPy) per evitare prestazioni pessime nelle attività di elaborazione dei dati. Inoltre, l’utilizzo di più librerie tende a creare molta frizione quando i dati devono essere spostati da una libreria all’altra.
  • Le prestazioni della memoria sono scarse e, in particolare, la garbage collection basata sul conteggio dei riferimenti di Python è datata - e tutti i linguaggi di programmazione più recenti come Java, C# o JavaScript utilizzano invece il tracciamento. Quando si lavora con attività intensive di memoria su grandi quantità di dati, questo è un problema.
  • La gestione dei pacchetti in Python è stata un disastro per molto tempo, ed è necessario uno specialista dei pacchetti per farla funzionare correttamente. Inoltre, questo problema è stato aggravato dagli aggiornamenti del linguaggio ad alta frizione.
  • La maggior parte dei (pochi) controlli di correttezza avviene solo a runtime, quando il programma viene eseguito, il che è una fonte di frustrazione infinita quando si tratta di elaborazione dei dati. I problemi evidenti si manifestano solo dopo diversi minuti di esecuzione, riducendo la produttività.

In conclusione, anche se Python è fantastico (lo è), non è una risposta soddisfacente per l’ottimizzazione della supply chain. Costruire e mantenere un’app di machine learning di produzione in Python è molto possibile, ma i costi sono significativi e, a meno che la tua azienda non sia pronta ad avere almeno un piccolo team di ingegneria del software dedicato alla manutenzione di questa app, il tutto non darà risultati soddisfacenti per la tua supply chain.

Sviluppare Envision, un linguaggio di programmazione specifico per il dominio dedicato all’ottimizzazione predittiva della supply chain, non è stata la nostra prima scelta. Non era nemmeno la nostra decima scelta. Era più come l’unica soluzione funzionante che avevamo dopo aver esaurito una lunga lista di alternative più convenzionali nel corso di cinque anni. Sette anni dopo e molte aziende clienti dopo, ogni nuovo cliente riesce ancora a sorprenderci, in un modo o nell’altro, con un altro colpo di scena nella loro supply chain, che non avremmo mai potuto abbracciare con un approccio classico di tipo enterprise. Era necessaria la programmabilità, ma Python non era la soluzione di cui avevamo bisogno.


  1. Nel 2013, ero ancora convinto che fosse possibile fornire un’app soddisfacente per l’ottimizzazione della supply chain. In realtà, è stato il confronto con sfide di prezzo che in qualche modo ci ha costretto la mano e ha indirizzato Lokad sulla strada della costruzione del proprio linguaggio specifico per il dominio. Questo linguaggio era inizialmente destinato solo all’ottimizzazione dei prezzi, ma presto ci siamo resi conto che questo approccio era esattamente ciò di cui avevamo bisogno anche per l’ottimizzazione della supply chain. ↩︎

  2. L’idea che fornire un’accuratezza di previsione superiore portasse di per sé a una performance superiore della supply chain era probabilmente una delle più grandi idee sbagliate che avevo quando ho fondato Lokad. Guarda questo episodio di Lokad TV per una prospettiva più sana su questo argomento. ↩︎

  3. La maggior parte dei problemi che abbiamo identificato con Python non avevano nulla a che fare con Python per se, che è un ottimo linguaggio di programmazione, ma semplicemente il fatto che Python è un linguaggio di programmazione generico↩︎

  4. Nel 2013, Python non aveva ancora raggiunto la dominanza che ha acquisito negli anni successivi nel campo dell’apprendimento automatico, R era ancora un forte concorrente, tuttavia, SciPy e NumPy, due eccellenti librerie, erano già presenti e in crescita in quel periodo. ↩︎

  5. Dai un’occhiata a questo eccellente talk Stop Writing Classes da Pycon 2012. Anche gli ingegneri software esperti tendono a sbagliare. ↩︎

  6. Purtroppo, per quanto riguarda la sicurezza del codice, non esiste un sostituto per le revisioni sistematiche del codice da parte dei pari. ↩︎

  7. A causa del problema dell’arresto, il lettore attento potrebbe dedurre che Envision non è un linguaggio Turing completo. Infatti, Envision non lo è. ↩︎

  8. Envision si basa sulla differenza tra i grafici di calcolo e cerca di ridurre al minimo la quantità di ricalcoli tra i cambiamenti incrementali al fine di consentire un prototipazione molto rapida su grandi set di dati. Tuttavia, a seconda della situazione, cambiare una singola riga può richiedere il ricalcolo dell’intero script. ↩︎

  9. Le riscritture automatiche del codice sono estremamente difficili per un linguaggio di programmazione generico. A meno che il linguaggio di programmazione e tutta la sua libreria standard non siano stati progettati con questa esigenza in mente, gli strumenti di aggiornamento automatico fanno poco in pratica. Quando abbiamo progettato Envision, sapevamo che avremmo commesso molti errori (e così è stato), e quindi abbiamo prestato molta attenzione per assicurarci che il linguaggio fosse particolarmente adatto per le riscritture automatiche. Fino ad oggi, abbiamo effettuato oltre 100 riscritture incrementali fin dall’inizio di Envision. ↩︎

  10. Ironicamente, “Batteries Included” è uno dei motti di Python. Tuttavia, la quantità di colla necessaria per unire tutti gli elementi richiesti per costruire un’applicazione destinata all’ottimizzazione predittiva della supply chain è spaventosa. ↩︎