venerdì 22 maggio 2015

Chi ha ucciso il software libero?

Sul banco degli imputati porto, con mia grande soddisfazione, il metodo induttivo.

Il metodo induttivo è quel processo mentale che attraverso la valutazione dei casi particolari noti tenta di stabilire una legge universale per predire eventi ignoti (e futuri).

Non so se avete mai sentito parlare del tacchino induttivista...

Un tacchino, in un allevamento statunitense, decise di formarsi una visione del mondo scientificamente fondata.

Il tacchino induttivista che riceveva il pasto tutte le mattine alle ore 9.00, trasse la conclusione che ogni mattina, alle ore 9.00, avrebbe ricevuto da mangiare, per tutta la vita, conclusione che si dimostrò falsa solo il giorno della vigilia di Natale, quando, invece di venir nutrito, fu sgozzato.

Morale della favola: una asserzione non è provata definitivamente da milioni di conferme ma può essere rigettata definitivamente per una sola confutazione.

Einstein avrebbe detto che nessuna quantità di esperimenti potrà dimostrare che ho ragione; un unico esperimento potrà dimostrare che ho sbagliato.

Quindi la pretesa del metodo induttivo è praticamente insostenibile. Con esso non si creano leggi universali, ma dogmi. E si finisce per cristallizzare ciò che più di buono abbiamo: Le idee.


Chi ha ucciso il software libero? Le procedure lo hanno ucciso. Le procedure che, a torto, riteniamo infallibili.

Il mondo nel quale viviamo è un mondo che non capiamo ma che sosteniamo, con arroganza, di capire. Un mondo in cui la nostra vita è plasmata da quanto è incerto e altamente dirompente piuttosto che da un corso di eventi semplice, ben pianificato e nella media. In verità, cercando di controllare gli eventi, attraverso la pianificazione, la programmazione ed elaborando strategie per conquistare il mondo, stiamo aumentando i fattori di alta instabilità, rendendoci più fragili. Più si perde tempo a discutere, a parlare del niente, a pianificare migrazioni, a sensibilizzare le coscienze, a studiare come rendere appetibile un sistema operativo open source alla gente, più sprofondiamo nel baratro.

Lo ha ucciso chi lo avrebbe dovuto promuovere. Lo ha ucciso chi di software libero si riempie la bocca.

Fare, adattarsi, essere, invece di prevedere, pianificare, teorizzare. La verità è che qui, sotto sotto, nessuno si vuole sporcare le mani, e allora si perde tempo a sprecare fiato, inutilmente.

Nassim Taleb, famoso epistemologo, in un suo libro, Il cigno nero, racconta la storia immaginaria di una scrittrice  e del suo libro pubblicato sul web che viene scoperto da una piccola casa editrice. Questa pubblica il libro, che diventa un bestseller internazionale. La piccola casa editrice si trasforma così in una grande società, e la scrittrice è diventata famosa.

Il mondo è governato dall'improbabile. Noi non siamo nelle condizioni di conoscere il corso degli eventi. È inutile pianificare, aumenteremmo solo i fattori di alta instabilità. Ce lo dimostrano quotidianamente gli economisti, che studiano studiano e studiano, ma la crisi economica si fa sempre più nera, la disoccupazione aumenta e le fabbriche chiudono.

Ma c'è un altro fattore per cui spendere due parole: Gli esperti. La forza conferita a un tecnico o a uno scienziato da un diploma o una laurea ha un effetto dirompente e incontrollabile. Sempre Taleb, in un altro suo libro, L'antifragile, fa presente che  i ponti romani costruiti con il sapere pratico (tipico degli imprenditori), sono ancora lì, a testimoniarci la loro superiorità di approccio rispetto al sapere accademico acquisito sui banchi di scuola.

E poi mi viene da pensare alla Salerno-Reggio Calabria... vabbe'.

