feat: add ginger bug notes
This commit is contained in:
parent
07057994d0
commit
0676f74dc9
@ -1 +0,0 @@
|
||||
- [ ] [SomeThing](#SomeThing)- [ ] [SomeThing](#SomeThing)_Markdown Test_
|
@ -1,17 +0,0 @@
|
||||
# Max Personal Wiki
|
||||
|
||||
## 🗂️ [[Resources/index|Resources]]
|
||||
|
||||
## 📕 [[Media/index|Media]]
|
||||
|
||||
## 🏛️ [[Archive/index|Archive]]
|
||||
|
||||
## 🚀 [[Projects/index|Projects]]
|
||||
|
||||
## 🗺️ [[Areas/index|Areas]]
|
||||
|
||||
---
|
||||
|
||||
### 🗒 [[Notes/index|Notes]]
|
||||
|
||||
### ✅ [[Notes/tododolo|Tododolo]]
|
162
Media/articles/A clean start for the web.md
Normal file
162
Media/articles/A clean start for the web.md
Normal file
@ -0,0 +1,162 @@
|
||||
---
|
||||
author: twitter:tmcw
|
||||
link: https://macwright.com/2020/08/22/clean-starts-for-the-web.html
|
||||
status: not-finished
|
||||
date: August 2, 2023
|
||||
image: https://macwright.com/images/2020-08-22-clean-starts-for-the-web-illustration-of-web-pages.jpg
|
||||
---
|
||||
# A clean start for the web - macwright.com
|
||||
#technology #web-development #internet
|
||||
The web is in need of some reinvention right now.
|
||||
|
||||
The web’s evolution over the last decade has mirrored the American economy. All of the essential indicators are going “up and to the right,” a steady stream of fundamental advances reassure us that there “is progress,” but the actual experience and effects for individuals stagnates or regresses.
|
||||
|
||||
The crisis affects platforms, creators, and consumers alike.
|
||||
|
||||
_I’m going to try and dissect and diagnose this situation, a bit. You can skip forward if you just want to read my casual, unprofessional pitch for a reboot of the web. The idea is that we could choose a new lightweight markdown format to replace HTML & CSS, split the web into documents and applications, and find performance, accessibility, and fun again._
|
||||
|
||||
This post uses the pedantic definition of "the web"Ive discussed attempts to reinvent the "Internet" a few times. Things like dat, IPFS, and arweave are all projects to reinvent an Internet, or a transport and data-sharing layer. The web is what lies on top of that, the HTML, CSS, URLs, JavaScript, browsing experience.
|
||||
|
||||
### The platform collapse
|
||||
|
||||
The platform side is what changed last week, when [Mozilla laid off 250 employees](https://arstechnica.com/information-technology/2020/08/firefox-maker-mozilla-lays-off-250-workers-says-covid-19-lowered-revenue/) and indicated that it would affect Firefox development. Firefox wasn’t the #2 browser - that’s Safari, mainly because of the captive audience of iPhone and iPad users. But it was the most popular browser that people _chose_ to use.
|
||||
|
||||
![Chart of browser market share, with Chrome becoming the monopoly](https://macwright.com/images/2020-08-22-clean-starts-for-the-web-chart-of-browser-market-share-with-chrome-becoming-the-monopoly.png)
|
||||
|
||||
_Chart from [statcounter](https://gs.statcounter.com/browser-market-share#monthly-200901-202007)_
|
||||
|
||||
The real winner is not just Chrome, but Chrome’s engine. One codebase, [KHTML](https://en.wikipedia.org/wiki/KHTML), split into [WebKit](https://en.wikipedia.org/wiki/WebKit) (Safari), and [Blink](https://en.wikipedia.org/wiki/Blink_(browser_engine)) (Chrome, Microsoft Edge, Opera, etc.)
|
||||
|
||||
This is a textbook monoculture. In one sense, it’s a victory for collaboration because nobody’s ‘wasting time’ on competing implementations and web developers can expect the same features and bugs across different browsers. But in a deeper way, it threatens one of the basic principles of how the web has evolved.
|
||||
|
||||
### Specs & implementations
|
||||
|
||||
![Decline](https://macwright.com/images/2020-08-22-clean-starts-for-the-web-decline.jpg)
|
||||
|
||||
The web has evolved through a combination of _specifications_ and _implementations_. Organizations like the [WHATWG](https://whatwg.org/), [W3C](https://www.w3.org/), and [IETF](https://www.ietf.org/) have been collaboration spaces for independent developers, corporations, and academics to discuss potential new features of the web. Then, browsers would test those ideas out in a variety of implementations.
|
||||
|
||||
This was an interesting structural piece: it reassured us all that it was _possible_ to follow along, and that a multi-participant web was one of our goals. It was frustrating to pull up [caniuse](https://caniuse.com/) and see blank spots, but the idea was that different browsers may take the lead in some areas, but everyone catches up eventually. Chrome was not always the first to jump on features, or the first to optimize.
|
||||
|
||||
It’s slower to collaborate than to work alone, but it was beneficial in some ways that we’ve lost now. Chrome has been moving extremely fast, adding new specifications and ideas at a startling rate, and it’s becoming one of the hardest pieces of software to replicate.
|
||||
|
||||
Mike Healy I think [said it best](https://twitter.com/mike_hasarms/status/1296575224599556097):
|
||||
|
||||
> Do you think the web has almost ‘priced itself out of the market’ in terms of complexity if only 1-2 organisations are capable of building rendering engines for it?
|
||||
|
||||
Not only is it nearly impossible to build a new browser from scratch, once you have one the ongoing cost of keeping up with standards requires a full team of experts. Read Drew DeVault’s [Web browsers need to stop](https://drewdevault.com/2020/08/13/Web-browsers-need-to-stop.html) for that point, and keep reading all of Drew’s stuff.
|
||||
|
||||
What about Flow?Yep, there’s a [browser called Flow](https://www.ekioh.com/flow-browser/), which may exist and may support a full range of web standards. If it does exist, I’ll be very excited about it, but it has been teased for almost a year now without any concrete evidence, so it could equally be vaporware.
|
||||
|
||||
### The problem for creators
|
||||
|
||||
The web has gotten much harder to develop for.
|
||||
|
||||
The web has had about 25 years to grow, few opportunities to shrink, and is now surrounded by an extremely short-sighted culture that is an outgrowth of economic and career short-termism. There are lots of [ways to do anything](https://frankchimero.com/blog/2018/everything-easy/), and some of the most popular ways of building applications on the web are - in my opinion - [usually ghoulish overkill](https://macwright.com/2020/05/10/spa-fatigue.html).
|
||||
|
||||
The best way for folks to enter _web development_ in 2020 is to choose a niche, like [Vue.js](https://vuejs.org/) or [React](https://reactjs.org/), and hope that there’s a CSS and accessibility expert on their team.
|
||||
|
||||
For folks who just want to create a web page, who don’t want to enter an industry, there’s a baffling array of techniques, but all the simplest, probably-best ones are stigmatized. It’s easier to stumble into building your resume in React with GraphQL than it is to type some HTML in Notepad.
|
||||
|
||||
### The problem for consumers
|
||||
|
||||
We hope that all this innovation is _for the user_, but often it isn’t. Modern websites seem to be as large, slow, and buggy as they’ve ever been. Our computers are [barely getting faster](https://macwright.com/2019/11/15/something-is-wrong-with-computers.html) and our internet connection speeds are stagnating (don’t even _try_ to mention 5G). Webpage [size growth](https://www.pingdom.com/blog/webpages-are-getting-larger-every-year-and-heres-why-it-matters/) is outpacing it all.
|
||||
|
||||
The end result is that I no longer expect pages to be fast, even with [uBlock](https://github.com/gorhill/uBlock) installed in Firefox and a good local [fiber internet provider](https://sonic.net/).
|
||||
|
||||
I don’t want to lay all of the blame at _those web developers_, though. Here’s a story from an old job that I find kind of funny. We were collecting some data from user interactions to answer simple questions like “do people click to upload or do they drag & drop?” So we enabled [Segment](https://segment.com/), a tool that lets you add data-collection pipelines by including a single script. The problem, though, is that Segment offered a big page of on/off switches with hundreds of data providers & ad-tech companies on it. And, sure, enough, some folks closer to the business side started _clicking all those buttons_.
|
||||
|
||||
See, the problem with ads and data tracking is that _you can_, and who is going to say no? (In that instance, I said no, and added a [CSP](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) that would block new advertiser access at the page level.)
|
||||
|
||||
## Recreating simplicity
|
||||
|
||||
> You cannot get a simple system by adding simplicity to a complex system. - [Richard O’Keefe](https://erlang.org/pipermail/erlang-questions/2012-March/065087.html)
|
||||
|
||||
Where do we go from here? Some of the smartest folks out there have been [advocating for a major version revision](https://twitter.com/_developit/status/1296628134406692865) of the web.
|
||||
|
||||
_I am in no way qualified to speculate on a whole new web from scratch, but the [air quality](https://www.nytimes.com/2020/08/21/us/california-wildfires.html) is scary so I’m skipping my run and it’s Saturday morning so here we are._
|
||||
|
||||
How do we make the web fun, participatory, and good?
|
||||
|
||||
My first thought is that there are two webs:
|
||||
|
||||
### The document web
|
||||
|
||||
![Illustration of web pages](https://macwright.com/images/2020-08-22-clean-starts-for-the-web-illustration-of-web-pages.jpg)
|
||||
|
||||
There is the “document web”, like blogs, news, Wikipedia, Twitter, Facebook. This is basically the original vision of the web, as far as I can understand it (I was 2). Basically CSS, which we now think of as a way for designers to add brand identity and tweak pixel-perfect details, was instead mostly a way of making plain documents readable and letting the _readers_ of those documents customize how they looked. This attribute actually [survived for a while in Chrome, in the form of user stylesheets](https://twitter.com/autiomaa/status/1296755641164468224), and [still works in Firefox](https://davidwalsh.name/firefox-user-stylesheet). Though it’s going to be a rough ride in the current web which has basically thrown away [semantic HTML](https://en.wikipedia.org/wiki/Semantic_HTML) as an idea.
|
||||
|
||||
### The “application” web
|
||||
|
||||
![Illustration of machines](https://macwright.com/images/2020-08-22-clean-starts-for-the-web-illustration-of-machines.jpg)
|
||||
|
||||
Then there’s the “application web”. This started as _server_ applications, built with things like [Django](https://www.djangoproject.com/) and [Ruby on Rails](https://rubyonrails.org/) and before them a variety of technologies that will live forever in corporations, like [Java Servlets](https://en.wikipedia.org/wiki/Jakarta_Servlet).
|
||||
|
||||
[Backbone.js](https://backbonejs.org/) demonstrated that a lot of these applications could be moved into the browser, and then [React](https://reactjs.org/) and its many SPA-style competitors established a new order for the web – highly-interactive, quite complex, client-side applications.
|
||||
|
||||
### The war between the parts of the web
|
||||
|
||||
I posit that this dual-nature is part of what gives the web its magic. But it’s also a destructive force.
|
||||
|
||||
The magic is that a simple blog can be creative expression, can be beautifully interactive. This one isn’t, but I’m just saying - [it’s possible](https://www.typewolf.com/site-of-the-day).
|
||||
|
||||
The problem is that the “document web” is often plagued by application characteristics - it’s the JavaScript and animations and complexity that makes your average newspaper website an unmitigated disaster. Where document websites adopt application patterns they often accidentally sacrifice [accessibility](https://www.a11yproject.com/), performance, and [machine readability](https://en.wikipedia.org/wiki/Web_scraping).
|
||||
|
||||
And the “application web” is plagued by the document characteristics - interactive applications are going to great lengths to avoid most of the essential characteristics of HTML & CSS and just use them as raw materials - avoiding writing any HTML directly at all, avoiding [writing any CSS directly at all](https://mxstbr.com/thoughts/css-in-js), avoiding [default animation features](https://www.react-spring.io/), replacing [page-based navigation with something that looks like it but works completely differently](https://reactrouter.com/). The application web uses [JSX](https://reactjs.org/docs/introducing-jsx.html), not HTML, and would like that in the browser itself, or [Svelte](https://svelte.dev/), instead of JavaScript, and would like that too.
|
||||
|
||||
When I read blog posts from ‘traditional web developers’ who are mad that HTML & CSS aren’t enough anymore and that everything is complicated – I think this is largely that the application stack for building websites has replaced the document stack in a lot of places. Where we would use Jekyll or server-side rendering, we now use React or Vue.js. There are advantages to that, but for a lot of minimally-interactive websites, it’s throwing away decades worth of knowledge in exchange for certain performance perks that might not even matter.
|
||||
|
||||
The appeal of social networks is partly because they let us create _documents_ without thinking about web technology, and they provide guarantees around performance, accessibility, and polish that otherwise would take up our time. You don’t have to think about whether your last Facebook post will load quickly on your friend’s phone or whether your Instagram post will be correctly cropped and resized in the timeline - those things are taken care of.
|
||||
|
||||
To some extent, this doesn’t _need_ to be something that only social networks provide, though: standards like [RSS](https://en.wikipedia.org/wiki/RSS) and services like [Instapaper](https://www.instapaper.com/) show that pleasing formatting and distribution can be done at the _platform level_ and be provided on top of existing vanilla websites.
|
||||
|
||||
These are not absolutes.Yeah, I can hear it now: but these categories are not precise! There are plenty of applications that dont sacrifice performance or accessibility, and plenty of document websites that genuinely need interactivity, and plenty of web developers who are just using the platform - vanilla JavaScript or web components - and who dont need or want the web to be different. All categories that you draw out of real-world environments are going to be imprecise. Thats how all non-technical thinking works: the question isnt whether theyre perfect, its whether theyre useful for advancing the discussion.
|
||||
|
||||
## Document web 2.0
|
||||
|
||||
A unified theory of a new web that had just enough application characteristics and enough document characteristics to provide the sorts of hybrid interactive documents that we see today - now that would be cool. But the path to a splintered web is clearer and is what I’m thinking of first, so here’s some of that.
|
||||
|
||||
- Rule #1 is _don’t make a subset_. If the replacement for the web is just whatever features were in Firefox 10 years ago, it’s not going to be a compelling vision.
|
||||
- Rule #2 is _don’t make it compatible_. If the replacement web lives alongside, undifferentiated from the current web, then you’ll never actually reduce complexity because replacement web browsers will still support everything, and people won’t be encouraged to leave the old web.
|
||||
- Rule #3 is _make it better for everyone_. There should be a perk for everyone in the ecosystem: people making pages, people reading them, and people making the technology for them to be readable.
|
||||
|
||||
Okay, so let’s say we’re creating a new document web.
|
||||
|
||||
**First, you need a minimal, standardized markup language for sending documents around.** You might want to start with a [lightweight markup language](https://en.wikipedia.org/wiki/Lightweight_markup_language), which will ironically be geared toward generating HTML. Markdown’s strict specified variation, [Commonmark](https://spec.commonmark.org/), seems like a pretty decent choice. That’s the language I’ve written all my blog posts in, and the most popular language in its family. There are lots of great parsers and a big ecosystem of tools for Markdown.
|
||||
|
||||
**Then, you need a browser.** Mozilla has been working on a brand new browser for a while - [Servo](https://servo.org/). That team got laid off last week, which sucks. That project includes standalone Rust crates for [font rendering](https://github.com/servo/pathfinder), and there’s a [world-class Rust Markdown implementation](https://github.com/raphlinus/pulldown-cmark), and a growing set of [amazing application frameworks](https://github.com/linebender/druid). Could you build a pure-Markdown-browsing browser that goes straight through this pipeline? Maybe?
|
||||
|
||||
I think this combination would bring speed back, in a huge way. You could get a page on the screen in a fraction of the time of the web. The memory consumption could be tiny. It would be incredibly accessible, by default. You could make great-looking default stylesheets and share alternative user stylesheets. With dramatically limited scope, you could port it to all kinds of devices.
|
||||
|
||||
And, maybe most importantly, what would website editing tools look like? They could be _way_ simpler.
|
||||
|
||||
What could aggregation look like? If web pages were more like documents than applications, we wouldn’t need RSS - websites would have an index that points to documents and a ‘reader’ could aggregate actual webpages by default.
|
||||
|
||||
We could link between the webs by using something like dat’s [well-known file](https://beakerbrowser.com/docs/guides/use-a-domain-name-with-dat#well-knowndat), or using the [Accept header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept) to create a browser that can accept HTML but prefers lightweight pages.
|
||||
|
||||
## Application web 2.0
|
||||
|
||||
I feel like every time I mention something about the web, the automatic response is that WebAssembly might fix it. Maybe?
|
||||
|
||||
I don’t know. WebAssembly _is_ pretty great, but should web applications just be rendered to a canvas, and every application brings its own graphics toolkit? Do we really want anti-aliasing differences between web applications? Applications-in-containers is a thing - look at [Qubes](https://www.qubes-os.org/) - but it’s not really something that users should want. Anyone who has used Blender or Inkscape on a mac has some idea of how this goes.
|
||||
|
||||
Or is WebAssembly the new ‘core’ and we still render UIs with HTML? Or… create a shared linked library that WebAssembly apps can use that works roughly like [SwiftUI](https://developer.apple.com/documentation/swiftui), offering application-friendly layout conventions like constraints instead of document-centric ideas like line heights and floats?
|
||||
|
||||
The problem with imagining the application web is that it’s pretty expansive.
|
||||
|
||||
The worse the ‘Mac App Store’ and ‘Windows App Store’ and ’App Store’ and ’Play Store’ get, the bigger a cut those monopolies demand, the more it costs to be a Mac or Windows developer, the more that applications get pushed to the web. Sure, some applications are _better_ on the web. But a lot are just there because it’s the only place left where you can easily, cheaply, and freely share or sell a product.
|
||||
|
||||
There was a time when we could install applications, give some sort of explicit agreement that something would run on our computers and use our hardware. That time is ending, and web pages now have rather complex ways of getting at everything from webcams to files, game controllers, audio synthesis, cryptography, and everything else that was once the domain of `.exe` and `.app`s. This is empowering, sure, but is quite an unusual situation.
|
||||
|
||||
### Who’s working on this?
|
||||
|
||||
- [Beaker Browser](https://beakerbrowser.com/) is partly a reinvention of the _internet_ – it’s the simplest [way to use dat for decentralization](https://macwright.com/2017/07/20/decentralize-your-website.html), but they’re also experimenting with new kinds of documents and ways of authoring.
|
||||
- [Project Gemini](https://gemini.circumlunar.space/) is a really interesting, distinctly retro-flavored web alternative. (via [Jesse](https://jklabs.net/))
|
||||
- I’ve been pretty inspired by [taizen](https://github.com/NerdyPepper/taizen), a command-line based Wikipedia browser. It shows how a text-first experience can be really fun.
|
||||
|
||||
### What do you think?
|
||||
|
||||
There are a lot of other ways to look at and solve this problem. I think it _is_ a problem, for everyone except Google. The idea of a web browser being something we can _comprehend_, of a web page being something that _more people can make_, feels exciting to me.
|
||||
|
||||
The markdown-centric approach feels very doable. I think the clearest rebuttal is that it ‘sucks all the fun out of the web,’ and there’s some truth to that. But the early web wasn’t fun in many conventional ways - you couldn’t quite create art there, or use it as much more than a way of sharing documents. But it was fun as heck, because sharing is fun and it was simple and flexible in some cool ways. So the key is to discover the small things that unlock the possibilities in this plan, if they’re there. Or find a different plan with ‘just enough fun.’
|
||||
|
||||
Social networks are universally _more restrictive_ than web pages but also _more fun_ in significant ways, chief amongst them being that more people can participate. What if the rest of the web have that simplicity and immediacy, but without the centralization? What if we could start over?
|
@ -0,0 +1,66 @@
|
||||
---
|
||||
author:
|
||||
link: https://netzpolitik.org/2023/studien-zu-facebook-und-instagram-algorithmen-ruetteln-kaum-an-politischen-einstellungen/
|
||||
status: not-finished
|
||||
date: August 1, 2023
|
||||
image: https://cdn.netzpolitik.org/wp-upload/2023/07/imago109546902_1600-860x484.jpg
|
||||
---
|
||||
# Studien zu Facebook und Instagram: Algorithmen rütteln kaum an politischen Einstellungen – netzpolitik.org
|
||||
|
||||
#scientific-research #social-media #algorithm #misinformation #political-influence
|
||||
|
||||
Es ist ein wissenschaftliches Großprojekt: In insgesamt 16 Studien untersuchen Wissenschaftler:innen, welchen Einfluss Algorithmen auf die Verbreitung von Falschinformationen und Polarisierung haben. Zwei der weltweit größten sozialen Netzwerke stehen dabei im Fokus: Facebook und Instagram. Beide Plattformen gehören dem Tech-Konzern Meta an.
|
||||
|
||||
Die ersten vier Studien wurden nun in den wissenschaftlichen Zeitschriften [Science](https://www.science.org/doi/10.1126/science.adj7023?adobe_mc=MCMID%3D61761082717445531361376140889916401782%7CMCORGID%3D242B6472541199F70A4C98A6%2540AdobeOrg%7CTS%3D1690482061) und [Nature](https://www.nature.com/articles/s41586-023-06297-w) veröffentlicht. Die Ergebnisse zeichnen – zumindest für den Zeitraum der zweiten Jahreshälfte 2020 in den Vereinigten Staaten – ein differenziertes Bild davon, wie US-Amerikaner:innen soziale Netzwerke nutzen, und welche Auswirkungen dies auf ihre politischen Überzeugen und den gesellschaftlichen Diskurs hat.
|
||||
|
||||
Demnach spielen die beiden Plattformen eine entscheidende Rolle dabei, die Nutzer:innen zu Inhalten zu leiten, denen sie wahrscheinlich zustimmen. Die Studien bezweifeln jedoch, dass Meta die politischen Überzeugungen der Nutzer:innen signifikant beeinflussen kann.
|
||||
|
||||
Aus Sicht von Meta bestätigen die Studien damit [frühere Aussagen des Unternehmens](https://www.washingtonpost.com/technology/2021/11/13/facebook-news-feed-algorithm-how-to-turn-it-off/), wonach es für die Nutzer:innen von Vorteil sei, wenn Algorithmen deren Feeds sortierten. Kritiker:innen entgegnen, dass die Studien vor allem zeigten, dass das Problem mannigfaltiger sei als bislang zumeist angenommen und der Konzern nicht aus der Verantwortung entlassen sei.
|
||||
|
||||
### Verschärfen Algorithmen die gesellschaftliche Polarisierung?
|
||||
|
||||
Die Forschungen starteten offiziell Ende August 2020, also noch vor der US-Präsidentschaftswahl im November des gleichen Jahres. Ein Team aus rund zwei Dutzend Facebook-Forscher:innen und externen Wissenschaftler:innen [untersuchte über mehrere Monate konkret](https://medium.com/@2020_election_research_project/a-proposal-for-understanding-social-medias-impact-on-elections-4ca5b7aae10), welche Auswirkungen Facebook und Instagram unter anderem auf die politische Beteiligung, die politische Polarisierung und die Verbreitung von Falschwahrnehmungen hat.
|
||||
|
||||
An drei der vier Studien nahmen für einen Zeitraum von knapp drei Monaten mehrere zehntausend US-amerikanische Facebook- und Instagram-Nutzer:innen teil. Ihre Identifikationsdaten wurden dabei unkenntlich gemacht. Für die vierte Studie stellte Meta den Forschenden anonymisierte Daten von rund 208 Millionen Facebook-Nutzer:innen zur Verfügung.
|
||||
|
||||
In der ersten Studie mit dem Titel [„Wie beeinflussen Algorithmen von Social-Media-Feeds die Einstellungen und Verhalten in Wahlkampagnen?“](https://www.science.org/doi/10.1126/science.abp9364) sahen die teilnehmenden Facebook- und Instagram-Nutzer:innen drei Monate lang einen chronologisch statt algorithmisch sortierten Nachrichten-Feed. Die Beiträge waren also nach ihrer zeitlichen Aktualität sortiert und nicht vorrangig nach den persönlichen Interessen der einzelnen Nutzer:innen.
|
||||
|
||||
Die Forschenden fanden heraus, dass die chronologische Anzeige – eine Option, die Facebook erst wieder seit Kurzem seinen Nutzer:innen anbietet – „den Anteil von Inhalten aus als nicht vertrauenswürdig eingestuften Quellen um mehr als zwei Drittel im Vergleich zum algorithmischen Feed erhöhte, während er die Anzeige von unhöflichen Inhalten um fast die Hälfte reduzierte“. Zugleich aber habe die chronologische Anzeige keinen nennenswerten Einfluss auf die „Polarisierung“ oder das politische Wissen der Menschen gehabt.
|
||||
|
||||
Algorithmen übten zweifelsohne einen großen Einfluss darauf aus, wie Menschen Inhalte auf den Plattformen wahrnehmen, so Talia Jomini Stroud, eine der Studienleiter:innen und Direktorin des Center for Media Engagement an der University of Texas [gegenüber dem britischen Guardian](https://www.theguardian.com/technology/2023/jul/27/meta-facebook-algorithm-2020-election), „wir haben aber auch festgestellt, dass \[…\] eine Änderung der Algorithmen in den sozialen Medien die politischen Einstellungen nicht beeinflusst haben.“
|
||||
|
||||
Und noch etwas habe sich gezeigt: Ohne algorithmisch vorsortiertem Feed verringert sich die Zeit, die Nutzer:innen auf Facebook oder Instagram verbringen, deutlich. Zugleich verbrachten sie mehr Zeit auf TikTok, YouTube und anderen Plattformen. Aus Sicht der Forschenden zeige dies, wie wichtig die algorithmischen Sortierung für Meta aus wirtschaftlichen Gründen ist.
|
||||
|
||||
### Facebook und Instagram sind mächtige Kuratiermaschinen
|
||||
|
||||
[Die zweite Studie](https://www.science.org/doi/10.1126/science.ade7138) nahm das Nutzungsverhalten von etwa 208 Millionen US-amerikanischen Facebook-Nutzer:innen rund um die US-Präsidentschaftswahl im Jahr 2020 – konkret von September 2020 bis Februar 2021 – in den Blick.
|
||||
|
||||
Die Forschenden kommen zu dem Schluss, dass Facebook „ideologisch stark gespalten ist – weit mehr als frühere Forschungen zum Nachrichtenkonsum im Internet auf der Grundlage des Surfverhaltens ergeben haben.“ Die Spaltung werde aber weniger durch die Inhalte geprägt, die Freund:innen posten, sondern erheblich mehr durch Facebook-Seiten und -Gruppen. Aus Sicht der Forschenden veranschaulicht dies, dass Facebook-Seiten und -Gruppen eine „sehr mächtige Kurations- und Verbreitungsmaschine“ seien.
|
||||
|
||||
Außerdem stellt die Studie fest, dass weit mehr Konservative Falschinformationen sehen und teilen würden als Liberale. Demnach waren 97 Prozent der als Falschinformation deklarierten Meldungen bei Konservativen beliebter als bei Liberalen. Konservative neigten zudem dazu, vergleichsweise mehr politische Nachrichten zu lesen, die auch von anderen Konservativen gelesen würden, so die Studie.
|
||||
|
||||
### Wenig Auswirkungen auf die Überzeugungen
|
||||
|
||||
Allerdings habe das Verhalten der Nutzer:innen nicht unmittelbar Einfluss auf deren Überzeugungen, so das Ergebnis [der dritten Studie](https://www.nature.com/articles/s41586-023-06297-w). Für diese Studie reduzierten die Forschenden die Menge jener Inhalte, die von „gleichgesinnten“ Verbindungen in die Feeds von mehr als 23.000 Facebook-Nutzer:innen gepostet wurden, um rund ein Drittel.
|
||||
|
||||
Dies führte zwar dazu, dass die Nutzer:innen deutlich mehr Inhalte aus Quellen jenseits des eigenen politischen Spektrums sahen. Allerdings interagierten sie weniger mit diesen Inhalten als mit jenen, die ihren eigenen Überzeugungen entsprachen. Vor allem aber hatten die anderen Inhalte keine messbaren Auswirkungen auf die Überzeugungen der Studienteilnehmer:innen, ihre Einschätzung von politischen Kandidat:innen oder die politische Polarisierung im Allgemeinen.
|
||||
|
||||
Zu einem ähnlichen Schluss kommt die [vierte Studie](https://www.science.org/doi/10.1126/science.add8424), die das Verhalten von 27.000 Facebook- und Instagram-Nutzer:innen untersuchte. Hier nahmen die die Forschenden den Teilnehmer:innen die Möglichkeit, Beiträge erneut zu teilen. Diese sogenannten Reshares sorgen maßgeblich dafür, das Inhalte bei Facebook „viral gehen“.
|
||||
|
||||
Fehlt die Möglichkeit, hat dies vor allem Auswirkungen darauf, wie sich politische Nachrichten sowie Meldungen aus nicht-vertrauenswürdigen Quellen verbreiten. Infolgedessen nimmt zwar unter anderem das Wissen der Studienteilnehmer:innen über politische Nachrichten ab. Allerdings habe auch dies keine signifikanten Folgen auf die Überzeugungen der Nutzer:innen, so die Studie.
|
||||
|
||||
### Ergebnisse sind nur eingeschränkt verallgemeinbar
|
||||
|
||||
Meta sieht sich durch die bisherigen Forschungsergebnisse bestätigt. Laut Nick Clegg, Leiter von Metas Unternehmenskommunikation, [zeigen die Forschungen](https://about.fb.com/news/2023/07/research-social-media-impact-elections/), „dass es wenig Beweise dafür gibt, dass zentrale Funktionen von Metas Plattformen allein eine schädliche ‚affektive‘ Polarisierung verursachen oder irgendeinen bedeutenden Einfluss auf wichtige politische Einstellungen, Überzeugungen oder Verhaltensweisen haben.“
|
||||
|
||||
Indes [sagen selbst die Forschenden](https://www.science.org/doi/10.1126/science.abp9364), die die erste Studie erstellt haben, dass die Ergebnisse der Studien nur mit Einschränkungen verallgemeinbar seien. Demnach sei der Studienzeitraum von drei Monaten zwar länger als der vieler anderer Untersuchungen zur politischen Kommunikation. Allerdings wären die Ergebnisse „möglicherweise anders ausgefallen, wenn diese Studie nicht während eines polarisierten Wahlkampfes \[…\] und in einem spezifischen politischen Kontext (den Vereinigten Staaten) durchgeführt worden wäre.“
|
||||
|
||||
Die Whistleblowerin Frances Haugen kritisiert ebenfalls den Zeitpunkt der Untersuchungen. Die ehemalige Facebook-Produktmanagerin, [die 2021 Tausende von internen Facebook-Dokumenten an die Börsenaufsichtsbehörde weitergab](https://netzpolitik.org/2021/facebook-leaks-whistleblowerin-erhebt-schwere-vorwuerfe-gegen-facebook/), [weist unter anderem darauf hin](https://www.washingtonpost.com/technology/2023/07/27/social-media-research-meta-political-views/), dass Meta bereits in den Monaten vor der damaligen US-Präsidentschaftswahl einige „seiner aggressivsten Wahlschutzmaßnahmen“ eingeführt habe, um gegen extreme Beiträge vorzugehen. Viele der Maßnahmen habe der Konzern nach der Wahl wieder zurückgenommen, so Haugen.
|
||||
|
||||
### Meta darf sich nicht der Verantwortung entziehen
|
||||
|
||||
Ohnehin sollte sich Meta nicht allzu kräftig auf die Schulter dafür klopfen, dass es Forschenden seine Daten zur Verfügung stellt. Denn die laut Clegg „beispiellose Forschungspartnerschaft zwischen Meta und externen Akademikern“ wird wohl gezwungenermaßen fortgesetzt: Laut Digital Service Act (DSA), der im November vergangenen Jahres in Kraft trat, [müssen Internet-Plattformen](https://netzpolitik.org/2023/digital-services-act-wie-die-forschung-den-datenschatz-der-plattformen-heben-kann/) künftig deutlich rigider gegen „systemische Risiken“ vorgehen als in der Vergangenheit. Zu diesen Risiken zählen unter anderem die systematische Verletzung der Privatsphäre oder des Rechts auf freie Meinungsäußerung. Damit diese Risiken aber überhaupt entdeckt werden können, räumt das EU-Gesetz Forscher:innen umfassenden Zugang zu den Daten der großen Plattformen ein – ob diese wollen oder nicht.
|
||||
|
||||
Bürgerrechtsorganisationen weisen zudem darauf hin, dass die Studienergebnisse Meta und andere Technologieunternehmen keineswegs aus jener Verantwortung entlassen würden, die sie für gesellschaftliche Spaltungen, politische Umwälzungen und der Verbreitung von Verschwörungsmythen trügen. „Die von Meta unterstützten Studien, die sich mit kleinen Stichprobenzeiträumen befassen, sollten nicht als Entschuldigung dafür dienen, dass Lügen verbreitet werden können“, sagt [Nora Benavidez](https://www.freepress.net/about/staff/nora-benavidez), Senior Counsel bei der Bürgerrechtsgruppe Free Press [gegenüber der Washington Post](https://www.washingtonpost.com/technology/2023/07/27/social-media-research-meta-political-views/). „Social-Media-Plattformen sollten sich im Vorfeld von Wahlen stärker engagieren und nicht neue Pläne aushecken, um sich der Verantwortung zu entziehen“, so die Juristin.
|
||||
|
||||
Ähnlich sieht das der Journalismus-Professor Michael W. Wagner, der an der Universität von Wisconsin lehrt und als unabhängiger Beobachter der Forschungskooperation fungiert. Aus seiner Sicht belegen die Studien keineswegs, dass soziale Plattformen wie Facebook „kein Problem sind“. Vielmehr dienten die Studien aus seiner Sicht als „ein guter wissenschaftlicher Beweis dafür, dass es nicht nur ein Problem gibt, das leicht zu lösen ist.“![](https://vg03.met.vgwort.de/na/f9cc43553fa34f59b5a4b27bc0dfd306)
|
317
Media/articles/CRDT Conflict-free Replicated Data Types.md
Normal file
317
Media/articles/CRDT Conflict-free Replicated Data Types.md
Normal file
@ -0,0 +1,317 @@
|
||||
---
|
||||
author: Anton Zagorskii
|
||||
link: https://medium.com/@amberovsky/crdt-conflict-free-replicated-data-types-b4bfc8459d26
|
||||
status: not-finished
|
||||
date: August 2, 2023
|
||||
image: https://miro.medium.com/v2/resize:fit:640/format:webp/1*XuvlrrlQl3jU7-NWbWzmSw.png
|
||||
---
|
||||
# CRDT: Conflict-free Replicated Data Types | by Anton Zagorskii | Medium
|
||||
#technology #data-synchronization #distributed-systems
|
||||
|
||||
How to count google.com hits? What about how to store “likes” of popular users? In this article we will consider solutions for these tasks using CRDT (Conflict-free Replicated Data Types) and also a more general case — how to synchronize replicas in a multi-leader distributed system.
|
||||
|
||||
## 1. Introduction:
|
||||
|
||||
We used to use applications such us calendar or Evernote for a long time. They have something in common — at the same time all of them allow (in any combination)
|
||||
|
||||
- to work offline
|
||||
- to access from different devices
|
||||
- several people to modify the same data
|
||||
|
||||
The task the developers of those systems have to solve is how to ensure “smooth” data synchronization in such cases. Ideally, user interaction should not be required.
|
||||
|
||||
In the [previous article](/coinmonks/operational-transformations-as-an-algorithm-for-automatic-conflict-resolution-3bf8920ea447) we’ve considered an approach to solve a similar task — Operational Transformation. This time we are going to consider another approach which introduces a special set of base data types which resolves merge conflicts by themselves.
|
||||
|
||||
## 2. Strong eventual consistency:
|
||||
|
||||
Many works and many researches have been done recently about eventual consistency. In my opinion, the current trend is to shift from strong consistency to other possible consistency variations, to research what consistency model fits best in a particular system/situation, to rethink current definitions.
|
||||
|
||||
That leads us to some inconsistency, for example when some researchers consider an eventual consistency with a special property but at the same time, other authors already created a definition for that particular case.
|
||||
|
||||
There is a question raised by authors of one research about current definition of the eventual consistency. According to it, if your system always returns “42” to all requests — all is OK, it is eventually consistent.
|
||||
|
||||
I will use the following terminology without breaking the correctness either of this article or of original researches (please note these are not definitions!)
|
||||
|
||||
- Strong consistency (SC): all write operations are done strictly sequentially, read request on any replicas returns the same, last written result. **A real-time consensus (with all its following consequences) is required** to solve conflicts, allow n/2–1 nodes to be down
|
||||
- Eventual consistency (EC): make updates on the local, then propagate updates. Read on some replicas can return obsolete state. Rollback or somehow decide what to do in case of conflicts. That means **we still need consensus, but not in the real-time**
|
||||
- Strong eventual consistency (SEC): EC + replicas have a recipe to solve conflicts automatically. Therefore we do not require a consensus. Allows n-1 nodes to be down.
|
||||
|
||||
A quick note: if we loosen SC requirement in the CAP theorem then SEC solves it — all properties are satisfied.
|
||||
|
||||
So, we are happy to sacrifice SC and we want a set of base data types for our unstable and often partitioned distributed system. Also, we want those data types to resolve conflicts for us so we don’t need to interact with a user or query an arbiter node.
|
||||
|
||||
## 3. “Likes and hits” problems:
|
||||
|
||||
Of course, there are several ways to solve those problems, CRDT offers a simple and elegant solution.
|
||||
|
||||
## Count google.com hits:
|
||||
|
||||
Google.com serves approximately 150000 requests per second from all places on Earth. It is clear — we need to update the counter asynchronously. Queues will help, but not entirely — imagine if we exposed an API to get counter’s value then we would need to do a replication, otherwise read requests can put the system down.
|
||||
|
||||
If we already do the replication — can we avoid queues?
|
||||
|
||||
## Count a user’s likes:
|
||||
|
||||
The problem is similar to the previous one, but this time we need to count unique hits.
|
||||
|
||||
## 4. Terminology:
|
||||
|
||||
It is advised to be familiar with the following terminology:
|
||||
|
||||
1. [Idempotence](https://en.wikipedia.org/wiki/Idempotence) The result doesn’t change if you apply the same operation several times.
|
||||
Example:
|
||||
1) GET request
|
||||
2) f(x) = x + 0
|
||||
2. [Commutative property](https://en.wikipedia.org/wiki/Commutative_property) f(x, y) = f(y, x)
|
||||
3. [Partial order](https://en.wikipedia.org/wiki/Partially_ordered_set) Reflexivity + Transitivity + Antisymmetry
|
||||
4. [Semilattice](https://en.wikipedia.org/wiki/Semilattice) Partially ordered set with a least upper bound
|
||||
5. [Version vector](https://en.wikipedia.org/wiki/Version_vector)
|
||||
A vector with a size of the amount of nodes. Each node increments its vector element in case of some predefined events. During synchronization, these vectors are sent together with the payload and then by examining which node has greater value it can be decided which node has new/obsolete values. Thus it defines a total order.
|
||||
|
||||
## 5. Synchronisation models:
|
||||
|
||||
## State-based:
|
||||
|
||||
Also called a passive synchronisation, forms **Convergent Replicated Data Type — CvRDT**.
|
||||
|
||||
Used in such file systems as NFS, AFS, Coda and in such KV-storages like Riak, Dynamo.
|
||||
|
||||
In this case, replicas propagated changes by sending a full state of the objects. A merge() function must be defined to merge incoming changes with the current state.
|
||||
|
||||
Following requirements have to be satisfied to ensure convergence for replicas:
|
||||
|
||||
- Data type (or states on replicas) forms a semilattice
|
||||
- merge() function produces a least upper bound
|
||||
- Replicas form a connected graph
|
||||
|
||||
Example:
|
||||
|
||||
- Data type: set of natural numbers N
|
||||
- Minimal element — negative infinity
|
||||
- merge(x, y) = max(x, y)
|
||||
|
||||
Such requirements give us a **commutative** and **idempotent** merge() function, which also is **a monotonically increasing** function on the given data type.
|
||||
|
||||
That guarantees all replicas will eventually converge and allows us not to worry about a transmission protocol — **we can lose propagation updates, we can send them several times or even send them in any order**.
|
||||
|
||||
## Operation-based:
|
||||
|
||||
Also called an active synchronisation, forms **Commutative Replicated Data Type — CmRDT**.
|
||||
|
||||
Used in such cooperative systems, like Bayou, Rover, IceCube, Telex.
|
||||
|
||||
In this case replica propagates changes by sending the operation to all replicas. When a change is made on a replica, it:
|
||||
|
||||
1. Executes generate() method which returns an effector() function to be called on other replicas. In other words, effector() is a closure to modify state on other replicas.
|
||||
2. Applies effector() to the local state.
|
||||
3. Propagates effector() to all other replicas
|
||||
|
||||
Following requirements have to be satisfied to ensure convergence for replicas:
|
||||
|
||||
- Reliable transmission protocol
|
||||
- If effector() is delivered in causal order then concurrent effector() have to commute **OR**
|
||||
- If effector() is delivered without respecting causal order then all effecter() have to commute
|
||||
- effector() has to be idempotent if it can be delivered more than once.
|
||||
|
||||
Some realisations rely on reliable publish-subscribe systems (Kafka) as a part of the delivery.
|
||||
|
||||
## Delta-based:
|
||||
|
||||
It can be easily noted considering State/Op based synchronisations that it doesn’t make sense to transmit a whole object’s state if a change affects only a part of it. Also, we can periodically send only one aggregated state if updates modify the same state — like counters.
|
||||
|
||||
Delta synchronisation combines both State/op approaches and propagates so-called delta-mutators which update the state accordingly to the last synchronisation date. You need to send a full state in case of the first ever synchronisation, however, some realisations actually consider the state of the remote replicas to lower the amount of needed data.
|
||||
|
||||
If delays are allowed then an op-based log compression could be the next optimization:
|
||||
|
||||
## Pure operation-based:
|
||||
|
||||
There is a delay in the op-based synchronization to create an effector(). In some systems such delays are unacceptable. In this case an update must be propagated immediately at the cost of more complex organization protocol and more space requirements for metadata.
|
||||
|
||||
## Typical usages:
|
||||
|
||||
- If in your system **updates must be propagated immediately** the state-based synchronization is the bad choice because it costs more to the whole state. Delta-based would be the better choice, however, in this particular case the difference with state-based won’t be that much.
|
||||
- In case when you need to **synchronize a replica after a failure** — state-based / delta-based is the right choice. If you have to use the op-based, then there are options:
|
||||
1) Reply all missed changes since the failure
|
||||
2) Take a full copy of one of the replicas and apply all missed operations
|
||||
- As it has been mentioned earlier, op-based synchronization requires effector() to be delivered only once to each replica. This requirement can be loosened by requiring effector() to be idempotent. In practice, it is much easier to implement the former than the latter.
|
||||
|
||||
## The relation between Op-based and State-based:
|
||||
|
||||
Op-based and State-based synchronizations can be emulated by each other with keeping CRDT requirements. So further we are not going to pay much attention to the realization details except some interesting cases.
|
||||
|
||||
## Now it’s time to talk about CRDT!
|
||||
|
||||
## 6. CRDT: Counter
|
||||
|
||||
An integer value with two operations: inc() and dec(). Let’s consider some implementations of op-based и state-based synchronisation:
|
||||
|
||||
## 6.1 Op-based counter:
|
||||
|
||||
Quite obvious, we just need to propagate updates. An example of inc():
|
||||
generator() { return function (counter) { counter += 1 } }
|
||||
|
||||
## **6.2 State-based counter:**
|
||||
|
||||
Tricky one as it is very unclear how to implement the merge() function. To address that some variations were proposed:
|
||||
|
||||
**_6.2.1 Increment only counter, G-Counter:_**
|
||||
|
||||
Let’s use a vector with the size of the amount of replicas (aka version vector) and each replica increases it’s vector element (by replica id) in the inc() operation. merge() function takes the maximum of corresponding vector items, the sum of all vector elements in the value of the counter
|
||||
|
||||
Also, G-Set can be used (see below)
|
||||
|
||||
Usages:
|
||||
|
||||
- Hits/likes counter (sic!)
|
||||
|
||||
**_6.2.2 PN-counter (Increment + Decrement):_**
|
||||
|
||||
Uses two G-Counters — one for increments, another one for decrements.
|
||||
|
||||
Usages:
|
||||
|
||||
- Amount of logged in users in a p2p network (Skype)
|
||||
|
||||
**_6.2.3 Non-negative counter:_**
|
||||
|
||||
Unfortunately, there is no simple implementation so far. Suggest your ideas in the comments to discuss.
|
||||
|
||||
## 7. CRDT: Register
|
||||
|
||||
A memory cell with two operations — assign() and value(). The issue is with the assign() operations — they do not commute. There are two approaches to solve this issue:
|
||||
|
||||
## **7.1 LWW-Register**
|
||||
|
||||
Introduce a total order by generating unique ids (timestamps) on each operation.
|
||||
|
||||
Example: state-based, updates via tuples (value, id):
|
||||
|
||||
Usages:
|
||||
|
||||
- Columns in cassandra
|
||||
- NFS — a whole file or a part of it
|
||||
|
||||
## **7.2 Multi-Value Register, MV-Register:**
|
||||
|
||||
The approach is similar to the G-Counter — store set (value, version vector) per each node. The value of the MV-Register is all values, merge() function applies LWW approach to all vector elements.
|
||||
|
||||
Usages:
|
||||
|
||||
- Amazon shopping basket. It has a well-known bug when an item re-appears in the basket after deletion. The reason is that MV-Register doesn’t behave like a set even though it stores a set of values (see below). Amazon indeed doesn’t treat that as a bug — it actually increases sales.
|
||||
- Riak. In the more general case we let the application to decide which values are the actual one (please note — we are not talking about conflicts!)
|
||||
|
||||
Amazon shopping basket bug:
|
||||
|
||||
## 8. CRDT: Set
|
||||
|
||||
A set has two non-commute operations — add() and rmv() and it is a base type for containers, maps, graphs, etc.
|
||||
|
||||
Let’s consider a naive set implementation where add() and rmv() are executed sequentially as they arrive: (First, we have concurrent add() on the 1st and the 2nd replicas, then rmv() arrives on the 1st replica)
|
||||
|
||||
Naive implementation
|
||||
|
||||
As you can see replicas diverged after synchronisation. Let’s consider possible correct set implementations:
|
||||
|
||||
## **8.1 Grow-Only Set, G-Set:**
|
||||
|
||||
A very simple solution — to disallow rmv() operation at all. add() operations commute, the merge() function is just a set union.
|
||||
|
||||
## **8.2 2P-Set:**
|
||||
|
||||
Allows rmv() operation but you can’t re-add an element after its deletion. An additional G-set can be used to track removed elements (also called tombstone set).
|
||||
|
||||
## **8.3 LWW-element Set**:
|
||||
|
||||
Idea is to introduce a total order on a set. For example, generating timestamps. We need to have two sets: add-set and remove-set.
|
||||
|
||||
add() adds (element, unique\_id()) to the add-set, rmv() adds to the remove-set. lookup() checks where the id is greater — in add-set or rmv-set.
|
||||
|
||||
## **8.4 PN-Set:**
|
||||
|
||||
One more way with ordering a set — add a counter per each element. Increase it on add() operation, decrease on rmv(). Element to be considered in the set if and only if his counter is positive.
|
||||
|
||||
Notice an interesting side-effect: the element didn’t appear after it has been added in the 3rd replica
|
||||
|
||||
## **8.5 Observe-Remove Set, OR-Set, Add-Win Set:**
|
||||
|
||||
add() has priority over rmv() In this data type. An example of possible implementation could be: add a unique tag (per element) to each newly added element. Then rmv() sends all seen tags of the element to other replicas. Replicas keep other tags.
|
||||
|
||||
## **8.6 Remove-win Set:**
|
||||
|
||||
Same as above but rmv() has priority over add()
|
||||
|
||||
## 9. CRDT: Graph
|
||||
|
||||
The graph type is based on the set type. Here we have the following problem: if there are two concurrent addEdge(u, v) and removeVertex(u) operations — what should we do? There are 3 possible strategies:
|
||||
|
||||
1. removeVertex() has priority, all incident edges are removed
|
||||
2. addEdge() has priority, all removed vertices are re-added
|
||||
3. Delay removeVertex() execution till all concurrent removeVertex() are executed.
|
||||
|
||||
The first one is the easiest to implement, for that we can just use two 2P-Sets. The resulted data type is called 2P2P-Graph
|
||||
|
||||
## 10\. CRDT: Map
|
||||
|
||||
## 10.1 Map of literals:
|
||||
|
||||
With maps we have two problems to solve:
|
||||
|
||||
- How to deal with concurrent put() operations? We can do by analogy with counters and use LWW or MV semantics
|
||||
- How to deal with concurrent put()/rmv() operations? We can do by analogy with sets and use put-wins or rmv-wins or last-put-wins semantics.
|
||||
|
||||
## 10.2 Map of CRDTs:
|
||||
|
||||
More interesting case as it allows nest other CRDT types. The important note here is that map data type does not deal with concurrent changes of its values — it must be done by the nested CRDT itself.
|
||||
|
||||
**_10.2.1 Remove-as-recursive-reset map:_**
|
||||
|
||||
In this data type rmv(k) operation “resets” the value of the CRDT object under given key k. For example, for a counter that would be zero value.
|
||||
|
||||
Consider the example — there is a shared shopping cart. One user adds more flour, the other one concurrently does a checkout (which causes deletion on all elements). After synchronisation we have one “unit” of the floor, which seems reasonable.
|
||||
|
||||
**_10.2.2 Remove-wins map:_**
|
||||
|
||||
In this case rmv() has priority over add()
|
||||
|
||||
Example: Player Alice has 10 coins and a hammer in an online game. Next two concurrent operations happen: on the replica A she has found a nail and on the replica B Alice has been removed (with deletion of all items)
|
||||
|
||||
**_10.2.3 Update-wins map:_**
|
||||
|
||||
add() has priority over rmv(), more precisely — add() cancels all previous concurrent rmv().
|
||||
|
||||
Consider the example: Player Alice in an online game is removed on the replica A because of the inactivity, at the same time she does some activity on the replica B. It is clear the rmv() operation must be cancelled.
|
||||
|
||||
Please note an interesting case: imagine we have two replicas A and B, and they store a set by the key k. If A removes the key k and B removes all elements from the set then, in the end, we’ll have an empty set under key k on both replicas.
|
||||
|
||||
One more important observation — we can’t just cancel all previous rmv() operations. Consider the following example — with such approach the synchronised state would be the same as initial, which is an incorrect result.
|
||||
|
||||
## 11\. CRDT: List
|
||||
|
||||
The problem with this type is that elements indices will be different on different replicas after local update operations. To address this issue the Operational Transformation approach is used — the original index must be considered when applying received update operations.
|
||||
|
||||
## 12\. Riak
|
||||
|
||||
As an example let’s consider what CRDT are used in Riak:
|
||||
|
||||
- Counter: PN-Counter
|
||||
- Set: OR-Set
|
||||
- Map: Update-wins Map of CRDTs
|
||||
- (Boolean) Flag: OR-Set with no more than 1 element
|
||||
- Register: tuples of (value, timestamp)
|
||||
|
||||
## 13\. Usages of CRDT
|
||||
|
||||
Wikipedia has good [examples](https://en.wikipedia.org/wiki/Conflict-free_replicated_data_type#Industry_use)
|
||||
|
||||
## 14\. References
|
||||
|
||||
- [Key-CRDT Stores](https://run.unl.pt/bitstream/10362/7802/1/Sousa_2012.pdf)
|
||||
- A [Conflict-Free Replicated JSON Datatype](https://arxiv.org/abs/1608.03960)
|
||||
- [A comprehensive study of Convergent and Commutative Replicated Data Types](https://hal.inria.fr/inria-00555588/document)
|
||||
- [Convergent and Commutative Replicated Data Type](https://core.ac.uk/download/pdf/55634119.pdf)
|
||||
- [Conflict-free replicated data type](https://en.wikipedia.org/wiki/Conflict-free_replicated_data_type)
|
||||
- [A Bluffers Guide to CRDTs in Riak](https://gist.github.com/russelldb/f92f44bdfb619e089a4d)
|
||||
- [CRDTs: An UPDATE (or just a PUT)](https://speakerdeck.com/lenary/crdts-an-update-or-just-a-put)
|
||||
- [Conflict-free Replicated Data Types: An Overview](https://arxiv.org/pdf/1806.10254.pdf)
|
||||
- [Strong Eventual Consistency and Conflict-free Replicated Data Types](https://www.youtube.com/watch?v=oyUHd894w18)
|
||||
- [Eventually-Consistent Data Structures](https://www.infoq.com/presentations/CRDT)
|
86
Media/articles/Cynefin-Framework.md
Normal file
86
Media/articles/Cynefin-Framework.md
Normal file
@ -0,0 +1,86 @@
|
||||
---
|
||||
author: The author of the Cynefin-Framework is Dave Snowden.
|
||||
link: https://de.wikipedia.org/wiki/Cynefin-Framework
|
||||
status: not-finished
|
||||
date: August 2, 2023
|
||||
---
|
||||
# Cynefin-Framework – Wikipedia
|
||||
#wissensmanagement #modell #kontexte #probleme #systeme
|
||||
[![](https://de.wikipedia.org//upload.wikimedia.org/wikipedia/commons/thumb/a/aa/Cynefin_framework%2C_September_2006.png/200px-Cynefin_framework%2C_September_2006.png)](https://de.wikipedia.org/wiki/Datei:Cynefin_framework,_September_2006.png)
|
||||
|
||||
Das **Cynefin-Framework** \[[kənɛvɪn](https://de.wikipedia.org/wiki/Liste_der_IPA-Zeichen)\][\[1\]](https://de.wikipedia.org/wiki/Cynefin-Framework#cite_note-1) ist ein [Wissensmanagement](https://de.wikipedia.org/wiki/Wissensmanagement)\-Modell mit der Aufgabe Probleme, Situationen und Systeme zu beschreiben. Das Modell liefert eine Typologie von Kontexten, die einen Anhaltspunkt bieten, welche Art von Erklärungen oder Lösungen zutreffen könnten.
|
||||
|
||||
Cynefin ist ein [walisisches](https://de.wikipedia.org/wiki/Walisische_Sprache) Wort, das üblicherweise im Deutschen mit Lebensraum oder Platz übersetzt wird, obwohl diese Übersetzung nicht seine volle Bedeutung vermitteln kann. Eine vollständige Übersetzung des Wortes würde aussagen, dass wir alle mehrere Vergangenheiten haben, derer wir nur teilweise bewusst sein können: kulturelle, religiöse, geographische, stammesgeschichtliche usw.
|
||||
|
||||
Der Begriff wurde von dem walisischen Gelehrten [Dave Snowden](https://de.wikipedia.org/w/index.php?title=David_J._Snowden&action=edit&redlink=1) gewählt, um die evolutionäre Natur komplexer Systeme zu veranschaulichen, einschließlich ihrer [inhärenten](https://de.wikipedia.org/wiki/Inh%C3%A4renz) Unsicherheit. Der Name ist eine Erinnerung daran, dass alle menschlichen Interaktionen stark von unseren Erfahrungen beeinflusst und häufig ganz davon bestimmt sind, sowohl durch den direkten Einfluss der persönlichen Erfahrung als auch durch kollektive Erfahrung wie Geschichten oder Musik.
|
||||
|
||||
Das Cynefin-Framework stützt sich auf Forschungen aus der Theorie komplexer adaptiver Systeme, [Kognitionswissenschaft](https://de.wikipedia.org/wiki/Kognitionswissenschaft), [Anthropologie](https://de.wikipedia.org/wiki/Anthropologie) und [narrativer Muster](https://de.wikipedia.org/wiki/Narrativ_(Sozialwissenschaften)) sowie der [evolutionären Psychologie](https://de.wikipedia.org/wiki/Evolution%C3%A4re_Psychologie). Es „untersucht die Beziehung zwischen Mensch, Erfahrung und Kontext“[\[2\]](https://de.wikipedia.org/wiki/Cynefin-Framework#cite_note-2) und schlägt neue Wege vor für Kommunikation, Entscheidungsfindung, Richtlinienfindung und Wissensmanagement in einem komplexen sozialen Umfeld.
|
||||
|
||||
## Herkunft\[[Bearbeiten](https://de.wikipedia.org/w/index.php?title=Cynefin-Framework&veaction=edit§ion=1) | [Quelltext bearbeiten](https://de.wikipedia.org/w/index.php?title=Cynefin-Framework&action=edit§ion=1)\]
|
||||
|
||||
Das Cynefin-Framework wurde im Jahr 1999 im Kontext von Wissensmanagement und Organisationsstrategie entwickelt von Mary E. Boone und [Dave Snowden](https://de.wikipedia.org/w/index.php?title=Dave_Snowden&action=edit&redlink=1).[\[3\]](https://de.wikipedia.org/wiki/Cynefin-Framework#cite_note-3) Es war ursprünglich eine Modifikation von [Max Boisots](https://de.wikipedia.org/w/index.php?title=Max_Boisot&action=edit&redlink=1) **I-Space**,[\[4\]](https://de.wikipedia.org/wiki/Cynefin-Framework#cite_note-4) kombiniert mit dem Studium der tatsächlichen (im Gegensatz zur verkündeten) Management-Praxis bei IBM. Bis 2002 hatte es sich so weit entwickelt, dass es die Theorie komplexer adaptiver Systeme beinhaltete, und hatte begonnen, ein allgemeines Strategie-Modell zu werden.
|
||||
|
||||
## Beschreibung\[[Bearbeiten](https://de.wikipedia.org/w/index.php?title=Cynefin-Framework&veaction=edit§ion=2) | [Quelltext bearbeiten](https://de.wikipedia.org/w/index.php?title=Cynefin-Framework&action=edit§ion=2)\]
|
||||
|
||||
Das Cynefin-Framework hat fünf Domänen.[\[5\]](https://de.wikipedia.org/wiki/Cynefin-Framework#cite_note-5) Die ersten vier davon sind:
|
||||
|
||||
- **Clear** (bisher "Simple" bzw. "Obvious") in der die Beziehung zwischen Ursache und Wirkung für alle offensichtlich ist. Die Herangehensweise ist hier _Sense - Categorise - Respond_, und wir können bewährte Praktiken (_[best practice](https://de.wikipedia.org/wiki/Best_practice)_) anwenden.
|
||||
- **Complicated**, in der die Beziehung zwischen Ursache und Wirkung eine Analyse, eine andere Form der Prüfung und/oder die Anwendung von Fachwissen erfordert. Hier geht man mittels _Sense - Analyze - Respond_ heran, und man kann gute Praktiken (_good practice_) anwenden.
|
||||
- **Complex**, in der die Beziehung zwischen Ursache und Wirkung nur im Nachhinein wahrgenommen werden kann, aber nicht im Voraus. Hier ist der Ansatz _Probe - Sense - Respond_, und wir können [emergente](https://de.wikipedia.org/wiki/Emergenz) Praktiken (_emergent practice_) feststellen.
|
||||
- **Chaotic**, in der es keine Beziehung zwischen Ursache und Wirkung auf Systemebene gibt (wohl aber in der System-Umwelt, jedoch nicht erfahrbar). Hier ist der Ansatz _Act - Sense - Respond_, und wir können _[innovative](https://de.wikipedia.org/wiki/Innovativ)_ Praktiken entdecken.
|
||||
|
||||
Die fünfte Domäne ist **Disorder**, der Zustand des Nicht-Wissens, welche Art von [Kausalität](https://de.wikipedia.org/wiki/Kausalit%C3%A4t) besteht. In diesem Zustand gehen die Leute in ihre eigene [Komfortzone](https://de.wikipedia.org/wiki/Komfortzone) zurück, wenn sie eine Entscheidung fällen. In vollem Umfang genutzt, hat Cynefin Sub-Domänen, und die Grenze zwischen „simple“ und „chaotic“ wird als katastrophale gesehen: [Selbstzufriedenheit](https://de.wikipedia.org/wiki/Selbstzufriedenheit) führt zum Scheitern.
|
||||
|
||||
## Anwendungen\[[Bearbeiten](https://de.wikipedia.org/w/index.php?title=Cynefin-Framework&veaction=edit§ion=3) | [Quelltext bearbeiten](https://de.wikipedia.org/w/index.php?title=Cynefin-Framework&action=edit§ion=3)\]
|
||||
|
||||
Die Arbeit von Snowden und seinem Team begann zunächst in den Bereichen [Wissensmanagement](https://de.wikipedia.org/wiki/Wissensmanagement), [kultureller Wandel](https://de.wikipedia.org/wiki/Kulturwandel) und [Gruppendynamik](https://de.wikipedia.org/wiki/Gruppendynamik). Sie befassten sich später auch mit einigen kritischen Unternehmensprozessen, wie z. B. Produktentwicklung, Markterschließung und [Branding](https://de.wikipedia.org/wiki/Branding). In jüngerer Zeit umfasste ihre Tätigkeit auch Fragen der [Unternehmensstrategie](https://de.wikipedia.org/wiki/Unternehmensstrategie) und der [nationalen Sicherheit](https://de.wikipedia.org/wiki/Nationale_Sicherheit).
|
||||
|
||||
Mit dem Cynefin-Framework wurden verschiedenste Themenbereiche analysiert, zum Beispiel der Einfluss der Religion auf die [Entscheidungsprozesse](https://de.wikipedia.org/wiki/Entscheidungsprozess) innerhalb der George-W.-Bush-Regierung,[\[6\]](https://de.wikipedia.org/wiki/Cynefin-Framework#cite_note-6) die Art der Reaktion auf Bioterrorismus sowie Untersuchungen zur Komplexität der Pflege im britischen National Health Service[\[7\]](https://de.wikipedia.org/wiki/Cynefin-Framework#cite_note-7). Das Framework wurde auch verwendet für die retrospektive Auswertung von Krisensituationen,[\[8\]](https://de.wikipedia.org/wiki/Cynefin-Framework#cite_note-8) das Management von Risiken der Nahrungskette,[\[9\]](https://de.wikipedia.org/wiki/Cynefin-Framework#cite_note-9) zum Studium der Interaktion zwischen Zivilisten und Militärs während des Katastrophenschutzes[\[10\]](https://de.wikipedia.org/wiki/Cynefin-Framework#cite_note-10) sowie zur Erkennung von Mustern in den Fragen von Bürgern an (soziale) Serviceorganisationen.[\[11\]](https://de.wikipedia.org/wiki/Cynefin-Framework#cite_note-11)
|
||||
|
||||
## Einfluss\[[Bearbeiten](https://de.wikipedia.org/w/index.php?title=Cynefin-Framework&veaction=edit§ion=4) | [Quelltext bearbeiten](https://de.wikipedia.org/w/index.php?title=Cynefin-Framework&action=edit§ion=4)\]
|
||||
|
||||
Das Cynefin-Framework und verwandte Open-Source-Methoden werden durch eine große und wachsende Gruppe von Praktikern weltweit umfangreich genutzt: die [BT Group](https://de.wikipedia.org/wiki/BT_Group), [IBM](https://de.wikipedia.org/wiki/IBM), [Oracle Corporation](https://de.wikipedia.org/wiki/Oracle_Corporation) und [Microsoft](https://de.wikipedia.org/wiki/Microsoft) sind die bekanntesten Beispiele.
|
||||
|
||||
Sein Einsatz im Rahmen der Führung wurde das Titelthema in der [Harvard Business Review](https://de.wikipedia.org/wiki/Harvard_Business_Review) im November 2007.[\[12\]](https://de.wikipedia.org/wiki/Cynefin-Framework#cite_note-12) Dieser Artikel wurde 2007 als das beste Praktiker-Papier im Bereich _Organizational Behavior_ von der _Organizational Behavior Division_ der _Academy of Management_ bezeichnet, mit folgendem Zitat: „Das Papier führt eine wichtige neue Perspektive ein, die großen zukünftigen Wert hat, und tut dies in einem klaren Ansatz, der zeigt, dass sie genutzt werden kann. (Der Artikel) macht mehrere bedeutende Beiträge. Zuerst und vor allem führt er die Komplexitätswissenschaft als Anleitung zum Denken und Handeln für Manager ein. Zweitens wendet er diese Perspektive an, um eine Typologie von Kontexten voranzubringen, um Führungspersonen zu helfen, die Vielfalt der Situationen, in denen sie Entscheidungen fällen müssen, zu sortieren. Drittens berät er Führungskräfte darin, welche Aktionen sie als Antwort einleiten sollten.“[\[13\]](https://de.wikipedia.org/wiki/Cynefin-Framework#cite_note-13)
|
||||
|
||||
## Siehe auch\[[Bearbeiten](https://de.wikipedia.org/w/index.php?title=Cynefin-Framework&veaction=edit§ion=5) | [Quelltext bearbeiten](https://de.wikipedia.org/w/index.php?title=Cynefin-Framework&action=edit§ion=5)\]
|
||||
|
||||
- [Sensemaking](https://de.wikipedia.org/wiki/Sensemaking)
|
||||
|
||||
## Einzelnachweise\[[Bearbeiten](https://de.wikipedia.org/w/index.php?title=Cynefin-Framework&veaction=edit§ion=6) | [Quelltext bearbeiten](https://de.wikipedia.org/w/index.php?title=Cynefin-Framework&action=edit§ion=6)\]
|
||||
|
||||
1. [↑](https://de.wikipedia.org/wiki/Cynefin-Framework#cite_ref-1) CognitiveEdge: [_The Cynefin Framework._](https://www.youtube.com/watch?v=N7oz366X0-8) 11. Juli 2010, abgerufen am 6. März 2019.
|
||||
2. [↑](https://de.wikipedia.org/wiki/Cynefin-Framework#cite_ref-2) Louisa-Jayne O’Neill. 2004. O’Neill, Louisa-Jayne. 2004. [Faith and decision-making in the Bush presidency: The God elephant in the middle of America’s livingroom](https://web.archive.org/web/20080509071551/http://emergence.org/ECO_site/ECO_Archive/Issue_6_1-2/ONeill.pdf) ([Memento](https://de.wikipedia.org/wiki/Web-Archivierung#Begrifflichkeiten) des [Originals](https://redirecter.toolforge.org/?url=http%3A%2F%2Femergence.org%2FECO_site%2FECO_Archive%2FIssue_6_1-2%2FONeill.pdf) vom 9. Mai 2008 im _[Internet Archive](https://de.wikipedia.org/wiki/Internet_Archive)_) **Info:** Der Archivlink wurde automatisch eingesetzt und noch nicht geprüft. Bitte prüfe Original- und Archivlink gemäß [Anleitung](https://de.wikipedia.org/wiki/Benutzer:InternetArchiveBot/Anleitung/Archivlink) und entferne dann diesen Hinweis.[@1](http://iabotmemento.invalid/http://emergence.org/ECO_site/ECO_Archive/Issue_6_1-2/ONeill.pdf)[@2](http://emergence.org/ECO_site/ECO_Archive/Issue_6_1-2/ONeill.pdf)[Vorlage:Webachiv/IABot/emergence.org](https://de.wikipedia.org/w/index.php?title=Vorlage:Webachiv/IABot/emergence.org&action=edit&redlink=1). Emergence: Complexity and Organisation. Vol. 6, No. 1/2, S. 149.
|
||||
3. [↑](https://de.wikipedia.org/wiki/Cynefin-Framework#cite_ref-3) D. Snowden. (2000) “Cynefin, A Sense of Time and Place: an Ecological Approach to Sense Making and Learning in Formal and Informal Communities” conference proceedings of KMAC at the University of Aston, July 2000 and D. Snowden. (2000) “Cynefin: a sense of time and space, the social ecology of knowledge management”. In Knowledge Horizons : The Present and the Promise of Knowledge Management ed. C Despres & D Chauvel Butterworth Heinemann October 2000
|
||||
4. [↑](https://de.wikipedia.org/wiki/Cynefin-Framework#cite_ref-4) Boisot Knowledge Assets 1998
|
||||
5. [↑](https://de.wikipedia.org/wiki/Cynefin-Framework#cite_ref-5) D. Snowden (2005) “Multi-ontology sense making – a new simplicity in [decision making](https://de.wikipedia.org/wiki/Entscheidungsprozess)” in Informatics in Primary Health Care 2005:13:00
|
||||
6. [↑](https://de.wikipedia.org/wiki/Cynefin-Framework#cite_ref-6) Louisa-Jayne O’Neill. 2004. O’Neill, Louisa-Jayne. 2004. [Faith and decision-making in the Bush presidency: The God elephant in the middle of America’s livingroom](https://emergentpublications.com/(S(qxgarqfj4flbd0we2pft2ili)X(1))/ECO/ECO_other/Issue_6_1-2_20_FM.pdf). Emergence: Complexity and Organisation. Vol. 6, No. 1/2, S. 149–156.
|
||||
7. [↑](https://de.wikipedia.org/wiki/Cynefin-Framework#cite_ref-7) Mark, Annabelle L.: Notes from a Small Island: Researching Organisational Behaviour in Healthcare from a UK Perspective. In: Journal of Organizational Behavior. Band 27, Nr. 7, 2006, S. 851–867, [doi](https://de.wikipedia.org/wiki/Digital_Object_Identifier):[10.1002/job.414](https://doi.org/10.1002/job.414), [JSTOR](https://de.wikipedia.org/wiki/JSTOR):[4093874](http://www.jstor.org/stable/4093874) (englisch).
|
||||
8. [↑](https://de.wikipedia.org/wiki/Cynefin-Framework#cite_ref-8) Simon French, Carmen Niculae: Believe in the Model: Mishandle the Emergency. In: Journal of Homeland Security and Emergency Management. Band 2, Nr. 1, 2005, [doi](https://de.wikipedia.org/wiki/Digital_Object_Identifier):[10.2202/1547-7355.1108](https://doi.org/10.2202/1547-7355.1108) (englisch). [_BELIEVE IN THE MODEL: MISHANDLE THE EMERGENCY._](http://idl.iscram.org/files/french/2004/111_French+Niculae2004.pdf) Abgerufen am 25. Juni 2022.
|
||||
9. [↑](https://de.wikipedia.org/wiki/Cynefin-Framework#cite_ref-9) Shepherd, Richard. Barker, Gary. French, Simon. Hart, Andy. Maule, John. Cassidy, Angela. 2006. Managing Food Chain Risks: Integrating Technical and Stakeholder Perspectives on Uncertainty. Journal of Agricultural Economics. Volume 57, Issue 2, S. 313–327.
|
||||
10. [↑](https://de.wikipedia.org/wiki/Cynefin-Framework#cite_ref-10) Otten, Jan. 2006. Civiel-militaire samenwerking bij crisisbeheersing, Carré, 29 (11-12), S. 32–34.
|
||||
11. [↑](https://de.wikipedia.org/wiki/Cynefin-Framework#cite_ref-11) Martha van Biene: _Beyond the standard question - narrative research into question-patterns._ Hogeschool Arnhem-Nijmegen, 2008, [ISBN 978-90-813751-1-5](https://de.wikipedia.org/wiki/Spezial:ISBN-Suche/9789081375115).
|
||||
12. [↑](https://de.wikipedia.org/wiki/Cynefin-Framework#cite_ref-12) David J. Snowden & Mary E. Boone: _A Leader’s Framework for Decision Making._ In: _[Harvard Business Review](https://de.wikipedia.org/wiki/Harvard_Business_Review)._ November 2007, S. 69–76 ([Online](https://hbr.org/2007/11/a-leaders-framework-for-decision-making))
|
||||
13. [↑](https://de.wikipedia.org/wiki/Cynefin-Framework#cite_ref-13) Organizational Behavior Division of the Academy of Management. 2008. [Outstanding Practitioner Oriented Publication in OB](http://www.obweb.org/index.php?option=com_content&view=article&id=56&Itemid=64)
|
||||
|
||||
## Literatur\[[Bearbeiten](https://de.wikipedia.org/w/index.php?title=Cynefin-Framework&veaction=edit§ion=7) | [Quelltext bearbeiten](https://de.wikipedia.org/w/index.php?title=Cynefin-Framework&action=edit§ion=7)\]
|
||||
|
||||
- Christopher Bellavita: [_Shape Patterns, Not Programs._](http://www.hsaj.org/?article=2.3.5) In: [_Homeland Security Affairs._](http://www.hsaj.org/) vol. II, no. 3, 2006, S. 1–21.
|
||||
- Joachim P. Sturmberg, Carmel M. Martin: _Knowing – in Medicine._ In: _Journal of Evaluation in Clinical Practice._ Volume 14 Issue 5, 2008, S. 767–770.
|
||||
- J. M. Firestone, M. W. McElroy: _Key Issues in the New Knowledge Management._ KMCI Press/Butterworth Heinemann, Burlington, MA 2003, S. 104–133.
|
||||
- S. French: [_Cynefin: repeatability, science and value._](http://www.inescc.pt/~ewgmcda/OpFrench.pdf) (PDF; 161 kB) European Working Group “Multiple Criteria Decision Aiding”. Series 3, nº 17, Spring 2008, S. 1–5.
|
||||
- Simon French, Carmen Niculae: [_Believe in the Model: Mishandle the Emergency._](https://www.degruyter.com/document/doi/10.2202/1547-7355.1108/html) In: _Journal of Homeland Security and Emergency Management._ volume 2, issue 1, (2005), auch [BELIEVE IN THE MODEL: MISHANDLE THE EMERGENCY](http://idl.iscram.org/files/french/2004/111_French+Niculae2004.pdf).
|
||||
- Lauri Koskela, Mike Kagioglou: [_On the Metaphysics of Production._](http://www.iglc.net/conferences/2005/papers/session01/05_059_Koskela_Kagioglou.pdf). Proceedings of the 13th Annual Conference on Lean Construction. 2006, S. 37–45.
|
||||
- C. Kurtz, D. Snowden: _The New Dynamics of Strategy: Sense-making in a Complex-Complicated World._ In: _IBM Systems Journal._ vol. 42, no. 3 2003, S. 462–83.
|
||||
- P. Lambe: _Organising Knowledge: Taxonomies, Knowledge and Organisational Effectiveness._ Chandos, Oxford 2007.
|
||||
- M. Lazaroff, D. Snowden: _Anticipatory modes for counter terrorism._ In: R. Popp, J. Yen (Hrsg.): _Emergent Information Technologies and Enabling Policies for Counter-Terrorism._ IEEE Press, Wiley, 2006.
|
||||
- A. Mark, D. Snowden: _Researching practice or practising research - innovating methods in healthcare the contribution of Cynefin._ Presented paper at the Organisational Behaviour in Health Care Conference on the theme of Innovation held by the Centre for Health and Policy Studies (CHAPS). University of Calgary at the Banff Centre Alberta Canada, 2004.
|
||||
- Louisa-Jayne O’Neill: [_Faith and decision-making in the Bush presidency: The God elephant in the middle of America’s livingroom._](https://emergentpublications.com/(S(qxgarqfj4flbd0we2pft2ili)X(1))/ECO/ECO_other/Issue_6_1-2_20_FM.pdf) (PDF; 423 kB) In: _Emergence: Complexity and Organisation._ Vol. 6, No. 1/2, 2004, S. 149–156.
|
||||
- Jan Otten: _Civiel-militaire samenwerking bij crisisbeheersing._ In: _Carré._ 29 (11-12), 2006, S. 32–34.
|
||||
- Richard Shepherd, Gary Barker, Simon French, Andy Hart, John Maule, Angela Cassidy: _Managing Food Chain Risks: Integrating Technical and Stakeholder Perspectives on Uncertainty._ In: _Journal of Agricultural Economics._ Volume 57, Issue 2, 2006, S. 313–327.
|
||||
- D. Snowden: _Cynefin: a sense of time and space, the social ecology of knowledge management._ In: C. Despres, D. Chauvel (Hrsg.): _Knowledge Horizons: The Present and the Promise of Knowledge Management._ Butterworth-Heinemann, Oxford 2000.
|
||||
- D. Snowden: [_Multi-ontology sense making – a new simplicity in decision making._](http://www.cognitive-edge.com/articledetails.php?articleid=40) In: _Informatics in Primary Health Care._ 2005.
|
||||
- D. Snowden: _Perspectives Around Emergent Connectivity, Sense-Making and Asymmetric Threat Management._ In: _Public Money & Management._ Volume 26 Issue 5, 2006, S. 275–277.
|
||||
- D. Snowden, M. Boone: [_A Leaders Framework for Decision Making._](http://www.mpiweb.org/CMS/uploadedFiles/Article%20for%20Marketing%20-%20Mary%20Boone.pdf) (PDF; 259 kB) In: _Harvard Business Review._ November 2007, S. 69–76.
|
||||
- J. Verdon: [_Transformation in the CF, Concept towards a theory of Human Network-Enabled._](http://pubs.drdc.gc.ca/PDFS/unc42/p524061.pdf) (PDF; 5,2 MB) National Defence, Directory of Strategic Human Resources, Research Note, Ottawa Juli 2005.
|
||||
- A.J. Woodhill: [_Shaping behaviour - How institutions evolve._](http://www.thebrokeronline.eu/en/articles/Shaping-behaviour) In: _The Broker._ Issue 10, Oktober 2008, S. 4–8.
|
25
Media/articles/Docker Basics.md
Normal file
25
Media/articles/Docker Basics.md
Normal file
@ -0,0 +1,25 @@
|
||||
---
|
||||
status: not-finished
|
||||
link: https://www.youtube.com/watch?v=lS1RLNqflUQ
|
||||
author: Coding Tech
|
||||
date: November 23, 2019
|
||||
---
|
||||
# Docker For Novices
|
||||
#docker #containers #deployment #cloud
|
||||
Docker is a popular technology but it is often confusing for the novice. This talk makes no assumptions about prior Docker knowledge and takes the student through the basic concepts and terminology. Along the way attendees will learn how to build images, run containers, map ports and create mounts. Finally Docker Compose is introduced.
|
||||
|
||||
EVENT:
|
||||
|
||||
linux.conf.au 2019 — Christchurch, New Zealand
|
||||
|
||||
SPEAKER:
|
||||
|
||||
Alec Clews
|
||||
|
||||
PUBLICATION PERMISSIONS:
|
||||
|
||||
Original video was published with the Creative Commons Attribution license (reuse allowed)
|
||||
|
||||
ATTRIBUTION CREDITS:
|
||||
|
||||
Original video source: https://www.youtube.com/watch?v=xsjSadjKXns
|
289
Media/articles/Efficient Editing With vim.md
Normal file
289
Media/articles/Efficient Editing With vim.md
Normal file
@ -0,0 +1,289 @@
|
||||
---
|
||||
author: Jonathan McPherson
|
||||
link: http://robertames.com/files/vim-editing.html
|
||||
status: not-finished
|
||||
date: August 1, 2023
|
||||
---
|
||||
# Efficient Editing With vim - Jonathan McPherson
|
||||
#tutorial #editing #productivity
|
||||
|
||||
> _This article has been translated into French by [Geoffrey Bachelet](http://fashion.hosmoz.net/blog/). You can read the French version here: [L<EFBFBD>dition efficace avec vim](http://fashion.hosmoz.net/blog/2004/05/08/150-ledition-efficace-avec-vim)._
|
||||
|
||||
_
|
||||
"To me, vi is Zen.
|
||||
To use vi is to practice zen.
|
||||
Every command is a koan.
|
||||
Profound to the user,
|
||||
unintelligible to the uninitiated.
|
||||
You discover truth every time you use it."
|
||||
_\--reddy@lion.austin.com
|
||||
|
||||
This tutorial assumes a basic knowledge of vim -- insert mode, command mode, loading and saving files, etc. It is intended to help vi novices develop their skills so that they can use vi efficiently.
|
||||
|
||||
In this tutorial, <C-X> means Ctrl-X -- that is, hold down the Ctrl key and press X. You can get help on most of the commands used here by typing :help _command_ in vim, where _command_ is what you need help on.
|
||||
|
||||
## Moving efficiently
|
||||
|
||||
### Stay out of insert mode
|
||||
|
||||
In general, you want to spend as little of your time in vims insert mode as possible, because in that mode it acts like a dumb editor. This is why most vim novices spend so much time in insert mode -- it makes vim easy to use. But vims real power lies in command mode! Youll find that the better you know vim, the less time you will spend in insert mode.
|
||||
|
||||
### Use h, j, k, and l
|
||||
|
||||
The first step to efficient editing in vim is to wean yourself from the arrow keys. One of the the advantages of vims modal design is that you do not need to constantly move your hands back and forth between the arrow keys and the letter keys; when you are in command mode, the letters h, j, k and l correspond to the directions _left, down, up,_ and _right_, respectively. It takes some practice to get used to, but you _will_ notice the speed difference once youre used to it.
|
||||
|
||||
When you are editing e-mail or other paragraph-formatted text, you might notice that the direction keys skip more lines than you expect. This is because your paragraphs appear as one long line to vim. Type g before h, j, k or l to move by screen lines instead of virtual lines.
|
||||
|
||||
### Use motions to move the cursor in the current line
|
||||
|
||||
Most editors have only simple commands for moving the cursor (left, up, right, down, to beginning/end of line, etc). vim has very advanced commands for moving the cursor; these commands are referred to as _motions_. When the cursor moves from one point in the text to another, the text between the points (and including the points themselves) is considered to be "_moved over_." (This will be important later.)
|
||||
|
||||
Here are a few of the more useful motions:
|
||||
|
||||
|
||||
**fx**
|
||||
Move the cursor **f**orward to the next occurance of the character x on the current line (obviously, x can be any character you like). This is an extremely useful command. You can type ; to repeat the last f command you gave.
|
||||
|
||||
**tx**
|
||||
Same as above, but moves the cursor to right before the character, not all the way to it. (Its very useful, really.)
|
||||
|
||||
**Fx**
|
||||
Move the cursor _backward_ to the next occurance of the character x on the current line.
|
||||
|
||||
**w**
|
||||
Move the cursor forward by a word.
|
||||
|
||||
**b**
|
||||
Move the cursor backward by a word.
|
||||
|
||||
**0**
|
||||
Move the cursor to the beginning of the current line.
|
||||
|
||||
**^**
|
||||
Move the cursor to the first character on the current line.
|
||||
|
||||
**$**
|
||||
Move the cursor to the end of the line
|
||||
|
||||
**)**
|
||||
Move the cursor forward to the next sentence. (Useful when editing e-mail or text documents.)
|
||||
|
||||
**(**
|
||||
Move the cursor backward by a sentence.
|
||||
|
||||
### Move efficiently through the file
|
||||
|
||||
vim has many commands that can send you to where you want to go in your file -- theres rarely a need to scroll manually through it. The below keystrokes are not technically _motions_, since they move around in the file instead of in a particular line.
|
||||
|
||||
**<C-F>**
|
||||
Move the cursor **f**orward by a screenful of text
|
||||
|
||||
**<C-B>**
|
||||
Move the cursor **b**ackward by a screenful of text
|
||||
|
||||
**G**
|
||||
Move the cursor to the end of the file
|
||||
|
||||
**_num_G**
|
||||
Move the cursor line _num_. (For instance, 10G moves to line 10.)
|
||||
|
||||
**gg**
|
||||
Move the cursor to the beginning of the file
|
||||
|
||||
**H**
|
||||
Move the cursor to the top of the screen.
|
||||
|
||||
**M**
|
||||
Move the cursor to the middle of the screen.
|
||||
|
||||
**L**
|
||||
Move the cursor to the bottom of the screen.
|
||||
|
||||
\*
|
||||
|
||||
Read the string under the cursor and go to the next place it appears. (For instance, if your cursor was somewhere on the word "bob," the cursor would move to the next occurance of "bob" in your file.)
|
||||
|
||||
#
|
||||
|
||||
Same as above, except it moves the cursor to the _previous_ occurance.
|
||||
|
||||
**/_text_**
|
||||
Starting from the cursor, find the next occurance of the string _text_ and go to it. You will need to press Enter to execute the search. To re-execute your last search, type n (for **n**ext occurance).
|
||||
|
||||
**?_text_**
|
||||
Same as /, but searches in the opposite direction.
|
||||
|
||||
**ma**
|
||||
Make a bookmark named a at the current cursor position. A bookmark can be named any lowercase letter. You cant see the bookmark, but its there!
|
||||
|
||||
**\`a**
|
||||
Go to bookmark a. Important: thats a _backtick_, not a single quote. The backtick is located to the left of the 1 on most keyboards.
|
||||
|
||||
**\`.**
|
||||
Go to the line that you last edited. This is very useful! If you need to scroll through the file to look something up, you can go back to where you were without bookmarking it by using the \`. command.
|
||||
|
||||
**## Typing efficiently**
|
||||
### Use keyword completion
|
||||
|
||||
vim has a very nice keyword completion system. This means that you can type part of a long word, press a key, and have vim finish the word for you. For instance, if you have a variable called iAmALongAndAwkwardVarName somewhere in your code, you probably dont want to type the whole thing in every time you use it.
|
||||
|
||||
To use keyword completion, just type the first few letters of the string (e.g. iAmAL) and press <C-N> (that means hold down Ctrl and type N) or <C-P>. If vim doesnt give you the word you want at first, keep trying -- vim will cycle through all completions it can find.
|
||||
|
||||
### Enter insert mode intelligently
|
||||
|
||||
Most users new to vim get into insert mode by typing i. This works, but its often pretty inefficient, since vi has a host of commands that leave the editor in insert mode. Here are some of the more popular ones:
|
||||
|
||||
**i**
|
||||
Insert text to the left of the current character.
|
||||
|
||||
**I**
|
||||
Insert text at the beginning of the current line.
|
||||
|
||||
**a**
|
||||
Insert text to the right of the current character.
|
||||
|
||||
**A**
|
||||
Insert text at the end of the current line.
|
||||
|
||||
**o**
|
||||
Create a new line under the current one and insert text there.
|
||||
|
||||
**O**
|
||||
Create a new line above the current one and insert text there.
|
||||
|
||||
**c_{motion}_**
|
||||
Delete (**c**hange) the text moved over by _{motion}_ and insert text to replace it. For instance, c$ would delete the text from the cursor to the end of the line and enter insert mode. ct! would delete the text from the cursor up to (but not including) the next exclamation mark and enter insert mode. The deleted text is copied to the clipboard and can be pasted.
|
||||
|
||||
**d_{motion}_**
|
||||
Delete the text moved over by _{motion}_ -- same as c_{motion}_, but doesnt enter insert mode.
|
||||
|
||||
## Moving blocks of text efficiently
|
||||
|
||||
### Use visual selections and the appropriate selection mode
|
||||
|
||||
Unlike the original vi, vim allows you to highlight text and perform operations on it. There are three main visual selection modes (that is, text highlighting modes). These modes are as follows:
|
||||
|
||||
**v**
|
||||
Characterwise selection mode. This is the selection mode that most people are used to, so practice with it before trying the others.
|
||||
|
||||
**V**
|
||||
Linewise selection mode. Whole lines are always selected. This is better than characterwise mode when you want to copy or move a group of lines.
|
||||
|
||||
**<C-V>**
|
||||
Blockwise selection mode. _Extremely_ powerful and available in very few other editors. You can select a rectangular block and any text inside that block will be highlighted.
|
||||
|
||||
All the usual cusor movement keys apply -- so, for instance, vwww would go into visual selection mode and highlight the next three words. Vjj would go into linewise visual selection mode and highlight the current line and the two lines below it.
|
||||
|
||||
### Cutting and copying from visual selections
|
||||
|
||||
Once you have a highlighted selection, you probably want to do something with it. Some of the more useful commands you can give when an area of text is highlighted:
|
||||
|
||||
**d**
|
||||
Cut (**d**elete) the highlighted text and put it into the clipboard.
|
||||
|
||||
**y**
|
||||
Copy (or **y**ank, which is vim-ese for "copy") the highlighted text into the clipboard.
|
||||
|
||||
**c**
|
||||
Cut the highlighted text into the clipboard. This is just like d, except it leaves the editor in insert mode.
|
||||
|
||||
**### Cutting and copying from non-visual selections**
|
||||
If you know exactly what you want to copy or cut, you can do it without entering visual mode. This saves time.
|
||||
|
||||
**d_{motion}_**
|
||||
Cut the text moved over by _{motion}_ to the clipboard. For instance, dw would cut a word and dfS would cut from the cursor up to and including the next capital S on the current line of text.
|
||||
|
||||
**y_{motion}_**
|
||||
Copy the text moved over by _{motion}_.
|
||||
|
||||
**c_{motion}_**
|
||||
Cut the text moved over by _{motion}_ and leave the editor in insert mode.
|
||||
|
||||
**dd**
|
||||
Cut the current line.
|
||||
|
||||
**yy**
|
||||
Copy the current line.
|
||||
|
||||
**cc**
|
||||
Cut the current line and leave the editor in insert mode.
|
||||
|
||||
**D**
|
||||
Cut from the cursor to the end of the current line.
|
||||
|
||||
**Y**
|
||||
Yank the whole line, just like yy. (Yes, its inconsistent! You can use y$ to do what you would expect Y to do.)
|
||||
|
||||
**C**
|
||||
Cut from the cursor to the end of the current line and leave the editor in insert mode.
|
||||
|
||||
**x**
|
||||
Cut the current character. (This is sort of like a command-mode backspace.)
|
||||
|
||||
**s**
|
||||
Cut the current character and leave the editor in insert mode.
|
||||
|
||||
### Pasting
|
||||
|
||||
Pasting is easy. Put the cursor where you want the pasted text and type p.
|
||||
|
||||
### Using multiple clipboards
|
||||
|
||||
Most editors have a single clipboard. vim has many more; clipboards in vim are called _registers_. You can list all the currently defined registers and their contents by typing :reg. Typically, youll be using the lowercase letter registers; the others are used for various internal vim purposes and are only occasionally helpful.
|
||||
|
||||
To use a specific register for a copy or paste operation, simply type "a before the command for the operation, where a is the register you want to use.
|
||||
|
||||
For example, to copy the current line into register k, you could type "kyy. (You could also type V"ky. Why would that work?). That line would stay in register k until you specifically copied something else into register k. You would then use "kp to paste the text from register k.
|
||||
|
||||
## Avoiding repetition
|
||||
|
||||
### The amazing . command
|
||||
|
||||
In vi, typing . (a period) will repeat the last command you gave. For instance, if your last command was dw (delete word), vi will delete another word.
|
||||
|
||||
### Using counts
|
||||
|
||||
Counts are one of the most powerful and time-saving features of vim. _Any_ command can be preceded by a number. The number will tell vim how many times to execute the command. Here are a few examples:
|
||||
|
||||
3j will move the cursor down three lines.
|
||||
|
||||
10dd will delete ten lines.
|
||||
|
||||
y3"e; will yank (copy) text from the cursor to the third quotation mark after the cursor on the current line. Counts are useful to extend the range of a motion in this manner.
|
||||
|
||||
### Recording macros
|
||||
|
||||
Occasionally, youll find yourself doing the same thing over and over to blocks of text in your document. vim will let you record an ad-hoc macro to perform the operation.
|
||||
|
||||
**q_register_**
|
||||
Start macro recording into the named register. For instance, qa starts recording and puts the macro into register a.
|
||||
|
||||
**q**
|
||||
End recording.
|
||||
|
||||
**@_register_**
|
||||
Replay the macro stored in the named register. For instance, @a replays the macro in register a.
|
||||
|
||||
Keep in mind that macros just record your keystrokes and play them back; they are not magic. Recording macros is almost an art form because there are so many commands that accomplish a given task in vim, and you must carefully select the commands you use while your macro is recording so that they will work in all the places you plan to execute the macro.
|
||||
|
||||
## Writing code in vim
|
||||
|
||||
vim is an excellent editor for source code because it has many features that are specifically designed to help programmers. Here are a few of the more handy ones:
|
||||
|
||||
**\]p**
|
||||
Just like p, but it automatically adjusts the indent level of the pasted code to match that of the code you paste into. Try it!
|
||||
|
||||
**%**
|
||||
Putting the cursor on a brace, bracket, or parenthese and pressing % will send the cursor to the matching brace, bracket, or parenthese. Great for fixing parse problems related to heavily nested blocks of code or logic.
|
||||
|
||||
**\>>**
|
||||
Indent the highlighted code. (See the earlier section about efficient text selection. If no text is selected, the current line is indented.)
|
||||
|
||||
**<<**
|
||||
Like >>, but un-indents.
|
||||
|
||||
**gd**
|
||||
**G**o to the **d**efinition (or **d**eclaration) of the function or variable under the cursor.
|
||||
|
||||
**K**
|
||||
Go to the man page for the word currently under the cursor. (For instance, if your cursor is currently over the word sleep, you will see the man page for sleep displayed.)
|
@ -1,5 +0,0 @@
|
||||
# Error propagation patterns
|
||||
|
||||
Link: https://www.fourzerofour.pw/posts/error-propagation/
|
||||
Status: Finished
|
||||
Type: Article
|
147
Media/articles/Everyone Is Beautiful.md
Normal file
147
Media/articles/Everyone Is Beautiful.md
Normal file
@ -0,0 +1,147 @@
|
||||
---
|
||||
author: Blood Knife
|
||||
link: https://bloodknife.com/everyone-beautiful-no-one-horny/
|
||||
status: not-finished
|
||||
date: August 4, 2023
|
||||
image: >-
|
||||
https://i0.wp.com/bloodknife.com/wp-content/uploads/2023/07/Stormtroopers.webp?fit=1555%2C816&ssl=1
|
||||
---
|
||||
# Everyone Is Beautiful and No One Is Horny - Blood Knife
|
||||
#film-critique #sociology #body-image #pop-culture
|
||||
### Everyone Is Beautiful and No One Is Horny
|
||||
|
||||
#### **Modern action and superhero films fetishize the body, even as they desexualize it.**
|
||||
|
||||
**by RS Benedict**
|
||||
|
||||
When Paul Verhoeven adapted _Starship Troopers_ in the late 1990s, did he know he was predicting the future? The endless desert war, the ubiquity of military propaganda, a cheerful face shouting victory as more and more bodies pile up?
|
||||
|
||||
But the scene that left perhaps the greatest impact on the minds of Nineties kids—and the scene that anticipated our current cinematic age the best—does not feature bugs or guns. It is, of course, the shower scene, in which our heroic servicemen and -women enjoy a communal grooming ritual.
|
||||
|
||||
On the surface, it is idyllic: racial harmony, gender equality, unity behind a common goal—and firm, perky asses and tits.
|
||||
|
||||
And then the characters speak. The topic of conversation? Military service, of course. One joined for the sake of her political career. Another joined in the hopes of receiving her breeding license. Another talks about how badly he wants to kill the enemy. No one looks at each other. No one flirts.
|
||||
|
||||
A room full of beautiful, bare bodies, and everyone is only horny for war.
|
||||
|
||||
\* \* \* \* \*
|
||||
|
||||
In the early 2000s, there was a brief period where actresses pretended that their thinness was natural, almost accidental. Skinny celebrities confessed their love of burgers and fries in magazines; models undergoing profile interviews engaged in public consumption of pasta; leading ladies joked about how little they exercised and how much they hated it. It was all bullshit: no one looks like that without calorie restriction. We knew it then, and we know it now.
|
||||
|
||||
We don’t pretend anymore. The promotional cycles for blockbuster movies now include detailed descriptions of the performers’ fitness regimens. We watch actors doing burpees or shaking ropes with expensive personal trainers. There is some talk of diets, though not terribly detailed—and no mention of steroids or other hormonal supplements, even though male actors’ suddenly ultra-swole selfies on Instagram suggest physiques crafted with chemical assistance.
|
||||
|
||||
Actors are more physically perfect than ever: impossibly lean, shockingly muscular, with magnificently coiffed hair, high cheekbones, impeccable surgical enhancements, and flawless skin, all displayed in form-fitting superhero costumes with the obligatory shirtless scene thrown in to show off shredded abs and rippling pecs.
|
||||
|
||||
> **Even background extras are good-looking, or at least inoffensively bland. No one is ugly. No one is really fat. Everyone is beautiful.**
|
||||
|
||||
And this isn’t just the lead and the love interest: supporting characters look this way too, and even villains (frequently clad in monstrous makeup) are still played by conventionally attractive performers. Even background extras are good-looking, or at least inoffensively bland. No one is ugly. No one is really fat. Everyone is beautiful.
|
||||
|
||||
And yet, [**no one is horny**](https://www.cheatsheet.com/entertainment/marvel-movies-this-esteemed-director-says-theyre-not-sexy-enough.html/). Even when they have sex, no one is horny. No one is attracted to anyone else. No one is hungry for anyone else.
|
||||
|
||||
When revisiting a beloved Eighties or Nineties film, Millennial and Gen X viewers are often startled to encounter long-forgotten sexual content content: John Connor’s conception in _Terminator_, Jamie Lee Curtis’s toplessness in _Trading Places_, the spectral blowjob in _Ghostbusters_. These scenes didn’t shock us when we first saw them. Of _course_ there’s sex in a movie. Isn’t there always?
|
||||
|
||||
The answer, of course, is not anymore—at least not when it comes to modern blockbusters
|
||||
|
||||
![](https://i0.wp.com/bloodknife.com/wp-content/uploads/2021/02/qicstnq7qznw0tipo9fa.jpg?resize=511%2C319&ssl=1)
|
||||
|
||||
We’re told that Tony Stark and Pepper Potts are an item, but no actual romantic or sexual chemistry between them is shown in the films. Wonder Woman and Steve Trevor utterly lack the sexual chemistry to convince us that either of them would be thirsty enough to commandeer a coma victim’s body (as they do in _Wonder Woman 1984_) so they can enjoy a posthumous hookup. In defiance of Norse mythology, Chris Hemsworth’s Thor smiles at Natalie Portman like a dumb golden retriever puppy without ever venturing to rend her asunder with his mighty hammer, so to speak. Not that the competition is any better. Despite accusations of being an incel icon, it is Heath Ledger’s Joker, not Christian Bale’s chaste and sexless Batman, who exudes the most sexual energy in the Dark Knight trilogy.
|
||||
|
||||
And speaking of Christopher Nolan’s inexplicably sexless oeuvre—did anyone else think it odd how _Inception_ enters the deepest level of a rich man’s subconscious and finds _not_ a psychosexual Oedipal nightmare of staggering depravity, but… a ski patrol?
|
||||
|
||||
\* \* \* \* \*
|
||||
|
||||
Let’s not pretend that Old Hollywood was a progressive haven of body positivity. Since the departure of voluptuous vamp Theda Bara from the silver screen, actors have always gone to extremes to maintain a certain look. Rita Hayworth underwent an ethnic makeover to appear more Caucasian so she could get leading roles. Stars of the 1920s limited their fluid consumption to two glasses a day to avoid water weight. Jane Fonda suffered from severe bulimia at the height of her sex symbol status; so did Marlon Brando.
|
||||
|
||||
> **Snake Plissken didn’t fuck on screen, but the character radiates overwhelming sex-haver energy.**
|
||||
|
||||
But old films still featured recognizable human bodies and human faces—bodies that could theoretically be achieved by a single person without the aid of a team of personal trainers, dieticians, private chefs, and chemists.
|
||||
|
||||
![](https://i0.wp.com/bloodknife.com/wp-content/uploads/2021/02/actors-featured-2.jpg?resize=503%2C252&ssl=1)
|
||||
|
||||
In the films of the Eighties and Nineties, leading actors were good looking, yes, but still human. Kurt Russel’s Snake Plissken was a hunk, but in shirtless scenes his abs have no definition. Bruce Willis was handsome, but he’s more muscular now than he was in the Nineties, when he was routinely branded a bona fide sex symbol. And when Isabella Rosselini strips in _Blue Velvet_, her skin is pale and her body is soft. She looks vulnerable and real.
|
||||
|
||||
And yet, these characters fucked. _Blue Velvet’s_ Dorothy Vallens and Jeffrey Beaumant fucked. Michael Keaton’s Batman and Michelle Pfeiffer’s domme Catwoman fucked. Kyle Reese and Sarah Connor fucked. Snake Plissken didn’t fuck on screen, but the character radiates overwhelming sex-haver energy. And I defy you to find a mainstream film with a moment as horny and gay as the [**Sexy Saxophone Solo**](https://io9.gizmodo.com/the-true-story-of-the-lost-boys-sax-man-1842774832) from _The Lost Boys_.
|
||||
|
||||
\* \* \* \* \*
|
||||
|
||||
Seen today, one of the most striking scenes in 1982’s Poltergeist is not the evil clown doll or the monster tree, but a moment of relaxed affection between the parents. The father—a bald, beer-bellied Craig T. Nelson—cracks jokes and prances for his wife, who wears a frumpy nightgown and smokes a joint and yammers weed thoughts and laughs at her husband’s silly display. Finally, the husband playfully dives onto the bed. Neither character is glamorous in this scene, but their relationship feels frisky and lived-in and charismatic and _real_.
|
||||
|
||||
The house looks real, too. There are toys and magazines scattered around the floor. There are cardboard boxes waiting to be unpacked since the recent move. Framed pictures rest against the wall; the parents haven’t gotten around to mounting them yet. The kitchen counters are cluttered and mealtimes are rambunctious and sloppy, as one expects in a house with three children. They’re building a pool in the backyard, but not for appearances: it’s a place for the kids to swim, for the parents to throw parties, and for the father to reacquaint himself with his love of diving.
|
||||
|
||||
At the time, this house represented an aspirational ideal of American affluence.
|
||||
|
||||
Compare this to homes in films now: massive, sterile cavernous spaces with minimalist furniture. Kitchens are industrial-sized and spotless, and they contain no food. There is no excess. There is no mess.
|
||||
|
||||
> **A body is no longer a holistic system. It is not the vehicle through which we experience joy and pleasure. It is not a home to live in and be happy.**
|
||||
|
||||
In her blog McMansion Hell, Kate Wagner examines precisely why these widely-hated 5000-square foot housing bubble behemoths are so awful. Over and over again, she reiterates the point that McMansions are not built to be homes; they’re built to be short-term investments.
|
||||
|
||||
[**Kate writes**](https://mcmansionhell.com/post/150597521816/mcmansions-101-revisited-aesthetics-aside-why), “The inside of McMansions are designed in order to cram the most ‘features’ inside for the lowest costs.” These features exist to increase the house’s resale value, not to make it a good place to live. No thought is given to the labor needed to clean and maintain these spaces. The master bathroom includes intricate stone surfaces that can only be scrubbed with a toothbrush; the cathedral ceilings in the living room raise the heating and cooling costs to an exorbitant sum; the chandelier in the grand entryway dangles so high that no one can replace the bulbs in it, even with a stepladder.
|
||||
|
||||
The same fate has befallen our bodies. A body is no longer a holistic system. It is not the vehicle through which we experience joy and pleasure during our brief time in the land of the living. It is not a home to live in and be happy. It, too, is a collection of features: six pack, thigh gap, cum gutters. And these features exist not to make our lives more comfortable, but to increase the value of our assets. Our bodies are investments, which must always be optimized to bring us… what, exactly? Some vague sense of better living? Is a life without bread objectively better than a life with it? When we were children, did we dream of counting every calorie and logging every step?
|
||||
|
||||
A generation or two ago, it was normal for adults to engage in sports not purely as self-improvement but as an act of leisure. People danced for fun; couples socialized over tennis; kids played stickball for lack of anything else to do. Solitary exercise at the gym also had a social, rather than moral, purpose. People worked out to look hot so they could attract other hot people and fuck them. Whatever the ethos behind it, the ultimate goal was pleasure.
|
||||
|
||||
![](https://i0.wp.com/bloodknife.com/wp-content/uploads/2021/02/ConanBarbarian-1280x720-1.jpg?resize=520%2C293&ssl=1)
|
||||
|
||||
Not so today. Now, we are perfect islands of emotional self-reliance, and it is seen as embarrassing and co-dependent to want to be touched. We are doing this for ourselves, because we, apropos of nothing, desperately want to achieve a physical standard set by some invisible Other in an insurance office somewhere.
|
||||
|
||||
Contemporary gym ads focus on rigidly isolated self-improvement: be your best self. Create a new you. We don’t exercise, we don’t work out: we _train_, and we train in fitness programs with names like _Booty Bootcamp_, as if we’re getting our booties battle-ready to fight in the Great Booty War. There is no promise of intimacy. Like our heroes in the Marvel Cinematic Universe, like Rico and Dizzy and all the other infantry in _Starship Troopers_, we are horny only for annihilation.
|
||||
|
||||
A lesser-discussed side effect of extreme calorie restriction is the loss of libido. Bodybuilders experience this as they go on crash diets to quickly cut fat so that their muscles will show during competitions; though they look like physically perfect specimens of manhood, they don’t dream of women, but of cheeseburgers and fries. Many eating disorder patients lose their sex drive completely and even stop menstruating.
|
||||
|
||||
When a body receives fewer calories, it must prioritize essential life support systems over any function not strictly necessary for the body’s immediate survival. Sexual desire falls into the latter category, as does high-level abstract thought. A body that restricts food and increases exercise believes it is undergoing a famine, which is not an ideal time to reproduce.
|
||||
|
||||
Is there anything more cruelly Puritanical than enshrining a sexual ideal that leaves a person unable to enjoy sex?
|
||||
|
||||
\* \* \* \* \*
|
||||
|
||||
When a nation feels threatened, it gets swole. Germans and Norwegians became [**obsessed with individual self-improvement through physical fitness**](https://www.movementhealth.com.au/news/physical-culture-movement/) around the end of the Napoleonic Era. British citizens took up this Physical Culture as the 19th century—and their empire—began to wane. And yoga, in its current practice as a form of meditative strength training, [**came out of the Indian Independence movement**](https://www.bbc.co.uk/blogs/adamcurtis/entries/2989a78a-ee94-385e-808f-c9c7c38d1cb7) of the 1920s and 30s.
|
||||
|
||||
The impetus of these movements isn’t fitness for the sake of pleasure, for the pure joys of strength and physical beauty. It’s competitive. It’s about getting strong enough to fight The Enemy, whoever that may be.
|
||||
|
||||
> **The impetus of these movements isn’t fitness for the sake of pleasure, for the pure joys of strength and physical beauty. It’s competitive.**
|
||||
|
||||
The United States is, of course, not immune to this. The Presidential Fitness Test sprang up in the mid-20th century after studies found that American children lagged behind Europeans in certain tests of flexibility and calisthenic ability. Cold War paranoia only amped up this anxiety, [**particularly as we entered the 1980s**](https://podcasts.apple.com/us/podcast/bonus-the-presidents-physical-fitness-test/id1380008439?i=1000495675212). What if our kids were too fat to defeat communism? This obsession meshed beautifully with boomer yuppie narcissism and birthed the aerobics fad.
|
||||
|
||||
Then the Nineties hit, the Berlin Wall fell, and spandex and sweatbands became hilariously passe. While America still obsessed over thinness, it was not for the sake of strength. Two things happened at the dawn of the new millennium to bring back physical culture.
|
||||
|
||||
The first occurred in 1998, [**when BMI standards shifted a few points**](https://www.washingtonpost.com/wp-srv/style/guideposts/fitness/optimal.htm). Formerly, one needed a BMI of 27 (for women) or 28 (for men) to be classified as overweight, but the new standard lowered the cutoff to 25 points. Twenty-nine million Americans instantly became overweight without gaining an ounce. Under the new guidelines, doctors could prescribe them diet drugs or recommend weight loss surgery.
|
||||
|
||||
A nationwide panic rose; headlines screamed about a new plague of fat people whose bodies were ticking time bombs destined to deliver death and destruction at any moment. Stock footage of fat people ambling about in public, filmed from the neck down to protect their identities (and more effectively dehumanize them), became a common sight on television news as bony broadcasters droned about the horrors of the Obesity Epidemic. Curiously, hardly any of the reports on this sudden increase in overweight/obese Americans bothered to mention the BMI standard shift.
|
||||
|
||||
The second event was, of course, 9/11.
|
||||
|
||||
The attack on the World Trade Center and the Pentagon sparked a new War on Terror, and America needed to get in shape so we could _win that war_. The USA’s hyper-militaristic troop-worshipping post-9/11 culture seeped into the panic over obesity and gave birth to a terrifying, swole baby. Public school gym classes featured special military fitness days in which students practiced throwing mock grenades. George W. Bush added an Adult Fitness Challenge to the [**Presidential Fitness program**](https://www.wellandgood.com/10-things-you-never-knew-about-the-presidents-physical-fitness-challenge/#:~:text=In%201966%2C%20the%20Presidential%20Physical,600%2Dyard%20walk%2Frun). On American and British television, a new wave of documentaries and reality shows sprang up to bellow at us for being too fat to defeat al Qaeda: _Honey, We’re Killing the Kids_; _Supersize Me_; _You Are What You Eat_, in which a bony harridan screeched at Britons whose feces did not meet her exacting standards; _The Biggest Loser_, where lean coaches bellowed at fat contestants in a manner strikingly similar to that of a stereotypical drill instructor.
|
||||
|
||||
> **The new muscle era lacks the eroticism of Eighties action cinema.**
|
||||
|
||||
And muscles—giant, pulsating, steroid-enhanced muscles—returned to screens. But the new muscle era lacks the eroticism of Eighties action cinema. Arnold Schwarzenegger showed his glutes in _Terminator_; Sylvester Stallone stripped for _First Blood_ and _Tango & Cash_; _Bloodsport_ shows more of Jean Claude Van Damme’s body than that of his love interest.
|
||||
|
||||
For the most part, though, today’s cinema hunks are nevernudes. The Marvel Cinematic Universe is strictly PG-13, as one expects from a Disney product. And even in the DC universe, there’s very little of human sexuality. Capefans’ demands for more “mature” superhero movies always mean more graphic violence, _not_ more sex. They panicked over Dr. Manhattan’s glowing blue penis in _Watchmen_, and they still haven’t forgiven Joel Schumacher for putting nipples on the batsuit.
|
||||
|
||||
Today’s stars are action figures, not action heroes. Those perfect bodies exist only for the purpose of inflicting violence upon others. To have fun is to become weak, to let your team down, and to give the enemy a chance to win, like Thor did when he got fat in _Endgame_.
|
||||
|
||||
This cinematic trend reflects the culture around it. Even before the pandemic hit, Millennials and Zoomers were less sexually active than the generation before them. Maybe we’re too anxious about the Apocalypse; maybe we’re too broke to go out; maybe having to live with roommates or our parents makes it a little awkward to bring a partner home; maybe there are chemicals in the environment screwing up our hormones; maybe we don’t know how to navigate human sexuality outside of rape culture; maybe being raised on the message that our bodies are a nation-ending menace has dampened our enthusiasm for physical pleasure.
|
||||
|
||||
[**Eating disorders have steadily increased, though**](https://academic.oup.com/ajcn/article/109/5/1402/5480601). We are still getting our bodies ready to fight The Enemy, and since we are at war with an abstract concept, the enemy is invisible and ethereal. To defeat it, our bodies must lose solidity as well.
|
||||
|
||||
\* \* \* \* \*
|
||||
|
||||
But there is hope.
|
||||
|
||||
Robert Pattinson is playing the next Batman in a film set to release in 2022. He has proudly bragged about his refusal to bulk up for the role, despite an outcry from superhero movie fans.
|
||||
|
||||
In a 2019 interview with _Variety,_ [**Pattinson said**](https://variety.com/2019/film/features/robert-pattinson-batman-the-lighthouse-1203319866/), “In the last three or four movies, I’ve got a masturbation scene. I did it in ‘High Life.’ I did it in ‘Damsel.’ And ‘The Devil All the Time.’ I only realized when I did it the fourth time \[in _The Lighthouse_\].”
|
||||
|
||||
Perhaps he will be the hero we need.
|
||||
|
||||
---
|
||||
|
||||
![Raquel S. Benedict](https://i0.wp.com/bloodknife.com/wp-content/uploads/2020/11/rsbenedict-author.jpg?fit=100%2C100&ssl=1)
|
||||
|
||||
Raquel S. Benedict is the most dangerous woman in speculative fiction. Her fiction has appeared in The New Haven Review and The Magazine of Fantasy & Science Fiction. She also has a podcast called Rite Gud.
|
||||
|
||||
Liked it? Take a second to support Blood Knife on Patreon!
|
||||
|
||||
[![Become a patron at Patreon!](https://i0.wp.com/bloodknife.com/wp-content/plugins/patron-button-and-widgets-by-codebard/images/become_a_patron_button.png?w=1300&ssl=1)](https://www.patreon.com/bloodknife?utm_content=post_button&utm_medium=patron_button_and_widgets_plugin&utm_campaign=4889897&utm_term=&utm_source=https://bloodknife.com/everyone-beautiful-no-one-horny/)
|
398
Media/articles/Front-end Practices That Changed My Life.md
Normal file
398
Media/articles/Front-end Practices That Changed My Life.md
Normal file
@ -0,0 +1,398 @@
|
||||
---
|
||||
author: twitter:hmillerdev
|
||||
link: https://dev.to/arthyn/front-end-practices-that-changed-my-life-56md
|
||||
status: not-finished
|
||||
date: August 2, 2023
|
||||
---
|
||||
# Front-end Practices That Changed My Life - DEV Community
|
||||
#programming #web-development #software-development
|
||||
Hey there! My name is Hunter Miller and Ive been developing web software for about 6 years now. Along the way Ive taken many paths to produce effective software, some that worked well and some that didnt. Ive collected those that I found most influential so that maybe you can get a jump start. Although Ive had some success using "larger" patterns I find the smaller ones more powerful and better for overall quality.
|
||||
|
||||
_By no means is this an exhaustive list. Also please excuse some of the examples, I had to make most of them up. 😂_
|
||||
|
||||
## [](https://dev.to/arthyn/front-end-practices-that-changed-my-life-56md#general)General
|
||||
|
||||
### [](https://dev.to/arthyn/front-end-practices-that-changed-my-life-56md#youre-never-too-far-along-to-learnrelearn-the-fundamentals)Youre Never Too Far Along to Learn/Relearn the Fundamentals
|
||||
|
||||
Its awesome to jump in, start building things, and get something working especially as a beginner. Without learning the fundamentals though, you will often find that you arent quite sure precisely why something is happening, leading to lots of headaches when trying to fix bugs. The fundamentals help you narrow down whats happening so that you can piece it together. For HTML that means learn the basic tags and when its appropriate to use them. For CSS that means knowing all the different properties that affect layout and how they interact together. For JS it means knowing what `this` is at all times 😂.
|
||||
|
||||
### [](https://dev.to/arthyn/front-end-practices-that-changed-my-life-56md#prefer-the-simplest-tech-when-possible)Prefer the Simplest Tech When Possible
|
||||
|
||||
When building web experiences, I try and use HTML first, CSS second, and finally JS if necessary. HTML + CSS can get you really far before you have to reach for JS. Its often simpler and more performant to not have to handle such interactions in JS.
|
||||
|
||||
### [](https://dev.to/arthyn/front-end-practices-that-changed-my-life-56md#read-documentation-and-source-code-especially-mdn-for-the-web)Read Documentation and Source Code (Especially MDN for the web)
|
||||
|
||||
Documentation and source code are your gateways into learning how things really work. Every time you take the time to read the documentation/source code you gain new little bits that youve never noticed before. Theres lots of functionality in the web that you probably dont know. And if you only ever read blogs, tutorials, and Stack Overflow youll never see the full potential of the tools you are using. Its especially helpful for open source libraries where authors dont always have time to write documentation. This made me a better programmer.
|
||||
|
||||
### [](https://dev.to/arthyn/front-end-practices-that-changed-my-life-56md#accessibility-is-necessary)Accessibility Is Necessary
|
||||
|
||||
Without proper accessibility your site will be unusable by those who need to use screen readers, high-contrast text, keyboard navigation, etc. Taking the time to learn the accessibility features of the browser will set you up for success the next time youre trying to create a new experience. I found these people and organizations helped a lot when learning more about accessibility:
|
||||
|
||||
- [Heydon Pickering](https://heydonworks.com/)
|
||||
- [Laura Kalbag](https://laurakalbag.com/)
|
||||
- [A11y Project](https://a11yproject.com/checklist/)
|
||||
- [Simply Accessible](http://simplyaccessible.com/article/listening-web-part-one-thinking-accessibility/)
|
||||
|
||||
### [](https://dev.to/arthyn/front-end-practices-that-changed-my-life-56md#learn-how-the-browser-loads-resources)Learn How the Browser Loads Resources
|
||||
|
||||
This ones tricky because browsers arent always opaque on how they prioritize loading different types of resources. But you can learn a lot about performance from these people and organizations:
|
||||
|
||||
- [CSS Wizardry by Harry Roberts](https://csswizardry.com/)
|
||||
- [Varvy by Patrick Sexton](https://varvy.com/pagespeed/)
|
||||
- [Tim Kadlec](https://timkadlec.com/)
|
||||
- [Filament Group](https://www.filamentgroup.com/lab/)
|
||||
- [web.dev](https://web.dev/fast/)
|
||||
|
||||
## [](https://dev.to/arthyn/front-end-practices-that-changed-my-life-56md#css)CSS
|
||||
|
||||
### [](https://dev.to/arthyn/front-end-practices-that-changed-my-life-56md#atomic-or-utilityfirst-css)Atomic or Utility-first CSS
|
||||
|
||||
Atomic CSS is a way of structuring your CSS classes which mimics the properties and values available in CSS. At first this sounds pretty crazy. There are tons of properties in CSS and each has multiple or even infinite values, so how could this possibly work? Well, first off you dont actually produce a class for each and every value. For those properties with numerical values, we come up with a standard set to use so that will benefit us the most.
|
||||
|
||||
For example, we might have a set of classes for various vertical margins. They might be `my-0 my-1 my-2 my-3`...where each number represents some "level" of margin. So maybe `my-1` equals `margin-top: .25rem; margin-bottom: .25rem;`, and each level after is just + .25rem. Now we have a very useful set of classes to apply pretty much whatever vertical margin we need, and we no longer have to write margins in CSS unless its an extremely specific case. Not only that, but weve given everyone who uses this a standard set of values to choose from. A third benefit is that we know exactly what the class does, theres no guesswork or hidden values. Finally, weve now opened the possibility for any element or component to have their margin changed, if the situation arises, without making a specific override in CSS. This is probably the most powerful pattern in CSS that Ive encountered, even more so than LESS/SASS/SCSS.
|
||||
|
||||
If you want to read more about it here are some great links, [In Defense of Utility-First CSS](https://frontstuff.io/in-defense-of-utility-first-css), [Tailwind CSS](https://tailwindcss.com/docs/utility-first/), [Tachyons CSS](http://tachyons.io/), and a whole slew of articles linked at [The Case for Atomic CSS](https://johnpolacek.github.io/the-case-for-atomic-css/).
|
||||
|
||||
### [](https://dev.to/arthyn/front-end-practices-that-changed-my-life-56md#consistently-ordering-properties)Consistently Ordering Properties
|
||||
|
||||
This is really small and has no actual effects on your CSS (unless its duplicate properties for fallbacks of properties that arent supported). However I find it really helpful when reading/writing CSS to stick with a consistent order. My preferred order is layout/positioning, sizing, spacing, typography, colors/visual effects, transition/animations, and then finally "miscellaneous". Within each category I try to stay ordered as well. It helps to spot bugs and speed things up.
|
||||
|
||||
### [](https://dev.to/arthyn/front-end-practices-that-changed-my-life-56md#single-class-specificity)Single Class Specificity
|
||||
|
||||
I learned this the hard way after nesting way too much SASS and before I got deep into atomic CSS. I was working at a design agency building boutique level websites so everything was very creative and unsystematic or at least each component had lots of exceptions 😉. I quickly found that it was becoming difficult to override CSS I had previously written because everything varied in specificity. By flattening all of it to as close to one class level of specificity it became much easier to override properties on a class. This works hand-in-hand with atomic CSS because as long as your utility classes come last (or have important applied because lets face it if you put that class on their you wanted it) itll override the component class. This leads to much less specificity wars.
|
||||
|
||||
### [](https://dev.to/arthyn/front-end-practices-that-changed-my-life-56md#performant-transitions-and-animations)Performant Transitions and Animations
|
||||
|
||||
This one is very simple, but can be annoying in practice. There are only two properties in CSS that can be reliably performant, `transform` and `opacity`. Everything else is subject to more expensive operations that can cause jank. In general I try to use only these, but I still use `color`, `background-color`, and `border-color` often in low-impact situations, like links or buttons. Read more here about [high performance animations](https://www.html5rocks.com/en/tutorials/speed/high-performance-animations/).
|
||||
|
||||
## [](https://dev.to/arthyn/front-end-practices-that-changed-my-life-56md#html)HTML
|
||||
|
||||
### [](https://dev.to/arthyn/front-end-practices-that-changed-my-life-56md#semantics-aka-learn-the-basic-tags)Semantics, aka Learn the Basic Tags
|
||||
|
||||
There are so many HTML elements. Its hard to know them all and everything that they do, but they will help you build web experiences that are more accessible and maybe even help you write less CSS and JS. Proper HTML also helps your site get crawled by search engines, which helps your content get found. They are the basic bits of the web and using them properly helps you create websites that work.
|
||||
|
||||
### [](https://dev.to/arthyn/front-end-practices-that-changed-my-life-56md#responsive-images)Responsive Images
|
||||
|
||||
Heres the best way to save bytes on your images. Responsive images allow you to serve just the right size to your users by giving you channels to describe images of different sizes and when those sizes will apply. Theres a great doc written by MDN that explains it [here](https://developer.mozilla.org/en-US/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images).
|
||||
|
||||
### [](https://dev.to/arthyn/front-end-practices-that-changed-my-life-56md#ltinputgt-ltlabelgt-interaction-ltdialoggt-ltdetailsgt-and-more)<input> + <label> = interaction (<dialog>, <details>, and more)
|
||||
|
||||
There are a lot of interactions built into the default browser elements. We can leverage those to build interactive elements that do not require Javascript. And since they dont require JS, theyre just a little more robust. Sometimes though, JS is required to really make a set of elements usable and accessible. In those cases we start with the HTML+CSS and layer on the additional functionality required with JS.
|
||||
|
||||
We can build custom toggles, file inputs, and many other types of elements using an `<input>` + `<label>` combination by simply using the `:checked` selector to update the state of the visible element.
|
||||
|
||||
Popovers and collapsible elements can also be built with the details element. A great presentation on this: [The Details on Details by Mu-An Chiou](https://github.com/muan/details-on-details) and a similar one on modals/dialogs by the same author [A Dialog on Dialogs](https://docs.google.com/presentation/d/1BOfauRVTJnGGBQUeNa75N5AzoHCX_sFHpmxcKEKMEB8/edit#slide=id.p)
|
||||
|
||||
## [](https://dev.to/arthyn/front-end-practices-that-changed-my-life-56md#js)JS
|
||||
|
||||
### [](https://dev.to/arthyn/front-end-practices-that-changed-my-life-56md#state-and-special-attributes-as-strings-or-getting-rid-of-boolean-addiction)State and Special Attributes as Strings (or getting rid of boolean addiction)
|
||||
|
||||
When writing Javascript we have a tendency when starting out to write states as a set of boolean flags. We might simply start with one state, `isError`, and assign that a boolean value. And at first this might be fine if its the only state were tracking. Soon though well probably add more, maybe we need an `isInProgress` state. Now we have two flags to represent what should realistically only be one state for the whole component. If both of those states are `true`, then what state should we be in? We quickly get into situations where invalid states are possible.
|
||||
|
||||
The simplest way to resolve this is to track state with a string. The string should be part of a limited set that represents all the states that our component can be in. This helps clean up all the `isX` properties that litter our components and we can simply check the state with a function that returns a boolean value.
|
||||
|
||||
Heres a basic example of an ajax call to a server to load some data:
|
||||
|
||||
```
|
||||
const loaderStates = {
|
||||
initial: initial,
|
||||
loading: loading,
|
||||
success: success,
|
||||
error: error
|
||||
}
|
||||
|
||||
let state = loaderStates.initial;
|
||||
|
||||
function is(status) {
|
||||
return Array.isArray(status)
|
||||
? status.indexOf(state) > -1
|
||||
: state === status;
|
||||
}
|
||||
|
||||
|
||||
async function loadTodos() {
|
||||
state = loaderStates.loading;
|
||||
|
||||
try {
|
||||
const todos = await fetch(/todos).then(response => response.json());
|
||||
state = loaderStates.success;
|
||||
} catch (error) {
|
||||
state = loaderStates.error;
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Enter fullscreen mode Exit fullscreen mode
|
||||
|
||||
You can see weve created an object to hold our states called `loaderStates`. We also created a function which lets us check if the current state matches a state we want to know about, equivalent to what we had before `isError` vs `is(loaderStates.error)`. Now we can use this function to trigger things like spinners when loading or error messages when were in an error state.
|
||||
|
||||
A much more advanced version of this pattern is called _state machines_ which you can find out more about [here](https://www.youtube.com/watch?v=czi24DqUfSA) from David K Piano where he uses the library he wrote [xstate](https://github.com/davidkpiano/xstate).
|
||||
|
||||
Similarly, we tend to use these types of boolean flags to describe attributes like `CanUpdate`, `CanEdit`, etc. which is just as unmaintainable. In the same way as above, we can move to strings to give us a more succinct way to represent some set of attributes. This is also gives us the added benefit of being able to iterate through the set of strings with array functions, whereas before we might have had to have a huge if-else statement to check all the attributes.
|
||||
|
||||
```
|
||||
const admin = {
|
||||
id: 1,
|
||||
name: Hunter Miller,
|
||||
canEdit: true,
|
||||
canPublish: true,
|
||||
canManageUsers: true,
|
||||
canApprove: true,
|
||||
canViewOtherUsersContent: true,
|
||||
canAccessBackend: true
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Enter fullscreen mode Exit fullscreen mode
|
||||
|
||||
vs.
|
||||
|
||||
```
|
||||
const admin = {
|
||||
id: 1,
|
||||
name: Hunter Miller,
|
||||
permissions: [
|
||||
edit,
|
||||
publish,
|
||||
manage-users,
|
||||
approve,
|
||||
view-others-content,
|
||||
access-backend
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Enter fullscreen mode Exit fullscreen mode
|
||||
|
||||
### [](https://dev.to/arthyn/front-end-practices-that-changed-my-life-56md#making-maps)Making Maps
|
||||
|
||||
Theres a common pattern in JS where we want to run some functionality or get some data based on a key. Instead of using a chain of if statements or a switch with cases, we can use an object to associate a particular key with whatever we need, and then just access what we need with `map[key]`.
|
||||
|
||||
Data were working with:
|
||||
|
||||
```
|
||||
const transaction = {
|
||||
id: 88,
|
||||
price: 33.93,
|
||||
loginId: hmillerdev,
|
||||
email: hunter@hmiller.dev,
|
||||
paymentId: e2b7291d-8838-4435-942a-ec6bec938673
|
||||
paymentType: credit-card
|
||||
};
|
||||
```
|
||||
|
||||
Enter fullscreen mode Exit fullscreen mode
|
||||
|
||||
Using ifs:
|
||||
|
||||
```
|
||||
function processTransaction(transaction) {
|
||||
...
|
||||
if (transaction.paymentType === credit-card) {
|
||||
processCreditCard(transaction);
|
||||
} else if (transaction.paymentType === paypal) {
|
||||
processPaypal(transaction);
|
||||
} else if (transaction.paymentType === bank) {
|
||||
processBank(transaction);
|
||||
} else if (transaction.paymentType === bitcoin) {
|
||||
processBitcoin(transaction);
|
||||
} else if (transaction.paymentType === seashells) {
|
||||
processSeashells(transaction);
|
||||
}
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
Enter fullscreen mode Exit fullscreen mode
|
||||
|
||||
Now with a map:
|
||||
|
||||
```
|
||||
const processors = {
|
||||
credit-card: processCreditCard,
|
||||
paypal: processPaypal,
|
||||
bank: processBank,
|
||||
bitcoin: processBitcoin,
|
||||
seashells: processSeashells
|
||||
}
|
||||
|
||||
function processTransaction(transaction) {
|
||||
...
|
||||
const processPayment = processors[transaction.paymentType];
|
||||
processPayment(transaction);
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
Enter fullscreen mode Exit fullscreen mode
|
||||
|
||||
### [](https://dev.to/arthyn/front-end-practices-that-changed-my-life-56md#functionalize)Functionalize
|
||||
|
||||
This one is pretty near and dear to me. One of the first things I learned was to break my functions down as small as they can be, so that we can reuse that chunk of code later. This comes with the added benefit that now weve given that chunk of functionality a name. So when we read through the code, we can get a better sense of whats going on. It also lets us leverage one of the main features provided to us in JS, that lets us pass functions around to alter the functionality of other functions.
|
||||
|
||||
One of the best examples, is the array function `map`. We call this function off of an array and pass it a function which will transform each item in the array returning a whole new array.
|
||||
|
||||
```
|
||||
const itemPrices = [25.00, 10.00, 48.00];
|
||||
|
||||
function priceWithHalfOffDiscount(price) {
|
||||
return price * 0.5;
|
||||
}
|
||||
|
||||
const discountedPrices = itemPrices.map(price => priceWithHalfOffDiscount(price));
|
||||
|
||||
```
|
||||
|
||||
Enter fullscreen mode Exit fullscreen mode
|
||||
|
||||
So now `discountedPrices` equals `[12.50, 5.00, 24.00]`.
|
||||
|
||||
Anytime we need to transform each item in an array and get that transformed array back, we can use map with whatever transforming function we need. We now have an immense set of functionality with just one function, because we can give it something to change what it does.
|
||||
|
||||
This is the very tip of the iceberg to a style of programming called functional programming which you can learn about from Mattias at Fun Fun Function from his [functional programming playlist](https://www.youtube.com/watch?v=BMUiFMZr7vk) or you can learn from this fun little online book called the [Professor Frisbys Mostly Adequate Guide to Functional Programming](https://mostly-adequate.gitbooks.io/mostly-adequate-guide/content/). Ive found that this style of programming has vastly improved my code quality and resiliency and makes a lot of problems much easier to think about. However it can be very confusing when you first learn it because it is a bit of a brain change for most people.
|
||||
|
||||
### [](https://dev.to/arthyn/front-end-practices-that-changed-my-life-56md#dont-repeat-yourself-too-much)Dont Repeat Yourself (Too Much)
|
||||
|
||||
Related to the previous section, if we have two blocks of code that are very similar, it can be beneficial to combine them into a function and let the parameters dictate the differences. Sometimes this can get us into trouble if were trying to force things that are too different together. It might force us to make a function that has way too many branching paths or long lists of parameters. I find that is less often the case though. We actually more often have a ton of things that are very similar and once we start de-duplicating one part of the code it can lead to a waterfall of changes that makes the code much cleaner and easier to read. A good rule of thumb is that if this helps the code handle things more consistently and improves the readability then its a good time to remove the redundancy. This can be a double-edged sword, but mostly beneficial when not overused.
|
||||
|
||||
```
|
||||
function processOrderWithShipments(data) {
|
||||
if (!data) {
|
||||
return;
|
||||
}
|
||||
|
||||
const order = new Order(data);
|
||||
const shipments = assignItemsToShipments(order.items);
|
||||
const paymentProcessor = new PaymentProcessor();
|
||||
|
||||
if(!order.isValid()) {
|
||||
throw new Error("Order is invalid");
|
||||
}
|
||||
|
||||
const receipt = paymentProcessor.pay(order.paymentMethod, order.Total);
|
||||
sendOrderConfirmationEmail(order, receipt);
|
||||
|
||||
const shipments = assignItemsToShipments(order.items);
|
||||
alertFulfillment(shipments);
|
||||
}
|
||||
|
||||
function processRecurringDigitalGoodsOrder(orderData, timePeriod) {
|
||||
if (!data) {
|
||||
return;
|
||||
}
|
||||
|
||||
const order = new Order(data);
|
||||
const paymentProcessor = new PaymentProcessor();
|
||||
|
||||
if(!order.isValid()) {
|
||||
throw new Error("Order is invalid");
|
||||
}
|
||||
|
||||
const receipt = paymentProcessor.pay(order.paymentMethod, order.Total);
|
||||
sendOrderConfirmationEmail(order, receipt);
|
||||
|
||||
setupSubscription(order.paymentMethod, order.items, timePeriod);
|
||||
sendGoods(order.goods);
|
||||
}
|
||||
```
|
||||
|
||||
Enter fullscreen mode Exit fullscreen mode
|
||||
|
||||
vs
|
||||
|
||||
```
|
||||
function processOrder(order) {
|
||||
const paymentProcessor = new PaymentProcessor();
|
||||
|
||||
if(!order.isValid()) {
|
||||
throw new Error("Order is invalid");
|
||||
}
|
||||
|
||||
const receipt = paymentProcessor.pay(order.paymentMethod, order.Total);
|
||||
sendOrderConfirmationEmail(order, receipt);
|
||||
}
|
||||
|
||||
function processOrderWithShipments(data) {
|
||||
if (!data) {
|
||||
return;
|
||||
}
|
||||
|
||||
const order = new Order(data);
|
||||
const shipments = assignItemsToShipments(order.items);
|
||||
|
||||
try {
|
||||
processOrder(order);
|
||||
alertFulfillment(shipments);
|
||||
} catch (error) {
|
||||
console.log("😭😭😭😭", error);
|
||||
}
|
||||
}
|
||||
|
||||
function processRecurringDigitalGoodsOrder(orderData, timePeriod) {
|
||||
if (!orderData || !timePeriod) {
|
||||
return;
|
||||
}
|
||||
|
||||
const order = new Order(orderData);
|
||||
|
||||
try {
|
||||
processOrder(order);
|
||||
setupSubscription(order.paymentMethod, order.items, timePeriod);
|
||||
sendGoods(order.goods);
|
||||
} catch (error) {
|
||||
console.log("😭😭😭😭", error);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Enter fullscreen mode Exit fullscreen mode
|
||||
|
||||
### [](https://dev.to/arthyn/front-end-practices-that-changed-my-life-56md#getting-rid-of-a-few-ifs)Getting Rid of a Few Ifs
|
||||
|
||||
Often in our code we want to provide some default values or not call a function if somethings `null`. We can get around using if statements by using boolean checks. For example if we want to default a value based on a parameter that may or may not be null we can do something like this: `const items = newItems || []`. Because of the way JS works, boolean checks like this return the value of the expression so `items` will be assigned `[]` if newItems is null or undefined. This is a tip I picked up from Addy Osmani though I cant seem to find the article he wrote about it. Sometimes this can result in code thats less readable and in those cases you should use an if statement.
|
||||
|
||||
### [](https://dev.to/arthyn/front-end-practices-that-changed-my-life-56md#separate-api-calls-into-their-own-module)Separate API Calls into Their Own Module
|
||||
|
||||
If you have multiple calls to a shared endpoint or API, it can often be helpful to encapsulate all those AJAX calls into a module where each call is a function. Now, setup and the handling of the response can be the same across the application. Anytime something changes about that API all the changes can be made in one place and we dont have all that clogging up our specific components logic.
|
||||
|
||||
```
|
||||
class todoAPI {
|
||||
getTodos() {
|
||||
return fetch(/todos).then(response => response.json())
|
||||
}
|
||||
|
||||
editTodo(id) {
|
||||
return fetch(/todos, {
|
||||
method: POST,
|
||||
body: JSON.stringify({ id })
|
||||
}).then(response => response.json())
|
||||
}
|
||||
...
|
||||
}
|
||||
|
||||
export const todoAPI = new todoAPI();
|
||||
```
|
||||
|
||||
Enter fullscreen mode Exit fullscreen mode
|
||||
|
||||
Later on when you need to get the todos:
|
||||
|
||||
```
|
||||
import { todoAPI } from ./todoAPI;
|
||||
|
||||
const todos = await todoAPI.getTodos();
|
||||
```
|
||||
|
||||
Enter fullscreen mode Exit fullscreen mode
|
||||
|
||||
This gives us the ability to pass around the API to whatever module or component needs it, and its not stuck in some specific component. Yet another way to increase re-usability and reduce duplication.
|
||||
|
||||
## [](https://dev.to/arthyn/front-end-practices-that-changed-my-life-56md#conclusion)Conclusion
|
||||
|
||||
The web evolves constantly and so do my practices and philosophies around development, but the thoughts above have stuck around. These things are like old regulars that just keep coming back to the cafe even though the rest of the customers keep changing. A lot of what Ive picked up above came from trial and error. I also read a ton of web dev Twitter, and am never scared to Google something to try out new methods. Like my good friend [Bennett Dungan](https://www.bennettdungan.com/) said, learning to code is a marathon. It takes time to build practices and methods that make you productive. Try some of these things and [let me know what you think on Twitter.](https://twitter.com/intent/tweet/?text=Here%27s%20a%20long%20list%20of%20simple%20front-end%20development%20practices%20that%20will%20help%20you%20be%20more%20productive%20in%20your%20day-to-day.%20by%20@hmillerdev&url=https://hmiller.dev/posts/front-end-practices-that-changed-my-life/)
|
||||
|
||||
– Hunter ✌
|
||||
|
||||
_Originally posted on [hmiller.dev](https://hmiller.dev/posts/front-end-practices-that-changed-my-life/). Cover photo by [Tim Gouw](https://unsplash.com/@punttim?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) on [Unsplash](https://unsplash.com/?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)_
|
166
Media/articles/How Figma's multiplayer technology works.md
Normal file
166
Media/articles/How Figma's multiplayer technology works.md
Normal file
@ -0,0 +1,166 @@
|
||||
---
|
||||
author:
|
||||
link: https://www.figma.com/blog/how-figmas-multiplayer-technology-works/
|
||||
status: not-finished
|
||||
date: August 1, 2023
|
||||
---
|
||||
# How Figma’s multiplayer technology works | Figma Blog
|
||||
|
||||
#technology #design #collaboration
|
||||
|
||||
When we first started [building multiplayer functionality](/blog/multiplayer-editing-in-figma/)
|
||||
|
||||
in [Figma](https://www.figma.com/) four years ago, we decided to develop our own solution. No other design tool offered this feature, and we didn’t want to use operational transforms (a.k.a. OTs), the standard multiplayer algorithm popularized by apps like Google Docs. As a startup we value the ability to ship features quickly, and OTs were unnecessarily complex for our problem space. So we built a custom multiplayer system thats simpler and easier to implement.
|
||||
|
||||
![c87b9b526653b43596c015c808a54c2dc6e323d1-4240x2000.webp](https://cdn.sanity.io/images/599r6htc/localized/4318861f261dfea4e4de7829e8a1ee1738833dd8-2120x1000.webp?w=2120&h=1000&q=75&fit=max&auto=format)
|
||||
|
||||
At the time, we weren’t sure building this feature was the right product decision. No one was clamoring for a multiplayer design tool—if anything, people hated the idea. Designers worried that live collaborative editing would result in “hovering art directors” and “design by committee” catastrophes.
|
||||
|
||||
But ultimately, we had to do it because it just felt wrong not to offer multiplayer as a tool on the web. It eliminates the need to export, sync, or email copies of files and allows more people to take part in the design process (like copy-writers and developers). Just by having the right link, everyone can view the current status of a design project without interrupting the person doing the work.
|
||||
|
||||
Our bet paid off, and these days it’s obvious that multiplayer is the way all productivity tools on the web should work, not just design. But while we use products with live collaborative editing every day, there aren’t that many public case studies on these production systems.
|
||||
|
||||
We decided it was time to share a peek into how we did it at Figma, in the hopes of helping others. It should be a fun read for those who like seeing how computer science theory is applied in practice. We’ll cover a lot but each section builds upon the previous ones. By the end, you should hopefully have an understanding of the entire system.
|
||||
|
||||
## [Background context: Figma’s setup, OTs, and more](#background-context-figma-s-setup-ots-and-more)
|
||||
|
||||
Before talking about our multiplayer protocol, its useful to have some context about how our multiplayer system is set up. We use a client/server architecture where Figma clients are web pages that talk with a cluster of servers over WebSockets. Our servers currently spin up a separate process for each multiplayer document which everyone editing that document connects to. If you’re interested in learning more, [this article](/blog/rust-in-production-at-figma/) talks about how we scale our production multiplayer servers.
|
||||
|
||||
![4ebb54efbfa2fd4951e04ddb0b3f2b67146976ad-2120x1000.webp](https://cdn.sanity.io/images/599r6htc/localized/9b191bec39eaafd24d76dc589e4d68c54a7706dc-2120x1000.webp?w=2120&h=1000&q=75&fit=max&auto=format)
|
||||
|
||||
When a document is opened, the client starts by downloading a copy of the file. From that point on, updates to that document in both directions are synced over the WebSocket connection. Figma lets you go offline for an arbitrary amount of time and continue editing. When you come back online, the client downloads a fresh copy of the document, reapplies any offline edits on top of this latest state, and then continues syncing updates over a new WebSocket connection. This means that connecting and reconnecting are very simple and all of the complexity with multiplayer (which is what this blog post is about) is in dealing with updates to already connected documents.
|
||||
|
||||
It’s worth noting that we only use multiplayer for syncing changes to Figma documents. We also sync changes to a lot of other data (comments, users, teams, projects, etc.) but that is stored in Postgres, not our multiplayer system, and is synced with clients using a completely separate system that won’t be discussed in this article. Although these two systems are similar, they have separate implementations because of different tradeoffs around certain properties such as performance, offline availability, and security.
|
||||
|
||||
We didnt start with this setup though. When making a change this fundamental, its important to be able to iterate quickly and experiment before committing to an approach. Thats why we first created a prototype environment to test our ideas instead of working in the real codebase. This playground was a web page that simulated three clients connecting to a server and visualized the whole state of the system. It let us easily set up different scenarios around offline clients and bandwidth limited connections.
|
||||
|
||||
Once we figured out how we wanted to build our multiplayer system, it was straightforward to graft the ideas from our prototype onto our existing codebase. We used this prototype to quickly research and evaluate different collaborative algorithms and data structures.
|
||||
|
||||
![](https://cdn.sanity.io/images/599r6htc/localized/e8a6196bdd0f029131c81e45cc44e3dbf908e412-1500x751.png?rect=1,0,1498,751&w=804&h=403&q=75&fit=max&auto=format)
|
||||
|
||||
A screenshot of our internal prototype
|
||||
|
||||
![](data:image/jpeg;base64,/9j/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj/wAARCAAbABQDASIAAhEBAxEB/8QAGQAAAgMBAAAAAAAAAAAAAAAAAAYDBwgF/8QAJxAAAQMDAwQBBQAAAAAAAAAAAgEDBAAFEQYSMQcTQVEIISMyNEL/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8AsjqS2RalZaBREnVQMlwlLtxglDlGx3AcUOVHzSr1m1Dcrf1VQJYELLJisc0XAoK+/dTXPUbTN0SVGLvxlRFkkC52580DC20W3laKsO1aXiTbdHktyD2PAhpkU4VKKCmPkhcbVdp9seakDkVJt1Q/LavC0naNs9imNME5eHsI5hxOFIfVcPXJKd/JTXcuwU+tKj32JxKyqhhf5XFBsBrV1viMtx4k0uw0KAGV8JRWW4Nwl9j9hzlfNFB//9k=)![](https://cdn.sanity.io/images/599r6htc/localized/49450fd4c6833ef369a4cfa5f65b3a6bf56bcc7e-440x604.jpg?w=440&h=604&q=75&fit=max&auto=format)
|
||||
|
||||
###### Douglas Engelbart practicing for "The Mother of All Demos"
|
||||
|
||||
### [How OTs and CRDTs informed our multiplayer approach](#how-ots-and-crdts-informed-our-multiplayer)
|
||||
|
||||
Multiplayer technology has a rich history and has arguably been around at least since [Douglas Engelbarts demo in 1968](https://en.wikipedia.org/wiki/The_Mother_of_All_Demos). Before we dive in too deep into how our own multiplayer system works, it’s worth a quick overview on the traditional approaches that informed ours: OTs and CRDTs.
|
||||
|
||||
## Critique of OT
|
||||
|
||||
While the classic OT approach of defining operations through their offsets in the text seems to be simple and natural, [real-world distributed systems raise serious issues](https://en.wikipedia.org/wiki/Operational_transformation#Critique_of_OT). Namely, that operations propagate with finite speed, states of participants are often different, thus the resulting combinations of states and operations are extremely hard to foresee and understand. As Li and Li put it, "Due to the need to consider complicated case coverage, formal proofs are very complicated and error-prone, even for OT algorithms that only treat two characterwise primitives (insert and delete)."
|
||||
|
||||
As mentioned earlier, OTs power most collaborative text-based apps such as Google Docs. They’re the most well-known technique but in researching them, we quickly realized they were overkill for what we wanted to achieve. They’re a great way of editing long text documents with low memory and performance overhead, but they are very complicated and hard to implement correctly. They result in a combinatorial explosion of possible states which is [very difficult to reason about](https://en.wikipedia.org/wiki/Operational_transformation#Critique_of_OT).
|
||||
|
||||
Our primary goal when designing our multiplayer system was for it to be no more complex than necessary to get the job done. A simpler system is easier to reason about which then makes it easier to implement, debug, test, and maintain. Since Figma isnt a text editor, we didnt need the power of OTs and could get away with something less complicated.
|
||||
|
||||
## Conflict-free replicated data type
|
||||
|
||||
In distributed computing, a [conflict-free replicated data type (CRDT)](https://en.wikipedia.org/wiki/Conflict-free_replicated_data_type) is a data structure that is replicated across multiple computers in a network, with the following features:
|
||||
|
||||
1. The application can update any replica independently, concurrently and without coordinating with other replicas.
|
||||
2. An algorithm (itself part of the data type) automatically resolves any inconsistencies that might occur.
|
||||
3. Although replicas may have different state at any particular point in time, they are guaranteed to eventually converge.
|
||||
|
||||
Figmas tech is instead inspired by something called CRDTs, which stands for [conflict-free replicated data types](https://en.wikipedia.org/wiki/Conflict-free_replicated_data_type). CRDTs refer to a collection of different data structures commonly used in distributed systems. All CRDTs satisfy certain mathematical properties which guarantee eventual consistency. If no more updates are made, eventually everyone accessing the data structure will see the same thing. This constraint is required for correctness; we cannot allow two clients editing the same Figma document to diverge and never converge again.
|
||||
|
||||
There are many types of CRDTs. See [this list](https://github.com/pfrazee/crdt_notes/tree/68c5fe81ade109446a9f4c24e03290ec5493031f#portfolio-of-basic-crdts) for a good overview. Some examples:
|
||||
|
||||
- **Grow-only set:** This is a set of elements. The only type of update is to add something to the set. Adding something twice is a no-op, so you can determine the contents of the set by just applying all of the updates in any order.
|
||||
- **Last-writer-wins register:** This is a container for a single value. Updates can be implemented as a new value, a timestamp, and a peer ID. You can determine the value of the register by just taking the value of the latest update (using the peer ID to break a tie).
|
||||
|
||||
Figma isnt using true CRDTs though. CRDTs are designed for decentralized systems where there is no single central authority to decide what the final state should be. There is some unavoidable performance and memory overhead with doing this. Since Figma is centralized (our server is the central authority), we can simplify our system by removing this extra overhead and benefit from a faster and leaner implementation.
|
||||
|
||||
It’s also worth noting that Figmas data structure isnt a single CRDT. Instead its inspired by multiple separate CRDTs and uses them in combination to create the final data structure that represents a Figma document (described below).
|
||||
|
||||
Even if you have a client-server setup, CRDTs are still worth researching because they provide a well-studied, solid foundation to start with. Understanding them helps build intuition on how to create a correct system. From that point, its possible to relax some of the requirements of CRDTs based on the needs of the application as we have done.
|
||||
|
||||
### [How a Figma document is structured](#how-a-figma-document-is-structured)
|
||||
|
||||
Ok, so we want to sync updates to Figma documents using CRDTs. What does the structure of a Figma document even look like?
|
||||
|
||||
![DOM HTML tree](https://cdn.sanity.io/images/599r6htc/localized/70a805a5416a06ccc4f5cb6096c4324a9d950b82-486x266.png?w=486&h=266&q=75&fit=max&auto=format)
|
||||
|
||||
### HTML DOM
|
||||
|
||||
The [HTML Document Object Model (DOM)](https://www.w3schools.com/js/js_htmldom.asp#:~:text=The%20HTML%20DOM%20is%20a,to%20access%20all%20HTML%20elements) is a standard object model and programming interface for HTML. It defines: The HTML elements as objects, the properties of all HTML elements, the methods to access all HTML elements, and the events for all HTML elements.
|
||||
|
||||
Every Figma document is a tree of objects, similar to the HTML DOM. There is a single root object that represents the entire document. Underneath the root object are page objects, and underneath each page object is a hierarchy of objects representing the contents of the page. This tree is is presented in the layers panel on the left-hand side of the Figma editor.
|
||||
|
||||
Each object has an ID and a collection of properties with values. One way to think about this is by picturing the document as a two-level map: `Map<ObjectID, Map<Property, Value>>`. Another way to think about this is a database with rows that store `(ObjectID, Property, Value)` tuples. This means that adding new features to Figma usually just means adding new properties to objects.
|
||||
|
||||
## [The details of Figma’s multiplayer system](#the-details-of-figma-s-multiplayer-system)
|
||||
|
||||
For the rest of this post, we will talk about the details of Figmas multiplayer algorithm and how we solved some of the edge cases we encountered.
|
||||
|
||||
### [Syncing object properties](#syncing-object-properties)
|
||||
|
||||
Figma’s multiplayer servers keep track of the latest value that any client has sent for a given property on a given object. This means that two clients changing unrelated properties on the same object won’t conflict, and two clients changing the same property on unrelated objects also won’t conflict. A conflict happens when two clients change the same property on the same object, in which case the document will just end up with the last value that was sent to the server. This approach is similar to a last-writer-wins register in CRDT literature except we don’t need a timestamp because the server can define the order of events.
|
||||
|
||||
An animation showing two clients sending updates without any conflicts
|
||||
|
||||
An important consequence of this is that changes are atomic at the property value boundary. The eventually consistent value for a given property is always a value sent by one of the clients. This is why simultaneous editing of the same text value doesn’t work in Figma. If the text value is B and someone changes it to AB at the same time as someone else changes it to BC, the end result will be either AB or BC but never ABC. That’s ok with us because Figma is a design tool, not a text editor, and this use case isn’t one we’re optimizing for.
|
||||
|
||||
The most complicated part of this is how to handle conflicts on the client when there’s a conflicting change. Property changes on the client are always applied immediately instead of waiting for acknowledgement from the server since we want Figma to feel as responsive as possible. However, if we do this and we also apply every change from the server as it comes in, conflicting changes will sometimes “flicker” when older acknowledged values temporarily overwrite newer unacknowledged ones. We want to avoid this flickering behavior.
|
||||
|
||||
Intuitively, we want to show the user our best prediction of what the eventually-consistent value will be. Since our change we just sent hasn’t yet been acknowledged by the server but all changes coming from the server have been, our change is our best prediction because it’s the most recent change we know about in last-to-the-server order. So we want to discard incoming changes from the server that conflict with unacknowledged property changes.
|
||||
|
||||
An animation showing how to avoid “flickering” during a conflict between two clients
|
||||
|
||||
### [Syncing object creation and removal](#syncing-object-creation-and-removal)
|
||||
|
||||
Creating a new object and removing an existing object are both explicit actions in our protocol. Objects cannot automatically be brought into existence by writing a property to an unassigned object ID. Removing an object deletes all data about it from the server including all of its properties.
|
||||
|
||||
Object creation in Figma is most similar to a last-writer-wins set in CRDT literature, where whether an object is in the set or not is just another last-writer-wins boolean property on that object. A big difference from this model is that Figma doesn’t store any properties of deleted objects on the server. That data is instead stored in the undo buffer of the client that performed the delete. If that client wants to undo the delete, then it’s also responsible for restoring all properties of the deleted objects. This helps keep long-lived documents from continuing to grow in size as they are edited.
|
||||
|
||||
This system relies on clients being able to generate new object IDs that are guaranteed to be unique. This can be easily accomplished by assigning every client a unique client ID and including that client ID as part of newly-created object IDs. That way no two clients will ever generate the same object ID. Note that we can’t solve this by having the server assign IDs to newly-created objects because object creation needs to be able to work offline.
|
||||
|
||||
### [Syncing trees of objects](#syncing-trees-of-objects)
|
||||
|
||||
Arranging objects in an eventually-consistent tree structure is the most complicated part of our multiplayer system. The complexity comes from what to do about reparenting operations (moving an object from one parent to another). When designing the tree structure, we had two main goals in mind:
|
||||
|
||||
- Reparenting an object shouldn’t conflict with changes to unrelated properties on those objects. If someone is changing the object’s color while someone else is reparenting the object, those two operations should both succeed.
|
||||
- Two concurrent reparenting operations for the same object shouldn’t ever result in two copies of that object in separate places in the tree.
|
||||
|
||||
Many approaches represent reparenting as deleting the object and recreating it somewhere else with a new ID, but that doesnt work for us because concurrent edits would be dropped when the objects identity changes. The approach we settled on was to represent the parent-child relationship by storing a link to the parent as a property on the child. That way object identity is preserved. We also don’t need to deal with the situation where an object somehow ends up with multiple parents that we might have if, say, we instead had each parent store links to its children.
|
||||
|
||||
However, we now have a new problem. Without any other restrictions, these parent links are just directed edges on a graph. There’s nothing to ensure that they have no cycles and form a valid tree. An example of this is a concurrent edit where one client makes A a child of B while another client makes B a child of A. Then A and B are both each other’s parent, which forms a cycle.
|
||||
|
||||
Figma’s multiplayer servers reject parent property updates that would cause a cycle, so this issue can’t happen on the server. But it can still happen on the client. Clients can’t reject changes from the server because the server is the ultimate authority on what the document looks like. So a client could end up in a state where it has both sent the server an unacknowledged change to parent A under B and also received a change from the server that parents B under A. The client’s change will be rejected in the future by the server because it will form a cycle, but the client doesn’t know it yet.
|
||||
|
||||
An animation of a reparenting conflict
|
||||
|
||||
Figma’s solution is to temporarily parent these objects to each other and remove them from the tree until the server rejects the client’s change and the object is reparented where it belongs. This solution isn’t great because the object temporarily disappears, but it’s a simple solution to a very rare temporary problem so we didn’t feel the need to try something more complicated here such as breaking these temporary cycles on the client.
|
||||
|
||||
To construct a tree we also need a way of determining the order of the children for a given parent. Figma uses a technique called “fractional indexing” to do this. At a high level, an object’s position in its parent’s array of children is represented as a fraction between 0 and 1 exclusive. The order of an object’s children is determined by sorting them by their positions. You can insert an object between two other objects by setting its position to the average of the positions of the two other objects.
|
||||
|
||||
An animation of reordering using fractional indexing
|
||||
|
||||
We’ve already written [another article](/blog/realtime-editing-of-ordered-sequences/#fractional-indexing) that describes this technique in detail. The important part to mention here is that the parent link and this position must both be stored as a single property so they update atomically. It doesn’t make sense to continue to use the position from one parent when the parent is updated to point somewhere else.
|
||||
![eb174f1882c5e0b196054814f529ab9c29db709a-2120x1000.webp](https://cdn.sanity.io/images/599r6htc/localized/cc54a8a0e37737bb221602eb57af2638a62ca9de-2120x1000.webp?w=2120&h=1000&q=75&fit=max&auto=format)
|
||||
|
||||
## [Implementing undo](#implementing-undo)
|
||||
|
||||
Undo history has a natural definition for single-player mode, but undo in a multiplayer environment is inherently confusing. If other people have edited the same objects that you edited and then undo, what should happen? Should your earlier edits be applied over their later edits? What about redo?
|
||||
|
||||
We had a lot of trouble until we settled on a principle to help guide us: if you undo a lot, copy something, and redo back to the present (a common operation), the document should not change. This may seem obvious but the single-player implementation of redo means “put back what I did” which may end up overwriting what other people did next if you’re not careful. This is why in Figma an undo operation modifies redo history at the time of the undo, and likewise a redo operation modifies undo history at the time of the redo.
|
||||
|
||||
An animation showing undo and redo history modification
|
||||
|
||||
## [The big takeaways](#the-big-takeaways)
|
||||
|
||||
Weve covered a lot! This is the post we wished we could have read when we were first starting our research. Its one thing to learn about CRDTs in the abstract, but its a different thing to find out how those ideas work in practice in a real production system.
|
||||
|
||||
Some of our main takeaways:
|
||||
|
||||
- CRDT literature can be relevant even if youre not creating a decentralized system
|
||||
- Multiplayer for a visual editor like ours wasnt as intimidating as we thought
|
||||
- Taking time to research and prototype in the beginning really paid off
|
||||
|
||||
If you made it this far, you should now have enough information to make your own collaborative tree data structure. And even if your problem space isnt exactly like ours, I hope this post shows how CRDT research can be a great source of inspiration.
|
||||
|
||||
Do you love thinking about collaborative editing, distributed systems, or building scalable services? [We’re hiring](/careers/)!
|
||||
|
||||
_Hero illustration by [Rose Wong](https://www.rosewongart.com/)_.
|
@ -1,7 +0,0 @@
|
||||
# How Figma’s multiplayer technology works
|
||||
|
||||
Link: https://www.figma.com/blog/how-figmas-multiplayer-technology-works/
|
||||
Score /5: ⭐️⭐️⭐️⭐️⭐️
|
||||
Status: Finished
|
||||
Tags: Tech, crdt
|
||||
Type: Article
|
137
Media/articles/Live Like the World is Dying.md
Normal file
137
Media/articles/Live Like the World is Dying.md
Normal file
@ -0,0 +1,137 @@
|
||||
---
|
||||
author: Not found.
|
||||
link: https://www.liveliketheworldisdying.com/were-all-preppers-now/
|
||||
status: not-finished
|
||||
date: August 2, 2023
|
||||
---
|
||||
# We’re All Preppers Now | Live Like the World is Dying
|
||||
#apocalyptic #survival #prepping #crisis
|
||||
We’re all preppers now. Whether we want to be or not. It’s hard to think about, but we’re just in the opening credits to the apocalypse movie. As I write this, we’re in the calm before the storm. This is your moment to get ready. We can get through this. Remember: most people survive the collapse of their way of life, most of the time. The end of the world isn’t always, or even usually, the uh… end of the world.
|
||||
|
||||
Prepping has a bad name for a good reason. For as long as I’ve been alive, the public face of prepping has been strange old men with bunkers full of canned food who have more guns than they have friends. It’s not a good look. Don’t get me wrong, some of the best people in this world are strange old men with garages full of dried rice. If you’ve got someone like that in your neighborhood, now’s a good time to make friends with them. But that lifestyle is not a good representation of what being prepared looks like for most of us.
|
||||
|
||||
First and foremost, the bunker mentality will get us all killed. Even if a lot of us (myself included) are introverts and curmudgeons at heart, the human animal is still a social animal. We’ve evolved to take care of one another and be taken care of. We weather crisis better when we do it together.
|
||||
|
||||
When crisis hits, we work together. This happens naturally. Think about waiting for a bus at a bus stop with some strangers. There’s no reason to talk to each other. As soon as the bus is ten minutes late, though, the barriers of social isolation break down and everyone is friends. You’re all in it together, suffering the disaster of a missed bus. The social norms go out the window, and most of the time, what comes rushing in is a sense of togetherness.
|
||||
|
||||
Popular media about disaster shows us that crises drive us apart, that without the rule of law we all immediately turn on one another, trying desperately to get to the top. Yet actual studies of disaster show exactly the opposite. During Hurricane Katrina in New Orleans, a large number of the looters were able-bodied, risk-tolerant young people gathering resources for those who were trapped at home by the floodwaters. It’s precisely the reassertion of authority (usually from the government, but sometimes from new, alternative power structures) that tends to disrupt the process of mutual aid.
|
||||
|
||||
The main exception to this is, of course, rich people. People who are used to being in control are the ones who freak out the moment anything goes wrong. There’s even a word for this: elite panic. Insisting on the norms of the now-failing status quo is exactly the wrong move.
|
||||
|
||||
So is choosing to self-isolate. If you go hole up with your ten friends in the woods when the power grid fails, that’s fine and good until your appendix bursts and none of you are surgeons. Or maybe you have a surgeon, and you survive that particular crisis. But while you were off hiding in the woods, someone stepped in to the vacuum of power, and you weren’t there to stop them or to organize something better, and society is reforming without your input.
|
||||
|
||||
Prepping has a bad name, for good reason. Prepping has such a bad name that I don’t always call what I do prepping. Most of what is labeled prepping is this individualist mentality—what I call the bunker mentality. Instead, we’re going to talk about preparedness from a point of view that remembers we’re social creatures and that we’re part of a society, from a point of view that recognizes how disaster tends to bring people together more than it pushes people apart. We’re going to talk about community preparedness, even if we’re going to talk about what you as an individual, a family, or a small community can do to be prepared to participate in a broader community preparedness.
|
||||
|
||||
I used to feel the relationship between individual and community preparedness as a tension: I was one of the only people I knew who focused on prepping before Covid, and I wondered what the point of it was. I don’t believe in individualist survival, so what good is it if I, and only I, have a gas mask or a few months of dried food lying around? Then, come Covid, I learned what the point is. The point of being prepared, as an individual, is that you’re better situated to help your community. The more of my own shit I have sorted out, the less I need to rely on others and the more I’m able to help people. It’s one of those “please put on your own oxygen mask before assisting others” things.
|
||||
|
||||
Besides, having enough to share, even just a little bit to share, is incredibly rewarding. My mother caretakes my grandmother. When Covid hit, and the supply chain on N95 masks dried up, I was able to say to her “I have a few extras and I’ll get you one.” In that moment, I understood the advantage of individual preparation.
|
||||
|
||||
## **Some basic rules of preparation**
|
||||
|
||||
- The goal of being prepared is that, by having your own shit together, you’re more able to help others.
|
||||
- Gear is less important than skills. Skills are less important than relationships. All three matter and all three interrelate.
|
||||
- An abundance mindset will beat a scarcity mindset in the longterm more often than not. The best thing you can do for yourself, for your own self-interest, is build resilient communities.
|
||||
- Encourage people’s natural desire to work together during crisis. Err on the side of inclusion, not exclusion.
|
||||
- Having more of something that is good enough is better than having the single best, most expensive thing. The best way to upgrade your med kit is to get your friend a med kit so that there’s someone else around with a med kit.
|
||||
- Stockpile perishables that you use, and use what you stockpile.
|
||||
- Learn to favor practical clothes and tools.
|
||||
|
||||
## **Gear, skills, and relationships**
|
||||
|
||||
I love triangles. Strong shape, the triangle. Need an emergency shelter? Build a triangle. More importantly, it’s easier to avoid getting caught up in binary thinking when you think about ideas as sides of triangles instead of as opposite ends of various dichotomies.
|
||||
|
||||
So here’s a triangle—preparation is built on three sides: gear; skills; relationships.
|
||||
|
||||
Gear are physical resources: everything from backpacks and boots to water purifiers and dried rice, solar panels to power tools, quilts to cars. Gear is important. It’s not as important as people make it out to be, but it’s important. A lighter in your pocket and a knife on your belt can be the difference between life and death in any number of situations. In our consumerist society, preppers tend to fetishize gear: the lightest camping spoon, the most expensive rifle scope, the sharpest chainsaw, the strongest rope, the most tactical shoelaces. These things matter, sort of, but also they don’t. When you get gear, think about what is affordable, sturdy, and effective.
|
||||
|
||||
It’s okay, and useful, to gather physical resources while you can. The trick is to anticipate the next disaster rather than always just responding to the current one. Ideally, you want the respirator before the pandemic worsens and you want an electronic air filter before the wildfire smoke reaches your city. You want the backup generator or the solar setup before the grid fails. You want dried food stores before the stores run dry.
|
||||
|
||||
Skills matter more, of course. A tourniquet won’t save your life if no one around you knows how to use it. Yet preppers tend to dangerously fetishize skills as well. Most people will not become “preppers” full time. Most people will pursue new skills (and they should!) but won’t learn how to use everything. None of us will learn how to do everything. The thing people forget is that sometimes it’s okay to own gear you don’t know how to use. This isn’t universal, of course: don’t buy a gun to just keep it around, because owning a gun you don’t know how to use is more dangerous than not owning a gun. But maybe buy a tourniquet, or better yet an IFAK (individual first aid kit… the kits used to deal with massive trauma like gunshot wounds). Your IFAK is so that you can use it, sure, but it’s also so that the medic who responds when you’re shot can use it. Some stuff, it’s okay to get and learn how to use later. Get buckets full of dried beans while you can. Learn how to cook them later. Still, skills matter an awful lot.
|
||||
|
||||
Some skills relate to using or fixing gear, but other skills have little to nothing to do with gear. Conflict deescalation and group facilitation are as important as first aid and radio communication. Learn many skills to a basic level of competency, then dive deeper into certain skills as interest you, are underdeveloped in your community, or feel particularly relevant to the sorts of crises you think you might encounter. For example: if you can’t drive a car, maybe learn how to drive a car. If you can already drive a car, consider learning to drive stick, or a motorcycle, or commercial vehicles. If you want to step it up even further, learn evasive driving. Wouldn’t be cool if you knew how to fly a helicopter you find abandoned after the zombie apocalypse? Skills are useful at all kinds of different levels.
|
||||
|
||||
Relationships might matter the most. No one person can know everything, and even the most rugged individualist would fare better in most circumstances when working or coordinating with other people and larger structures. What people sometimes overlook is that building relationships is also something that involves work: learning how to communicate clearly and deal fairly with people, building trust and camaraderie, and learning to compromise and build consensus all take time and attention. Despite what capitalist society has led us to believe, healthy and genuine relationships are not transactional: preparedness relationships are not based on simple exchange like “I made him dinner, so he’ll fix my radios.” It’s closer to “I made him dinner while he was busy doing childcare for several people in the community, and some of those people help me fix my car when it breaks down.” Even at this larger scale, it’s still not transactional: maybe you’re just making dinner for him because he’s hungry and you hope he eats. There’s no need to keep track of who is contributing what, and cold calculations like that do not make for strong communities. Cold calculations make for competitive, instead of cooperative, interpersonal relations.
|
||||
|
||||
The goal should never be to specifically seek people out for their skillsets, but rather for who they are as people. You are not building a Dungeons & Dragons party: your goal isn’t to make friends with one surgeon, one veteran, one mechanic, and one farmer. Your goal is to develop healthy relationships with the people around you whether that’s your family, your neighbors, or those who share your values. Your goal is to foster their own preparedness, and together figure out what skills and capacities you have and are lacking.
|
||||
|
||||
Decolonialists and herbalists remind us that relationships are not just with people, but with the land, with plants, and with animals. Learning to listen to the environment is vital to survival and to avoid replicating the problems with mainstream society that have led us to this crisis in the first place—dominating the land (or your neighbors!) is not nearly so good as learning to be in relationship with it.
|
||||
|
||||
Not all of us are equally equipped to develop each of the three sides of this preparedness triangle. If you work all the time, leaving scant time for developing skills or even relationships, you can acquire gear—and use the few relationships you have to disseminate the gear more widely. If you are particularly non-social, you might be able to work on skills that allow you to be more independent. If you’re experienced at bringing people together, then maybe you can focus on relationships—and in particular, in tying people into community who might not normally have access to community.
|
||||
|
||||
When “the shit hits the fan” (it’s such a cliche that I have a hard time saying it outside of scare quotes: the shit is always hitting the fan for huge chunks of society. Poverty and marginalization are their own forms of apocalypse. And even the breakdown of larger society is rarely a fast event with clearly demarcated moments of “the shit hitting the fan.”) social and property relations become a lot more malleable. People who’ve never had community are likely to find themselves with community. And people without much access to financial resources can suddenly find themselves substantially more capable of getting the things they need—whether through looting, scavenging, or voluntary redistribution of resources. Skillshares become more common as well. So while preparedness is good, it’s important to remember it isn’t everything. The unprepared have a chance of surviving as well. Preparedness isn’t a magic bullet. Those who cannot prioritize it should not despair.
|
||||
|
||||
## **Scale**
|
||||
|
||||
Here’s another thing that is neither a hierarchy nor a dichotomy: scale of preparedness. Don’t think about “individual” or “short-term” preparedness as less important than larger scale and longer term preparedness. Conversely, don’t think only about yourself, or your immediate community.For me, because I like threes (an easy way to avoid dichotomies), I think about preparedness at three scales:
|
||||
|
||||
1. emergency: individual, short term;
|
||||
2. off-grid: community, medium-term; and
|
||||
3. grid reclamation: federation of multiple communities, long-term.
|
||||
|
||||
These three scales ought to each be considered for any given need. Take water for example. One ought to be prepared to store or filter water in case clean water becomes harder to come by. At the emergency level, you might have water storage tanks (or even your hot water heater and bathtub) or you might have various means of water purification. This could get you and your immediate circle through a short-term crisis. At the off-grid level, if municipal water stays unavailable, you might want to set up various gravity filter systems or stills to process rainwater or creek water. If you’re on the coast, you might look into homestead-scale desalination. These systems could last you months or years if setup and maintained properly. Yet it’s also worth thinking about how to restore water infrastructure more broadly, and move it from places where it is plentiful to places it is scarce. It’s worth reclaiming or rebuilding the grid.
|
||||
|
||||
This framework applies even better to food: for an emergency, maybe you’ve got stored food and a sense of what you can hunt or forage. For an off-grid life, you can garden. Yet there are vast fields of wheat and corn in the midwest of the United States, and there are trains, and tracks, and there are people alive who know how to get those hard-to-garden carbohydrates into those trains and there are people who can drive those trains and there are people who can repair railroad tracks, and there are people on the coasts in higher population density who need that food. The mutual aid and anarchist slogan “we keep us safe” applies. We who desire to be prepared need to stop thinking small—or rather, we need to stop only thinking small.
|
||||
|
||||
All the time people ask me how we can continue to make this or that object (eyeglasses, let’s say, or antibiotics). The answer is deceptively simple: we’ll just continue to make those things. Our economic system is not what grows and distributes food, nor conducts research, nor builds houses. People do. If anything, economic systems based on growth (like capitalism, or state communism as we’ve seen it) get in the way of people doing these things. By and large, the world has enough stuff in it to last quite some time, especially if our effort goes into maintaining and repairing the existing objects instead of mass-manufacturing more of them.
|
||||
|
||||
All of this is to say: revolution, and the radical restructuring of society, is absolutely a survival skill.
|
||||
|
||||
## **Dependence, independence, interdependence**
|
||||
|
||||
By now, you’ve probably picked up on how much I hate dichotomies. This one, though, I’m not replacing with a triangle. This one, both sides are absolute bullshit. Dependence on people on one side, and independence on the other side. Individualism on one side, community on the other side. No, no, no, no. This is all wrong. When we build this kind of dichotomy, we are fracturing the world. Some of us will be naturally more drawn to one side or the other of this dichotomy if you draw it, and for ethically defensible reasons. Some people, for good reason, look at the horrors and purges of Lenin and Stalin and say “never communism” (to reject communism because of state communism is to misunderstand communism, I would argue, but that’s besides the point). Others look at the horrors of capitalism and say “capitalism is a nightmare” and therefore embrace the authoritarian communism they perceive to be capitalism’s opposite. These people correctly understand capitalism, but they too misunderstand communism, or at least they misunderstand what it means to be an individual in a community.
|
||||
|
||||
Rather than being something that limits my liberty, participating in society is a precondition of my liberty. Freedom is not best understood as “me alone in the woods with no interference from anyone else.” If I was alone in the woods forever, I would die. Freedom is not a static thing, it is not “the lack of interference in our lives by others.” Freedom is instead a relationship between people. Freedom is something we give one another. If I want to be free to pursue my life as I best see fit (which I do), I am most capable of doing that when I’m part of a society that fosters not dependence of the individual upon “society” as an abstraction (as is the problem with some strains of authoritarian communism), nor one that fosters independence from society that puts me in competition with others in that society (as is the problem with capitalism), but one that fosters interdependence.In a healthy society, we rely on each other while also working to preserve each other’s autonomy. We create a culture of solidarity, in which we freely help one another, rather than a culture of competition or subservience.
|
||||
|
||||
## **Generalize and specialize**
|
||||
|
||||
To be useful to yourself and others, to foster interdependence, I recommend seeking to both generalize and specialize (another bullshit false dichotomy!). Study a lot of fields, and gather the basics of a lot of trades. Gathering a general education of practical skills is worth your time. From there, let yourself deep dive into what interests you more specifically.
|
||||
|
||||
By knowing the basics of cooking, you reduce your reliance on others. Reducing your reliance on others isn’t meant as a way to distance yourself from society, but instead to allow you to minimize your impact on others. Reducing your reliance on others, when you can, is itself a way of giving to the community. So if you can, learn the basics of cooking, of first aid, of survival, of conflict resolution, of self-defense, of transportation, of gardening, of mental health.
|
||||
|
||||
We’ll always rely on specialists as well. Feeding large crowds, or cooking extravagant and luxurious meals, is a specialized skill and it’s good some that some people develop those skills. Knowing how to stop bleeding is a generalist’s skill, while sewing people back together after the bleeding has stopped is a specialist’s skill. Surviving an overnight hike is a good generalist’s skill, while leading an expedition across a closed land border in winter might take a specialist.
|
||||
|
||||
## **Centralization versus decentralization**
|
||||
|
||||
While I’m talking shit on dichotomies, let me talk shit on centralization versus decentralization. Let’s break that one apart into another triangle: the self, the community, the society. This is not a hierarchy, of course. The needs of one side of this triangle do not outweigh the needs of another side.
|
||||
|
||||
Rather than demand centralization, for the sake of efficiency, or decentralization, for the sake of some misguided understanding of “freedom,” we ought to see how these three sides can find balance with one another—a balance that will be different for each person or each community and might shift from day to day, from year to year.Each of us has some things that we are capable of providing for ourselves and some things that we rely on our community, or society at large, to provide. The things we can provide for ourselves as individuals, we should. The things we can provide for our own community, we should. Some things we need to provide to people from society at large, and that’s fine. One small community might lack access to the ability to grow grain. Rather than demand decentralization, and that they either meet all their own needs internally (rugged individualism expanded to the small community level) or enter into some competitive system of capitalist exchange, they might have their needs met by society at large, through a system of mutual aid.
|
||||
|
||||
I’m no economist, and I could not tell you with any kind of certainty the exact model by which one person or community ought to relate economically to others. It’s probable that there’s no single right answer that ought to be applied on a worldwide level. You also don’t need to agree with me about the exact blueprint that some future society might hold. These are merely the ways that I like thinking about these things. I offer them to you so that you might decide for yourself which parts are useful and which parents aren’t.
|
||||
|
||||
## **Fuck the rugged frontiersman**
|
||||
|
||||
I hope, by now, I’ve convinced you to rid yourself of the bunker mentality, the “I’ve got mine, fuck you” approach to disaster preparedness. At the very least, I’m certain I’ve convinced you that I have no love for such an idea personally. Let me present to you another level of the same critique: fuck the rugged frontiersman. Fuck the extractive mentality. Settler culture in the US, which I’m absolutely a product of, has always maintained the myth, the archetype, of the rugged frontiersman. Armed with nothing but a hatchet, and a musket, and a bowie knife, and a broken treaty with the inhabitants of the area, and the might of a colonial army at his back, and maybe some people he’s enslaved, he sets off into the wilderness to conquer the aforementioned wilderness. All by… himself… sort of… not really.
|
||||
|
||||
The words “conquer” and “tame” appear quite often in tales of the rugged frontiersman. It’s a strange and terrible idea, to be so in love with wildness yet dedicating your life to “taming” that very wildness. Destroying what you claim to love.
|
||||
|
||||
Right up there with the bunker mentality, of unchecked individualism, is the rugged frontiersman mentality, of an unchecked extractive mentality.
|
||||
|
||||
The extractive mentality is the mentality, imposed upon us to varying degrees by western colonialist and capitalist thinking, that the world and its inhabitants are ours to be done with as we see fit. It’s this mindset that stripmines, it’s this mindset that factory farms. It’s this mindset that clearcuts. It’s this mindset that enslaves people, through chattel slavery or prison labor. It’s this mindset that colonizes lands and peoples. And importantly to our understanding about survival and preparation, it’s also this mindset that over-harvests wild medicinal plants and over-hunts game animals.
|
||||
|
||||
The inversion of this, of course, is a reluctance to ever make use of anything from nature. But the raw inversion of a bad idea is not in itself a better idea. Personally, I’m vegan and have been more than half my life. My veganism is a response to, and yes perhaps a dangerously raw inversion of, the extractive mindset as forced upon animals. I see a system of captivity and exploitation and I want to have nothing to do with it. So within the society we currently live in, that sees animals as nothing more than meat and fur waiting for death, I choose personally not to partake. This is a decision each of us must make on their own, and one that all of us will reach different conclusions about. Me being vegan does not solve the problem. Even the entire world going vegan doesn’t solve the problem, because the problem that I’m responding to isn’t “people kill and eat animals” but “some people treat animals like they treat everything else in this world: as resources to extract for value.”
|
||||
|
||||
The solution to extractive thinking is not abstinence. It’s okay to cut down trees when we need shelter. It’s okay to eat plants or animals when we’re hungry. The solution to extractive thinking is to avoid being wasteful, especially in the name of economic efficiency. The solution is to build relationships with the land in a similar, but not identical, way to how we build relationships with people. The solution is to see that we are in community with more than just other people, but with everything living and nonliving around us. Being in community means giving and it means taking. It means relating.If that sounds real weird to you, you’re not alone. It’s a hard transition to make, and it begs questions that no one, least of all myself, can offer you easy answers to.
|
||||
|
||||
Yet I offer to you that alongside the image of the man in the bunker, you must abandon the image of the man with a musket and a wilderness to tame. These are two sides of the same bad coin. On one side, the prepper who dreams of isolation, of making himself safe and free at the expense of his own connections to community. On the other side, there’s the prepper who dreams of a post-apocalyptic landscape because he sees it as a return to wildness—a wildness that he and his AR-15 and his night-vision goggles can tame.
|
||||
|
||||
The return to wildness itself, there’s something to that. But it’s not so that we can tame it, that we can colonize the burned-out 7-11s. So that we can relate to it. That we can see what it needs, and what we need, and how we can work together.
|
||||
|
||||
## **Threat modeling**
|
||||
|
||||
You aren’t going to be able to prepare for everything bad that could possibly happen. Trying to would destroy your mental health. Yet preparing is still worthwhile. So how do you decide what to prepare for?
|
||||
|
||||
The fancy word for this process is “threat modeling.” It just means thinking about the threats you face, and about what forms they might take, so that you can more rationally decide how to prepare yourself. If you live in Wyoming you shouldn’t worry about hurricanes much. If you live in North Carolina you might be more concerned with thunderstorms than earthquakes.
|
||||
|
||||
Sometimes good threat modeling means balancing your preparation based on your current active threat. For example: when you decide whether or not you want a gun, you need to think long and hard about what threats a gun helps keep you safe from and which threats it makes worse. If you struggle with depression, then the risk of self-harm might be higher than the risk of home intruders who want to kill you. (Even if you don’t struggle with depression normally, if anything happens to change that balance, you should be aware of it—even if you’re being threatened by fascists, if you go through a gnarly breakup, you might want to take the bolt out of your gun and give it to a friend for safe keeping). Are you more likely to be raided by the police for protest activity (in which case, having a gun might lower your chances of survival) or attacked by fascists (in which case, having a gun might increase your chances of survival)? Is it more likely that you will have to scare off wild hogs or that neighborhood kids might break into your remote cabin and accidentally hurt themselves with your gun?I’m using gun ownership as an example because it’s one of the more complicated questions for threat modeling, and one that requires active and ongoing thought. But the same might apply elsewhere. Do you push yourself to practice survival in dangerous situations, so that you can use those skills later? It likely depends on what sorts of threats you see yourself encountering.
|
||||
|
||||
Once you’ve thought about the threats you’re likely to face, and how you’d likely handle those threats, you can prioritize how you’d like to prepare. If you live in a remote area, you might be more concerned about shoring up your home preparation. In crowded areas, you might be looking how to stay on the move. If you’re worried about fascist takeover, you might prioritize community defense skills, or evasion, in ways that you wouldn’t if you are primarily concerned about natural disaster.
|
||||
|
||||
Of course, there is plenty that you can do to get prepared that applies to a wide number of scenarios. A half-mask respirator with particulate and organic vapor filters is effective against a lot of threats people have faced this year, such as wildfire smoke, airborne viruses, and riot control chemical weapons. A full-face gas mask with a CBRN filter is effective against all of those things too, plus biological and radiological crises. But in lieu of nuclear war, it might be overkill. So you might want to start with the half-mask respirator.
|
||||
|
||||
## **Peace of mind**
|
||||
|
||||
Done right, prepping can alleviate anxiety. Done poorly, it makes anxiety worse. The point of keeping a to go bag in the corner, packed and ready, is so that you don’t have to worry about what you would do in the case of a forest fire anymore. You know what you would do. You’re at least somewhat prepared. Done poorly, prepping leaves you constantly worrying about this or that disaster. It leaves you probing your strategies for any possible weaknesses, staying ever-vigilant. Hypervigilant. This isn’t healthy.
|
||||
|
||||
Prep so that you’re ready enough and then learn to forget about it.There’s a lot of criticism one can lay on gear, or skill, fetishism. But one advantage of talking about prepping, about thinking about gear and skills and talking about them with friends, is that you can move from worrying about disaster to geeking out about preparation. You really, really don’t need the super cool newest survival watch with built-in altimeter and a blood oxygen sensor. But geeking out about it is a natural method our brains use to turn something stressful to ponder into something enjoyable to ponder.
|
||||
|
||||
So if you can set-it-and-forget-it with your preparation, do that. But if your brain wants to linger on it, geek out about it. Pondering the insulation factors of various sleeping bags turns the horrors of imagining hypothermia into something abstract and interesting. It’s dangerous to turn everything into an abstraction, of course: watching people geek out and get excited about what bullets kill people the fastest and most effectively is disconcerting. Yet, when approached in a balanced way, that might be healthier than letting ourselves worry and stress instead.
|
@ -1,6 +0,0 @@
|
||||
# Mental Wealth
|
||||
|
||||
Link: https://jjbeshara.com/2020/06/04/mental-wealth/
|
||||
Status: Finished
|
||||
Tags: Mental Health
|
||||
Type: Article
|
154
Media/articles/Mental Wealth.md
Normal file
154
Media/articles/Mental Wealth.md
Normal file
@ -0,0 +1,154 @@
|
||||
---
|
||||
author:
|
||||
link: https://jjbeshara.com/2020/06/04/mental-wealth/
|
||||
status: not-finished
|
||||
image: https://i0.wp.com/jjbeshara.com/wp-content/uploads/2020/06/img_1962.png
|
||||
date: August 1, 2023
|
||||
---
|
||||
# Mental Wealth – James Beshara
|
||||
#mentalhealth #wellness #self-improvement
|
||||
_TL;DR_
|
||||
|
||||
• When it comes to mental health, our society approaches it like we did with physical health 50 years ago. We only think about it when something goes wrong.
|
||||
|
||||
• To the wider public, mental health is synonymous with mental illness. Our notion of physical health is, however, very different than our notion of physical illness.
|
||||
|
||||
• We might benefit from approaching mental health like we invest in anything else in our lives (finances, relationships, careers, physical health, etc), where one builds wealth in this area by continuous, conscious investment.
|
||||
|
||||
• Estimates say that 83% of us will be hit with a mental health crisis in our lives, we can all make the choices to invest wisely in this area to improve our ‘mental durability’ to deal with it properly.
|
||||
|
||||
• In my 19 years of paying close attention to mental health, my experience has taught me that there are five foundations towards a concept I will call ‘mental wealth’ — sleep, diet, exercise, stress management, and exogenous compounds (anything from coffee to alcohol to prescription medication).
|
||||
|
||||
• There are simple tips one can adopt for these five areas to invest in one’s mental wealth.
|
||||
|
||||
![](https://i0.wp.com/jjbeshara.com/wp-content/uploads/2020/06/img_1962.png?fit=640%2C434&ssl=1)
|
||||
|
||||
_The biggest risk in investing is not losing money; it’s missing out on the upside._
|
||||
|
||||
**After 19 years** of thinking about mental health, watching it go from hidden epidemic to a much discussed one, I still think there is a fundamental flaw in how we view mental health holistically.
|
||||
|
||||
To give a sense for how big of an issue this is, some estimate that 83% of people will have a life-interrupting event with mental illness at some point — from acute things like a panic attack to pervasive anxiety to bouts with depression or life-long symptoms of bipolar disorder (depression alone is the leading cause of disability for working age adults in America). \[[1](https://www.thecut.com/2017/02/most-people-experience-mental-health-problems-at-least-once.html)\]
|
||||
|
||||
When I say these terms and diagnoses, I want to point out that we don’t really know what they are or what they mean… we have names for them (and those names change about every 20-30 years, like the term PTSD, which has consistently changed over the last few decades), but we don’t really know what they mean. Like our medical terms “spina bifida” (split spine in Latin) or “arthritis” (meaning “joint”), we are accustomed to naming symptoms in our culture, with fancy sounding names, but we often have no idea what we’re really pointing to when it comes to causes or what is going on beneath that symptom. And we don’t really know how to treat the underlying causes of these, especially when it comes to mental illness symptoms. Outside of the recent scientifically based interest in psychedelics, pharmacology has all but abandoned it as a field of study. This is evidenced by the fact that you could have been a psychiatrist in 1999, left medicine for 20 years, and come back… and it would be the same prescriptions that you would write today as you did 20 years ago. This is not hyperbole, there genuinely has been almost an institutional abandonment of these confounding, complex illnesses by the pharmaceutical companies that are the most incentivized to make headway into such widespread epidemics and illnesses.
|
||||
|
||||
But here’s the shift in thinking I’ve had in recent years — which is that we only think about mental health in terms of illnesses.
|
||||
|
||||
When it comes to our mental health, as a society, we’re where we were 50 years ago with regards to physical health. In other words, we pay attention to it when something is wrong. And we fix (and name) symptoms instead of pursuing an understanding of the underlying issues.
|
||||
|
||||
Having trouble falling asleep? Oh, that’s called insomnia. Here’s a pill.
|
||||
|
||||
Feeling sad for more than two weeks straight? Oh that’s depression. Oh it’s really bad? It’s clinical major depression. Well, the singular important goal is to feel happy in life, so let’s fix it and try these 10 drugs sequentially to see if any of them work.
|
||||
|
||||
Panic attack? “Oh that’s, when panic of some sort sets in, and it feels like it’s attacking you. I’m a psychiatrist — four syllables and a shit-ton of medical school, so I know what I’m doing. Doctors 50 years ago might have prescribed (literally prescribed) cigarettes to pregnant women. Doctors back then, LOL. We’re all totally in control of the landscape of your physical and mental health now though… Here is something that will relieve the discomfort of that thing that we medically call a ‘panic attack.’”
|
||||
|
||||
In trying to think about why we have such little humility when it comes to physical and mental health within our medical professional realms, I struggle to find an answer (when history has shown us that it’s prudent to have a healthy dose of it). Perhaps the equation of 12 years of schooling, mounting student debt, and charging you $300 for a visit is not an inviting situation for the words “I don’t know.”
|
||||
|
||||
Still — I want to be clear that there is great work being done by countless medical professional individuals and groups. And there is great work, _amazing_ work being done in the realms of destigmatization and non-medical interventions with approaches like cognitive behavioral therapy (CBT), dialectical behavioral therapy (DBT), among others. And these are creating the current environment where we can explore these topics in the abstract collectively — or the acute symptoms we are feeling with loved ones and therapists alike with more positive encouragement from others than ever before, and that helps us zoom in on our individual underlying root causes… and for better or worse, it seems more and more clear that optimal mental health is an individual sport.
|
||||
|
||||
However, we still have a long way to go on these fronts as well. Today, from a first symptom of major depression to treatment, the average timespan is 10 years. From the first insomnia symptom to a discussion with your doctor is 15 years. Progress is being made, but we have a long way to go in continued open, public dialogue and destigmatization of these common ailments. So when you get a chance to talk about your direct or indirect experience with a mental illness, seize the opportunity to talk about it openly. There’s never been more receptivity to open dialogue than now.
|
||||
|
||||
Though the destigmatization and personalization of each person’s direct and indirect experience has allowed us to zoom in more openly on one illness or another, my shift in the last few years has been to zoom out.
|
||||
|
||||
Instead of symptoms or treatment, which much smarter people than myself are focusing tirelessly on, I’d like us to collectively zoom out to a viewpoint similar to where we are with physical health — more and more in the preventative realm rather than solely the treatment realm. More and more physical healthcare dialogue centers around things like leading indicators of illnesses (like high blood pressure, diet and nutrition, and the most innovative and head-turning fields are in longevity)… quite literally the long-view on health and prevention of the most destructive of physical illnesses.
|
||||
|
||||
I think it’s time for us to view mental health in that same light, something I call “Mental Wealth” rather than mental health… where it’s not a term synonymous with illness, but is an area in which even the mentally healthiest of us can still pay close attention. Can still invest in. And can increasingly raise our consciousnesses around (for ourselves and those around us), when “an ounce of prevention is worth a pound of cure.”
|
||||
|
||||
It goes from a lens of “fixing” to “investing” — in other words, instead of _fixing_ something that is by implication broken, it’s _investing in its durability_ to withstand the wear and tear that comes with modern life. And this begins well before the internal or external life-interrupting event itself (in fact, that is the whole point).
|
||||
|
||||
For example, instead of just thinking about fixing an acute financial problem like personal debt, wiser heads are thinking about _investing_ in the optimal outcome with almost every economic decision; financial freedom.
|
||||
|
||||
Instead of fixing a mental illness when it comes across your path, it’s investing in the optimal goal with daily and weekly habits beginning as a teenager; mental freedom. After all, optimal outcomes are planned years and decades in advance. We have this understanding in other investments in our lives… financial, career, relationships, acquired skills, hobbies, etc, and we’re starting to have that with regards to mental health, and I want to further encourage that with the concept of mental wealth.
|
||||
|
||||
So what does investing in mental health look like?
|
||||
|
||||
Well, there are very few generic pieces of financial investing advice (the details and application of those details are where the yield is) — but I still think we can establish and normalize some fundamental areas, and as someone that has paid close attention to this cross-lattice work of interweaving disciplines for a while now (but is wholly not an expert on any one of them), I will kick this conversation off with what I’ve noticed.
|
||||
|
||||
_Side-bar: Why has our medical system conventionally only cared about acute care when something goes wrong? It’s because the Western medical system evolved from medical treatments during warfare. In 2020, our medical system is phenomenal at acute interventions like surgery, and this is because the first medical professionals were surgeons saving a soldier’s life (or fixing a less terminal issue) so they could fight again in the next battle. 150 years ago, there was no consultation with the village doctor on prevention of disease. There was no discussion with a scientifically informed expert on approaches to optimal health or longevity. It was on the basis of… “I have a problem. Can you fix it?” This is in contrast to Eastern approaches like Ayurvedic medicine that is primarily focused on prevention versus cure, and though it is not well understood by Western medicine (and lacks the amazing progress we’ve made on acute treatments among other favorable comparisons towards Western medicine), it predates our mainstream medical acknowledgment of diet, exercise, and lifestyle by a few thousand years (going back as far as 6,000 BCE). You’d have to ask a scholar of why they were so attuned to this “investment” versus “fixing” attitude 8,000 years ago, but it may have something to do with the Hindu tradition of revering the human form as an expression of God (versus something akin to a proto-slavery culture in the Judeo-historical sense or the “inherently broken compared to the perfection of God” in the classical Christian viewpoint. After all, before there was a medical profession, it was the village priest or rabbi that one saw for assistance with an ailment, be it physical or mental)._
|
||||
|
||||
_Note: This concept and this list below are not meant to be points of “reference” that stand the test of time. The concept of mental wealth is meant to be a point of “departure” from how we conventionally think of mental health (ie, synonymous with mental illness)._
|
||||
|
||||
Here are the five areas that I have spoken about in piecemeal in various episodes of the podcast and cover a few times in my book last year — and they are in this order:
|
||||
|
||||
\*Sleep
|
||||
|
||||
\*Diet
|
||||
|
||||
\*Exercise
|
||||
|
||||
\*Stress Management
|
||||
|
||||
\*Exogenous Compounds
|
||||
|
||||
And all five are inter-related. In other words, are you not sleeping well? Audit what you’ve been eating or drinking (from those 3 glasses of wine before bed to a caffeinated drink at 4pm) to whether you have been exercising to sufficiently tire your body out before bed.
|
||||
|
||||
Really stressed? Try exercising. Really stressed and you’re getting plenty of exercise? By drinking a few cocktails before bed each night, that can disrupt your sleep, tiring you out the next day requiring more caffeine or more coffee that then keeps you too stimulated to fall asleep, and therefore, you feel the need for your nightly drinking routine.
|
||||
|
||||
So, let’s go over them again, and the two big takeaways I’d like you to have is just the _order_ of paying attention to them in addition to the fact that they _inter-relate_ — so in your own personal audit of all five, you can see which levers might be affecting the others. I will also add the biggest pro-tips from medical professionals and researchers that I’ve received over the years for each.
|
||||
|
||||
\*Sleep
|
||||
|
||||
\*Diet
|
||||
|
||||
\*Exercise
|
||||
|
||||
\*Stress Management
|
||||
|
||||
\*Exogenous Compounds (from coffee to melatonin to Prozac to LSD, and anything in between)
|
||||
|
||||
Starting with _sleep_, my biggest pro-tip towards mental wealth here _is that waking up every morning at the same time is perhaps the best professional and personal advice I’ve ever received_.
|
||||
|
||||
Your body operates on a 24-hour circadian rhythm, so your energy isn’t just tied to the hours of sleep you get. It’s tied to an entire 24-hour cycle and rhythm that your body is biologically designed for. To get into a solid 24-hour rhythm, do the mental calculus on when that morning time would be for you (and it’s ok to break from this once a week, but even then, it is better to wake up at that time and take a nap later in the day). Let’s say it’s at 8:15am every morning, and you have a really late night that goes until 2am on a Friday night. Still, wake up at 8:15am on Saturday for a few hours, then fall asleep again as a nap for an hour if needed.
|
||||
|
||||
And by sticking to that biological alarm clock, you continue to reinforce it for all the days you want to wake up at that time. You will start to naturally, almost without fail, wake up at that time within 8-9 days of trying this out. So it doesn’t take very long to set this rhythm (and from personal experience, I can say that 2-3 days of waking up at different times is all it takes to get out of rhythm or reset the rhythm to another time).
|
||||
|
||||
There are fantastic books written on the topic of sleep, so if I try to go beyond one or two pro-tips, this will become too long, but check out books like “Why We Sleep” or even make an appointment with a trained sleep therapist to go further into this first foundational element of mental wealth.
|
||||
|
||||
Second, we have _diet_, and there are even more great scientific works on diet and nutrition in recent years (on things like an anti-inflammatory diet, eating whole foods, etc), but I am going to center my two pro-tips on this next foundational element of mental wealth on two things:
|
||||
|
||||
1) Get your food allergens checked and make sure you’re not consuming foods that your allergic to on a regular basis (I used Everlywell.com for their at home food allergy test recently, and it was great). This is my most recent pro-tip on here, but at 32-years-old, I found out that I was allergic to eggs… a food I would eat _every_ _single_ _morning_. The inflammatory response in our bodies to foods we’re allergic to (when it comes to mental and physical health) is like subjecting yourself to an infection or cold each day; if you’re consuming that food regularly. So first pro-tip on diet — figure out what foods you’re allergic to and avoid them.
|
||||
|
||||
2) Consuming multiple alcoholic drinks before bed can absolutely wreck your sleep, which is the first foundation to mental wealth.
|
||||
|
||||
So here is the first area in which one foundation is inter-related to the other. You can actually destroy the quality of your sleep with things like heavy meals or high carb meals before bed as well, but nothing is as scientifically pronounced than immoderate alcohol consumption (for me, it’s anything more than 1-2 drinks, and I’ll see it in my sleep tracker) before bed.
|
||||
|
||||
So my diet pro-tips are nixing your allergens and nixing alcohol before bed, especially excessive alcohol consumption.
|
||||
|
||||
Third up is _exercise_. I could go in many directions with this one, everything from weight training being one of the best ways for you to support the production of ATP (the body’s fuel currency and where we actually get energy from) to the fact that exercise improves mood, your metabolism, and sleep quality, but I’m going to zero in on the anti-inflammatory effects of high intensity aerobic exercise 3 times a week (which incorporates improvement to mood, detoxification, and anti-inflammation).
|
||||
|
||||
So this is all about using a stair-master or elliptical, cycling, or high intensity running for anywhere from 15-30 minutes, etc. 3x per week. Cycling has been shown to be superior to running for the aerobic effects, so I use our family’s Peloton for 20 min HIIT rides at least 3x a week, preferably more.
|
||||
|
||||
_Side bar: Over the last decade, perhaps the most interesting scientific discoveries in my view, when it comes to mental health, have been primarily in two areas: psychedelics and inflammation. The first is pharmacologically interesting and the second is biologically interesting (with the second being the increased understanding that there is a strong relationship between inflammation in the body and our body’s mental health response). Inflammation is linked to everything from anxiety to depression to bipolar disorder. An anti-inflammatory diet, one that someone like Dr. Andrew Weil (who’s been on my podcast promotes is a great approach here), but I think an anti-inflammatory lifestyle that includes regular high intensity aerobic exercise is a powerful addition your diet._
|
||||
|
||||
Try this for 4 weeks and see what it does for your mental health (and your sleep).
|
||||
|
||||
Next up is _stress management_. From meditation to building and maintaining social connections to gratitude journaling to exercise as a form of stress management, this one is coming into the foreground more and more each year.
|
||||
|
||||
My pro-tip here would be that finding time to sit quietly for 15 minutes in the morning, with your cup of coffee or tea in-hand, to do three primary things has been extremely helpful for me:
|
||||
|
||||
1) Gratitude journaling of 5 things that I’m grateful for (nothing is too small here, from the sunrise to the laugh of my daughter will make the list),
|
||||
|
||||
2) 2-3 minutes of breathing exercises (google 4-7-8 breathing for a really simple breath work exercise),
|
||||
|
||||
3) Lastly, 5 minutes outline my to do list for the day. Taking thoughts out of your head and putting them to paper is so profoundly powerful for me. It’s like my mind gets to say “ok, great, I don’t have to keep track of all that anymore” when I put it on paper or in my digital to do list (and I just use the reminders app on my phone). My mind thanks me every time I lessen its burden with this practice.
|
||||
|
||||
In the effort towards simplicity over comprehensiveness, I won’t get into meditation here, but there are many other ways to naturally mitigate and limit stress (a few other personal favorites in this bucket are practicing the ‘art of undercommiting,’ being honest at _all_ times, and morning meditation) — but if proactive stress mitigation is new for you, I don’t think there’s anything better to start with than gratitude journaling, physical to-do lists, and breathing exercises (after all, breathing is one of the only activities that is both voluntary and involuntary for the body, so it’s a way for you to communicate with the involuntary system).
|
||||
|
||||
You can also add the benefits of disconnecting to dopamine-inducing social media or fear-inducing mainstream news media to this list (you can read more about my viewpoint here; “[The](https://jjbeshara.com/2018/11/20/the-information-pathology-2/) [Information Pathology”](https://jjbeshara.com/2018/11/20/the-information-pathology-2/)).
|
||||
|
||||
And just to build on the point that these are in a prioritized list — no matter how much you meditate or practice a stress management / mitigation technique, it won’t make much of a difference on your mental wellbeing if you are only sleeping two hours a night if your body requires 7 or 8.
|
||||
|
||||
Alright, last up… _exogenous compounds_. Sorry for the lame, long term, but I haven’t found a better one.
|
||||
|
||||
As someone that wrote an entire book on this topic (“[Beyond Coffee](http://beyondcoffeebook.com/)”) and started a side-project of my morning concoction ritual, I could tell you the pro-tip here is to read my book… But that’s not my pro-tip.
|
||||
|
||||
My pro-tip here is much simpler and a lot less work… it’s that these things, whether it’s a 5-hour energy shot, a Magic Mind shot, that third coffee, popping a melatonin pill before bed, or leaning on Xanax for anxiety… my pro-tip here is that any of these, from the innocuous to the Schedule II prescription, should be _last_ on the list of your personal “mental wealth” audit.
|
||||
|
||||
In other words, it’s part of the personal audit, but the body of scientific literature that exists out there suggests strongly that this bucket should come after the fundamentals like sleep, diet, exercise, and stress management are properly managed.
|
||||
|
||||
So there you go.
|
||||
|
||||
A proposed shift in how we think about mental health as a society, from _fixing_ to _investing_ toward mental wealth — followed by some practical viewpoints on what that investment strategy could look like.
|
||||
|
||||
I hope you’ve found this interesting (and hopefully even useful).
|
||||
|
||||
From knowing financially uber-successful people in my career that plunge into depths of misery the moment they find out about a health crisis, there’s truth to the phrase “health is wealth”… However, if I balance that with also knowing athletes at their peak of physical health and still finding themselves in a daily, hidden depression — or knowing a paraplegic neighbor with one of the most consistent smiles and maybe the most consistent psychological/spiritual warmth I’ve ever come across — along with my own direct and indirect experience with mental illness, it makes me question our conventional notion that “health is wealth”… and makes me think that maybe, more accurately, “mental health is wealth.”
|
@ -0,0 +1,58 @@
|
||||
---
|
||||
status: not-finished
|
||||
link: https://www.youtube.com/watch?v=VLZjd_Y1gJ8
|
||||
author: John Jackson
|
||||
date: April 23, 2020
|
||||
---
|
||||
# Recreating Noitas Sand Simulation in C and OpenGL | Game Engineering
|
||||
#C++ #OpenGL #Game #Engine #Games
|
||||
Exploring and attempting to recreate Noitas "Falling-Sand" Simulation from scratch using C and OpenGL.
|
||||
|
||||
Be sure to like and subscribe, you cool people. That way I can continue to make more vids
|
||||
like this.
|
||||
|
||||
NOTE: Theres a typo @2:07. I wrote "bytes" when it should be "bits" for the gs_vec2, color_t, and b32 member variables for the particle struct. So the overall size should be *drastically* different (only 24 bytes in total). Sorry for the confusion!
|
||||
|
||||
00:00 - Introduction
|
||||
00:33 - Gunslinger
|
||||
00:58 - Research/Resources
|
||||
01:13 - Cellular Automata
|
||||
01:52 - Sand Algorithm
|
||||
03:15 - Water
|
||||
05:25 - Wood/Walls
|
||||
05:53 - Fire
|
||||
06:32 - Gunpowder/Salt/Lava/Oil/Acid
|
||||
07:37 - Polish/UI/Drag-Drop Images
|
||||
08:56 - Final Sand Sim Presentation / Exploding Pictures
|
||||
|
||||
Project source:
|
||||
https://github.com/GameEngineering/EP01_SandSim
|
||||
|
||||
Gunslinger:
|
||||
https://github.com/MrFrenik/gunslinger/
|
||||
|
||||
Get Noita:
|
||||
https://store.steampowered.com/app/881100/Noita/
|
||||
|
||||
Get Powder Toy:
|
||||
https://powdertoy.co.uk/
|
||||
|
||||
Music:
|
||||
Blue Dot Sessions - Lakdeside Path: https://www.sessions.blue/?fwp_sessions=duck-lake
|
||||
|
||||
Resources Used:
|
||||
Nolla Games GDC: https://www.youtube.com/watch?v=prXuyMCgbTc&t=0s
|
||||
Noita Gameplay Showcase - https://www.youtube.com/watch?v=1pUItG5RUTM&t=0s
|
||||
Noita Technical Explanation - https://www.youtube.com/watch?v=0We8a8AFPp8&t=0s
|
||||
Game Of Life: https://www.youtube.com/watch?v=ouipbDkwHWA&t=84s
|
||||
Game Of LIfe: https://www.youtube.com/watch?v=C2vgICfQawE&t=322s
|
||||
|
||||
Stuff To Read:
|
||||
https://medium.com/starts-with-a-bang/it-from-bit-is-the-universe-a-cellular-automaton-4a5b1426ba6d
|
||||
https://80.lv/articles/noita-a-game-based-on-falling-sand-simulation/
|
||||
https://maxbittker.com/making-sandspiel
|
||||
|
||||
Special Thanks:
|
||||
Guilherme Teres from Uniday Studio: https://www.youtube.com/channel/UCntWQfGQ_KN4ABafiwSiuGA/featured
|
||||
|
||||
Everyone in my Discord channel. Thanks for hanging around and being awesome.
|
52
Media/articles/S.O.L.I.D. Principles - DEV Community.md
Normal file
52
Media/articles/S.O.L.I.D. Principles - DEV Community.md
Normal file
@ -0,0 +1,52 @@
|
||||
---
|
||||
author: twitter:Trekhleb
|
||||
link: https://dev.to/trekhleb/s-o-l-i-d-principles-around-you-1o17
|
||||
status: not-finished
|
||||
date: August 2, 2023
|
||||
---
|
||||
# S.O.L.I.D. Principles Around You - DEV Community
|
||||
#programming #software-development #object-oriented-design
|
||||
![Cover image for S.O.L.I.D. Principles Around You](https://res.cloudinary.com/practicaldev/image/fetch/s--twyS3ck3--/c_imagga_scale,f_auto,fl_progressive,h_420,q_auto,w_1000/https://dev-to-uploads.s3.amazonaws.com/i/0qazxkim2uf50lnwjkhx.png)
|
||||
|
||||
In this article, I want to briefly go through [SOLID](https://en.wikipedia.org/wiki/SOLID_(object-oriented_design)) principles (the acronym that stands for five basic principles of object-oriented programming and design) supplying each of them with real-world visual examples to make those principles more understandable, readable and memorizable.
|
||||
|
||||
> If you want to see code examples instead you may take a look at [variety of tree data structure implementations](https://github.com/trekhleb/javascript-algorithms/tree/master/src/data-structures/tree) in **JavaScript** like [Binary Search Tree](https://github.com/trekhleb/javascript-algorithms/tree/master/src/data-structures/tree/binary-search-tree), [AVL Tree](https://github.com/trekhleb/javascript-algorithms/tree/master/src/data-structures/tree/avl-tree), [Red-Black Tree](https://github.com/trekhleb/javascript-algorithms/tree/master/src/data-structures/tree/red-black-tree), [Segment Tree](https://github.com/trekhleb/javascript-algorithms/tree/master/src/data-structures/tree/segment-tree) or [Fenwick Tree](https://github.com/trekhleb/javascript-algorithms/tree/master/src/data-structures/tree/fenwick-tree).
|
||||
|
||||
So let’s move on!
|
||||
|
||||
## [](https://dev.to/trekhleb/s-o-l-i-d-principles-around-you-1o17#s-single-responsibility-principle)S — Single Responsibility Principle
|
||||
|
||||
\[a.k.a [SRP](https://en.wikipedia.org/wiki/Single_responsibility_principle)\] A class should have only a single responsibility. Only one potential change in the software’s specification should be able to affect the specification of the class.
|
||||
|
||||
[![Single Responsibility Principle](https://res.cloudinary.com/practicaldev/image/fetch/s--Qh1_I3hH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/xabfs57cezxegih8uh2f.png)](https://res.cloudinary.com/practicaldev/image/fetch/s--Qh1_I3hH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/xabfs57cezxegih8uh2f.png)
|
||||
|
||||
## [](https://dev.to/trekhleb/s-o-l-i-d-principles-around-you-1o17#o-openclosed-principle)O — Open/Closed Principle
|
||||
|
||||
\[a.k.a [OCP](https://en.wikipedia.org/wiki/Open/closed_principle)\] Software entities should be open for EXTENSION, but closed for MODIFICATION. Allow behavior to be extended without modifying the source code.
|
||||
|
||||
[![Open/Closed Principle](https://res.cloudinary.com/practicaldev/image/fetch/s--pagpCyfX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/fv3xpd9kkfgntqby9eg6.png)](https://res.cloudinary.com/practicaldev/image/fetch/s--pagpCyfX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/fv3xpd9kkfgntqby9eg6.png)
|
||||
|
||||
## [](https://dev.to/trekhleb/s-o-l-i-d-principles-around-you-1o17#l-liskov-substitution-principle)L — Liskov Substitution Principle
|
||||
|
||||
\[a.k.a. [LSP](https://en.wikipedia.org/wiki/Liskov_substitution_principle)\] Objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program.
|
||||
|
||||
[![Liskov Substitution Principle](https://res.cloudinary.com/practicaldev/image/fetch/s--ArU0mGdu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/7wdzib8lqfq9bcstfqu3.png)](https://res.cloudinary.com/practicaldev/image/fetch/s--ArU0mGdu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/7wdzib8lqfq9bcstfqu3.png)
|
||||
|
||||
## [](https://dev.to/trekhleb/s-o-l-i-d-principles-around-you-1o17#i-interface-segregation-principle)I — Interface Segregation Principle
|
||||
|
||||
\[a.k.a. [ISP](https://en.wikipedia.org/wiki/Interface_segregation_principle)\] Many client-specific interfaces are better than one general-purpose interface. No client should be forced to depend on methods it does not use.
|
||||
|
||||
[![Interface Segregation Principle](https://res.cloudinary.com/practicaldev/image/fetch/s--58sXrCsO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/rnwds5cv5qcodlam1wc6.png)](https://res.cloudinary.com/practicaldev/image/fetch/s--58sXrCsO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/rnwds5cv5qcodlam1wc6.png)
|
||||
|
||||
## [](https://dev.to/trekhleb/s-o-l-i-d-principles-around-you-1o17#d-dependency-inversion-principle)D — Dependency Inversion Principle
|
||||
|
||||
\[a.k.a. [DIP](https://en.wikipedia.org/wiki/Dependency_inversion_principle)\] One should depend upon abstractions, not concretions.
|
||||
|
||||
- High-level modules should not depend on low-level modules. Both should depend on abstractions.
|
||||
- Abstractions should not depend on details. Details should depend on abstractions.
|
||||
|
||||
[![Dependency Inversion Principle](https://res.cloudinary.com/practicaldev/image/fetch/s--yw39zKqE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/wugaxuqznqow3wzgp8hr.png)](https://res.cloudinary.com/practicaldev/image/fetch/s--yw39zKqE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/wugaxuqznqow3wzgp8hr.png)
|
||||
|
||||
The plug doesn’t care which type of wire it uses, it just needs wires that conduct electricity.
|
||||
|
||||
I hope these illustrations have been useful for you :)
|
@ -1,8 +0,0 @@
|
||||
# Slavoj Žižek: Don't Act. Just Think. | Big Think
|
||||
|
||||
Author: Slavoj Žižek
|
||||
Link: https://youtu.be/IgR6uaVqWsQ
|
||||
Publishing/Release Date: August 28, 2012
|
||||
Score /5: ⭐️⭐️⭐️⭐️⭐️
|
||||
Status: Finished
|
||||
Type: Video
|
@ -0,0 +1,10 @@
|
||||
---
|
||||
author: Slavoj Žižek
|
||||
link: https://youtu.be/IgR6uaVqWsQ
|
||||
date: August 28, 2012
|
||||
rating: 5
|
||||
status: Finished
|
||||
---
|
||||
|
||||
# Slavoj Žižek: Don't Act. Just Think. | Big Think
|
||||
|
1013
Media/articles/The Company That Might End Privacy as We Know It.md
Normal file
1013
Media/articles/The Company That Might End Privacy as We Know It.md
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,7 +0,0 @@
|
||||
# The Economics of AI Today
|
||||
|
||||
Link: https://thegradient.pub/the-economics-of-ai-today/
|
||||
Score /5: ⭐️⭐️⭐️⭐️
|
||||
Status: Finished
|
||||
Tags: AI, Automation, Economics, Tech
|
||||
Type: Article
|
@ -1,6 +0,0 @@
|
||||
# The Elon Musk Post Series
|
||||
|
||||
Link: https://waitbutwhy.com/2017/03/elon-musk-post-series.html
|
||||
Status: Finished
|
||||
Tags: Entrepeneurship, Tech
|
||||
Type: Article
|
8
Media/articles/The Elon Musk Post Series.md
Normal file
8
Media/articles/The Elon Musk Post Series.md
Normal file
@ -0,0 +1,8 @@
|
||||
---
|
||||
link: https://waitbutwhy.com/2017/03/elon-musk-post-series.html
|
||||
status: finished
|
||||
---
|
||||
|
||||
# The Elon Musk Post Series
|
||||
|
||||
#entrpreneurship #tech
|
106
Media/articles/The Future of Design Systems is Semantic.md
Normal file
106
Media/articles/The Future of Design Systems is Semantic.md
Normal file
@ -0,0 +1,106 @@
|
||||
---
|
||||
author: Carly Ayres
|
||||
link: https://www.figma.com/blog/the-future-of-design-systems-is-semantic/
|
||||
status: not-finished
|
||||
date: July 27, 2023
|
||||
image: https://cdn.sanity.io/images/599r6htc/localized/10e55cde1be89fb32aa3d7414fa3cd83b0859a51-3264x1836.jpg?w=1632&h=918&q=75&fit=max&auto=format
|
||||
---
|
||||
# The Future of Design Systems is Semantic | Figma Blog
|
||||
|
||||
#design-systems #prototyping #variables
|
||||
|
||||
Variables, one of Figma’s newest features, help you streamline designs and connect more closely to code, but what do they tell us about larger shifts in the industry? We dig into what they might signal for the future of design systems.
|
||||
|
||||
In Figma, **variables** store reusable values that can be applied to all kinds of design properties and prototyping actions. They help save time and effort when building designs, managing design systems, and creating complex prototyping flows. [Learn more](https://help.figma.com/hc/en-us/articles/15339657135383-Guide-to-variables-in-Figma).
|
||||
|
||||
There were tons of big moments at Config 2023, but for those working with design systems—whether building them, maintaining them, or using them—one likely stood out from the rest: [**variables**](https://www.figma.com/blog/config-2023-recap/#with-variables-design-systems-speak-the-same).
|
||||
|
||||
Ever since we started supporting design systems, [the community has been asking us](https://youtu.be/yI9QVwkk2Go?t=564) to bring design tokens capability into Figma. This year, we finally made that wish come true with variables, which deliver on the same use case and more.
|
||||
|
||||
But more than just codifying design decisions, variables also _literally_ vary to unlock design theming and dynamic prototyping logic. As reusable and changeable values, this feature goes a step further than tokens in their holistic approach and signal a larger shift in how we design today. So, we sat down with the people working across design systems tooling both inside and outside Figma to understand what the rise of tokens and features like variables mean for the future of design systems.
|
||||
|
||||
### [Token primer](https://www.figma.com/blog/the-future-of-design-systems-is-semantic/#token-primer)
|
||||
|
||||
If youre already familiar with tokens, you can [skip ahead](https://www.figma.com/blog/the-future-of-design-systems-is-semantic/#introducing-variables). If you’re new, check out Design Systems Advocate Jina Anne’s introduction in this video, aptly titled [WTF are Design Tokens?](https://www.youtube.com/watch?v=q5qIowMyVt8)
|
||||
|
||||
Picture this: You’ve just been tasked with reining in your product’s color palette. The product has been around for a whopping _15 years_—relatively unheard of in the app space—and has been touched by quite a few folks before your time. Still, though. How many colors could there _really_ be? Fifty? A hundred? How many colors are there in the world, anyway? Turns out, a lot. When an intrepid team of designers at Google Maps [took on a similar project](https://design.google/library/exploring-color-google-maps), they discovered that the tool had over 700 colors and, a year later, winnowed that palette down to 25 hues.
|
||||
|
||||
With subtle tones and transparency effects removed, bold colors now clearly distinguish map details.
|
||||
|
||||
That’s impressive, but what keeps them from ballooning back into the many hundreds again? How do you maintain a color system that is meant to encapsulate the entire world? The Google Maps team turned to **design tokens** as a way to document and distribute their new, more limited palette.
|
||||
|
||||
#### [The token origin story](https://www.figma.com/blog/the-future-of-design-systems-is-semantic/#the-token-origin-story)
|
||||
|
||||
\*Salesforce is widely considered the “design token pioneer.” In a 2014 article published in [Salesforce Designer](https://medium.com/salesforce-ux), Salesforce UX Vice President Sönke Rohde described how the company uses design tokens to apply the same design principles across multiple platforms and software. ([UXPin](https://www.uxpin.com/studio/blog/what-are-design-tokens/#:~:text=name%20a%20few.-,Where%20did%20Design%20Tokens%20Come%20From%3F,across%20multiple%20platforms%20and%20software.), 2022)
|
||||
|
||||
Design tokens—or _tokens_, for short—have been rattling around the design systems space since early 2014.\* Tokens are bits of data that represent small, repeatable design decisions such as border radii, sizing, typography, or colors. By separating design properties from specific components or implementation details, they allow for a more versatile, platform-agnostic approach. Elements such as color, number, and string can have multiple values, or tokens, that can be easily updated across a product (or several), reducing redundancy and maintaining consistency wherever they are used. So, if you have to change the color of _all the trees_, that change can be made in one place and reflected everywhere else. (Great for managing [rising complexity](https://www.figma.com/blog/the-future-of-design-systems-is-complicated/), right?)
|
||||
|
||||
“The new color system helps our users better understand the world around them, while aligning it to the Google palette sets us apart and builds brand equity,” says Director of UX Sang Han, who worked on [the project](https://design.google/library/exploring-color-google-maps). “Because the system is easier to update, it also positions our team to keep moving the brand forward.”
|
||||
|
||||
When a variable acting as a global token is updated, then everything downstream changes, too.
|
||||
|
||||
#### [Introducing variables](https://www.figma.com/blog/the-future-of-design-systems-is-semantic/#introducing-variables)
|
||||
|
||||
Product designer and design systems pro Joey Banks shared an extensive [deep dive into variables](https://medium.com/@joeyabanks/a-guide-to-variables-in-figma-b500b80d4e4) with tips and shortcuts to make the most of the new feature.
|
||||
|
||||
Like tokens, [variables in Figma](https://help.figma.com/hc/en-us/articles/15339657135383-Guide-to-variables-in-Figma) store reusable values that can be applied across designs. However, their _variability_ inherently broadens their potential for use: In addition to implementing design tokens, variables and modes enable teams to switch designs between different contexts—such as light and dark themes, different languages, or screen sizes. Variables can also reference _other_ variables, making it easier to update all the little details—be that padding, color, radii, or spacing—that exist within a system.
|
||||
|
||||
“In my mind, variables is a much broader concept, and tokens are one flavor of that,” says Lauren LoPrete, design systems expert. At Dropbox, her design systems team beta-tested the feature, leveraging it for their token system. She also sees wider applications with [regards to localization](https://twitter.com/figma/status/1671563500546842625) in its ability to represent various strings, letting users swap between content in multiple languages. More broadly, she says that variables can help free up her teams time by empowering other teams who might want to quickly build and prototype new ideas or implementations.
|
||||
|
||||
> In my mind, variables is a much broader concept, and tokens are one flavor of that.
|
||||
|
||||
Lauren LoPrete, design systems expert
|
||||
|
||||
The ability to introduce flexibility—and with that _complexity_—to design systems (like how the colors of an entire app surface may change in dark mode), means _less_ maintenance for design systems managers. “I’m excited to see a big reduction in the amount of overhead that those managing design systems will need to deal with,” says Tom Lowry, Design Advocate Manager at Figma. “For years, I’ve worked with teams who have tried to solve this with complex multi-library setups, unruly component sets where color modes like light or dark are defined as variants, or even bespoke plugins. Instead, a designer can now work on a UI in dark or light mode depending on their own preference and, at any point in time, switch to see what it looks like in the other mode.”
|
||||
|
||||
### [Closing the gap between design and code](https://www.figma.com/blog/the-future-of-design-systems-is-semantic/#closing-the-gap-between-design-and-code)
|
||||
|
||||
Variables are also _communication tools_, establishing a [shared language](https://www.figma.com/blog/the-shared-language-of-props/) between design and development. Design as a whole has been [taking cues from code](https://www.figma.com/blog/taking-cues-from-code/) for years, but variables mark yet another step toward minimizing the gap between the two. Additionally, Figma’s [REST API](https://www.figma.com/developers/api#variables), with read and write access for variables, and [Plugin API](https://www.figma.com/plugin-docs/working-with-variables/) open the doors for a variety of ways to connect variables in Figma to tokens in code, even bidirectionally—from querying and reading to creating and deleting, as well as binding them to components.
|
||||
|
||||
![phone ui showing basket with three items, the add more icon is connected to a blue variables icon and a mouse is seen setting the variable to "cart number"](https://cdn.sanity.io/images/599r6htc/localized/0e33919ac2ff1ecaf5c2e46a967d0a9888eed786-1608x1206.png?w=804&h=603&q=75&fit=max&auto=format)
|
||||
|
||||
Community members have even built fully working versions of [Flappy Bird](https://twitter.com/DavidWilliames/status/1672919178259628033) and [Jeopardy](https://twitter.com/lalizlabeth/status/1674153486588551169?s=46&t=_Qb4j1zsCAafRnX8ECz9tg) using prototyping with variables.
|
||||
|
||||
Perhaps the most direct example of that narrowing gap exists in Figma’s new prototyping capabilities, enabled by variables. Variable values can be set and modified with [prototyping actions](https://help.figma.com/hc/en-us/articles/14506587589399-Use-variables-in-prototypes) to create fully functional prototypes that respond to user input. The stored values can be combined with expressions to generate dynamic string values, perform basic math operations with number values, or evaluate boolean expressions—similar to code. But, of course, without the code. This breaks down barriers so that _anyone_ familiar with the feature can build a successful prototype, test their ideas, and gather the necessary feedback to evaluate if it’s worth building.
|
||||
|
||||
“One of our design team’s principles is to _empower creativity through flexibility_,” shares Lauren. “Before variables, our system was so rigid that consumers werent able to manipulate it in a way that wouldnt break the system completely or revert to a hard-coded solution. Variables helped us introduce more flexibility, so we can hand over some of the keys of that system to the people actually making the products.” She cites one example where her team was able to give their Growth team a playground with variables to A/B test different calls-to-action and pop-up colors, in order to optimize for their own goals.
|
||||
|
||||
[**A/B testing**](https://en.wikipedia.org/wiki/A/B_testing) (also known as bucket testing, split-run testing, or split testing) is a user experience research methodology consisting of a randomized experiment that usually involves two variants (A and B).
|
||||
|
||||
While the concept of the linear product design process with clean handoffs (or high-fives) [has long been something of a myth](https://www.figma.com/blog/welcome-to-the-wip/), those loosely defined phases will continue to collapse further into themselves and into each other. “It still feels like theres a fence that you throw your work over and an engineer picks it up on the other side,” says Lauren. “I’d like to see that get to a place where its a much more collaborative or shared process.” As design and code drift towards each other, roles and swim-lanes will blur together. Soon, steps might be skipped or eliminated entirely. Teams, collectively, will ship more, faster.
|
||||
|
||||
We don’t know what the future holds, but with the rise of AI, many in the community are wondering what types of processes might be automated entirely. “I wish I knew the future so that I could help guide my clients in those directions,” says Nathan Curtis, design systems architect and founder of the UX firm [EightShapes](https://eightshapes.com/). “But I will say this: Ive designed a button far more times than I would like to admit. Ive designed token taxonomies, what, 30 or 40 times and they all tend to have an action-color group and an alert-color group. They all have the same basic taxonomy choices and, sure, there are devilish things in the details, but broadly theyre the same patterns. So from that perspective, I dont anticipate many people paying me to do token taxonomies five years from now.”
|
||||
|
||||
### [Bringing more people into the process](https://www.figma.com/blog/the-future-of-design-systems-is-semantic/#bringing-more-people-into-the-process)
|
||||
|
||||
At the very least, these shifts suggest we’ll start seeing more people from a variety of roles and backgrounds building new products—which is a good thing. “Variables historically are very much a developer concept, and now were putting this interface around it that makes it more accessible for more people to be involved in that process,” says Tom. “Its not exclusive to design systems people working on design systems. Weve expanded the utility to where a content designer can come in and define terminology.”
|
||||
|
||||
And as Lauren adds, we _need_ different people to participate in the process—because the people who might have been great for spinning up or establishing a system might not be the same people who are great at maintaining, evolving, or driving adoption of that system. “You need a different set of skills,” she says. Her design system team at Dropbox includes technologists who prototype components, build them in React, and test them in code—alongside designers who focus on community and collaboration models, as well as operations people who ensure adoption and maintain feedback loops in service of the whole design organization.
|
||||
|
||||
![highres_variables_thumbnail.jpg](https://cdn.sanity.io/images/599r6htc/localized/f2ebf6b47224a3ac51e99a509b80e116424cf299-2560x1440.jpg?w=2560&h=1440&q=75&fit=max&auto=format)
|
||||
|
||||
### [One small step for design systems managers…](https://www.figma.com/blog/the-future-of-design-systems-is-semantic/#one-small-step-for-design-systems-managers)
|
||||
|
||||
For now, there’s still a long way to go. “Theres a really interesting opportunity to build more content design systems within the system, especially with the rise of AI-powered tools like [Ditto](https://www.dittowords.com/),” says Lauren. “Im really passionate about getting more voice and tone style guides into the tool where our consumers are. So the more best practices we can have built into Figma, the more productive our designers can be.”
|
||||
|
||||
Nathan agrees: “I see documentation websites diminishing, as more products like Figma that incorporate design systems provide that natively within the app. Over time, I anticipate more and more systems-oriented docs embedded within a tool like Figma so that people need not leave to go to a site to learn how to use things or make the right decision.”
|
||||
|
||||
“The vision \[for variables\] is much broader than whats supported today,” says Tom. “Any design decision that can be reused could be a variable, whether or not that fits in the scope of design tokens.” He cites localization (echoing Lauren’s point above) as one example, currently solved with tokens, but that opens the door for new approaches to standardizing language that could help teams make more informed decisions. Instead of wondering what a button should say, a team could pull up their content library where all product terms are defined, review all other ‘calls to action,’ and have a meaningful conversation about the role of the string in a particular use case.
|
||||
|
||||
The same goes for animation, typography, or any other design decision. “While we dont support this today, in the future, you might have a variable that supports an easing curve that could change based on use, say for an alert versus something more transactional,” says Tom. “Could you use variables within other variables? Could you create expressions that make a calculation based on variables for a value? Like a saturation function that consumes a variable from your system? There are so many ways that variables could help us create more complex, more dynamic designs. This is the start. Were not done.”
|
||||
|
||||
![home_OG.png](https://cdn.sanity.io/images/599r6htc/localized/6dd0b818bf5d087b52c4f01736ec167558efc67b-1200x630.png?w=1200&h=630&q=75&fit=max&auto=format)
|
||||
|
||||
![](https://cdn.sanity.io/images/599r6htc/localized/a67e01fa282a548ebda4a2fa9ff93d4668a092df-451x451.png?w=451&h=451&q=75&fit=max&auto=format)
|
||||
|
||||
Carly Ayres is a writer and editor on Figmas Content & Editorial team. Previously, she worked on Google Design and ran a small design studio. Her words have appeared in Its Nice That, Communication Arts, Wallpaper\*, Core77, and elsewhere. 🤠
|
||||
|
||||
## Subscribe for a Shortcut to fresh news and fun surprises
|
||||
|
||||
I agree to opt-in to Figmas mailing list.
|
||||
|
||||
## More on the future of design systems
|
||||
|
||||
## Create and collaborate with Figma
|
||||
|
||||
[Get started for free](https://www.figma.com/signup?locale=en)
|
@ -1,6 +0,0 @@
|
||||
# The Secretive Company That Might End Privacy as We Know It
|
||||
|
||||
Link: https://www.nytimes.com/2020/01/18/technology/clearview-privacy-facial-recognition.htm
|
||||
Score /5: ⭐️⭐️⭐️⭐️⭐️
|
||||
Status: Finished
|
||||
Type: Article
|
108
Media/articles/The Strange Case of Dr. Ho Man Kwok.md
Normal file
108
Media/articles/The Strange Case of Dr. Ho Man Kwok.md
Normal file
@ -0,0 +1,108 @@
|
||||
---
|
||||
author: Michael Blanding
|
||||
link: https://news.colgate.edu/magazine/2019/02/06/the-strange-case-of-dr-ho-man-kwok/
|
||||
status: not-finished
|
||||
date: August 1, 2023
|
||||
image: https://news.colgate.edu/magazine/wp-content/uploads/sites/6/2019/02/MSG-OpenerFinal11-copy.jpg
|
||||
---
|
||||
# The Strange Case of Dr. Ho Man Kwok | Colgate Magazine
|
||||
#medical #food #history
|
||||
_Illustrations by James Steinberg_
|
||||
|
||||
---
|
||||
|
||||
**A medical hoax leads to a 50-year mistruth about MSG and an unexpected Colgate connection.**
|
||||
|
||||
---
|
||||
|
||||
_Since the initial reporting of this story, information has come to light calling into question Howard Steel’s role in the MSG controversy. For more on this fascinating story, listen to [This American Life episode #668](https://www.thisamericanlife.org/668/the-long-fuse)._
|
||||
|
||||
The letter was just a few paragraphs long. Published in the _New England Journal of Medicine_ (_NEJM_) under the heading “Chinese-Restaurant Syndrome,” it began: “For several years since I have been in this country, I have experienced a strange syndrome whenever I have eaten out in a Chinese restaurant.” It went on to describe symptoms including “numbness in the back of the neck, gradually radiating to both arms and the back, general weakness, and palpitation.”
|
||||
|
||||
For the next couple of paragraphs, the writer speculated on the cause of his ailments, suggesting that perhaps it was due to the food’s high sodium content or some ingredient in soy sauce or cooking wine. “Others have suggested,” he continued, “that it may be caused by the monosodium glutamate used to a great extent for seasoning in Chinese restaurants.” The letter ended with an appeal to other doctors to conduct more research and was signed “Robert Ho Man Kwok, MD, Senior Research Investigator, National Biomedical Research Foundation, Silver Spring, Md.”
|
||||
|
||||
Professor [Jennifer LeMesurier](https://www.colgate.edu/facultysearch/FacultyDirectory/jennifer-lemesurier) first heard about the letter in 2013, when she and her husband were watching an episode of the PBS show _The Mind of a Chef_ with David Chang, featuring Japanese ramen noodles. LeMesurier perked up when a guest mentioned the controversy over monosodium glutamate (MSG), a food additive in Asian cuisine that has long had a harmful reputation. Not true, the guest said, MSG was perfectly safe — and, in fact, the whole controversy had started with one letter to the _NEJM_ back in the 1960s that bogusly claimed MSG caused illness.
|
||||
|
||||
“It was a throwaway line,” remembers LeMesurier, an assistant professor of writing and rhetoric at Colgate. Yet, it made her curious. Could a decades-long food controversy really have started with one letter? Then a graduate student at the University of Washington, LeMesurier went to the medical library the next day where, sure enough, she found the missive in an old issue of _NEJM_ from April 4, 1968. Wondering if there had ever been any response, she began to pull subsequent issues of the journal and found a cascade of other letters that either detailed their writers’ own unfortunate run-ins with Chinese food, or ridiculed the whole idea. Both types of letters had one thing in common, however — a disturbing undercurrent of racism that seemed to blame the unsavoriness of Chinese food rather than the chemical itself for its supposed effects. “You would expect doctors to be very clinical, but this quickly veered into ethnic name-calling,” LeMesurier said.
|
||||
|
||||
She published her findings last February in a paper titled, “Uptaking Race: Genre, MSG, and Chinese Dinner,” in _Poroi: An Interdisciplinary Journal of Rhetorical Analysis and Invention_. In it, LeMesurier argues that the racist distrust of MSG snowballed through the media to create a hysteria over the additive that has continued to the present day. In detailing the outsized effects that letter has had, though, she never doubted its authenticity — until a few months later.
|
||||
|
||||
In January 2018, LeMesurier was shocked when she listened to a voicemail message. The caller identified himself as Dr. Howard Steel ’42, a Colgate alumnus and former trustee. “Boy, have I got a surprise for you,” he said. “I am Dr. Ho Man Kwok.”
|
||||
|
||||
## A Fateful Wager
|
||||
|
||||
It started out as a bet. In 1968, Steel was a young orthopedic surgeon at Shriner’s Hospital and a professor at Temple University in Philadelphia. Another doctor, Bill Hanson, used to rib Steel about his specialty, saying orthopedic surgeons were too stupid to get published in a prestigious journal such as the _NEJM_. In fact, he bet Steel $10 he couldn’t make it into its pages. “That was a threat, and he was willing to make a buck,” said Steel in an interview earlier this year, before he passed away in September at the age of 97.
|
||||
|
||||
[![Illustration of two doctors shaking hands, one with his fingers crossed in his other hand](http://news.colgate.edu/magazine/wp-content/uploads/sites/6/2019/02/MSGDocsSpotFinal-1.jpg)](http://news.colgate.edu/magazine/wp-content/uploads/sites/6/2019/02/MSGDocsSpotFinal-1.jpg) At the time, Steel and Hanson used to go to a Chinese restaurant called Jack Louie once a week, drinking too much beer and overeating — invariably feeling sick afterward. Following one of those episodes, Steel had a fit of inspiration. “I decided, well, I’ll write a little article and send it to the _New England Journal of Medicine_,” Steel said. “I’ll make it so obvious, they will know immediately \[that it’s fake\].” After penning the notorious letter, he signed it Robert Ho Man Kwok, which he thought would be an obvious play on words.
|
||||
|
||||
“It was a breakdown of a not-nice word we used when someone was a jerk,” Steel said. “We called them a human crock of you-know-what.” If anyone needed further proof that the letter was a spoof, he also made up a fake medical institution, the National Biomedical Research Foundation of Silver Spring, Md. “It doesn’t exist.”
|
||||
|
||||
A few weeks later, when the letter was actually published under the title “Chinese-Restaurant Syndrome,” Steel was pleased with himself and promptly went to Hanson to pay up. Lest anyone think the phenomenon was real, Steel contacted the letters editor to tell him it was “a big fat lie,” he said. When he didn’t hear back, Steel called the journal’s editor, Franz Ingelfinger. “I told him it was a bunch of junk, it was all fake, it was all made up, and he hung up the phone on me,” Steel claimed. The brush-off was even more surprising, considering he knew Ingelfinger from his boyhood in Atlantic City (see “[A Charmed Life](#charmed)”).
|
||||
|
||||
**As LeMesurier researched the journal, she discovered that _NEJM_ actually had a long tradition of such “comic syndrome letters.”**
|
||||
|
||||
After the _NEJM_ published his letter, Steel watched with a mix of humor and horror as the MSG controversy unfolded, with dozens more letters to the editor responding to his original. He persisted in calling the publication’s office, leaving messages for Ingelfinger without response. A current spokesperson for the _NEJM_ can’t confirm whether or not the publication considered pulling the letter. “Due to the fact that it was published 50 years ago … we can’t comment or speculate on its publication, or the purported refusal at the time to retract it,” responded Julia Agresto, a media relations and communications specialist, via e-mail. Today, she said, letters are peer reviewed on a “case-by-case basis,” but she does not know if Steel’s letter was peer reviewed. “However, we would imagine that it was not,” she wrote.
|
||||
|
||||
Years later, as LeMesurier read all of the MSG letters, she tried to parse their subtle mix of earnestness and dry humor. One of them, published May 16, 1968, by H. Schaumburg of Albert Einstein College, claimed that he, too, “on three occasions experienced a tightening of my masseter and temporalis muscles, lacrimation, periorbital fasciculation, numbness of the neck and hands, palpitation, and syncope” within 20 minutes of eating Chinese food. The overly scientific phraseology (lacrimation means crying) is the first clue that Schaumburg may have been writing with tongue in cheek, and LeMesurier’s suspicions only grew when she read that he and his companions had “consumed twenty-four ounces of beer” before one episode, and that he would be “delighted to submit a grant, perhaps a career development award, to the National Institutes of Health for an intensive study (with foreign travel funds) of this problem.”
|
||||
|
||||
As LeMesurier researched the journal, she discovered that _NEJM_ actually had a long tradition of such “comic syndrome letters,” as one observer called them: missives that used pretentious medical language to poke fun at a common problem. One letter, for example, decried the “cryogenic cephalagia” — otherwise known as “brain freeze” — that accompanied drinking slushies. The letters about Chinese-restaurant syndrome, however, seemed different. Rather than focus in on the symptoms of the supposed ailment, they increasingly focused on the fact that it was associated with Chinese food — with some writers apparently “in on the joke” while others weren’t.
|
||||
|
||||
## The Truth about MSG
|
||||
|
||||
MSG is a naturally occurring food substance, with a distinctive savory taste known by Japanese as umami. “It’s a chemical the same way water is a chemical,” said LeMesurier, who is herself of Korean descent, raised by white parents. “If you have ever eaten aged cheese or heirloom tomatoes, you’ve eaten MSG.” Its powdered form was created in 1908 by a chemist in Japan, and it made its way with Chinese immigrants to the United States, where it was commonly added to dishes in Chinese restaurants.
|
||||
|
||||
[![man eating with chopsticks while steam in the shape of dragons circles his face](http://news.colgate.edu/magazine/wp-content/uploads/sites/6/2019/02/MSG-OpenerFinal11-copy.jpg)](http://news.colgate.edu/magazine/wp-content/uploads/sites/6/2019/02/MSG-OpenerFinal11-copy.jpg) Despite the fact that MSG appears in everything from flavored potato chips to Parmesan cheese, the letter writers universally described experiencing symptoms after eating foods such as “egg foo yung” or “duck sauce.” One writer described what he called his “Chinese headache.” Another detailed aching in the arms after eating egg rolls. A definitive note from the _NEJM_ editor even targeted one specific Boston restaurant, Yee Hong Guey, for its adverse effects and coined the mock-scientific term post-cibal-sinal (roughly “after eating Chinese”) syndrome as an official name for the ailment.
|
||||
|
||||
Although LeMesurier doesn’t think the writers were being overtly racist, she believes they were picking up on larger stereotypes in the culture of Asian Americans as exotic and strange. “They had a supposed subject, the Chinese-Restaurant syndrome, but the focus was really on Chinese identity and getting in digs about these stereotypically Chinese foods,” she said. “They used Kwok and MSG as figureheads for everything that was silly and frivolous and dangerous about Chinese identity.”
|
||||
|
||||
In that, they joined a long tradition of exoticism and mistrust of Chinese food, LeMesurier found. Since Chinese immigrants first appeared in America en masse in the mid-1800s, media has been ridiculing their food. A 19th-century cartoon depicts Chinese people eating rats, and many writers of the period similarly describe Chinese food as dirty or unclean — including Mark Twain, who refers to a Chinese grocer selling a “mess of birds’-nests” and sausages each containing “the corpse of a mouse.” The _NEJM_ letter writers picked up on these tropes, with one writer choosing the exotic bird’s-nest soup as a stand-in for all Chinese food and another referencing Chinese foods in a doggerel poem as a “vile miasma.”
|
||||
|
||||
**Although LeMesurier doesn’t think the writers were being overtly racist, she believes they were picking up on larger stereotypes in the culture of Asian Americans as exotic and strange.**
|
||||
|
||||
Ironically, while LeMesurier was researching her paper, she came across a reference to a real Dr. Robert Ho Man Kwok, who died in 2014, and she logically assumed he was the original letter writer. Many of the _NEJM_ letter writers at the time, however, made the same joke as Steel, playing on the word Kwok with “crock” — though it’s unclear whether they suspected the name was real or a pseudonym. The one letter that got closest to Steel’s ruse commented: “For certainly he is Dr. Human Crock, and his ‘Chinese-restaurant syndrome’ is totally illusory and nonexistent.”
|
||||
|
||||
However self-aware the letter writers were, the joke was totally lost on the mainstream media, which picked up the story almost immediately. A _New York Times_ article from May 19, 1968 — six weeks after Steel’s letter — took Chinese-restaurant syndrome at face value, noting that it had been first identified by “a Cantonese doctor named Robert Ho Man Kwok,” who had come to the United States “eight years ago.” How the _Times_ had gotten specific information about this doctor who didn’t exist is anyone’s guess. Like the _NEJM_ letter writers, the paper ignored MSG’s larger prevalence in food to focus squarely on Chinese cooking as the culprit for MSG’s ill effects, even interviewing Chinese restaurant owners around New York to defend their cuisine.
|
||||
|
||||
## A Cautionary Tale
|
||||
|
||||
From a made-up malady to “comic syndrome,” now problems with MSG had become a nationally recognized ailment. “The _New York Times_ and other national newspapers gave legitimacy to a lot of the stereotypes around Chinese cooking,” said Ian Mosby, a historian from York University in Toronto, who wrote a paper in _The Social History of Medicine_ in 2009 examining Chinese-restaurant syndrome.
|
||||
|
||||
That journalistic misunderstanding is unfortunate, but hardly surprising, said [Jeff Bary](http://www.colgate.edu/facultysearch/FacultyDirectory/jeff-bary), a Colgate [astrophysics](http://www.colgate.edu/academics/departments-and-programs/physics-astronomy) professor who teaches the course, “Saving the Appearances: Galileo, the Church, and the Scientific Endeavor,” about how prejudice in culture influences the way we talk about science. “It represents a lack of scientific literacy on the part of people in the media, not to be savvy enough to know the difference between a letter submitted like this and a true scientific study,” he said. At the same time, he added, cultural forces can predispose journalists and readers alike to believe in science that wasn’t necessarily true. “On the face of it, it’s pointing to racism in the culture that they are so willing to accept this negative perception of another culture’s food,” Bary said. “It’s a narrative that fits into a particular worldview.”
|
||||
|
||||
[![caution ticker tape coming out of a giant fortune cookie as people look on](http://news.colgate.edu/magazine/wp-content/uploads/sites/6/2019/02/MSG-Spot2Final1.jpg)](http://news.colgate.edu/magazine/wp-content/uploads/sites/6/2019/02/MSG-Spot2Final1.jpg) Ironically, however, once the media established that worldview, doctors then set about to prove it, coming full circle from treating Chinese-restaurant syndrome like a joke to studying it as a real phenomenon. In fact, the same letter writer who kidded about receiving “foreign travel funds” to investigate the syndrome, pharmacologist Herbert Schaumburg, conducted the first actual experiments exposing subjects to MSG. Along with his colleague, neurologist Robert Byck, he gave MSG intravenously to 13 people and orally to another 56, recording symptoms including burning, facial pressure, chest pain, and headache. Publishing their findings in _Science_ in February 1969, they concluded from this scant evidence that “Chinese-restaurant syndrome” was real. Other scientists followed with more studies, including some that injected large amounts of MSG into mice and monkeys, alleging long-term effects.
|
||||
|
||||
None of them could explain why a chemical that had always been in such common use was suddenly spawning such extreme reactions. “It would be safe to say that the studies were pretty poorly done,” Mosby said. “There were almost no double-blind studies.” In fact, other studies began appearing as soon as 1970, taking issue with the methods of Byck, Schaumburg, and other researchers. By then, however, Chinese-restaurant syndrome had caught on in the culture, and the general public began warily checking labels in an effort to cut MSG from their diets. Consumer advocate Ralph Nader even lobbied Congress to ban its use in baby food.
|
||||
|
||||
More recently, studies have roundly debunked the idea that MSG is harmful. Multiple studies using placebos have shown no difference in effects on people eating food with or without MSG. In 1995, the Food and Drug Administration asked an independent scientific group, the Federation of American Societies for Experimental Biology, to study MSG’s safety. It found that only a small number of people experienced any side effects, and that was only after consuming six times the normal serving of MSG on an empty stomach.
|
||||
|
||||
Contacted at Albert Einstein College of Medicine, Schaumburg stands by his research. “We don’t think this stuff is harmful, but it definitely has a pharmacological effect,” he said. “If you take it intravenously, everyone is going to have incredibly distressing symptoms.” Most people, Schaumburg continued, don’t have any consequences from MSG when they eat it because they don’t absorb it. A small number of people who absorb it more readily could have effects if they eat food with MSG on an empty stomach, “like wonton soup as an appetizer,” he said. Schaumburg took issue with the implication in LeMesurier’s paper that there was any kind of racism involved in how MSG is perceived.
|
||||
|
||||
**“It’s a narrative that fits into a particular worldview.” — Professor Jeff Bary**
|
||||
|
||||
No matter how many articles appear exposing the fallacy of Chinese-restaurant syndrome, prejudice against MSG persists. According to a survey by the International Food Information Council, an industry-funded nonprofit, 42 percent of the population still actively avoids MSG. That’s slightly less than the percentage who avoid artificial flavors and colors, but more than those who avoid caffeine, GMOs, or gluten. Major snack food brands such as Frito-Lay and Utz have apologetically posted information pages about the substance on their website and prominently display to consumers which of its products do and don’t contain MSG. Meanwhile, reviewers of Chinese restaurants on Yelp still complain about hearts racing and limbs tingling after eating.
|
||||
|
||||
For LeMesurier, the story of MSG is a cautionary tale of how a simple prejudice can seep its way into a culture, even from scientists who should know better. “A lot of times people get into medicine because they want to fix things, but sometimes the fixing becomes the goal rather than dealing with what is really going on in a situation,” she said. “Medical students need to understand the ethics of writing, especially when representing a culture or a person and talking about sensitive things.” When Steel contacted her soon after her paper came out, it only solidified her feelings. “In a weird way, it shows the power of these narratives, that this wasn’t based on any facts at all,” she said.
|
||||
|
||||
Steel maintained that his letter wasn’t intended to be racist, and — insisted that he never caused any real harm with the controversy he helped launch. “Everyone is eating Chinese food anyway,” he said. In that claim, at least, he is right. According to a recent survey by food research firm Technomic, Chinese is the most popular ethnic cuisine in America, just edging out Mexican and Italian. Even so, Steel was earnestly apologetic about the trouble he caused with his fake letter. “I wish I had never written the damn thing,” he said. Lest anyone think that he somehow profited from the mishap, however, he was quick to add that his erstwhile colleague Dr. Hanson never made good on their wager. “I never got the 10 bucks,” Steel said. “Bill never paid me a dime.”
|
||||
|
||||
---
|
||||
|
||||
[![Howard Steel ’42 fishing](http://news.colgate.edu/magazine/wp-content/uploads/sites/6/2019/02/Steel-fishing_high-re_bxw.jpg)](http://news.colgate.edu/magazine/wp-content/uploads/sites/6/2019/02/Steel-fishing_high-re_bxw.jpg)
|
||||
|
||||
Howard Steel ’42
|
||||
|
||||
## A Charmed Life
|
||||
|
||||
As improbable as the MSG controversy sounds, it was just one event in a life that reads like a page torn out of _David Copperfield_ or _Forrest Gump_. Howard Steel’s family started Steel’s Fudge on the Atlantic City Boardwalk, which still doles out fudge and salt water taffy to sunburned beachgoers today. Sadly, both of Steel’s parents died of separate diseases before he turned 5, leaving him an orphan in the care of an aunt, with an allowance from the bank. He excelled in both football and academics, earning acceptance to Harvard, Yale, Columbia, and Princeton — but the bank told him the schools were too expensive.
|
||||
|
||||
His high school English teacher, who was a Colgate alumnus, offered to drive him up to see the campus. When Steel spoke with the dean, the dean offered him admission along with a football scholarship on the spot, Steel remembered. He fell in love with the University, where he majored in [physics](http://www.colgate.edu/academics/departments-and-programs/physics-astronomy) and [chemistry](http://www.colgate.edu/academics/departments-and-programs/chemistry), and served as president of Theta Chi as well as president of his class.
|
||||
|
||||
Listening to a radio report about the deepening conflict of World War II, on Dec. 6, 1941, Steel enlisted in the Navy and convinced his fraternity brothers to join, too. The next day, Japan bombed Pearl Harbor. But Steel never saw combat. While in boot camp, another soldier accidentally shot in his direction, whizzing past his head and taking off part of Steel’s ear. The Navy gave him a Purple Heart, and then took it away when it realized he hadn’t been shot in combat.
|
||||
|
||||
After his service, Steel drifted down to Philadelphia, graduating with a medical degree from Temple University in an accelerated program of only two and a half years. He took up a residency at Temple University Hospital, and eventually was appointed chief of staff at Shriners in 1966, just before his fateful letter to the _NEJM_.
|
||||
|
||||
Steel went on to have a distinguished career as a surgeon, founding the first pediatric spinal injury center at Shriners and pioneering new surgical techniques. Some of his grateful patients pooled together their money to create a foundation in his name with more than a million dollars, which supports lecture series at orthopedic associations around the world.
|
||||
|
||||
For those who worked with him, Steel’s _joie de vivre_ left an indelible mark. In a 2012 video made about his legacy, colleagues called him “magnetic,” “charismatic,” and a “legend in the operating room.” During lectures to medical students, he would play The Beatles. And when he walked the halls, the toys and lollipops he had for his pediatric patients would be falling out of his white coat pockets. “Happiness should never be allowed to escape from the practice of medicine,” he said.
|
||||
|
||||
Steel, a Colgate trustee emeritus, died Sept. 5, 2018. He is survived by his wife, Elizabeth; five children, including Anna ’91; three stepchildren, Turner Cary Smith ’77, Celia Smith Carroll ’76, and Townsend Cary Smith ’81; son-in-law Brian Carroll ’76; 11 grandchildren; and two great-granddaughters.
|
@ -1,7 +0,0 @@
|
||||
# Ultimate Vim TypeScript Setup
|
||||
|
||||
Link: https://medium.com/swlh/ultimate-vim-typescript-setup-35b5ac5c8c4e
|
||||
Score /5: ⭐️⭐️
|
||||
Status: Finished
|
||||
Tags: Tech, Typescript
|
||||
Type: Article
|
30
Media/articles/Ultimate Vim TypeScript Setup.md
Normal file
30
Media/articles/Ultimate Vim TypeScript Setup.md
Normal file
@ -0,0 +1,30 @@
|
||||
---
|
||||
author: twitter:nikolalsvk
|
||||
link: https://medium.com/swlh/ultimate-vim-typescript-setup-35b5ac5c8c4e
|
||||
date: August 2, 2023
|
||||
rating: ⭐⭐
|
||||
image: https://miro.medium.com/v2/resize:fit:1100/format:webp/1*1bqKunmuJ7norWgYfqQGYQ.jpeg
|
||||
---
|
||||
# Ultimate Vim TypeScript Setup. How and why to use Vim for TypeScript… | by Nikola Đuza | The Startup | Medium
|
||||
#technology #coding #text-editors
|
||||
Vim is great. I have been using different text editors and IDEs through years, and Vim stuck with me through all hardships and happy times. Maybe because I invested much time in learning and fine-tuning it to my needs that it became a part of me, a bit.
|
||||
|
||||
> _I love Vim. It’s not easy to use. I love Vim anyway._
|
||||
>
|
||||
> _Maxin Cardamom_
|
||||
|
||||
With those lines, [one of the best Vim talks on YouTube starts](https://youtu.be/XA2WjJbmmoM?t=50). And it makes perfect sense. I remember being frustrated and asking why would anyone use Vim while I was learning it. But all that paid struggle off. If you are afraid of the Vim learning curve, I found this great [post](https://thoughtbot.com/blog/the-vim-learning-curve-is-a-myth) that proclaims you can learn Vim 30 minutes!
|
||||
|
||||
One of the main reasons why I use Vim as my editor is speed. And I do not mean the speed of writing code, which is also excellent. I am thinking of the reading speed of the code. Did you know that the [ratio of reading versus writing code is 10 to 1](https://www.goodreads.com/quotes/835238-indeed-the-ratio-of-time-spent-reading-versus-writing-is). That means that you are regularly reading old code to write new code. And with Vim, **reading** and **finding** old code has been the easiest and fastest for me!
|
||||
|
||||
I will explain in another blog post which plugins and shortcuts I use, so be sure to [subscribe to the newsletter](https://pragmaticpineapple.com/newsletter).
|
||||
|
||||
## VSCode vs. Vim
|
||||
|
||||
A lot of folks are using [Visual Studio Code](https://code.visualstudio.com/) for development. I do not blame them. I have used VSCode and [Visual Studio](https://visualstudio.microsoft.com/) and it is one of the best software that came out of Microsoft!
|
||||
|
||||
Most recently, I have been using VSCode for writing (and reading) [TypeScript](https://www.typescriptlang.org/) code. Why you’d ask? Well, before I made an ultimate Vim TypeScript setup, I had to use VSCode. The only reason why I used VSCode, was that Vim was too slow for editing TypeScript files.
|
||||
|
||||
Luckily, I have upgraded Vim to [8.2 version](https://www.vim.org/vim-8.2-released.php), and it started to be blazing fast once again. I ditched VSCode and moved back to Vim and [my .vimrc](https://github.com/nikolalsvk/dotfiles/blob/master/.vimrc).
|
||||
|
||||
If you are thinking about the two, I would say to use Vim, but I am probably biased. [VSCodeVim](https://github.com/VSCodeVim/Vim) lets you combine the best of two worlds…
|
@ -1,5 +1,300 @@
|
||||
# Values, Types, and Operators
|
||||
---
|
||||
author: Marijn Haverbeke
|
||||
link: https://eloquentjavascript.net/01_values.html
|
||||
status: not-finished
|
||||
date: August 2, 2023
|
||||
image: https://eloquentjavascript.net/img/chapter_picture_1.jpg
|
||||
---
|
||||
# Values, Types, and Operators :: Eloquent JavaScript
|
||||
#programming #computer-science
|
||||
[◀](https://eloquentjavascript.net/00_intro.html) [◆](https://eloquentjavascript.net/index.html) [▶](https://eloquentjavascript.net/02_program_structure.html)
|
||||
|
||||
Link: https://eloquentjavascript.net/01_values.html
|
||||
Status: Reading
|
||||
Type: Article
|
||||
## Chapter 1Values, Types, and Operators
|
||||
|
||||
> Below the surface of the machine, the program moves. Without effort, it expands and contracts. In great harmony, electrons scatter and regroup. The forms on the monitor are but ripples on the water. The essence stays invisibly below.
|
||||
|
||||
![Picture of a sea of bits](https://eloquentjavascript.net/img/chapter_picture_1.jpg)
|
||||
|
||||
Inside the computer’s world, there is only data. You can read data, modify data, create new data—but that which isn’t data cannot be mentioned. All this data is stored as long sequences of bits and is thus fundamentally alike.
|
||||
|
||||
_Bits_ are any kind of two-valued things, usually described as zeros and ones. Inside the computer, they take forms such as a high or low electrical charge, a strong or weak signal, or a shiny or dull spot on the surface of a CD. Any piece of discrete information can be reduced to a sequence of zeros and ones and thus represented in bits.
|
||||
|
||||
For example, we can express the number 13 in bits. It works the same way as a decimal number, but instead of 10 different digits, you have only 2, and the weight of each increases by a factor of 2 from right to left. Here are the bits that make up the number 13, with the weights of the digits shown below them:
|
||||
|
||||
0 0 0 0 1 1 0 1
|
||||
128 64 32 16 8 4 2 1
|
||||
|
||||
So that’s the binary number 00001101. Its non-zero digits stand for 8, 4, and 1, and add up to 13.
|
||||
|
||||
Imagine a sea of bits—an ocean of them. A typical modern computer has more than 30 billion bits in its volatile data storage (working memory). Nonvolatile storage (the hard disk or equivalent) tends to have yet a few orders of magnitude more.
|
||||
|
||||
To be able to work with such quantities of bits without getting lost, we must separate them into chunks that represent pieces of information. In a JavaScript environment, those chunks are called _values_. Though all values are made of bits, they play different roles. Every value has a type that determines its role. Some values are numbers, some values are pieces of text, some values are functions, and so on.
|
||||
|
||||
To create a value, you must merely invoke its name. This is convenient. You don’t have to gather building material for your values or pay for them. You just call for one, and _whoosh_, you have it. They are not really created from thin air, of course. Every value has to be stored somewhere, and if you want to use a gigantic amount of them at the same time, you might run out of memory. Fortunately, this is a problem only if you need them all simultaneously. As soon as you no longer use a value, it will dissipate, leaving behind its bits to be recycled as building material for the next generation of values.
|
||||
|
||||
This chapter introduces the atomic elements of JavaScript programs, that is, the simple value types and the operators that can act on such values.
|
||||
|
||||
## Numbers
|
||||
|
||||
Values of the _number_ type are, unsurprisingly, numeric values. In a JavaScript program, they are written as follows:
|
||||
|
||||
13
|
||||
|
||||
Use that in a program, and it will cause the bit pattern for the number 13 to come into existence inside the computer’s memory.
|
||||
|
||||
JavaScript uses a fixed number of bits, 64 of them, to store a single number value. There are only so many patterns you can make with 64 bits, which means that the number of different numbers that can be represented is limited. With _N_ decimal digits, you can represent 10N numbers. Similarly, given 64 binary digits, you can represent 264 different numbers, which is about 18 quintillion (an 18 with 18 zeros after it). That’s a lot.
|
||||
|
||||
Computer memory used to be much smaller, and people tended to use groups of 8 or 16 bits to represent their numbers. It was easy to accidentally _overflow_ such small numbers—to end up with a number that did not fit into the given number of bits. Today, even computers that fit in your pocket have plenty of memory, so you are free to use 64-bit chunks, and you need to worry about overflow only when dealing with truly astronomical numbers.
|
||||
|
||||
Not all whole numbers less than 18 quintillion fit in a JavaScript number, though. Those bits also store negative numbers, so one bit indicates the sign of the number. A bigger issue is that nonwhole numbers must also be represented. To do this, some of the bits are used to store the position of the decimal point. The actual maximum whole number that can be stored is more in the range of 9 quadrillion (15 zeros)—which is still pleasantly huge.
|
||||
|
||||
Fractional numbers are written by using a dot.
|
||||
|
||||
9.81
|
||||
|
||||
For very big or very small numbers, you may also use scientific notation by adding an _e_ (for _exponent_), followed by the exponent of the number.
|
||||
|
||||
2.998e8
|
||||
|
||||
That is 2.998 × 108 = 299,800,000.
|
||||
|
||||
Calculations with whole numbers (also called _integers_) smaller than the aforementioned 9 quadrillion are guaranteed to always be precise. Unfortunately, calculations with fractional numbers are generally not. Just as π (pi) cannot be precisely expressed by a finite number of decimal digits, many numbers lose some precision when only 64 bits are available to store them. This is a shame, but it causes practical problems only in specific situations. The important thing is to be aware of it and treat fractional digital numbers as approximations, not as precise values.
|
||||
|
||||
### Arithmetic
|
||||
|
||||
The main thing to do with numbers is arithmetic. Arithmetic operations such as addition or multiplication take two number values and produce a new number from them. Here is what they look like in JavaScript:
|
||||
|
||||
|
||||
$100 + 4 * 11 $
|
||||
|
||||
The `+` and `*` symbols are called _operators_. The first stands for addition, and the second stands for multiplication. Putting an operator between two values will apply it to those values and produce a new value.
|
||||
|
||||
But does the example mean “add 4 and 100, and multiply the result by 11,” or is the multiplication done before the adding? As you might have guessed, the multiplication happens first. But as in mathematics, you can change this by wrapping the addition in parentheses.
|
||||
|
||||
|
||||
$(100 + 4) * 11$
|
||||
|
||||
For subtraction, there is the `-` operator, and division can be done with the `/` operator.
|
||||
|
||||
When operators appear together without parentheses, the order in which they are applied is determined by the _precedence_ of the operators. The example shows that multiplication comes before addition. The `/` operator has the same precedence as `*`. Likewise for `+` and `-`. When multiple operators with the same precedence appear next to each other, as in `1 - 2 + 1`, they are applied left to right: `(1 - 2) + 1`.
|
||||
|
||||
These rules of precedence are not something you should worry about. When in doubt, just add parentheses.
|
||||
|
||||
There is one more arithmetic operator, which you might not immediately recognize. The `%` symbol is used to represent the _remainder_ operation. `X % Y` is the remainder of dividing `X` by `Y`. For example, `314 % 100` produces `14`, and `144 % 12` gives `0`. The remainder operator’s precedence is the same as that of multiplication and division. You’ll also often see this operator referred to as _modulo_.
|
||||
|
||||
### Special numbers
|
||||
|
||||
There are three special values in JavaScript that are considered numbers but don’t behave like normal numbers.
|
||||
|
||||
The first two are `Infinity` and `-Infinity`, which represent the positive and negative infinities. `Infinity - 1` is still `Infinity`, and so on. Don’t put too much trust in infinity-based computation, though. It isn’t mathematically sound, and it will quickly lead to the next special number: `NaN`.
|
||||
|
||||
`NaN` stands for “not a number”, even though it _is_ a value of the number type. You’ll get this result when you, for example, try to calculate `0 / 0` (zero divided by zero), `Infinity - Infinity`, or any number of other numeric operations that don’t yield a meaningful result.
|
||||
|
||||
## Strings
|
||||
|
||||
The next basic data type is the _string_. Strings are used to represent text. They are written by enclosing their content in quotes.
|
||||
|
||||
\`Down on the sea\`
|
||||
"Lie on the ocean"
|
||||
Float on the ocean
|
||||
|
||||
You can use single quotes, double quotes, or backticks to mark strings, as long as the quotes at the start and the end of the string match.
|
||||
|
||||
Almost anything can be put between quotes, and JavaScript will make a string value out of it. But a few characters are more difficult. You can imagine how putting quotes between quotes might be hard. _Newlines_ (the characters you get when you press enter) can be included without escaping only when the string is quoted with backticks (`` ` ``).
|
||||
|
||||
To make it possible to include such characters in a string, the following notation is used: whenever a backslash (`\`) is found inside quoted text, it indicates that the character after it has a special meaning. This is called _escaping_ the character. A quote that is preceded by a backslash will not end the string but be part of it. When an `n` character occurs after a backslash, it is interpreted as a newline. Similarly, a `t` after a backslash means a tab character. Take the following string:
|
||||
|
||||
"This is the first line\\nAnd this is the second"
|
||||
|
||||
The actual text contained is this:
|
||||
|
||||
This is the first line
|
||||
And this is the second
|
||||
|
||||
There are, of course, situations where you want a backslash in a string to be just a backslash, not a special code. If two backslashes follow each other, they will collapse together, and only one will be left in the resulting string value. This is how the string “_A newline character is written like `"`\\n`"`._” can be expressed:
|
||||
|
||||
"A newline character is written like \\"\\\\n\\"."
|
||||
|
||||
Strings, too, have to be modeled as a series of bits to be able to exist inside the computer. The way JavaScript does this is based on the _Unicode_ standard. This standard assigns a number to virtually every character you would ever need, including characters from Greek, Arabic, Japanese, Armenian, and so on. If we have a number for every character, a string can be described by a sequence of numbers.
|
||||
|
||||
And that’s what JavaScript does. But there’s a complication: JavaScript’s representation uses 16 bits per string element, which can describe up to 216 different characters. But Unicode defines more characters than that—about twice as many, at this point. So some characters, such as many emoji, take up two “character positions” in JavaScript strings. We’ll come back to this in [Chapter 5](https://eloquentjavascript.net/05_higher_order.html#code_units).
|
||||
|
||||
Strings cannot be divided, multiplied, or subtracted, but the `+` operator _can_ be used on them. It does not add, but it _concatenates_—it glues two strings together. The following line will produce the string `"concatenate"`:
|
||||
|
||||
"con" + "cat" + "e" + "nate"
|
||||
|
||||
String values have a number of associated functions (_methods_) that can be used to perform other operations on them. I’ll say more about these in [Chapter 4](https://eloquentjavascript.net/04_data.html#methods).
|
||||
|
||||
Strings written with single or double quotes behave very much the same—the only difference is in which type of quote you need to escape inside of them. Backtick-quoted strings, usually called _template literals_, can do a few more tricks. Apart from being able to span lines, they can also embed other values.
|
||||
|
||||
\`half of 100 is ${100 / 2}\`
|
||||
|
||||
When you write something inside `${}` in a template literal, its result will be computed, converted to a string, and included at that position. The example produces “_half of 100 is 50_”.
|
||||
|
||||
## Unary operators
|
||||
|
||||
Not all operators are symbols. Some are written as words. One example is the `typeof` operator, which produces a string value naming the type of the value you give it.
|
||||
|
||||
```js
|
||||
console.log(typeof 4.5)
|
||||
|
||||
console.log(typeof "x")
|
||||
```
|
||||
|
||||
We will use `console.log` in example code to indicate that we want to see the result of evaluating something. More about that in the [next chapter](https://eloquentjavascript.net/02_program_structure.html).
|
||||
|
||||
The other operators shown all operated on two values, but `typeof` takes only one. Operators that use two values are called _binary_ operators, while those that take one are called _unary_ operators. The minus operator can be used both as a binary operator and as a unary operator.
|
||||
|
||||
```js
|
||||
console.log(\- (10 \- 2))
|
||||
```
|
||||
|
||||
## Boolean values
|
||||
|
||||
It is often useful to have a value that distinguishes between only two possibilities, like “yes” and “no” or “on” and “off”. For this purpose, JavaScript has a _Boolean_ type, which has just two values, true and false, which are written as those words.
|
||||
|
||||
### Comparison
|
||||
|
||||
Here is one way to produce Boolean values:
|
||||
|
||||
```js
|
||||
console.log(3 \> 2)
|
||||
|
||||
console.log(3 < 2)
|
||||
```
|
||||
|
||||
The `>` and `<` signs are the traditional symbols for “is greater than” and “is less than”, respectively. They are binary operators. Applying them results in a Boolean value that indicates whether they hold true in this case.
|
||||
|
||||
Strings can be compared in the same way.
|
||||
|
||||
```js
|
||||
console.log("Aardvark" < "Zoroaster")
|
||||
```
|
||||
|
||||
The way strings are ordered is roughly alphabetic but not really what you’d expect to see in a dictionary: uppercase letters are always “less” than lowercase ones, so `"Z" < "a"`, and nonalphabetic characters (!, -, and so on) are also included in the ordering. When comparing strings, JavaScript goes over the characters from left to right, comparing the Unicode codes one by one.
|
||||
|
||||
Other similar operators are `>=` (greater than or equal to), `<=` (less than or equal to), `==` (equal to), and `!=` (not equal to).
|
||||
|
||||
```js
|
||||
console.log("Itchy" != "Scratchy")
|
||||
|
||||
console.log("Apple" \== "Orange")
|
||||
```
|
||||
|
||||
There is only one value in JavaScript that is not equal to itself, and that is `NaN` (“not a number”).
|
||||
|
||||
```js
|
||||
console.log(NaN \== NaN)
|
||||
```
|
||||
|
||||
`NaN` is supposed to denote the result of a nonsensical computation, and as such, it isn’t equal to the result of any _other_ nonsensical computations.
|
||||
|
||||
### Logical operators
|
||||
|
||||
There are also some operations that can be applied to Boolean values themselves. JavaScript supports three logical operators: _and_, _or_, and _not_. These can be used to “reason” about Booleans.
|
||||
|
||||
The `&&` operator represents logical _and_. It is a binary operator, and its result is true only if both the values given to it are true.
|
||||
|
||||
```js
|
||||
console.log(true && false)
|
||||
|
||||
console.log(true && true)
|
||||
```
|
||||
|
||||
The `||` operator denotes logical _or_. It produces true if either of the values given to it is true.
|
||||
|
||||
```js
|
||||
console.log(false || true)
|
||||
|
||||
console.log(false || false)
|
||||
```
|
||||
|
||||
_Not_ is written as an exclamation mark (`!`). It is a unary operator that flips the value given to it—`!true` produces `false`, and `!false` gives `true`.
|
||||
|
||||
When mixing these Boolean operators with arithmetic and other operators, it is not always obvious when parentheses are needed. In practice, you can usually get by with knowing that of the operators we have seen so far, `||` has the lowest precedence, then comes `&&`, then the comparison operators (`>`, `==`, and so on), and then the rest. This order has been chosen such that, in typical expressions like the following one, as few parentheses as possible are necessary:
|
||||
|
||||
```js
|
||||
1 + 1 \== 2 && 10 \* 10 \> 50
|
||||
```
|
||||
|
||||
The last logical operator I will discuss is not unary, not binary, but _ternary_, operating on three values. It is written with a question mark and a colon, like this:
|
||||
|
||||
```js
|
||||
console.log(true ? 1 : 2);
|
||||
|
||||
console.log(false ? 1 : 2);
|
||||
```
|
||||
|
||||
This one is called the _conditional_ operator (or sometimes just the _ternary_ operator since it is the only such operator in the language). The value on the left of the question mark “picks” which of the other two values will come out. When it is true, it chooses the middle value, and when it is false, it chooses the value on the right.
|
||||
|
||||
## Empty values
|
||||
|
||||
There are two special values, written `null` and `undefined`, that are used to denote the absence of a _meaningful_ value. They are themselves values, but they carry no information.
|
||||
|
||||
Many operations in the language that don’t produce a meaningful value (you’ll see some later) yield `undefined` simply because they have to yield _some_ value.
|
||||
|
||||
The difference in meaning between `undefined` and `null` is an accident of JavaScript’s design, and it doesn’t matter most of the time. In cases where you actually have to concern yourself with these values, I recommend treating them as mostly interchangeable.
|
||||
|
||||
## Automatic type conversion
|
||||
|
||||
In the Introduction, I mentioned that JavaScript goes out of its way to accept almost any program you give it, even programs that do odd things. This is nicely demonstrated by the following expressions:
|
||||
|
||||
```js
|
||||
console.log(8 \* null)
|
||||
|
||||
console.log("5" \- 1)
|
||||
|
||||
console.log("5" + 1)
|
||||
|
||||
console.log("five" \* 2)
|
||||
|
||||
console.log(false \== 0)
|
||||
```
|
||||
|
||||
When an operator is applied to the “wrong” type of value, JavaScript will quietly convert that value to the type it needs, using a set of rules that often aren’t what you want or expect. This is called _type coercion_. The `null` in the first expression becomes `0`, and the `"5"` in the second expression becomes `5` (from string to number). Yet in the third expression, `+` tries string concatenation before numeric addition, so the `1` is converted to `"1"` (from number to string).
|
||||
|
||||
When something that doesn’t map to a number in an obvious way (such as `"five"` or `undefined`) is converted to a number, you get the value `NaN`. Further arithmetic operations on `NaN` keep producing `NaN`, so if you find yourself getting one of those in an unexpected place, look for accidental type conversions.
|
||||
|
||||
When comparing values of the same type using `==`, the outcome is easy to predict: you should get true when both values are the same, except in the case of `NaN`. But when the types differ, JavaScript uses a complicated and confusing set of rules to determine what to do. In most cases, it just tries to convert one of the values to the other value’s type. However, when `null` or `undefined` occurs on either side of the operator, it produces true only if both sides are one of `null` or `undefined`.
|
||||
|
||||
```js
|
||||
console.log(null \== undefined);
|
||||
|
||||
console.log(null \== 0);
|
||||
```
|
||||
|
||||
That behavior is often useful. When you want to test whether a value has a real value instead of `null` or `undefined`, you can compare it to `null` with the `==` (or `!=`) operator.
|
||||
|
||||
But what if you want to test whether something refers to the precise value `false`? Expressions like `0 == false` and `"" == false` are also true because of automatic type conversion. When you do _not_ want any type conversions to happen, there are two additional operators: `===` and `!==`. The first tests whether a value is _precisely_ equal to the other, and the second tests whether it is not precisely equal. So `"" === false` is false as expected.
|
||||
|
||||
I recommend using the three-character comparison operators defensively to prevent unexpected type conversions from tripping you up. But when you’re certain the types on both sides will be the same, there is no problem with using the shorter operators.
|
||||
|
||||
### Short-circuiting of logical operators
|
||||
|
||||
The logical operators `&&` and `||` handle values of different types in a peculiar way. They will convert the value on their left side to Boolean type in order to decide what to do, but depending on the operator and the result of that conversion, they will return either the _original_ left-hand value or the right-hand value.
|
||||
|
||||
The `||` operator, for example, will return the value to its left when that can be converted to true and will return the value on its right otherwise. This has the expected effect when the values are Boolean and does something analogous for values of other types.
|
||||
|
||||
```js
|
||||
console.log(null || "user")
|
||||
|
||||
console.log("Agnes" || "user")
|
||||
```
|
||||
|
||||
We can use this functionality as a way to fall back on a default value. If you have a value that might be empty, you can put `||` after it with a replacement value. If the initial value can be converted to false, you’ll get the replacement instead. The rules for converting strings and numbers to Boolean values state that `0`, `NaN`, and the empty string (`""`) count as `false`, while all the other values count as `true`. So `0 || -1` produces `-1`, and `"" || "!?"` yields `"!?"`.
|
||||
|
||||
The `&&` operator works similarly but the other way around. When the value to its left is something that converts to false, it returns that value, and otherwise it returns the value on its right.
|
||||
|
||||
Another important property of these two operators is that the part to their right is evaluated only when necessary. In the case of `true || X`, no matter what `X` is—even if it’s a piece of program that does something _terrible_—the result will be true, and `X` is never evaluated. The same goes for `false && X`, which is false and will ignore `X`. This is called _short-circuit evaluation_.
|
||||
|
||||
The conditional operator works in a similar way. Of the second and third values, only the one that is selected is evaluated.
|
||||
|
||||
## Summary
|
||||
|
||||
We looked at four types of JavaScript values in this chapter: numbers, strings, Booleans, and undefined values.
|
||||
|
||||
Such values are created by typing in their name (`true`, `null`) or value (`13`, `"abc"`). You can combine and transform values with operators. We saw binary operators for arithmetic (`+`, `-`, `*`, `/`, and `%`), string concatenation (`+`), comparison (`==`, `!=`, `===`, `!==`, `<`, `>`, `<=`, `>=`), and logic (`&&`, `||`), as well as several unary operators (`-` to negate a number, `!` to negate logically, and `typeof` to find a value’s type) and a ternary operator (`?:`) to pick one of two values based on a third value.
|
||||
|
||||
This gives you enough information to use JavaScript as a pocket calculator but not much more. The [next chapter](https://eloquentjavascript.net/02_program_structure.html) will start tying these expressions together into basic programs.
|
||||
|
||||
[◀](https://eloquentjavascript.net/00_intro.html) [◆](https://eloquentjavascript.net/index.html) [▶](https://eloquentjavascript.net/02_program_structure.html)
|
||||
|
@ -1,9 +0,0 @@
|
||||
# WSL2, zsh, and docker. Linux through Windows.
|
||||
|
||||
Author: Nicky Meuleman
|
||||
Link: https://nickymeuleman.netlify.app/blog/linux-on-windows-wsl2-zsh-docker
|
||||
Publishing/Release Date: June 15, 2019
|
||||
Score /5: ⭐️⭐️⭐️
|
||||
Status: Finished
|
||||
Tags: Tech
|
||||
Type: Article
|
476
Media/articles/WSL2, zsh, docker Linux on Windows.md
Normal file
476
Media/articles/WSL2, zsh, docker Linux on Windows.md
Normal file
@ -0,0 +1,476 @@
|
||||
---
|
||||
author:
|
||||
link: https://nickymeuleman.netlify.app/blog/linux-on-windows-wsl2-zsh-docker
|
||||
status: not-finished
|
||||
date: August 1, 2023
|
||||
---
|
||||
# WSL2, zsh, and docker. Linux through Windows. | Nicky blogs
|
||||
#technology #development #windows subsystem for linux #virtualization #windows 10
|
||||
|
||||
Compromises are great. When it comes to technology, having your cake and eating it too is better.
|
||||
|
||||
The machine I normally use for development broke. The [Windows Subsystem for Linux version 2](https://devblogs.microsoft.com/commandline/announcing-wsl-2/) just came out, so I decided to set up another machine with that.
|
||||
|
||||
When all was said and done, it was nothing short of awesome. I just booted a full-stack application that uses [docker](https://www.docker.com/) from an [Oh My ZSH](https://ohmyz.sh/) terminal window inside of [VSCode](https://code.visualstudio.com/). It booted faster than it ever had natively on Windows.
|
||||
|
||||
I’m using Windows 10 Home, that means the [hyper-V](https://en.wikipedia.org/wiki/Hyper-V) virtualization technology normally isn’t available. But WSL2 lets you take advantage of it anyway (if your hardware supports it).
|
||||
|
||||
This post describes the steps I went through to set that up.
|
||||
|
||||
It’s going to be a long one, so buckle up! 💪
|
||||
|
||||
## Update Windows 10
|
||||
|
||||
To use WSL2, Windows 10 has to be updated to version 2004 (Build 10941) or higher.
|
||||
|
||||
* Run Windows update
|
||||
|
||||
* Check your Windows version by opening the “Run” dialog (Windows key + R) and entering `winver`.
|
||||
|
||||
|
||||
![Windows version](/static/1da3c5fa193dab10653d3a8e96b2e2ee/b4ffe/winver.png "Windows version")
|
||||
|
||||
## Activate optional features
|
||||
|
||||
WSL1 and WSL2 use some features that aren’t activated by default, enabling those is necessary.
|
||||
|
||||
This is possible through a GUI, by going to “turn Windows features on or off” or through an elevated Powershell prompt.
|
||||
|
||||
* The GUI option:
|
||||
|
||||
![Turn Windows features on or off](/static/b2b1235c9f2c4a45c0a68c8f4a0217cb/7fee5/features-search.png "Turn Windows features on or off")
|
||||
|
||||
To use WSL, enable the aptly named “Windows Subsystem for Linux” feature.
|
||||
|
||||
![Windows Subsystem for Linux feature](/static/cdaa2ca58b4ce71a62c5934cd792e80b/73926/feature-wsl.png "Windows Subsystem for Linux feature")
|
||||
|
||||
* Through Powershell:
|
||||
|
||||
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux
|
||||
|
||||
Regardless of the option you chose, a reboot is required.
|
||||
|
||||
### Feature for WSL2
|
||||
|
||||
That was enough for WSL1. To use WSL2, also make sure virtualization is enabled in your BIOS.
|
||||
|
||||
Enabling virtualization in the BIOS looks different for most motherboard brands.
|
||||
On my MSI board the option was called “Virtualization Technology” and was hidden in the overclocking settings.
|
||||
|
||||
Next: enabling another optional feature in Windows!
|
||||
|
||||
Same story here, either use the GUI or an elevated Powershell window.
|
||||
The option to enable is called the “virtual machine platform”.
|
||||
|
||||
* GUI
|
||||
|
||||
![virtual machine platform feature](/static/7f5cc541880a4f778779f24741da3b39/73926/feature-virtual-machine-platform.png "virtual machine platform feature")
|
||||
|
||||
* Powershell
|
||||
|
||||
Enable-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform
|
||||
|
||||
## Install a distro
|
||||
|
||||
Once that reboot is done, you can go to the Microsoft store and install your favourite Linux distribution. I went with Ubuntu, because a lot of install instructions and other documentation are written for that distro.
|
||||
|
||||
![Ubuntu in the Microsoft store](/static/8075506f7745d2c879e8e04d2f98662f/21b4d/store-ubuntu.png "Ubuntu in the Microsoft store")
|
||||
|
||||
On the first boot of the distro you just installed (which presents itself as a terminal window), you’ll be asked to enter a password for when you want to **do** stuff as a **su**per user (`sudo`).
|
||||
|
||||
## WSL1 to WSL2
|
||||
|
||||
To check which version of WSL is installed you can run a command in Powershell.
|
||||
|
||||
wsl --list --verbose
|
||||
|
||||
wsl -l -v
|
||||
|
||||
If the number for the version is 2, all systems go!
|
||||
|
||||
If not, convert that puppy from 1 to 2.
|
||||
|
||||
wsl --set-version <distro-name\> 2
|
||||
|
||||
wsl --set-version Ubuntu 2
|
||||
|
||||
The output will tell you that this operation might take a while.
|
||||
It’s not one of those that says that only to finish 5 seconds later. It took about 10 minutes here.
|
||||
|
||||
![Converting a distro from WSL1 to WSL2](/static/c9c1e98a28811f3faf6b878e3827e81e/39a20/wsl-set-version.png "Converting a distro from WSL1 to WSL2")
|
||||
|
||||
At this point, WSL2 is ready to go.
|
||||
Opening the distro you installed will show a bash prompt.
|
||||
|
||||
Windows Subsystem for Linux 2 comes with a real Linux kernel.
|
||||
Previously there was a kernel compatibility layer that could not do quite as much.
|
||||
|
||||
In the words of a certain wooden puppet, it is now a _real boy_.
|
||||
|
||||
![Pinocchio is a real boy](https://i.imgur.com/fLW42gG.jpg)
|
||||
|
||||
Users of WSL2 are encouraged to place their files inside the Linux file system.
|
||||
That way they benefit from file performance increases compared to WSL1.
|
||||
|
||||
In WSL2 you can now access files from Linux in Windows and the other way around.
|
||||
Modifying Linux files from Windows in WSL1 was always warned against, as this could cause _bad things_ to happen. Whoooo, spooky 👻 (but, really, it was a bad idea.)
|
||||
|
||||
More details on changes are available in Microsoft’s [WSL2 release blogpost](https://devblogs.microsoft.com/commandline/wsl-2-is-now-available-in-windows-insiders/)
|
||||
|
||||
Let’s start loading up our environment with some needed tools. A few tools still need to be installed on the Windows side, the rest are all Linux tools.
|
||||
|
||||
The two I’ll install for Windows are: [VSCode](https://code.visualstudio.com/) and [git for Windows](https://git-scm.com/). Remember to set the autocrlf setting to input for git. VSCode handles it well.
|
||||
|
||||
git config --global core.autocrlf input
|
||||
|
||||
Before beginning to install Linux tools, we’ll update our already installed packages.
|
||||
|
||||
sudo apt update
|
||||
|
||||
sudo apt upgrade
|
||||
|
||||
More preparation, installing build tools for [node-gyp](https://github.com/nodejs/node-gyp)
|
||||
|
||||
sudo apt install build-essential
|
||||
|
||||
### Git
|
||||
|
||||
This one should also be installed on the Linux side.
|
||||
|
||||
After installing git, remember to [configure it](/blog/fresh-development-environment-part-2/#configuration).
|
||||
Especially setting the autocrlf setting to input is important here.
|
||||
|
||||
git config --global core.autocrlf input
|
||||
|
||||
### Node & NPM
|
||||
|
||||
You can install it as a standalone package.
|
||||
|
||||
Now we can harness all those Linux-y tools, I’ll use nvm instead to make using different versions easier.
|
||||
|
||||
[The nvm repo](https://github.com/nvm-sh/nvm) has excellent installation instructions.
|
||||
|
||||
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash
|
||||
|
||||
Restart your terminal after the install.
|
||||
To confirm the installation was successfull:
|
||||
|
||||
It should return: `nvm`
|
||||
That’s all, no version number, just that string.
|
||||
|
||||
To install the latest the latest stable version of node:
|
||||
|
||||
When node releases a new version, you can run that same command again.
|
||||
|
||||
You’ll need to tell nvm which version of node you want to use.
|
||||
So next time you boot your Linux distro, you’ll have to use.
|
||||
|
||||
When the project you are working on requires a different version of node, specify that one.
|
||||
|
||||
nvm use v<version number\>
|
||||
|
||||
nvm use
|
||||
|
||||
Having to do that manually seems annoying right?
|
||||
Many solutions to this annoyance exist. Later in this post that annoyance will be dealt with.
|
||||
|
||||
### Docker
|
||||
|
||||
* Kick things off by updating the packages index and installing dependencies.
|
||||
|
||||
sudo apt update
|
||||
|
||||
sudo apt install apt-transport-https ca-certificates curl software-properties-common
|
||||
|
||||
* Add Dockers’s official GPG-key.
|
||||
|
||||
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
|
||||
|
||||
* Verify this by running:
|
||||
|
||||
sudo apt-key fingerprint 0EBFCD88
|
||||
|
||||
You should see the full key in the output.
|
||||
|
||||
9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88
|
||||
|
||||
* Add the Docker repository to your list of repositories.
|
||||
|
||||
sudo add-apt-repository "deb \[arch=amd64\] https://download.docker.com/linux/ubuntu $(lsb\_release -cs) stable"
|
||||
|
||||
* Update the list of repositories again and install Docker CE.
|
||||
|
||||
sudo apt update
|
||||
|
||||
sudo apt install docker-ce
|
||||
|
||||
Normally, the docker engine starts automatically after the install.
|
||||
For me that was not the case so I started it manually.
|
||||
|
||||
sudo service docker start
|
||||
|
||||
* Verify Docker CE was installed correcly by booting up their hello-world container.
|
||||
|
||||
sudo docker run hello-world
|
||||
|
||||
### Docker Compose
|
||||
|
||||
As a handy tool for managing docker containers, `docker-compose` is frequently installed alongside `docker-ce`.
|
||||
|
||||
* Download the current stable release and place it in the `/usr/local/bin` folder.
|
||||
|
||||
sudo curl -L "https://github.com/docker/compose/releases/download/1.24.0/docker-compose-$(uname -s)\-$(uname -m)" -o /usr/local/bin/docker-compose
|
||||
|
||||
* Make the file executable.
|
||||
|
||||
sudo chmod +x /usr/local/bin/docker-compose
|
||||
|
||||
* Verify the installation.
|
||||
|
||||
### Docker Desktop
|
||||
|
||||
A short trip back to the Windows side!
|
||||
|
||||
The previous way to _do Docker-y things_ all happened through the Linux terminal. While this is fine, the [Docker Desktop for Windows](https://www.docker.com/products/docker-desktop) application integrates with WSL2 quite well and provides a GUI.
|
||||
|
||||
![Installing the Docker Desktop application](/static/74dc836f010ba50ca452b2339b374969/5ebd7/docker-desktop-install.png "Installing the Docker Desktop application")
|
||||
|
||||
If you start a docker container in your (Linux) terminal, it will appear in, and can be controlled through the interface.
|
||||
|
||||
e.g. Running the getting-started docker container in the Linux terminal
|
||||
|
||||
docker run -dp 80:80 docker/getting-started
|
||||
|
||||
will make the container appear in the interface, where it can be opened in a browser, stopped, restarted, …
|
||||
|
||||
![The container we started appears in the interace.](/static/39cf09a4af2da9886d46dc916e2912b1/1ff84/docker-desktop-dashboard.png "The container we started appears in the interace.")
|
||||
|
||||
### Yarn
|
||||
|
||||
[Yarn](https://yarnpkg.com/) is a package manager for JavaScript made by Facebook.
|
||||
|
||||
* Add their gpg key.
|
||||
|
||||
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
|
||||
|
||||
* Add their repository.
|
||||
|
||||
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
|
||||
|
||||
* Update the list of repositories and install Yarn.
|
||||
|
||||
sudo apt update
|
||||
|
||||
sudo apt install --no-install-recommends yarn
|
||||
|
||||
* Verify the installation.
|
||||
|
||||
### Visual Studio Code Remote - WSL extension
|
||||
|
||||
The [Visual Studio Code Remote - WSL](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-wsl) extension will let you use [VSCode](https://code.visualstudio.com/) on Windows to interact with WSL. You can develop entirely in the Linux environment, while viewing the results in Windows.
|
||||
|
||||
Below is a screenshot of me writing this blogpost in VSCode, while connected to my Ubuntu installation. Notice the `WSL: Ubuntu` badge in the lower left corner.
|
||||
|
||||
![Me writing this blogpost in VSCode](/static/fbd80cb0ea37608b6e789fa1401a72e0/68947/vscode-remote-wsl.png "Me writing this blogpost in VSCode")
|
||||
|
||||
## A better terminal
|
||||
|
||||
When you open your terminal there are 2 sides at work.
|
||||
The thing you see and type into, **the terminal**.
|
||||
The thing that terminal communicates with and does most of the work, **the shell**.
|
||||
|
||||
Let’s face it, the terminal that ships with Windows is pretty lackluster.
|
||||
Good news: they are ~coming~ came out with [a new one](https://youtu.be/8gw0rXPMMPE) and it looks really awesome!
|
||||
|
||||
~In anticipation of that release, I’m not going to change much there. I’ll use the one that’s integrated into VSCode most of the time anyway.~
|
||||
|
||||
### Change integrated VSCode terminal
|
||||
|
||||
VSCode’s integrated terminal is a great productivity booster.
|
||||
Let’s use the brand new Linux shell in there.
|
||||
|
||||
When opening the integrated terminal, you can choose wich one to use as the default one.
|
||||
Select WSL from the resulting list of options and you are done!
|
||||
|
||||
![select terminal in Visual Studio Code](/static/650283d5ed274f48f93fc136b42a008b/57dc1/terminal-select.png "select terminal in Visual Studio Code")
|
||||
|
||||
Alternatively, edit the `settings.json` to point to the correct location.
|
||||
|
||||
"terminal.integrated.shell.linux": "/bin/sh",
|
||||
|
||||
### ZSH
|
||||
|
||||
I chose [ZSH](https://en.wikipedia.org/wiki/Z_shell) to replace the standard bash shell that opens when clicking the Ubuntu icon in the start menu.
|
||||
|
||||
Installing it is a oneliner thanks to the package manager in Ubuntu.
|
||||
|
||||
When you launch Ubuntu, you’ll still see the usual bash prompt.
|
||||
To start the zsh shell from that familiar bash prompt, enter:
|
||||
|
||||
The first time this launches, a configuration wizard will be shown.
|
||||
The choice made here doesn’t matter all that much, since the resulting file `.zshrc` file will be overwritten when we install [oh-my-zsh](https://ohmyz.sh/) a bit later. I chose the option `2` anyway and went with the defaults.
|
||||
|
||||
![zsh-install](/static/35e6e0a23d0b3b43a4bc3572ea4026f6/adc48/zsh-install.png "zsh-install")
|
||||
|
||||
Typing `zsh` into bash every time we launch it gets old quick.
|
||||
Time to change the default shell to zsh!
|
||||
|
||||
_Thanks to Reddit user_ [bhramchari](https://www.reddit.com/r/bashonubuntuonwindows/comments/c1fy1c/stock_win10_to_wsl2_ubuntu_with_zsh_and_docker/erdckwe/) _for suggesting this method!_
|
||||
|
||||
### Oh My ZSH
|
||||
|
||||
This extension to zsh has one of the best URLs out there: [ohmyz.sh](https://ohmyz.sh/)
|
||||
It will also enable a huge list of nice features, which is more important.
|
||||
|
||||
Installing oh-my-zsh is a oneliner.
|
||||
|
||||
sh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
|
||||
|
||||
This will also replace that `.zshrc` file we initialised earlier.
|
||||
|
||||
Enjoy the cool ASCII art signalling a successful installation!
|
||||
|
||||
#### Theme oh-my-zsh
|
||||
|
||||
oh-my-zsh comes with lots of fancy themes, so let’s install a pretty one!
|
||||
Take a look at [a list of them](https://github.com/robbyrussell/oh-my-zsh/wiki/Themes).
|
||||
|
||||
I like the agnoster one, so that’s what I’ll go with.
|
||||
|
||||
Edit the `.zshrc` file to enable it.
|
||||
This file is also located in your Linux home directory (`cd $home` to go there).
|
||||
|
||||
.zshrc
|
||||
|
||||
ZSH\_THEME\="robbyrussell"
|
||||
|
||||
ZSH\_THEME\="agnoster"
|
||||
|
||||
restart your terminal for it to take effect.
|
||||
|
||||
#### Powerline fonts
|
||||
|
||||
Aaaaaaaaaah, it’s … broken. 😥
|
||||
|
||||
![ugly oh my ZSH](/static/4eab3fb6a81577500c2e25d8660f6bbe/cd138/ugly-oh-my-zsh.png "ugly oh my ZSH")
|
||||
|
||||
That’s partly because this is a fancy prompt that needs a [Powerline-patched font](https://github.com/powerline/fonts) to render correctly.
|
||||
|
||||
You can either download the specific font you want and install it that way (double clicking on the file and hitting the install button), or use the install script to install them all at once.
|
||||
|
||||
To install them all at once first clone that repo.
|
||||
Then open an elevated Powershell window.
|
||||
To be able to execute the `install.ps1` file, we need to open up the execution policy temporarily.
|
||||
|
||||
Set-ExecutionPolicy Bypass
|
||||
|
||||
Now navigate to the cloned repo and execute the install script.
|
||||
|
||||
You’ll see the same thing happening as you would when downloading and installing each font seperatly, but of course much quicker.
|
||||
|
||||
Set-ExecutionPolicy Default
|
||||
|
||||
After installing the fonts, setting them in your terminal application changes the weird boxes to icons.
|
||||
|
||||
Note that the standard terminal in Windows still doesn’t work quite right after that. It has many limitations, this not working completely is just one of them.
|
||||
As stated before, I’m mainly going to use the terminal inside VSCode, so I’m leaving the standard terminal behind.
|
||||
|
||||
After setting the terminal font in VSCode, all icons show up beautifully.
|
||||
|
||||
The colors when listing directories and files with the `ls` command still look, euuuhm, suboptimal.
|
||||
|
||||
![ugly dircolors](/static/2a019f31f94b76753aa42751b8ffa162/6c2f2/ugly-dircolors.png "ugly dircolors")
|
||||
|
||||
#### dircolors
|
||||
|
||||
To replace those ugly colors, something called dircolors may be used.
|
||||
I’ll install the popular [solarized dircolors](https://github.com/seebi/dircolors-solarized)
|
||||
|
||||
Pick the theme you want and download the file to your home directory.
|
||||
|
||||
curl https://raw.githubusercontent.com/seebi/dircolors-solarized/master/dircolors.ansi-dark --output ~/.dircolors
|
||||
|
||||
Add a line to the bottom of your zsh configuration file to use what you just downloaded.
|
||||
|
||||
eval \`dircolors ~/.dircolors\`
|
||||
|
||||
Much better, it looks great now!
|
||||
|
||||
![pretty-terminal](/static/dcdbda00edb6e5b4e4f2fcac9d301b7c/2a50c/pretty-terminal.png "pretty-terminal")
|
||||
|
||||
### Plugins for oh-my-zsh
|
||||
|
||||
By itself, oh-my-zsh is already feature-rich. For further productivity increases, plugins are there to help.
|
||||
|
||||
Many of those plugins ship alongside oh-my-zsh, making installing them as easy as adding a line to `.zshrc`.
|
||||
Others require a bit more effort, let’s start with those!
|
||||
|
||||
#### Syntax Highlighting
|
||||
|
||||
[zsh-syntax-highlighting](https://github.com/zsh-users/zsh-syntax-highlighting) is a handy plugin that prevents syntax errors by highlighting valid commands in green and invalid ones in red.
|
||||
|
||||
To install the plugin first clone [the repo](https://github.com/zsh-users/zsh-syntax-highlighting).
|
||||
Then add the script to your `.zshrc`.
|
||||
|
||||
.zshrc
|
||||
|
||||
source <path-to-the-script\>
|
||||
|
||||
source ~/.zsh/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
|
||||
|
||||
#### Auto Suggestions
|
||||
|
||||
[zsh-autosuggestions](https://github.com/zsh-users/zsh-autosuggestions) makes typing the same command over and over much quicker by suggesting what you could type next. These suggestions are based on command history.
|
||||
|
||||
Installing it follows the same pattern as the plugin we installed above.
|
||||
|
||||
First clone the repo, then add a line to `.zshrc`
|
||||
|
||||
.zshrc
|
||||
|
||||
source <path-to-the-script\>
|
||||
|
||||
source ~/.zsh/zsh-autosuggestions/zsh-autosuggestions.zsh
|
||||
|
||||
#### pre-installed plugins
|
||||
|
||||
A list of the plugins that ship with oh-my-zsh can be viewed on this [Github page](https://github.com/robbyrussell/oh-my-zsh/tree/master/plugins).
|
||||
|
||||
Each one should have a `README.md` that tells you more about what it does and how to activate the plugin.
|
||||
Most of the time, activating the plugin requires you to add it to the list of plugins in `.zshrc`.
|
||||
|
||||
This is what I ended up with:
|
||||
|
||||
.zshrc
|
||||
|
||||
plugins\=(
|
||||
|
||||
git
|
||||
|
||||
node
|
||||
|
||||
npm
|
||||
|
||||
npx
|
||||
|
||||
nvm
|
||||
|
||||
z
|
||||
|
||||
)
|
||||
|
||||
The plugin I would like to call out here is [z](https://github.com/robbyrussell/oh-my-zsh/tree/master/plugins/z).
|
||||
It make navigating to _frecent_ folders easy.
|
||||
|
||||
You read that right, it’s not a typo.
|
||||
It’s a contraction of frequent and recent.
|
||||
|
||||
For example, my blog is located at `~/projects/nicky-blog`
|
||||
If I type `z blog`, z will take me there.
|
||||
|
||||
## Result
|
||||
|
||||
Whew! That was quite the journey 😅💦
|
||||
The result is very powerful, and it looks good too! 🎊🎉🎉🎉🎊
|
||||
|
||||
![the end result](/static/3ad6eb8e76c6317b9e71e75e61562896/bb3b7/end-result.png "the end result")
|
@ -1,6 +0,0 @@
|
||||
# Wisdom and/or Madness of Crowds
|
||||
|
||||
Link: https://ncase.me/crowds/
|
||||
Status: Finished
|
||||
Tags: Psychology
|
||||
Type: Article
|
9
Media/articles/Wisdom and or Madness of Crowds.md
Normal file
9
Media/articles/Wisdom and or Madness of Crowds.md
Normal file
@ -0,0 +1,9 @@
|
||||
---
|
||||
link: https://ncase.me/crowds/
|
||||
status: finished
|
||||
---
|
||||
|
||||
# Wisdom and/or Madness of Crowds
|
||||
|
||||
#psychology
|
||||
|
BIN
Media/articles/images/19clearview-promo-sub-square640.png
Normal file
BIN
Media/articles/images/19clearview-promo-sub-square640.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 848 KiB |
@ -23,9 +23,6 @@ not yet rated
|
||||
### [[Media/movies/The Godfather|The Godfather]] - not seen
|
||||
⭐⭐⭐⭐⭐ by _Francis Ford Coppola_
|
||||
|
||||
### [[Media/movies/The Matrix|The Matrix]] - not seen
|
||||
⭐⭐⭐⭐ by _The Wachowskis_
|
||||
|
||||
### [[Media/movies/We Almost Lost Bochum|We Almost Lost Bochum]] - not seen
|
||||
not yet rated
|
||||
|
||||
@ -35,18 +32,12 @@ not yet rated
|
||||
### [[Media/movies/Soylent Green|Soylent Green]] - not seen
|
||||
not yet rated
|
||||
|
||||
### [[Media/movies/Ponyo|Ponyo]] - not seen
|
||||
not yet rated
|
||||
|
||||
### [[Media/movies/Pi|Pi]] - not seen
|
||||
not yet rated
|
||||
|
||||
### [[Media/movies/Memento|Memento]] - not seen
|
||||
not yet rated
|
||||
|
||||
### [[Media/movies/Magnolia Tree|Magnolia Tree]] - not seen
|
||||
not yet rated
|
||||
|
||||
### [[Media/movies/Drowning by Numbers|Drowning by Numbers]] - not seen
|
||||
not yet rated by _Peter Greenaway_
|
||||
|
||||
@ -59,63 +50,63 @@ not yet rated
|
||||
|
||||
## Movies (Seen)
|
||||
<!-- #query page where name =~ /^Media\/movies/ and status != Finished order by rating desc limit 20 render [[templates/movies]] -->
|
||||
### [[Media/movies/2001 A Space Odyssey|2001 A Space Odyssey]] - Finished
|
||||
### [[Media/movies/2001 A Space Odyssey|2001 A Space Odyssey]] - finished
|
||||
⭐️⭐️⭐️⭐️⭐️ by _Stanley Kubrick_
|
||||
|
||||
### [[Media/movies/A Clockwork Orange|A Clockwork Orange]] - NeedToWatchAgain
|
||||
⭐️⭐️⭐️⭐️⭐️ by _Stanley Kubrick_
|
||||
|
||||
### [[Media/movies/Apocalypse Now|Apocalypse Now]] - NeedToWatchAgain
|
||||
### [[Media/movies/Apocalypse Now|Apocalypse Now]] - watch-again
|
||||
⭐️⭐️⭐️⭐️⭐️ by _Francis Ford Coppola_
|
||||
|
||||
### [[Media/movies/Burning|Burning]] - Finished
|
||||
### [[Media/movies/Burning|Burning]] - finished
|
||||
⭐️⭐️⭐️⭐️⭐️ by _Lee Chang-dong_
|
||||
|
||||
### [[Media/movies/Call Me by Your Name|Call Me by Your Name]] - Finished
|
||||
### [[Media/movies/Call Me by Your Name|Call Me by Your Name]] - finished
|
||||
⭐️⭐️⭐️⭐️⭐️ by _Luca Guadagnino_
|
||||
|
||||
### [[Media/movies/Chihiros Reise ins Zauberland|Chihiros Reise ins Zauberland]] - Finished
|
||||
### [[Media/movies/Chihiros Reise ins Zauberland|Chihiros Reise ins Zauberland]] - finished
|
||||
⭐️⭐️⭐️⭐️⭐️ by _Hayao Miyazaki_
|
||||
|
||||
### [[Media/movies/Die Fabelhafte Welt der Amelie|Die Fabelhafte Welt der Amelie]] - Finished
|
||||
### [[Media/movies/Die Fabelhafte Welt der Amelie|Die Fabelhafte Welt der Amelie]] - finished
|
||||
⭐️⭐️⭐️⭐️⭐️ by _Jean-Pierre Jeunet_
|
||||
|
||||
### [[Media/movies/Drive|Drive]] - Finished
|
||||
### [[Media/movies/Drive|Drive]] - finished
|
||||
⭐️⭐️⭐️⭐️⭐️ by _Nicolas Winding Refn_
|
||||
|
||||
### [[Media/movies/Her|Her]] - Finished
|
||||
### [[Media/movies/Her|Her]] - finished
|
||||
⭐️⭐️⭐️⭐️⭐️ by _Spike Jonze_
|
||||
|
||||
### [[Media/movies/I Lost My Body|I Lost My Body]] - Finished
|
||||
### [[Media/movies/I Lost My Body|I Lost My Body]] - finished
|
||||
⭐️⭐️⭐️⭐️⭐️ by _Jérémy Clapin_
|
||||
|
||||
### [[Media/movies/I'm Thinking of Ending Things|I'm Thinking of Ending Things]] - NeedToWatchAgain
|
||||
### [[Media/movies/I'm Thinking of Ending Things|I'm Thinking of Ending Things]] - watch-again
|
||||
⭐️⭐️⭐️⭐️⭐️ by _Charlie Kaufman_
|
||||
|
||||
### [[Media/movies/Jules and Jim|Jules and Jim]] - Finished
|
||||
⭐️⭐️⭐️⭐️⭐️ by _François Truffaut_
|
||||
|
||||
### [[Media/movies/Koyaanisqatsi|Koyaanisqatsi]] - Finished
|
||||
⭐️⭐️⭐️⭐️⭐️
|
||||
### [[Media/movies/Koyaanisqatsi|Koyaanisqatsi]] - finished
|
||||
⭐️⭐️⭐️⭐️⭐️ by _Godfrey Reggio_
|
||||
|
||||
### [[Media/movies/Mein Nachbar Totoro|Mein Nachbar Totoro]] - Finished
|
||||
### [[Media/movies/Mein Nachbar Totoro|Mein Nachbar Totoro]] - finished
|
||||
⭐️⭐️⭐️⭐️⭐️ by _Hayao Miyazaki_
|
||||
|
||||
### [[Media/movies/Moonlight|Moonlight]] - Finished
|
||||
### [[Media/movies/Moonlight|Moonlight]] - finished
|
||||
⭐️⭐️⭐️⭐️⭐️ by _Barry Jenkins_
|
||||
|
||||
### [[Media/movies/Oldboy|Oldboy]] - Finished
|
||||
### [[Media/movies/Oldboy|Oldboy]] - finished
|
||||
⭐️⭐️⭐️⭐️⭐️ by _Park Chan-wook_
|
||||
|
||||
### [[Media/movies/Pulp Fiction|Pulp Fiction]] - Finished
|
||||
### [[Media/movies/Pulp Fiction|Pulp Fiction]] - finished
|
||||
⭐️⭐️⭐️⭐️⭐️ by _Quentin Tarantino_
|
||||
|
||||
### [[Media/movies/The Cakemaker|The Cakemaker]] - Finished
|
||||
### [[Media/movies/The Cakemaker|The Cakemaker]] - finished
|
||||
⭐️⭐️⭐️⭐️⭐️ by _Ofir Raul Graizer_
|
||||
|
||||
### [[Media/movies/Whiplash|Whiplash]] - Finished
|
||||
### [[Media/movies/Whiplash|Whiplash]] - finished
|
||||
⭐️⭐️⭐️⭐️⭐️ by _Damien Chazelle_
|
||||
|
||||
### [[Media/movies/A Fistful of Dollars|A Fistful of Dollars]] - Finished
|
||||
### [[Media/movies/A Fistful of Dollars|A Fistful of Dollars]] - finished
|
||||
⭐️⭐️⭐️⭐️ by _Sergio Leone_
|
||||
<!-- /query -->
|
||||
|
@ -3,6 +3,7 @@ author: Stanley Kubrick
|
||||
published: April 8, 1968
|
||||
rating: ⭐️⭐️⭐️⭐️⭐️
|
||||
status: finished
|
||||
image: Media/movies/images/2001_a_space_odyssey_cover.jpg
|
||||
---
|
||||
|
||||
# 2001: A Space Odyssey
|
||||
|
@ -1,8 +1,9 @@
|
||||
---
|
||||
date: December 19, 1971
|
||||
image: Media/movies/images/a_clockwork_orange_cover.jpg
|
||||
author: Stanley Kubrick
|
||||
date: December 17, 1971
|
||||
rating: ⭐️⭐️⭐️⭐️⭐️
|
||||
status: NeedToWatchAgain
|
||||
---
|
||||
# A Clockwork Orange
|
||||
![](Media/movies/images/a_clockwork_orange_cover.jpg)
|
||||
|
||||
|
||||
|
@ -3,8 +3,9 @@ author: Sergio Leone
|
||||
date: September 11, 1964
|
||||
rating: ⭐️⭐️⭐️⭐️
|
||||
status: finished
|
||||
image: Media/movies/images/a_fistful_of_dollars_cover.jpg
|
||||
---
|
||||
|
||||
# A Fistful of Dollars
|
||||
|
||||
#western
|
||||
|
||||
|
@ -2,8 +2,9 @@
|
||||
author: Tony Kaye
|
||||
date: October 29, 1998
|
||||
status: not-seen
|
||||
image: Media/movies/images/american_history_x_cover.jpg
|
||||
---
|
||||
|
||||
# American History X
|
||||
|
||||
#drama
|
||||
\#drama
|
||||
|
@ -2,8 +2,9 @@
|
||||
author: Charlie Kaufman, Duke Johnson
|
||||
date: December 29, 2015
|
||||
status: not-seen
|
||||
image: Media/movies/images/anomalisa_cover.jpg
|
||||
---
|
||||
|
||||
# Anomalisa
|
||||
|
||||
#animation #comedy #drama #romance
|
||||
|
||||
|
@ -3,6 +3,7 @@ author: Francis Ford Coppola
|
||||
date: August 14, 1979
|
||||
rating: ⭐️⭐️⭐️⭐️⭐️
|
||||
status: watch-again
|
||||
image: Media/movies/images/apocalypse_now_cover.jpg
|
||||
---
|
||||
# Apocalypse Now
|
||||
|
||||
# Apocalypse Now
|
||||
|
10
Media/movies/Arrival.md
Normal file
10
Media/movies/Arrival.md
Normal file
@ -0,0 +1,10 @@
|
||||
---
|
||||
date: November 10, 2016
|
||||
image: Media/movies/images/arrival_cover.jpg
|
||||
author: Denis Villeneuve
|
||||
rating: ⭐⭐⭐⭐⭐
|
||||
---
|
||||
# Arrival
|
||||
![](Media/movies/images/arrival_cover.jpg)
|
||||
|
||||
|
@ -3,9 +3,9 @@ author: Damien Chazelle
|
||||
published: November 14, 2022
|
||||
rating: ⭐️⭐️⭐️
|
||||
status: finished
|
||||
image: Media/movies/babylon_cover.jpg
|
||||
image: Media/movies/images/babylon_cover.jpg
|
||||
---
|
||||
|
||||
# Babylon
|
||||
![](Media/movies/babylon_cover.jpg)
|
||||
![](Media/movies/images/babylon_cover.jpg)
|
||||
Babylon is a 2022 American epic period black comedy-drama film written and directed by Damien Chazelle. It features an ensemble cast that includes Brad Pitt, Margot Robbie, Diego Calva, Jean Smart, Jovan Adepo, and Li Jun Li. The film chronicles the rise and fall of multiple characters during Hollywood's transition from silent to sound films in the late 1920s.
|
||||
|
@ -3,8 +3,9 @@ author: Charlie Kaufman, Spike Jonze
|
||||
date: October 28, 1999
|
||||
rating: ⭐️⭐️⭐️⭐️
|
||||
status: finished
|
||||
image: Media/movies/images/being_john_malkovich_cover.jpg
|
||||
---
|
||||
|
||||
# Being John Malkovich
|
||||
|
||||
#comedy #drama #fantasy
|
||||
\#comedy #drama #fantasy
|
||||
|
@ -1,3 +1,9 @@
|
||||
---
|
||||
date: December 14, 1984
|
||||
image: Media/movies/images/birdy_cover.jpg
|
||||
author: Alan Parker
|
||||
---
|
||||
|
||||
---
|
||||
date: December 13, 1984
|
||||
rating: ⭐️⭐️⭐️
|
||||
|
@ -2,6 +2,8 @@
|
||||
rating: ⭐⭐⭐⭐⭐
|
||||
author: Denis Villeneuve
|
||||
status: finished
|
||||
image: Media/movies/images/blade_runner_2049_cover.jpg
|
||||
date: October 4, 2017
|
||||
---
|
||||
|
||||
# Blade Runner 2049
|
||||
|
@ -3,11 +3,12 @@ author: David Lynch
|
||||
date: July 31, 1986
|
||||
rating: ⭐️⭐️⭐️⭐️
|
||||
status: finished
|
||||
image: Media/movies/images/blue_velvet_cover.jpg
|
||||
---
|
||||
|
||||
# Blue Velvet
|
||||
|
||||
#crime #drama #mystery #thriller
|
||||
\#crime #drama #mystery #thriller
|
||||
|
||||
With my current knowledge of David Lynch movies this one definitely falls out of line. The story is surprisingly linear, altough i very much appreciated the surreal symbolism that serves as a reminder that this Film is definitely made by Lynch.
|
||||
|
||||
@ -21,6 +22,6 @@ I must say it is always interesting to watch movies where *most* of the female c
|
||||
|
||||
Jeffrey
|
||||
|
||||
I liked that character a lot, most of his motivations had some depth and complexity to them that even he didn't seem to fully understand sometimes. He was as much discovering the mystery of himself, the mystery of sexuality and sadomasochismus and the myster of dorothy at the same time.
|
||||
I liked that character a lot, most of his motivations had some depth and complexity to them that even he didnt seem to fully understand sometimes. He was as much discovering the mystery of himself, the mystery of sexuality and sadomasochismus and the myster of dorothy at the same time.
|
||||
|
||||
Dorothy
|
||||
|
@ -1,9 +1,9 @@
|
||||
---
|
||||
author: Lee Chang-dong
|
||||
date: June 6, 2019
|
||||
rating: ⭐️⭐️⭐️⭐️⭐️
|
||||
status: finished
|
||||
image: Media/movies/images/burning_cover.jpg
|
||||
date: November 20, 2018
|
||||
---
|
||||
|
||||
# Burning
|
||||
|
||||
|
@ -3,7 +3,7 @@ author: Luca Guadagnino
|
||||
date: August 31, 2017
|
||||
rating: ⭐️⭐️⭐️⭐️⭐️
|
||||
status: finished
|
||||
image: Media/movies/images/call_me_by_your_name_cover.jpg
|
||||
---
|
||||
|
||||
# Call Me by Your Name
|
||||
|
||||
|
@ -3,7 +3,7 @@ author: Hayao Miyazaki
|
||||
date: June 20, 2001
|
||||
rating: ⭐️⭐️⭐️⭐️⭐️
|
||||
status: finished
|
||||
image: Media/movies/images/chihiros_reise_ins_zauberland_cover.jpg
|
||||
---
|
||||
|
||||
# Chihiros Reise ins Zauberland
|
||||
|
||||
|
@ -3,6 +3,7 @@ author: Mike Wells
|
||||
date: November 19, 2021
|
||||
status: Finished
|
||||
rating: ⭐⭐⭐⭐
|
||||
image: Media/movies/images/cmon_cmon_cover.jpg
|
||||
---
|
||||
|
||||
# C’mon C’mon
|
||||
|
@ -3,7 +3,7 @@ author: David Cronenberg
|
||||
date: October 21, 1983
|
||||
rating: ⭐️⭐️⭐️
|
||||
status: finished
|
||||
image: Media/movies/images/dead_zone_cover.jpg
|
||||
---
|
||||
|
||||
# Dead Zone
|
||||
|
||||
|
10
Media/movies/Dr. Strangelove.md
Normal file
10
Media/movies/Dr. Strangelove.md
Normal file
@ -0,0 +1,10 @@
|
||||
---
|
||||
date: January 29, 1964
|
||||
image: >-
|
||||
Media/movies/images/dr._strangelove_or_how_i_learned_to_stop_worrying_and_love_the_bomb_cover.jpg
|
||||
author: Stanley Kubrick
|
||||
---
|
||||
# Dr. Strangelove
|
||||
![](Media/movies/images/dr._strangelove_or_how_i_learned_to_stop_worrying_and_love_the_bomb_cover.jpg)
|
||||
|
||||
|
@ -3,7 +3,8 @@ author: Nicolas Winding Refn
|
||||
date: August 5, 2011
|
||||
rating: ⭐️⭐️⭐️⭐️⭐️
|
||||
status: finished
|
||||
image: Media/movies/images/drive_cover.jpg
|
||||
---
|
||||
|
||||
# Drive
|
||||
|
||||
![](Media/movies/images/drive_cover.jpg)
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
author: Peter Greenaway
|
||||
image: Media/movies/images/drowning_by_numbers_cover.jpg
|
||||
date: September 10, 1988
|
||||
---
|
||||
|
||||
# Drowning by Numbers
|
||||
|
||||
|
@ -1,7 +1,8 @@
|
||||
---
|
||||
author: Autumn de Wilde
|
||||
status: not-seen
|
||||
image: Media/movies/images/emma_cover.jpg
|
||||
date: February 13, 2020
|
||||
---
|
||||
|
||||
# Emma
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
---
|
||||
author: Michel Gondry
|
||||
status: not-seen
|
||||
image: Media/movies/images/eternal_sunshine_of_the_spotless_mind_cover.jpg
|
||||
date: March 19, 2004
|
||||
---
|
||||
|
||||
# Eternal Sunshine of the Spotless Mind
|
||||
|
@ -1,6 +1,10 @@
|
||||
---
|
||||
author: David Fincher
|
||||
rating: ⭐⭐⭐⭐⭐
|
||||
image: Media/movies/images/fight_club_cover.jpg
|
||||
date: October 15, 1999
|
||||
---
|
||||
|
||||
# Fight Club
|
||||
|
||||
![](Media/movies/images/fight_club_cover.jpg)
|
||||
|
@ -1,7 +1,8 @@
|
||||
---
|
||||
author: Andrew Niccol
|
||||
status: not-seen
|
||||
image: Media/movies/images/gattaca_cover.jpg
|
||||
date: September 7, 1997
|
||||
---
|
||||
|
||||
# Gattaca
|
||||
|
||||
|
@ -3,6 +3,7 @@ author: Jordan Peele
|
||||
date: February 23, 2017
|
||||
rating: ⭐️⭐️⭐️⭐️
|
||||
status: finished
|
||||
image: Media/movies/images/get_out_cover.jpg
|
||||
---
|
||||
|
||||
# Get Out
|
||||
|
@ -1,6 +1,8 @@
|
||||
---
|
||||
status: not-seen
|
||||
author: Ben Affleck
|
||||
image: Media/movies/images/gone_baby_gone_cover.jpg
|
||||
date: September 18, 2007
|
||||
---
|
||||
|
||||
# Gone Baby Gone
|
||||
|
||||
|
8
Media/movies/Good Will Hunting.md
Normal file
8
Media/movies/Good Will Hunting.md
Normal file
@ -0,0 +1,8 @@
|
||||
---
|
||||
date: December 5, 1997
|
||||
image: Media/movies/images/good_will_hunting_cover.jpg
|
||||
author: Gus Van Sant
|
||||
---
|
||||
# Good Will Hunting
|
||||
|
||||
|
@ -3,6 +3,7 @@ author: Spike Jonze
|
||||
date: December 17, 2013
|
||||
rating: ⭐️⭐️⭐️⭐️⭐️
|
||||
status: finished
|
||||
image: Media/movies/images/her_cover.jpg
|
||||
---
|
||||
|
||||
# Her
|
||||
|
@ -1,3 +1,8 @@
|
||||
---
|
||||
date: November 9, 2020
|
||||
image: Media/movies/images/hillbilly_elegie_cover.jpg
|
||||
---
|
||||
|
||||
---
|
||||
author: Ron Howard
|
||||
date: November 12, 2020
|
||||
@ -7,5 +12,4 @@ status: finished
|
||||
|
||||
# Hillbilly Elegie
|
||||
|
||||
#drama
|
||||
|
||||
\#drama
|
||||
|
@ -2,8 +2,9 @@
|
||||
author: Charlie Kaufman, Michel Gondry
|
||||
date: May 17, 2001
|
||||
status: not-seen
|
||||
image: Media/movies/images/human_nature_cover.jpg
|
||||
---
|
||||
|
||||
# Human Nature
|
||||
|
||||
#comedy #drama #indie
|
||||
\#comedy #drama #indie
|
||||
|
@ -3,7 +3,7 @@ author: Jérémy Clapin
|
||||
date: November 6, 2019
|
||||
rating: ⭐️⭐️⭐️⭐️⭐️
|
||||
status: finished
|
||||
image: Media/movies/images/i_lost_my_body_cover.jpg
|
||||
---
|
||||
|
||||
# I Lost My Body
|
||||
|
||||
|
@ -2,7 +2,8 @@
|
||||
author: Charlie Kaufman
|
||||
rating: ⭐️⭐️⭐️⭐️⭐️
|
||||
status: watch-again
|
||||
image: Media/movies/images/im_thinking_of_ending_things_cover.jpg
|
||||
date: August 28, 2020
|
||||
---
|
||||
|
||||
# I'm Thinking of Ending Things
|
||||
|
||||
# Im Thinking of Ending Things
|
||||
|
@ -2,7 +2,8 @@
|
||||
author: Spike Jonze
|
||||
rating: ⭐️⭐️⭐️⭐️
|
||||
status: finished
|
||||
image: Media/movies/images/im_here_cover.jpg
|
||||
date: March 1, 2010
|
||||
---
|
||||
|
||||
# Im Here
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
---
|
||||
rating: ⭐⭐⭐⭐⭐
|
||||
author: Christopher Nolan
|
||||
image: Media/movies/images/inception_cover.jpg
|
||||
date: July 15, 2010
|
||||
---
|
||||
|
||||
# Inception
|
@ -2,6 +2,9 @@
|
||||
rating: ⭐⭐⭐⭐⭐
|
||||
status: finished
|
||||
author: Christopher Nolan
|
||||
image: Media/movies/images/interstellar_cover.jpg
|
||||
---
|
||||
|
||||
# Interstellar
|
||||
|
||||
![](Media/movies/images/interstellar_cover.jpg)
|
||||
|
@ -3,6 +3,7 @@ author: François Truffaut
|
||||
date: January 22, 1962
|
||||
rating: ⭐️⭐️⭐️⭐️⭐️
|
||||
status: Finished
|
||||
image: Media/movies/images/jules_and_jim_cover.jpg
|
||||
---
|
||||
|
||||
# Jules and Jim
|
||||
|
@ -3,8 +3,9 @@ author: Quentin Tarantino
|
||||
date: October 9, 2003
|
||||
rating: ⭐️⭐️⭐️⭐️
|
||||
status: finished
|
||||
image: Media/movies/images/kill_bill_vol_1_cover.jpg
|
||||
---
|
||||
|
||||
# Kill Bill Vol 1
|
||||
|
||||
#crime #action
|
||||
\#crime #action
|
||||
|
@ -3,8 +3,9 @@ author: Rian Johnson
|
||||
date: November 27, 2019
|
||||
rating: ⭐️⭐️⭐️⭐️
|
||||
status: finished
|
||||
image: Media/movies/images/knives_out_cover.jpg
|
||||
---
|
||||
|
||||
# Knives Out
|
||||
|
||||
#crime #comedy #drama #mystery #thriller
|
||||
\#crime #comedy #drama #mystery #thriller
|
||||
|
@ -1,9 +1,11 @@
|
||||
---
|
||||
rating: ⭐️⭐️⭐️⭐️⭐️
|
||||
status: finished
|
||||
author: Godfrey Reggio
|
||||
image: Media/movies/images/koyaanisqatsi_cover.jpg
|
||||
date: August 24, 1983
|
||||
---
|
||||
|
||||
# Koyaanisqatsi
|
||||
|
||||
Gesehen mit David in Valencia, abstrakt ohne direkte Handlung, überraschend kurzweilig
|
||||
|
||||
|
@ -3,6 +3,7 @@ author: Paul Thomas Anderson
|
||||
date: December 17, 1999
|
||||
status: finished
|
||||
rating: ⭐⭐⭐
|
||||
image: Media/movies/images/magnolia_cover.jpg
|
||||
---
|
||||
|
||||
# Magnolia Tree
|
||||
# Magnolia
|
@ -2,7 +2,8 @@
|
||||
author: David Fincher
|
||||
rating: ⭐️⭐️⭐️
|
||||
status: finished
|
||||
image: Media/movies/images/mank_cover.jpg
|
||||
date: November 13, 2020
|
||||
---
|
||||
|
||||
# Mank
|
||||
|
||||
|
@ -3,7 +3,7 @@ author: Hayao Miyazaki
|
||||
date: May 4, 2007
|
||||
rating: ⭐️⭐️⭐️⭐️⭐️
|
||||
status: finished
|
||||
image: Media/movies/images/mein_nachbar_totoro_cover.jpg
|
||||
---
|
||||
|
||||
# Mein Nachbar Totoro
|
||||
|
||||
|
@ -1,2 +1,7 @@
|
||||
# Memento
|
||||
---
|
||||
date: October 11, 2000
|
||||
image: Media/movies/images/memento_cover.jpg
|
||||
author: Christopher Nolan
|
||||
---
|
||||
|
||||
# Memento
|
||||
|
@ -3,6 +3,7 @@ author: Barry Jenkins
|
||||
date: October 20, 2016
|
||||
rating: ⭐️⭐️⭐️⭐️⭐️
|
||||
status: finished
|
||||
image: Media/movies/images/moonlight_cover.jpg
|
||||
---
|
||||
|
||||
# Moonlight
|
||||
|
@ -3,9 +3,9 @@ author: David Lynch
|
||||
date: September 7, 2001
|
||||
rating: ⭐️⭐️⭐️
|
||||
status: finished
|
||||
image: Media/movies/images/mulholland_drive_cover.jpg
|
||||
---
|
||||
|
||||
# Mullholland Drive
|
||||
# Mulholland Drive
|
||||
|
||||
Very abstract, little bit tipsy while writing. Basics: The main actress betty is very jealous because her girlfriend is dating somebody else. Somebodyd dies, or not. There is an accident, or not. And in the end maybe she kills herself. Good overall mood, not as immersive as i would like.
|
||||
|
@ -1,3 +1,8 @@
|
||||
---
|
||||
date: February 1, 1991
|
||||
image: Media/movies/images/my_private_idaho_cover.jpg
|
||||
---
|
||||
|
||||
---
|
||||
author: Gus Van Sant
|
||||
date: September 28, 1991
|
||||
@ -6,4 +11,3 @@ status: finished
|
||||
---
|
||||
|
||||
# My Private Idaho
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
---
|
||||
image: Media/movies/images/oldboy_cover.jpg
|
||||
author: Park Chan-wook
|
||||
date: February 9, 2003
|
||||
rating: ⭐️⭐️⭐️⭐️⭐️
|
||||
@ -6,4 +7,3 @@ status: finished
|
||||
---
|
||||
|
||||
# Oldboy
|
||||
|
||||
|
@ -1,3 +1,8 @@
|
||||
---
|
||||
date: July 24, 2019
|
||||
image: Media/movies/images/once_upon_a_time_in_hollywood_cover.jpg
|
||||
---
|
||||
|
||||
---
|
||||
author: Quentin Tarantino
|
||||
date: July 25, 2019
|
||||
@ -7,4 +12,4 @@ status: finished
|
||||
|
||||
# Once Upon a Time… in Hollywood
|
||||
|
||||
#comedy #drama
|
||||
\#comedy #drama
|
||||
|
@ -2,8 +2,9 @@
|
||||
author: Miloš Forman
|
||||
date: November 17, 1975
|
||||
status: not-seen
|
||||
image: Media/movies/images/one_flew_over_the_cuckoos_nest_cover.jpg
|
||||
---
|
||||
|
||||
# One Flew Over the Cuckoo's Nest
|
||||
# One Flew Over the Cuckoos Nest
|
||||
|
||||
#drama
|
||||
\#drama
|
||||
|
@ -1 +1,8 @@
|
||||
---
|
||||
status: not-seen
|
||||
author: Hayao Miyazaki
|
||||
image: Media/movies/images/ponyo_cover.jpg
|
||||
date: July 19, 2008
|
||||
---
|
||||
|
||||
# Ponyo
|
||||
|
@ -3,6 +3,7 @@ author: Christopher Caldwell, Zeek Earl
|
||||
date: October 2, 2018
|
||||
rating: ⭐️⭐️⭐️⭐️
|
||||
status: finished
|
||||
image: Media/movies/images/prospect_cover.jpg
|
||||
---
|
||||
|
||||
# Prospect
|
||||
|
@ -3,8 +3,9 @@ author: Quentin Tarantino
|
||||
date: September 9, 1994
|
||||
rating: ⭐️⭐️⭐️⭐️⭐️
|
||||
status: finished
|
||||
image: Media/movies/images/pulp_fiction_cover.jpg
|
||||
---
|
||||
|
||||
# Pulp Fiction
|
||||
|
||||
#crime #thriller
|
||||
\#crime #thriller
|
||||
|
@ -2,7 +2,7 @@
|
||||
author: Darren Aronofsky
|
||||
date: October 5, 2000
|
||||
status: not-seen
|
||||
image: Media/movies/images/requiem_for_a_dream_cover.jpg
|
||||
---
|
||||
|
||||
# Requiem for a Dream
|
||||
|
||||
|
@ -1,7 +1,8 @@
|
||||
---
|
||||
Author: Quentin Tarantino
|
||||
author: Quentin Tarantino
|
||||
date: September 1, 1992
|
||||
status: not-seen
|
||||
image: Media/movies/images/reservoir_dogs_cover.jpg
|
||||
---
|
||||
|
||||
# Reservoir Dogs
|
||||
|
@ -1,8 +1,11 @@
|
||||
---
|
||||
date: August 25, 2018
|
||||
author: Alfonso Cuarón
|
||||
status: not-seen
|
||||
date: December 6, 2018
|
||||
image: Media/movies/images/roma_cover.jpg
|
||||
---
|
||||
|
||||
# Roma
|
||||
|
||||
#movie
|
||||
![](Media/movies/images/roma_cover.jpg)
|
||||
|
9
Media/movies/Seven Pounds.md
Normal file
9
Media/movies/Seven Pounds.md
Normal file
@ -0,0 +1,9 @@
|
||||
---
|
||||
date: December 18, 2008
|
||||
image: Media/movies/images/seven_pounds_cover.jpg
|
||||
author: Gabriele Muccino
|
||||
---
|
||||
# Seven Pounds
|
||||
![](Media/movies/images/seven_pounds_cover.jpg)
|
||||
|
||||
|
@ -3,6 +3,8 @@ author: Guy Ritchie
|
||||
published: 23 August, 2000
|
||||
rating: ⭐️⭐️⭐️
|
||||
status: Finished
|
||||
image: Media/movies/images/snatch_cover.jpg
|
||||
date: September 1, 2000
|
||||
---
|
||||
|
||||
# Snatch
|
||||
|
@ -1 +1,7 @@
|
||||
---
|
||||
date: April 18, 1973
|
||||
image: Media/movies/images/soylent_green_cover.jpg
|
||||
author: Richard Fleischer
|
||||
---
|
||||
|
||||
# Soylent Green
|
@ -3,7 +3,7 @@ author: Billy Wilder
|
||||
date: August 9, 1950
|
||||
rating: ⭐️⭐️
|
||||
status: finished
|
||||
image: Media/movies/images/sunset_boulevard_cover.jpg
|
||||
---
|
||||
|
||||
# Sunset Boulevard
|
||||
|
||||
![](Media/movies/images/sunset_boulevard_cover.jpg)
|
@ -1 +1,7 @@
|
||||
---
|
||||
date: September 24, 2009
|
||||
image: Media/movies/images/surrogates_cover.jpg
|
||||
author: Jonathan Mostow
|
||||
---
|
||||
|
||||
# Surrogates
|
@ -2,8 +2,11 @@
|
||||
author: Dario Argento
|
||||
date: January 31, 1977
|
||||
status: not-seen
|
||||
image: Media/movies/images/suspiria_cover.jpg
|
||||
---
|
||||
|
||||
# Suspiria
|
||||
|
||||
![](Media/movies/images/suspiria_cover.jpg)
|
||||
|
||||
#horror #mystery #thriller
|
||||
|
@ -3,6 +3,7 @@ author: Nora Fingscheidt
|
||||
date: September 19, 2019
|
||||
rating: ⭐️⭐️⭐️⭐️
|
||||
status: finished
|
||||
image: Media/movies/images/system_crasher_cover.jpg
|
||||
---
|
||||
|
||||
# System Crasher
|
||||
|
@ -3,6 +3,7 @@ author: Ethan Coen, Joel Coen
|
||||
date: November 8, 2018
|
||||
rating: ⭐️⭐️⭐️⭐️
|
||||
status: Finished
|
||||
image: Media/movies/images/the_ballad_of_buster_scruggs_cover.jpg
|
||||
---
|
||||
# The Ballad of Buster Scruggs
|
||||
|
||||
# The Ballad of Buster Scruggs
|
||||
|
@ -3,7 +3,7 @@ author: Ofir Raul Graizer
|
||||
date: December 28, 2017
|
||||
rating: ⭐️⭐️⭐️⭐️⭐️
|
||||
status: finished
|
||||
image: Media/movies/images/the_cakemaker_cover.jpg
|
||||
---
|
||||
|
||||
# The Cakemaker
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user