La programmation fonctionnelle

pour les développeuses·eurs web

@ThibaudDauce | https://thibaud.dauce.fr
Quantic Telecom

Co-fondateur de Quantic Telecom

https://www.quantic-telecom.net
Formations Laravel

Formations Laravel

https://www.formations-laravel.fr

La programmation fonctionnelle

pour les développeuses·eurs web

@ThibaudDauce | https://thibaud.dauce.fr

Euh… J'en fais déjà, non ?


                    // Get invoices
                    $api = new API()
                    $result = $api->post('/invoices', []);
                    $invoices = json_decode($result);

                    // Get students
                    $customers = Customer::all();
                    $students = [];
                    foreach ($customers as $customer) {
                        if ($customer->isStudent()) {
                            $students[] = $customer;
                        }
                    }
                

Euh… J'en fais déjà, non ?


                    // Get invoices
                    $invoices = getInvoices();

                    // Get students
                    $students = getStudents();
                

Votre serveur web est une fonction

Requête HTTP → Réponse HTTP


                // 1. Vérifiez que la personne est connectée
                // 2. Enregistrer le début du traitement de la requête
                // 3. Faire ce que tu as à faire
                //    (retourne une chaîne de caractères)
                // 4. Transformer la chaîne de caractères en réponse HTTP
                // 5. Enregistrer le temps de traitement grâce à 2.
                
                $tasks = [
                    new CheckAuthentication,
                    new LogRequestTime,
                    new TransformToResponse,
                ];
                

Pipelines / Middlewares


                    (new Pipeline)
                        ->send(Request::createFromGlobals())
                        ->through([
                            new CheckAuthentication,
                            new LogRequestTime,
                            new TransformToResponse,
                        ])
                        ->then(function ($request) {
                            return "Welcome {$request->session('customer')}!";
                        });
                    
                

                    class CheckAuthentication
                    {
                        public function handle($request, $next)
                        {
                            if (! $request->session()->has('customer')) {
                                return new RedirecResponse('/login', 302);
                            }

                            return $next($request);
                        }
                    }
                

                    class LogRequestTime
                    {
                        public function handle($request, $next)
                        {
                            $start = microtime(true);

                            $response = $next($request);

                            $time = microtime(true) - $start;
                            $text = "Request {$request->requestUri} took {$time}s \n";
                            file_put_content('timings.txt', $text, FILE_APPEND);

                            return $response;
                        }
                    }
                

                    class TransformToResponse
                    {
                        public function handle($request, $next)
                        {
                            $response = $next($request);

                            if ($response instanceof Response) {
                                return $response;
                            }

                            return new Response((string) $response, 200);
                        }
                    }
                

                    function ($request) {
                        return "Welcome {$request->session('customer')}!";
                    }
                

Votre serveur web est une fonction

(Le retour)

  1. Requête HTTP → Identifiant client
  2. Identifiant client → Client
  3. Client → Total des comptes
  4. Total des comptes → Page HTML
  5. Page HTML → Réponse

Collections


                    function getMonthlyMeanRevenueForStudents() {
                        $customers = Customer::all();
                        $totalRevenue = [];
                        $counts = [];

                        foreach($customers as $customer) {
                            if ($customer->isStudent()) {
                                foreach($customer->invoices() as $invoice) {
                                    $totalRevenue[$invoice->month()] +=
                                        $invoice->total();
                                    $counts[$invoice->month()]++;
                                }
                            }
                        }

                        $meanRevenue = [];

                        foreach ($revenues as $month => $total) {
                            $meanRevenue[$month] = $totalRevenue[$month] / $counts[$month];
                        }

                        return $meanRevenue;
                    }
                

Collections


                function getMonthlyMeanRevenueForStudents() {
                    return Customer::all()
                        // [
                        //     'Étudiant John',
                        //     'Étudiante Jane',
                        //     'Entreprise Google',
                        // ]
                        ->filter(function ($customer) {
                            return $customer->isStudent();
                        })
                        // [
                        //     'Étudiant John',
                        //     'Étudiante Jane',
                        // ]
                        ->map(function ($customer) {
                            return $customer->invoices();
                        })
                        // [
                        //     ['2017-07-001', '2017-08-001'],
                        //     ['2017-07-002'],
                        // ]
                        ->flatten()
                        // [ '2017-07-001', '2017-08-001', '2017-07-002' ]
                        ->groupBy(function ($invoice) {
                            return $invoice->month();
                        })
                        // [
                        //     '2017-07' => ['2017-07-001', '2017-07-002'],
                        //     '2017-08' => ['2017-08-001'],
                        // ]
                        ->map(function ($invoices) {
                            // = ['2017-07-001', '2017-07-002']// = [80, 100]// = 180// = 90
                            return $invoices->map(function ($invoice) {
                                return $invoice->total();
                            })->sum() / $invoices->count();
                        });
                        
                        // [
                        //     '2017-07' => 90,
                        //     '2017-08' => 150,
                        // ]
                }
                

Collections


                function getMonthlyMeanRevenueForStudents() {
                    return Customer::all()
                        ->filter->isStudent()
                        ->flatMap->invoices()
                        ->groupBy->month()
                        ->map(function ($invoices) {
                            return $invoices->map->total()->sum() / $invoices->count();
                        });
                }
                

Un peu de Front-End

Elm

MVU

Model View Update

Model


                    type alias Model = String
                

                    init : Model
                    init = ""
                

Update


                    type Event = Typed String
                

                    update : Event -> Model -> Model
                    update (Typed textTyped) oldTextTyped = textTyped
                

View


                    view : Model -> Html Event
                    view textTyped =
                    div []
                        [ input [ placeholder "Text to reverse", onInput Typed ] []
                        , div [] [ text (String.reverse textTyped) ]
                        ]
                

elm-lang.org

D'autres ressources

Merci à tous

@ThibaudDauce | https://thibaud.dauce.fr