Anche la globalizzazione, frutto di procedure sofisticate, pace all'anima sua, è fallita, dobbiamo farcene una ragione. Ciò che resta è il lavoro dell'artigiano. Ciò che resta sono i sogni da realizzare partendo dalla propria realtà territoriale e, soprattutto, sporcandosi le mani.

Il 2016 sarà l'anno di Linux? Da che punto guardi il mondo tutto dipende, diceva una nota canzone.


mercoledì 20 maggio 2015

Software libero, ma di cosa stiamo parlando?

Il solipsismo è la credenza secondo cui tutto quello che l'individuo percepisce viene creato dalla propria coscienza. Di conseguenza, tutte le azioni e tutto quello che fa l'individuo è parte di una morale prestabilita dal proprio io. L'io che crea il mondo. E questo avviene in maniera trasversale, nel senso che si prescinde da classi e ceti sociali.

L'individuo, nell'accezione peggiore del termine, diviene il centro dell'universo. O, forse, più che di individuo dovremmo parlare dell'ego. Di una sorta di patologia grave dell'io. Un egocentrismo malato e subdolo, schizofrenico e dirompente.

Siamo tutti figli di Cartesio. Per Cartesio, nell'atto in cui io penso, non posso dubitare del fatto che "io esisto". Stabilito questo però risultava difficile, se non impossibile, per Cartesio, determinare qualche conoscenza certa che andasse al di là del Cogito, dell'io penso. Quindi l'unica realtà è l'io che pensa. Cogito, dunque sono.

Siamo nell'ambito dell'autoreferenzialità patologica dell'io. Io, io e solo io. Fateci caso quando parlate con qualcuno, provate a contare quante volte pronunciate il pronome personale "io" in dieci minuti di conversazione.

E siccome l'io è l'unica realtà esistente, tutto il resto diviene un prolugamento di me stesso: Figli, amici, coniuge, gli altri.

Questa è la vera malattia di cui è affetto l'occidente. Ogni cosa altro non è che il prolungamento del proprio io malato. Allora posso decidere di privatizzare l'acqua, posso decidere di destabilizzare politicamente interi popoli per poterli poi meglio depauperare, spogliarli delle proprie ricchezze. Alla fine non faccio male a nessuno, se non a me stesso essendo ogni cosa un prolugamento del mio io. Mi posso permettere di considerare finanche i miei figli come parte di me stesso. Figli mai svezzati e cordoni ombelicali ancora da recidere.

Inquinare, rubare, arroganza, tracotanza non vengono sentiti come immorali, come comportamenti inopportuni. Questo perchè ciò che è giusto e ciò che è ingiusto è stabilito dall'io malato. E siccome gli altri non esistono se non li penso, sono miei prodotti, da usare e gettare come e quando voglio.

In questo contesto parlare di software libero è quasi assurdo. Il software libero pressuppone una base comunitaria. E questa idea, anche a livello inconscio, va a cozzare con le categorie mentali impregnate di solipsismo.

Provate ad osservare un fenomeno. Se si cerca di creare una comunità intorno ad un'idea, in realtà non si crea una comunità, ma un'arena dove i vari "io" lottano per la supremazia. E questo accade perchè ognuno vede gli altri come il prolungamento del proprio io. Ed è guerra senza esclusione di colpi.

L'idea comunitaria del software libero è solo apparente. Assistiamo a progetti impermeabili e portati avanti da poche persone. Tutti, o quasi, rilasciano la ricetta, ma nessuno, o quasi, ti dice la procedura per far interagire i vari elementi e arrivare al dolce. Perchè dire agli altri come si fa se gli altri altro non sono che il prolungamento di me stesso?

Ma anche nel momento in cui rendi aperto un progetto, nel senso che permetti ad altri di imbarcarsi, primo o poi ti accorgi che la gente non viene per aiutarti ma per sovvertire il progetto stesso. Non si tratta di mettersi a disposizione per migliorare un qualcosa, ma ancora una volta si innesca la guerra spietata di supremazia. Ancora una volta è una guerra per la supremazia del proprio io.

