Social Links Search User Login Menu
Tools
Close
Close

Articoli Low-Code Italia

Niente codice, nessun pensiero?
Andrei Balan 229

Niente codice, nessun pensiero?

Diversi livelli per una programmazione più semplice

Il no-code è un nuovo tema caldo per le startup che si occupano di programmazione. L'idea è quella di sviluppare un sistema che consenta agli utenti finali di eseguire la programmazione di cui hanno bisogno senza il difficile lavoro di formulare il codice. Esistono sistemi no-code per la creazione di applicazioni mobile, per l'analisi dei dati e molto altro ancora.

Forse non è una sorpresa che "eliminare il carico di programmazione" non sia un'idea così nuova come qualcuno potrebbe pensare e c'è un'eccellente serie di blog sulla storia del no-code di Instadeq, che risale al 1959.

Curiosamente, la brochure promozionale del 1957 su FLOW-MATIC, un predecessore del COBOL creato da Grace Hopper, utilizza quasi lo stesso linguaggio che si trova oggi nei piani di lancio delle startup (Figura 1). Naturalmente, nel 1957, la programmazione si riferiva al noioso processo di trascrizione del programma desiderato in formato assembler di basso livello o (più spesso) direttamente in codice macchina, mentre "eliminare virtualmente il carico di dati" significava disporre di un linguaggio di programmazione simbolico di alto livello così semplice che anche un matematico ragionevolmente esperto sarebbe stato in grado di utilizzarlo.

Figura 1.
Figura 1. Elimina praticamente il carico di programmazione. Opuscolo promozionale FLOW-MATIC (1957)

Quindi, c'è davvero qualcosa di nuovo nei sistemi no-code? È davvero possibile "eliminare il proprio carico di programmazione"? E cosa servirebbe per fare dei veri progressi in questa direzione?

1. Substrati per l'interazione

Se guardiamo al di là delle parole d'ordine, cosa possono fare realmente le piattaforme no-code? Per capirlo, vorrei introdurre l'idea di substrato di programmazione. L'idea è che se si dispone di un sistema software di qualsiasi tipo, è possibile interagire con esso a più livelli attraverso diversi substrati. Se state costruendo un software, interagirete con esso attraverso un linguaggio di programmazione modificando il suo codice sorgente. Se si utilizza un software, si interagisce con esso attraverso un'interfaccia grafica (strutturata). Tutte queste interazioni - codice in un linguaggio e interazioni con un'interfaccia grafica - sono interazioni con diversi substrati (di programmazione).

L'idea dei substrati di programmazione generalizza la consueta distinzione tra programmazione di un sistema software e utilizzo di un sistema software. Questo è utile perché spesso esistono più di due substrati diversi. È utile anche perché possiamo analizzare i diversi substrati in termini di quali tipi di modifiche al software consentono e quali sono le difficoltà di utilizzo.

Figura 2.
Figura 2. Un ipotetico sistema di contabilità con substrati per lo sviluppo (source code), la configurazione (grafica o testuale) e l'utilizzo (user interface).

Ad esempio, la Figura 2 illustra i diversi substrati che potrebbe avere un ipotetico software per la contabilità. L'utente interagisce ("use") con un'interfaccia grafica. È facile, ma permette solo "cambiamenti" limitati: si possono inserire le fatture e ottenere i moduli per la dichiarazione dei redditi! Un utente più avanzato può anche modificare la configurazione del sistema. Anche in questo caso si tratta di un'interfaccia grafica o di un file di configurazione testuale. È più difficile, ma consente di modificare, ad esempio, il modo in cui il sistema calcola le imposte. Infine, l'utente (o la società che sviluppa il sistema) può modificare il codice del sistema stesso. Si tratta di un'operazione molto difficile, ma che consente di modificarlo in modo arbitrario. Potrebbe essere necessario se il governo inventa un nuovo tipo di calcolo delle imposte che nessuno si aspettava e che quindi non può essere aggiunto semplicemente attraverso la configurazione. Questo è un esempio piuttosto ovvio, ma mostra alcuni aspetti importanti dei substrati di programmazione:

  • Se ci sono più substrati, prima o poi gli utenti che hanno familiarità con uno di essi raggiungeranno i suoi limiti e dovranno investire nell'apprendimento del successivo substrato più potente. Questo può essere un divario grande (o addirittura incolmabile).               
  • Se avete bisogno di modificare il sistema in modo complesso, avrete bisogno di un substrato sufficientemente espressivo. In altre parole, l'angolo in basso a destra del diagramma sarà sempre vuoto. Questo è un punto sollevato da Fred Brooks nel suo saggio No Silver Bullet: non importa quanto riduciamo la complessità accidentale causata dai nostri strumenti scadenti, la complessità essenziale del problema rimane.

