November 2013 Archives

Sun Nov 10 22:12:04 CET 2013

Anticipazioni

Ho iniziato a scrivere la prossima versione di supplier.

Le API saranno un poco differenti. Niente di rivoluzionario, solo i nomi delle funzioni che non erano certo il massimo (tnx to Mauro).

All'array dinamico, che si chiamerà ArrayList, dovrei affiancare un LinkedList, ancora tutto da fare...


Posted by athos | Permanent link | File under: supplier

Sat Nov 2 17:55:37 CET 2013

Introduzione a Supplier 0.2

Qualche parola sul perché, secondo me, il supplier è veramente utile e non solo comodo come "scorciatoia sintattica".

Supponiamo di scrivere una funzione che, dato in input un array di stringhe, restituisce un altro array di stringhe contenente le stesse oppure, nel caso in cui soddisfino una qualche condizione, altre. Per esempio, se le stringhe sono più lunghe di 10 caratteri (per semplicità consideriamo solo stringhe ASCII per non gestire il problema della codifica) le raddoppia.

Dovendo implementare un metodo Java su queste specifiche, al di là delle variazioni sintattiche che potrebbero rendere il programma più bello, si potrebbe scrivere qualcosa di questo tipo.

static String[] transform(String[] inputa) {
    String[] outputa = new String[inputa.length];
    for (int i = 0; i<inputa.length; ++i) {
        String s = inputa[i];
        if (10<s.length())
            outputa[i] = s + s;
        else
            outputa[i] = s;
    }
    return (outputa);
}

Quello che voglio sottolineare è che non tutte le stringhe vengono ricopiate. Per le stringhe corte, che magari sono la maggioranza, viene semplicemente condiviso il riferimento.

Se dovessi scrivere una funzione equivalente in C potrei avere dei problemi! dovrei STRcopiare tutto con grande spreco di memoria e questo per un motivo molto semplice: perché è la struttura stessa che ci fornisce informazioni su come disallocare.

Ho evidenziato l'affermazione precedente perché è quello che io considero "il male"! Quello che voglio risolvere per ritrovare il piacere di programmare in C!

Con il supplier la scriverei nel seguente modo.

char **transform(void *supplier, char **inputv, int inputc) {
    char **outputv;
    int i, j;
    char *cp;
    outputv = (char **) s_supply(supplier, (int) (inputc*sizeof (char *)));
    if (!outputv)
        return (NULL);
    for (i = 0; i<inputc; ++i) {
        j = (int) strlen(inputv[i]);
        if (10<j) {
            cp = (char *) s_supply(supplier, 2*j+1);
            if (!cp)
                return (NULL);
            strncpy(cp, inputv[i], j);
            strcpy(cp+j, inputv[i]);
            outputv[i] = cp;
        }
        else
            outputv[i] = inputv[i];
    }
    return (outputv);
}

Posso non restituire la dimensione perché è uguale a quella dell'input.

Il secondo array esiste fino a quando il supplier non viene distrutto, non necessariamente il primo, a meno che non venga costruito nel medesimo supplier in tutto oppure in parte... e notare che nelle condizioni di errore non bisogna fare nulla! non male!

La logica è esattamente la stessa del primo esempio. Si vede ancora di più se uso le funzioni si supporto presenti nella libreria.

 char **transform(void *supplier, char **inputv, int inputc) {
    void *output;
    int i;
    char *cp;
    output = v_new(supplier, 0);
    if (!output)
        return (NULL);
    for (i = 0; i<inputc; ++i) {
        cp = inputv[i];
        if (10<strlen(cp)) {
            cp = buffer_strconcat(supplier, cp, cp);
            if (!cp)
                return (NULL);
        }
        if (!v_add(output, cp))
            return (NULL);
    }
    return ((char**) v_elements(output));
}

Qui uso anche memoria per l'array dinamico che è comunque contenuto nel supplier e quindi potrei anche restituire (invece dell'array dei suoi valori). Per comodità, in quanto contiene anche l'informazione della propria dimensione.

Notare che con il supplier posso anche impacchettare più risultati e restituirli (come potrei fare in Java) senza utilizzare quindi parametri per i valori di ritorno.

In poche parole, gestendo uno o più supplier possiamo programmare in C (quasi) con la stessa disinvoltura del Python... un bel risultato, no?


Posted by athos | Permanent link | File under: supplier