add static builder

This commit is contained in:
Thibaud Dauce
2026-02-18 17:23:24 +01:00
parent e60f150611
commit ab1fa58b8b
907 changed files with 332529 additions and 12 deletions

View File

@@ -0,0 +1,352 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>Programmation fonctionnelle pour les développeuses·eurs web</title>
<link rel="stylesheet" href="css/reveal.css">
<link rel="stylesheet" href="css/theme/solarized.css">
<!-- Theme used for syntax highlighting of code -->
<link rel="stylesheet" href="lib/css/zenburn.css">
<!-- Printing and PDF exports -->
<script>
var link = document.createElement( 'link' );
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = window.location.search.match( /print-pdf/gi ) ? 'css/print/pdf.css' : 'css/print/paper.css';
document.getElementsByTagName( 'head' )[0].appendChild( link );
</script>
<style media="screen">
.fragment.current-visible.visible:not(.current-fragment) {
display: none;
height:0px;
line-height: 0px;
font-size: 0px;
}
</style>
</head>
<body>
<div class="reveal">
<div class="slides">
<section>
<h3>La programmation fonctionnelle</h3>
<h4> pour les développeuses·eurs web</h4>
<small><a href="https://twitter.com/ThibaudDauce">@ThibaudDauce</a> | <a href="https://thibaud.dauce.fr">https://thibaud.dauce.fr</a></small>
</section>
<section>
<img src="images/quantic-telecom.png" alt="Quantic Telecom" />
<h4>Co-fondateur de Quantic Telecom</h4>
<small><a href="https://www.quantic-telecom.net">https://www.quantic-telecom.net</a></small>
<hr>
<img src="images/laravel.png" alt="Formations Laravel" />
<h4>Formations Laravel</h4>
<small><a href="https://www.formations-laravel.fr">https://www.formations-laravel.fr</a></small>
</section>
<section>
<h3>La programmation fonctionnelle</h3>
<h4> pour les développeuses·eurs web</h4>
<small><a href="https://twitter.com/ThibaudDauce">@ThibaudDauce</a> | <a href="https://thibaud.dauce.fr">https://thibaud.dauce.fr</a></small>
</section>
<section>
<h3>Euh… J'en fais déjà, non ?</h3>
<pre class="fragment"><code data-trim data-noescape class="php">
// 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;
}
}
</pre></code>
</section>
<section>
<h3>Euh… J'en fais déjà, non ?</h3>
<pre><code data-trim data-noescape class="php">
// Get invoices
$invoices = getInvoices();
// Get students
$students = getStudents();
</pre></code>
</section>
<section>
<h3>Votre serveur web est une fonction</h3>
<h4><span class="fragment">Requête HTTP</span> <span class="fragment">&#8594; Réponse HTTP</span></h4>
</section>
<section>
<pre><code data-trim data-noescape class="php">
// 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.
<span class="fragment">
$tasks = [
new CheckAuthentication,
new LogRequestTime,
new TransformToResponse,
];</span>
</pre></code>
</section>
<section>
<h3>Pipelines / Middlewares</h3>
<pre><code data-trim data-noescape class="php">
(new Pipeline)
->send(Request::createFromGlobals())
->through([
new CheckAuthentication,
new LogRequestTime,
new TransformToResponse,
])
->then(function ($request) {
return "Welcome {$request->session('customer')}!";
});
</span>
</pre></code>
</section>
<section>
<pre><code data-trim data-noescape class="php">
class CheckAuthentication
{
public function handle($request, $next)
{
if (! $request->session()->has('customer')) {
return new RedirecResponse('/login', 302);
}
return $next($request);
}
}
</pre></code>
</section>
<section>
<pre><code data-trim data-noescape class="php">
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;
}
}
</pre></code>
</section>
<section>
<pre><code data-trim data-noescape class="php">
class TransformToResponse
{
public function handle($request, $next)
{
$response = $next($request);
if ($response instanceof Response) {
return $response;
}
return new Response((string) $response, 200);
}
}
</pre></code>
</section>
<section>
<pre><code data-trim data-noescape class="php">
function ($request) {
return "Welcome {$request->session('customer')}!";
}
</pre></code>
</section>
<section>
<h3>Votre serveur web est une fonction</h3>
<h4>(Le retour)</h4>
<ol>
<li class="fragment">Requête HTTP &#8594; Identifiant client</li>
<li class="fragment">Identifiant client &#8594; Client</li>
<li class="fragment">Client &#8594; Total des comptes</li>
<li class="fragment">Total des comptes &#8594; Page HTML</li>
<li class="fragment">Page HTML &#8594; Réponse</li>
</ol>
</section>
<section>
<h3>Collections</h3>
<pre><code data-trim data-noescape class="php">
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;
}
</pre></code>
</section>
<section>
<h3>Collections</h3>
<pre><code data-trim data-noescape class="php">
function getMonthlyMeanRevenueForStudents() {
<span class="fragment" data-fragment-index="0">return Customer::all()</span><span class="fragment current-visible" data-fragment-index="0">
// [
// 'Étudiant John',
// 'Étudiante Jane',
// 'Entreprise Google',
// ]</span>
<span class="fragment" data-fragment-index="1">->filter(function ($customer) {
return $customer->isStudent();
})</span><span class="fragment current-visible" data-fragment-index="1">
// [
// 'Étudiant John',
// 'Étudiante Jane',
// ]</span>
<span class="fragment" data-fragment-index="2">->map(function ($customer) {
return $customer->invoices();
})<span class="fragment current-visible" data-fragment-index="2">
// [
// ['2017-07-001', '2017-08-001'],
// ['2017-07-002'],
// ]</span>
<span class="fragment" data-fragment-index="3">->flatten()<span class="fragment current-visible" data-fragment-index="3">
// [ '2017-07-001', '2017-08-001', '2017-07-002' ]</span>
<span class="fragment" data-fragment-index="4">->groupBy(function ($invoice) {
return $invoice->month();
})<span class="fragment current-visible" data-fragment-index="4">
// [
// '2017-07' => ['2017-07-001', '2017-07-002'],
// '2017-08' => ['2017-08-001'],
// ]</span>
<span class="fragment" data-fragment-index="5">->map(function ($invoices) {</span>
<span class="fragment current-visible" data-fragment-index="5">// = ['2017-07-001', '2017-07-002']</span><span class="fragment current-visible" data-fragment-index="6">// = [80, 100]</span><span class="fragment current-visible" data-fragment-index="7">// = 180</span><span class="fragment current-visible" data-fragment-index="8">// = 90</span>
<span class="fragment" data-fragment-index="6">return $invoices->map(function ($invoice) {
return $invoice->total();
})</span><span class="fragment" data-fragment-index="7">->sum()</span><span class="fragment" data-fragment-index="8"> / $invoices->count();</span>
<span class="fragment" data-fragment-index="5">});</span>
<span class="fragment current-visible" data-fragment-index="9">
// [
// '2017-07' => 90,
// '2017-08' => 150,
// ]</span>
}
</pre></code>
</section>
<section>
<h3>Collections</h3>
<pre><code data-trim data-noescape class="php">
function getMonthlyMeanRevenueForStudents() {
return Customer::all()
->filter->isStudent()
->flatMap->invoices()
->groupBy->month()
->map(function ($invoices) {
return $invoices->map->total()->sum() / $invoices->count();
});
}
</pre></code>
</section>
<section>
<h3>Un peu de Front-End</h3>
<h4 class="fragment">Elm</h4>
</section>
<section>
<h3>MVU</h3>
<h4 class="fragment"><strong>M</strong>odel <strong>V</strong>iew <strong>U</strong>pdate</h4>
</section>
<section>
<h3>Model</h3>
<pre><code data-trim data-noescape class="elm">
type alias Model = String
</pre></code>
<pre class="fragment"><code data-trim data-noescape class="elm">
init : Model
init = ""
</pre></code>
</section>
<section>
<h3>Update</h3>
<pre><code data-trim data-noescape class="elm">
type Event = Typed String
</pre></code>
<pre class="fragment"><code data-trim data-noescape class="elm">
update : Event -> Model -> Model
update (Typed textTyped) oldTextTyped = textTyped
</pre></code>
</section>
<section>
<h3>View</h3>
<pre><code data-trim data-noescape class="elm">
view : Model -> Html Event
view textTyped =
div []
[ input [ placeholder "Text to reverse", onInput Typed ] []
, div [] [ text (String.reverse textTyped) ]
]
</pre></code>
</section>
<section>
<h3><a href="http://elm-lang.org">elm-lang.org</a></h3>
</section>
<section>
<h3>D'autres ressources</h3>
<ul>
<li><a href="https://medium.com/@jeffochoa/understanding-laravel-pipelines-a7191f75c351">Understanding Laravel Pipelines</a></li>
<li><a href="https://adamwathan.me/refactoring-to-collections/">Refactoring to Collection</a></li>
<li><a href="http://haskellbook.com/">Haskell Book</a></li>
<li><a href="http://www.purescript.org/">PureScript</a></li>
<li><a href="https://leanpub.com/purescript/">Learn PureScript by Example</a></li>
</ul>
</section>
<section>
<h3>Merci à tous</h3>
<small><a href="https://twitter.com/ThibaudDauce">@ThibaudDauce</a> | <a href="https://thibaud.dauce.fr">https://thibaud.dauce.fr</a></small>
</section>
</div>
</div>
<script src="lib/js/head.min.js"></script>
<script src="js/reveal.js"></script>
<script>
// More info about config & dependencies:
// - https://github.com/hakimel/reveal.js#configuration
// - https://github.com/hakimel/reveal.js#dependencies
Reveal.initialize({
dependencies: [
{ src: 'plugin/markdown/marked.js' },
{ src: 'plugin/markdown/markdown.js' },
{ src: 'plugin/notes/notes.js', async: true },
{ src: 'plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } }
]
});
</script>
</body>
</html>