Figura 3.
Figura 3. Excel dispone di substrati per l'inserimento di dati (tabelle), la scrittura di calcoli (equazioni), lo scripting (macro VBA) e il codice sorgente per la modifica del sistema stesso, accessibile solo agli sviluppatori di Excel.

Un sistema con una struttura di substrati più interessante è Excel (Figura 3). Si noti che ho separato l'inserimento dei dati dalla scrittura delle equazioni, perché molte persone lo usano solo per registrare i dati. Grazie alle macro, Excel ha un substrato più espressivo che consente maggiori cambiamenti, ma è anche più complesso. Questo significa anche che il divario è più evidente: passare dalla scrittura di equazioni allo scripting VBA comporta una curva di apprendimento non banale.

2. Il No-Code è una sfida 

Ho due semplici problemi di programmazione su cui ho lavorato di recente che, immagino, sarebbero idealmente risolvibili da un'adeguata struttura no-code. L'esame di questi problemi illustra alcune delle sfide che i sistemi no-code devono affrontare.

2.1. Caso di studio: Gestione delle ammissioni all'anno di Informatica

Durante la pandemia, ero responsabile della gestione delle ammissioni all'anno di informatica nel Kent. Gli studenti facevano domanda tramite Google Form, noi verificavamo i loro studi passati in un sistema interno, fissavamo un colloquio Zoom con loro, inviavamo loro un invito via e-mail e un risultato dopo il colloquio. Di tanto in tanto dovevo anche avere un resoconto sul numero di studenti a cui era stato offerto un posto, che avevano accettato la nostra offerta, ecc.

Naturalmente, ho finito per scrivere uno script F# (e un po' di JavaScript) per automatizzare in parte tutto questo, ma sarebbe un buon caso di studio per il no-code, perché si tratta per lo più di un'integrazione di servizi esistenti (Google docs, e-mail, Zoom). Molti strumenti di automazione no-code forniscono l'integrazione con questi servizi. Ma ci sono due problemi.

  • Il primo è che questo potrebbe non essere scalabile. Nel marzo 2020, Zoom era ancora nuovo e l'API stava cambiando, quindi gli sviluppatori della piattaforma no-code dovrebbero tenere il passo per assicurarsi che l'integrazione funzioni ed esponga tutto ciò che è necessario.
  • Il secondo problema sono le eccezioni. Nel mio caso, dovevo ottenere i voti degli studenti da un sistema interno, che era oscuro (ed è stato sostituito l'anno successivo). Avevo un hack JavaScript per estrarre i dati da incollare in una console JavaScript del browser, che per lo più funzionava. Ma non si trattava di un semplice compito di estrazione di numeri da una tabella: ci sono voti non numerici (Pass/Fail), anni ripetuti, esami ripetuti e altre eccezioni.

2.2. Caso di studio: Raccolta di dati sulle donazioni di beneficenza

Un altro progetto a cui ho partecipato è stato lo scraping dei dati dalle piattaforme di crowdfunding, che abbiamo iniziato a fare durante la pandemia e che è sfociato in un documento congiunto di politica sociale (Figura 5).

Figura 5.
Figura 5. Grafici che mostrano il numero di raccolte di fondi e l'importo donato ai "banchi alimentari" in seguito all'epidemia di Covid-19. Si è registrato un picco importante durante la prima ondata, ma nessun aumento significativo nelle altre onda

Si tratta di un compito altrettanto semplice dal punto di vista concettuale. Basta cercare vari termini sulla piattaforma, iterare sui risultati e recuperare i dati relativi ai dettagli della raccolta fondi, alle date e (quando possibile) alle singole donazioni. In realtà, non è così semplice:

  • Alcuni servizi restituiscono solo HTML, ma uno carica tutti i dati dinamicamente tramite GraphQL, quindi è necessario lavorare a livello di browser (simulando i clic), il che è lento, oppure estrarre i dati da strutture diverse (HTML divertente, JSON divertente).
  • Come sempre, ci sono cambiamenti inaspettati. Dopo circa un anno di funzionamento del mio script, una delle piattaforme ha rinominato alcune classi CSS; dopo qualche altro mese, una pagina raccoglieva donazioni in euro (in seguito è apparsa anche una in dollari). Due anni dopo aver iniziato a farlo, una pagina riportava l'importo raccolto in portoghese. Anche un servizio governativo è stato chiuso a metà del mio progetto.

La domanda da porsi è quindi: di che tipo di substrati di programmazione abbiamo bisogno se vogliamo essere in grado di risolvere i problemi nel modo più semplice possibile (con o senza codice)?

3. Dimensioni tecniche dei sistemi no-code3. Dimensioni tecniche dei sistemi No-Code

Sappiamo come parlare di linguaggi di programmazione e delle loro caratteristiche, ma parlare di sistemi di programmazione possibilmente visuali, interattivi e statici è stata una sfida. Per semplificare la questione, Joel Jakubovic, Jonathan Edwards ed io abbiamo recentemente elaborato il quadro delle dimensioni tecniche dei sistemi di programmazione. Si tratta di un quadro qualitativo che definisce una serie di dimensioni che possono essere utilizzate per descrivere i sistemi di programmazione. Ad esempio, la dimensione "feedback loops" descrive il modo in cui un sistema fornisce un feedback allo sviluppatore o all'utente (in Excel, ad esempio, c'è un loop attivo quando si modificano i valori in un foglio o un controllo degli errori meno immediato quando si modificano equazioni o script VBA).

