Browse Source

Articles

master
David Larlet 1 year ago
parent
commit
038090ae42

+ 330
- 0
cache/2023/0f8bbba127c48a13b35fdf265c2dc106/index.html View File

@@ -0,0 +1,330 @@
<!doctype html><!-- This is a valid HTML5 document. -->
<!-- Screen readers, SEO, extensions and so on. -->
<html lang="fr">
<!-- Has to be within the first 1024 bytes, hence before the `title` element
See: https://www.w3.org/TR/2012/CR-html5-20121217/document-metadata.html#charset -->
<meta charset="utf-8">
<!-- Why no `X-UA-Compatible` meta: https://stackoverflow.com/a/6771584 -->
<!-- The viewport meta is quite crowded and we are responsible for that.
See: https://codepen.io/tigt/post/meta-viewport-for-2015 -->
<meta name="viewport" content="width=device-width,initial-scale=1">
<!-- Required to make a valid HTML5 document. -->
<title>Company Announcement | Pydantic (archive) — David Larlet</title>
<meta name="description" content="Publication mise en cache pour en conserver une trace.">
<!-- That good ol' feed, subscribe :). -->
<link rel="alternate" type="application/atom+xml" title="Feed" href="/david/log/">
<!-- Generated from https://realfavicongenerator.net/ such a mess. -->
<link rel="apple-touch-icon" sizes="180x180" href="/static/david/icons2/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/static/david/icons2/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/static/david/icons2/favicon-16x16.png">
<link rel="manifest" href="/static/david/icons2/site.webmanifest">
<link rel="mask-icon" href="/static/david/icons2/safari-pinned-tab.svg" color="#07486c">
<link rel="shortcut icon" href="/static/david/icons2/favicon.ico">
<meta name="msapplication-TileColor" content="#f7f7f7">
<meta name="msapplication-config" content="/static/david/icons2/browserconfig.xml">
<meta name="theme-color" content="#f7f7f7" media="(prefers-color-scheme: light)">
<meta name="theme-color" content="#272727" media="(prefers-color-scheme: dark)">
<!-- Documented, feel free to shoot an email. -->
<link rel="stylesheet" href="/static/david/css/style_2021-01-20.css">
<!-- See https://www.zachleat.com/web/comprehensive-webfonts/ for the trade-off. -->
<link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
<link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
<link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
<script>
function toggleTheme(themeName) {
document.documentElement.classList.toggle(
'forced-dark',
themeName === 'dark'
)
document.documentElement.classList.toggle(
'forced-light',
themeName === 'light'
)
}
const selectedTheme = localStorage.getItem('theme')
if (selectedTheme !== 'undefined') {
toggleTheme(selectedTheme)
}
</script>

<meta name="robots" content="noindex, nofollow">
<meta content="origin-when-cross-origin" name="referrer">
<!-- Canonical URL for SEO purposes -->
<link rel="canonical" href="https://pydantic.dev/announcement/">

<body class="remarkdown h1-underline h2-underline h3-underline em-underscore hr-center ul-star pre-tick" data-instant-intensity="viewport-all">


<article>
<header>
<h1>Company Announcement | Pydantic</h1>
</header>
<nav>
<p class="center">
<a href="/david/" title="Aller à l’accueil"><svg class="icon icon-home">
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-home"></use>
</svg> Accueil</a> •
<a href="https://pydantic.dev/announcement/" title="Lien vers le contenu original">Source originale</a>
</p>
</nav>
<hr>
<p>I've decided to start a company based on the principles that I believe have led to Pydantic's success.</p>

<p>I have closed a seed investment round led by <a href="https://www.sequoiacap.com">Sequoia</a>, with participation from
<a href="https://partechpartners.com/">Partech</a>, <a href="https://irregex.vc">Irregular Expressions</a> and some amazing angel investors
including <a href="https://www.linkedin.com/in/bryanhelmig/">Bryan Helmig</a> (co-founder and CTO of Zapier),
<a href="https://www.linkedin.com/in/tristanhandy/">Tristan Handy</a> (founder and CEO of Dbt Labs) and
<a href="https://www.linkedin.com/in/dmcramer/">David Cramer </a>(co-founder and CTO of Sentry).</p>
<h2 id="2-why">Why?</h2>

<p>I've watched with fascination as Pydantic has grown to become the most widely used Python data validation library, with over 40m downloads a month. </p>

<p class="plot-title">Pydantic Downloads from PyPI vs. Django</p>

<p><img src="https://pydantic.dev/imgs/pydantic-vs-django-downloads.fdc147d.png" alt="Pydantic Downloads from PyPI vs. Django"></p>

<p>By my rough estimate, Pydantic is used by 12% of professional web developers! <a href="#3-quot12-of-professional-web-developersquot-claim">†</a></p>

<p>But Pydantic wasn't the first (or last) such library. Why has it been so successful?</p>

<p>I believe it comes down to two things:</p>
<ol>
<li>We've always made developer experience the first priority.</li>
<li>We've leveraged technologies which developers already understand — most notably, Python type annotations.</li>
</ol>
<p>In short, we've made Pydantic easy to get started with, and easy to do powerful things with.</p>

<p>I believe the time is right to apply those principles to other, bigger challenges.</p>

<p>"The Cloud" is still relatively new (think about what cars or tractors looked like 15 years after their conception), and
while it has already transformed our lives, it has massive shortcomings. I think we're uniquely positioned to address
some of these shortcomings.</p>

<p>We'll start by transforming the way those 12% of web developers who already know and trust Pydantic use cloud services
to build and deploy web applications. Then, we'll move on to help the other 88%!</p>
<h3 id="3-cloud-services-suck-at-least-for-us-developers">Cloud services suck (at least for us developers)</h3>

<p>Picture the driving position of a 1950s tractor — steel seat, no cab, knobs sticking out of the engine compartment near
the component they control, hot surfaces just waiting for you to lean on them. Conceptually, this isn't surprising — the
tractor was a tool to speed up farming; its driver was an afterthought, and as long as they could manage to operate it
there was no value in making the experience pleasant or comfortable.</p>

<p><img src="https://pydantic.dev/imgs/tractor.8345002.svg" alt="1950s tractor"></p>

<p>Today's cloud services have the look and feel of that tractor. They're conceived by infrastructure people who care about
efficient computation, fast networking, and cheap storage. The comfort and convenience of the developers who need to
drive these services to build end-user facing applications has been an afterthought.</p>

<p>Both the tractor and the cloud service of the past made sense: The majority of people who made the purchasing decisions
didn't operate them, and those who did had little influence. Why bother making them nice to operate?</p>

<blockquote>
<p><em>"At least it's not a <del>cart horse</del> Windows box in the corner — quit complaining!"</em></p>
</blockquote>

<p>Just as the experience of driving tractors transformed as their drivers' pay and influence increased, so cloud services
are going through a transformation as their operators' pay and influence increases significantly. </p>

<p>There are many examples now of services and tools that are winning against incumbents because of great developer
experience:</p>
<ul>
<li><a href="https://stripe.com">Stripe</a> is winning in payments despite massive ecosystem of incumbents</li>
<li><a href="https://sentry.io/welcome/">Sentry</a> is winning in application monitoring, even though you can send, store, and view the same data in CloudWatch et al. more cheaply</li>
<li><a href="https://vercel.com/">Vercel</a> is winning in application hosting by focusing on one framework — Next.js</li>
<li><a href="https://www.tiobe.com/tiobe-index/">Python</a> is winning against other programming languages, even though it's not backed by a massive corporation</li>
<li><a href="https://docs.pydantic.dev/">Pydantic</a> is winning in data validation for Python, even though it's far from the first such library</li>
</ul>
<p>In each case the developer experience is markedly better than what came before, and developers have driven adoption.</p>

<p>There is a massive opportunity to create cloud services with great developer experience at their heart.
I think we're well positioned to be part of it.</p>
<h3 id="3-developers-are-still-drowning-under-the-weight-of-duplication">Developers are still drowning under the weight of duplication</h3>

<p>The story of the cloud has been about reducing duplication, abstracting away infrastructure and boilerplate:
co-location facilities with servers, cages and wires gave way to VMs. VMs gave way to PaaS offerings where you
just provide your application code. Serverless is challenging PaaS by offering to remove scaling worries.</p>

<p>At each step, cloud providers took work off engineers which was common to many customers.</p>

<p>But this hasn't gone far enough. Think about the last web application you worked on —
how many of the views or components were unique to your app?</p>

<p>Sure, you fitted them together in a unique way, but many (20%, 50%, maybe even 80%?) will exist hundreds or thousands of
times in other code bases. Couldn't many of those components, views, and utilities be shared with other apps without
affecting the value of your application? Again, reducing duplication, and reducing the time and cost of building an
application.</p>

<p>At the same time, serverless, despite being the trendiest way to deploy applications for the last few years, has made
much of this worse — complete web frameworks have often been switched out for bare-bones entry points which lack
even the most basic functionality of a web framework like routing, error handling, or database integration.</p>

<p>What if we could build a platform with the best of all worlds? Taking the final step in reducing the boilerplate
and busy-work of building web applications — allowing developers to write nothing more than the core logic which
makes their application unique and valuable?</p>

<p>And all with a developer experience to die for.</p>
<h2 id="2-what-specifically-are-we-building">What, specifically, are we building?</h2>

<p>I'm not sharing details yet :).</p>

<p>The immediate plan is to hire the brightest developers I can find and work with them to refine our vision and exactly
what we're building while we finish and release Pydantic V2.</p>

<p>While I have some blueprints in my head of the libraries and services we want to build, we have a lot of options
for exactly where to go; we won't constrain what we can design by making any commitments now.</p>

<p><strong>If you're interested in what we're doing, hit subscribe on
<a href="https://github.com/pydantic/pydantic/issues/5063">this GitHub issue</a>.
We'll comment there when we have
more concrete information.</strong></p>
<h2 id="2-the-plan">The plan</h2>

<p>The plan, in short, is this:</p>
<ol>
<li>Hire the best developers from around the world (see <a href="#2-were-hiring">"We're Hiring"</a> below)</li>
<li>Finish and release Pydantic V2, and continue to maintain, support and develop Pydantic over the years</li>
<li>Build cloud services and developer tools that developers love</li>
</ol>
<p>Pydantic, the open source project, will be a cornerstone of the company. It'll be a key technical component
in what we're building and an important asset to help convince developers that the commercial tools and services
we build will be worth adopting. It will remain open source and MIT licenced, and support and development will
accelerate.</p>

<p>I'm currently working full time on Pydantic V2 (learn more from the <a href="https://docs.pydantic.dev/blog/pydantic-v2/">previous blog post</a>).
It should be released later this year, hopefully in Q1. V2 is a massive advance for Pydantic — the core has been
re-written in Rust, making Pydantic V2 around 17x faster than V1. But there are lots of other goodies: strict mode,
composable validators, validation context, and more. I can't wait to get Pydantic V2 released and see how the community
uses it.</p>

<p>We'll keep working closely with <a href="https://github.com/topics/pydantic">other open source libraries</a> that use and depend
on Pydantic as we have up to this point, making sure the whole Pydantic ecosystem continues to thrive.</p>

<p><em>On a side note: Now that I'm paid to work on Pydantic, I'll be sharing all future open source sponsorship among
other open source projects we rely on.</em></p>
<h2 id="2-were-hiring">We're hiring</h2>

<p>If you're a senior Python or full stack developer and think the ideas above are exciting, we'd love to hear from you.
Please email <a href="/cdn-cgi/l/email-protection#254644574040575665555c41444b514c460b414053"><span class="__cf_email__" data-cfemail="aecdcfdccbcbdcddeeded7cacfc0dac7cd80cacbd8">[email protected]</span></a> with a brief summary of your skills and experience,
including links to your GitHub profile and your CV.</p>
<h2 id="2-appendix">Appendix</h2>
<h3 id="3-quot12-of-professional-web-developersquot-claim">"12% of professional web developers" claim</h3>

<p>At first glance this seems like a fairly incredible number, where does it come from?</p>

<p>According to the
<a href="https://survey.stackoverflow.co/2022/#section-most-popular-technologies-web-frameworks-and-technologies">StackOverflow developer survey 2022</a>,
FastAPI is used by 6.01% of professional developers.</p>

<p>According to my survey of Pydantic users, Pydantic's usage is split roughly into:</p>
<ul>
<li>25% FastAPI</li>
<li>25% other web development</li>
<li>50% everything else</li>
</ul>
<p>That matches the numbers from PyPI downloads, which shows that (as of 2023-01-31)
<a href="https://pepy.tech/project/pydantic">Pydantic has 46m</a> downloads in the last 30 days, while
<a href="https://pepy.tech/project/fastapi">FastAPI has 10.7m</a> — roughly 25%.</p>

<p>Based on these numbers, I estimate Pydantic is used for web development by about twice the number who use it through
FastAPI — roughly 12%.</p>
</article>


<hr>

<footer>
<p>
<a href="/david/" title="Aller à l’accueil"><svg class="icon icon-home">
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-home"></use>
</svg> Accueil</a> •
<a href="/david/log/" title="Accès au flux RSS"><svg class="icon icon-rss2">
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-rss2"></use>
</svg> Suivre</a> •
<a href="http://larlet.com" title="Go to my English profile" data-instant><svg class="icon icon-user-tie">
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-user-tie"></use>
</svg> Pro</a> •
<a href="mailto:david%40larlet.fr" title="Envoyer un courriel"><svg class="icon icon-mail">
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-mail"></use>
</svg> Email</a> •
<abbr class="nowrap" title="Hébergeur : Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33184162340"><svg class="icon icon-hammer2">
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-hammer2"></use>
</svg> Légal</abbr>
</p>
<template id="theme-selector">
<form>
<fieldset>
<legend><svg class="icon icon-brightness-contrast">
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-brightness-contrast"></use>
</svg> Thème</legend>
<label>
<input type="radio" value="auto" name="chosen-color-scheme" checked> Auto
</label>
<label>
<input type="radio" value="dark" name="chosen-color-scheme"> Foncé
</label>
<label>
<input type="radio" value="light" name="chosen-color-scheme"> Clair
</label>
</fieldset>
</form>
</template>
</footer>
<script src="/static/david/js/instantpage-5.1.0.min.js" type="module"></script>
<script>
function loadThemeForm(templateName) {
const themeSelectorTemplate = document.querySelector(templateName)
const form = themeSelectorTemplate.content.firstElementChild
themeSelectorTemplate.replaceWith(form)

form.addEventListener('change', (e) => {
const chosenColorScheme = e.target.value
localStorage.setItem('theme', chosenColorScheme)
toggleTheme(chosenColorScheme)
})

const selectedTheme = localStorage.getItem('theme')
if (selectedTheme && selectedTheme !== 'undefined') {
form.querySelector(`[value="${selectedTheme}"]`).checked = true
}
}

const prefersColorSchemeDark = '(prefers-color-scheme: dark)'
window.addEventListener('load', () => {
let hasDarkRules = false
for (const styleSheet of Array.from(document.styleSheets)) {
let mediaRules = []
for (const cssRule of styleSheet.cssRules) {
if (cssRule.type !== CSSRule.MEDIA_RULE) {
continue
}
// WARNING: Safari does not have/supports `conditionText`.
if (cssRule.conditionText) {
if (cssRule.conditionText !== prefersColorSchemeDark) {
continue
}
} else {
if (cssRule.cssText.startsWith(prefersColorSchemeDark)) {
continue
}
}
mediaRules = mediaRules.concat(Array.from(cssRule.cssRules))
}

// WARNING: do not try to insert a Rule to a styleSheet you are
// currently iterating on, otherwise the browser will be stuck
// in a infinite loop…
for (const mediaRule of mediaRules) {
styleSheet.insertRule(mediaRule.cssText)
hasDarkRules = true
}
}
if (hasDarkRules) {
loadThemeForm('#theme-selector')
}
})
</script>
</body>
</html>

+ 165
- 0
cache/2023/0f8bbba127c48a13b35fdf265c2dc106/index.md View File

@@ -0,0 +1,165 @@
title: Company Announcement | Pydantic
url: https://pydantic.dev/announcement/
hash_url: 0f8bbba127c48a13b35fdf265c2dc106

<p>I've decided to start a company based on the principles that I believe have led to Pydantic's success.</p>

<p>I have closed a seed investment round led by <a href="https://www.sequoiacap.com">Sequoia</a>, with participation from
<a href="https://partechpartners.com/">Partech</a>, <a href="https://irregex.vc">Irregular Expressions</a> and some amazing angel investors
including <a href="https://www.linkedin.com/in/bryanhelmig/">Bryan Helmig</a> (co-founder and CTO of Zapier),
<a href="https://www.linkedin.com/in/tristanhandy/">Tristan Handy</a> (founder and CEO of Dbt Labs) and
<a href="https://www.linkedin.com/in/dmcramer/">David Cramer </a>(co-founder and CTO of Sentry).</p>
<h2 id="2-why">Why?</h2>

<p>I've watched with fascination as Pydantic has grown to become the most widely used Python data validation library, with over 40m downloads a month. </p>

<p class="plot-title">Pydantic Downloads from PyPI vs. Django</p>

<p><img src="https://pydantic.dev/imgs/pydantic-vs-django-downloads.fdc147d.png" alt="Pydantic Downloads from PyPI vs. Django"></p>



<p>By my rough estimate, Pydantic is used by 12% of professional web developers! <a href="#3-quot12-of-professional-web-developersquot-claim">†</a></p>

<p>But Pydantic wasn't the first (or last) such library. Why has it been so successful?</p>

<p>I believe it comes down to two things:</p>
<ol>
<li>We've always made developer experience the first priority.</li>
<li>We've leveraged technologies which developers already understand — most notably, Python type annotations.</li>
</ol>
<p>In short, we've made Pydantic easy to get started with, and easy to do powerful things with.</p>

