Sul sito di GenroPy, stiamo discutendo della programmazione ad eventi e della programmazione asincrona. Non abbiamo ancora identificato la tecnica migliore per scrivere il codice.
Con un po’ di fantasia, potremmo scrivere così:
def tbDetail(self, parent, **kwargs):
tb = parent.toolbar(**kwargs)
tb.button('New Detail', action=fire('master.save')|fire('detail.record.pkey'))
Per chiarezza, togliamo un po’ di magia dal parametro action:
def tbDetail(self, parent, **kwargs):
tb = parent.toolbar(**kwargs)
tb.button('New Detail', action=self.onNewDetail)
def onNewDetail(self, do):
do | fire('master.save') | fire('detail.record.pkey')
Può sembrare che stia piegando la sintassi di Python per i miei torbidi scopi, in realtà sto facendo ricorso ad un ben noto strumento della programmazione funzionale. In particolare, la struttura dati che viene passata a onNewDetail è una monade.
Si possono scrivere funzioni di ordine superiore, per combinare insieme computazioni e fornire strutture di controllo:
def onNewDetail(self, do):
do | unless(get('master.saved'), fire('master.save')) | fire('detail.record.pkey')
L’operatore | (bind) modifica la monade (inizialmente vuota, passata nel parametro do), applicando la funzione che lo segue.
Qui uso le monadi a due livelli:
- nel codice Python, per costruire una semplice AST e generare codice Javascript.
- nel codice Javascript che verrà generato, per implementare la programmazione asincrona sotto forma di continuation monad basata sulle Promise di Dojo 1.5.