Diverse dimensioni tecniche sono molto importanti per i sistemi no-code:

  • Struttura nozionale - Quali sono le diverse notazioni coinvolte nella programmazione e nell'utilizzo del sistema? Nei sistemi di programmazione convenzionali, esiste una notazione primaria - il linguaggio di programmazione in cui viene scritto il codice - insieme a varie notazioni secondarie. Nei sistemi no-code, la notazione primaria è tipicamente un linguaggio visivo o un'interfaccia grafica. Questo può essere integrato da un piccolo DSL, ad esempio per specificare le condizioni, ed eventualmente anche da un linguaggio di programmazione (esposto o meno), ad esempio per scrivere estensioni da integrare con altre piattaforme.

  • Autosostenibilità - In che misura il comportamento di un sistema può essere modificato al suo interno? In Java o C#, ciò si limita alla riflessione, ma le macchine Smalltalk o Lisp consentono di modificare l'ambiente di sviluppo dall'interno. L'autosostenibilità dei sistemi no-code è in genere molto limitata. Sono closed-source e in gran parte scritti in un altro linguaggio di programmazione e possono essere usati solo per costruire applicazioni in un particolare dominio. Anche l'integrazione di altri servizi deve essere fatta al di fuori del sistema.
  • Gradi di automazione - Quale parte della logica del programma non deve essere specificata esplicitamente? In C# o Java, l'unica cosa che viene fatta automaticamente è la garbage collection(GC), ma si può andare oltre. Ad esempio, Prolog e SQL automatizzano la valutazione e sono necessari programmi più dichiarativi. Questo è forse un modo in cui i sistemi no-code possono provare a fare qualcosa di intelligente. Alcune delle eccezioni degli esempi precedenti potrebbero essere gestite da uno strumento di programmazione per esempi come FlashFill in Excel.

Per ulteriori idee, si consiglia di consultare il nostro quadro delle dimensioni tecniche, ma le tre dimensioni sopra citate sono una buona struttura per tre pensieri che ho sulle piattaforme di programmazione no-code.

3.1. Struttura notazionale e HyperCard

