emanuele delbono
ema.blog

Emanuele DelBono

  • Fp-ts validation spiegata bene

    In CodicePlastico stiamo studiando la programmazione funzionale, abbiamo fatto un corso con Matteo Baglini (che consiglio a tutti) e in questi giorni stiamo provando a fare un po’ di refactoring verso il paradigma funzionale. Naturalmente i dubbi vengono, e ieri ho scritto una mail a Matteo per chiedere aiuto su una parte di codice dedicata alla validazione. La mail di risposta e’ stata talmente dettagliata che ho pensato fosse uno spreco tenerla solo per me, così (con l’autorizzazione di matteo) la pubblico qui:

    [ema] Ciao Matteo, nell’addentrarmi nella programmazione funzionale in Typescript usando questa libreria https://github.com/gcanti/fp-ts mi sono imbattuto in questo meccanismo di validazione che non capisco completamente e mi sembra molto complesso. L’esempio particolare a cui mi riferisco e’ questo: https://github.com/gcanti/fp-ts/blob/master/docs/Validation.md


    Ciao Ema,

    Personalmente direi articolato non complesso. Più avanti mi spiego.

    [ema] Perche’ si deve creare una funzione curried per costruire la Person?

    In generale per costruire Person ti serve una funzione, questo banalmente perchè sei in fp e in fp tutto si fa con le funzioni. Le strutture dati algebriche (Person è un product type) non fanno niente se non immagazzinare dati. Le funzioni permettono la costruzione e/o manipolazione di questi dati. Ambienti come haskell e scala (con le case class) ti offrono out-of-box la funzione di costruzione. Typescript no, prima sfiga.

    [ema] Allora perchè curried?

    Questo accade perchè Applicative serva a comporre una funzione con effetti (le funzioni di validazione) + una funzione senza effetti con due parametri (la funzione di creazione di person). Nel mondo fp ovvero haskell una funzione con due paramentri (a, b) => c è di fatto (grazie a curry) 2 funzioni da 1 parametro a => b => c. Molto probabilmente Fp-Ts ha scelto di seguire più da vicino lo stile haskell, seconda sfiga. In scala gli autori di librerie tendono ad evitare il currying perchè non è naturale nel linguaggio.

    Detto questo, perchè validatePerson nell’esempio di Fp-Ts è così complessa? Perchè ti mostra a basso livello come si compone una funzione con effetto con una funzione senza effetti con due parametri (curried).

    Dissezioniamo questo mostro:

    A.ap(validateName(input['name']).map(person), validateAge(input['age']))
    

    la funzione ap è fatta così:

    readonly ap: <A, B>(fab: HKT<F, (a: A) => B>, fa: HKT<F, A>) => HKT<F, B>
    

    in scala

    def ap: [A, B](fab: F[A => B], fa: F[A]): F[B]
    

    in poche parole

    1. accetta fab: una funzione da A=>B wrappata in un effetto F aka F[A => B]
    2. accetta fa: un valore A wrappato in un effetto aka F[A]
    3. restutisce un F[B]

    invocando le singole validazioni ottengo

    const nameResult: Validation<NonEmptyArray<string>, string> = validateName(input['name'])
    const ageResult: Validation<NonEmptyArray<string>, number> = validateAge(input['age'])  
    
    A.ap(nameResult.map(person), ageResult)  
    

    ora concentriamoci qui

    nameResult.map(person) 
    

    passando alla map (che accetta in ingresso una funzione con 1 parametro) il curried constructor ottengo

    const nameResultBindend: Validation<NonEmptyArray<string>, number => Person> = nameResult.map(person)
    

    dai! non ci credo! ho una funzione wrappata in un effetto sta a vedere che ora posso chiamare ap! ;-)

    A.ap(nameResultBindend, ageResult)
    

    applicando più volte la stessa tecnica (ap + map) posso comporre funzioni con 3/4/5/N parametri. Ripeto è un dettaglio low level, importante, ma low level.

    Durante il corso per non andare così low level abbiamo usato la map2/map3/etc oppure la mapN. Prendiamo la map2, in scala la sua firma è:

    def map2[A, B, Z](fa: F[A], fb: F[B])(f: (A, B) => Z): F[Z]
    

    il suo scopo è quello di valutare in maniera indipendente 2 effetti (fa e fb), passare i risultati alla funzione f e liftare quanto prodotto (Z) nel solito effetto (F). Questo ci permetteva di fare una roba tipo

    case class Person(name:String, age:Int)
    def makePerson(name:String, age:Int):ValidationResult[Person] = 
       Applicative[ValidationResult].map2(validateName(name), validateAge(age))(Person.apply)
    

    Quindi se vuoi usare questo tipo di combinatori (a più alto livello) devi cercarli in fp-ts. Ho fatto un giro e controllando la definizione di Applicative (https://github.com/gcanti/fp-ts/blob/master/docs/Apply.md) non ho trovato map2 ma una cosa equivalente liftA2: Lift a function of two arguments to a function which accepts and returns values wrapped with the type constructor F

    ovvero data la funzione f: (A, B) => Z passandola a liftA2 otteniamo una funzione g: (F[A], F[B]) => F[Z].

    nel mondo curry andiamo da f: A => B => Z a g: F[A] => F[B] => F[Z]

    in pratica prendiamo una funzione senza effetti (f) e la trasformiamo in una che funziona allo stesso modo ma effectful.

    Se caliamo liftA2 nell’esempio di validation di Fp-Ts dobbiamo prima di tutto prendere il curried constructor

    const person = (name: string) => (age: number): Person => ({ name, age })
    

    e liftarlo con liftA2 (non conosco typescript e fp-ts quindi vado un po’ di pseudo codice)

    const A = getApplicative(getSemigroup<string>())
    const personLiftata = liftA2(A)(person)
    

    ed in fine validationPerson invocherà la versione liftata

    function validatePerson(input: Record<string, string>): Validation<NonEmptyArray<string>, Person> {
      return personLiftata(validateName(input['name']), validateAge(input['age']))
    }
    

    sintetizzando prendiamo una funzione

    string => number => Person
    

    e “senza fare niente” la facciamo operare in un contesto di validazione

    Validation<NonEmptyArray<string>, string> => Validation<NonEmptyArray<string>, number> => Validation<NonEmptyArray<string>, Person>
    

    E qui sta la figata, ipotizziamo che validateName e validateAge siano implementate server side, quindi la validazione diventa asyn con i Task (sempre di Fp-Ts). Come cambia il tutto? La contruction function non cambia, non dipende da effetti.

    Le validateName e validateAge le riscriviamo.

    function validateName(input: string): Task<string> ...
    function validateAge(input: string): Task<number>  ...
    

    La definizione della personLiftata non cambia.

    Mentre validatePerson cambia solo come tipo di ritorno

    function validatePerson(input: Record<string, string>): Task<Person> {
      return personLiftata(validateName(input['name']), validateAge(input['age']))
    }
    

    Il tutto accade perchè prendiamo la solita

    string => number => Person
    

    e “senza fare niente” la facciamo operare in un contesto di HTTP async

    Task<string> => Task<number> => Task<Person>
    

    Forte, no?

    [ema] E se avesse 20 campi?

    Hai un problema di design! :-) Detto questo, esistono tante liftA con il numero di parametri

    fp-ts arriva al max a liftA4. haskell arriva al max fino a liftA3 in scala arriviamo a map22 (siamo troppo avanti :-) scherzi a parte sono 22 perchè in java possiamo definire metodi fino ad un massimo di 22 parametri).

    Quindi se cambiano i requisiti ed a Person viene aggiunto un campo “email” da validare dobbiamo:

    1. aggiungere il campo sul product type
    2. aggiungere il parametro curried alla constructor funcion
    3. definire eventuali nuovi validatori
    4. usare liftA3 invece di liftA2
    5. usare il terzo validatore in validatePerson

    Meccanico e dal punto 2 in poi guidato dal compilatore, per questo lo vedo articolato, ma non complesso. Una volta conosciute bene le astazioni. :-)

    Nel nostro caso le validazioni sono N e sullo stesso campo devo poter fare piu’ validazioni (ad. es. la stringa e’ una data e la data e’ maggiore di oggi).

    ti fai una funzione di validazione da stringa a data poi una da data a data in pratica ti fai le singole “check” slegati da cosa andrai a creare

    function validateNotEmpty(input: string): Validation<NonEmptyArray<string>, string>
    function validateGtToday(input: date): Validation<NonEmptyArray<string>, date>  
    

    dopo la validatione della data per la solution da stringa a data è solo la composizione dei check (faccio ancora un typescript “a braccio”)

    function validateDate(input: string): Validation<NonEmptyArray<string>, date> 
                  validateNotEmpty.flatMap(validateGtToday)
    

    flatMap, aka composizione monadica, perchè prima devi poter passare da stringa a data e solo se riesci devi vedere se la data è maggiore di oggi, altrimenti non fare niente.

    [ema] E in uscita vogliamo:

    export type SelectedSolution = {
      from: Station,
      to: Station,
      outbound: TrainDateTime,
    }
    export type TrainDateTime = {
      date: Date,
      time: Time
    }
    

    la validazione della TrainDateTime è una composizione applicativa di validateDate e validateTime (che non ho implemetato…)

    function validateTrainDateTime(input: Record<string, string>): Validation<NonEmptyArray<string>, TrainDateTime> 
        createTrainDateTimeLiftata(validateDate(input['date']), validateTime(input['time']))
    

    idem per Station e SelectedSolution, comporre le altre funzioni (che erano a sua volta composte da altre funzioni)

    function validateStation(input: string): Validation<NonEmptyArray<string>, Station>
        validateNotEmpty(input).map(createStation)
    
    function validateSelectedSolution(input: Record<string, string>): Validation<NonEmptyArray<string>, SelectedSolution>  
        createSelectedSolutionLiftata(validateStation(input['from']),  validateStation(input['to']), validateTrainDateTime(input))  
    

    :-)

  • Arcade in Codiceplastico

    In CodicePlastico abbiamo sempre cercato modi per creare un ambiente piacevole in cui passare la giornata lavorativa. Sappiamo benissimo che il nostro lavoro di programmatori ha parecchi aspetti negativi legati principalmente al poco movimento e al prolungarsi delle ore passate a concentrarsi su un problema. Per questo, senza imporre regole o obblighi, nel tempo ci siamo inventati strumenti e metodi per migliorare la situazione. Abbiamo iniziato anni fa con le freccette, “sport” al quale ci dedichiamo giornalmente con sfide all’ultimo 20 triplo! Da un annetto circa abbiamo introdotto anche l’acquisto aziendale di frutta (esistono fruttivendoli che vendono su internet!) e non ci facciamo mai mancare un po’ di frutta di stagione da consumare durante i meeting interni o durante le pause. Ma la grande novita’ di questi gioni e’ lui:

    Eccolo

    Ci siamo regalati un cabinato brandizzato CodicePlastico per staccare la mente dal codice e ritornare ai tempi delle scuole medie con i videogiochi del passato.

    Insomma le giornate lavorative sono diventate piu’ divertenti e tra un test verde e uno rosso abbiamo tempo per qualche sfida!

  • Lens in javascript

    Qualche settimana fa per un progetto che stiamo sviluppando abbiamo dovuto interfacciarci con le API di wordpress per recuperare alcune informazioni dai post pubblicati su un blog. La struttura dati restituita dalle API di wordpress e’ abbastanza nested e ogni livello potrebbe non essere presente, questo comporta che prima di accedere ad un attributo figlio va controllato che il padre non sia undefined.

    Per andare sul concreto questa e’ una parte del json che le API restituiscono:

    const obj = {
      ...
      "media_details": {
        "width": 913,
        "height": 1345,
        "file": "2017\/07\/immagine1.jpg",
        "sizes": [{
          "thumbnail": {
            "file": "immagine1-150x150.jpg",
            "width": 150,
            "height": 150,
            "mime_type": "image\/jpeg",
            "source_url": "http:\/\/blog.my-site.com\/wp-content\/uploads\/2017\/07\/immagine1-150x150.jpg"
          },
        },{}]
      }
    }
    

    L’attributo che andava estrapolato e’ l’url dell’immagine thumbnail

    La prima implementazione che ci e’ venuta in mente e’ questa:

    if (obj.media_details) {
      if (obj.media_details.sizes) {
        if (obj.media_details.sizes && obj.media_details.sizes.length > 0){
          if (obj.media_details.sizes[0].thumbnail.source_url) {
            img = obj.media_details.sizes[0].thumbnail.source_url
          }
        }
      }
    }
    

    NB: sto andando direttamente sull’indice 0 dell’array thumbnails per semplificare l’esempio

    Non e’ sicuramente un’implementazione elegante…ma funziona. Possiamo fare di meglio? A parte fare un po’ di microrefactoring che non porta molto lontano possiamo provare ad usare un costrutto della programmazione funzionale: le Lens (o lenti in italiano). Le lens sono delle functional reference ad un attributo di una struttura dati che permettono di leggerne il valore o di settarne il valore. Librerie come ramda.js hanno un set di funzioni pronte all’uso e il codice sopra puo’ essere riscritto in questo modo:

    const imgLens = R.lensPath(['media_details', 'sizes', 0, 'thumbnail', 'source_url'])
    img = R.view(imgLens, obj)
    

    Decisamente piu’ semplice, leggibile e mantenibile. La funzione lensPath construisce il percorso per raggiungere l’attributo, la funzione view ne estrae il valore.

    Le Lens sono molto utili anche per cambiare il valore di un attributo di una struttura dati tipo quella sopra tramite la funzione R.set di ramda.

    Supponiamo di voler modificare l’attributo ricercato prima tramite la lens per ottenere un nuovo obj. Senza il costrutto lens dovremmo scrivere una funzione simile a quella usata per il get (anche se sarebbe meglio che la modifica crei un nuovo oggetto). Con le lens l’operazione di set diventa:

    const newObj = R.set(imgLens, 'nuovo_url', obj)
    

    Le Lens sono un costrutto molto utile anche se poco conosciuto e spesso annegato in librerie tipo Ramda.js. La cosa interessante oltre alla semplificazione che portano al codice e’ la peculiarita’ di essere funzioni che possono essere riutilizzate in varie parti del codice e che si possono comporre con altre per ottenere funzionalita’ piu’ complesse, cosa che si sposa benissimo con altri costrutti della programmazione funzionale.

  • Reactjs Redux pattern

    React and Redux

    ReactJs e’ diventato in breve tempo una delle più diffuse librerie per sviluppare applicazioni web. Ho usato il termine libreria per marcare la differenza che React ha con framework piu’ esaustivi quali ad esempio AngularJS. Proprio per il fatto che ReactJs e’ una libreria, il suo scope e’ legato esclusivamente alla generazione delle View di un ipotetico framework MV*. Questo ha un duplice vantaggio: ci permettere di scegliere quale altra libreria affiancare a ReactJs per l’implementazione delle nostre applicazioni (chiamata alle api, servizi, utilities, ecc…) e lascia liberta’ di disegnare l’architettura più adatta all’applicazione che si sta sviluppando. Quindi non siamo vincolati ad usare architetture complesse per semplici applicazioni, ma possiamo usare React e poco altro per piccole applicazioni e usare Flux e Redux per applicazioni più complesse. Redux e’ oggi lo standard di fatto anche se talvolta può essere troppo complesso, prolisso o “pesante” per applicazioni di medie dimensioni. Redux resta comunque una ottima implementazione basata su pochi chiari principi che rendono l’applicazione semplice, testabile e manutenibile. In questo breve articolo mi piacerebbe mostrarvi un’implementazione di redux che usiamo in CodicePlastico che e’ completamente aderente ai principi di Redux ma che rimane più semplice e meno prolissa.

    I principi di redux sono:

    • Esiste un unico stato: i componenti di react non usano this.state ma lo stato viene memorizzato esternamente al componente e gli viene passato dall’esterno sotto forma di proprietà.
    • Lo stato e’ read-only: l’unico modo di cambiare lo stato e’ quello di inviare un’azione e far si che chi riceva l’azione crei il nuovo stato
    • La trasformazione dello stato e’ fatto da funzioni pure

    Come potete vedere i principi sono molto semplici e Redux di fatto non fa altro che fornire alcuni moduli che semplificano la loro applicazione.

    Un po’ di codice

    Partiamo da un esempio implementato con l’uso dello stato internamente al componente per poi rifattorizzarlo verso un’architettura in puro stile redux. Il componente e’ questo:

    class MyCounter extends React.Component {
      constructor() {
    	  super()
        this.state = { counter: 0 }
      }
      plusOne() {
        this.setState({counter: this.state.counter + 1})         
      }
      render() {
        return (
         <div>
          <div>Click count: {this.state.counter}</div>
          <button onClick={this.plusOne.bind(this)}>Add 1</button>
        </div>)
      }
    }
    

    Questo componente mostra un bottone che se cliccato incrementa il valore del contatore visualizzato sopra il bottone stesso. L’implementazione e’ quella classica con l’uso dello stato per memorizzare il valore del contatore. Pur non essendoci nulla di male in questa implementazione (specialmente per il caso in questione) in casi più complessi la gestione dello stato non si limita ad una sola chiamata a setState ma a diverse chiamate in tempi diversi e con logiche (e molti if).

    Il primo principio di redux sottintende che lo stato sia tenuto fuori dal componente e che venga passato al componente MyCounter attraverso l’uso delle props. Possiamo quindi introdurre un componente esterno che “wrappa” il nostro counter:

    class WithState extends React.Component { 
      constructor() {
    	  super()
        this.state = { counter: 0 }
      }
      plusOne() {
        this.setState({counter: this.state.counter + 1})         
      }
      render() {
        return (
          <MyCounter value={this.state.counter} onPlusOne={this.plusOne.bind(this)} />
         )
      }
    }
    
    class MyCounter extends React.Component {
      render() {
        return (
         <div>
          <div>Click count: {this.props.value}</div>
          <button onClick={this.props.onPlusOne}>Add 1</button>
        </div>)
      }
    }
    

    In questo modo il componente MyCounter non fa più uso dello stato e potrebbe essere scritto sotto forma di funzione semplificando ulteriormente la sua implementazione:

    function MyCounter({value, onPlusOne}) {
       return (
         <div>
          <div>Click count: {value}</div>
          <button onClick={onPlusOne}>Add 1</button>
        </div>)
    }
    

    Ma abbiamo un problema. Il componente WithState non e’ riutilizzabile per altri componenti avendo al suo interno conoscenza di alcune cose:

    • Il componente che sta “wrappando”
    • La forma dello stato
    • La funzione che modifica lo stato (plusOne)

    Vediamo come risolvere questi tre problemi. Partiamo dal terzo punto: dobbiamo rimuovere la logica di modifica dello stato dal componente WithState Nei principi di redux si dice che per modificare lo stato bisogna scatenare un’azione che verra’ gestita da funzioni chiamate reducer. L’idea di inviare azioni proviene dall’architettura unidirezionale di Flux che ha gettato le basi anche per redux. L’idea e’ quella di introdurre un dispatcher che si occupa di inoltrare le richieste di azioni a tutti coloro che sono interessati. Una semplicissima (e semplificata) implementazione di un dispatcher può essere questa:

    const dispatcher = {
      subscribers: [],
      register(subscriber) {
        this.subscribers.push(subscriber)
      },
      dispatch(action) {
        this.subscribers.forEach(s => s(action))
      }
    }
    

    Il suo ruolo e’ quello di ricevere una richiesta di dispatch da parte di un componente e inoltrare la richiesta a tutte le funzioni interessate all’azione. Il reducer prenderà’ l’azione (e lo stato corrente) e ritornerà il nuovo stato. Una prima idea potrebbe essere quella di lasciare al componente WithState l’applicazione del reducer:

    function counterReducer(state, action) {
      return {counter: state.counter + action.value}  
    }
    
    class WithState extends React.Component { 
      constructor() {
    	  super()
        this.state = { counter: 0 }
      }
      componentWillMount() {
        dispatcher.register(action => {
          const nextState = counterReducer(this.state, action)
          this.setState(nextState)
        })
      }
      render() {
        return (
          <MyCounter value={this.state.counter}  />
         )
      }
    }
    
    function MyCounter({value, onPlusOne}) {
       return (
         <div>
          <div>Click count: {value}</div>
          <button onClick={() => dispatcher.dispatch({value: 1})}>Add 1</button>
        </div>)
    }
    

    In questo modo abbiamo portato all’esterno la logica di modifica dello stato. Ora non ci resta che generalizzare portando fuori la definizione dello stato iniziale, il componente wrappato e il riferimento alla funzione reducer (che ora e’ cablata in WithState). Per estrapolare quelle informazioni possiamo scrivere una funzione che prende i 3 parametri (nome del componente, stato iniziale, la funzione che modifica lo stato) e ritorna il nuovo componente WithState opportunamente configurato.

    function counterReducer(state, action) {
      return {counter: state.counter + action.value}
    }
    
    function createWithState(WrappedComponent, reducer, INITIAL_STATE) {
      return class WithState extends React.Component { 
        constructor() {
    	    super()
          this.state = INITIAL_STATE
        }
        componentWillMount() {
          dispatcher.register(action => {
            const nextState = reducer(this.state, action)
            this.setState(nextState)
          })
        }
        render() {
          return (
            <WrappedComponent {...this.state}  />
          )
        }
      }
    }
    
    function MyCounter({counter}) {
       return (
         <div>
          <div>Click count: {counter}</div>
          <button onClick={() => dispatcher.dispatch({value: 1})}>Add 1</button>
        </div>)
    }
         
    const MyComponent = createWithState(MyCounter, counterReducer, {counter: 0})
    

    Con questo ultimo giro di refactoring il componente WithState e’ completamente all’oscuro del componente MyCounter ed e’ in grado di fare da wrapper a qualsiasi altro componente. Ciao’ che varia e’ il componente wrappato, il reducer che si occupa di creare il nuovo stato, e la forma dello stato. Questi sono i tre parametri della funzione createWithState.

    Questa implementazione e’ molto semplificata ma con un pizzico di sofisticazione in più si riesce a scrivere un modulo pronto ad essere utilizzato in produzione e a supportare la casistica di applicazioni molto complesse. La nostra implementazione la trovate qui: t-redux e se date un’occhiata al codice ritroverete tutti i concetti spiegati in questo articolo.

    Redux e’ leggermente più complesso ha il concetto di store, di selectors e poco altro ma la sua implementazione, almeno nei concetti e principi e molto simile a quanto presentato in questo post. Una cosa che mi piace sempre ricordare e’ che e’ molto piu’ importante imparare i principi e i pattern utilizzati invece che imparare ad usare una libreria, questo perché i principi restano e le librerie passano (soprattutto nel mondo javascript). Ad esempio Redux implementa molti principi utilizzati in architetture basate su eventsourcing, CQRS e programmazione funzionale, inventate anni fa….come al solito non si inventa quasi mai nulla, si adattano e riusano vecchi concetti.

  • Build your ASP.NET MVC app with Grunt

    Grunt (and Gulp) is a marvellous tool to automate your development and build pipeline but until few months ago it was directly tied to the node environment. But since Microsoft is becaming more open source, some developers started to develope Grunt tasks to support the .NET pipeline. So I tried to combine a set of developer tasks to automate an ASP.NET MVC/WebApi project….and it works! I was able to watch the project folder and to start a set of tasks on every change to a file so that I can rebuild the app, publish it in a folder and refresh the browser to see what’s changed.

    The project structure is:

    /src
    |-- MyProject.sln
    |-- package.json
    |-- Gruntfile.js
    |-- /MyProject
           |-- /App_Start
           |-- /assets
           |-- /Controllers
           |-- /Properties
           |-- /Views
           |-- MyProject.csproj
    

    Task by task I created the Gruntfile. Here is the list of task that I used:

    grunt.loadNpmTasks('grunt-msbuild');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-iisexpress');
    grunt.loadNpmTasks('grunt-contrib-compass');
    grunt.loadNpmTasks('grunt-contrib-jshint');
    grunt.loadNpmTasks('grunt-contrib-uglify');
    
    • grunt-msbuild is used to compile the project. I added a watcher that monitor all the csharp files and everytime one of these change it runs the msbuild task.
    • grunt-iisexpress is used to run the IISExpress local server on the web folder so that we can see the result of our changes
    • grunt-contrib-compass is for compiling the SCSS/SASS files into CSS
    • grunt-contrib-jshint simply analyze the javascript files
    • grunt-contrib-uglify is used to minify the javascript files

    The full Gruntfile.js is available as a gist feel free to use it and modify on your needs.

    Consider that this works without Visual Studio so if you prefer you can use a lighweight editor like SublimeText (with Omnisharp)