<p>I believe the time is right to apply those principles to other, bigger challenges.</p>

<p>"The Cloud" is still relatively new (think about what cars or tractors looked like 15 years after their conception), and
while it has already transformed our lives, it has massive shortcomings. I think we're uniquely positioned to address
some of these shortcomings.</p>

<p>We'll start by transforming the way those 12% of web developers who already know and trust Pydantic use cloud services
to build and deploy web applications. Then, we'll move on to help the other 88%!</p>
<h3 id="3-cloud-services-suck-at-least-for-us-developers">Cloud services suck (at least for us developers)</h3>

<p>Picture the driving position of a 1950s tractor — steel seat, no cab, knobs sticking out of the engine compartment near
the component they control, hot surfaces just waiting for you to lean on them. Conceptually, this isn't surprising — the
tractor was a tool to speed up farming; its driver was an afterthought, and as long as they could manage to operate it
there was no value in making the experience pleasant or comfortable.</p>

<p><img src="https://pydantic.dev/imgs/tractor.8345002.svg" alt="1950s tractor"></p>

<p>Today's cloud services have the look and feel of that tractor. They're conceived by infrastructure people who care about
efficient computation, fast networking, and cheap storage. The comfort and convenience of the developers who need to
drive these services to build end-user facing applications has been an afterthought.</p>

<p>Both the tractor and the cloud service of the past made sense: The majority of people who made the purchasing decisions
didn't operate them, and those who did had little influence. Why bother making them nice to operate?</p>

<blockquote>
<p><em>"At least it's not a <del>cart horse</del> Windows box in the corner — quit complaining!"</em></p>
</blockquote>

<p>Just as the experience of driving tractors transformed as their drivers' pay and influence increased, so cloud services
are going through a transformation as their operators' pay and influence increases significantly. </p>

<p>There are many examples now of services and tools that are winning against incumbents because of great developer
experience:</p>
<ul>
<li><a href="https://stripe.com">Stripe</a> is winning in payments despite massive ecosystem of incumbents</li>
<li><a href="https://sentry.io/welcome/">Sentry</a> is winning in application monitoring, even though you can send, store, and view the same data in CloudWatch et al. more cheaply</li>
<li><a href="https://vercel.com/">Vercel</a> is winning in application hosting by focusing on one framework — Next.js</li>
<li><a href="https://www.tiobe.com/tiobe-index/">Python</a> is winning against other programming languages, even though it's not backed by a massive corporation</li>
<li><a href="https://docs.pydantic.dev/">Pydantic</a> is winning in data validation for Python, even though it's far from the first such library</li>
</ul>
<p>In each case the developer experience is markedly better than what came before, and developers have driven adoption.</p>

<p>There is a massive opportunity to create cloud services with great developer experience at their heart.
I think we're well positioned to be part of it.</p>
<h3 id="3-developers-are-still-drowning-under-the-weight-of-duplication">Developers are still drowning under the weight of duplication</h3>

<p>The story of the cloud has been about reducing duplication, abstracting away infrastructure and boilerplate:
co-location facilities with servers, cages and wires gave way to VMs. VMs gave way to PaaS offerings where you
just provide your application code. Serverless is challenging PaaS by offering to remove scaling worries.</p>

<p>At each step, cloud providers took work off engineers which was common to many customers.</p>

<p>But this hasn't gone far enough. Think about the last web application you worked on —
how many of the views or components were unique to your app?</p>

<p>Sure, you fitted them together in a unique way, but many (20%, 50%, maybe even 80%?) will exist hundreds or thousands of
times in other code bases. Couldn't many of those components, views, and utilities be shared with other apps without
affecting the value of your application? Again, reducing duplication, and reducing the time and cost of building an
application.</p>

<p>At the same time, serverless, despite being the trendiest way to deploy applications for the last few years, has made
much of this worse — complete web frameworks have often been switched out for bare-bones entry points which lack
even the most basic functionality of a web framework like routing, error handling, or database integration.</p>

<p>What if we could build a platform with the best of all worlds? Taking the final step in reducing the boilerplate
and busy-work of building web applications — allowing developers to write nothing more than the core logic which
makes their application unique and valuable?</p>

<p>And all with a developer experience to die for.</p>
<h2 id="2-what-specifically-are-we-building">What, specifically, are we building?</h2>

<p>I'm not sharing details yet :).</p>

<p>The immediate plan is to hire the brightest developers I can find and work with them to refine our vision and exactly
what we're building while we finish and release Pydantic V2.</p>

<p>While I have some blueprints in my head of the libraries and services we want to build, we have a lot of options
for exactly where to go; we won't constrain what we can design by making any commitments now.</p>

<p><strong>If you're interested in what we're doing, hit subscribe on
<a href="https://github.com/pydantic/pydantic/issues/5063">this GitHub issue</a>.
We'll comment there when we have
more concrete information.</strong></p>
<h2 id="2-the-plan">The plan</h2>

<p>The plan, in short, is this:</p>
<ol>
<li>Hire the best developers from around the world (see <a href="#2-were-hiring">"We're Hiring"</a> below)</li>
<li>Finish and release Pydantic V2, and continue to maintain, support and develop Pydantic over the years</li>
<li>Build cloud services and developer tools that developers love</li>
</ol>
<p>Pydantic, the open source project, will be a cornerstone of the company. It'll be a key technical component
in what we're building and an important asset to help convince developers that the commercial tools and services
we build will be worth adopting. It will remain open source and MIT licenced, and support and development will
accelerate.</p>

<p>I'm currently working full time on Pydantic V2 (learn more from the <a href="https://docs.pydantic.dev/blog/pydantic-v2/">previous blog post</a>).
It should be released later this year, hopefully in Q1. V2 is a massive advance for Pydantic — the core has been
re-written in Rust, making Pydantic V2 around 17x faster than V1. But there are lots of other goodies: strict mode,
composable validators, validation context, and more. I can't wait to get Pydantic V2 released and see how the community
uses it.</p>

<p>We'll keep working closely with <a href="https://github.com/topics/pydantic">other open source libraries</a> that use and depend
on Pydantic as we have up to this point, making sure the whole Pydantic ecosystem continues to thrive.</p>

<p><em>On a side note: Now that I'm paid to work on Pydantic, I'll be sharing all future open source sponsorship among
other open source projects we rely on.</em></p>
<h2 id="2-were-hiring">We're hiring</h2>

<p>If you're a senior Python or full stack developer and think the ideas above are exciting, we'd love to hear from you.
Please email <a href="/cdn-cgi/l/email-protection#254644574040575665555c41444b514c460b414053"><span class="__cf_email__" data-cfemail="aecdcfdccbcbdcddeeded7cacfc0dac7cd80cacbd8">[email protected]</span></a> with a brief summary of your skills and experience,
including links to your GitHub profile and your CV.</p>
<h2 id="2-appendix">Appendix</h2>
<h3 id="3-quot12-of-professional-web-developersquot-claim">"12% of professional web developers" claim</h3>

<p>At first glance this seems like a fairly incredible number, where does it come from?</p>

<p>According to the
<a href="https://survey.stackoverflow.co/2022/#section-most-popular-technologies-web-frameworks-and-technologies">StackOverflow developer survey 2022</a>,
FastAPI is used by 6.01% of professional developers.</p>

<p>According to my survey of Pydantic users, Pydantic's usage is split roughly into:</p>
<ul>
<li>25% FastAPI</li>
<li>25% other web development</li>
<li>50% everything else</li>
</ul>
<p>That matches the numbers from PyPI downloads, which shows that (as of 2023-01-31)
<a href="https://pepy.tech/project/pydantic">Pydantic has 46m</a> downloads in the last 30 days, while
<a href="https://pepy.tech/project/fastapi">FastAPI has 10.7m</a> — roughly 25%.</p>

<p>Based on these numbers, I estimate Pydantic is used for web development by about twice the number who use it through
FastAPI — roughly 12%.</p>

+ 192
- 0
cache/2023/19ec475bd5d92b02fbef043c52ea0589/index.html View File

@@ -0,0 +1,192 @@
<!doctype html><!-- This is a valid HTML5 document. -->
<!-- Screen readers, SEO, extensions and so on. -->
<html lang="fr">
<!-- Has to be within the first 1024 bytes, hence before the `title` element
See: https://www.w3.org/TR/2012/CR-html5-20121217/document-metadata.html#charset -->
<meta charset="utf-8">
<!-- Why no `X-UA-Compatible` meta: https://stackoverflow.com/a/6771584 -->
<!-- The viewport meta is quite crowded and we are responsible for that.
See: https://codepen.io/tigt/post/meta-viewport-for-2015 -->
<meta name="viewport" content="width=device-width,initial-scale=1">
<!-- Required to make a valid HTML5 document. -->
<title>Investing in RSS (archive) — David Larlet</title>
<meta name="description" content="Publication mise en cache pour en conserver une trace.">
<!-- That good ol' feed, subscribe :). -->
<link rel="alternate" type="application/atom+xml" title="Feed" href="/david/log/">
<!-- Generated from https://realfavicongenerator.net/ such a mess. -->
<link rel="apple-touch-icon" sizes="180x180" href="/static/david/icons2/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/static/david/icons2/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/static/david/icons2/favicon-16x16.png">
<link rel="manifest" href="/static/david/icons2/site.webmanifest">
<link rel="mask-icon" href="/static/david/icons2/safari-pinned-tab.svg" color="#07486c">
<link rel="shortcut icon" href="/static/david/icons2/favicon.ico">
<meta name="msapplication-TileColor" content="#f7f7f7">
<meta name="msapplication-config" content="/static/david/icons2/browserconfig.xml">
<meta name="theme-color" content="#f7f7f7" media="(prefers-color-scheme: light)">
<meta name="theme-color" content="#272727" media="(prefers-color-scheme: dark)">
<!-- Documented, feel free to shoot an email. -->
<link rel="stylesheet" href="/static/david/css/style_2021-01-20.css">
<!-- See https://www.zachleat.com/web/comprehensive-webfonts/ for the trade-off. -->
<link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
<link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
<link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
<script>
function toggleTheme(themeName) {
document.documentElement.classList.toggle(
'forced-dark',
themeName === 'dark'
)
document.documentElement.classList.toggle(
'forced-light',
themeName === 'light'
)
}
const selectedTheme = localStorage.getItem('theme')
if (selectedTheme !== 'undefined') {
toggleTheme(selectedTheme)
}
</script>

<meta name="robots" content="noindex, nofollow">
<meta content="origin-when-cross-origin" name="referrer">
<!-- Canonical URL for SEO purposes -->
<link rel="canonical" href="https://timkadlec.com/remembers/2023-02-23-investing-in-rss/">

<body class="remarkdown h1-underline h2-underline h3-underline em-underscore hr-center ul-star pre-tick" data-instant-intensity="viewport-all">


<article>
<header>
<h1>Investing in RSS</h1>
</header>
<nav>
<p class="center">
<a href="/david/" title="Aller à l’accueil"><svg class="icon icon-home">
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-home"></use>
</svg> Accueil</a> •
<a href="https://timkadlec.com/remembers/2023-02-23-investing-in-rss/" title="Lien vers le contenu original">Source originale</a>
</p>
</nav>
<hr>
<p>One of the first jobs I had gave me the opportunity to work with <a href="https://elroyjetson.org/about">James King</a>, and one of the great habits I picked up from him was making sure to set aside time to learn from others. He would set aside an hour or so a day, sometimes less, sometimes more, to read through the RSS feeds he had subscribed to in Google Reader (RIP), and he encouraged me to always do the same.</p>

<p>So I would. I would grab a coffee, sit down, and start reading. Often we’d share posts back and forth, or chat about some of the more interesting ones we had read. It was something we did that was never on accident…it was intentional, deliberate. It was a way, I think, of investing in ourselves while also acknowledging how much we still could learn from others.</p>

<p>Nowadays, of course, a few things have changed.</p>

<p>Obviously, I’m no longer using Google Reader—I’m a big fan of <a href="https://feedbin.com/">Feedbin</a> and the annual payment I make is perhaps the easiest payment to justify all year.</p>

<p>I don’t subscribe to as many tech news outlets as I used to. In fact, there are just a handful of publications in my RSS feeds.</p>

<p>Personal blogs have always been my favorite, and continue to be my favorite, though they’re a lot quieter than they used to be (mine too).</p>

<p>Some of those have been replaced by newsletters. Historically, newsletters were a format I could just never quite get into (gosh email is rough enough without having those in there), but Feedbin’s ability to subscribe to email newsletters that then show up in my reader has been a massive game-changer there.</p>

<p>Some things are also the same as they’ve always been.</p>

<p>Opening up my RSS reader, a cup of coffee in hand, still feels calm and peaceful in a way that trying to keep up with happenings in other ways just never has. There’s more room for nuance and thoughtfulness, and I feel more in control of what I choose to read, and what I don’t.</p>

<p>The act of spending that time in those feeds still feels like a very deliberate, intentional act. Curating a set of feeds I find interesting and making the time to read them feels like an investment in myself.</p>

<p>I still make a point to spend some time each day, reading through my feeds, learning from others, and it still feels like one of the most important and enjoyable parts of each workday.</p>
</article>


<hr>

<footer>
<p>
<a href="/david/" title="Aller à l’accueil"><svg class="icon icon-home">
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-home"></use>
</svg> Accueil</a> •
<a href="/david/log/" title="Accès au flux RSS"><svg class="icon icon-rss2">
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-rss2"></use>
</svg> Suivre</a> •
<a href="http://larlet.com" title="Go to my English profile" data-instant><svg class="icon icon-user-tie">
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-user-tie"></use>
</svg> Pro</a> •
<a href="mailto:david%40larlet.fr" title="Envoyer un courriel"><svg class="icon icon-mail">
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-mail"></use>
</svg> Email</a> •
<abbr class="nowrap" title="Hébergeur : Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33184162340"><svg class="icon icon-hammer2">
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-hammer2"></use>
</svg> Légal</abbr>
</p>
<template id="theme-selector">
<form>
<fieldset>
<legend><svg class="icon icon-brightness-contrast">
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-brightness-contrast"></use>
</svg> Thème</legend>
<label>
<input type="radio" value="auto" name="chosen-color-scheme" checked> Auto
</label>
<label>
<input type="radio" value="dark" name="chosen-color-scheme"> Foncé
</label>
<label>
<input type="radio" value="light" name="chosen-color-scheme"> Clair
</label>
</fieldset>
</form>
</template>
</footer>
<script src="/static/david/js/instantpage-5.1.0.min.js" type="module"></script>
<script>
function loadThemeForm(templateName) {
const themeSelectorTemplate = document.querySelector(templateName)
const form = themeSelectorTemplate.content.firstElementChild
themeSelectorTemplate.replaceWith(form)

form.addEventListener('change', (e) => {
const chosenColorScheme = e.target.value
localStorage.setItem('theme', chosenColorScheme)
toggleTheme(chosenColorScheme)
})

const selectedTheme = localStorage.getItem('theme')
if (selectedTheme && selectedTheme !== 'undefined') {
form.querySelector(`[value="${selectedTheme}"]`).checked = true
}
}

const prefersColorSchemeDark = '(prefers-color-scheme: dark)'
window.addEventListener('load', () => {
let hasDarkRules = false
for (const styleSheet of Array.from(document.styleSheets)) {
let mediaRules = []
for (const cssRule of styleSheet.cssRules) {
if (cssRule.type !== CSSRule.MEDIA_RULE) {
continue
}
// WARNING: Safari does not have/supports `conditionText`.
if (cssRule.conditionText) {
if (cssRule.conditionText !== prefersColorSchemeDark) {
continue
}
} else {
if (cssRule.cssText.startsWith(prefersColorSchemeDark)) {
continue
}
}
mediaRules = mediaRules.concat(Array.from(cssRule.cssRules))
}

// WARNING: do not try to insert a Rule to a styleSheet you are
// currently iterating on, otherwise the browser will be stuck
// in a infinite loop…
for (const mediaRule of mediaRules) {
styleSheet.insertRule(mediaRule.cssText)
hasDarkRules = true
}
}
if (hasDarkRules) {
loadThemeForm('#theme-selector')
}
})
</script>
</body>
</html>

+ 25
- 0
cache/2023/19ec475bd5d92b02fbef043c52ea0589/index.md View File

@@ -0,0 +1,25 @@
title: Investing in RSS
url: https://timkadlec.com/remembers/2023-02-23-investing-in-rss/
hash_url: 19ec475bd5d92b02fbef043c52ea0589

<p>One of the first jobs I had gave me the opportunity to work with <a href="https://elroyjetson.org/about">James King</a>, and one of the great habits I picked up from him was making sure to set aside time to learn from others. He would set aside an hour or so a day, sometimes less, sometimes more, to read through the RSS feeds he had subscribed to in Google Reader (RIP), and he encouraged me to always do the same.</p>

<p>So I would. I would grab a coffee, sit down, and start reading. Often we’d share posts back and forth, or chat about some of the more interesting ones we had read. It was something we did that was never on accident…it was intentional, deliberate. It was a way, I think, of investing in ourselves while also acknowledging how much we still could learn from others.</p>

<p>Nowadays, of course, a few things have changed.</p>

<p>Obviously, I’m no longer using Google Reader—I’m a big fan of <a href="https://feedbin.com/">Feedbin</a> and the annual payment I make is perhaps the easiest payment to justify all year.</p>

<p>I don’t subscribe to as many tech news outlets as I used to. In fact, there are just a handful of publications in my RSS feeds.</p>

<p>Personal blogs have always been my favorite, and continue to be my favorite, though they’re a lot quieter than they used to be (mine too).</p>

<p>Some of those have been replaced by newsletters. Historically, newsletters were a format I could just never quite get into (gosh email is rough enough without having those in there), but Feedbin’s ability to subscribe to email newsletters that then show up in my reader has been a massive game-changer there.</p>

<p>Some things are also the same as they’ve always been.</p>