Stando così le cose, non dobbiamo lamentarci se il software proprietario prenderà sempre più piede. Anche qui sembrerebbe semplice capire il perchè. Perchè nelle società commerciali, nelle multinazionali non vige una base comunitaria, nell'accezione genuina del termine, ma una reductio ad unum. In altri termini, in queste realtà c'è un capo. E tutti gli altri subalterni. Per contratto si accetta di essere il prolungamento del capo.

"La comunità anzitutto non ha una base contrattuale: essa fiorisce «da germi dati, quando le condizioni sono favorevoli; al suo interno si forma una gerarchia naturale basata sulle differenze di età, forza e saggezza, ma domina un atteggiamento di benevolenza e rispetto reciproci." [Tönnies, sociologo.]
 



Software libero, ma di cosa stiamo parlando? Intelligenti pauca, ovverosia alle persone intelligenti poche parole...

sabato 16 maggio 2015

Un semplice esperimento di Intelligenza Artificiale

Salve!

Non so se ricordate i vecchi film di fantascienza, quelli dove il ragazzo smanettone di turno inizia a dialogare attraverso il pc con una presenza sconosciuta.

Ecco, grazie a Python ho cercato di rivivere quelle atmosfere creando un programmino che, come un bambino, è capace di apprendere e ricordare. In pratica, il programma chiede ciò che non sa e non lo dimentica più.

Presto, una volta sistemato meglio, pubblicherò anche il codice. :)


A presto! 

sabato 9 maggio 2015

Modern C++ - Classi base e derivate

Benritrovati sulle pagine del corso di Modern C++.

Nelle puntate precedenti abbiamo visto cosa sono le classi e come vengono istanziati gli oggetti.

Oggi vediamo come realizzare un albero genealogico di classi ed oggetti: per prima cosa, torniamo all'esempio della nostra automobile.
Una automobile é caratterizzata da un predefinito motore (la cilindrata), da un numero di ruote, da un numero di porte e cosí via. Le varie specializzazioni di una auto potrebbero essere: macchina sportiva, station wagon, ecc. Una auto é un mezzo di locomozione: suoi correlati possono essere furgoni, autobus, motociclette, barche, aerei.

Pertanto, ha senso definire la seguente struttura:

  • Veicolo
    • VeicoloTerrestre
      • Automobile
      • Motocicletta
      • Bus
      • Tir
      • Furgone
      • Treno
    • VeicoloNavale
      • Nave
      • Sommergibile
    • VeicoloAereo 
      • Aereo
      • Elicottero
Cosa accomuna queste classi tra loro? Tutti questi tipi di veicoli sono caratterizzati da un motore che li fa muovere, sia esso elettrico o termico. Un'altra caratteristica che accomuna tutti i veicoli tra loro puó essere il colore, la velocitá massima e appunto il tipo di motore (termico o elettrico).

Prima di passare alla realizzazione pratica, pensiamo ad alcuni dettagli:
  • I veicoli sopracitati funzionano tutti allo stesso modo?
  • I veicoli sopracitati sono dotati tutti di porte?
Teoricamente si, ma praticamente no: un aereo ed un sommergibile possono accelerare e frenare, ma la modalitá con cui frenano od accelerano cambia drasticamente. Pertanto, l'azione di frenare ed accelerare é astratta, dipendente dall'implementazione.

In C++ (ma anche in altri linguaggi OOP) vengono in soccorso i metodi e le classi virtuali o astratte: a seconda di come sono dichiarate le funzioni e se esse hanno o meno una definizione (ovvero, un corpo), esse vengono dette virtual o pure virtual. I metodi virtual hanno una implementazione che puó esser sovrascritta oppure utilizzata cosí com'é dalle classi derivate. I metodi pure virtual non hanno una propria implementazioni e vengono seguite da un = 0: in questo caso, le classi non possono avere una loro istanza, ma vanno obbligatoriamente derivate e i loro metodi vanno definiti.
Riferendoci all'esempio, non posso creare un oggetto Veicolo, ma devo per forza creare un oggetto Aereo oppure Sommergibile, in cui definisco come questi oggetti possono accelerare o frenare.