HyperCard non è una piattaforma no-code, perché permette di scrivere codice in HyperTalk (e inoltre è stato creato circa 30 anni prima che il no-code diventasse una parola d'ordine), ma ha avuto un successo straordinario nel permettere ai non esperti di creare programmi. Inoltre, ha un modo molto intelligente di strutturare il suo substrato di programmazione. In HyperCard si progettano le schede in un editor WYSIWYG e si possono associare comportamenti agli elementi. È possibile specificare che un pulsante si collega a un'altra scheda senza bisogno di programmarla, ma le interazioni più avanzate richiedono HyperTalk.

Ci sono ancora due substrati. Il software stesso è scritto in un altro linguaggio (non è autosufficiente, a parte la documentazione che è uno stack HyperCard) e c'è l'ambiente visuale HyperCard stesso. Tuttavia, l'ambiente visivo è strutturato in termini di diversi livelli operativi (Figura 6) che sbloccano gradualmente funzioni più avanzate del sistema. Questi aggiungono ulteriori notazioni (come il codice HyperTalk), ma vivono ancora all'interno di un unico substrato.

Figura 6.
Figura 6. Scelta di un livello utente in HyperCard. Ogni livello consente all'utente di accedere a funzioni di modifica o programmazione più avanzate.

Figura 7.
Figura 7. I diversi livelli utente hanno notazioni diverse, ma sono accessibili da un unico substrato: l'interfaccia utente di HyperCard.

L'aspetto positivo è che il processo di apprendimento è graduale. Come illustrato nella Figura 7, si inizia con la navigazione, si passa alla modifica del testo e del design, quindi si sbloccano le funzionalità per l'aggiunta di nuove schede e solo successivamente si passa alla scrittura del codice. Questo riduce in qualche modo il divario (come, ad esempio, tra i substrati di Excel) che si deve colmare se si ha bisogno di modifiche più complesse, perché si rimane nello stesso substrato, anche se si accede a funzionalità più complesse che esso fornisce. Ciò significa anche che non si viene sopraffatti da tutto ciò che è disponibile, poiché le funzioni più avanzate sono inizialmente nascoste. Nel mondo dei linguaggi di programmazione, Racket segue lo stesso modello con il suo come progettare i programmi insegnando i linguaggi.

3.2. Autosostenibilità e sistemi aperti

Nonostante l'interessante struttura nozionistica, HyperCard non è autosufficiente, il che significa che non può essere modificato da se stesso. È un'applicazione (apparentemente scritta in Apple Pascal!) e se si vuole cambiarla, bisogna modificare il suo codice sorgente.

In che modo questo è rilevante per le piattaforme no-code? Quanto più un sistema è autosufficiente, tanto più sarà possibile fare da sé. Questo può non avere molta importanza quando si tratta di integrare solo un paio di servizi. Ma, come illustrano i miei casi di studio, ci sono sempre eccezioni e casi a cui gli sviluppatori della piattaforma non potevano pensare. Se il sistema può essere modificato, è possibile per l'utente diventare gradualmente programmatore. (E anche di sviluppare un'ecologia aperta e condivisa di funzioni che si occupa del problema della scalabilità di cui ho parlato prima).

L'idea che l'utente possa diventare gradualmente programmatore esiste, ad esempio, in Smalltalk (da User-oriented Descriptions of Smalltalk Systems):