<p>Opening up my RSS reader, a cup of coffee in hand, still feels calm and peaceful in a way that trying to keep up with happenings in other ways just never has. There’s more room for nuance and thoughtfulness, and I feel more in control of what I choose to read, and what I don’t.</p>

<p>The act of spending that time in those feeds still feels like a very deliberate, intentional act. Curating a set of feeds I find interesting and making the time to read them feels like an investment in myself.</p>

<p>I still make a point to spend some time each day, reading through my feeds, learning from others, and it still feels like one of the most important and enjoyable parts of each workday.</p>

+ 239
- 0
cache/2023/482252d2b8806e99bc30ffab2b2c51c9/index.html View File

@@ -0,0 +1,239 @@
<!doctype html><!-- This is a valid HTML5 document. -->
<!-- Screen readers, SEO, extensions and so on. -->
<html lang="fr">
<!-- Has to be within the first 1024 bytes, hence before the `title` element
See: https://www.w3.org/TR/2012/CR-html5-20121217/document-metadata.html#charset -->
<meta charset="utf-8">
<!-- Why no `X-UA-Compatible` meta: https://stackoverflow.com/a/6771584 -->
<!-- The viewport meta is quite crowded and we are responsible for that.
See: https://codepen.io/tigt/post/meta-viewport-for-2015 -->
<meta name="viewport" content="width=device-width,initial-scale=1">
<!-- Required to make a valid HTML5 document. -->
<title>Des questions · Boris Schapira (archive) — David Larlet</title>
<meta name="description" content="Publication mise en cache pour en conserver une trace.">
<!-- That good ol' feed, subscribe :). -->
<link rel="alternate" type="application/atom+xml" title="Feed" href="/david/log/">
<!-- Generated from https://realfavicongenerator.net/ such a mess. -->
<link rel="apple-touch-icon" sizes="180x180" href="/static/david/icons2/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/static/david/icons2/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/static/david/icons2/favicon-16x16.png">
<link rel="manifest" href="/static/david/icons2/site.webmanifest">
<link rel="mask-icon" href="/static/david/icons2/safari-pinned-tab.svg" color="#07486c">
<link rel="shortcut icon" href="/static/david/icons2/favicon.ico">
<meta name="msapplication-TileColor" content="#f7f7f7">
<meta name="msapplication-config" content="/static/david/icons2/browserconfig.xml">
<meta name="theme-color" content="#f7f7f7" media="(prefers-color-scheme: light)">
<meta name="theme-color" content="#272727" media="(prefers-color-scheme: dark)">
<!-- Documented, feel free to shoot an email. -->
<link rel="stylesheet" href="/static/david/css/style_2021-01-20.css">
<!-- See https://www.zachleat.com/web/comprehensive-webfonts/ for the trade-off. -->
<link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
<link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
<link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
<script>
function toggleTheme(themeName) {
document.documentElement.classList.toggle(
'forced-dark',
themeName === 'dark'
)
document.documentElement.classList.toggle(
'forced-light',
themeName === 'light'
)
}
const selectedTheme = localStorage.getItem('theme')
if (selectedTheme !== 'undefined') {
toggleTheme(selectedTheme)
}
</script>

<meta name="robots" content="noindex, nofollow">
<meta content="origin-when-cross-origin" name="referrer">
<!-- Canonical URL for SEO purposes -->
<link rel="canonical" href="https://boris.schapira.dev/notes/2023-02-des-questions/">

<body class="remarkdown h1-underline h2-underline h3-underline em-underscore hr-center ul-star pre-tick" data-instant-intensity="viewport-all">


<article>
<header>
<h1>Des questions · Boris Schapira</h1>
</header>
<nav>
<p class="center">
<a href="/david/" title="Aller à l’accueil"><svg class="icon icon-home">
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-home"></use>
</svg> Accueil</a> •
<a href="https://boris.schapira.dev/notes/2023-02-des-questions/" title="Lien vers le contenu original">Source originale</a>
</p>
</nav>
<hr>
<p>Depuis plusieurs semaines, il ne se passe pas une journée sans que ChatGPT ne fasse irruption dans les discussions que j’ai avec de très nombreux professionnel<span aria-hidden="true">·les</span> du numérique.</p>
<p>Et sincèrement, l’émergence de ces LLM (Large Language Model) capable de produire du contenu (sous la forme d’une discussion ou non) m’interroge.</p>
<p>Je vais utiliser cet article pour jeter mes points d’attention. Je ne m’interdis pas de le mettre à jour plus tard avec de nouveaux éléments. Je parle au présent parce que ces solutions sont déjà là. Nous ne parlons pas d’un problème du futur. Ce n’est pas de la science-fiction, mais un problème politique.</p>
<hr><h2>Intro</h2>
<p>Besoin d’une intro sur ChatGPT ? J’ai trouvé personnellement que cette vidéo était très bien construite, et accessible pour des néophytes :</p>
<p class="videoWrapper"> </p>
<p>En quelques mots, si vous préférez me lire : un LLM est un système à modèle d’apprentissage automatique dont l’objectif est de manipuler le langage naturel (on parle de Natural Language Processing ou NLP).</p>
<p>Une fois le modèle alimenté et entrainé statistiquement, il peut servir à :</p>
<ul> <li>classifier des contenus</li> <li>élaborer de nouveaux contenus textuels à partir d’un contexte interactionnel : à partir d’une consigne ou dans le cadre d’un échange textuel (chat)</li> <li>modifier des contenues existants</li> </ul>
<p>Ces systèmes ne comprennent pas ce qu’ils écrivent, en tout cas pas dans le sens où nous l’entendons. Ils se basent sur des analyses statistiques pour prédire le prochain élément d’une phrase, compte tenu du contexte à leur disposition (constitué de la consigne d’origine et d’une partie de l’historique d’interaction).</p>
<p>Leur nature profonde les amène à produire des contenus très consensuels (au regard des données qui les ont alimentées).</p>
<h2>Le positif</h2>
<p>Ces systèmes sont utilisés ou peuvent l’être de manière à profiter aux organisations et la société.</p>
<p>Les usages décrits ici doivent tous êtres validés par un<span aria-hidden="true">·e</span> opérateur<span aria-hidden="true">·ice</span> humain<span aria-hidden="true">·e</span> doué de compétences spécifiques, qui se chargera de corriger les défauts éventuels. L’outil lui apporte une productivité importante sur la partie la plus fastidieuse de la tâche.</p>
<h3>Inclusion</h3>
<p>Quand on est capable de créer ou de modifier un contenu à partir d’un autre, alors on peut fabrique des correspondances multimédia.</p>
<p>On peut, par exemple, prendre le sous-titrage automatique d’une conférence et corriger son contenu pour qu’il soit :</p>
<ul> <li>plus intelligible</li> <li>découpé de manière optimale pour la lecture</li> </ul>
<p>On peut aussi faire décrire automatiquement des images qui n’auraient pas de description textuelle sans cela, par défaut d’éducation des contributeur<span aria-hidden="true">·ices</span>.</p>
<p>On peut aussi prendre un texte légal, comme les conditions générales d’utilisation d’un service, et demander au LLM de le convertir en français Facile à lire et à comprendre (FALC).</p>
<h3>Manipulation de large jeux de données</h3>
<p>La puissance de calcul de ces outils, couplées à l’analyse textuelle, peut également service à classer de très nombreux commentaires pour en faciliter l’analyse ou l’exclusion (par exemple dans le cadre de la modération).</p>
<p>Ils peuvent ainsi aider à acheminer une question vers la personne la plus susceptible d’y répondre ou améliorer les réponses d’un moteur de recherche sur une base de connaissance bien délimitée.</p>
<h3>Appariement de consensus</h3>
<p>Un domaine dans lequel il est très pertinent d’établir du consensus linguistique c’est… la langue elle-même. Ces solutions améliorent tout ce que nous avons en termes de correction orthographique, grammaticale, ainsi que nos outils de traduction, du moins dans une compréhension universaliste de la langue (qu’on le veuille ou non, certaines spécificité seront intraduisibles car n’ayant pas d’équivalent dans la langue de destination).</p>
<h2>Ce qui m’inquiète</h2>
<p>Une fois qu’on a dit ce qui va pousser l’adoption de ce type de solutions, voyons les conséquences.</p>
<h2>Contribution invisible</h2>
<p>Dans la chaîne de production de valeur autour des LLM, on trouve bien sûr l’algorithme. Mais il n’est rien sans le renforcement par des humains (on parle de Reinforcement Learning from Human Feedback, aka RLHF). Pour ChatGPT, on parle de Kenyan payés 2$ de l’heure pour répondre à des scrutins et « éduquer » le système<sup class="footnote-ref"><a href="#fn1" id="fnref1">1</a></sup>.</p>
<p>Si, à termes, un LLM comme ChatGPT permet de supprimer des emplois en répondant à la place d’interlocuteur<span aria-hidden="true">·ices</span> humain<span aria-hidden="true">·es</span> à des questions, ce n’est que grâce à d’autres emplois, moins rémunérés, invisibles à un<span aria-hidden="true">·e</span> consommateur<span aria-hidden="true">·ice</span> occidental<span aria-hidden="true">·e</span>.</p>
<p>On reproduit le modèle de sous-traitance de l’industrie textile, dans des proportions inégalées mais en conservant sa toxicité.</p>
<p><ins datetime="2023-02-24T07:25:32.586Z">Je parle de toxicité du modèle, pas écologique. En termes d’impact écologique, l’industrie textile est difficile à dépasser.</ins></p>
<h2>Consensualité violente</h2>
<p>La contribution caractéristique de ces systèmes en fait de très bon baratineurs, statistiquement capables de nous dire avec une très grande certitude les choses qu’on veut entendre.</p>
<p>Et pour savoir ce que nous voulons entendre, ils se basent sur des corpus monstrueux de données.</p>
<p>Je ne sais pas qui fournit les données. Je ne connais pas la nature des données.</p>
<p>La plupart des contenus produits par des humain<span aria-hidden="true">·es</span> sont biaisés, violents, et je ne vois pas ce qui pourrait résulter d’une telle éducation, si ce n’est de nouveaux contenus consensuellement biaisés et violents.</p>
<p>Au mieux, s’ils ne sont ni biaisés ni violents, les contenus seront juste plats, globalement ininstructifs. Une usine à produire un consensus mou et sans réelle dialectique.</p>
<h2>À 100 à l’heure sur l’autoroute du totalitarisme</h2>
<p>Dans un monde où il est facile d’inonder le marché de l’information avec des données qui se contredisent, la démocratie ne peut pas survivre.</p>
<blockquote> <p>Quand tout le monde vous ment en permanence, le résultat n’est pas que vous croyez ces mensonges mais que plus personne ne croit plus rien (…). Un peuple qui ne peut plus rien croire ne peut se faire une opinion. Il est privé non seulement de sa capacité d’agir mais aussi de sa capacité de penser et de juger. Et avec un tel peuple, vous pouvez faire ce que vous voulez. <cite>Hannah Arendt</cite></p> </blockquote>
<h2>Autorité</h2>
<p>Quand je lis l’article d’un confrère ou d’une consoeur spécialisée dans un de mes domaines de prédilection, je m’accroche à certains éléments de savoir que je connais pour établir l’autorité de l’auteur<span aria-hidden="true">·ice</span> et ainsi savoir si je peux faire confiance à la partie du contenu qui m’échappe.</p>
<p>Cela n’est pas possible avec du contenu produit par ces systèmes. Le contenu peut être incroyablement juste et m’inspirer confiance puis, deux lignes plus loin, complètement faux, sans que je n’ai aucun moyen de le savoir.</p>
<p>Et contrairement à un<span aria-hidden="true">·e</span> professionnel<span aria-hidden="true">·le</span>, tant qu’il ne se trompe pas sur des choses incroyablement consensuelles, le système n’a pas à craindre pour sa réputation.</p>
<p>Pire, il peut produire les pires absurdités et dire, parce que c’est crédible, que <strong>vous</strong> les avez dites. Ou expliquer que votre entreprise produit un service qu’elle ne produit pas, et ainsi détériorer à la fois votre stratégie d’acquisition et votre réputation<sup class="footnote-ref"><a href="#fn2" id="fnref2">2</a></sup>. Il peut détruire sa propre autorité, mais aussi la nôtre.</p>
<h2>Loi de Brandolini</h2>
<blockquote> <p>la quantité d’énergie nécessaire pour réfuter des sottises […] est supérieure d’un ordre de grandeur à celle nécessaire pour les produire. <cite><a href="https://fr.wikipedia.org/wiki/Loi_de_Brandolini">Loi de Brandolini (Wikipédia)</a></cite></p> </blockquote>
<p>Nous n’avons pas la puissance de calcul nécessaire à détecter les absurdités qui seront dites pas ces LLM et les contredire efficacement.</p>
<h2>Boucles de rétro-alimentation</h2>
<p>Que se passe-t-il quand un LLM se nourrit en continu ? Soit il se retrouve exposé à des contenus produits par d’autres LLM, soit il continue à être alimenté par des données hiérarchisées par des scrutins alimentés par des personnes qui, elles-mêmes, sont exposées à des contenus produits par un LLM. Quel impact cela pourrait-il avoir sur la qualité des contenus ?</p>
<h2>Volumes</h2>
<p>Le <i lang="en">copywriting</i> était hier un métier avec divers critères de qualité. Avec ces innovations, c’est désormais un marché industriel où inonder les consommateurs de contenus a un coût fixe plutôt que variable.</p>
<p>Comment gérons-nous ce volume important de contenus dont il ne sera rapidement plus possible de savoir s’ils proviennent d’humains ou de machines (si tant est que ce soit possible aujourd’hui) ?</p>
<h2>Reproduction des inégalités</h2>
<p>Dans un monde où le marché est inondé de produits (ici des contenus textuels) de qualité médiocre, la capacité à distinguer la qualité n’a plus de valeur. Cela prend trop de temps. Il est plus rentable de chercher des sources de qualité.</p>
<p>Réussir au mérite est déjà difficile : demain, cela sera quasiment impossible. Non pas qu’on ne veuille pas vous laisser votre chance mais il est tout bonnement inconcevable de trouver la bonne prestation, le bon CV, le bon service, au milieu de l’ensemble des générations automatiques. Tout comme il est très difficile de trouver un bon produit sur une <i lang="en">marketplace</i>.</p>
<p>Les réseaux les plus établis, comme les cercles bourgeois et/ou les groupes de diplômé<span aria-hidden="true">·es</span>, continuent à servir de références. Des cercles où il vaut mieux être « fils » ou « fille de » pour entrer.</p>
<h2>Réseaux de distribution</h2>
<p>Quand le contenu n’a plus de valeur, c’est le réseau de distribution qui gagne en valeur d’usage. Les réseaux sociaux sont désormais payants ou en voie de l’être. Les éditeurs de livres augmentent leurs marges pour assumer de nouveaux coûts. Les réseaux immobiliers améliorent leur pourcentage vs. celui des agents. La mise en compétition de la production originale avec des copycats sans coût d’exploitation détruit tout espace de création.</p>
<p>Il est impossible de penser une stratégie de contenus non-quantitatives, car elle n’aura aucune visibilité dans la masse.</p>
<h2>Empoisonnement de l’espace public</h2>
<p>Si tous les contenus produits sont reconnus et acceptés comme étant des vérités car extrêmement consensuels, que se passe-t-il quand, volontairement ou non, le système est empoisonné ? Seules quelques franges d’extrême gauche dénoncent la manière dont les assistants vocaux valorisent déjà le capitalisme effréné. Qui détectera un glissement sémantique des IA, quand leur utilisation sera totalement normalisée et leur parole d’or ?</p>
<h2>Le prix de l’humanité</h2>
<p>Si nous arrivons à contourner les limites et risques actuels de ces systèmes et que la productivité mondiale croît, qui en bénéficiera ? Est-ce que nous travaillerons d’autant moins ?</p>
<p>Est-ce que les entreprises propriétaires de ces systèmes se mettent spontanément à payer des impôts dans les pays qui ont éduqué et maintenu en bonne santé et en sécurité les ingénieur<span aria-hidden="true">·euses</span> qui ont créés ces systèmes ?</p>
<p>Est-ce qu’elles en paient dans les pays où elles embauchent à bas coût des forçats pour en améliorer les réponses ?</p>
<p>Est-ce qu’elles paient des impôts pour rembourser les infrastructures sociales, éducatives, médicales, qui sont détruites par leur adoption ?</p>
</article>


<hr>

<footer>
<p>
<a href="/david/" title="Aller à l’accueil"><svg class="icon icon-home">
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-home"></use>
</svg> Accueil</a> •
<a href="/david/log/" title="Accès au flux RSS"><svg class="icon icon-rss2">
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-rss2"></use>
</svg> Suivre</a> •
<a href="http://larlet.com" title="Go to my English profile" data-instant><svg class="icon icon-user-tie">
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-user-tie"></use>
</svg> Pro</a> •
<a href="mailto:david%40larlet.fr" title="Envoyer un courriel"><svg class="icon icon-mail">
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-mail"></use>
</svg> Email</a> •
<abbr class="nowrap" title="Hébergeur : Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33184162340"><svg class="icon icon-hammer2">
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-hammer2"></use>
</svg> Légal</abbr>
</p>
<template id="theme-selector">
<form>
<fieldset>
<legend><svg class="icon icon-brightness-contrast">
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-brightness-contrast"></use>
</svg> Thème</legend>
<label>
<input type="radio" value="auto" name="chosen-color-scheme" checked> Auto
</label>
<label>
<input type="radio" value="dark" name="chosen-color-scheme"> Foncé
</label>
<label>
<input type="radio" value="light" name="chosen-color-scheme"> Clair
</label>
</fieldset>
</form>
</template>
</footer>
<script src="/static/david/js/instantpage-5.1.0.min.js" type="module"></script>
<script>
function loadThemeForm(templateName) {
const themeSelectorTemplate = document.querySelector(templateName)
const form = themeSelectorTemplate.content.firstElementChild
themeSelectorTemplate.replaceWith(form)

form.addEventListener('change', (e) => {
const chosenColorScheme = e.target.value
localStorage.setItem('theme', chosenColorScheme)
toggleTheme(chosenColorScheme)
})

const selectedTheme = localStorage.getItem('theme')
if (selectedTheme && selectedTheme !== 'undefined') {
form.querySelector(`[value="${selectedTheme}"]`).checked = true
}
}