Ecco come possiamo trasformare questi concetti in C++:


//Vehicles.h

#ifndef VEHICLES_H
#define VEHICLES_H

//Definisco il tipo di motore
enum class EngineType { Undefined, Electric, Termic };

//Definisco il tipo di Vehicle
enum class VehicleType { Undefined, Terrestrial, Naval, Aerial };

class Vehicle
{
  public:
    virtual ~Vehicle(){} //distruttore

    virtual EngineType getEngineType() const final
    {
       return m_engine;
    }

    virtual VehicleType getVehicleType() const final
    {
       return m_type;
    }

    virtual int getSpeed() const final
    {
       return m_speed;
    }

    virtual void accelerate() = 0;

    virtual void decelerate() = 0;

  protected:
    int m_speed{0};
    EngineType m_engine{EngineType::Undefined};
    VehicleType m_type{VehicleType::Undefined};
};

class VehicleTerrestrial : public Vehicle
{
  public:
    VehicleTerrestrial()
    {
        m_type = VehicleType::Terrestrial;
    }

    virtual ~VehicleTerrestrial(){}

    virtual int wheels() const final
    {
       return m_wheels;
    }

  protected:
    int m_wheels{0};
};

class VehicleNaval : public Vehicle
{
  public:
    VehicleNaval()
    {
        m_type = VehicleType::Naval;
    }

    virtual ~VehicleNaval(){}

    virtual bool hasBackupBoats() const final
    {
       return m_backup_boats;
    }

  protected:
    bool m_backup_boats{false};
};

class VehicleAerial : public Vehicle
{
  public:
    VehicleAerial()
    {
        m_type = VehicleType::Aerial;
    }
    virtual ~VehicleAerial(){}

    virtual bool hasStorageRoom() const final
    {
       return m_storage;
    }

  protected:
    bool m_storage{false};
};

#endif // VEHICLES_H


Finora abbiamo realizzato la "prima generazione" del nostro albero genealogico. Come potete osservare, non abbiamo un costruttore (le classi sono astratte, non possono essere creati oggetti di tipo Veicolo o VeicoloNavale) ma solo un distruttore virtuale e metodi virtuali e puramente virtuali.

Il distruttore e' virtuale perché ci permette di poter modificare gli oggetti di classi derivate da Veicolo attraverso i puntatori. Infatti, potremo creare una Automobile nel seguente modo:



Veicolo *automobile = new Automobile();
delete automobile;  //senza il virtual destructor non funzionerebbe!
std::unique_ptr m_veicolo(new Automobile());
std::vector veicoli;
Procediamo con la definizione di una automobile. Le implementazioni degli altri veicoli vengono lasciate a voi lettori come esercizio:

//Car.h

#ifndef CAR_H
#define CAR_H

#include "Vehicles.h"

class Car : public VehicleTerrestrial
{
  public:
    Car()
    {
        m_engine = EngineType::Termic;
    }

    virtual ~Car(){} //distruttore

    void accelerate() override
    {
      m_speed += m_accel; //definiamo una accelerazione lineare qui
    }

    void decelerate() override
    {
      m_speed -= m_accel;
    }

  private:
    int m_accel{20}; //20 m/s
    int m_doors{4};
    int m_seats{5};
};

#endif // CAR_H

Come potete vedere, posso accedere dalla mia classe Car (Automobile) al membro m_engine, che é protetto. Se esso fosse stato private, avrei potuto modificarlo solo tramite una funzione protected o public della classe base.

Trovate l'esempio nel mio repository su GitHub: https://github.com/blackibiza/ModernCpp che potete liberamente scaricare e modificare a vostro piacimento per sperimentare.

Alla prossima :)