[Il nuovo utente di un sistema Smalltalk probabilmente inizierà a usare i suoi sistemi applicativi già pronti [...]. Dopo un po', può diventare curioso di sapere come funziona il suo sistema. Dovrebbe quindi          essere in grado di "aprire" l'oggetto applicazione [...] La cosa successiva che l'utente potrebbe voler fare è costruire nuovi sistemi simili a quello che ha usato. Infine, l'utente esperto vorrà creare i propri            ["kit" per la costruzione di tali sistemi].

Il substrato per un sistema completamente autosostenibile deve consentire di apportare cambiamenti sia piccoli che grandi. Come discusso in precedenza, le piccole modifiche possono essere facili, ma le grandi modifiche saranno inevitabilmente difficili da realizzare. Questo è illustrato nella Figura 8, che mostra la possibile gamma di substrati di programmazione e nella Figura 9, che mostra ciò che vorremmo ottenere idealmente.

Figura 8.
Figura 8. I substrati di programmazione possono facilitare le piccole modifiche, ma le grandi modifiche rimarranno inevitabilmente difficili.

Figura 9.
Figura 9. Il substrato ideale fa sì che apportare un piccolo cambiamento sia facile anziché difficile.

Il problema dei sistemi autosostenibili è che in genere sono piuttosto difficili da usare. Nelle macchine Smalltalk o Lisp, bisogna padroneggiare un vero linguaggio di programmazione prima di poter fare praticamente tutto. In altre parole, il substrato di programmazione si trova nella parte alta del mio grafico e fare anche un piccolo cambiamento è difficile. Lo scopo delle piattaforme no-code è quello di rendere facili le modifiche più piccole (o medie). Un sistema perfetto avrebbe un substrato di programmazione mostrato nella Figura 9. Questo renderebbe facili le piccole modifiche per design. Questo renderebbe semplici le piccole modifiche, ma consentirebbe una progressione graduale verso modalità di lavoro più complesse, necessarie per le modifiche più grandi. (Non ho idea di come si possa fare, ma HyperCard sembra un'opzione interessante).

3.3. Limiti dell'automazione

I sistemi come FLOW-MATIC, con cui ho aperto questo post, erano chiamati "sistemi di programmazione automatica" negli anni Cinquanta e Sessanta. Alla fine si sono trasformati in linguaggi di programmazione, ma all'epoca la speranza era che si potesse gradualmente automatizzare la programmazione in misura sempre maggiore. Oggi, questa è di nuovo una speranza di molti che cercano di rendere la programmazione più "facile", soprattutto con l'idea che l'apprendimento automatico possa magicamente fare il nostro lavoro.

Ci sono certamente aree in cui questo ha funzionato bene, come la programmazione per esempio nel caso di Excel FlashFill. David Canfield Smith, che nel 1975 creò l'ambiente di programmazione visuale Pygmalion, è uno di quelli che ha riconosciuto il pericolo di questo approccio:

[La [programmazione automatica] presenta un pericolo, se portata troppo avanti. Rendendo il computer una "scatola nera" che esegue la programmazione vera e propria, l'utente deve pensare meno alla      struttura logica del problema. [...] 

Se avranno successo, i sistemi di programmazione automatica sostituiranno alcuni processi di pensiero di alto livello nell'uomo. Invece di incoraggiare l'uomo a pensare di più e meglio, la programmazione automatica potrebbe incoraggiarlo a pensare di meno e meno bene.

Pygmalion era un sistema interessante, perché cercava di semplificare la programmazione, senza però automatizzarla. L'approccio, oggi noto come "programmazione per dimostrazione", consisteva nell'istruire il computer su come completare un compito mostrando i passi necessari che il computer avrebbe poi ripetuto meccanicamente.

4. Direzioni di ricerca per il no-code

Ho introdotto l'idea dei substrati di programmazione e ho parlato del nostro lavoro sulle dimensioni tecniche, perché queste forniscono un quadro utile per pensare alla domanda principale di questo post: che cosa servirebbe per fare dei veri progressi verso una programmazione più semplice?

Ora, non ho esaminato tutte le piattaforme no-code esistenti. Ci sono sicuramente molte idee interessanti e innovative in quelle che ho esaminato e sono sicuro che ce ne sono altre in quelle che non conosco. Ma credo anche che ci siano dei limiti fondamentali.

Un sistema che non è autosufficiente inevitabilmente, prima o poi, renderà impossibile all'utente fare qualcosa che desidera. (Le storie dell'orrore che a volte sento su alcuni elaborati usi di Excel nel settore finanziario ne sono una prova).

L'automazione può aiutare solo fino a un certo punto. In ultima analisi, la programmazione consiste nel pensare al problema che stiamo risolvendo e cercare di eliminarlo sarebbe un passo nella direzione sbagliata. Trovare il modo di incoraggiare un pensiero chiaro e di alto livello (possibilmente utilizzando una metafora visiva come quella tentata da Pygmalion o Boxer) è un approccio più interessante!

Per concludere, credo che la grande questione aperta sia come creare un substrato di programmazione che sia abbastanza semplice per piccoli cambiamenti, ma che racchiuda il potenziale per grandi cambiamenti.

In una certa misura, HyperCard riesce in questo intento, avendo tutti gli strumenti di creazione incorporati in un ambiente che ha lo stesso aspetto del programma in esecuzione. In questo modo è facile per gli utenti scoprire gradualmente le capacità più avanzate del sistema. Una cosa del genere potrebbe essere più visiva e più autosufficiente?

Penso anche che il problema del "codice" sia molto diverso da quello che si pensa di solito. Non è che il "codice" sia in qualche modo intrinsecamente complicato. Le persone lo trovano spaventoso, ma se lo provano davvero (e ottengono un'esperienza d'uso decente), sono in grado di lavorare con il codice (almeno, questa è stata la mia conclusione da alcuni esperimenti empirici che ho fatto usando The Gamma). Il problema è che è molto difficile collegare il codice a ciò che vediamo effettivamente accadere sullo schermo. E questo è un problema indipendentemente dal fatto che il codice sia testuale o che utilizzi un linguaggio di programmazione visuale.

 

Autore: Tomas Petricek

 

 

 

Rate article

Nessun voto
Vota questo articolo:
Nessun voto

Condividi

Stampa

Comment

Collapse Expand Comments (0)
You don't have permission to post comments.
Back To Top