const prefersColorSchemeDark = '(prefers-color-scheme: dark)'
window.addEventListener('load', () => {
let hasDarkRules = false
for (const styleSheet of Array.from(document.styleSheets)) {
let mediaRules = []
for (const cssRule of styleSheet.cssRules) {
if (cssRule.type !== CSSRule.MEDIA_RULE) {
continue
}
// WARNING: Safari does not have/supports `conditionText`.
if (cssRule.conditionText) {
if (cssRule.conditionText !== prefersColorSchemeDark) {
continue
}
} else {
if (cssRule.cssText.startsWith(prefersColorSchemeDark)) {
continue
}
}
mediaRules = mediaRules.concat(Array.from(cssRule.cssRules))
}

// WARNING: do not try to insert a Rule to a styleSheet you are
// currently iterating on, otherwise the browser will be stuck
// in a infinite loop…
for (const mediaRule of mediaRules) {
styleSheet.insertRule(mediaRule.cssText)
hasDarkRules = true
}
}
if (hasDarkRules) {
loadThemeForm('#theme-selector')
}
})
</script>
</body>
</html>

+ 5
- 0
cache/2023/482252d2b8806e99bc30ffab2b2c51c9/index.md
File diff suppressed because it is too large
View File


+ 187
- 0
cache/2023/660b2a27b116787ac44e536e6c9dbcd3/index.html View File

@@ -0,0 +1,187 @@
<!doctype html><!-- This is a valid HTML5 document. -->
<!-- Screen readers, SEO, extensions and so on. -->
<html lang="fr">
<!-- Has to be within the first 1024 bytes, hence before the `title` element
See: https://www.w3.org/TR/2012/CR-html5-20121217/document-metadata.html#charset -->
<meta charset="utf-8">
<!-- Why no `X-UA-Compatible` meta: https://stackoverflow.com/a/6771584 -->
<!-- The viewport meta is quite crowded and we are responsible for that.
See: https://codepen.io/tigt/post/meta-viewport-for-2015 -->
<meta name="viewport" content="width=device-width,initial-scale=1">
<!-- Required to make a valid HTML5 document. -->
<title>Vibe Driven Development (archive) — David Larlet</title>
<meta name="description" content="Publication mise en cache pour en conserver une trace.">
<!-- That good ol' feed, subscribe :). -->
<link rel="alternate" type="application/atom+xml" title="Feed" href="/david/log/">
<!-- Generated from https://realfavicongenerator.net/ such a mess. -->
<link rel="apple-touch-icon" sizes="180x180" href="/static/david/icons2/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/static/david/icons2/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/static/david/icons2/favicon-16x16.png">
<link rel="manifest" href="/static/david/icons2/site.webmanifest">
<link rel="mask-icon" href="/static/david/icons2/safari-pinned-tab.svg" color="#07486c">
<link rel="shortcut icon" href="/static/david/icons2/favicon.ico">
<meta name="msapplication-TileColor" content="#f7f7f7">
<meta name="msapplication-config" content="/static/david/icons2/browserconfig.xml">
<meta name="theme-color" content="#f7f7f7" media="(prefers-color-scheme: light)">
<meta name="theme-color" content="#272727" media="(prefers-color-scheme: dark)">
<!-- Documented, feel free to shoot an email. -->
<link rel="stylesheet" href="/static/david/css/style_2021-01-20.css">
<!-- See https://www.zachleat.com/web/comprehensive-webfonts/ for the trade-off. -->
<link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
<link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
<link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
<script>
function toggleTheme(themeName) {
document.documentElement.classList.toggle(
'forced-dark',
themeName === 'dark'
)
document.documentElement.classList.toggle(
'forced-light',
themeName === 'light'
)
}
const selectedTheme = localStorage.getItem('theme')
if (selectedTheme !== 'undefined') {
toggleTheme(selectedTheme)
}
</script>

<meta name="robots" content="noindex, nofollow">
<meta content="origin-when-cross-origin" name="referrer">
<!-- Canonical URL for SEO purposes -->
<link rel="canonical" href="https://www.robinrendle.com/notes/vibe-driven-development/">

<body class="remarkdown h1-underline h2-underline h3-underline em-underscore hr-center ul-star pre-tick" data-instant-intensity="viewport-all">


<article>
<header>
<h1>Vibe Driven Development</h1>
</header>
<nav>
<p class="center">
<a href="/david/" title="Aller à l’accueil"><svg class="icon icon-home">
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-home"></use>
</svg> Accueil</a> •
<a href="https://www.robinrendle.com/notes/vibe-driven-development/" title="Lien vers le contenu original">Source originale</a>
</p>
</nav>
<hr>
<p>Building a great product is a matter of two questions: How should we measure progress? And what should we build next?</p>
<p>That first question is the most important because how you collect data and what you count as success influences everything else; if your organization is measuring shit then they’ll build nothing but shit. And most product orgs suck and churn out garbage projects because they waste so much time thinking in terms of junk data and half baked user inputs to inform their decisions.</p>
<p>(Show me what your org measures and I’ll show ya the crappy product that comes out the other side.)</p>
<p>The problem underlying all this is that when it comes to building a product, all data is garbage, a lie, or measuring the wrong thing. Folks will be obsessed with clicks and charts and NPS scores—the NFTs of product management—and in this sea of noise they believe they can see the product clearly. There are courses and books and talks all about measuring happiness and growth—surveys! surveys! surveys!—with everyone in the field believing that they’ve built a science when they’ve really built a cult.</p>
<p>(No great product has ever been made because of the answers collected in a dumb user survey.)</p>
<p>So how do you measure progress then?</p>
<p>I guess customers could tell us the answer, right? Well, no. Sure, you can talk to customers to see <em>how</em> they struggle but they cannot tell you <em>why</em> they struggle. They’ll have terrible ideas for improvements like “I really wish AI could show me all the relevant things on this page” or “I want more dashboards” where the answer is always much simpler than that. Customer feedback is a geiger counter: they can tell you about the problem coming your way but not how to prevent it.</p>
<p>(Customers, like data, will always mislead us on what to build next.)</p>
<p>See, I don’t think you can build a great product for customers. Yes, yes, yes; you can make billions of dollars building something for customers and go live on a beach in the south of France. But you’ll have built junk in the process; the product will suffer if you build it for customers. You’ll spend every waking moment trying to measure user happiness and score feelings in a spreadsheet and not improving the product.</p>
<p>In every product org it feels as if folks mistake qualitative data—stuff that can’t be measured like feelings—with quantitative data—stuff that can be measured like numbers or time or temperature. They’ll say “this user is 4.5% happy” and, okay, great. Now what? This numerical value sure is bullshit but it’s not even helpful bullshit because these numbers never explain why things suck.</p>
<p>(Just look at the product and it will tell you why it sucks.)</p>
<p>It comes down to this annoying, upsetting, stupid fact: the only way to build a great product is to use it every day, to stare at it, to hold it in your hands to feel its lumps. The data and customers will lie to you but the product never will. And most product orgs suck because they simply don’t use the products that they’re building; they ship incremental nothings without direction because they’re looking at spreadsheets all day long filled with junk data nothings.</p>
<p>See, I don’t know much about product stuff. I have no experience as a product manager, no experience running teams or building a company. Take everything I say here with an enormous silo of salt. But: I don’t care what the data shows me and I’m not sure I ever will. You can show me charts and spreadsheets all day long and I will not care. Tell me what your gut says instead after relentless experience of the product every day. This is the only way to see the world clearly.</p>
<p>Perhaps arbitrary, perhaps a bit naive, but the answer is <a href="https://weeknotes.buttondown.email/archive/trading-time-for-visibility/">vibe-driven development</a>. If you have good experience of the product, your vibes will lead you down the right path of what to build next. I think this is why small orgs make better things faster than large orgs; they’re all about the vibes. Large orgs are bloated and frozen in place because they spend all their time talking about bullshit numbers instead of looking at the product. Whilst smaller orgs typically aren’t run by the numbers, they’re so focused on the product because they have to.</p>
<p>So when we use data to drive development it always leads us down the wrong path, it forces us to look in all the wrong places for the answers. Customers can tell you what sucks, sure. Dashboards and spreadsheets can show you attrition or whatever, yes. But these inputs can’t build a vision of your product for you. They’re mostly distractions and any moment with your eye off the product is a moment lost to making it better.</p>
<p>You can only build a great product if you care more for the vibes than for the data.</p>
</article>


<hr>

<footer>
<p>
<a href="/david/" title="Aller à l’accueil"><svg class="icon icon-home">
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-home"></use>
</svg> Accueil</a> •
<a href="/david/log/" title="Accès au flux RSS"><svg class="icon icon-rss2">
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-rss2"></use>
</svg> Suivre</a> •
<a href="http://larlet.com" title="Go to my English profile" data-instant><svg class="icon icon-user-tie">
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-user-tie"></use>
</svg> Pro</a> •
<a href="mailto:david%40larlet.fr" title="Envoyer un courriel"><svg class="icon icon-mail">
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-mail"></use>
</svg> Email</a> •
<abbr class="nowrap" title="Hébergeur : Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33184162340"><svg class="icon icon-hammer2">
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-hammer2"></use>
</svg> Légal</abbr>
</p>
<template id="theme-selector">
<form>
<fieldset>
<legend><svg class="icon icon-brightness-contrast">
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-brightness-contrast"></use>
</svg> Thème</legend>
<label>
<input type="radio" value="auto" name="chosen-color-scheme" checked> Auto
</label>
<label>
<input type="radio" value="dark" name="chosen-color-scheme"> Foncé
</label>
<label>
<input type="radio" value="light" name="chosen-color-scheme"> Clair
</label>
</fieldset>
</form>
</template>
</footer>
<script src="/static/david/js/instantpage-5.1.0.min.js" type="module"></script>
<script>
function loadThemeForm(templateName) {
const themeSelectorTemplate = document.querySelector(templateName)
const form = themeSelectorTemplate.content.firstElementChild
themeSelectorTemplate.replaceWith(form)

form.addEventListener('change', (e) => {
const chosenColorScheme = e.target.value
localStorage.setItem('theme', chosenColorScheme)
toggleTheme(chosenColorScheme)
})

const selectedTheme = localStorage.getItem('theme')
if (selectedTheme && selectedTheme !== 'undefined') {
form.querySelector(`[value="${selectedTheme}"]`).checked = true
}
}

const prefersColorSchemeDark = '(prefers-color-scheme: dark)'
window.addEventListener('load', () => {
let hasDarkRules = false
for (const styleSheet of Array.from(document.styleSheets)) {
let mediaRules = []
for (const cssRule of styleSheet.cssRules) {
if (cssRule.type !== CSSRule.MEDIA_RULE) {
continue
}
// WARNING: Safari does not have/supports `conditionText`.
if (cssRule.conditionText) {
if (cssRule.conditionText !== prefersColorSchemeDark) {
continue
}
} else {
if (cssRule.cssText.startsWith(prefersColorSchemeDark)) {
continue
}
}
mediaRules = mediaRules.concat(Array.from(cssRule.cssRules))
}

// WARNING: do not try to insert a Rule to a styleSheet you are
// currently iterating on, otherwise the browser will be stuck
// in a infinite loop…
for (const mediaRule of mediaRules) {
styleSheet.insertRule(mediaRule.cssText)
hasDarkRules = true
}
}
if (hasDarkRules) {
loadThemeForm('#theme-selector')
}
})
</script>
</body>
</html>

+ 20
- 0
cache/2023/660b2a27b116787ac44e536e6c9dbcd3/index.md View File

@@ -0,0 +1,20 @@
title: Vibe Driven Development
url: https://www.robinrendle.com/notes/vibe-driven-development/
hash_url: 660b2a27b116787ac44e536e6c9dbcd3

<p>Building a great product is a matter of two questions: How should we measure progress? And what should we build next?</p>
<p>That first question is the most important because how you collect data and what you count as success influences everything else; if your organization is measuring shit then they’ll build nothing but shit. And most product orgs suck and churn out garbage projects because they waste so much time thinking in terms of junk data and half baked user inputs to inform their decisions.</p>
<p>(Show me what your org measures and I’ll show ya the crappy product that comes out the other side.)</p>
<p>The problem underlying all this is that when it comes to building a product, all data is garbage, a lie, or measuring the wrong thing. Folks will be obsessed with clicks and charts and NPS scores—the NFTs of product management—and in this sea of noise they believe they can see the product clearly. There are courses and books and talks all about measuring happiness and growth—surveys! surveys! surveys!—with everyone in the field believing that they’ve built a science when they’ve really built a cult.</p>
<p>(No great product has ever been made because of the answers collected in a dumb user survey.)</p>
<p>So how do you measure progress then?</p>
<p>I guess customers could tell us the answer, right? Well, no. Sure, you can talk to customers to see <em>how</em> they struggle but they cannot tell you <em>why</em> they struggle. They’ll have terrible ideas for improvements like “I really wish AI could show me all the relevant things on this page” or “I want more dashboards” where the answer is always much simpler than that. Customer feedback is a geiger counter: they can tell you about the problem coming your way but not how to prevent it.</p>
<p>(Customers, like data, will always mislead us on what to build next.)</p>
<p>See, I don’t think you can build a great product for customers. Yes, yes, yes; you can make billions of dollars building something for customers and go live on a beach in the south of France. But you’ll have built junk in the process; the product will suffer if you build it for customers. You’ll spend every waking moment trying to measure user happiness and score feelings in a spreadsheet and not improving the product.</p>
<p>In every product org it feels as if folks mistake qualitative data—stuff that can’t be measured like feelings—with quantitative data—stuff that can be measured like numbers or time or temperature. They’ll say “this user is 4.5% happy” and, okay, great. Now what? This numerical value sure is bullshit but it’s not even helpful bullshit because these numbers never explain why things suck.</p>
<p>(Just look at the product and it will tell you why it sucks.)</p>
<p>It comes down to this annoying, upsetting, stupid fact: the only way to build a great product is to use it every day, to stare at it, to hold it in your hands to feel its lumps. The data and customers will lie to you but the product never will. And most product orgs suck because they simply don’t use the products that they’re building; they ship incremental nothings without direction because they’re looking at spreadsheets all day long filled with junk data nothings.</p>
<p>See, I don’t know much about product stuff. I have no experience as a product manager, no experience running teams or building a company. Take everything I say here with an enormous silo of salt. But: I don’t care what the data shows me and I’m not sure I ever will. You can show me charts and spreadsheets all day long and I will not care. Tell me what your gut says instead after relentless experience of the product every day. This is the only way to see the world clearly.</p>
<p>Perhaps arbitrary, perhaps a bit naive, but the answer is <a href="https://weeknotes.buttondown.email/archive/trading-time-for-visibility/">vibe-driven development</a>. If you have good experience of the product, your vibes will lead you down the right path of what to build next. I think this is why small orgs make better things faster than large orgs; they’re all about the vibes. Large orgs are bloated and frozen in place because they spend all their time talking about bullshit numbers instead of looking at the product. Whilst smaller orgs typically aren’t run by the numbers, they’re so focused on the product because they have to.</p>
<p>So when we use data to drive development it always leads us down the wrong path, it forces us to look in all the wrong places for the answers. Customers can tell you what sucks, sure. Dashboards and spreadsheets can show you attrition or whatever, yes. But these inputs can’t build a vision of your product for you. They’re mostly distractions and any moment with your eye off the product is a moment lost to making it better.</p>
<p>You can only build a great product if you care more for the vibes than for the data.</p>

+ 219
- 0
cache/2023/9718ae2062146285e1c4f406240e04af/index.html View File

@@ -0,0 +1,219 @@
<!doctype html><!-- This is a valid HTML5 document. -->
<!-- Screen readers, SEO, extensions and so on. -->
<html lang="fr">
<!-- Has to be within the first 1024 bytes, hence before the `title` element
See: https://www.w3.org/TR/2012/CR-html5-20121217/document-metadata.html#charset -->
<meta charset="utf-8">
<!-- Why no `X-UA-Compatible` meta: https://stackoverflow.com/a/6771584 -->
<!-- The viewport meta is quite crowded and we are responsible for that.
See: https://codepen.io/tigt/post/meta-viewport-for-2015 -->
<meta name="viewport" content="width=device-width,initial-scale=1">
<!-- Required to make a valid HTML5 document. -->
<title>An update on Robust Client-Side JavaScript (archive) — David Larlet</title>
<meta name="description" content="Publication mise en cache pour en conserver une trace.">
<!-- That good ol' feed, subscribe :). -->
<link rel="alternate" type="application/atom+xml" title="Feed" href="/david/log/">
<!-- Generated from https://realfavicongenerator.net/ such a mess. -->
<link rel="apple-touch-icon" sizes="180x180" href="/static/david/icons2/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/static/david/icons2/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/static/david/icons2/favicon-16x16.png">
<link rel="manifest" href="/static/david/icons2/site.webmanifest">
<link rel="mask-icon" href="/static/david/icons2/safari-pinned-tab.svg" color="#07486c">
<link rel="shortcut icon" href="/static/david/icons2/favicon.ico">
<meta name="msapplication-TileColor" content="#f7f7f7">
<meta name="msapplication-config" content="/static/david/icons2/browserconfig.xml">
<meta name="theme-color" content="#f7f7f7" media="(prefers-color-scheme: light)">
<meta name="theme-color" content="#272727" media="(prefers-color-scheme: dark)">
<!-- Documented, feel free to shoot an email. -->
<link rel="stylesheet" href="/static/david/css/style_2021-01-20.css">
<!-- See https://www.zachleat.com/web/comprehensive-webfonts/ for the trade-off. -->
<link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
<link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
<link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
<script>
function toggleTheme(themeName) {
document.documentElement.classList.toggle(
'forced-dark',
themeName === 'dark'
)
document.documentElement.classList.toggle(
'forced-light',
themeName === 'light'
)
}
const selectedTheme = localStorage.getItem('theme')
if (selectedTheme !== 'undefined') {
toggleTheme(selectedTheme)
}
</script>

<meta name="robots" content="noindex, nofollow">
<meta content="origin-when-cross-origin" name="referrer">
<!-- Canonical URL for SEO purposes -->
<link rel="canonical" href="https://molily.de/update-on-robust-javascript/">

<body class="remarkdown h1-underline h2-underline h3-underline em-underscore hr-center ul-star pre-tick" data-instant-intensity="viewport-all">


<article>
<header>
<h1>An update on Robust Client-Side JavaScript</h1>
</header>
<nav>
<p class="center">
<a href="/david/" title="Aller à l’accueil"><svg class="icon icon-home">
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-home"></use>
</svg> Accueil</a> •
<a href="https://molily.de/update-on-robust-javascript/" title="Lien vers le contenu original">Source originale</a>
</p>
</nav>
<hr>
<p>In 2017, I published the online book <strong><a href="/robust-javascript/">Robust Client-Side JavaScript – A Developer’s Guide</a></strong>. More than five years later, I think my advice is still valuable. JavaScript as a language has not changed much when it come to techniques for writing robust code.</p>
<p>At the moment I do not have the time for a substantial book update. In this post, I would like to describe how I regard the whole issue today and how I would restructure the book today.</p>
<p>Recently, yet another debate sparked over single page apps, client-side frameworks like <a href="https://www.zachleat.com/web/react-criticism/">React</a> and client-side versus server-side rendering. The arguments are not new. During the last decade, I found criticism of the dominant client-side JavaScript usage necessary and worthwhile. Especially proponents of progressive enhancement challenged the JavaScript ecosystem. Yet the mainstream did not adapt patterns for robustness and performance. Web sites became slower, more fragile, error-prone, inaccessible and exclusive largely due to client-side JavaScript misuse.</p>
<p>There always has been a class of full-stack, “universal” JavaScript frameworks with a focus on speed and simplicity – think of <a href="https://markojs.com/">Marko</a>, <a href="https://astro.build/">Astro</a>, <a href="https://fresh.deno.dev/">Fresh</a> or <a href="https://qwik.builder.io/">Qwik</a>. They render HTML on the server and aim to ship the minimal necessary amount of JavaScript to the client. The client-side JavaScript then picks up where the server-side JavaScript left off, ideally without duplicating the server-side logic. More and more frameworks adapt such a workflow. But the mainstream is still dominated by React monoliths that comprises megabytes of client-side JavaScript.</p>
<p>Unfortunately, the chasm between the opposite sides of the debate grew wider. The groups are no longer listening and talking to each other, but mock and ridicule each other while talking to their in-group. Echo chambers in social media amplify this divisive discourse.</p>
<p>Certain posts from prominent JavaScript critics are filled with scathing polemic. They personally attack JavaScript project maintainers, calling them <a href="https://infrequently.org/2023/02/the-market-for-lemons/">liars, fraudsters and grifters</a> because they only recently have “discovered” the downsides of single page apps.</p>
<p>I am all for radical criticism, especially targeted at billion-dollar tech corporations and powerful project leaders who <a href="https://hachyderm.io/@zachleat@zachleat.com/109830049815165514">try to silence critics</a>. We need to hold them accountable for tech that produces harmful, subpar web experiences. They deserve their decent share of “told you so”.</p>
<p>It is frustrating that influential people did not listen to the facts or did not deliver on their own promises. Will it help to call them fraudsters in the moment they start to acknowledge the facts? I believe vitriol makes the situation even more dire. I am disappointed that smart people who made valueable contributions to the web engage in mudslinging.</p>
<p>Only a few note that such a behavior may harm the developer community that is already toxic and exclusive:</p>
<blockquote cite="https://hachyderm.io/@hbuchel/109830004886148541"> <p>I’ve been wailing on about <abbr title="single page apps">SPA</abbr> frameworks recently (like a lot of us have, probably because we’ve found more of our people over here) but just to be clear:</p> <p>The world sucks right now. Get a job where you can. If React or Vue or Angular or Next or whatever gets you a job, then that is absolutely fantastic. If you are new in web dev and it introduces you to a love for the web, that is also fantastic.</p> <p>You’re going to spend a lot of time as a web developer figuring out where web experiences are broken for humans and how your platform or tech choices affect that. That always has been and is always going to be true.</p> <p>Sometimes this conversation can veer into the “sounding self righteous” lane which gives me the ick.</p>
<p>– <a href="https://hachyderm.io/@hbuchel/109830004886148541">Heather Buchel</a></p> </blockquote>
<blockquote cite="https://social.lol/@sophie/109836319615664190"> <p>There’s a lot of fair criticism of React floating around at the mo. My one request is that people take care to separate “The React Community” from the people who just get paid to build things in React. I build stuff in React for money, but I do it as accessibly and consciously as I can. I know it’s far from ideal but that’s what we use. Switching to Not React isn’t really an option in an org of our size. So please avoid mud-slinging and name-calling, and keep the discussion civil.</p> <p>I think the biggest takeaway is that you probably don’t need React; and if you really do, and you’re sure, make sure you’re aware of the drawbacks and have plans to mitigate them.</p> <p>– <a href="https://social.lol/@sophie/109836319615664190">Sophie Koonin</a></p> </blockquote>
<p>What a year, huh? – Captain, it’s February!</p>
<p>Anyway, where were we?</p>
<p>My 2017 book was an attempt to mediate between the different camps of the debate on client-side JavaScript usage. Much advice from JavaScript critics was and is abstract for the sole reason that you need a robust site architecture in the first place before writing any robust client-side JavaScript code. With my book, I wanted to teach patterns any developer who writes client-side JavaScript can apply in their daily work regardless of the framework used.</p>
<p>Around 2015 and 2016, several front-end developers wondered how to properly address JavaScript failure. <a href="https://molily.de/javascript-failure/">What happens when a JavaScript enhancement fails?</a> These essential and much needed discussions urged me to write a book on robust JavaScript.</p>
<p>Unfortunately, only a few developers and projects picked up the ideas and integrated them into their work. Preventing and dealing with failing JavaScript is still an afterthought for many projects, frameworks and libraries. We need to continuously explore how practical progressive enhancement in JavaScript looks like.</p>
<p>In 2017, I also wanted to emphasize that progressive enhancement is much more than server-side rendering. The discussion on progressive enhancement regarding JavaScript still revolves around server-side rendering versus client-side rendering. For good reason, but this is where progressive enhancement starts.</p>
<p>It is a first step to use a framework that renders fully-functional HTML documents on the server. A frameworks that understands your code, identifies client-side interactivity and figures out the least amount of JavaScript that needs to be shipped to the client.</p>
<p>It does not mean you are done with it. Adding client-side JavaScript should not be one monolithic enhancement step from 0 to 100, but many small deliberate and considerate steps. That is why it is called progressive enhancement.</p>
<p>So, where are we today? I welcome the new discussions on better web site architectures and sensible JavaScript usage. The industry is already shifting and new universal JavaScript frameworks are pushing the existing ecosystems.</p>
<p>My 2017 book concluded with <a href="/robust-javascript/#writing-less-javascript">Writing less JavaScript</a>:</p>
<blockquote> <p>An important skill of a front-end developer is to know when not to solve a problem with client-side JavaScript. It is always more robust to solve a problem further down in the stack.</p> <p>If all techniques and tools did not help you to write robust JavaScript, consider reducing the code complexity and the amount of code. In the last resort, reduce the usage of client-side JavaScript. Find simpler solutions that rely on HTML, CSS and server-side logic alone.</p> </blockquote>
<p>Today I would turn the reasoning upside down. Reducing client-side JavaScript is the most effective technique to prevent JavaScript failure. The most robust client-side JavaScript is the JavaScript that is never written, never shipped to the client and never executed. (<a href="https://knowyourmeme.com/memes/roll-safe">Clever, huh?</a>)</p>
<p>Apart from that, what techniques are essential today to write robust JavaScript?</p>
<p>I’ve mentioned <strong>TypeScript</strong> as a compile-to-JavaScript language in the book. Since 2017, TypeScript conquered the JavaScript world, superseded other compile-to-JavaScript languages and became a de-facto standard for a great share of libraries and frameworks.</p>
<p>TypeScript is the single tool that made my JavaScript significantly more robust in the last couple of years. It helps me to design cascades of operations that may fail and helps me to implement the success and error handling. Strict typing forces me to think twice and write cautious code.</p>
<p>With the goal of writing robust JavaScript in mind, we should utilize TypeScript as a static code checker for JavaScript – like ESLint.</p>
<p>TypeScript is also a language that is a superset of JavaScript. It is also a program that compiles (transpiles) this language to JavaScript. But you do not have to use these parts to get most benefits.</p>
<p>You can check plain JavaScript files with the TypeScript type checker. It understands plain JavaScript well enough to spot my lapses and lazy thinking. You can <a href="https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html">define types and add type annotations with JSDoc</a>.</p>
<p>While there are benefits to write <code class="language-plaintext highlighter-rouge">.ts</code> files with TypeScript syntax, this is not necessary to get started. In several projects, I have hardly written any <code class="language-plaintext highlighter-rouge">.ts</code> file, but TypeScript is an essential development tool.</p>
<p>My advice is to install an editor like Visual Studio Code and start using TypeScript in your <code class="language-plaintext highlighter-rouge">.js</code> or <code class="language-plaintext highlighter-rouge">.jsx</code> or <code class="language-plaintext highlighter-rouge">.vue</code> or <code class="language-plaintext highlighter-rouge">.svelte</code> files today.</p>
<p>I understand that TypeScript adds a heavy burden for web developers who already struggle with JavaScript and its toolchains. (I guess that is, ehm, everyone here?) Fortunately, editors, libraries and frameworks make it easy to integrate typed code gradually so you can learn as you go.</p>
<p>My 2017 book featured several chapters on <strong>automated testing</strong> from a high-level perspective. Since then, I gained more experience on automatic testing of web sites in general and client-side JavaScript in particular.</p>
<p>In 2021, I published an extensive book on <strong><a href="https://testing-angular.com/">Testing Angular</a></strong>. It is the spiritual successor of <cite>Robust JavaScript</cite>.</p>
<p>The fact that the book deals with Angular is partly consequence, partly coincidence. I had been working on large Angular projects for clients who demanded (and could afford) technical robustness and understood test automation. Plus, Angular is built with testability in mind and the community values well-tested, robust code.</p>
<p>While the second book goes into all necessary details and Angular specifics, it was the big picture that inspired me. How can testing help us to make better web sites that do not let the user down, but empower them? How can we write better, more robust JavaScript through testing?</p>
<p>So eventually I wrote <cite>Testing Angular</cite> for the same reason I wrote <cite>Robust JavaScript</cite>: I wanted to explore and teach writing better web experiences. Preventing JavaScript failure is still my white whale.</p>
<p>Fortunately, testing tools improved since 2017 and both end-to-end testing as well as JavaScript unit and integration testing got more approachable and reliable. Today I put much more emphasis on automated testing to make JavaScript robust.</p>
<p>Angular is the “special occasion” framework in the JavaScript world. While <a href="https://almanac.httparchive.org/en/2022/javascript#libraries-and-frameworks">jQuery is used on 81% and React is used on 8% of the web sites analyzed</a>, Angular is suitable for heavy-weight corporate intranet applications with a restricted audience using desktop computers.</p>
<p>Especially JavaScript critics shake their head when Angular is mentioned. It ships larger amounts of client-side JavaScript than other frameworks. While it has rudimentary server-side rendering, it is not a practically viable default yet. Nonetheless, I think the Angular community listens to criticism and innovates.</p>
<p>Angular has some architectural advantages that allows it to evolve in order to improve the site’s robustness and thereby the user experience. The core of Angular is a compiler. Like the Svelte compiler, it transforms your high-level, declarative and human-readable code into low-level, imperative and concise code that is shipped to the browser.</p>
<p>The Angular team can optimize the compiler to produce more efficient and less code. In fact, the team recently rewrote the whole compiler and rendering engine. Thanks to the ahead-of-time compilation, there is dormant potential in Angular.</p>
<p>I am excited that the Angular ecosystem catches up with projects like <a href="https://github.com/analogjs/analog">Analog.js</a>, a full-stack framework that compares itself to SvelteKit, Nuxt and Next.js. Although Angular will most likely stick with the single page application architecture, folks from the Angular community are building next-generation frameworks. For example, Miško Hevery, the creator of the original AngularJS framework and co-creator of Angular, now works on Qwik.</p>
<p>While I still deem it necessary to teach basic defensive coding techniques, one cannot talk about robust client-side JavaScript without discussing the whole web site architecture. I have done so in several blog posts, but not prominently in <cite>Robust JavaScript</cite>.</p>
<p>Client-side JavaScript affects performance and accessibility, and I have realized that these are essential aspects of robustness as well. If JavaScript is freezing a mobile browser for 20 seconds, the site is not usable, let alone robust. If a single page application breaks browser navigation features that users of assistive technologies rely on in particular, the site is not robust. And so on.</p>
<p>All things considered, I think we are in a crucial phase of turmoil. My hope is that the JavaScript community convenes in a respectful and productive way, takes criticism seriously and makes radical technical and social changes.</p>
</div>
</article>


<hr>

<footer>
<p>
<a href="/david/" title="Aller à l’accueil"><svg class="icon icon-home">
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-home"></use>
</svg> Accueil</a> •
<a href="/david/log/" title="Accès au flux RSS"><svg class="icon icon-rss2">
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-rss2"></use>
</svg> Suivre</a> •
<a href="http://larlet.com" title="Go to my English profile" data-instant><svg class="icon icon-user-tie">
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-user-tie"></use>
</svg> Pro</a> •
<a href="mailto:david%40larlet.fr" title="Envoyer un courriel"><svg class="icon icon-mail">
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-mail"></use>
</svg> Email</a> •
<abbr class="nowrap" title="Hébergeur : Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33184162340"><svg class="icon icon-hammer2">
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-hammer2"></use>
</svg> Légal</abbr>
</p>
<template id="theme-selector">
<form>
<fieldset>
<legend><svg class="icon icon-brightness-contrast">
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-brightness-contrast"></use>
</svg> Thème</legend>
<label>
<input type="radio" value="auto" name="chosen-color-scheme" checked> Auto
</label>
<label>
<input type="radio" value="dark" name="chosen-color-scheme"> Foncé
</label>
<label>
<input type="radio" value="light" name="chosen-color-scheme"> Clair
</label>
</fieldset>
</form>
</template>
</footer>
<script src="/static/david/js/instantpage-5.1.0.min.js" type="module"></script>
<script>
function loadThemeForm(templateName) {
const themeSelectorTemplate = document.querySelector(templateName)
const form = themeSelectorTemplate.content.firstElementChild
themeSelectorTemplate.replaceWith(form)

form.addEventListener('change', (e) => {
const chosenColorScheme = e.target.value
localStorage.setItem('theme', chosenColorScheme)
toggleTheme(chosenColorScheme)
})

const selectedTheme = localStorage.getItem('theme')
if (selectedTheme && selectedTheme !== 'undefined') {
form.querySelector(`[value="${selectedTheme}"]`).checked = true
}
}

const prefersColorSchemeDark = '(prefers-color-scheme: dark)'
window.addEventListener('load', () => {
let hasDarkRules = false
for (const styleSheet of Array.from(document.styleSheets)) {
let mediaRules = []
for (const cssRule of styleSheet.cssRules) {
if (cssRule.type !== CSSRule.MEDIA_RULE) {
continue
}
// WARNING: Safari does not have/supports `conditionText`.
if (cssRule.conditionText) {
if (cssRule.conditionText !== prefersColorSchemeDark) {
continue
}
} else {
if (cssRule.cssText.startsWith(prefersColorSchemeDark)) {
continue
}
}
mediaRules = mediaRules.concat(Array.from(cssRule.cssRules))
}

// WARNING: do not try to insert a Rule to a styleSheet you are
// currently iterating on, otherwise the browser will be stuck
// in a infinite loop…
for (const mediaRule of mediaRules) {
styleSheet.insertRule(mediaRule.cssText)
hasDarkRules = true
}
}
if (hasDarkRules) {
loadThemeForm('#theme-selector')
}
})
</script>
</body>
</html>

+ 14
- 0
cache/2023/9718ae2062146285e1c4f406240e04af/index.md View File

@@ -0,0 +1,14 @@
title: An update on Robust Client-Side JavaScript
url: https://molily.de/update-on-robust-javascript/
hash_url: 9718ae2062146285e1c4f406240e04af

<p>In 2017, I published the online book <strong><a href="/robust-javascript/">Robust Client-Side JavaScript – A Developer’s Guide</a></strong>. More than five years later, I think my advice is still valuable. JavaScript as a language has not changed much when it come to techniques for writing robust code.</p> <p>At the moment I do not have the time for a substantial book update. In this post, I would like to describe how I regard the whole issue today and how I would restructure the book today.</p>
<p>Recently, yet another debate sparked over single page apps, client-side frameworks like <a href="https://www.zachleat.com/web/react-criticism/">React</a> and client-side versus server-side rendering. The arguments are not new. During the last decade, I found criticism of the dominant client-side JavaScript usage necessary and worthwhile. Especially proponents of progressive enhancement challenged the JavaScript ecosystem. Yet the mainstream did not adapt patterns for robustness and performance. Web sites became slower, more fragile, error-prone, inaccessible and exclusive largely due to client-side JavaScript misuse.</p> <p>There always has been a class of full-stack, “universal” JavaScript frameworks with a focus on speed and simplicity – think of <a href="https://markojs.com/">Marko</a>, <a href="https://astro.build/">Astro</a>, <a href="https://fresh.deno.dev/">Fresh</a> or <a href="https://qwik.builder.io/">Qwik</a>. They render HTML on the server and aim to ship the minimal necessary amount of JavaScript to the client. The client-side JavaScript then picks up where the server-side JavaScript left off, ideally without duplicating the server-side logic. More and more frameworks adapt such a workflow. But the mainstream is still dominated by React monoliths that comprises megabytes of client-side JavaScript.</p>
<p>Unfortunately, the chasm between the opposite sides of the debate grew wider. The groups are no longer listening and talking to each other, but mock and ridicule each other while talking to their in-group. Echo chambers in social media amplify this divisive discourse.</p> <p>Certain posts from prominent JavaScript critics are filled with scathing polemic. They personally attack JavaScript project maintainers, calling them <a href="https://infrequently.org/2023/02/the-market-for-lemons/">liars, fraudsters and grifters</a> because they only recently have “discovered” the downsides of single page apps.</p> <p>I am all for radical criticism, especially targeted at billion-dollar tech corporations and powerful project leaders who <a href="https://hachyderm.io/@zachleat@zachleat.com/109830049815165514">try to silence critics</a>. We need to hold them accountable for tech that produces harmful, subpar web experiences. They deserve their decent share of “told you so”.</p> <p>It is frustrating that influential people did not listen to the facts or did not deliver on their own promises. Will it help to call them fraudsters in the moment they start to acknowledge the facts? I believe vitriol makes the situation even more dire. I am disappointed that smart people who made valueable contributions to the web engage in mudslinging.</p> <p>Only a few note that such a behavior may harm the developer community that is already toxic and exclusive:</p> <blockquote cite="https://hachyderm.io/@hbuchel/109830004886148541"> <p>I’ve been wailing on about <abbr title="single page apps">SPA</abbr> frameworks recently (like a lot of us have, probably because we’ve found more of our people over here) but just to be clear:</p> <p>The world sucks right now. Get a job where you can. If React or Vue or Angular or Next or whatever gets you a job, then that is absolutely fantastic. If you are new in web dev and it introduces you to a love for the web, that is also fantastic.</p> <p>You’re going to spend a lot of time as a web developer figuring out where web experiences are broken for humans and how your platform or tech choices affect that. That always has been and is always going to be true.</p> <p>Sometimes this conversation can veer into the “sounding self righteous” lane which gives me the ick.</p>
<p>– <a href="https://hachyderm.io/@hbuchel/109830004886148541">Heather Buchel</a></p> </blockquote> <blockquote cite="https://social.lol/@sophie/109836319615664190"> <p>There’s a lot of fair criticism of React floating around at the mo. My one request is that people take care to separate “The React Community” from the people who just get paid to build things in React. I build stuff in React for money, but I do it as accessibly and consciously as I can. I know it’s far from ideal but that’s what we use. Switching to Not React isn’t really an option in an org of our size. So please avoid mud-slinging and name-calling, and keep the discussion civil.</p> <p>I think the biggest takeaway is that you probably don’t need React; and if you really do, and you’re sure, make sure you’re aware of the drawbacks and have plans to mitigate them.</p> <p>– <a href="https://social.lol/@sophie/109836319615664190">Sophie Koonin</a></p> </blockquote>
<p>What a year, huh? – Captain, it’s February!</p> <p>Anyway, where were we?</p> <p>My 2017 book was an attempt to mediate between the different camps of the debate on client-side JavaScript usage. Much advice from JavaScript critics was and is abstract for the sole reason that you need a robust site architecture in the first place before writing any robust client-side JavaScript code. With my book, I wanted to teach patterns any developer who writes client-side JavaScript can apply in their daily work regardless of the framework used.</p> <p>Around 2015 and 2016, several front-end developers wondered how to properly address JavaScript failure. <a href="https://molily.de/javascript-failure/">What happens when a JavaScript enhancement fails?</a> These essential and much needed discussions urged me to write a book on robust JavaScript.</p> <p>Unfortunately, only a few developers and projects picked up the ideas and integrated them into their work. Preventing and dealing with failing JavaScript is still an afterthought for many projects, frameworks and libraries. We need to continuously explore how practical progressive enhancement in JavaScript looks like.</p> <p>In 2017, I also wanted to emphasize that progressive enhancement is much more than server-side rendering. The discussion on progressive enhancement regarding JavaScript still revolves around server-side rendering versus client-side rendering. For good reason, but this is where progressive enhancement starts.</p> <p>It is a first step to use a framework that renders fully-functional HTML documents on the server. A frameworks that understands your code, identifies client-side interactivity and figures out the least amount of JavaScript that needs to be shipped to the client.</p> <p>It does not mean you are done with it. Adding client-side JavaScript should not be one monolithic enhancement step from 0 to 100, but many small deliberate and considerate steps. That is why it is called progressive enhancement.</p>
<p>So, where are we today? I welcome the new discussions on better web site architectures and sensible JavaScript usage. The industry is already shifting and new universal JavaScript frameworks are pushing the existing ecosystems.</p> <p>My 2017 book concluded with <a href="/robust-javascript/#writing-less-javascript">Writing less JavaScript</a>:</p> <blockquote> <p>An important skill of a front-end developer is to know when not to solve a problem with client-side JavaScript. It is always more robust to solve a problem further down in the stack.</p> <p>If all techniques and tools did not help you to write robust JavaScript, consider reducing the code complexity and the amount of code. In the last resort, reduce the usage of client-side JavaScript. Find simpler solutions that rely on HTML, CSS and server-side logic alone.</p> </blockquote> <p>Today I would turn the reasoning upside down. Reducing client-side JavaScript is the most effective technique to prevent JavaScript failure. The most robust client-side JavaScript is the JavaScript that is never written, never shipped to the client and never executed. (<a href="https://knowyourmeme.com/memes/roll-safe">Clever, huh?</a>)</p>
<p>Apart from that, what techniques are essential today to write robust JavaScript?</p> <p>I’ve mentioned <strong>TypeScript</strong> as a compile-to-JavaScript language in the book. Since 2017, TypeScript conquered the JavaScript world, superseded other compile-to-JavaScript languages and became a de-facto standard for a great share of libraries and frameworks.</p> <p>TypeScript is the single tool that made my JavaScript significantly more robust in the last couple of years. It helps me to design cascades of operations that may fail and helps me to implement the success and error handling. Strict typing forces me to think twice and write cautious code.</p> <p>With the goal of writing robust JavaScript in mind, we should utilize TypeScript as a static code checker for JavaScript – like ESLint.</p> <p>TypeScript is also a language that is a superset of JavaScript. It is also a program that compiles (transpiles) this language to JavaScript. But you do not have to use these parts to get most benefits.</p> <p>You can check plain JavaScript files with the TypeScript type checker. It understands plain JavaScript well enough to spot my lapses and lazy thinking. You can <a href="https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html">define types and add type annotations with JSDoc</a>.</p> <p>While there are benefits to write <code class="language-plaintext highlighter-rouge">.ts</code> files with TypeScript syntax, this is not necessary to get started. In several projects, I have hardly written any <code class="language-plaintext highlighter-rouge">.ts</code> file, but TypeScript is an essential development tool.</p> <p>My advice is to install an editor like Visual Studio Code and start using TypeScript in your <code class="language-plaintext highlighter-rouge">.js</code> or <code class="language-plaintext highlighter-rouge">.jsx</code> or <code class="language-plaintext highlighter-rouge">.vue</code> or <code class="language-plaintext highlighter-rouge">.svelte</code> files today.</p> <p>I understand that TypeScript adds a heavy burden for web developers who already struggle with JavaScript and its toolchains. (I guess that is, ehm, everyone here?) Fortunately, editors, libraries and frameworks make it easy to integrate typed code gradually so you can learn as you go.</p>
<p>My 2017 book featured several chapters on <strong>automated testing</strong> from a high-level perspective. Since then, I gained more experience on automatic testing of web sites in general and client-side JavaScript in particular.</p> <p>In 2021, I published an extensive book on <strong><a href="https://testing-angular.com/">Testing Angular</a></strong>. It is the spiritual successor of <cite>Robust JavaScript</cite>.</p> <p>The fact that the book deals with Angular is partly consequence, partly coincidence. I had been working on large Angular projects for clients who demanded (and could afford) technical robustness and understood test automation. Plus, Angular is built with testability in mind and the community values well-tested, robust code.</p> <p>While the second book goes into all necessary details and Angular specifics, it was the big picture that inspired me. How can testing help us to make better web sites that do not let the user down, but empower them? How can we write better, more robust JavaScript through testing?</p> <p>So eventually I wrote <cite>Testing Angular</cite> for the same reason I wrote <cite>Robust JavaScript</cite>: I wanted to explore and teach writing better web experiences. Preventing JavaScript failure is still my white whale.</p> <p>Fortunately, testing tools improved since 2017 and both end-to-end testing as well as JavaScript unit and integration testing got more approachable and reliable. Today I put much more emphasis on automated testing to make JavaScript robust.</p>
<p>Angular is the “special occasion” framework in the JavaScript world. While <a href="https://almanac.httparchive.org/en/2022/javascript#libraries-and-frameworks">jQuery is used on 81% and React is used on 8% of the web sites analyzed</a>, Angular is suitable for heavy-weight corporate intranet applications with a restricted audience using desktop computers.</p> <p>Especially JavaScript critics shake their head when Angular is mentioned. It ships larger amounts of client-side JavaScript than other frameworks. While it has rudimentary server-side rendering, it is not a practically viable default yet. Nonetheless, I think the Angular community listens to criticism and innovates.</p> <p>Angular has some architectural advantages that allows it to evolve in order to improve the site’s robustness and thereby the user experience. The core of Angular is a compiler. Like the Svelte compiler, it transforms your high-level, declarative and human-readable code into low-level, imperative and concise code that is shipped to the browser.</p> <p>The Angular team can optimize the compiler to produce more efficient and less code. In fact, the team recently rewrote the whole compiler and rendering engine. Thanks to the ahead-of-time compilation, there is dormant potential in Angular.</p> <p>I am excited that the Angular ecosystem catches up with projects like <a href="https://github.com/analogjs/analog">Analog.js</a>, a full-stack framework that compares itself to SvelteKit, Nuxt and Next.js. Although Angular will most likely stick with the single page application architecture, folks from the Angular community are building next-generation frameworks. For example, Miško Hevery, the creator of the original AngularJS framework and co-creator of Angular, now works on Qwik.</p>
<p>While I still deem it necessary to teach basic defensive coding techniques, one cannot talk about robust client-side JavaScript without discussing the whole web site architecture. I have done so in several blog posts, but not prominently in <cite>Robust JavaScript</cite>.</p> <p>Client-side JavaScript affects performance and accessibility, and I have realized that these are essential aspects of robustness as well. If JavaScript is freezing a mobile browser for 20 seconds, the site is not usable, let alone robust. If a single page application breaks browser navigation features that users of assistive technologies rely on in particular, the site is not robust. And so on.</p> <p>All things considered, I think we are in a crucial phase of turmoil. My hope is that the JavaScript community convenes in a respectful and productive way, takes criticism seriously and makes radical technical and social changes.</p> </div>

+ 221
- 0
cache/2023/a09b5bf450d2cf86fb9e9d6f13b070e0/index.html View File

@@ -0,0 +1,221 @@
<!doctype html><!-- This is a valid HTML5 document. -->
<!-- Screen readers, SEO, extensions and so on. -->
<html lang="fr">
<!-- Has to be within the first 1024 bytes, hence before the `title` element
See: https://www.w3.org/TR/2012/CR-html5-20121217/document-metadata.html#charset -->
<meta charset="utf-8">
<!-- Why no `X-UA-Compatible` meta: https://stackoverflow.com/a/6771584 -->
<!-- The viewport meta is quite crowded and we are responsible for that.
See: https://codepen.io/tigt/post/meta-viewport-for-2015 -->
<meta name="viewport" content="width=device-width,initial-scale=1">
<!-- Required to make a valid HTML5 document. -->
<title>Clever Code Considered Harmful (archive) — David Larlet</title>
<meta name="description" content="Publication mise en cache pour en conserver une trace.">
<!-- That good ol' feed, subscribe :). -->
<link rel="alternate" type="application/atom+xml" title="Feed" href="/david/log/">
<!-- Generated from https://realfavicongenerator.net/ such a mess. -->
<link rel="apple-touch-icon" sizes="180x180" href="/static/david/icons2/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/static/david/icons2/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/static/david/icons2/favicon-16x16.png">
<link rel="manifest" href="/static/david/icons2/site.webmanifest">
<link rel="mask-icon" href="/static/david/icons2/safari-pinned-tab.svg" color="#07486c">
<link rel="shortcut icon" href="/static/david/icons2/favicon.ico">
<meta name="msapplication-TileColor" content="#f7f7f7">
<meta name="msapplication-config" content="/static/david/icons2/browserconfig.xml">
<meta name="theme-color" content="#f7f7f7" media="(prefers-color-scheme: light)">
<meta name="theme-color" content="#272727" media="(prefers-color-scheme: dark)">
<!-- Documented, feel free to shoot an email. -->
<link rel="stylesheet" href="/static/david/css/style_2021-01-20.css">
<!-- See https://www.zachleat.com/web/comprehensive-webfonts/ for the trade-off. -->
<link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
<link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
<link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
<script>
function toggleTheme(themeName) {
document.documentElement.classList.toggle(
'forced-dark',
themeName === 'dark'
)
document.documentElement.classList.toggle(
'forced-light',
themeName === 'light'
)
}
const selectedTheme = localStorage.getItem('theme')
if (selectedTheme !== 'undefined') {
toggleTheme(selectedTheme)
}
</script>

<meta name="robots" content="noindex, nofollow">
<meta content="origin-when-cross-origin" name="referrer">
<!-- Canonical URL for SEO purposes -->
<link rel="canonical" href="https://www.joshwcomeau.com/career/clever-code-considered-harmful/">

<body class="remarkdown h1-underline h2-underline h3-underline em-underscore hr-center ul-star pre-tick" data-instant-intensity="viewport-all">


<article>
<header>
<h1>Clever Code Considered Harmful</h1>
</header>
<nav>
<p class="center">
<a href="/david/" title="Aller à l’accueil"><svg class="icon icon-home">
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-home"></use>
</svg> Accueil</a> •
<a href="https://www.joshwcomeau.com/career/clever-code-considered-harmful/" title="Lien vers le contenu original">Source originale</a>
</p>
</nav>
<hr>
<p class="sc-e646da6e-0 buyZsM">There is something undeniably satisfying about coming up with clever solutions to hard problems. There is a joy when you challenge yourself to use recursion instead of iteration, for example, or when you create elegant, cascading layers of abstraction that ensure code is never duplicated.</p>
<p class="sc-e646da6e-0 buyZsM">My favourite outlet for this kind of programming is <a href="https://projecteuler.net" rel="noopener noreferrer" target="_blank" class="sc-7af019d9-0 fZHCDu sc-53808c2b-0 NuBMO">Project Euler</a>.</p>
<p class="sc-e646da6e-0 buyZsM">Project Euler is a repository of challenges based around advanced mathematics, meant to be solved with software. The catch is that your program should run in under a minute, on 2004-era hardware. That means that a brute-force solution often won’t cut it, and you’ll have to come up with a smarter solution.</p>
<p class="sc-e646da6e-0 buyZsM">Here’s an example:</p>
<p class="sc-e646da6e-0 buyZsM"><span type="default" class="sc-9a7b0d0-0 jvgAVO"><img src="/images/legacy/1__sbbO5gKvxk__TuJOIRMUzKA.png" alt="A math problem, to calculate numbers arranged in a spiral problem. Screenshot of this page: https://projecteuler.net/problem=58" class="sc-9a7b0d0-2 jkoJNm"><span class="sc-9a7b0d0-1 fbsvTj">Helpful tip: Euler is pronounced “Oiler”. Impress your math friends with this knowledge!</span></span></p>
<p class="sc-e646da6e-0 buyZsM">Once you’ve solved a problem, you’re able to view solutions that other people have shared. And oh wow, do people come up with terse, clever solutions for these things.</p>
<aside class="sc-3583c7cd-0 sc-3583c7cd-3 Nmjxf bsUafj"><p class="sc-3583c7cd-6 iESgn">I’m kinda breaking the Project Euler rules here— you’re not supposed to share solutions, to avoid spoiling it for others— but don’t worry, these solutions are totally indecipherable. You won’t spoil the challenge.</p></aside>
<p class="sc-e646da6e-0 buyZsM">Here's one by a user named WillNess written in Haskell, a functional programming language:</p>
<pre></pre>
<p class="sc-e646da6e-0 buyZsM">Here's another one, written in <a href="https://en.wikipedia.org/wiki/J_%28programming_language%29" rel="noopener noreferrer" target="_blank" class="sc-7af019d9-0 fZHCDu sc-53808c2b-0 NuBMO">J lang</a> by user u56:</p>
<pre></pre>
<p class="sc-e646da6e-0 buyZsM">Clearly, it takes a tremendous amount of skill to solve such a hard problem with such a small amount of code. I would feel very pleased with myself if I was able to write a solution like this; my solutions are always way longer and less elegant.</p>
<p class="sc-e646da6e-0 buyZsM">This is not "production-ready" code, though. This is recreational code. This is code that you write to feel clever, to impress fellow math nerds, to exercise your brain. When you solve a Project Euler problem, you never have to look at that code again. It's disposable. We aren't handing it off to someone else to maintain it.</p>
<p class="sc-e646da6e-0 buyZsM">This is a different universe from the environments we write code in day-to-day.</p>
<p class="sc-e646da6e-0 buyZsM">When it comes to day-to-day production code, here's the barometer I like to use: will a junior developer, someone at the very start of their career, struggle to understand this code?</p>
<p class="sc-e646da6e-0 buyZsM">In the context of a shared codebase, good code is simple code. Code that doesn’t do anything fancy. Code that makes minimal use of abstractions. Code that you’d use to explain fundamental concepts to novices.</p>
<p class="sc-e646da6e-0 buyZsM">A few years ago, I was asked to review a pull request that included the following function:</p>
<pre></pre>
<p class="sc-e646da6e-0 buyZsM">I suggested we re-write it like this:</p>
<pre></pre>
<p class="sc-e646da6e-0 buyZsM">The original version has lots of things going for it, on paper:</p>
<ul class="sc-19724b12-1 hKaNYm"><li class="sc-19724b12-3 kuSaGk"><span class="sc-19724b12-5 jxFLLh"><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="5" y1="12" x2="19" y2="12"></line><polyline points="12 5 19 12 12 19"></polyline></svg></span><p class="sc-19724b12-4 kJtFVp">Less code (only 4 statements instead of 7)</p></li><li class="sc-19724b12-3 kuSaGk"><span class="sc-19724b12-5 jxFLLh"><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="5" y1="12" x2="19" y2="12"></line><polyline points="12 5 19 12 12 19"></polyline></svg></span><p class="sc-19724b12-4 kJtFVp">No duplication (the second version uses two <code class="sc-1a723291-0 YrISa">if</code> statements that do essentially the same thing)</p></li><li class="sc-19724b12-3 kuSaGk"><span class="sc-19724b12-5 jxFLLh"><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="5" y1="12" x2="19" y2="12"></line><polyline points="12 5 19 12 12 19"></polyline></svg></span><p class="sc-19724b12-4 kJtFVp">Doesn't mutate any variables</p></li><li class="sc-19724b12-3 kuSaGk"><span class="sc-19724b12-5 jxFLLh"><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="5" y1="12" x2="19" y2="12"></line><polyline points="12 5 19 12 12 19"></polyline></svg></span><p class="sc-19724b12-4 kJtFVp">More scalable: could easily be rewritten to handle 10 fields instead of 2.</p></li></ul>
<p class="sc-e646da6e-0 buyZsM">And yet, the original version is <em class="sc-51e913c7-0 cWQfrg">way</em> harder to understand. I had to burn a ton of calories trying to work out what it was doing. I suspect many junior developers would be completely stumped trying to decipher it.</p>
<p class="sc-e646da6e-0 buyZsM">In my opinion, the readability cost of the functional version is too high. It's not worth it.</p>
<p class="sc-e646da6e-0 buyZsM">To understand why I think readability is such a crucial attribute of good code, let’s look at a popular open-source library, <a href="https://github.com/lodash/lodash" rel="noopener noreferrer" target="_blank" class="sc-7af019d9-0 fZHCDu sc-53808c2b-0 NuBMO">lodash</a>.</p>
<p class="sc-e646da6e-0 buyZsM"><span type="default" class="sc-9a7b0d0-0 jvgAVO"><img src="/images/legacy/1__cDMSqwCi1aSPRxXdG5PUzg.png" alt="Screenshot of the “lodash” Github page" class="sc-9a7b0d0-2 jkoJNm"></span></p>
<p class="sc-e646da6e-0 buyZsM">lodash is an immensely popular tool. It’s downloaded more than 26,000,000 times a week on NPM alone, and has over 42,000 Github stars. There is something absolutely curious about it, though; it consistently has less than 10 open issues.</p>
<p class="sc-e646da6e-0 buyZsM">"Inbox zero" is a thing with email, but it <em class="sc-51e913c7-0 cWQfrg">never</em> happens with issues on popular projects. And yet, lodash often sits at zero open issues. It's been like this for years.</p>
<p class="sc-e646da6e-0 buyZsM">Well, one reason is that the library’s primary author, John-David Dalton, is a passionate maintainer who spends a lot of his time triaging issues as they come in. But I don’t believe anyone, no matter how superhuman, can get a library this popular to 0 issues alone.</p>
<p class="sc-e646da6e-0 buyZsM">Years ago, I heard JDD on <a href="https://podcasts.apple.com/us/podcast/012-jsair-lodash-open-source-with-john-david-dalton/id1066446588?i=1000364088851" rel="noopener noreferrer" target="_blank" class="sc-7af019d9-0 fZHCDu sc-53808c2b-0 NuBMO">a podcast</a> talk about how the key to managing a project like this is to encourage lots of folks to contribute to it. One of the ways he’s done this is by keeping the code at a pretty fundamental level; by using simple, basic constructs, it ensures that aspiring contributors can understand and contribute to the code, regardless of how much experience they have. I believe JDD mentions that they prefer if/else to ternaries simply because less people have experience with ternaries. When the goal is to keep the code simple, the expressive power of the ternary operator is detrimental.</p>
<p class="sc-e646da6e-0 buyZsM">This is important to keep in mind if you’re building an open-source tool, but it’s <em class="sc-51e913c7-0 cWQfrg">even more important</em> if you’re working in a production codebase with other humans. Especially ones that have less experience than you.</p>
<aside class="sc-3583c7cd-0 sc-3583c7cd-1 Nmjxf bvghBJ"><p class="sc-3583c7cd-5 crvSnl"><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><line x1="12" y1="16" x2="12" y2="12"></line><line x1="12" y1="8" x2="12.01" y2="8"></line></svg></p><strong class="sc-3583c7cd-4 ghVlSM">Zero issues no more</strong><div class="sc-3583c7cd-6 iESgn"><p class="sc-e646da6e-0 buyZsM">As I write this update in 2023, Lodash has a couple hundred open issues. This is likely because its maintainer, JDD, has moved onto other projects.</p></div></aside>
<p class="sc-e646da6e-0 buyZsM">Have you ever heard someone say this?</p>
<blockquote class="sc-4c838171-0 lkTYca"><p class="sc-e646da6e-0 buyZsM">Less code means less space for bugs to hide</p></blockquote>
<p class="sc-e646da6e-0 buyZsM">This argument makes the case that short code is better, because it'll be easier to spot bugs. With every additional character you type, you're increasing the likelihood of a mistake.</p>
<p class="sc-e646da6e-0 buyZsM">This is true when it comes to <em>typos</em>, sure. But typos tend to be easy to catch and fix. The <em class="sc-51e913c7-0 cWQfrg">really</em> troublesome bugs — the ones that tend to break user experiences for <em>weeks</em> as developers pass the support ticket around like a hot potato — are often caused by too much <em class="sc-51e913c7-0 cWQfrg">complexity</em>, not too many characters.</p>
<p class="sc-e646da6e-0 buyZsM">In order to debug an issue, you have to wrap your mind around what the code is doing. When you create an abstraction to reduce duplication (“Make it DRY”), you add a layer of indirection that your mind has to unpack. The harder it is for your mental model to account for every edge-case and possible state, the more likely it is that you’ll have trouble diagnosing what’s gone wrong.</p>
<blockquote class="sc-4c838171-0 lkTYca"><p class="sc-e646da6e-0 buyZsM">“Everyone knows that debugging is twice as hard as writing a program in the first place. So if you’re as clever as you can be when you write it, how will you ever debug it?”</p></blockquote>
<p class="sc-e646da6e-0 buyZsM">— <a href="https://en.wikipedia.org/wiki/Brian_Kernighan" rel="noopener noreferrer" target="_blank" class="sc-7af019d9-0 fZHCDu sc-53808c2b-0 NuBMO">Brian Kernighan</a>, The Elements of Programming Style</p>
<p class="sc-e646da6e-0 buyZsM">If the goal is to reduce complexity, and abstractions add complexity, should we abolish abstractions altogether?</p>
<p class="sc-e646da6e-0 buyZsM">Well, no. Abstractions are everywhere. Loops are abstractions. Functions are abstractions. Programming languages themselves are abstractions over machine code, which itself is an abstraction over transistors flickering off and on really fast. It’s abstractions all the way down.</p>
<p class="sc-e646da6e-0 buyZsM">The key is to weigh the cost of an abstraction against its benefit. Say we’re building a React app, and we have a list of 100 things to render. We could copy/paste the same JSX 100 times, or we could map over an array and write the JSX once. The “complex” solution in this case is totally worth it, because the underlying complexity is commonly known, and the alternative would be burdensome to maintain.</p>
<p class="sc-e646da6e-0 buyZsM">As we build stuff, we make trade-off decisions like this all the time. If I have a point, it’s that we should consider these tradeoffs with our most junior teammates in mind; how much complexity are we adding for them? Is it worth it?</p>
<p class="sc-e646da6e-0 buyZsM">Code sometimes has to be complex, because the real world is complex and our software has to model it! We won’t always be able to write code that a junior engineer can easily parse and contribute to. Sometimes the business logic is genuinely really tricky, sometimes we have to use an API with an inscrutable interface, and so on.</p>
<p class="sc-e646da6e-0 buyZsM">I think the best way to deal with this is to try and sequester complexity. Set up clear boundaries between the simple stuff and the complex stuff. Don’t let the complexity seep into the surrounding areas.</p>
<p class="sc-e646da6e-0 buyZsM">John-David Dalton did this with lodash. According to his interview in <a href="https://podcasts.apple.com/us/podcast/012-jsair-lodash-open-source-with-john-david-dalton/id1066446588?i=1000364088851" rel="noopener noreferrer" target="_blank" class="sc-7af019d9-0 fZHCDu sc-53808c2b-0 NuBMO">that same podcast</a>, the vast majority of lodash code is simple and easy-to-follow, and they’ve pushed the complex bits to a sophisticated core that handles the hard problems. This means that most contributors are spared from having to deal with that complexity, since it isn’t sprinkled across the application.</p>
<p class="sc-e646da6e-0 buyZsM">If your app is architected so that the most complex concerns are all dealt with in the same place, you can keep the overwhelming majority of your app’s surface area simple.</p>
<p class="sc-e646da6e-0 buyZsM">What if the junior engineer needs to work on that complex core? Well, good news! They have a more-senior person (you) to help guide them through it. Mentorship and education is a huge part of being a senior developer.</p>
<p class="sc-e646da6e-0 buyZsM">One of my favourite talks from React Rally last year was <a href="https://www.youtube.com/watch?v=-NP_upexPFg" rel="noopener noreferrer" target="_blank" class="sc-7af019d9-0 fZHCDu sc-53808c2b-0 NuBMO">Chantastic’s “Hot Garbage; Clean Code is Dead”</a>. I won’t spoil the talk (seriously, go watch it!), but one of the takeaways I took from it is that everyone suffers from impostor syndrome, and as a result, we're always trying to prove to each other that we know our stuff. If we write a function that is super clever and indecipherable, our co-workers will know that we're smart, that we belong here!</p>
<p class="sc-e646da6e-0 buyZsM">What I've come to realize, though, is that anyone can write code that seems complicated. The hard thing is solving complex problems with simple code. If you can develop that skill, nobody will ever doubt your abilities. ✨</p>
</article>


<hr>

<footer>
<p>
<a href="/david/" title="Aller à l’accueil"><svg class="icon icon-home">
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-home"></use>
</svg> Accueil</a> •
<a href="/david/log/" title="Accès au flux RSS"><svg class="icon icon-rss2">
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-rss2"></use>
</svg> Suivre</a> •
<a href="http://larlet.com" title="Go to my English profile" data-instant><svg class="icon icon-user-tie">
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-user-tie"></use>
</svg> Pro</a> •
<a href="mailto:david%40larlet.fr" title="Envoyer un courriel"><svg class="icon icon-mail">
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-mail"></use>
</svg> Email</a> •
<abbr class="nowrap" title="Hébergeur : Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33184162340"><svg class="icon icon-hammer2">
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-hammer2"></use>
</svg> Légal</abbr>
</p>
<template id="theme-selector">
<form>
<fieldset>
<legend><svg class="icon icon-brightness-contrast">
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-brightness-contrast"></use>
</svg> Thème</legend>
<label>
<input type="radio" value="auto" name="chosen-color-scheme" checked> Auto
</label>
<label>
<input type="radio" value="dark" name="chosen-color-scheme"> Foncé
</label>
<label>
<input type="radio" value="light" name="chosen-color-scheme"> Clair
</label>
</fieldset>
</form>
</template>
</footer>
<script src="/static/david/js/instantpage-5.1.0.min.js" type="module"></script>
<script>
function loadThemeForm(templateName) {
const themeSelectorTemplate = document.querySelector(templateName)
const form = themeSelectorTemplate.content.firstElementChild
themeSelectorTemplate.replaceWith(form)

form.addEventListener('change', (e) => {
const chosenColorScheme = e.target.value
localStorage.setItem('theme', chosenColorScheme)
toggleTheme(chosenColorScheme)
})

const selectedTheme = localStorage.getItem('theme')
if (selectedTheme && selectedTheme !== 'undefined') {
form.querySelector(`[value="${selectedTheme}"]`).checked = true
}
}

const prefersColorSchemeDark = '(prefers-color-scheme: dark)'
window.addEventListener('load', () => {
let hasDarkRules = false
for (const styleSheet of Array.from(document.styleSheets)) {
let mediaRules = []
for (const cssRule of styleSheet.cssRules) {
if (cssRule.type !== CSSRule.MEDIA_RULE) {
continue
}
// WARNING: Safari does not have/supports `conditionText`.
if (cssRule.conditionText) {
if (cssRule.conditionText !== prefersColorSchemeDark) {
continue
}
} else {
if (cssRule.cssText.startsWith(prefersColorSchemeDark)) {
continue
}
}
mediaRules = mediaRules.concat(Array.from(cssRule.cssRules))
}

// WARNING: do not try to insert a Rule to a styleSheet you are
// currently iterating on, otherwise the browser will be stuck
// in a infinite loop…
for (const mediaRule of mediaRules) {
styleSheet.insertRule(mediaRule.cssText)
hasDarkRules = true
}
}
if (hasDarkRules) {
loadThemeForm('#theme-selector')
}
})
</script>
</body>
</html>

+ 5
- 0
cache/2023/a09b5bf450d2cf86fb9e9d6f13b070e0/index.md
File diff suppressed because it is too large
View File


+ 178
- 0
cache/2023/e44bfaaecad989f67cb2032fac000276/index.html View File

@@ -0,0 +1,178 @@
<!doctype html><!-- This is a valid HTML5 document. -->
<!-- Screen readers, SEO, extensions and so on. -->
<html lang="fr">
<!-- Has to be within the first 1024 bytes, hence before the `title` element
See: https://www.w3.org/TR/2012/CR-html5-20121217/document-metadata.html#charset -->
<meta charset="utf-8">
<!-- Why no `X-UA-Compatible` meta: https://stackoverflow.com/a/6771584 -->
<!-- The viewport meta is quite crowded and we are responsible for that.
See: https://codepen.io/tigt/post/meta-viewport-for-2015 -->
<meta name="viewport" content="width=device-width,initial-scale=1">
<!-- Required to make a valid HTML5 document. -->
<title>The Hippocratic License (archive) — David Larlet</title>
<meta name="description" content="Publication mise en cache pour en conserver une trace.">
<!-- That good ol' feed, subscribe :). -->
<link rel="alternate" type="application/atom+xml" title="Feed" href="/david/log/">
<!-- Generated from https://realfavicongenerator.net/ such a mess. -->
<link rel="apple-touch-icon" sizes="180x180" href="/static/david/icons2/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/static/david/icons2/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/static/david/icons2/favicon-16x16.png">
<link rel="manifest" href="/static/david/icons2/site.webmanifest">
<link rel="mask-icon" href="/static/david/icons2/safari-pinned-tab.svg" color="#07486c">
<link rel="shortcut icon" href="/static/david/icons2/favicon.ico">
<meta name="msapplication-TileColor" content="#f7f7f7">
<meta name="msapplication-config" content="/static/david/icons2/browserconfig.xml">
<meta name="theme-color" content="#f7f7f7" media="(prefers-color-scheme: light)">
<meta name="theme-color" content="#272727" media="(prefers-color-scheme: dark)">
<!-- Documented, feel free to shoot an email. -->
<link rel="stylesheet" href="/static/david/css/style_2021-01-20.css">
<!-- See https://www.zachleat.com/web/comprehensive-webfonts/ for the trade-off. -->
<link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
<link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
<link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
<script>
function toggleTheme(themeName) {
document.documentElement.classList.toggle(
'forced-dark',
themeName === 'dark'
)
document.documentElement.classList.toggle(
'forced-light',
themeName === 'light'
)
}
const selectedTheme = localStorage.getItem('theme')
if (selectedTheme !== 'undefined') {
toggleTheme(selectedTheme)
}
</script>

<meta name="robots" content="noindex, nofollow">
<meta content="origin-when-cross-origin" name="referrer">
<!-- Canonical URL for SEO purposes -->
<link rel="canonical" href="https://firstdonoharm.dev/">

<body class="remarkdown h1-underline h2-underline h3-underline em-underscore hr-center ul-star pre-tick" data-instant-intensity="viewport-all">


<article>
<header>
<h1>The Hippocratic License</h1>
</header>
<nav>
<p class="center">
<a href="/david/" title="Aller à l’accueil"><svg class="icon icon-home">
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-home"></use>
</svg> Accueil</a> •
<a href="https://firstdonoharm.dev/" title="Lien vers le contenu original">Source originale</a>
</p>
</nav>
<hr>
<h2 id="hippocratic-license-30-hl3-an-ethical-license-for-open-source-communities">Hippocratic License 3.0 (HL3): An Ethical License for Open Source Communities</h2>
<p>Technological advancement is often <a href="https://openlibrary.org/books/OL25573370M/Technoculture" rel="noreferer nofollow" target="_blank">shaped by the choices and priorities of the powerful</a>— in particular, the military, governments, and corporate interests. Their distorted priorities are often at odds with the promise of technology as a force for <a href="https://blog.archive.org/2021/09/03/the-sacred-geometry-of-respect-trust-and-equity/" rel="noreferer nofollow" target="_blank">promoting justice and equity worldwide</a>, and this increasingly includes open source technologies.</p>
<p>Traditional open source is based on the <a href="https://ieeexplore.ieee.org/document/5010049" rel="noreferer nofollow" target="_blank">flawed premise that technology is fundamentally neutral</a>, and that <a href="https://www.gnu.org/philosophy/free-sw.en.html#four-freedoms" rel="noreferer nofollow" target="_blank">unrestricted access to source code</a>— even for <a href="https://opensource.org/faq#evil" rel="noreferer nofollow" target="_blank">explicitly “evil” purposes</a>— is in fact an unqualified good. But around the world, open source developers are starting to realize that the software that they create, with its tremendous potential to change the world for the better, is also being abused to sustain and promote systems of inequity and injustice, globally, and at unprecedented scale.</p>
<p>The Hippocratic License 3.0 (HL3) aims to confront the potential harms and abuses technology can have on fundamental human rights. It empowers open source communities to establish a clear set of ethical standards that licensees must abide by in order to adopt their code. These standards are based on international agreements and authorities on fundamental human rights norms, including the <a href="https://www.un.org/en/about-us/universal-declaration-of-human-rights" rel="noreferer nofollow" target="_blank">United Nations Universal Declaration of Human Rights</a>, the <a href="https://www.ohchr.org/en/instruments-mechanisms/instruments/international-covenant-economic-social-and-cultural-rights" rel="noreferer nofollow" target="_blank">International Covenant on Economic, Social and Cultural Rights</a>, the <a href="https://www.ohchr.org/en/instruments-mechanisms/instruments/international-covenant-civil-and-political-rights" rel="noreferer nofollow" target="_blank">International Covenant on Civil and Political Rights</a>, and the <a href="https://www.ilo.org/" rel="noreferer nofollow" target="_blank">International Labour Organization</a>.</p>
<p>HL3 also offers optional modules that focus on specific areas of concern, such as environmental justice, labor rights, and ethical supply chains. This modular approach lets open source maintainers <a href="/build/" rel="noreferer nofollow">customize the license</a> to reflect the unique needs and challenges of their particular communities.</p>
<p>Healthy open source communities don’t just form around code, but also around <a href="https://ethicalsource.dev/principles" rel="noreferer nofollow" target="_blank">shared values</a> and a vision for how their work can improve the world. The true measure of the success of open source is its impact— how the technologies we develop are leveraged to bring about positive social, cultural, and political change.</p>
<p>To get started, <a href="https://firstdonoharm.dev/build/" rel="noreferer nofollow">customize your license</a>.</p>
</article>


<hr>

<footer>
<p>
<a href="/david/" title="Aller à l’accueil"><svg class="icon icon-home">
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-home"></use>
</svg> Accueil</a> •
<a href="/david/log/" title="Accès au flux RSS"><svg class="icon icon-rss2">
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-rss2"></use>
</svg> Suivre</a> •
<a href="http://larlet.com" title="Go to my English profile" data-instant><svg class="icon icon-user-tie">
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-user-tie"></use>
</svg> Pro</a> •
<a href="mailto:david%40larlet.fr" title="Envoyer un courriel"><svg class="icon icon-mail">
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-mail"></use>
</svg> Email</a> •
<abbr class="nowrap" title="Hébergeur : Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33184162340"><svg class="icon icon-hammer2">
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-hammer2"></use>
</svg> Légal</abbr>
</p>
<template id="theme-selector">
<form>
<fieldset>
<legend><svg class="icon icon-brightness-contrast">
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-brightness-contrast"></use>
</svg> Thème</legend>
<label>
<input type="radio" value="auto" name="chosen-color-scheme" checked> Auto
</label>
<label>
<input type="radio" value="dark" name="chosen-color-scheme"> Foncé
</label>
<label>
<input type="radio" value="light" name="chosen-color-scheme"> Clair
</label>
</fieldset>
</form>
</template>
</footer>
<script src="/static/david/js/instantpage-5.1.0.min.js" type="module"></script>
<script>
function loadThemeForm(templateName) {
const themeSelectorTemplate = document.querySelector(templateName)
const form = themeSelectorTemplate.content.firstElementChild
themeSelectorTemplate.replaceWith(form)

form.addEventListener('change', (e) => {
const chosenColorScheme = e.target.value
localStorage.setItem('theme', chosenColorScheme)
toggleTheme(chosenColorScheme)
})

const selectedTheme = localStorage.getItem('theme')
if (selectedTheme && selectedTheme !== 'undefined') {
form.querySelector(`[value="${selectedTheme}"]`).checked = true
}
}

const prefersColorSchemeDark = '(prefers-color-scheme: dark)'
window.addEventListener('load', () => {
let hasDarkRules = false
for (const styleSheet of Array.from(document.styleSheets)) {
let mediaRules = []
for (const cssRule of styleSheet.cssRules) {
if (cssRule.type !== CSSRule.MEDIA_RULE) {
continue
}
// WARNING: Safari does not have/supports `conditionText`.
if (cssRule.conditionText) {
if (cssRule.conditionText !== prefersColorSchemeDark) {
continue
}
} else {
if (cssRule.cssText.startsWith(prefersColorSchemeDark)) {
continue
}
}
mediaRules = mediaRules.concat(Array.from(cssRule.cssRules))
}

// WARNING: do not try to insert a Rule to a styleSheet you are
// currently iterating on, otherwise the browser will be stuck
// in a infinite loop…
for (const mediaRule of mediaRules) {
styleSheet.insertRule(mediaRule.cssText)
hasDarkRules = true
}
}
if (hasDarkRules) {
loadThemeForm('#theme-selector')
}
})
</script>
</body>
</html>

+ 11
- 0
cache/2023/e44bfaaecad989f67cb2032fac000276/index.md View File

@@ -0,0 +1,11 @@
title: The Hippocratic License
url: https://firstdonoharm.dev/
hash_url: e44bfaaecad989f67cb2032fac000276

<h2 id="hippocratic-license-30-hl3-an-ethical-license-for-open-source-communities">Hippocratic License 3.0 (HL3): An Ethical License for Open Source Communities</h2>
<p>Technological advancement is often <a href="https://openlibrary.org/books/OL25573370M/Technoculture" rel="noreferer nofollow" target="_blank">shaped by the choices and priorities of the powerful</a>— in particular, the military, governments, and corporate interests. Their distorted priorities are often at odds with the promise of technology as a force for <a href="https://blog.archive.org/2021/09/03/the-sacred-geometry-of-respect-trust-and-equity/" rel="noreferer nofollow" target="_blank">promoting justice and equity worldwide</a>, and this increasingly includes open source technologies.</p>
<p>Traditional open source is based on the <a href="https://ieeexplore.ieee.org/document/5010049" rel="noreferer nofollow" target="_blank">flawed premise that technology is fundamentally neutral</a>, and that <a href="https://www.gnu.org/philosophy/free-sw.en.html#four-freedoms" rel="noreferer nofollow" target="_blank">unrestricted access to source code</a>— even for <a href="https://opensource.org/faq#evil" rel="noreferer nofollow" target="_blank">explicitly “evil” purposes</a>— is in fact an unqualified good. But around the world, open source developers are starting to realize that the software that they create, with its tremendous potential to change the world for the better, is also being abused to sustain and promote systems of inequity and injustice, globally, and at unprecedented scale.</p>
<p>The Hippocratic License 3.0 (HL3) aims to confront the potential harms and abuses technology can have on fundamental human rights. It empowers open source communities to establish a clear set of ethical standards that licensees must abide by in order to adopt their code. These standards are based on international agreements and authorities on fundamental human rights norms, including the <a href="https://www.un.org/en/about-us/universal-declaration-of-human-rights" rel="noreferer nofollow" target="_blank">United Nations Universal Declaration of Human Rights</a>, the <a href="https://www.ohchr.org/en/instruments-mechanisms/instruments/international-covenant-economic-social-and-cultural-rights" rel="noreferer nofollow" target="_blank">International Covenant on Economic, Social and Cultural Rights</a>, the <a href="https://www.ohchr.org/en/instruments-mechanisms/instruments/international-covenant-civil-and-political-rights" rel="noreferer nofollow" target="_blank">International Covenant on Civil and Political Rights</a>, and the <a href="https://www.ilo.org/" rel="noreferer nofollow" target="_blank">International Labour Organization</a>.</p>
<p>HL3 also offers optional modules that focus on specific areas of concern, such as environmental justice, labor rights, and ethical supply chains. This modular approach lets open source maintainers <a href="/build/" rel="noreferer nofollow">customize the license</a> to reflect the unique needs and challenges of their particular communities.</p>
<p>Healthy open source communities don’t just form around code, but also around <a href="https://ethicalsource.dev/principles" rel="noreferer nofollow" target="_blank">shared values</a> and a vision for how their work can improve the world. The true measure of the success of open source is its impact— how the technologies we develop are leveraged to bring about positive social, cultural, and political change.</p>
<p>To get started, <a href="https://firstdonoharm.dev/build/" rel="noreferer nofollow">customize your license</a>.</p>

+ 14
- 0
cache/2023/index.html View File

@@ -69,6 +69,8 @@
<li><a href="/david/cache/2022/f7957bdde7af740e322756668784d355/" title="Accès à l’article dans le cache local : Speed for who? | Andy Bell">Speed for who? | Andy Bell</a> (<a href="https://andy-bell.co.uk/speed-for-who/" title="Accès à l’article original distant : Speed for who? | Andy Bell">original</a>)</li>
<li><a href="/david/cache/2022/e44bfaaecad989f67cb2032fac000276/" title="Accès à l’article dans le cache local : The Hippocratic License">The Hippocratic License</a> (<a href="https://firstdonoharm.dev/" title="Accès à l’article original distant : The Hippocratic License">original</a>)</li>
<li><a href="/david/cache/2022/e1a26da20c603d214d0f844d5836569e/" title="Accès à l’article dans le cache local : my mind is full of webs">my mind is full of webs</a> (<a href="https://winnielim.org/journal/my-mind-is-full-of-webs/" title="Accès à l’article original distant : my mind is full of webs">original</a>)</li>
<li><a href="/david/cache/2022/5b35e3f3639ceb7d9f684aa81979f304/" title="Accès à l’article dans le cache local : The Market for Lemons">The Market for Lemons</a> (<a href="https://infrequently.org/2023/02/the-market-for-lemons/" title="Accès à l’article original distant : The Market for Lemons">original</a>)</li>
@@ -119,6 +121,10 @@
<li><a href="/david/cache/2022/8440372c6df33b8f23cfce7a9eca5961/" title="Accès à l’article dans le cache local : A highly opinionated guide to learning about ActivityPub">A highly opinionated guide to learning about ActivityPub</a> (<a href="https://tinysubversions.com/notes/reading-activitypub/" title="Accès à l’article original distant : A highly opinionated guide to learning about ActivityPub">original</a>)</li>
<li><a href="/david/cache/2022/0f8bbba127c48a13b35fdf265c2dc106/" title="Accès à l’article dans le cache local : Company Announcement | Pydantic">Company Announcement | Pydantic</a> (<a href="https://pydantic.dev/announcement/" title="Accès à l’article original distant : Company Announcement | Pydantic">original</a>)</li>
<li><a href="/david/cache/2022/19ec475bd5d92b02fbef043c52ea0589/" title="Accès à l’article dans le cache local : Investing in RSS">Investing in RSS</a> (<a href="https://timkadlec.com/remembers/2023-02-23-investing-in-rss/" title="Accès à l’article original distant : Investing in RSS">original</a>)</li>
<li><a href="/david/cache/2022/d6b891fd250a6ae967ae55564770b67a/" title="Accès à l’article dans le cache local : The Open-Source Software bubble that is and the blogging bubble that was">The Open-Source Software bubble that is and the blogging bubble that was</a> (<a href="https://www.baldurbjarnason.com/2021/the-oss-bubble-and-the-blogging-bubble/" title="Accès à l’article original distant : The Open-Source Software bubble that is and the blogging bubble that was">original</a>)</li>
<li><a href="/david/cache/2022/7469f181ef4b031f59ae69356af16e28/" title="Accès à l’article dans le cache local : Modern Health, frameworks, performance, and harm">Modern Health, frameworks, performance, and harm</a> (<a href="https://ericwbailey.website/published/modern-health-frameworks-performance-and-harm/" title="Accès à l’article original distant : Modern Health, frameworks, performance, and harm">original</a>)</li>
@@ -145,12 +151,18 @@
<li><a href="/david/cache/2022/3ca10b945c7517c2f234e3b9534bfb6d/" title="Accès à l’article dans le cache local : Software Maxims">Software Maxims</a> (<a href="https://www.softwaremaxims.com/blog/not-a-supplier" title="Accès à l’article original distant : Software Maxims">original</a>)</li>
<li><a href="/david/cache/2022/9718ae2062146285e1c4f406240e04af/" title="Accès à l’article dans le cache local : An update on Robust Client-Side JavaScript">An update on Robust Client-Side JavaScript</a> (<a href="https://molily.de/update-on-robust-javascript/" title="Accès à l’article original distant : An update on Robust Client-Side JavaScript">original</a>)</li>
<li><a href="/david/cache/2022/63654b08ad9eda03b6bea8d1f82e2843/" title="Accès à l’article dans le cache local : Yearnotes #3 • détour.studio">Yearnotes #3 • détour.studio</a> (<a href="https://détour.studio/yearnotes/3/" title="Accès à l’article original distant : Yearnotes #3 • détour.studio">original</a>)</li>
<li><a href="/david/cache/2022/a09b5bf450d2cf86fb9e9d6f13b070e0/" title="Accès à l’article dans le cache local : Clever Code Considered Harmful">Clever Code Considered Harmful</a> (<a href="https://www.joshwcomeau.com/career/clever-code-considered-harmful/" title="Accès à l’article original distant : Clever Code Considered Harmful">original</a>)</li>
<li><a href="/david/cache/2022/daa39b64681b0574bbe189e80c8a4653/" title="Accès à l’article dans le cache local : I Was Wrong About Mastodon">I Was Wrong About Mastodon</a> (<a href="https://escapingtech.com/tech/opinions/i-was-wrong-about-mastodon-moderation.html" title="Accès à l’article original distant : I Was Wrong About Mastodon">original</a>)</li>
<li><a href="/david/cache/2022/3d3259256af967c84b199220b3a5244a/" title="Accès à l’article dans le cache local : Variability, Not Repetition, is the Key to Mastery">Variability, Not Repetition, is the Key to Mastery</a> (<a href="https://www.scotthyoung.com/blog/2022/10/26/variable-mastery/" title="Accès à l’article original distant : Variability, Not Repetition, is the Key to Mastery">original</a>)</li>
<li><a href="/david/cache/2022/660b2a27b116787ac44e536e6c9dbcd3/" title="Accès à l’article dans le cache local : Vibe Driven Development">Vibe Driven Development</a> (<a href="https://www.robinrendle.com/notes/vibe-driven-development/" title="Accès à l’article original distant : Vibe Driven Development">original</a>)</li>
<li><a href="/david/cache/2022/57fcca8aa6194cb2840d1dea002cb59b/" title="Accès à l’article dans le cache local : The Rise of GitHub in Scholarly Publications">The Rise of GitHub in Scholarly Publications</a> (<a href="https://arxiv.org/abs/2208.04895" title="Accès à l’article original distant : The Rise of GitHub in Scholarly Publications">original</a>)</li>
<li><a href="/david/cache/2022/d7f9460e62402a298210736cdf64b88c/" title="Accès à l’article dans le cache local : 7 Reasons why I don’t write">7 Reasons why I don’t write</a> (<a href="https://mxb.dev/blog/seven-reasons-why-i-dont-write/" title="Accès à l’article original distant : 7 Reasons why I don’t write">original</a>)</li>
@@ -193,6 +205,8 @@
<li><a href="/david/cache/2022/a0ccec7acb932e4155960c1c88d65eff/" title="Accès à l’article dans le cache local : La mission de Deuxfleurs">La mission de Deuxfleurs</a> (<a href="https://plume.deuxfleurs.fr/~/Deuxfleurs/La%20mission%20de%20Deuxfleurs" title="Accès à l’article original distant : La mission de Deuxfleurs">original</a>)</li>
<li><a href="/david/cache/2022/482252d2b8806e99bc30ffab2b2c51c9/" title="Accès à l’article dans le cache local : Des questions · Boris Schapira">Des questions · Boris Schapira</a> (<a href="https://boris.schapira.dev/notes/2023-02-des-questions/" title="Accès à l’article original distant : Des questions · Boris Schapira">original</a>)</li>
<li><a href="/david/cache/2022/ae079737f65e55da1d7a672b3a685b46/" title="Accès à l’article dans le cache local : Tolerance for boredom">Tolerance for boredom</a> (<a href="https://aworkinglibrary.com/writing/tolerance-for-boredom" title="Accès à l’article original distant : Tolerance for boredom">original</a>)</li>
<li><a href="/david/cache/2022/eebbf1a999fdf5c8aa80b65eccd9c48a/" title="Accès à l’article dans le cache local : Automating podcast transcripts on my Mac with OpenAI Whisper">Automating podcast transcripts on my Mac with OpenAI Whisper</a> (<a href="https://sixcolors.com/post/2023/02/automating-podcast-transcripts-on-my-mac-with-openai-whisper/" title="Accès à l’article original distant : Automating podcast transcripts on my Mac with OpenAI Whisper">original</a>)</li>

Loading…
Cancel
Save