<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Elia Scotto</title><description>Essays, reviews, and tech articles</description><link>https://scotto.me/</link><item><title>A conversation between two human beings</title><link>https://scotto.me/notes/2026-07-24-a-conversation-between-two-human-beings/</link><guid isPermaLink="true">https://scotto.me/notes/2026-07-24-a-conversation-between-two-human-beings/</guid><description>A conversation between two human beings</description><pubDate>Fri, 24 Jul 2026 13:34:50 GMT</pubDate><content:encoded>&lt;p&gt;import QuoteBack from &amp;quot;../../components/QuoteBack.astro&amp;quot;;&lt;/p&gt;
&lt;p&gt;&lt;QuoteBack
  author=&quot;Tom MacWright&quot;
  title=&quot;Accidental Anonymity&quot;
  cite=&quot;https://macwright.com/2026/06/24/accidental-anonymity&quot;
  content=&quot;People capable of liking some paintings or prints or whatever can rarely do so without knowing something about the artist. Again, the situation is social rather than scientific. Any work of art is half of a conversation between two human beings, and it helps a lot to know who is talking at you. Does he or she have a reputation for seriousness, for religiosity, for suffering, for concupiscence, for rebellion, for sincerity, for jokes?&quot;
/&gt;&lt;/p&gt;
&lt;p&gt;Here is Kurt Vonnegut telling his brother to show his experimental art in public and to use his face, because “pictures are famous for their humanness, and not for their pictureness”.&lt;/p&gt;
&lt;p&gt;Frequently, when I open a book for the first time, I encounter a new author. I need to know something about them: where and when they lived, what they looked like, what they did besides writing, and what else they wrote. I need to have an idea of the kind of person who is going to tell me a story, because understanding a book often requires me to ask why the author wrote it. What was their purpose?&lt;/p&gt;
&lt;p&gt;It’s a bit the same when I read an article on a blog or look at an open-source project. I want to know the human behind it and read something brief about the author.&lt;/p&gt;
&lt;p&gt;&lt;QuoteBack
  author=&quot;Tom MacWright&quot;
  title=&quot;Accidental Anonymity&quot;
  cite=&quot;https://macwright.com/2026/06/24/accidental-anonymity&quot;
  content=&quot;The fear is being found out for being imperfect. The fear is also for being known in general: maybe you&apos;re a real butch tough guy but your art style is playful and tender and you don&apos;t want that side to come out. Maybe your taste is weird or undeveloped and you don&apos;t want anyone to know. But the person who puts nothing out for judgment just isn&apos;t known at all.&quot;
/&gt;&lt;/p&gt;
&lt;p&gt;Tom is right. At a time when the internet is filling up with artificial content, it is even more important to put ourselves out there rather than remain anonymous. Show that you are real, and give others a reason to trust you before asking for their attention.&lt;/p&gt;
</content:encoded></item><item><title>Introducing a new format</title><link>https://scotto.me/notes/2026-07-24-a-new-format/</link><guid isPermaLink="true">https://scotto.me/notes/2026-07-24-a-new-format/</guid><pubDate>Fri, 24 Jul 2026 13:30:48 GMT</pubDate><content:encoded>&lt;p&gt;I decided to add a new section for short notes that don’t deserve an entire post.&lt;/p&gt;
&lt;p&gt;I’ll mostly use it to share thoughts and interesting links, the kind of content that usually works well on social media. Since I don’t use socials much, I’d rather save those things here, where I have full control over them.&lt;/p&gt;
&lt;p&gt;I’ve also updated the RSS feed page, splitting the content into multiple feeds. I’ll add a new one that includes these notes as well, for the most devoted readers.&lt;/p&gt;
</content:encoded></item><item><title>One Tool to Read Them All</title><link>https://scotto.me/blog/2026-07-23-one-tool-to-read-them-all/</link><guid isPermaLink="true">https://scotto.me/blog/2026-07-23-one-tool-to-read-them-all/</guid><description>Looking for a better way to read content online</description><pubDate>Thu, 23 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Reading some of the feedback on my recent article about &lt;a href=&quot;/blog/2026-07-12-how-to-read-more-books/&quot;&gt;reading more books&lt;/a&gt; made me realise how much the tools we use influence the way we read. One observation in the article was about replacing the time spent on your phone with a book and making your phone look boring to help you do that. It’s easy to pick up a phone and scroll, so it should be easy to use it to read more. So why don’t people use it to read books? Because a phone is a pocket computer designed to distract users, a book is a boring technology designed to focus their attention.&lt;/p&gt;
&lt;p&gt;I’m satisfied with the tools I have for reading books. Unfortunately, I can’t say the same for reading online. After all these years, I still haven’t found a single tool that brings together content discovery, following, reading, and exploring a website’s archive.&lt;/p&gt;
&lt;p&gt;My wish for a perfect online reading experience starts with &lt;em&gt;discovering content&lt;/em&gt;. I want to find interesting material to read, and since time is always limited, I want it to be &lt;em&gt;filtered&lt;/em&gt; according to my interests and &lt;em&gt;ranked&lt;/em&gt; in a transparent way that I can directly influence. Then, when I find a good article, I want a good interface to &lt;em&gt;consume&lt;/em&gt; it. Since the reading experience varies from one website to another, I want a clean interface designed to keep me focused. I also want to be able to highlight passages and take notes, to help me remember and make reading more rewarding. I’d like a way to &lt;em&gt;keep track&lt;/em&gt; of the blogs I follow and get &lt;em&gt;notified&lt;/em&gt; when they publish new content. Lastly, I want a tool that treats &lt;em&gt;older&lt;/em&gt; content as &lt;em&gt;relevant&lt;/em&gt; as newer content. A tool that doesn’t force me to prioritise the latest article.&lt;/p&gt;
&lt;p&gt;This last point is really important to me, since I haven’t found anything yet that tries to solve this problem. Relevant content can be found in the entire archive of a blog, not just in the latest posts. Just as I reach for old books considered classics because they have stood the test of time, I often find articles published years ago still relevant. But to discover those articles, I have to rely on other people’s recommendations or hope that the website I’m visiting has an archive page. Without either, old content could stay buried forever on the web.&lt;/p&gt;
&lt;p&gt;Most of the tools and platforms we use are designed to show content sorted by &lt;em&gt;publication date&lt;/em&gt;, as if it has to be fresh to be worthwhile. And it’s not always an algorithmic decision. Often, it’s simply how the technology has been designed. For how I like to read, the date is just one of the factors that contributes to the value of an article. In some fields, I might prioritise recent content. In others, I’d prefer something that has remained relevant for years, since time can be a sign that an idea has held up. I would like a boring technology that makes reading online a more focused activity, where content is valuable regardless of its novelty. A tool that doesn’t force design decisions or hide content behind algorithmic selection.&lt;/p&gt;
&lt;h2&gt;Discovery&lt;/h2&gt;
&lt;p&gt;The most common solution to fix the discoverability problem is the &lt;em&gt;feed&lt;/em&gt;. It’s the algorithm that decides what content users see on the social media platforms. It helps people find information relevant to their interests and tailor the platform to their needs. The issue is that users have no control over the algorithms. They don’t know why certain content is shown to them, and they cannot directly influence the choice.&lt;/p&gt;
&lt;p&gt;One system I’ve found effective is link aggregators, because they rely on simpler algorithms and usually have a clear interface. I mostly use Hacker News to find new blogs and relevant content in the tech fields. The most interesting articles are ranked daily by the community, where I can contribute directly with my votes and join discussions using the comment system. But when I have to find content unrelated to technology, I don’t have a valid alternative. I have to resort to social-media, video platforms, search engines, hoping that they will do a good job at choosing what I’m looking for.&lt;/p&gt;
&lt;h2&gt;Following&lt;/h2&gt;
&lt;p&gt;The concept of feeds was already used to deliver content before social media. RSS feeds have been used to &lt;em&gt;follow&lt;/em&gt; websites and blogs since the 2000s. Users can subscribe to a website by adding its feed to an RSS reader and get notified whenever something new is published. The main distinction from social media algorithms is that RSS feeds are not a content discovery mechanism, but a &lt;em&gt;subscription&lt;/em&gt; system. Users control which publications they subscribe to, rather than relying on algorithms controlled by platforms.&lt;/p&gt;
&lt;p&gt;What I like about RSS is that it keeps track of the blogs I follow, but beyond that the experience is inconsistent: some feeds contain full articles, others only previews, some include years of archives, and others just the most recent posts. On top of that, RSS readers are designed to prioritise new content, emphasising unread counts and showing the newest articles first. Using RSS feeds might free us from the algorithms, but not from the persistent feeling that we need to keep up with whatever is new.&lt;/p&gt;
&lt;p&gt;RSS apps let users read articles without distractions. But in doing so, readers may never visit the authors’ websites. They might miss features not available in the RSS reader, and their visits might not count for the website’s analytics. Over time, this can end up giving authors less incentive to improve the reading experience on their websites.&lt;/p&gt;
&lt;h2&gt;Reading&lt;/h2&gt;
&lt;p&gt;To improve my reading experience, I rely on read-it-later apps. Instapaper is my favourite so far. It offers a clean and consistent interface across different websites, with useful features like highlights and notes. I’ve saved hundreds of articles over the years, and it’s quite handy to save an article on the desktop and read it later on the tablet or the phone. It works by grabbing the page I’m visiting right now, so if I can read it, Instapaper can likely read it too. The problem is that it does not contribute to content discovery, or following either, since it doesn’t track updates or notify me when new content appears, or help me find more content.&lt;/p&gt;
&lt;h2&gt;Centralised platforms&lt;/h2&gt;
&lt;p&gt;Some startups tried to address all the challenges together, creating publishing platforms on the web. One example is Substack, which offers most of the tools needed to write, to read, to find content and even allows users to escape the algorithmic feed trap with personalised newsletters. That said, the price that readers and writers have to pay for the platform is giving up control over the space where they put the content. &lt;/p&gt;
&lt;p&gt;If all online content gets centralised on a single platform, users will become dependent on it, having to accept whatever product decisions the company might make. There would also be less individuality than there is on the small web, where bloggers and passionate people customise their own websites, potentially controlling every single detail of them. Finally, the incentives these platforms create still push authors to constantly produce new content rather than focus on creating something refined and durable. They still have algorithmic feeds and email marketing that make new content more important by design.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;For now, my online reading remains scattered through many apps and platforms. However, I imagined a solution that has the potential to unify a few of the components of reading online discussed above. It does not have to be another platform or app, but rather something that we all already use to access the internet; the browser.&lt;/p&gt;
&lt;p&gt;Centralised platforms tried to solve the integration problem by putting all the content into a single interconnected system, which is exactly what the web already does. And the web also already partially solved content discovery, since search engines, social media, recommendation platforms and link aggregators are already playing a part. The solution in this case is not to look at the web itself, but observe the problem one layer up. It has to live in the interface we use to access the web. The browser is the layer that sits between readers and independent websites. Modern browsers render pages perfectly, integrate bookmarks, can grab RSS instantly, and most of them already integrate a &lt;em&gt;reading mode&lt;/em&gt; for articles. Connecting these components together is the key to creating a perfect tool to read online, without removing the website itself from the experience. A browser could let me follow a website directly, notify me when it publishes something new, give me a clean place to read it, and let me browse the entire archive without treating the newest articles as inherently more important.&lt;/p&gt;
&lt;p&gt;We saw a recent wave of new browsers that mostly offered UI makeovers on top of existing engines (Blink and Webkit). Maybe a differentiator for the next browser, instead of improving usability or privacy, might be to help people to follow and read more valuable content online.&lt;/p&gt;
&lt;p&gt;Curious to hear your thoughts.&lt;/p&gt;
</content:encoded></item><item><title>A Road to Lisp: Which Lisp</title><link>https://scotto.me/blog/2026-07-17-which-lisp/</link><guid isPermaLink="true">https://scotto.me/blog/2026-07-17-which-lisp/</guid><description>Comparison of modern Lisp dialects</description><pubDate>Fri, 17 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Most programming languages evolve as a single language. Python, Java, Javascript, C++, have new versions and standards, multiple implementations, but they still remain the same language. C and C++ can be compiled with GCC or Clang, Python can be compiled with CPython or PyPy, the same JavaScript runs in both Firefox and Chrome, and Java programs can run on JVM or GraalVM.&lt;/p&gt;
&lt;p&gt;Lisp is not like that.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/lisp-logo.svg&quot; alt=&quot;[Lisp Logo]&quot; title=&quot;Lisp logo, NASA version.&quot;&gt;&lt;/p&gt;
&lt;p&gt;The &lt;a href=&quot;https://en.wikipedia.org/wiki/Lisp_(programming_language)&quot;&gt;Wikipedia&lt;/a&gt; page lists more than 20 different &lt;em&gt;dialects&lt;/em&gt;, which means there are many variations to choose from. That’s because &lt;strong&gt;Lisp is a &lt;em&gt;family&lt;/em&gt; of programming languages&lt;/strong&gt;. They share the same fundamental syntax but differ in their operators, semantics, standard libraries, and language capabilities.&lt;/p&gt;
&lt;p&gt;One of the main concerns Lisp beginners have is which dialect to learn first. I see this question frequently asked in online forums. The answer is that the dialect matters, but not as much as a beginner might think. Learning Lisp is about learning a new type of programming. &lt;strong&gt;A new way of thinking about problems using code.&lt;/strong&gt; You will learn the fundamental concepts with any dialect. Then, once you have learned one, it will be relatively easy to switch to another.&lt;/p&gt;
&lt;p&gt;I will briefly present the most relevant dialects that are actively used and maintained. I’ll try to highlight their strengths and weaknesses to help you overcome your indecision and pick one to start your Lisp journey. &lt;/p&gt;
&lt;p&gt;If you are a beginner, many of the concepts in this article might be completely new to you. Don’t worry too much about them yet. When I was a beginner, I found many of these concepts fascinating and they pushed me to learn more about the Lisp world.&lt;/p&gt;
&lt;h2&gt;Common Lisp&lt;/h2&gt;
&lt;p&gt;Abbreviated as CL, it is the most mature and comprehensive of all Lisp dialects. It’s considered the old-school Lisp, since the language — I will call it a &lt;em&gt;language&lt;/em&gt; from now on — was standardised in 1994 with a formal ANSI specification. Thanks to this standardisation, there are multiple implementations of Common Lisp targeting different platforms and use cases.&lt;/p&gt;
&lt;p&gt;The most famous implementation is &lt;em&gt;SBCL&lt;/em&gt;, which compiles directly to native code. It is fast, open-source, and compatible with modern hardware. With it, well-written Common Lisp code can achieve performance comparable to C and Rust. Because SBCL optimises heavily, it compiles a bit more slowly than other implementations but generates some of the fastest code in the Lisp family.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/common-lisp-logo.svg&quot; alt=&quot;[Common Lisp Logo]&quot; title=&quot;The Yin and Yang Common Lisp logo. The lambda symbol (λ) refer to lambda calculus invented by Alonzo Church.&quot;&gt;&lt;/p&gt;
&lt;p&gt;When I said above that Common Lisp is the most comprehensive dialect, I meant that it offers the broadest set of features among all Lisps. It provides a large amount of functionality out of the box, much of it defined directly in the standard. For example, CL has functions for controlling compilation and evaluation from within the language itself (&lt;code&gt;COMPILE&lt;/code&gt;, &lt;code&gt;LOAD&lt;/code&gt;, &lt;code&gt;EVAL&lt;/code&gt;, &lt;code&gt;COMPILE-FILE&lt;/code&gt;, and others). This means that I can use these functions in my code or at the REPL to tell the Lisp process to compile a function, load a file, or evaluate some code. CL also provides &lt;code&gt;DISASSEMBLE&lt;/code&gt;, which lets you inspect the machine code generated for a compiled function.&lt;/p&gt;
&lt;p&gt;Common Lisp has a condition and restart system, which is one of the most powerful way I ever saw to debug and inspect programs. If a condition occurs during execution, the Lisp process might stop and let you inspect the state of the program and its variables at that point in time. You can then choose to restart the program and maybe retry the operation, or ignore the condition and continue execution. This is also possible because the Common Lisp REPL is deeply integrated with the running system. If your program fails on a remote server, you can connect to its REPL and inspect the live process to understand what went wrong.&lt;/p&gt;
&lt;p&gt;Common Lisp supports all major programming paradigms, like functional, imperative, metaprogramming, and object-oriented programming. It offers one of the most advanced object systems, called &lt;a href=&quot;https://courses.cs.northwestern.edu/325/readings/clos.html&quot;&gt;CLOS&lt;/a&gt;, which supports features such as multiple dispatch and generic functions. This makes OOP more flexible than in common object-oriented languages such as Java or C++. It is also worth noting that Common Lisp is dynamically typed but has a rich and expressive type system with optional type declarations.&lt;/p&gt;
&lt;p&gt;Standardisation means that the language is stable. The ANSI Common Lisp from 1994 is still the one in use today. Because of it, lispers rarely fall victim to &lt;em&gt;backward incompatibility&lt;/em&gt;, and old Common Lisp code often still runs perfectly today. For example, if you go through old Lisp books such as &lt;a href=&quot;https://github.com/norvig/paip-lisp&quot;&gt;PAIP&lt;/a&gt; by Peter Norvig, published in 1991, you’ll find that much of the code still runs on modern implementations. With Common Lisp, you encounter far fewer of the incompatibilities typical of languages like Ruby and Python. Even Common Lisp libraries that haven’t been updated recently will often still run fine on your system because they don’t need to be continually adapted to new versions of the language.&lt;/p&gt;
&lt;p&gt;Common Lisp lacks some conveniences that have become common in newer languages, such as concise literals for a wider variety of data structures, persistent immutable collections, lazy sequences and built-in general-purpose pattern matching. Common Lisp was designed in the 1980s by consolidating several existing Lisp dialects into a single language. Its designers chose to retain much of the syntax and patterns of those older dialects, making sure that existing Lisp programmers could adopt the language without having to learn a completely new syntax.&lt;/p&gt;
&lt;p&gt;Common Lisp doesn’t have a central direction or corporate sponsor. The community is relatively small and spread across several implementations, projects and communication channels. It’s mostly made up of volunteers who help keep the language alive. It can be a bit difficult to find guides and help: tutorials are often either too simple or too advanced, and documentation is not always easy to find.&lt;/p&gt;
&lt;p&gt;It’s currently used in &lt;a href=&quot;https://www.youtube.com/watch?v=svmPz5oxMlI&quot;&gt;quantum computing&lt;/a&gt; at &lt;a href=&quot;https://www.rigetti.com/&quot;&gt;Rigetti Computing&lt;/a&gt;, and has been used at &lt;a href=&quot;https://www.grammarly.com/blog/engineering/running-lisp-in-production/&quot;&gt;Grammarly&lt;/a&gt; for its core grammar service and also powers &lt;a href=&quot;https://www.itasoftware.com/&quot;&gt;Google Flight Search&lt;/a&gt;. Worth mentioning is &lt;a href=&quot;https://codeberg.org/shirakumo/kandria&quot;&gt;Kandria&lt;/a&gt;, an open-source video game released on Steam and written entirely in Common Lisp. &lt;/p&gt;
&lt;p&gt;An interesting fact: Paul Graham originally wrote HackerNews in a custom Lisp dialect called Arc, based on Racket. Today, Daniel Gackle (&lt;a href=&quot;https://news.ycombinator.com/user?id=dang&quot;&gt;@dang&lt;/a&gt;) reimplemented it in Clarc, a Common Lisp implementation of Arc that runs on SBCL&lt;a href=&quot;https://news.ycombinator.com/item?id=41683969&quot;&gt;^1&lt;/a&gt;, serving around 10 million pages per day.&lt;/p&gt;
&lt;h3&gt;Where Common Lisp shines&lt;/h3&gt;
&lt;p&gt;CL compiles to native code on all major operating systems and can achieve fast execution, at the cost of slightly slower startup times, so it’s great for long-running processes. It offers one of the most powerful REPLs among Lisp dialects and can be considered, despite its steep learning curve, one of the fastest languages for writing solid software in a short time.&lt;/p&gt;
&lt;p&gt;CL shines when you need to do research and prototyping with quick iterations, as in quantum computing, or when the specifications aren’t fully defined yet and change frequently, requiring the software to adapt quickly, as in startups. Paul Graham wrote a famous and inspiring &lt;a href=&quot;https://www.paulgraham.com/avg.html&quot;&gt;article&lt;/a&gt; about how Common Lisp helped his internet startup beat the competition.&lt;/p&gt;
&lt;h3&gt;Learning resources&lt;/h3&gt;
&lt;p&gt;A good starting point is &lt;a href=&quot;https://stevelosh.com/blog/2018/08/a-road-to-common-lisp/&quot;&gt;A Road to Common Lisp&lt;/a&gt; by Steve Losh, which inspired me to write this series. One of the most accessible books for beginners is &lt;a href=&quot;https://gigamonkeys.com/book/&quot;&gt;Practical Common Lisp&lt;/a&gt; by Peter Seibel, which is available entirely online. It’s the best introduction to the language I’ve read, as the most important concepts are neatly separated into chapters. A more playful introduction is &lt;a href=&quot;http://landoflisp.com/&quot;&gt;Land of Lisp&lt;/a&gt;, which uses funny characters and comics to teach programming through games. A more advanced book that I enjoyed is &lt;a href=&quot;https://www.paulgraham.com/onlisp.html&quot;&gt;On Lisp&lt;/a&gt; by Paul Graham, which is entirely dedicated to macros.&lt;/p&gt;
&lt;p&gt;The best IDE support for CL is Emacs + &lt;a href=&quot;https://github.com/joaotavora/sly&quot;&gt;Sly&lt;/a&gt;/&lt;a href=&quot;https://slime.common-lisp.dev/&quot;&gt;Slime&lt;/a&gt; (&lt;a href=&quot;https://github.com/doomemacs/doomemacs&quot;&gt;Doom&lt;/a&gt; already has support for it) or Vim + &lt;a href=&quot;https://github.com/vlime/vlime&quot;&gt;VLime&lt;/a&gt;. A weaker alternative is VSCode + &lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=rheller.alive&quot;&gt;Alive&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;One of the best resources for beginners is &lt;a href=&quot;https://lispcookbook.github.io/cl-cookbook/&quot;&gt;The Common Lisp Cookbook&lt;/a&gt;, which has many up-to-date tutorials. For references and libraries, the &lt;a href=&quot;https://github.com/CodyReichert/awesome-cl&quot;&gt;Awesome-CL&lt;/a&gt; list is worth a look. I also printed my own copy of the &lt;a href=&quot;http://clqr.boundp.org/&quot;&gt;Common Lisp Quick Reference&lt;/a&gt; booklet, which can be faster than finding information in the CL &lt;a href=&quot;https://www.lispworks.com/documentation/HyperSpec/Front/index.htm&quot;&gt;HyperSpec&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Clojure&lt;/h2&gt;
&lt;p&gt;Rich Hickey created it during a sabbatical year, frustrated by clients refusing to let him use Common Lisp instead of Java and C# because they were concerned about compatibility and maintenance issues. So he decided to write a new Lisp language targeting the JVM, allowing it to access everything the Java ecosystem had built over decades and making it a practical language from the start. The deal is that Clojure provides the language, while the host platform — the JVM — provides the runtime.&lt;/p&gt;
&lt;p&gt;Clojure compiles directly to JVM bytecode, which means it’s compatible with any codebase that runs on the JVM (Java, Kotlin, Scala). This compatibility means that Clojure can coexist with other JVM languages in the same codebase, use Java libraries directly, and access all the features the JVM offers, such as OS portability, garbage collection, a fast and optimised runtime, and so on.&lt;/p&gt;
&lt;p&gt;Rich Hickey chose to target the JVM so that he didn&amp;#39;t have to reinvent the wheel and build a new compiler for Clojure from scratch. Instead, he focused his efforts on reading research papers on language design and data structures, bringing some of the newest and most effective ideas into the language.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/clojure-logo.svg&quot; alt=&quot;[Clojure Logo]&quot; title=&quot;The Clojure logo, designed by Tom Hickey, Rich&amp;#39;s brother.&quot;&gt;&lt;/p&gt;
&lt;p&gt;The language at its core is composed of &lt;strong&gt;pure functions operating on immutable data structures&lt;/strong&gt;. Instead of making mutable objects the primary way to represent changing state, it provides explicit mechanisms such as &lt;em&gt;atoms&lt;/em&gt;, &lt;em&gt;refs&lt;/em&gt; and &lt;em&gt;agents&lt;/em&gt; for managing change. This design choice makes Clojure a &lt;em&gt;functional&lt;/em&gt; programming language. It supports object-oriented programming, but replaces class-based inheritance with abstractions such as protocols and multimethods. Also the syntax is more modern than Common Lisp’s, with richer literals, destructuring, and overall more compact code.&lt;/p&gt;
&lt;p&gt;Clojure also comes with several new features. Its persistent data structures use structural sharing, making immutable updates efficient. It also uses lazy sequences, which allow computations to be performed only when their results are needed. It has strong support for concurrency through constructs such as &lt;em&gt;atoms&lt;/em&gt;, &lt;em&gt;refs&lt;/em&gt;, &lt;em&gt;agents&lt;/em&gt; and &lt;em&gt;futures&lt;/em&gt;, and provides &lt;em&gt;records&lt;/em&gt; and custom data types when more structured data is needed. &lt;a href=&quot;https://github.com/edn-format/edn&quot;&gt;EDN&lt;/a&gt; (Extensible Data Notation) offers a simple extensible data format based on Clojure’s literals, a better lispy alternative to JSON, YAML and similar. Clojure doesn&amp;#39;t have types, but &lt;code&gt;clojure.spec&lt;/code&gt; can be used to describe, validate and generate data without introducing a static type system, useful in large applications.&lt;/p&gt;
&lt;p&gt;Rich Hickey designed Clojure with the intention of prioritising stability, similar to what standardisation did for Common Lisp. Even though the language is actively developed, you don’t need to expect major deprecations when updating to a newer version, since the maintainers preserve backwards compatibility and mostly add new features through core libraries.&lt;/p&gt;
&lt;p&gt;Since Clojure is designed to be hosted on other platforms, it can be ported to other runtimes, like the JavaScript engine that runs in your browser. &lt;em&gt;ClojureScript&lt;/em&gt; is a Clojure compiler that targets JavaScript rather than the JVM, so the same language can run on both the server and the browser. This means that Clojure can be used as a full-stack language.&lt;/p&gt;
&lt;p&gt;The JVM integration is great, but it comes with some trade-offs. Error messages are contaminated with a lot of Java implementation details and aren’t always self-explanatory, so stack traces are not necessarily helpful when debugging issues. Java profilers like YourKit are compatible, but even there you will see a lot of Java classes, and it can be hard to map them back to the code you wrote.&lt;/p&gt;
&lt;p&gt;In general you don’t need to know Java to learn Clojure. I didn’t know Java when I started and never had substantial problems because of that. However, knowing how to tweak the JVM can be helpful when doing performance tuning on the server.&lt;/p&gt;
&lt;p&gt;The community around Clojure is small but active and happy to help newcomers pick up the language quickly. It’s known as &lt;em&gt;Clojurians&lt;/em&gt; and mostly hangs out on Slack, where you can also collaborate on open-source projects and find job opportunities.&lt;/p&gt;
&lt;p&gt;Clojure is actively used by companies and startups around the world, and it’s probably the most widely used Lisp in production. Some big names include Nubank (one of the largest fintech companies in Latin America), which acquired Cognitect (the main sponsor of Clojure’s development), as well as Walmart, Netflix, Apple, Salesforce, Amazon, Cisco, and Grammarly.&lt;/p&gt;
&lt;h3&gt;Where Clojure shines&lt;/h3&gt;
&lt;p&gt;Clojure shines in large software systems where the workload consists of a lot of data processing, or more broadly, anywhere you might previously have picked Java. Code can be written and tested quickly through continuous iteration thanks to the REPL, making the language suitable for delivering reliable solutions in less time. Its immutable design helps eliminate some of the hardest concurrency bugs, while its functional orientation guides programmers towards writing programs as a series of data transformations.&lt;/p&gt;
&lt;p&gt;Clojure is great in fields where operations need to happen quickly and often involve processing large sets of data, such as finance and trading. It’s also great for startups solving domain-specific problems with complex logic, since the language’s extensibility allows it to be modelled around the problem.&lt;/p&gt;
&lt;h3&gt;Learning resources&lt;/h3&gt;
&lt;p&gt;To give Clojure a try, you might want to check out &lt;a href=&quot;https://tryclojure.org/&quot;&gt;Try Clojure&lt;/a&gt;, then solve some exercises like the &lt;a href=&quot;http://clojurekoans.com/&quot;&gt;Clojure Koans&lt;/a&gt;, followed by &lt;a href=&quot;https://4clojure.oxal.org/&quot;&gt;4Clojure&lt;/a&gt; for more advanced stuff.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&quot;https://clojure.org/index&quot;&gt;official website&lt;/a&gt; offers some of the most curated material you can find, with great explanations of all the core features and the motivations behind the design choices that make the language special. Clojure also has one of the best &lt;a href=&quot;https://clojuredocs.org/&quot;&gt;documentation&lt;/a&gt; websites I’ve ever found for a language. All the core library functions come with docstrings, and the community has added usage examples, so you can quickly grasp what each function does.&lt;/p&gt;
&lt;p&gt;The best &lt;em&gt;pitch&lt;/em&gt; for the language is &lt;a href=&quot;https://yogthos.net/ClojureDistilled.html&quot;&gt;Clojure Distilled&lt;/a&gt;. It’s probably one of the shortest explanations of what Clojure has to offer.&lt;/p&gt;
&lt;p&gt;After the release of Clojure, Rich Hickey became famous for a series of talks about software design, in which he shared his deep expertise in fundamental topics like simplicity in software design, state and time, databases, concurrency, and language design. Some of his best talks — &lt;a href=&quot;https://www.youtube.com/watch?v=SxdOUGdseq4&quot;&gt;&lt;em&gt;Simple Made Easy&lt;/em&gt;&lt;/a&gt;, &lt;a href=&quot;https://www.youtube.com/watch?v=-6BsiVyC1kM&quot;&gt;&lt;em&gt;The Value of Values&lt;/em&gt;&lt;/a&gt;, &lt;a href=&quot;https://www.youtube.com/watch?v=f84n5oFoZBc&quot;&gt;&lt;em&gt;Hammock-Driven Development&lt;/em&gt;&lt;/a&gt;, &lt;a href=&quot;https://www.youtube.com/watch?v=ScEPu1cs4l0&quot;&gt;&lt;em&gt;Are We There Yet?&lt;/em&gt;&lt;/a&gt;, and &lt;a href=&quot;https://www.youtube.com/watch?v=QCwqnjxqfmY&quot;&gt;&lt;em&gt;Design, Composition, and Performance&lt;/em&gt;&lt;/a&gt;. I highly recommend spending some time watching them, whether you choose Clojure or not.&lt;/p&gt;
&lt;p&gt;Some good books are &lt;a href=&quot;https://www.braveclojure.com/&quot;&gt;Clojure for the Brave and True&lt;/a&gt; by Daniel Higginbotham, which is free to read online and good for beginners. The one I bought is &lt;a href=&quot;https://www.amazon.com/dp/1617291412&quot;&gt;The Joy of Clojure&lt;/a&gt;, which is recommended for programmers who come from OOP languages like Java.&lt;/p&gt;
&lt;p&gt;For editors, VSCode has &lt;a href=&quot;https://calva.io/&quot;&gt;Calva&lt;/a&gt;, a complete and rich extension for Clojure. If you use Emacs you can use &lt;a href=&quot;https://cider.mx/&quot;&gt;Cider&lt;/a&gt;, plus there are extensions available for most editors/IDEs.&lt;/p&gt;
&lt;h2&gt;Racket&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://racket-lang.org/&quot;&gt;Racket&lt;/a&gt; is a modern dialect descended of &lt;em&gt;Scheme&lt;/em&gt;. While other Scheme dialects are generally small languages, Racket has evolved into a fully featured language with its own unique features.&lt;/p&gt;
&lt;p&gt;The code is compiled on every major platform and the language has been used in a lot of fields to create web applications, graphical interfaces, database integrations and mostly to quickly develop tools with graphics.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/racket-logo.svg&quot; alt=&quot;[Racket Logo]&quot; title=&quot;Racket logo.&quot;&gt;&lt;/p&gt;
&lt;p&gt;Racket is &lt;strong&gt;language-oriented&lt;/strong&gt;, which means it’s designed for creating &lt;a href=&quot;https://racket-lang.org/languages.html&quot;&gt;new programming languages&lt;/a&gt;. Every source file begins with &lt;code&gt;#lang&lt;/code&gt;, which defines the language used by that module. You can create entirely new languages with their own syntax and semantics, while still using the Racket ecosystem underneath. Other Lisp dialects can easily build DSLs, but they are tied to Lisp. Racket advances the concept by making it easy to define completely new languages, without requiring them to use Lisp syntax.&lt;/p&gt;
&lt;p&gt;Racket also comes with a wide range of features. It includes libraries for cross-platform GUIs, web servers, concurrency and parallelism, regular expressions, pattern matching, classes and objects, and an FFI for calling C code. Its package manager is integrated into the ecosystem, and a large collection of libraries is immediately available. Compared with other Lisp dialects, there is generally less setup required before you can start building something substantial.&lt;/p&gt;
&lt;p&gt;Racket offers an advanced macro system, providing the same kind of macro support as other dialects, plus hygienic macros. &lt;em&gt;Hygienic&lt;/em&gt; means that identifiers introduced by a macro don’t accidentally capture those in the surrounding code. This makes macros safer to write, especially for beginners, that don’t have to rely on &lt;code&gt;gensym&lt;/code&gt; like in the other dialects.&lt;/p&gt;
&lt;p&gt;Static typing is supported with &lt;a href=&quot;https://docs.racket-lang.org/ts-guide/&quot;&gt;Typed Racket&lt;/a&gt;, a typed variant of the language that lets programmers add type annotations and have their code checked before execution. Typed and untyped Racket modules can also work together, so typing can be introduced where it is useful without requiring an entire program to be rewritten.&lt;/p&gt;
&lt;p&gt;Even though Racket comes from the Scheme tradition and has strong functional programming roots, it supports multiple paradigms. Programs can be written using imperative programming, objects and classes, functional techniques, and metaprogramming.&lt;/p&gt;
&lt;p&gt;The language installation comes with &lt;a href=&quot;https://docs.racket-lang.org/drracket/&quot;&gt;DrRacket&lt;/a&gt;, a great IDE with everything ready to use the language, available on all major platforms. It combines an editor, REPL, and debugger, in a single programming environment for writing and testing Racket code.&lt;/p&gt;
&lt;p&gt;The main downsides are its small ecosystem and limited use in the industry. There are fewer libraries, projects and jobs compared to more popular languages. Performance and deployment can also be weaker points, especially compared with other compiled dialects.&lt;/p&gt;
&lt;h3&gt;Where Racket shines&lt;/h3&gt;
&lt;p&gt;Racket shines when designing new programming languages, building compilers and interpreters, or experimenting with new language features. This makes it particularly popular in computer science education and university research. Also, since it’s language-oriented, it’s a great choice when a program needs to provide a simple DSL, for example for customisation, without forcing the user to use a Lisp dialect.&lt;/p&gt;
&lt;p&gt;Racket is ideal for prototyping, scripting, and projects where having a comprehensive set of libraries and development tools immediately available is important. It’s worth noting that other dialects offer GUI support through external libraries and wrappers, while in Racket it is available out of the box.&lt;/p&gt;
&lt;h3&gt;Learning Resources&lt;/h3&gt;
&lt;p&gt;Racket has a rich website with a lot of helpful information. Important resources for beginners include &lt;a href=&quot;https://docs.racket-lang.org/quick/&quot;&gt;Quick: An Introduction to Racket with Pictures&lt;/a&gt; and &lt;a href=&quot;https://docs.racket-lang.org/guide/&quot;&gt;The Racket Guide&lt;/a&gt;, which is the complete guide to the language. Also worth mentioning is &lt;a href=&quot;https://beautifulracket.com/&quot;&gt;Beautiful Racket&lt;/a&gt; by Matthew Butterick, a visually curated guide to the language written by a passionate contributor. If you’re looking to write a compiler, check out &lt;a href=&quot;https://kmicinski.com/functional-programming/2025/11/23/build-a-language/&quot;&gt;this course&lt;/a&gt; using Racket.&lt;/p&gt;
&lt;p&gt;The best resource available for Scheme is &lt;a href=&quot;https://web.mit.edu/6.001/6.037/sicp.pdf&quot;&gt;SICP&lt;/a&gt;, also known as the &lt;em&gt;Wizard Book&lt;/em&gt;. It’s not only about Lisp, but it’s a great book for learning the fundamentals of programming and programming languages. It’s also worth mentioning a rather unusual book, &lt;a href=&quot;https://www.goodreads.com/en/book/show/548914.The_Little_Schemer&quot;&gt;The Little Schemer&lt;/a&gt;, which consists of a long series of questions that forces the reader to think before looking at the answer on the page.&lt;/p&gt;
&lt;h2&gt;Special Mention&lt;/h2&gt;
&lt;h3&gt;Elisp&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://learnxinyminutes.com/elisp/&quot;&gt;Elisp&lt;/a&gt; is a specialised dialect that’s part of Emacs and is used to customise the editor. It’s an old Lisp dialect that comes with quite a few limitations, but it’s probably one of the best practical uses I’ve ever found for Lisp, beyond using it as a general-purpose programming language. It’s used to customise and extend the functionality of Emacs, since much of the editor itself is written in Elisp. By evaluating Elisp code inside it, you can change how Emacs looks and behaves in real time, without requiring a reload.&lt;/p&gt;
&lt;h4&gt;Learning resources&lt;/h4&gt;
&lt;p&gt;&lt;a href=&quot;https://www.gnu.org/software/emacs/manual/eintr.html&quot;&gt;An Introduction to Programming in Emacs Lisp&lt;/a&gt; is freely available online. Another useful resource is &lt;a href=&quot;https://protesilaos.com/emacs/emacs-lisp-elements&quot;&gt;Emacs Lisp Elements&lt;/a&gt; by Protesilaos Stavrou, an active Emacs contributor and advocate.&lt;/p&gt;
&lt;h2&gt;Syntax comparison&lt;/h2&gt;
&lt;p&gt;We can use a simple instruction interpreter to show some of the syntactic differences between the dialects.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-lisp&quot;&gt;(defun calculate (instructions)
  (loop with result = 0
        for (operation value) in instructions
        do (setf result
                 (case operation
                   (add      (+ result value))
                   (subtract (- result value))
                   (multiply (* result value))))
        finally (return result)))

(calculate &amp;#39;((add 5) (multiply 3) (subtract 4))) ;; =&amp;gt; 11
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In Common Lisp, I used the &lt;code&gt;LOOP&lt;/code&gt; macro to iterate over and destructure each instruction, then perform the operation by updating local state. Notice that it carries an accumulator (&lt;code&gt;result&lt;/code&gt;) through the sequence, essentially doing the same job as a &lt;code&gt;reduce&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-clojure&quot;&gt;(defn calculate [instructions]
  (reduce
    (fn [result [operation value]]
      (case operation
        :add      (+ result value)
        :subtract (- result value)
        :multiply (* result value)))
    0
    instructions))

(calculate [[:add 5] [:multiply 3] [:subtract 4]]) ;; =&amp;gt; 11
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In Clojure, I used a reduction over the sequence of instructions. Notice that it doesn’t use or update any local state, since the reduction uses immutable accumulation. I also used some syntax that is specific to Clojure, such as vectors &lt;code&gt;[]&lt;/code&gt; and keywords like &lt;code&gt;:add&lt;/code&gt;, and destructured the contents of each vector with &lt;code&gt;[operation value]&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-racket&quot;&gt;(define (calculate instructions)
  (for/fold ([result 0])
            ([instruction (in-list instructions)])
    (match instruction
      [(list &amp;#39;add value)
       (+ result value)]
      [(list &amp;#39;subtract value)
       (- result value)]
      [(list &amp;#39;multiply value)
       (* result value)])))

(calculate &amp;#39;((add 5) (multiply 3) (subtract 4))) ;; =&amp;gt; 11
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In Racket, we use &lt;code&gt;for/fold&lt;/code&gt; to iterate over the instructions while carrying the result from one iteration to the next. We also use pattern matching with &lt;code&gt;match&lt;/code&gt; to destructure each instruction and identify the operation at the same time. For example, &lt;code&gt;(list &amp;#39;add value)&lt;/code&gt; matches a two-element list whose first element is the symbol &lt;code&gt;add&lt;/code&gt; and binds the second element to &lt;code&gt;value&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;Which one to pick?&lt;/h2&gt;
&lt;p&gt;To summarise the above:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Clojure&lt;/strong&gt; gives you modern syntax, functional programming and immutable data structures, great tooling and libraries, an almost drop-in replacement for Java, a full-stack language, a strong community, and maybe even a job.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Common Lisp&lt;/strong&gt; gives you native compilation, high performance, the most powerful REPLs, multi-paradigm programming, and a stable, battle-tested language.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Racket&lt;/strong&gt; gives you a feature rich language, a great IDE for beginners, a cross-platform GUI, a powerful platform for building new languages and DSLs, easily approachable for students.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Elisp&lt;/strong&gt; gives you the ability to extend and customise Emacs.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For most programmers looking for a practical and elegant Lisp they could use professionally, &lt;strong&gt;Clojure is probably the safest first choice&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;If you want to experience the traditional Lisp development model at its fullest, you want native compilation without rely on JVM, an exceptionally interactive environment and a huge language, choose &lt;strong&gt;Common Lisp&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;If you are a computer science student, interested in compilers and programming-language design, or if you need a quick way to write tools or need an easy way to use a cross-platform GUI, choose &lt;strong&gt;Racket&lt;/strong&gt;. This is probably the easiest to start with between the dialects.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;If you have any questions of feedback, please send me an email.&lt;/p&gt;
</content:encoded></item><item><title>Confessions of an emigrant</title><link>https://scotto.me/blog/2026-07-15-confessions-of-an-emigrant/</link><guid isPermaLink="true">https://scotto.me/blog/2026-07-15-confessions-of-an-emigrant/</guid><description>Reflection on receiving my Australian citizenship</description><pubDate>Wed, 15 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Today at 3 pm I officially became an Australian citizen. I felt it was a formality, since I already had a permanent residency. But when I was sitting in the city hall, together with others that were receiving the citizenship as well, I reflected about the last few years I spent abroad and what it actually means being an emigrant. Looking back at my past, it seemed obvious that, sooner or later, I would have moved to another country.&lt;/p&gt;
&lt;p&gt;It all started in the early years of my adulthood, when I had the chance to fly to and work in Silicon Valley three times. During that period, I also moved to Turin to study at the university, in a much bigger city than the small town where I grew up. Something started changing in me back then. I appreciated the new level of freedom that I gained by leaving my parents&amp;#39; house, and I developed a certain thirst for what I believed the rest of the world had to offer. The thought of a future in my small town, seeing the same places, facing the same issues, having my entire family around all the time, and the feeling that certain things there were too slow to change, was frightening me. I didn’t want to feel stuck in that place.&lt;/p&gt;
&lt;p&gt;Also I wanted to be challenged, I wanted to confront difficulties and experience new surroundings. I believe there are few experiences as eye-opening as living for months, or even better, years, in another country.&lt;/p&gt;
&lt;p&gt;I wasn&amp;#39;t sure where or how I would move, but I knew I could find a way if I truly wanted to. On Facebook I can still see the groups I joined at the time to get a genuine, unspoiled insight into what life was like in different cities: “Italians in London”, “Italians in Valencia”, “Italians in Berkeley”, “Italians in Amsterdam”, “Italians in Dublin”. I was naive. I was trying to find something familiar that would soften the culture shock I knew would hit me once I stepped out of my comfort zone. I was trying to play it safe, not knowing what to expect.&lt;/p&gt;
&lt;p&gt;In those Facebook groups I still see many compatriots every day who ask what life is like there, how much it costs to live, whether there are enough jobs, and whether it&amp;#39;s worth moving their entire family to the other side of the world. I can see my younger self in their worries and their hope for a different future. They don’t know yet what emigrating really means. &lt;/p&gt;
&lt;p&gt;What I also find in those groups is the constant clash between those who defend their home country and those who criticise it, praising how much better their lives abroad are. This might seem like a typical social media interaction, but I think there&amp;#39;s another side to the story that people are overlooking. When you move abroad, you&amp;#39;re expected to do better, to build a better life. Otherwise, why would you do it?&lt;/p&gt;
&lt;p&gt;It&amp;#39;s a sort of unspoken expectation that every emigrant has to live up to, especially when interacting with people from back home. You don&amp;#39;t move abroad to live a life worse than the one you had at home. You have to “make it”, whatever that means. You can&amp;#39;t really talk about your struggles, the loneliness, the career setbacks, the sense of cultural isolation. Is not that simple to say that you miss what you left behind. Many emigrants end up hiding the reality of life abroad. They wear a mask to live up to the expectations of their family, friends, and the compatriots they left behind. They no longer live at home, they abandoned the land. The everyday problems of their compatriots are no longer theirs. They are in a liminal space between two countries, no longer physically present in one, but not yet belonging to the other.&lt;/p&gt;
&lt;p&gt;The truth is that life abroad is never easy, nor is it necessarily better than what we had at home. The job situation can be a rollercoaster. It wasn&amp;#39;t easy to tell my parents that I was picking fruit when, just a few months earlier, I had a high paying office job. It took me a while to get back to my original career, and in the meantime I had to work in less pleasant jobs where I was overqualified or overworked. I had to fill those gaps on my CV with something, because recruiters don’t care about immigration policies. Australia is a welcoming country, and its people are kind and generally open-minded, but I still feel like an immigrant every day. I had to adjust how I speak and behave, and I’m still working on softening my accent in order to fit in. I still carry the contradiction of being someone who “made it” back home while still being perpetually viewed as an outsider in my new country.&lt;/p&gt;
&lt;p&gt;I have missed important moments in the lives of the people I care about. My sister had a child, and I am not there to watch my nephew grow up. My school friends are getting married, and I’m not there to celebrate with them. I will not share some of their happiest moments, and they will not share mine. One day, my parents might fall seriously ill, and I might not be there when they need me most. These are costs I had to be willing to accept.&lt;/p&gt;
&lt;p&gt;The culture that shaped my childhood cannot be found overseas. I can join a small community of expatriates, buy imported products and spend time cooking a nice meal. I can find book in my language, teach my kids Italian while we visit my relatives. But I know it will be hard to transmit the same culture. Whatever home was for me cannot be bought online or shipped overseas in boxes. If I want to feel it again, I have to go back to it.&lt;/p&gt;
&lt;p&gt;I&amp;#39;ve had the opportunity to meet several emigrants in my life, mostly Italians like me, because we tend to gravitate towards one another, as if our shared culture acted like a magnet. Some of them returned to Italy after years of living overseas because they never found a reason strong enough to stay. Some of them kept moving from country to country before eventually returning to Italy when the right opportunity arose. Some people built a life abroad, advancing their careers and starting a family, while others are still trying to figure out where they belong. It&amp;#39;s impossible to predict what life abroad will be like for someone else, or how well they&amp;#39;ll cope with its challenges.&lt;/p&gt;
&lt;p&gt;After all this, one last confession, one that&amp;#39;s usually hard for an immigrant to admit. No matter how successful you become, how much money you make, or how much your life improves by moving overseas, there will always be moments when you feel a sense of regret, when you&amp;#39;ll be tempted to reply to those people on Facebook and tell them, “No. Don’t leave. It’s not worth it.” Then those moments pass, and life goes back to normal. They are simply part of choosing one life over another.&lt;/p&gt;
&lt;p&gt;Today, becoming an Australian citizen made that choice feel more permanent than ever. I don&amp;#39;t know whether Australia will ever feel like home in exactly the same way Italy does, and perhaps it doesn&amp;#39;t have to.&lt;/p&gt;
&lt;p&gt;And now it&amp;#39;s time for me to celebrate. For the occasion, I&amp;#39;ll have a chicken parmi with gravy. Wish me luck.&lt;/p&gt;
</content:encoded></item><item><title>How to read more books</title><link>https://scotto.me/blog/2026-07-12-how-to-read-more-books/</link><guid isPermaLink="true">https://scotto.me/blog/2026-07-12-how-to-read-more-books/</guid><description>My method for reading more</description><pubDate>Sun, 12 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I&amp;#39;ve read roughly a book a week for a few years, and I can tell you it&amp;#39;s doable. I didn&amp;#39;t always read this much. When I started, I read fewer than ten volumes per year, but making it a goal made me switch gears and achieve what I once thought was impossible. I want to explain what I did to become a prolific reader, and what I learned in the process, so that, with a bit of effort, you can do it too. I promise, it will be worth it.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/umberto_eco.jpg&quot; alt=&quot;[Umberto Eco in his library]&quot; title=&quot;Umberto Eco had a library of more than 30,000 books.&quot;&gt;&lt;/p&gt;
&lt;p&gt;First of all, you don&amp;#39;t have to make time to read. What you need to do is read every single time you are not doing something else. In today&amp;#39;s world, most people pick up their phones as soon as they get a moment of inactivity. Serious readers pick up their books instead. So an effective way is to replace the time you spend in front of a screen, like PCs, smartphones, and TVs, with time spent reading a book.&lt;/p&gt;
&lt;p&gt;This is probably the most difficult part. I had to remove all social media and streaming apps from my iPhone. I removed Instagram, YouTube, Facebook, etc. When I started, I found myself picking up the phone and immediately noticing that something was missing, since the only things left to do were to check the weather and read boring emails. After a few days my brain started remapping itself, and I felt less pressure to immediately reach for my phone as soon as I had nothing to do. I also wear a cheap analogue watch so I can check the time on my wrist and I don&amp;#39;t have to reach for my phone.&lt;/p&gt;
&lt;p&gt;Once you remove these distractions from your smartphone, you might find yourself a bit uncomfortable with having nothing to occupy your mind for ten minutes. This is the perfect time to boost your reading habit. You need to make sure you always have a book with you everywhere you go. I usually read a few pages as soon as I wake up, and do the same before falling asleep. I read while cooking lunch or dinner, or while eating breakfast. I love using public transport, especially trains, because I get time to read while someone else is driving for me.[^1] I always have a book with me when I go out with my partner, even if I don&amp;#39;t usually end up reading it. If she has to run an errand and I have to wait, I don&amp;#39;t waste time with nothing to read. I have become good at walking my dog while reading — I even got complimented for that by a stranger — and I make sure I never go to the bathroom without a book.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“I love the smell of book ink in the morning.”
— Umberto Eco&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Carrying a book wherever I go can become problematic, depending on its size. The best solution I have found is to use an ebook reader. They are thin devices that can fit in a pocket and are able to store hundreds of books. For a reader, an ebook reader might be one of the best inventions ever, considering how expensive books have been throughout history and how difficult they have always been to carry around. Ebooks, by contrast, are cheap. Moreover, you can have a backlight for reading in the dark — it doesn&amp;#39;t strain the eyes — and you can highlight text, take notes and get definitions for words. However, it&amp;#39;s not really a replacement for a book. After a while, always reading on an ebook reader feels like reading the same book, even if the story changes. I like to alternate digital books and physical ones, and I always prefer paperbacks since they are easier to carry around and cheaper to buy.&lt;/p&gt;
&lt;p&gt;I tend to read multiple books at the same time, since having only a single option can be boring. Sometimes I get so into a book that I put the others on pause because the story is taking up all my attention, but in general I like to have a few books that I read in parallel. I generally mix fiction and non-fiction to have a broader choice.&lt;/p&gt;
&lt;p&gt;What to read is a difficult question. I once read a phrase somewhere that puts it quite well: “read what you like until you like to read.” My suggestion is to read broadly, changing genres and subjects, because there are well-written books in every genre. Varying the topics can expose you to different perspectives. And sooner or later, you will understand which genres you like more.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“It is foolish to think that you have to read all the books you buy, as it is foolish to criticize those who buy more books than they will ever be able to read. It would be like saying that you should use all the cutlery or glasses or screwdrivers or drill bits you bought before buying new ones.”
— Umberto Eco&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Another secret is to not be scared of quitting books. I definitely start way more books than I finish. But I don&amp;#39;t consider an unfinished book a failure or a bad book. I think that certain books require the right time to be fully appreciated. So if I don&amp;#39;t finish a book today, I might try reading it again in the future. I still remember having abandoned &lt;a href=&quot;https://www.goodreads.com/en/book/show/52036.Siddhartha&quot;&gt;Siddhartha&lt;/a&gt; by Herman Hesse at least three times after the first few pages, before finally finishing it and considering it one of the most formative books of my life. Somehow I wasn&amp;#39;t ready for it the first time, and I had to wait for the right moment to fully understand it. Also, I believe there are way more bad books out there than good books. If you feel that you are not enjoying a book, it feels boring and makes you think you are wasting your time, just close it and move on. I have closed books by authors that I loved, because they weren&amp;#39;t as good as the rest of their work.&lt;/p&gt;
&lt;p&gt;If you are a serious reader, you need a library with physical books. So try to stack copies of books on your shelves for later. When I buy new books, it is mostly because I need a specific one I cannot find otherwise, or because I want to support local independent bookshops. However, I generally buy more used books than new ones. I usually find them in the book section of used stores, at markets, book fairs, and sometimes in the book boxes that I find around the city.[^2]&lt;/p&gt;
&lt;p&gt;An effective method to push yourself to read more is to set some goals. You can pick a reasonable number of books for the month or the year and try to reach it. Tracking progress is a well-known trick used to form new habits. Goodreads, for example, has what&amp;#39;s called the &lt;a href=&quot;https://help.goodreads.com/s/article/What-are-Reading-Challenges&quot;&gt;Reading Challenge&lt;/a&gt;, which helps you keep track of how many books you read in a year. I found it motivating to put in the effort to stay on track with the number I wanted to read. However, counting the volumes is not a healthy way of reading. It&amp;#39;s much better to read great books and take the right amount of time to understand and reflect on them rather than rushing to finish books just to increase the final count. You need to enjoy the process and get a good outcome from your reading.&lt;/p&gt;
&lt;p&gt;Writing a review is also a great method to make a book stick in your memory. Taking highlights and notes while you&amp;#39;re reading is a good thing, but revisiting them alongside your thoughts in a written document is something different. Reviewing books is a great way to become better at understanding what the messages contained in the books are and what the key elements of the story are. In addition, if you like writing, it&amp;#39;s a good reason to practise.&lt;/p&gt;
&lt;div class=&quot;video-container flex justify-center mb-10&quot;&gt;
    &lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/UoEuvgT1wBs?si=6N8uFfbgqh5F3rGG&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen&gt;&lt;/iframe&gt;
&lt;/div&gt;

&lt;p&gt;One of the duties of a serious reader is to find what to read next. I always have a long list of books to read, but I don&amp;#39;t stick to it all the time. I like to be immersed in something new and discover new authors or genres. I usually use two things: Goodreads and YouTube. The first one helps me form an idea of a book before I get to reading it, thanks to reviews and comments from people I follow. YouTube, on the other hand, is great for listening to book reviews to get recommendations. There are many great channels out there, and I watch quite a few of them. One of my favourites in English is &lt;a href=&quot;https://www.youtube.com/@BetterThanFoodBookReviews&quot;&gt;Better Than Food&lt;/a&gt;, which has reviewed books for more than a decade.&lt;/p&gt;
&lt;p&gt;What inspired me to try to read more was &lt;a href=&quot;https://www.youtube.com/watch?v=lIW5jBrrsS0&quot;&gt;this video&lt;/a&gt;, where Max Joseph explains that becoming a serial reader is just a matter of making a daily habit of reading a few pages, with surprisingly good results. Also, &lt;a href=&quot;https://www.youtube.com/watch?v=VA6kJoUEqPY&quot;&gt;Ryan Holiday&lt;/a&gt; — a famous author — has recently published a good guide on how to read more books with his own tips and tricks.&lt;/p&gt;
&lt;p&gt;One last recommendation: avoid hacks. Avoid speed reading. And don&amp;#39;t try to force yourself to increase your reading speed. It will come naturally the more you read. Avoid summaries and summary services. It might be okay to use them after you read a book to make sure you didn&amp;#39;t miss some parts, but reading a summary does not equal reading a book. Avoid audiobooks too. Big corporations want to grab your attention by trying to market audiobooks as books for busy people, but don&amp;#39;t fall into the trap. A book is just boring black text on a white page because that&amp;#39;s how it&amp;#39;s meant to be consumed, and it requires your full attention. Listening to audio while cooking or cleaning or whatever you do is not the same thing; you are not fully focused on the content. Also, reading is faster than listening, so use your time wisely.&lt;/p&gt;
&lt;p&gt;[^1]: I consider driving a huge waste of time. Sometimes it can be fun and adventurous, but I think life is too short to drive to work every day. 
[^2]: In Australia, some people put a wooden box with a door in their front yard and fill it with books, so that everyone passing by can pick one up or leave their own books for other readers.&lt;/p&gt;
</content:encoded></item><item><title>Blog Engines I&apos;ve Used</title><link>https://scotto.me/blog/2026-07-11-blog-engines-ive-used/</link><guid isPermaLink="true">https://scotto.me/blog/2026-07-11-blog-engines-ive-used/</guid><description>History of my blog engines</description><pubDate>Sat, 11 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Since I got my first internet connection as a kid, I’ve spent more time setting up new blogs than actually writing them. It’s not surprising. Configuring the platform and adding features was the whole point, the fun part. Writing never interested me at the time, perhaps because I never felt the urgency to express myself and didn’t have anything relevant to say.&lt;/p&gt;
&lt;p&gt;I’ve always used self-hosted solutions and learned the advantages and tradeoffs of using them, so I will summarise here each blog and platform I have used. I might not know much about writing a blog, but I’m sure I know a thing or two about the platforms that make a blog possible.&lt;/p&gt;
&lt;h2&gt;WordPress&lt;/h2&gt;
&lt;p&gt;This was the first blog I opened many years ago, and I believe I wrote it in Italian. I was mostly translating some guides from English, or reposting tutorials taken from other blogs or forums. I got a few readers and comments, but it was never a serious project.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://wordpress.org/&quot;&gt;WordPress&lt;/a&gt; has been the main CMS for a lot of websites for decades, and still today power 40% of the web. In 2006-2008 the community around it was active, and a lot of plugins and themes were released, since PHP, the language that WordPress uses, it’s easy to learn and quick to be productive with. Plenty of guides were available, so creating a blog at the time was a matter of installing WordPress, connecting to the hosting space via FTP using &lt;a href=&quot;https://filezilla-project.org/&quot;&gt;FileZilla&lt;/a&gt;, and then connecting a &lt;a href=&quot;https://www.mysql.com/&quot;&gt;MySQL&lt;/a&gt; database to it.&lt;/p&gt;
&lt;p&gt;In those years, the LAMP stack (Linux, Apache, MySQL, PHP) was the foundational architecture used by most websites and communities, so it wasn’t surprising that WordPress got so much traction. There were so many plugins and themes that it didn’t take much to put a decent website online. Besides my own blog, I had to install and configure WordPress websites for other people, and every time things went smoothly enough. Even when I had to do some small customisations to a theme, it was quite quick to do, considering that I never learned PHP and my changes were done by guessing and testing.&lt;/p&gt;
&lt;p&gt;The CMS that WordPress offers is top notch; I’ve never found one as good since. The editor is decent and includes an instant preview of the articles and theme changes. It’s so easy to use that even your noob uncle who needed a website was able to put one together with images without having to call you over for help.&lt;/p&gt;
&lt;p&gt;Also, the plugin library that WordPress offers is large, and the plugin quality is quite decent. Most website owners at the time were worried about SEO, and it was just a matter of installing the right plugins to make sure the website was picked up by Google with the right keywords.&lt;/p&gt;
&lt;p&gt;Since WordPress workes with a database, it offers simple integration to add comments to a website, with the Akismet spam filter plugin and other nice features like user login and Gravatar integration.&lt;/p&gt;
&lt;p&gt;The main problem with WordPress is that by supporting so many features it became a huge monster, far more than what’s really needed for a simple blog. I started abandoning WordPress when Markdown became popular and static websites had their Renaissance.&lt;/p&gt;
&lt;h2&gt;Jekyll&lt;/h2&gt;
&lt;p&gt;After PHP came the Ruby era in 2008. &lt;a href=&quot;https://tom.preston-werner.com/&quot;&gt;Tom Preston-Werner&lt;/a&gt;, after releasing GitHub (written in Ruby) in April, got tired of having to deal with a database in WordPress to host a simple blog and decided to write a new blog engine called &lt;a href=&quot;https://jekyllrb.com/&quot;&gt;Jekyll&lt;/a&gt;, also in Ruby.&lt;/p&gt;
&lt;p&gt;Jekyll is much simpler to configure and to understand what is happening inside the blog. A new project consists of a configuration file and a folder structure. Posts are simple Markdown files, and the styles use &lt;a href=&quot;https://sass-lang.com/&quot;&gt;SASS&lt;/a&gt;, which at the time was more advanced than plain CSS. The pages are composed of layouts and smaller reusable components. For rendering the pages, Jekyll uses the &lt;a href=&quot;https://shopify.github.io/liquid/&quot;&gt;Liquid&lt;/a&gt; template engine, which allow the use of variables, conditionals, and loops alongside normal HTML tags. When my blog was ready to be served, I just needed to run the CLI command to build the project, and the compiled website was saved into the output directory.&lt;/p&gt;
&lt;p&gt;Jekyll is a platform that mostly targets blogs. There are many plugins available that extended what is possible to put into posts and how the content is indexed. Plus, GitHub got popular and enabled the possibility to host a website directly on their platform. So publishing with Jekyll is a matter of pushing the updates to the repo, and the continuous integration would then run the build and serve the output directory.&lt;/p&gt;
&lt;p&gt;Jekyll served my needs for a longer period than any other platform. It was minimalist compared to WordPress and, in a way, made the components of a blog much more visible and in the hands of the developers, since most files were HTML, Markdown, and SCSS.&lt;/p&gt;
&lt;p&gt;Then Ruby lost its momentum and got a bit out of fashion. I have to admit that at the time I didn’t know Ruby well, and a few times when I wanted to change some plugins I ended up not doing it because of the language barrier. I didn’t abandon Jekyll because of that, but because the community itself got a bit smaller and less vibrant, probably because a part of it migrated to other platforms (or stopped blogging).&lt;/p&gt;
&lt;h2&gt;Org mode publish&lt;/h2&gt;
&lt;p&gt;When I learned &lt;a href=&quot;https://www.gnu.org/savannah-checkouts/gnu/emacs/emacs.html&quot;&gt;Emacs&lt;/a&gt;, I discovered the most advanced file format integration with an editor: &lt;a href=&quot;https://orgmode.org/&quot;&gt;org&lt;/a&gt;. If you don’t know it, think of it as a more powerful Markdown with a series of shortcuts and extensions that make editing really fast and transform a directory of files into a perfect organisational system for your personal information.&lt;/p&gt;
&lt;p&gt;Org comes with a publishing management system, which is a way to export a series of org files into HTML, with certain output configurations for directories and templating. It’s a static site generator that converts org files to HTML, similar to what Jekyll was doing with .md files. Once the project is configured with some Elisp code, saving a file in Emacs and running a command was enough for publishing changes to my Org-mode blog.&lt;/p&gt;
&lt;p&gt;Since org is an advanced file format, the publishing came with some nice features too, like title links, dates, and automatic sitemap generation.&lt;/p&gt;
&lt;p&gt;The difficulty is that org publish is more a system for converting files rather than producing a blog. So features like layouts, SASS for stylesheets, RSS feeds, a public folder for static files, they all needed a special Elisp configuration to be written and maintained.&lt;/p&gt;
&lt;p&gt;It didn’t take me long to adapt some Elisp code to fit my project, but after making a few changes to the directory structure, every time the build was failing and I had to debug what was happening. It wasn’t ideal. Plus, features like image compression or integrating a search would have been hard to implement.&lt;/p&gt;
&lt;p&gt;So, as usually happens with complex configurable systems, after having fun customising the whole setup, I got bored, since org publish wasn’t really what I would consider practical for a personal blog. Just my personal taste.&lt;/p&gt;
&lt;h2&gt;11ty&lt;/h2&gt;
&lt;p&gt;I finally found a static site generator written entirely in JS, so I wrote my blog in &lt;a href=&quot;https://www.11ty.dev/&quot;&gt;11ty&lt;/a&gt;. It’s another pretty good system for creating static websites.&lt;/p&gt;
&lt;p&gt;I found it a bit tricky to find official documentation for certain features, but I was able to integrate and customise my blog exactly how I wanted and write the plugins I needed in quite a short time.&lt;/p&gt;
&lt;p&gt;Honestly, I don’t have much to say about 11ty. It’s a good alternative to Jekyll, and it uses Javascript, so if you know the language it becomes easy to customise. It’s actively supported and used on the web, so I recommend checking it out if you are looking for a blog platform.&lt;/p&gt;
&lt;p&gt;What got me a bit frustrated is that I ended up having a large JS file with all the configuration required, and when I had to change some structure in my blog — for example, adding support for Italian/English translations to certain articles — the configuration file got a bit bloated.&lt;/p&gt;
&lt;h2&gt;Astro&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://astro.build/&quot;&gt;Astro&lt;/a&gt; is probably the definitive static site generator I’m using today. This blog moved from 11ty to Astro without even being noticeable, and I’ve used it in a few other projects where I needed a static site generator. I’ve even tried using &lt;a href=&quot;https://decapcms.org/&quot;&gt;DecapCMS&lt;/a&gt; with it, so that a friend was able to write pages and add images directly by pushing to the GitHub repo, avoiding the need for a database.&lt;/p&gt;
&lt;p&gt;Astro has pretty much all I want for a blog: asset optimisation, partial hydration with islands, advanced templating, and variable support. Also, Astro uses &lt;strong&gt;single-file components&lt;/strong&gt; to define pages, so that HTML, JS, and CSS that share the same scope are placed in a single file, like Vue does. Pretty neat, and it makes the code easy to organise and reuse. It also extensible using Javascript and offers an high level of customisation and a set of libraries to integrate more features.&lt;/p&gt;
&lt;h2&gt;What I look for now&lt;/h2&gt;
&lt;p&gt;After all this, here&amp;#39;s what I now consider essential for a blog engine:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;support for Markdown, since I write everything in Obsidian&lt;/li&gt;
&lt;li&gt;sensible defaults for common features like RSS and asset optimisation&lt;/li&gt;
&lt;li&gt;a healthy plugin ecosystem for when I need to extend things&lt;/li&gt;
&lt;li&gt;easy customisation&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I hope Astro stays around for a long time. I&amp;#39;d rather not migrate again and instead spend that time on what actually matters: the writing.&lt;/p&gt;
</content:encoded></item><item><title>On Running and Murakami</title><link>https://scotto.me/blog/2026-07-10-on-running-and-murakami/</link><guid isPermaLink="true">https://scotto.me/blog/2026-07-10-on-running-and-murakami/</guid><description>Review of What I Talk About When I Talk About Running</description><pubDate>Fri, 10 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I’ve been a runner for more than ten years. I started running a few times a week during university because it’s a sport that fits me well. It only requires a good pair of running shoes, it’s not time-consuming, and it can be done everywhere and in any season.&lt;/p&gt;
&lt;p&gt;I’ve always been a long distance runner, and most of my runs have been around an hour long. I always find it engaging to go for a long run, where I can distract my mind from the focus of the day. This frequently helps me find new ideas and inspiration, just like I did for this article.&lt;/p&gt;
&lt;p&gt;Recently I’ve started running every day, but for a shorter amount of time. The physical benefits remain the same. Two things made me change my habit: first, research suggests that shorter daily run are more beneficial for the well-being, reduce the risk of injuries, and allow the body to adapt gradually. Second, it takes less time. In a busy life, taking 30 minutes a day for your body and mind is not much, while one hour can become more of a burden.&lt;/p&gt;
&lt;p&gt;The second thing I mention when I talk about running, after describing what type of runner I am, is the type of shoes. I currently run with the Wave Rider 28, which I bought from the Mizuno store in Kyoto, Japan. I’ve tried other common brands, and while there are differences for the pros, for a casual runner like me they are negligible — and Mizuno are good shoes. I chose them because they are the shoes that the writer Haruki Murakami uses.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/murakami.jpg&quot; alt=&quot;[Haruki Murakami in Marathon, Greece]&quot; title=&quot;Murakami in Marathon, Greece.&quot;&gt;&lt;/p&gt;
&lt;p&gt;Haruki Murakami is the most famous Japanese author alive today. He has written multiple bestsellers that have been translated into more than 50 languages worldwide and have inspired several movies. Other than being a successful author, he’s a long distance marathon runner and wrote about his experience with running in a book called “&lt;a href=&quot;https://www.goodreads.com/en/book/show/2195464.What_I_Talk_About_When_I_Talk_About_Running&quot;&gt;What I Talk About When I Talk About Running&lt;/a&gt;”.&lt;/p&gt;
&lt;p&gt;Before dedicating himself entirely to writing, Murakami ran a jazz cafe in Tokyo with his wife, where he spent his days preparing cocktails, selecting music to play, and reading books. While it might seem like an easy job, he was working for 12 hours every day while smoking almost 60 cigarettes due to stress. Then one day, while watching a local baseball match, he had the realisation that he wanted to write fiction. Against the advice of his close friends, he sold the cafe and moved to the countryside with his wife, where he could have the calm environment needed to focus. While dedicating himself to writing, thanks also to some positive feedback received for his early stories, he discovered that sitting at a table for long hours every day wasn’t good for his health. So at 33, he quit smoking and decided that he would go for a run every single morning before immersing himself in writing.&lt;/p&gt;
&lt;p&gt;Since then, Murakami has never stopped running, participating in more than 30 marathons around the world, including ultramarathons and triathlons. In the book, he explains the entire process that transformed him from a complete beginner to a long endurance runner. His secret was &lt;strong&gt;running every single day&lt;/strong&gt;, mentioning that consistency was the key to his success.&lt;/p&gt;
&lt;p&gt;Murakami has run for most of his life and wrote novels professionally for a long time. In the book, he explains the loose correlation between the two: the fact that both are activities done in solitude and that both require, other than a bit of talent, constant training to be sustainable over a long period. Writing is not easy. It requires sitting at a table alone, immersed in a long and deep thinking flow into imagination and memory. It’s a task that requires concentration and can sometimes be so intense that it becomes exhausting.&lt;/p&gt;
&lt;p&gt;The book mixes the two experiences that Murakami had, describing that what he learned is that the key ingredients to engage in these activities are &lt;strong&gt;focus&lt;/strong&gt;, &lt;strong&gt;endurance&lt;/strong&gt;, and the &lt;strong&gt;patience&lt;/strong&gt; needed to persist while waiting for the results to come.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I didn&amp;#39;t start running because somebody asked me to become a runner. Just like I didn&amp;#39;t become a novelist because someone asked me to. One day, out of the blue, I wanted to write a novel. And one day, out of the blue, I started to run-simply because I wanted to. I&amp;#39;ve always done whatever I felt like doing in life. People may try to stop me, and convince me I&amp;#39;m wrong, but I won&amp;#39;t change.
— Haruki Murakami&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In the West, we tend to associate authors with a status, almost as if they are celebrities and rockstars. In recent decades, we saw the rise of literary artistic personas that romanticised drinking, taking drugs, and burning out young. Think Burroughs, Hunter S. Thompson, Bukowski, Bret Easton Ellis, or David Foster Wallace. They all made these themes central to their productions.&lt;/p&gt;
&lt;p&gt;Murakami is a different kind of writer. Instead of drinking, smoking, abusing substances, and promoting an unhealthy lifestyle, he followed a strict diet, did endurance training, and committed himself to a self-imposed discipline to seriously carry out his duties. He promoted a life dedicated to running and the craft of writing, honouring his commitments while constantly training his persistence and resilience. This choice resembles the life of ancient samurais, the Japanese warriors with a high moral code and self-control. If you’ve ever been interested in Japan, you will notice that the attitude that samurais had toward their duty still persists in today’s life of Japanese salarymen. The country is famously renowned for the perfection they put into their crafts and their dedication to work, which comes from the culture of imposing strict discipline on themselves in order to challenge their own limits.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Pain is inevitable. Suffering is optional.
— Haruki Murakami&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;There’s a quiet rebellion in choosing Murakami over Bukowski as a way of life. Our Western culture too often normalises burnout and, instead of condemning substance abuse, subtly encourages it. The power that comes from disciplining ourselves and restraining our desires in pursuit of a higher goal is what allows us to simply show up every day and do the work, whether that means running or writing. The point of these activities, in the end, is to prove to ourself that we are capable of enduring, and of moving forward, every single day.&lt;/p&gt;
</content:encoded></item><item><title>A road to Lisp: Why Lisp</title><link>https://scotto.me/blog/2026-07-09-why-lisp/</link><guid isPermaLink="true">https://scotto.me/blog/2026-07-09-why-lisp/</guid><description>Why Lisp</description><pubDate>Thu, 09 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The question that most programmers face when seeing some Lisp code for the first time is, without doubt, “what the hell is this?”. I asked myself the same thing when I first read its unconventional syntax: all those parentheses, the weird indentation, and who thought to use the first argument of &lt;code&gt;format&lt;/code&gt; to print to stdout?&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-lisp&quot;&gt;(defun flip-coin-for-real ()
  (&amp;lt;= (random 100) 80))

(defun hello-lisp ()
  (write-line &amp;quot;What is your name?&amp;quot;)
  (let ((name (read-line))
	    (learn-it (if (flip-coin-for-real)
		              &amp;quot;should&amp;quot;
		              &amp;quot;should not&amp;quot;)))
    (format t &amp;quot;Hello, ~A.~%&amp;quot; name)
    (format t &amp;quot;The Oracle said... you ~A learn Lisp!~%&amp;quot; learn-it)))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After getting comfortable reading code with so many parentheses, I had to learn how to use packages and symbols, how to create new projects and import libraries, how to use the REPL, and how to use conditions and restarts. Most importantly, I had to switch to a new way of thinking when constructing algorithms.&lt;/p&gt;
&lt;p&gt;The Lisp journey has a steep learning curve compared to most common languages. But it can also unlock skills that those languages never will. Why? Because &lt;strong&gt;in Lisp you can do things that are not possible in other languages&lt;/strong&gt;. Lisp enables new possibilities and allows algorithms to take different shapes, giving the programmer more power and flexibility.&lt;/p&gt;
&lt;p&gt;Paul Graham coined the term &lt;a href=&quot;https://paulgraham.com/avg.html&quot;&gt;Blub paradox&lt;/a&gt; to explain why it is difficult for programmers who have only used less powerful languages to understand the power of Lisp. In short, it’s because they are missing the concepts needed to perceive what is lacking in those languages and the advantage Lisp has over them. Louis Armstrong said something similar about jazz:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If you have to ask what jazz is, you&amp;#39;ll never know.
— Louis Armstrong.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In this article, I&amp;#39;ll explain a few features that show why this special language is worth learning. It&amp;#39;s not an easy path, and to truly grasp its power you&amp;#39;ll need to use Lisp yourself. And even if you don’t end up using Lisp, you will gain a different perspective on what programming languages can do.&lt;/p&gt;
&lt;p&gt;Lisp is going to make you a better programmer because &lt;strong&gt;it changes the way you think about problems using code&lt;/strong&gt;. To be more specific, it will teach you an approach that is not possible with other programming languages. You will be able to program Lisp itself and thus adapt the language you use to the problems you are solving. Using Lisp, you will learn to &lt;em&gt;grow the language toward your problem, then write the program in that language&lt;/em&gt;.&lt;/p&gt;
&lt;h2&gt;Extensibility&lt;/h2&gt;
&lt;p&gt;Lisp is extensible within itself. Experts — called lispers — commonly refer to it as &lt;em&gt;the programmable programming language&lt;/em&gt;[^1]. Not only will you write code for your programs, but you can write code that extends Lisp itself.&lt;/p&gt;
&lt;p&gt;This is possible thanks to the &lt;em&gt;macro&lt;/em&gt; operator. If you&amp;#39;ve used macros before in languages like C, Rust, or Swift, don’t expect the same thing. Those macros are primarily a way to eliminate boilerplate or generate repetitive code. Beyond that, macros in Lisp allow you to create new constructs that become part of the language itself.&lt;/p&gt;
&lt;p&gt;They are one of the hardest features to master for Lisp programmers, so I won&amp;#39;t try to teach you how to use them or how they work here. I just want to give you a taste of what they do. For example, C programmers might want to use the &lt;code&gt;while&lt;/code&gt; operator to define a simple loop. Common Lisp does not provide it, so the programmer can write a macro and add it to the language.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-lisp&quot;&gt;(defmacro while (condition &amp;amp;body body)
  `(loop while ,condition do
     (progn ,@body)))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The new &lt;code&gt;while&lt;/code&gt; macro executes a series of instructions (the &lt;code&gt;body&lt;/code&gt;) for as long as the &lt;code&gt;condition&lt;/code&gt; is true. It uses &lt;code&gt;loop&lt;/code&gt;, which is itself a macro used to write complex iterations (notice that it uses a &lt;code&gt;while&lt;/code&gt; symbol as well). &lt;code&gt;progn&lt;/code&gt; is a special form that takes multiple expressions, runs them in order, and returns the result of the last one.&lt;/p&gt;
&lt;p&gt;Instead of writing &lt;code&gt;(loop while ... do (progn ...))&lt;/code&gt;, we can use the new &lt;code&gt;while&lt;/code&gt; operator, shortening the code and making it similar to C. We just extended the language available to us.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-lisp&quot;&gt;(let ((counter 3))
  (while (&amp;gt; counter 0)
    (print counter)
    (decf counter)))

;; 3
;; 2
;; 1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The beginner might not grasp what is really magical here, since, other than the unique syntax, &lt;code&gt;defmacro&lt;/code&gt; looks pretty similar to &lt;code&gt;defun&lt;/code&gt;, which was used in the first code example to define new functions.&lt;/p&gt;
&lt;p&gt;To better understand the difference between the two, let’s define a new &lt;code&gt;while&lt;/code&gt; as a function, then call it.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-lisp&quot;&gt;(defun fake-while (condition body)
  (loop while condition do
    (funcall body)))
    
(let ((counter 3))
  (fake-while (&amp;gt; counter 0) 
	(progn
	  (print counter)
	  (decf counter))))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;loop&lt;/code&gt; is the same macro we used before; &lt;code&gt;funcall&lt;/code&gt; calls the function received as the first parameter, in this case &lt;code&gt;body&lt;/code&gt;. Try to execute the code above in a Common Lisp REPL. You will receive a condition of type error, similar to this: &lt;code&gt;The value 2 is not of type FUNCTION&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This happens because the arguments to &lt;code&gt;fake-while&lt;/code&gt; are evaluated immediately. &lt;code&gt;(&amp;lt; x 3)&lt;/code&gt; evaluates to &lt;code&gt;t&lt;/code&gt; -- true. Because &lt;code&gt;progn&lt;/code&gt; is a function, its arguments are evaluated. &lt;code&gt;(print counter)&lt;/code&gt; prints &lt;code&gt;3&lt;/code&gt;, and &lt;code&gt;(decf counter)&lt;/code&gt; returns &lt;code&gt;2&lt;/code&gt;. Since &lt;code&gt;progn&lt;/code&gt; returns the value of its last expression, &lt;code&gt;body&lt;/code&gt; becomes &lt;code&gt;2&lt;/code&gt;. So fake-while receives &lt;code&gt;t&lt;/code&gt; as its first argument and &lt;code&gt;2&lt;/code&gt; as its second, not a block of code. It will enter the &lt;code&gt;while&lt;/code&gt; since the condition is true, and then &lt;code&gt;funcall&lt;/code&gt; expects &lt;code&gt;body&lt;/code&gt; to be the function to be called, but &lt;code&gt;body&lt;/code&gt; is the value &lt;code&gt;2&lt;/code&gt;. This raises the condition above. The code executed by the compiler is the one below. &lt;code&gt;(funcall 2)&lt;/code&gt; raises the condition.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-lisp&quot;&gt;(loop while t
	  do (funcall 2))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The macro &lt;code&gt;while&lt;/code&gt; defined earlier works because it keeps the arguments — &lt;code&gt;condition&lt;/code&gt; and &lt;code&gt;body&lt;/code&gt; — intact, without evaluating them until needed. We can inspect the transformation that a macro operates in the REPL. This transformation is called &lt;em&gt;expansion&lt;/em&gt;. &lt;code&gt;macroexpand&lt;/code&gt; is a special Lisp command we can use to expand code.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-lisp&quot;&gt;CL-USER&amp;gt; (macroexpand-1 &amp;#39;(while (&amp;gt; counter 0) (print counter) (decf counter)))
(LOOP WHILE (&amp;gt; COUNTER 0)
      DO (PROGN (PRINT COUNTER) (DECF COUNTER)))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The code returned from the macro expansion is the one received and executed by the compiler. We can see that this time the &lt;code&gt;while&lt;/code&gt; macro preserved the arguments so they will be executed together with the rest of the code.&lt;/p&gt;
&lt;p&gt;A macro, unlike a function, does not evaluate the arguments in advance. Instead, it treats them as pure data. This is possible because (almost) everything you see in Lisp is made of lists. They are the main data structure, and they are used to write code.&lt;/p&gt;
&lt;h2&gt;It’s lists all the way down&lt;/h2&gt;
&lt;p&gt;Programs in Lisp are composed of a series of &lt;strong&gt;symbolic expressions&lt;/strong&gt; (abbreviated &lt;em&gt;s-expr&lt;/em&gt;). &lt;em&gt;Expression&lt;/em&gt; is a mathematical term meaning anything that evaluates to a value; &lt;em&gt;symbolic&lt;/em&gt; means that expressions are created using values and symbols.&lt;/p&gt;
&lt;p&gt;An &lt;em&gt;s-expression&lt;/em&gt; is one of two things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;an &lt;em&gt;atom&lt;/em&gt;, which is a unit of data (a number, a string, a symbol, etc)&lt;/li&gt;
&lt;li&gt;a &lt;em&gt;list&lt;/em&gt;, which is a collection of elements that can be atoms or other lists&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code class=&quot;language-lisp&quot;&gt;1           ;; An atom number
&amp;quot;hello&amp;quot;     ;; An atom string
&amp;#39;(1 &amp;quot;y&amp;quot; :c) ;; A list of atoms (a number, a string, a keyword)
(+ 1 2)     ;; A list composed of a symbol (plus) and two numbers
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Lisp means &lt;em&gt;LISt Processing&lt;/em&gt;, so the purpose of the language is to process the series of instructions expressed as lists that compose the program.&lt;/p&gt;
&lt;p&gt;Since lists are used both as the main data structure and to write the code, we can extract an interesting property of the language. In Lisp, &lt;strong&gt;code-as-data&lt;/strong&gt; means that both code and data are expressed using lists. This property is called &lt;strong&gt;homoiconicity&lt;/strong&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-lisp&quot;&gt;CL-USER&amp;gt; (+ 1 2)
3
CL-USER&amp;gt; &amp;#39;(+ 1 2)
(+ 1 2)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I’ve used two lists with the same content; the only difference is that I put &lt;code&gt;&amp;#39;&lt;/code&gt; in front of the second one, but the output is different. The first list is treated as &lt;em&gt;code&lt;/em&gt;. It gets evaluated, and specifically the symbol &lt;code&gt;+&lt;/code&gt; maps to a function that performs the sum of the arguments. Lisp uses what’s called &lt;a href=&quot;https://en.wikipedia.org/wiki/Polish_notation&quot;&gt;&lt;em&gt;Polish notation&lt;/em&gt;&lt;/a&gt;, where the function name is the first element of the list and what follows are the arguments. So instead of writing &lt;code&gt;print(&amp;quot;hello&amp;quot;)&lt;/code&gt;, we write &lt;code&gt;(print &amp;quot;hello&amp;quot;)&lt;/code&gt;, moving the function name inside the parentheses. The output is 3, which is the result of the code execution.&lt;/p&gt;
&lt;p&gt;The second list is treated as &lt;em&gt;data&lt;/em&gt;. &lt;code&gt;&amp;#39;&lt;/code&gt; is an operator that tells the interpreter not to evaluate the following list and keep it as manipulable data. The output is the same list, not evaluated.&lt;/p&gt;
&lt;p&gt;The subtle distinction between code and data is what makes macros possible. We can manipulate code as we manipulate data. By transforming the source code, we are able to write &lt;strong&gt;programs that write programs&lt;/strong&gt;, a capability other languages have spent decades trying to imitate.&lt;/p&gt;
&lt;p&gt;Extending the language means that by creating new constructs that are more expressive for your program&amp;#39;s specific scope, you can make your code more &lt;em&gt;concise&lt;/em&gt;. Repetitive boilerplate code can be replaced with custom macros to shorten the code and save time. New control structures can be created to control resource access and the evaluation of forms. Macros can generate code, improve performance, and, most importantly, create new syntactic abstractions that are easier to use to hide complex and error-prone code.&lt;/p&gt;
&lt;h2&gt;A live system&lt;/h2&gt;
&lt;p&gt;Lisp is not only a programming language, it&amp;#39;s a &lt;strong&gt;live system&lt;/strong&gt;. To clarify this point, let’s start with how different the workflow is between Lisp and other languages.&lt;/p&gt;
&lt;p&gt;With other languages, you open the project in the editor and start writing code. The first thing a lisper does is start a Lisp process, attach it to the REPL, and then load the project into that process.&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;Read-Eval-Print Loop&lt;/strong&gt; is an interactive environment used to evaluate code and immediately see the result. It&amp;#39;s a window into the Lisp living process that is currently running your program.&lt;/p&gt;
&lt;p&gt;In other languages, once you change the code, you have to stop and compile it, then run the project to observe, test, and debug the changes. If something&amp;#39;s wrong, you go back to the write-compile-run-debug cycle.&lt;/p&gt;
&lt;p&gt;Instead, a lisper continuously evaluates code in the running process and observes the output directly in the REPL, since &lt;strong&gt;the Lisp process is the running program&lt;/strong&gt;. Every single function can be immediately tested in the REPL as a single unit of code, as well as any other action useful for development, such as querying a database, inspecting variables, or debugging.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/REPL.png&quot; alt=&quot;[Lisp REPL]&quot; title=&quot;An example of REPL use with Calva and Clojure. Evaluation results are printed near each lines, as well as in the output window.&quot;&gt;&lt;/p&gt;
&lt;p&gt;A Lisp process is usually kept alive for weeks on end since there is no need to stop it. It can stay attached to the REPL in the editor for as long as needed. New functions, macros, and variables are continuously defined and redefined, a process called &lt;em&gt;binding&lt;/em&gt; within an internal memory called the &lt;em&gt;environment&lt;/em&gt;. This particular workflow even has a name: &lt;strong&gt;REPL-driven development&lt;/strong&gt;. This is a real killer feature. It has been available in Lisp since its invention in the 60s, and it has been imitated by other languages (where possible), like many other Lisp original features.&lt;/p&gt;
&lt;p&gt;Does the word &lt;em&gt;hot-reloading&lt;/em&gt; tell you anything? I’ve been lucky since I started my career working with web frontends, where the JavaScript code of the app is hot-reloaded with every hard refresh of the page. And thanks to modern tools, I now only need to &lt;em&gt;save a file&lt;/em&gt; and the webpage will automatically refresh itself with the new changes. Under the hood, hot-reloading means there is a process watching the files, recompiling the modules that changed, and a websocket connection is used to inject the changes silently into the page. But not all software stacks are that lucky. Some backend frameworks still require recompilation, the situation is mixed for desktop and mobile development, and low-level languages require full compilation every time.&lt;/p&gt;
&lt;p&gt;In Lisp, hot-reloading is not a separate tool or technique. It comes for free when evaluating code in the live environment. Every time I redefine a symbol, it picks up the new definition, whether it’s a function, data, or a macro. I don’t need to stop and compile, run tests separately, or use some special debugger. Everything comes automatically by evaluating in the REPL. A good analogy is that programming in Lisp is like &lt;em&gt;evolving&lt;/em&gt; a program rather than constructing it. Once a new Lisp process has started and code gets evaluated into it, that system will become the program itself.&lt;/p&gt;
&lt;p&gt;Lisp allows you to approach programming in a new way. You can evolve the programs while writing them, and at the same time, as discussed before, evolve the language to your needs. A Lisp CAD program has evolved by turning Lisp into a language that writes CAD programs. A high-frequency trading system has evolved with a language adapted to write similar trading systems. This is the nature of Lisp, and it offers many advantages.&lt;/p&gt;
&lt;h2&gt;Extensible software&lt;/h2&gt;
&lt;p&gt;This is something probably even less known, but the two features explained above (language extensibility and the Lisp live system) allow you to easily &lt;strong&gt;create extensible software&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;We&amp;#39;re used to desktop programs being extensible mainly through plugins, such as in text editors, or sometimes through scripting languages for customization, as in game modding. These solutions usually work well, but they require programmers to design and maintain an entire system for extensibility, and they require users to learn a specific set of APIs to write plugins or extensions. In Lisp, this comes almost for free.&lt;/p&gt;
&lt;p&gt;While extending the language, lispers write macros to encapsulate actions and make code easy to reuse. In doing so, beyond just creating new symbols, they are effectively writing a &lt;strong&gt;DSL&lt;/strong&gt;, a &lt;em&gt;domain-specific language&lt;/em&gt; for the program. When lispers need to make their software extensible, all they need to do is let users use the DSL they&amp;#39;ve created.&lt;/p&gt;
&lt;p&gt;To understand this concept, let’s look at some use case scenarios. I wrote a custom CMS server for clients’ websites. I wrote some macros for generating webpages server-side.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-lisp&quot;&gt;(html
  (:h1 &amp;quot;Lorem Ipsum&amp;quot;)
  (:p &amp;quot;Dolor sit &amp;quot; (:b &amp;quot;amet&amp;quot;) &amp;quot;.&amp;quot;))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I can expose the same DSL I’ve written internally to the users so they can write their own views and customise their CMS instance.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-lisp&quot;&gt;;; A user can write dynamic pages using the full power of Lisp
(let ((user-name &amp;quot;Alice&amp;quot;)
      (items &amp;#39;(&amp;quot;Apples&amp;quot; &amp;quot;Bananas&amp;quot; &amp;quot;Oranges&amp;quot;)))
  (html
    (:h1 (format nil &amp;quot;Welcome back, ~A!&amp;quot; user-name))
    (:ul (dolist (item items)
           (html (:li item))))))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice how the &lt;code&gt;html&lt;/code&gt; macro seamlessly integrates with Lisp&amp;#39;s variables (&lt;code&gt;user-name&lt;/code&gt;), loops (&lt;code&gt;dolist&lt;/code&gt;), and string formatting (&lt;code&gt;format&lt;/code&gt;). In a traditional templating language, you&amp;#39;d need to learn a separate syntax with special brackets like &lt;code&gt;{{ user_name }}&lt;/code&gt; or &lt;code&gt;{% for %}&lt;/code&gt;. In Lisp, you don&amp;#39;t need a new language since you just use Lisp itself to build your templates.&lt;/p&gt;
&lt;p&gt;This integration means your DSL inherits all the power of Lisp: conditionals, recursion, higher-order functions, and even the ability to debug your templates step-by-step in the REPL.&lt;/p&gt;
&lt;p&gt;Another scenario: I wrote a math software where users can write formulas and the program renders them on a Cartesian graph. So I wrote a DSL to write math and draw. I can expose a small subset of the language to users so they can draw directly without having to use math formulas.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-lisp&quot;&gt;(graph
  (:curve (lambda (x) (* x x)) 0 0)     ; plot y = x²
  (:point 0 0))                         ; mark the origin
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With this DSL, users can draw complex mathematical functions with minimal code. Since it&amp;#39;s just Lisp, they can use variables, define helper functions, or even generate multiple curves in a loop. This gives the users a clean interface while leaving the complex rendering code safely hidden away.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/lisp_dsl_parabola_on_graph.svg&quot; alt=&quot;[A parabola on a Cartesian graph]&quot;&gt;&lt;/p&gt;
&lt;p&gt;This technique for extending programs has been used successfully. AutoCAD uses &lt;em&gt;AutoLISP&lt;/em&gt; to automate repeating tasks and create complex geometries. Emacs is the most extensible text editor that has ever existed on this planet, and most of it is implemented in its own Lisp dialect in order to make it infinitely expandable. There&amp;#39;s a running joke that hardcore Emacs users never have to leave the editor because it already contains everything they would ever need. In fact, Emacs has been extended to be a PDF reader, a web browser, an email client, an RSS reader, a terminal multiplexer, a Git client, a music player, a chat client, a spreadsheet, an IRC client, and even a window manager for your entire desktop, all thanks to using Lisp under the hood[^2].&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The most powerful programming language is Lisp. If you don&amp;#39;t know Lisp, you don&amp;#39;t know what it means for a programming language to be powerful and elegant. Once you learn Lisp, you will see what is lacking in most other languages.
— &lt;a href=&quot;https://stallman.org/stallman-computing.html&quot;&gt;R. M. Stallman&lt;/a&gt; creator of GCC, Emacs, the GNU project.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;So why Lisp (or when)&lt;/h2&gt;
&lt;p&gt;A lot of people have argued that one day in the future there would be a time for Lisp. A time where it becomes popular, almost the default language, when the majority of programmers will come to appreciate what a fantastic experience it is to work with it. A time when Lisp would be taught at universities all over the world so companies would have no issues finding lispers, and engineers would become unafraid of incompatibility or performance issues. Programmers would joyfully spend their days using REPL-driven development, and most of the software we use would become extensible using variations of a single language.&lt;/p&gt;
&lt;p&gt;This time never happened, and probably never will.&lt;/p&gt;
&lt;p&gt;Still, Lisp has survived from the 60s, becoming the second oldest programming language still in use after Fortran. So many languages were inspired by it, and so many languages are still being created, missing some of the features that helped Lisp survive. So even if there isn&amp;#39;t a time for Lisp, that doesn&amp;#39;t mean it&amp;#39;s not a powerful language worth knowing.&lt;/p&gt;
&lt;p&gt;Better programmers than me have said that it&amp;#39;s hard to justify Lisp&amp;#39;s use by picking a single feature among its extensibility, its interactive environment, the REPL, and a lot of other features we haven&amp;#39;t touched yet. It is &lt;strong&gt;the combination of all of them&lt;/strong&gt; that makes Lisp programming what it is.&lt;/p&gt;
&lt;p&gt;So get ready to learn what the most powerful programming language truly is.&lt;/p&gt;
&lt;p&gt;[^1]: This quote belongs to John Foderaro, co-founder of &lt;a href=&quot;https://franz.com/enterprise_development_tools.lhtml&quot;&gt;Franz Lisp&lt;/a&gt;.
[^2]: To be fair, &lt;a href=&quot;https://en.wikipedia.org/wiki/Editor_war&quot;&gt;some people&lt;/a&gt; argue that Emacs is &amp;quot;a great operating system, lacking only a decent editor&amp;quot;.&lt;/p&gt;
</content:encoded></item><item><title>Blogging</title><link>https://scotto.me/blog/2026-07-08-blogging/</link><guid isPermaLink="true">https://scotto.me/blog/2026-07-08-blogging/</guid><description>Blogging</description><pubDate>Wed, 08 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In the next month I will be less busy than usual, and to not get too lazy I decided to commit to publishing one article a day. The goals I’m working toward are becoming more persistent in finishing the tasks I choose to do, and improving my writing abilities, especially in English. So a post every day seems like a good excuse to practice and move towards those goals.&lt;/p&gt;
&lt;p&gt;This challenge will definitely push me out of my comfort zone. I’m not that skilled at writing blog posts, and to be honest not even at writing in general. Also most of the writing I’ve done previously was in my native language, Italian, so a bit of English workout is waiting for me. Two other challenges are: finding interesting topics to write about every day, and my writing speed. To help me overcome the first one, being less busy will give me more time to think freely and use my imagination, plus I have a few saved article drafts that I can use. My writing speed is probably the hardest one. It directly relates to the quality of my writing, and for a beginner it’s worth spending time polishing each draft rather than writing a lot. But I&amp;#39;m 32, and it&amp;#39;s time to find a faster way to improve, even if it means producing less refined content. In any case, the speed is probably where I hope to see some progress at the end of this experiment.&lt;/p&gt;
&lt;p&gt;How will I know if this challenge has been successful? I don’t really have any metrics available other than basic web analytics. I would say that what matters the most is to commit every day and try not to go a single day without publishing. Then in a month I will be able to check the progress in the &lt;a href=&quot;/archive/&quot;&gt;archive&lt;/a&gt; page and count the days I missed.&lt;/p&gt;
&lt;h2&gt;Some blogging principles&lt;/h2&gt;
&lt;p&gt;Blogging is one of the best tools that writers have. Everything can go on a blog, from cooking and cat photos, to long essays about the meaning of nearly everything. While it&amp;#39;s comforting that nothing is off-topic, it also means I need to decide what belongs on my blog. What are my principles for writing here?&lt;/p&gt;
&lt;p&gt;I put down a few guidelines that I want to follow:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;One core idea per post.&lt;/strong&gt; This comes naturally since a post should be an idea or an opinion condensed in a small space. The hard part is sticking to the topic and not letting the discourse go in multiple directions. Having a short amount of time will also force me to keep my ideas small — I always tend to think too big.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Be concise.&lt;/strong&gt; This is more about the form than the content. People don’t have an infinite amount of time to spend reading a random post, so the more I can condense information while keeping a good rhythm, the better the result will be. A good technique is to quickly write a raw draft first, then do the polishing later, cutting the unnecessary and rewriting the parts that are unclear.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Keep it mine.&lt;/strong&gt; I believe that good writing is personal, bad writing is anonymous. There are no rules for good or bad writing on a blog, but the posts I appreciate more are the ones that give a perspective, an opinion, or more in general that tell a personal story. A personal blog should be a diary, a conversation with the reader. So in my posts I will put my real thoughts, not trying to be fair or even right.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Write manually.&lt;/strong&gt; This should be obvious, otherwise why put so much effort in it? Recent algorithms can put together a decent post and with a few tweaks I bet it can resemble something written by a human. We live in a strange time where machine-generated content is sprawling all over the web, with or without humans behind it. I see generated articles, generated comments on social media, generated images and code all over the place. I don’t like it and I don’t want to collaborate. Writing is like a muscle, it needs proper constant training to grow. Keeping a blog is a gym for the modern writer, so write it manually or don’t write it at all. Writing is one of the most effective ways to organise your thoughts in a cohesive way. Paraphrasing &lt;a href=&quot;https://paulgraham.com/writes.html&quot;&gt;Paul Graham&lt;/a&gt;, if you delegate this process entirely to the machine, not only you never learn how to write, but you lose one of the best ways that helps you think better.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Be positive.&lt;/strong&gt; To write angry rants, complain that everything is shit, that we deserve better without taking any action, it’s easy. It really is. But it has consequences. Look at how overexposure to media generates stress and anxiety in people and fuel anger and depression. The hard task here is to write interesting content using a positive attitude. I don’t like the forced optimism culture, too often delivered with large smiles, because I don’t feel it’s authentic, I don’t feel it really comes from a genuine place, but from the stakes involved or ideology. Instead, I like genuine positive thinking, which comes from putting content into the world with the intention of making it a little more interesting, useful, or thoughtful than before.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Enough rambling about blogging for today.  A new article is already boiling. Wish me luck.&lt;/p&gt;
</content:encoded></item><item><title>Junky - William S. Burroughs</title><link>https://scotto.me/blog/2026-01-23-junky-william-s-burroughs/</link><guid isPermaLink="true">https://scotto.me/blog/2026-01-23-junky-william-s-burroughs/</guid><description>Confessions of an Unredeemed Drug Addict</description><pubDate>Fri, 23 Jan 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Junky è un libro affascinante che tratta di un tema singolare in letteratura; la vita di un dipendente dall’eroina. William Burroughs decide di raccontare in prima persona — nonostante usi uno pseudonimo — perché lui stesso è stato dipendente dalla sostanza per quasi tutta la vita. Junky è stato il suo primo successo, ed ha elevato Burroughs a capostipite della beat generation, la corrente letteraria americana di metà secolo scorso, basata su una forte ribellione artistica e sessuale accompagnata da un consumo smoderato di droghe.&lt;/p&gt;
&lt;p&gt;La storia si svolge a metà degli anni 40 in America, ed è di fatto la biografia della dipendenza di Burroughs, anche se i fatti narrati non sono tutti totalmente reali. Cosa passa nella mente di un tossico? Come pensa? Qual’è il vocabolario che usa e quali sono le sue unità di misura? Il libro è fenomenale nel raccontare la quotidianità di un eroinomane, sempre alla ricerca della sostanza, o di soldi, sempre a fare attenzione di non esser “pizzicato” dalla polizia. Più che una successione di eventi, il racconto è un viaggio interiore. Le pagine contengono i pensieri quotidiani di un tossicodipendente accompagnati dalla cronaca minuziosa dei suoi frequenti abusi, delle astinenze e le successive ricadute.&lt;/p&gt;
&lt;p&gt;Junky è un viaggio scandito da continui spostamenti tra città e nazioni, per sfuggire a possibili arresti, da frequenti visite ai dottori per ottenere prescrizioni per la morfina, dallo spaccio per guadagnare soldi e poter mantenere la dipendenza, ma soprattutto dal costante bisogno quotidiano di eroina. Dalle pagine traspare il vero significato della dipendenza, che prima che esser fisica è soprattutto mentale. Il pensiero di trovare la sostanza diventa il motore sia della storia che della vita di chi, come Burroughs, ne è schiavo. Tutte le pagine non parlano d’altro che di eroina, trasformando il racconto nel diario intimo di un tossico.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/burroughs.jpg&quot; alt=&quot;William S. Burroughs&quot; title=&quot;William S. Burroughs&quot;&gt;&lt;/p&gt;
&lt;p&gt;La dipendenza viene continuamente interrotta. Una volta al protagonista manca l’eroina, un altra volta sceglie di disintossicarsi e si rivolge a una clinica, un altra ancora finisce in cella. Ogni volta è scabroso il racconto dei dolori fisici che prova quando al suo corpo viene a mancare la dose. Parliamo di febbre, nausea, insonnia, diarrea, dolori diffusi, soprattutto alla spina dorsale, quest’ultimo chiamato in gergo “la scimmia sulla schiena” — uno dei titoli alternativi con cui in Italia è uscito il romanzo. Sono paragrafi raccapriccianti e snervanti, dove spesso il protagonista è costretto ad assumere dosi di altre sostanze per calmare i dolori e compensare lo sbilanciamento chimico. Quando Burroughs si trova in astinenza si rivolge ad altre sostanze, principalmente alcool e erba, ma anche oppiacei vari, cocaina, barbiturici, addirittura prova il peyote messicano, per riuscire a calmare il bisogno di eroina. La cosa più triste di tutte sono le continue ricadute, che perdurano fino alla fine del romanzo. Burroughs non riesce mai a smettere per più di un paio di mesi, che incontra qualcuno che gli offre una nuova dose. Lui non riesce a trattenersi, si fa, e in un attimo si ritrova intrappolato nel solito ciclo distruttivo.&lt;/p&gt;
&lt;p&gt;I personaggi nella storia appaiono e scompaiono. Di solito sono clienti o amici che coprono un ruolo per la durata di qualche pagina, poi Burroughs si sposta, cambia città, finisce in cella, e tutto ricomincia da capo con nuovi personaggi, nuovi prezzi, ma identiche sostanze. Le persone più vicine a lui, come la moglie, vengono menzionate raramente, quasi fossero degli intoppi insignificanti davanti all’enorme soddisfazione che prova quando si inietta l’eroina. Eppure la moglie non esita a definirlo noioso e patetico quando intuisce che sta per ricadere nella dipendenza.&lt;/p&gt;
&lt;p&gt;Infinte Burroughs nel romanzo non critica direttamente la droga, anzi promuove l’eroina a stile di vita fin dall’introduzione. Nel libro non incoraggia il lettore a farne uso, anzi sembra quasi voglia ridimensionare la propria dipendenza. Parla spesso di vari parametri, come il numero di mesi e di iniezioni quotidiane, quasi a dire che la sua non è una dipendenza tale da dover esser ritenuta grave — una tipica auto-riflessione da tossico. La critica all’eroina fuoriesce dal racconto. Non si può che provare pena per i dolori che soffre il protagonista quando è in astinenza, per la continua lotta nella ricerca di una nuova dose, per il terrore costante di essere scoperto e incarcerato per spaccio, ma più di tutto per la continua ossessione per la droga che occupa la sua mente. Per un junky l&amp;#39;intera vita ruota attorno all&amp;#39;eroina: persino il risveglio viene dominato dal bisogno della dose, senza la quale la normalità resta irraggiungibile.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The question is frequently asked: Why does a man become a drug addict?&lt;br&gt;The answer is that he usually does not intend to become an addict. You don’t wake up one morning and decide to be a drug addict. It takes at least three months’ shooting twice a day to get any habit at all. And you don’t really know what junk sickness is until you have had several habits. It took me almost six months to get my first habit, and then the withdrawal symptoms were mild. I think it no exaggeration to say it takes about a year and several hundred injections to make an addict.&lt;br&gt;The questions, of course, could be asked: Why did you ever try narcotics? Why did you continue using it long enough to become an addict? You become a narcotics addict because you do not have strong motivations in the other direction. Junk wins by default. I tried it as a matter of curiosity. I drifted along taking shots when I could score. I ended up hooked. Most addicts I have talked to report a similar experience. They did not start using drugs for any reason they can remember. They just drifted along until they got hooked. If you have never been addicted, you can have no clear idea what it means to need junk with the addict’s special need. You don’t decide to be an addict. One morning you wake up sick and you’re an addict.&lt;/p&gt;
&lt;/blockquote&gt;
</content:encoded></item><item><title>Liture, How I Manage My Reading Notes</title><link>https://scotto.me/blog/2025-12-17-liture-how-i-manage-my-reading-notes/</link><guid isPermaLink="true">https://scotto.me/blog/2025-12-17-liture-how-i-manage-my-reading-notes/</guid><description>On preserving what we write in the margins of ebooks</description><pubDate>Wed, 17 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Useful software often comes out of frustration. When a programmer finds themselves wondering about a tool or a library that doesn’t exist yet, they may decide to write it. At least, they know it would be useful for one user, themself, not to mention the fun of coding. In my case, I needed an easy way to navigate my ebook notes, and all I could find were subscription based services that didn’t fit my casual use. This is how &lt;a href=&quot;https://liture.co/&quot;&gt;&lt;strong&gt;Liture&lt;/strong&gt;&lt;/a&gt; started.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“Readers eat books. Film eats viewers.”
— &lt;strong&gt;The Wave in the Mind, Ursula K. Le Guin&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;One of the advantages of physical books is that we can write on the margins. That text filling the white space that the page offers has a name, marginalia, and it’s the old analog way to make that book copy feel ours. By writing on it we can enrich the text with our thoughts, and also highlight our favourite passages as well as the most crucial one to help us revise our reading later on. I tend to use a pencil, a ruler, and some coloured tags attached in the margin for quickly jumping to the best parts in the future. &lt;/p&gt;
&lt;p&gt;A lot of great writers in the past have used marginalia. Some of their book copies are still preserved, online we can see photos of the annotations made by names like Herman Melville, William Blake, Mark Twain, Jane Austen, Sylvia Plath, Jack Kerouac. I know that Vladimir Nabokov used to draw maps and object, since some of the original pages were printed on his posthumous book &lt;a href=&quot;https://www.goodreads.com/book/show/51169646-lectures-by-vladimir-nabokov&quot;&gt;&lt;em&gt;Lectures on Literature&lt;/em&gt;&lt;/a&gt;, like his annotated copy of Franz Kafka’s Metamorphosis. David Foster Wallace became famous for his heavy use of margin annotations. Some of his copies of Cormac McCarthy and Don DeLillo, filled with various notes, numbers and drawings, are kept exposed at the University of Texas in Austin.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/nabokov-annot.jpg&quot; alt=&quot;A page from Franz Kafka’s Metamorphosis annotated by Nabokov&quot; title=&quot;Nabokov copy of Franz Kafka’s Metamorphosis&quot;&gt;&lt;/p&gt;
&lt;p&gt;I&amp;#39;ve read far more books recently than I did a few years ago, and I do most of my readings with an ebook reader. I love printed books. I miss the feeling that touching paper gives, the visual feedback of the progress, the different style for covers and typography used for each book. I still buy physical copies and often second-hand, but I prefer to read in Italian[^1], my original language, and since I&amp;#39;m in Australia, far from Italian bookshops and I don’t want to pollute the planet with my hobbies, I mostly read digital books.&lt;/p&gt;
&lt;p&gt;I also have the habit of highlighting in books and sometimes taking annotations, which it&amp;#39;s easy using an e-reader.  Soon my collection of quotes and notes had grown. For some books, like &lt;a href=&quot;https://www.goodreads.com/book/show/38820046-21-lessons-for-the-21st-century&quot;&gt;&lt;em&gt;21 Lessons for the 21st Century&lt;/em&gt;&lt;/a&gt;, I had to print my highlights to review them, filling around 15 pages, and then re-highlight the most important parts. Even if I find paper more effective for focus reading than digital text, I become frustrated every time I had to review my highlights and notes from an ebook, since I couldn&amp;#39;t find a way to access that data. &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/wallace_books_delillo_002_large.jpg&quot; alt=&quot;David Foster Wallace annotations on Don Delillo&apos;s Players&quot; title=&quot;David Foster Wallace annotations on Don Delillo&amp;#39;s Players&quot;&gt;&lt;/p&gt;
&lt;p&gt;I use a Kobo reader and all the content that the user generates is stored inside the device. Export is not officially supported. A few years ago I started maintaining &lt;a href=&quot;https://github.com/eliascotto/export-kobo&quot;&gt;a python script&lt;/a&gt; that extracts highlights and notes in different formats, but with a lot of notes it stopped being practical. I needed a way to &lt;strong&gt;search&lt;/strong&gt; my &lt;em&gt;highlights&lt;/em&gt; and &lt;em&gt;notes&lt;/em&gt;, to &lt;strong&gt;save&lt;/strong&gt; my favourite quotes, to see them grouped by author and book. Also highlighting as well as typing on an e-reader is not that precise, the devices are usually quite slow to respond, so I ended up having a lot of errors and imperfection to fix. I want to edit my content, and also add new notes to enrich it. I needed a new kind of software for this.&lt;/p&gt;
&lt;p&gt;Annotations on ebooks should mimic those on physical books; they have to be easily accessible and preserved. Keeping them stored inside devices in proprietary formats is dangerous. They can easily get lost. I started thinking that some of my book notes matter as much as photos of my past, they’re a part of my reading experience and I want to keep them for the future.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/liture_screen.png&quot; alt=&quot;A screenshot of Liture desktop app&quot; title=&quot;A screenshot of Liture&quot;&gt;&lt;/p&gt;
&lt;p&gt;Kobo, Kindle, Apple Books, none of them facilitates exporting highlights and notes outside of their own platform, no common format exists for that. That’s where &lt;a href=&quot;https://liture.co/&quot;&gt;&lt;strong&gt;Liture&lt;/strong&gt;&lt;/a&gt; comes helpful. It’s a desktop app to import and manage notes and highlights from the main three book platforms. The user can search and edit content, save the favourite items, and also manually add new authors, books, and notes. No cloud or subscriptions, free for all platforms. I’m using it to keep importing new highlights every time I sync my Kobo on my mac, and the content is automatically stored in a SQLite file that I regularly backup.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“There must be something in books, something we can&amp;#39;t imagine, to make a woman stay in a burning house; there must be something there. You don&amp;#39;t stay for nothing.”
— &lt;strong&gt;Fahrenheit 451, Ray Bradbury&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I think there’s a lot of potential for great software for readers, and still a lot to do. Big tech companies disregard reading and prefer to focus on more lucrative content, so readers are usually left with old platforms, not frequently updated, missing modern features, and often with incompatible formats. But it&amp;#39;s not all lost. Some groups of passionate readers are awakening and trying to fix the situation building new platforms and apps. I would like to do my part releasing &lt;a href=&quot;https://github.com/eliascotto/liture-quotes&quot;&gt;Liture&lt;/a&gt;. Enjoy and make good use of it!&lt;/p&gt;
&lt;p&gt;[^1]: I tell others that I prefer Italian because I find the language generally more expressive than English, but in reality it’s because I fear I might forget it one day. So I read in Italian to keep the language from rusting in my head.&lt;/p&gt;
</content:encoded></item><item><title>Quel che resta del giorno - Kazuo Ishiguro</title><link>https://scotto.me/blog/2025-09-26-quel-che-resta-del-giorno/</link><guid isPermaLink="true">https://scotto.me/blog/2025-09-26-quel-che-resta-del-giorno/</guid><description>Cosa rimane quando svaniscono le illusioni?</description><pubDate>Fri, 26 Sep 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;La sera è ciò che resta del giorno, come la vecchiaia è ciò che ti resta della vita. Il protagonista dell’opera di Kazuo Ishiguro uscita nel 1989, è un maggiordomo oramai anziano che decide di intraprendere un viaggio, sia fisico guidando la sua auto nelle campagne del sud-ovest dell’Inghilterra, sia nella sua memoria, ripercorrendo scene della sua carriera presso la dimora Darlington. &lt;em&gt;Quel che resta del giorno&lt;/em&gt; è stato il primo successo dello scrittore inglese, grazie al quale vinse il &lt;em&gt;Booker Prize&lt;/em&gt; che gli permise di esser riconosciuto a livello internazionale, anche grazie alla trasposizione cinematografica con Anthony Hopkins come attore protagonista.&lt;/p&gt;
&lt;figure&gt;
  &lt;source type=&quot;image/avif&quot; srcset=&quot;/assets/img/2721.avif&quot; /&gt;
  &lt;img
    src=&quot;/assets/img/2721.png&quot;
    alt=&quot;Describe the image here&quot;
    loading=&quot;lazy&quot;
    decoding=&quot;async&quot;
  /&gt;
  &lt;figcaption&gt;Stevens interpretato da Anthony Hopkins nel 1993&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Stevens è un maggiordomo a capo del servizio nella residenza di un lord inglese chiamato Darlington. Dopo la morte del padrone, la residenza omonima passa in mano a un magnate americano Mr Faraday, che nonostante i tagli del personale, necessita di buoni servitori al suo servizio. Stevens decide quindi di prendersi qualche giorno di vacanza per andare a trovare una sua conoscenza che anni prima aveva servito a Darlington hall, Miss Kenton, e convincerla a riprendere il suo vecchio ruolo. Il viaggio in auto lo porta attraverso i panorami della campagna inglese dove si trova a riflettere in una serie di flashback che raccontano episodi della sua carriera con lord Darlington. In queste memorie si intrecciano più trame, come il contesto storico del racconto, descritto tramite la partecipazione politica del lord nelle fasi preliminari della seconda guerra mondiale e la sua decisione di appoggiare l’operato della Germania, oltre che vari avvenimenti che riguardano i personaggi che soggiornano a Darlington hall.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“La sera è la parte più bella della giornata. Hai concluso una giornata di lavoro e adesso puoi sederti ed essere felice. Ecco come la vedo io. Domandate a chiunque e vedrete che vi diranno tutti la stessa cosa. La sera è la parte più bella della giornata.”
— &lt;strong&gt;Stevens&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Il racconto è in prima persona dal punto di vista del maggiordomo, un espediente utile a Ishiguro per narrare vari avvenimenti, come le cerimonie formali tra rappresentanti politici di varie nazioni che avvengono nella residenza, attraverso gli occhi — e le orecchie — di un maggiordomo. Stevens riporta solamente porzioni di conversazioni, battute di personaggi e piccoli incidenti che gli sono rimasti nella memoria, i quali vengono lasciati al lettore come pezzi di un puzzle da comporre per comprendere ciò che non viene direttamente narrato. Il nascondere gli eventi e rivelarli solo in parte durante la narrazione è uno dei tratti caratteristici dello stile di Ishiguro, che ho ritrovato anche nel suo romanzo successivo &lt;em&gt;Non lasciarmi&lt;/em&gt;. Oltre a questa unicità, in entrambi i romanzi i protagonisti prendono parte a una storia d’amore che, sebbene ordinaria, è anche inconclusiva. Infatti anche in &lt;em&gt;Quel che resta del giorno&lt;/em&gt;, scopriamo che i sentimenti di Miss Kenton per Stevens, in qualche modo si intuiscono dai flashback ma vengono rivelati del tutto nel finale, vengono totalmente ignorati dal maggiordomo. Stevens è profondamente convinto che esista una precisa nozione di &lt;em&gt;grandezza&lt;/em&gt; riferita alla professione del maggiordomo. Nonostante la definizione non appaia mai univoca nel libro ma sempre frammentaria, si può ricostruire che essa consista nel reputare &lt;em&gt;onorevole&lt;/em&gt; il servire il proprio lord al meglio delle proprie possibilità, ripudiando qualsiasi comportamento inadatto o giudizio sugli avvenimenti nella residenza, oltre che mostrandosi sempre in atteggiamento sobrio e disponibile a qualsiasi richiesta. Stevens intende chiaramente dimostrare a se stesso di poter essere un grande maggiordomo, nonostante non si reputi tale, ed è per questo che decide di non dar corda ai sentimenti di Miss Kenton, sarebbero per lui solo una distrazione inopportuna.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets//img/1xt1.brty8d.940.jpg&quot; alt=&quot;Darlington Hall&quot; title=&quot;Darlington Hall&quot;&gt;&lt;/p&gt;
&lt;p&gt;Le capacità narrative di Ishiguro sono eccezionali. Per esempio in una scena, di per se secondaria ma che nel contesto della storia assume un’importanza centrale, Stevens sta leggendo un libro e Miss Kenton gli si avvicina cercando di rubarglielo di mano per scoprire cosa stesse leggendo. Ella vorrebbe fare con quel gesto una qualche breccia nella barriera professionale che ancora li divide e cercare di andare oltre la formalità dei loro discorsi, sempre diretti al servizio della casa e alle nuove disposizioni da attuare. Stevens si rifiuta fermamente, invitandola molto educatamente a non violare i suoi momenti di riposo. Miss Kenton infatti scopre giocosamente che Stevens stava leggendo una banale storia d’amore, ma il maggiordomo mette subito a freno la curiosità della domestica spiegandole che per adempire al meglio al suo ruolo è richiesto leggere, anche romanzi, per poter adottare sempre il vocabolario più adatto ad ogni conversazione. La scena evocativa mostra quanto Stevens sia capace di dedicarsi al suo ruolo, al punto da reprimere i suoi sentimenti e non distinguere più la sua vita privata dal lavoro.&lt;/p&gt;
&lt;p&gt;In entrambi i romanzi che ho letto dell’autore, mi sono ritrovato a pormi delle domande non banali. Esse emergono dalle pagine e non vengono mai poste direttamente, siccome i personaggi finiscono per ritrovarsi in situazioni ambigue e moralmente complesse. È una delle specialità dello stile narrativo di Kazuo Ishiguro. Mentre in &lt;em&gt;Non lasciarmi&lt;/em&gt; mi ero posto domande sui quali debbano essere i limiti della scienza, in questo libro è impossibile non domandarsi quali siano i limiti nella dedizione al proprio lavoro. Non si tratta di puro stacanovismo, ma piuttosto di chiedersi la fede incondizionata che ha Stevens per il proprio padrone, al punto da sopprimere qualsiasi dubbio, giudizio o addirittura sentimento perché in contrasto con i requisiti per essere un &lt;em&gt;grande&lt;/em&gt; maggiordomo, sia giustificata. Più di trent’anni dall’uscita del libro, è ovvio che quel tipo di mentalità è oramai antiquata, allo stesso modo di tutte le riflessioni che Stevens fa a favore di lasciare le decisioni fondamentali per il futuro del paese ad un gruppo di leader, perché a suo dire loro sanno quello che fanno meglio di chiunque altro. Da queste riflessioni emergono le differenze tra il vecchio modo di pensare di inizio secolo scorso, in cui si credeva che un uomo avesse un ruolo assegnatogli nella società e l’unica cosa che dovesse fare e svolgerlo al meglio, senza occuparsi di faccende complesse fuori dalla sua portata, in contrasto con l’uomo moderno, che da importanza all’educazione personale, e si sente libero sia di scegliere la propria strada nella vita, sia di poter esprimere opinioni e preferenze su eventi e decisioni che non lo riguardano direttamente. Miss Kenton nel racconto la pensa diversamente da Stevens, non crede che il suo ruolo definisca la sua intera vita. Sceglie l’unica via liberatoria che ha a disposizione, e decide di sposarsi, provando a costruirsi una famiglia, e smettendo così di essere alle dipendenze altrui. Anche se le cose alla fine non le sono andate per il meglio, ha scelto di esercitare la sua libertà provando a crearsi una vita diversa, rinunciando a dedicare tutta se stessa al ruolo di domestica. Stevens nel finale si rende conto di aver sprecato gran parte della sua vita inseguendo un ideale inconclusivo, e ha il rimpianto di non aver scelto per se un’altra strada per evitare la solitudine alla fine dei suoi giorni.&lt;/p&gt;
&lt;p&gt;Leggendo alcune interviste sul romanzo, Ishiguro ha dichiarato essersi documentato a dovere e di aver addirittura letto dei manuali inglesi sui maggiordomi di inizio secolo, che spiegavano le procedure corrette per organizzare il servizio e intrattenere gli ospiti. Dopo mesi di ricerca l’autore ha prodotto la prima bozza del romanzo in un solo mese, chiudendosi in nel suo studio a scrivere anche per tredici ore al giorno, per ridurre al minimo qualsiasi influenza esterna sulla sua immaginazione e concentrarsi solamente sulla scrittura della storia che aveva in mente. Durante questa immersione nel processo creativo, Ishiguro ha detto di aver appositamente evitato di riscrivere o correggere le bozze, ma solo di essersi annotato le successive modifiche da apportare una volta concluso l’intero racconto. Mi vien da pensare che Ishiguro, oltre che a costringere se stesso a scrivere, volesse tentare di avvicinarsi il più possibile alla quella dedizione assoluta al proprio lavoro descritta nel romanzo, così da caratterizzare al meglio Stevens tramite le sensazioni che provava durante tutte quelle ore di intensa produzione.&lt;/p&gt;
</content:encoded></item><item><title>A simple Common Lisp web app</title><link>https://scotto.me/blog/2025-04-30-a-simple-common-lisp-web-app/</link><guid isPermaLink="true">https://scotto.me/blog/2025-04-30-a-simple-common-lisp-web-app/</guid><description>A tutorial for the web</description><pubDate>Wed, 30 Apr 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;One of the drawbacks I’ve found when dealing with Common Lisp is the lack of documentation available. Too often, I find published libraries without an explanation of how they are meant to be used or only partially documented, and I need to dig into the source code to understand what they do and to see all the functions available. Even though reading source code is a proven technique to improve one&amp;#39;s grasp of a programming language, most other systems come with extensively documented libraries, something appreciated by beginners and a factor that often contributes to a language&amp;#39;s popularity.&lt;/p&gt;
&lt;p&gt;In my opinion, this lack of good documentation is one of the reasons Common Lisp is often seen as challenging for beginners, which makes it harder for the language to become popular.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/lisp_cycles.png&quot; alt=&quot;xkcd.com/224&quot; title=&quot;xkcd.com/224&quot;&gt;&lt;/p&gt;
&lt;p&gt;Some time ago, when I looked for guidance on writing a generic web app, I was surprised by the absence of a quickstart page to help me set up a simple server—something the Python community has provided for &lt;a href=&quot;https://flask.palletsprojects.com/en/stable/quickstart/&quot;&gt;Flask&lt;/a&gt; for many years.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“The most underrated skill to learn as an engineer is how to document. Fuck, someone please teach me how to write good documentation. Seriously, if there&amp;#39;s any recommendations, I&amp;#39;d seriously pay for a course (like probably a lot of money, maybe 1k for a course if it guaranteed that I could write good docs.)”
&lt;a href=&quot;https://www.reddit.com/r/ExperiencedDevs/comments/nmodyl/drunk_post_things_ive_learned_as_a_sr_engineer/&quot;&gt;A drunk dev on reddit&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So I put together a short tutorial on how to build a simple web app in Common Lisp, inspired by the Clojure tutorial written for &lt;a href=&quot;https://luminusweb.com/docs/guestbook&quot;&gt;Luminus&lt;/a&gt;. The goal is to write a guestbook demo, involving template &lt;em&gt;rendering&lt;/em&gt;, connecting to a database to run queries, and exposing routes to the webpage.&lt;/p&gt;
&lt;p&gt;To follow the tutorial, you need a Common Lisp implementation, like &lt;a href=&quot;https://www.sbcl.org/&quot;&gt;SBCL&lt;/a&gt;, with &lt;a href=&quot;https://www.quicklisp.org/index.html&quot;&gt;Quicklisp&lt;/a&gt;, the dependency manager. I also recommend having a REPL integrated with your IDE, like &lt;a href=&quot;https://github.com/joaotavora/sly&quot;&gt;SLY&lt;/a&gt; for Emacs or &lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=rheller.alive&quot;&gt;Alive&lt;/a&gt; for VSCode.&lt;/p&gt;
&lt;p&gt;I’ll use more modern CL libraries that have an interface similar to other languages, so it might be a bit easier to follow along.&lt;/p&gt;
&lt;h2&gt;The server&lt;/h2&gt;
&lt;p&gt;First things first, I created a new Common Lisp project. To do that with a simple boilerplate, I loaded &lt;code&gt;cl-project&lt;/code&gt; in the environment and called the function &lt;code&gt;make-project&lt;/code&gt; with a path and a name for the project.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-lisp&quot;&gt;&amp;gt; (ql:quickload :cl-project)
To load &amp;quot;cl-project&amp;quot;:
  Load 1 ASDF system:
    cl-project
; Loading &amp;quot;cl-project&amp;quot;
..
(:CL-PROJECT)

&amp;gt; (cl-project:make-project #P&amp;quot;~/guestbook/&amp;quot; :name &amp;quot;guestbook&amp;quot;)
writing ~/guestbook/guestbook.asd
writing ~/guestbook/README.org
writing ~/guestbook/README.markdown
writing ~/guestbook/.gitignore
writing ~/guestbook/src/main.lisp
writing ~/guestbook/tests/main.lisp
T
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then I ran this command to let Quicklisp know where my new project is located.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-lisp&quot;&gt;&amp;gt; (pushnew #P&amp;quot;~/guestbook/&amp;quot; asdf:*central-registry* :test #&amp;#39;equal)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I declared the required libraries in the &lt;code&gt;:depends-on&lt;/code&gt; property so that Quicklisp would download them from the repo and load them into the environment.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-lisp&quot;&gt;(defsystem &amp;quot;guestbook&amp;quot;
  :version &amp;quot;0.0.1&amp;quot;
  :license &amp;quot;MIT&amp;quot;
  :depends-on (:alexandria        ;; utils
               :uiop
               :cl-ppcre          ;; regex library
               :cl-syntax-annot   ;; for @export annotation
               :clack             ;; Web libraries
               :lack
               :caveman2          ;; Web framework
               :djula             ;; Template engine
               :cl-dbi)           ;; Database
  :components ((:module &amp;quot;src&amp;quot;
                :components
                ((:file &amp;quot;config&amp;quot;) ;; files into src/
                 (:file &amp;quot;db&amp;quot;)
                 (:file &amp;quot;web&amp;quot;)
                 (:file &amp;quot;core&amp;quot;))))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, inside &lt;code&gt;src/core.lisp&lt;/code&gt; (I renamed the file from &lt;code&gt;main&lt;/code&gt; to &lt;code&gt;core&lt;/code&gt;) I added two new functions, to start and stop the server, which will be helpful to use from the REPL.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-lisp&quot;&gt;(defvar *server* nil)

(defparameter *app*
  (lack:builder
	  (:static
      :path (lambda (path)
              (if (ppcre:scan 
                    &amp;quot;^(?:/images/|/css/|/js/|/robot\\.txt$|/favicon\\.ico$)&amp;quot; 
                    path)
                  path
                  nil))
      :root *static-directory*)
  ;; Additional middlewares
    guestbook.web:*web*))

@export
(defun start (&amp;amp;rest args
              &amp;amp;key
                (server :hunchentoot)
                (port 3210)
                (debug nil)
              &amp;amp;allow-other-keys)
  &amp;quot;Starts the server.&amp;quot;
  (when *server*
    (restart-case (error &amp;quot;Server is already running.&amp;quot;)
      (restart-server ()
        :report &amp;quot;Restart the server.&amp;quot;
        (stop))))

  (setf *server* (apply #&amp;#39;clack:clackup *app*
                   :server server
                   :port port
                   :debug debug
                   args))
  (format t &amp;quot;Server started&amp;quot;))

@export
(defun stop ()
  &amp;quot;Stops the server.&amp;quot;
  (when *server*
    (clack:stop *server*)
    (format t &amp;quot;Server stopped&amp;quot;)
    (setf *server* nil)))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;*server*&lt;/code&gt; contains the server instance and is defined as a variable since we will need to redefine it. &lt;code&gt;*app*&lt;/code&gt; is the web application wrapped with a layer by &lt;em&gt;Lack&lt;/em&gt;. &lt;code&gt;start&lt;/code&gt; and &lt;code&gt;stop&lt;/code&gt; instantiate the server with some logging, or raise errors if the action is not successful.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Lack&lt;/em&gt; and &lt;em&gt;Clack&lt;/em&gt; are the two libraries I used to wrap the web application. &lt;a href=&quot;https://github.com/fukamachi/lack&quot;&gt;The first one&lt;/a&gt; allows to define a series of middlewares in the server; for example, I used &lt;code&gt;:static&lt;/code&gt; to tell the server where to find all the static assets in the project, inside the directory pointed to by &lt;code&gt;*static-directory*&lt;/code&gt;. Other middlewares are available, like logging, managing sessions or providing authentication features. &lt;a href=&quot;https://github.com/fukamachi/clack&quot;&gt;&lt;em&gt;Clack&lt;/em&gt;&lt;/a&gt; instead is an abstraction layer for the server that provides some parameters to customise it, for example, to quickly swap which server to use between development mode (&lt;code&gt;hunchentoot&lt;/code&gt;) and production (&lt;code&gt;woo&lt;/code&gt;).&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-lisp&quot;&gt;(unless (null *server*)
    (restart-case (error &amp;quot;Server is already running.&amp;quot;)
      (restart-server ()
        :report &amp;quot;Restart the server.&amp;quot;
        (stop))))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this portion of the code, I defined a restart action for the debugger. The Common Lisp debugger always has &lt;code&gt;RETRY&lt;/code&gt; and &lt;code&gt;ABORT&lt;/code&gt; actions for every exception raised. By declaring a &lt;code&gt;restart-case&lt;/code&gt;, we are signalling an error and adding custom choices to the ones offered by default by the debugger. The new option I added is called &lt;code&gt;restart-server&lt;/code&gt; and, if selected, it first &lt;code&gt;(stop)&lt;/code&gt;s the server and then restarts the operation, so the function runs again without raising an error. It’s a smart way to interact with the REPL and improve the developer experience using the language directly.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/cl-restart-case-server.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;More on conditions and restart &lt;a href=&quot;https://gigamonkeys.com/book/beyond-exception-handling-conditions-and-restarts&quot;&gt;here&lt;/a&gt; and &lt;a href=&quot;https://lispcookbook.github.io/cl-cookbook/error_handling.html&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;At the top of &lt;code&gt;src/core.lisp&lt;/code&gt; I set the package definition and some initialisation function calls.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-lisp&quot;&gt;(in-package :cl-user)
(defpackage guestbook.core
  (:use :cl)
  (:import-from :guestbook.config
                :*static-directory*))
(in-package :guestbook.core)

(syntax:use-syntax :annot)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;(syntax:use-syntax :annot)&lt;/code&gt;, from the package &lt;code&gt;cl-syntax-annot&lt;/code&gt;, allows us to use some special decoration notation at the top of the function. At the top of &lt;code&gt;start&lt;/code&gt; and &lt;code&gt;stop&lt;/code&gt; I added an &lt;code&gt;@export&lt;/code&gt; tag, which tells the compiler that a function is exported by the package. &lt;/p&gt;
&lt;h2&gt;Configuration&lt;/h2&gt;
&lt;p&gt;I put the configuration parameters for the app into a config file; there are better ways, but they’re not necessary for a project this simple.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-lisp&quot;&gt;@export
(defparameter *application-root* 
  (asdf:system-source-directory :guestbook))
@export
(defparameter *static-directory* 
  (merge-pathnames #P&amp;quot;static/&amp;quot; *application-root*))
@export
(defparameter *template-directory* 
  (merge-pathnames #P&amp;quot;templates/&amp;quot; *application-root*))

@export
(defvar *config*
  `(:databases 
      ((:maindb :sqlite3 
        :database-name ,(namestring (merge-pathnames &amp;quot;guestbook.sqlite&amp;quot;
                                                     *application-root*))))
    :schema-file &amp;quot;db/schema.sql&amp;quot;))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The variable &lt;code&gt;*config*&lt;/code&gt; needs a specific format to be used with &lt;code&gt;cl-dbi&lt;/code&gt;, which is the library that I used to interface with the database. In a real application, it would be good to differentiate between &lt;em&gt;dev&lt;/em&gt; and &lt;em&gt;prod&lt;/em&gt; mode with different configurations used, for example to point to different databases or to use a different server with &lt;em&gt;Clack&lt;/em&gt;.&lt;/p&gt;
&lt;h2&gt;Database&lt;/h2&gt;
&lt;p&gt;I created a new file in &lt;code&gt;db/schema.sql&lt;/code&gt; and put the SQL code to create a message table.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;CREATE TABLE message (
    id       INTEGER PRIMARY KEY AUTOINCREMENT,
    username VARCHAR(50) NOT NULL,
    ts       DATETIME NOT NULL,
    content  TEXT NOT NULL
);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then I ran &lt;code&gt;sqlite3 guestbook.sqlite --init db/schema.sql&lt;/code&gt; from the terminal to create and initialise a new database in the project root.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-lisp&quot;&gt;(in-package :cl-user)
(defpackage guestbook.db
  (:use :cl)
  (:import-from :guestbook.config
                :*config*
                :*application-root*))
(in-package :guestbook.db)

(syntax:use-syntax :annot)

(defun connection-settings (&amp;amp;optional (db :maindb))
  (cdr (assoc db (getf *config* :databases))))

@export
(defun db (&amp;amp;optional (db :maindb))
	&amp;quot;Returns a cached database connection for DB (defaults to :maindb). 
  Uses `connection-settings` and `dbi:connect-cached`. 
	
	Usage: (db) or (db :testdb)&amp;quot;
  (apply #&amp;#39;dbi:connect-cached (connection-settings db)))

@export
(defvar *connection* nil)

@export
(defmacro with-connection (conn &amp;amp;body body)
  &amp;quot;Executes BODY with *CONNECTION* dynamically bound to CONN.
CONN should be a database connection object, typically from `db`.

Usage: (with-connection (db :maindb)
         (dbi:do-sql *connection* \&amp;quot;SELECT * FROM users\&amp;quot;))&amp;quot;
  `(let ((*connection* ,conn))
     (unless *connection*
       (error &amp;quot;Database connection cannot be NIL&amp;quot;))
     ,@body))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is the first macro of the project. It’s a simple wrapper that provides a new variable &lt;code&gt;*connection*&lt;/code&gt; to use inside the &lt;code&gt;body&lt;/code&gt;. It raises an error if the &lt;code&gt;conn&lt;/code&gt; value that we passed is not initialised. The function &lt;code&gt;db&lt;/code&gt; instead returns a valid connection, cached automatically by the library.&lt;/p&gt;
&lt;p&gt;Then I defined some functions to perform CRUD operations on the database. &lt;code&gt;format-timestamp&lt;/code&gt; converts a universal timestamp value into a readable date-time string.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-lisp&quot;&gt;(defun format-timestamp (universal-time)
  &amp;quot;Converts a universal time value into a human-readable timestamp string,
formatted as &amp;#39;YYYY-MM-DD HH:MM:SS&amp;#39;.&amp;quot;
  (multiple-value-bind (sec min hour day month year)
      (decode-universal-time universal-time)
    (format nil &amp;quot;~4,&amp;#39;0D-~2,&amp;#39;0D-~2,&amp;#39;0D ~2,&amp;#39;0D:~2,&amp;#39;0D:~2,&amp;#39;0D&amp;quot; year month day hour min sec)))

(defun add-message (name message)
  &amp;quot;Inserts a new message into the database with the given NAME and MESSAGE content.&amp;quot;
  (with-connection (db)
    (let ((sql &amp;quot;INSERT INTO message (username, ts, content) VALUES (?, ?, ?)&amp;quot;)
          (ts (get-universal-time)))
      (dbi:do-sql *connection* sql (list name ts message)))))


(defun delete-message (id)
  &amp;quot;Deletes the message with the given ID from the database.&amp;quot;
  (with-connection (db)
    (let ((sql &amp;quot;DELETE FROM message WHERE id = ?&amp;quot;))
      (dbi:do-sql *connection* sql (list id)))))


(defun get-all-messages ()
  &amp;quot;Retrieves all messages from the database, ordered by timestamp descending.
Timestamps are formatted as human-readable strings.&amp;quot;
  (with-connection (db)
    (let* ((sql &amp;quot;SELECT * FROM message ORDER BY ts DESC&amp;quot;)
           (messages (dbi:fetch-all
                      (dbi:execute
                       (dbi:prepare *connection* sql)))))
      (mapcar (lambda (row)
                (setf (getf row :|ts|) (format-timestamp (getf row :|ts|)))
                row)
              messages))))
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;The Web App&lt;/h2&gt;
&lt;p&gt;Finally we can create the web application which I put inside &lt;code&gt;src/web.lisp&lt;/code&gt;. It’s a bit longer then the other files so I will break it into chunks.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-lisp&quot;&gt;(in-package :cl-user)
(defpackage guestbook.web
  (:use :cl
        :caveman2)
  (:import-from :guestbook.config
                :*template-directory*)
  (:import-from :guestbook.db
                :add-message
                :delete-message
                :get-all-messages)
  (:export :*web*))
(in-package :guestbook.web)

(defclass &amp;lt;web&amp;gt; (&amp;lt;app&amp;gt;) ())
(defvar *web* (make-instance &amp;#39;&amp;lt;web&amp;gt;))
(clear-routing-rules *web*)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The web framework I am using is called &lt;em&gt;Caveman&lt;/em&gt;, developed by &lt;a href=&quot;https://github.com/fukamachi&quot;&gt;Eitaro Fukamachi&lt;/a&gt;, who is a very prolific &lt;em&gt;lisper&lt;/em&gt; and the author of multiple libraries that I am using, including &lt;em&gt;Lack&lt;/em&gt;, &lt;em&gt;Clack&lt;/em&gt;, and &lt;em&gt;cl-dbi&lt;/em&gt;, all having great integration with each other. &lt;code&gt;&amp;lt;app&amp;gt;&lt;/code&gt; is a &lt;em&gt;class&lt;/em&gt; defined by the web framework, and I am extending it and instantiating it in &lt;code&gt;*web*&lt;/code&gt;. &lt;code&gt;clear-routing-rules&lt;/code&gt; is a function inherited from &lt;em&gt;Ningle&lt;/em&gt;, another web framework, which clears the route associations inside the web app instance.&lt;/p&gt;
&lt;h3&gt;Templates&lt;/h3&gt;
&lt;p&gt;Our web app needs to render some static templates with data, and to do that there’s a great library called &lt;code&gt;djula&lt;/code&gt;, which allows us to use most of the same tags and filters that &lt;a href=&quot;https://docs.djangoproject.com/en/5.1/ref/templates/builtins/&quot;&gt;Django exposes&lt;/a&gt; in its template engine.&lt;/p&gt;
&lt;p&gt;I’m not going to include the templates source here for space reasons, in the repository they&amp;#39;re in the &lt;code&gt;templates/&lt;/code&gt; folder.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-lisp&quot;&gt;(djula:add-template-directory *template-directory*)

(defun render (template-path &amp;amp;optional env)
  &amp;quot;Renders a Djula template from TEMPLATE-PATH.
ENV is an optional plist of variables passed to the template.&amp;quot;
  (apply #&amp;#39;djula:render-template*
         (djula:compile-template* (princ-to-string template-path))
         nil
         env))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The first function call tells &lt;code&gt;djula&lt;/code&gt; where to find the templates in the project. &lt;code&gt;render&lt;/code&gt; is a function that receives a template path as a parameter and compiles the template for better performance.&lt;/p&gt;
&lt;h3&gt;Routes&lt;/h3&gt;
&lt;p&gt;To allow users to perform CRUD operations, we need to expose a few routes to be called by the web frontend. There are two ways to define routes in Caveman, but this one seems a bit clearer to me than using annotations. &lt;code&gt;defroute&lt;/code&gt; is a macro that receives the route path, some parameters like &lt;code&gt;:method&lt;/code&gt; and eventually some arguments, and then defines the body to handle the request. Inside the body, we can access the request object via &lt;code&gt;*request*&lt;/code&gt; and extract data from it using, for example, the function &lt;code&gt;request-body-parameters&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The routes are self-descriptive. &lt;code&gt;/&lt;/code&gt; renders &lt;code&gt;index.html&lt;/code&gt;, passing all the messages from the db; &lt;code&gt;/message&lt;/code&gt; handles POST requests and inserts the message in the database if the parameters conform; and &lt;code&gt;/message/delete&lt;/code&gt; deletes a message. &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-lisp&quot;&gt;(defroute &amp;quot;/&amp;quot; ()
  (render #P&amp;quot;index.html&amp;quot;
          (list :messages (get-all-messages))))


(defroute (&amp;quot;/message&amp;quot; :method :POST) ()
  (let* ((body-params (request-body-parameters *request*))
         (name-param (assoc &amp;quot;name&amp;quot; body-params :test #&amp;#39;string=))
         (message-param (assoc &amp;quot;message&amp;quot; body-params :test #&amp;#39;string=)))
    (if (and (consp name-param) (consp message-param))
      (add-message (cdr name-param)
                   (cdr message-param))
      (format t &amp;quot;Missing body parameters: received ~A~%&amp;quot; body-params)))
  (redirect &amp;quot;/&amp;quot;))


(defroute (&amp;quot;/message/delete&amp;quot; :method :POST) ()
  (let* ((body-params (request-body-parameters *request*))
         (id-param (assoc &amp;quot;id&amp;quot; body-params :test #&amp;#39;string=)))
    (if (consp id-param)
        (let ((id (ignore-errors (parse-integer (cdr id-param)))))
          (when id
            (delete-message id)))
        (format t &amp;quot;Missing id parameter.&amp;quot;)))
  (redirect &amp;quot;/&amp;quot;))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I also added another function, which defines a method on the web app class. &lt;code&gt;on-exception&lt;/code&gt; is a generic function called when an exception occurs in the web application. This method is specific on the parameter type, since it will run only if the exception has code 404 — not found — and in that case I return a specific custom template.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-lisp&quot;&gt;(defmethod on-exception ((app &amp;lt;web&amp;gt;) (code (eql 404)))
  (declare (ignore app code))
  (render #P&amp;quot;404.html&amp;quot;))
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Run the demo&lt;/h2&gt;
&lt;p&gt;Now I can load the project into the environment with Quicklisp.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-lisp&quot;&gt;&amp;gt; (ql:quickload :guestbook)
To load &amp;quot;guestbook&amp;quot;:
  Load 1 ASDF system:
    guestbook
; Loading &amp;quot;guestbook&amp;quot;
......................
(:GUESTBOOK)
CL-USER&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then I can start the server and point my browser to &lt;code&gt;127.0.0.1:3210&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-lisp&quot;&gt;&amp;gt; (guestbook.core:start)
Hunchentoot server is started.
Listening on 127.0.0.1:3210.
Server started
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/guestbook.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;I can send messages that get saved with a timestamp and then delete them. Pretty simple.&lt;/p&gt;
&lt;h2&gt;Reducing boilerplate&lt;/h2&gt;
&lt;p&gt;Lisp became popular for a series of reasons, and one of the most cited is its ability to reduce boilerplate thanks to the metaprogramming capabilities of the language. Lisp hackers are proud of being able to code solutions faster and do exploratory programming, reducing the size of the code they need to write to reach a solution.&lt;/p&gt;
&lt;p&gt;When comparing the lines-of-code count of my Common Lisp guestbook against the Python-Flask version, the latter seems quicker and simpler to write — 36 lines of Python vs. 229 of Lisp. Lisp’s strength is its ability to model itself according to the problem the developer is solving. In this case, I am dealing with a simple guestbook demo, so it may not be strictly necessary, but to present the language better I will try to reduce the size of the program by hiding some code and configuration.&lt;/p&gt;
&lt;p&gt;First, let’s have a look at the new guestbook app, written in my new custom web framework called &lt;em&gt;flashcl&lt;/em&gt;: 29 LOC, properly formatted and stripped of all comments, and not too hard to read.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-lisp&quot;&gt;(in-package :cl-user)
(defpackage guestbook.core
  (:use :cl :flashcl))
(in-package :guestbook.core)

(init-flashcl :sqlite3 &amp;quot;guestbook.sqlite&amp;quot;)

(defmodel message
  ((username :col-type (:varchar 50) :accessor message-username)
   (content  :col-type  :text        :accessor message-content)))

(defroute &amp;quot;/&amp;quot; ()
  (render #P&amp;quot;index.html&amp;quot; (list :messages (db-all &amp;#39;message))))

(defroute (&amp;quot;/message&amp;quot; :method :POST) ()
  (let ((name (form-param &amp;quot;name&amp;quot;))
        (message (form-param &amp;quot;message&amp;quot;)))
    (if (and name message (&amp;gt; (length name) 0) (&amp;gt; (length message) 0))
      (db-add (make-instance &amp;#39;message :username name :content message))
      (format t &amp;quot;Missing body parameters: received ~A~%&amp;quot; (body-params))))
  (redirect &amp;quot;/&amp;quot;))

(defroute (&amp;quot;/message/delete/:id&amp;quot; :method :POST) (&amp;amp;key id)
  (if id
    (let ((id (ignore-errors (parse-integer id))))
      (when id
        (db-delete (db-find &amp;#39;message id)))
      (format t &amp;quot;Missing id parameter.&amp;quot;)))
  (redirect &amp;quot;/&amp;quot;))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Where did &lt;code&gt;start&lt;/code&gt; go? It is now part of the &lt;em&gt;flashcl&lt;/em&gt; framework, so it’s imported in the package. Here’s the usage reference.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-lisp&quot;&gt;;; --- Run the Application ---
;; Call run-app function from your REPL or add it here to run on load.
;; Call stop-app to stop the server.
;;
;; Example: (guestook::run-app) or just (run-app) inside the package.
;; (run-app :port 5000 :server :hunchentoot)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then I slightly modified the template delete button to point to the correct route with the &lt;code&gt;id&lt;/code&gt; parameter.&lt;/p&gt;
&lt;p&gt;I&amp;#39;m going to show just some the new code that I added to write &lt;em&gt;flashcl&lt;/em&gt;. I mostly merged the old code in a new file trying to make it as reusable as I could for other web projects, since it&amp;#39;s possible to define new database models and routes quickly, with support for static files and templates. I used &lt;em&gt;mito&lt;/em&gt;, another library from &lt;a href=&quot;https://github.com/fukamachi/mito&quot;&gt;Eitaro Fukamachi&lt;/a&gt;, which is an ORM that works well with SQLite.&lt;/p&gt;
&lt;p&gt;First I imported the library and exported only what’s needed by the user.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-lisp&quot;&gt;(defpackage :flashcl
  (:use #:cl)
  (:import-from #:caveman2
                #:defroute
                #:redirect
                #:*request*
                #:*response*)
  (:import-from #:lack.request
                #:request-parameters)
  (:import-from #:mito
                #:dao-table-class ; Re-export metaclass for use in defmodel
                #:connect-toplevel
                #:ensure-table-exists
                #:select-dao
                #:find-dao
                #:delete-dao
                #:insert-dao)
  (:export ;; Setup
          #:init-flashcl
          ;; App Definition
          #:flashcl-app ;; Variable holding the app instance
          #:defmodel
          ;; Routing &amp;amp; Request/Response
          #:defroute
          #:form-param
          #:render ;; Re-export caveman&amp;#39;s render (or wrap it)
          #:redirect ;; Re-export caveman&amp;#39;s redirect
          ;; Database
          #:db-all
          #:db-add
          #:db-find
          #:db-delete
          #:dao-table-class ;; Re-export metaclass
          ;; Running
          #:run-app
          #:stop-app))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then I wrote an initialisation function similar to Flask’s, which sets various variables and creates a new instance of the Caveman webapp.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-lisp&quot;&gt;(defun init-flashcl (db-type db-path &amp;amp;optional (template-dir &amp;quot;templates&amp;quot;)
                                               (static-dir &amp;quot;static&amp;quot;))
  &amp;quot;Initializes Flashcl environment. Sets DB/Template paths, connects DB.&amp;quot;
  (setf *database-path* (get-absolute-path db-path))
  (setf *static-directory* (get-absolute-path static-dir))

  ;; Set Djula&amp;#39;s template directory
  (djula:add-template-directory (get-absolute-path template-dir))
  (format t &amp;quot;Set template directory as ~A~%&amp;quot; (get-absolute-path template-dir))

  ;; Connect to SQLite database
  (handler-case (connect-toplevel db-type :database-name *database-path*)
    (error (c)
      (format *error-output* &amp;quot;~&amp;amp;Error connecting to database ~A: ~A~%&amp;quot; *database-path* c)))

  ;; Define the Caveman2 app instance here
  (setf flashcl-app (make-instance &amp;#39;caveman2:&amp;lt;app&amp;gt;)))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To make it easy to define a new database model for the application, hiding the &lt;em&gt;mito&lt;/em&gt; library, I created a macro that ensures the table gets created correctly. &lt;em&gt;mito&lt;/em&gt; automatically adds a few fields to the table definition, like &lt;code&gt;id&lt;/code&gt; and &lt;code&gt;created_at&lt;/code&gt; or &lt;code&gt;updated_at&lt;/code&gt;, so we don&amp;#39;t have to worry about them.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-lisp&quot;&gt;(defmacro defmodel (name slots &amp;amp;rest options)
  &amp;quot;Defines a Mito DAO class and ensures its table exists.
   Example: (flashcl:defmodel comment
              ((name :col-type (:varchar 20))
               (comment :col-type :text)))&amp;quot;
  (let ((class-options options)
        (table-name (string-downcase name))) ; Use singular name by default
    
    ;; Add table name inference if not present
    (unless (find :table-name options :key #&amp;#39;car)
      (push `(:table-name ,table-name) class-options))

    `(progn
      (defclass ,name ()
        ,slots
        (:metaclass mito:dao-table-class)
        ,@class-options)
      ;; Ensure table exists after class definition
      ;; Note: This runs at compile/load time when defmodel is processed.
      ;; Ensure DB is connected before loading code using defmodel.
      (handler-case (ensure-table-exists &amp;#39;,name)
        (error (c)
          (format *error-output* &amp;quot;~&amp;amp;Warning: Could not ensure table for ~A (DB might not be connected yet?): ~A~%&amp;quot; &amp;#39;,name c)))
      ;; Return the class name
      &amp;#39;,name)))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then I added some database helpers to perform a few CRUD actions on the db.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-lisp&quot;&gt;(defun db-all (class-name)
  &amp;quot;Selects all records for the given model class.&amp;quot;
  (select-dao class-name))

(defun db-find (class-name id)
  &amp;quot;Finds a model instance by ID.&amp;quot;
  (find-dao class-name :id id))

(defun db-add (instance)
  &amp;quot;Inserts a model instance into the database.&amp;quot;
  (insert-dao instance))

(defun db-delete (instance)
  &amp;quot;Deletes a model instance from the database.&amp;quot;
  (delete-dao instance))
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Conclusions&lt;/h2&gt;
&lt;p&gt;To recap, in this tutorial I used some of the latest libraries in Common Lisp to create a simple guestbook webapp. Then I wrote a simple reusable wrapper to make our code more concise, aiming to challenge the Flask framework in Python. The full source code of the two versions it&amp;#39;s &lt;a href=&quot;https://github.com/eliascotto/cl-guestbook&quot;&gt;here&lt;/a&gt; and &lt;a href=&quot;https://github.com/eliascotto/cl-guestbook-v2&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Ultimately I would like to give my opinion on using Common Lisp to write a web server. 
Common Lisp shines when dealing with low-level tasks like &lt;a href=&quot;https://blog.funcall.org/lisp%20psychoacoustics/2024/05/01/worlds-loudest-lisp-program/&quot;&gt;small systems programming&lt;/a&gt; or performing &lt;a href=&quot;https://www.grammarly.com/blog/engineering/running-lisp-in-production/&quot;&gt;intensive computation&lt;/a&gt; at scale. When these complex systems need to communicate with the outside world, perhaps via an API, writing a server is the correct way and Common Lisp is capable of delivering that.&lt;/p&gt;
&lt;p&gt;But despite the fact that the language is easily adaptable and comes with performant server libraries (Hunchentoot and Woo), I would say that there are better alternatives for developing generic modern web apps. Hot reloading is now a feature present in many web frameworks, and Common Lisp is not really shining for being ergonomic, nor does it come with many built-ins. Clojure, by contrast, is a modern Lisp dialect with great web frameworks, nice documentation and tons of stable libraries. I would definitely choose the latter for a fresh web project, since with CL I get the feeling that I would end up having to write more code than I should to add custom features and middlewares.&lt;/p&gt;
&lt;p&gt;I would like to give a shout-out to &lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=rheller.alive&quot;&gt;Alive&lt;/a&gt;, which is the only Common Lisp extension for VSCode that implements the REPL with features similar to what SLIME and SLY bring to Emacs. The extension is still under development and not yet a full replacement for Emacs, especially during debugging, but it has great features and a lot of potential to introduce Common Lisp to newcomers, thanks to the VSCode web interface.&lt;/p&gt;
&lt;p&gt;Feel free to email me if you have any questions, recommendations, or even complaints.&lt;/p&gt;
</content:encoded></item><item><title>Le parole di Nabokov</title><link>https://scotto.me/blog/2025-03-11-le-parole-di-nabokov/</link><guid isPermaLink="true">https://scotto.me/blog/2025-03-11-le-parole-di-nabokov/</guid><description>Il suo stile, le sue farfalle e i vocaboli di Lolita.</description><pubDate>Tue, 11 Mar 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;La mia opinione è che Nabokov non lo si legge per la trama. Ogni suo lavoro è una produzione artistica, uno studio meticoloso della prosa che lascia che i lettori sensibili all’estetica, ammaliati dal ritmo della sua scrittura. Nabokov sfida il lettore spingendolo al limite della sua conoscenza semantica, portando vocaboli poco comuni fuori dal loro contesto, trasformando il testo in un gioco stilistico che affascina ma, che al tempo stesso, scatena un complesso d’inferiorità, quando ci si rende conto che una qualità del genere è quantomeno ineguagliabile.&lt;/p&gt;
&lt;p&gt;Avendo di recente riletto il suo capolavoro &lt;em&gt;Lolita&lt;/em&gt; (ne ho anche scritto &lt;a href=&quot;blog/2024-02-04-lolita-nabokov-ita/&quot;&gt;una recensione&lt;/a&gt;) mi sono appuntato le parole di cui non conoscevo il significato, o di cui non ero del tutto certo, e ho deciso di riportarle in questo articolo con una breve definizione. L’invito a leggere Nabokov è sottinteso.&lt;/p&gt;
&lt;p&gt;Per conoscere e capire l’uomo dietro l’elegante scandalo che fu il romanzo, ho guardato &lt;em&gt;How do you solve a problem like Lolita?&lt;/em&gt; — in italiano, come si risolve un problema come Lolita? —, un documentario prodotto dalla BBC riguardo al libro. Nabokov nacque in una facoltosa famiglia della nobiltà russa, cosa che gli permise di vivere in condizioni privilegiate durante la giovinezza, e grazie alla quale ottenne accesso alla cultura internazionale. Imparò il francese e l’inglese — si dice abbia iniziato a leggere e scrivere in inglese prima che in russo —, e si dedicò a riempire quaderni di poesie romantiche durante l’adolescenza. Con la rivoluzione russa, l’intera famiglia fu costretta a scappare e Nabokov decise di trasferisci a Cambridge per studiare letteratura francese al Trinity College. Successivamente seguì il padre a Berlino, dove divenne famoso tra gli emigrati russi come scrittore e poeta, nonostante alcune difficoltà economiche. Con l’aumentare dell’antisemitismo in Germania precedente allo scoppio della guerra, decise di trasferirsi con la moglie Vera a Parigi, per poi qualche anno più tardi muoversi negli Stati Uniti, a Manhattan, avendo ottenuto un ruolo come entomologo al museo di storia naturale di New York. L’anno dopo divenne professore di letteratura e girò diversi college americani finendo la sua carriera alla Cornell University, dov’è alcune sue brillanti lezioni vennero raccolte  in dei libri, il più famoso dei quali è &lt;em&gt;Lezioni di letteratura&lt;/em&gt;. Le opere che composte negli Stati Uniti, tutte scritte in inglese,  lo resero celebre a livello internazionale. Le più famose; &lt;em&gt;Lolita&lt;/em&gt;, &lt;em&gt;Fuoco pallido&lt;/em&gt; e &lt;em&gt;Pnin&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/nabokov.jpeg&quot; alt=&quot;Nabokov che osserva una collezione di farfalle.&quot; title=&quot;© Marc Riboud / Magnum&quot;&gt;&lt;/p&gt;
&lt;p&gt;Oltre a essere un professore poliglotta, e un autore di talento, Nabokov era un appassionato di farfalle. Studiò e catalogò diverse specie, scrisse articoli per addetti ai lavori, e finì addirittura per curare una collezione di lepidotteri presso il Museo di Zoologia Comparata dell’Università di Harvard. Nel documentario hanno intervistato un responsabile del museo che ha confermato come Nabokov non fosse un appassionato alle prime armi, ma un preciso catalogatore di specie di farfalle. Egli, fece diversi viaggi nel mondo dedicandosi alla ricerca di specie rare, e creò una serie di &lt;a href=&quot;https://www.theguardian.com/books/gallery/2016/may/26/vladimir-nabokov-butterfly-art-illustrations&quot;&gt;illustrazioni delle farfalle che studiava&lt;/a&gt;. Cos’hanno in comune le farfalle e la scrittura? In apparenza nulla. Ma se pensiamo allo studio minuzioso dei particolari che hanno in comune le due attività, capiamo che dedizione e precisione sono requisiti essenziali per entrambe. Che il minuzioso studio dei colori dei lepidotteri possa aver contribuito alla precisa scelta delle parole e del tono nelle sue storie? Non lo sappiamo con certezza. Ciò di cui abbiamo invece testimonianza grazie ad alcune interviste è che gli anni passati da Nabokov come entomologo ad Harvard siano stati tra i migliori della sua vita.&lt;/p&gt;
&lt;p&gt;Tra le due passioni, quella che noi comuni lettori possiamo apprezzare è la scrittura, nell’eleganza della sua prosa, nel ritmo musicale e cadenzato, nella scelta accurata di ogni vocabolo. Il protagonista di Lolita è un professore di letteratura francese in America — coincidenze? — con cattive intenzioni, ma di farfalle alate nel romanzo nemmeno l’ombra.&lt;/p&gt;
&lt;p&gt;Ecco la lista delle parole per me difficili trovate in Lolita.&lt;/p&gt;
&lt;hr&gt;
&lt;div class=&quot;no-indent&quot;&gt;

&lt;p&gt;&lt;strong&gt;Chaperon:&lt;/strong&gt; Donna, per lo più anziana, che un tempo accompagnava una giovane nubile di buona famiglia ai ricevimenti e nei viaggi, per salvaguardarne la rispettabilità.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Marleniforme:&lt;/strong&gt; A forma rotonda e bombata, simile a una mela Marlene, tipica del Sud-Tirolo.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“D’un tratto la mano di Lo scivolò nella mia, e all’insaputa del nostro chaperon io strinsi e accarezzai e avvinghiai quella zampetta ardente per tutto il tragitto. Le pinne del naso marleniforme della guidatrice erano lucide, avendo perduto o consumato la loro razione di cipria…”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Bistrate&lt;/strong&gt;: Tinte, oscurate, scurite con il bistro, uba polvere colorante naturale bruno-scura, costituita da idrato di manganese, usata nei colori a olio o ad acquerello.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chador:&lt;/strong&gt; Lungo velo nero, indossato dalle donne islamiche conformemente alla tradizione religiosa. Parola di origine persiana.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Voluttà:&lt;/strong&gt; Il piacere intenso e predominante che si prova nella soddisfazione degli impulsi e dei desideri sessuali&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Eclettico:&lt;/strong&gt; Chi, nell’arte o nella scienza, non segue un determinato sistema o indirizzo, ma sceglie e armonizza i principi che ritiene migliori.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Reptazione:&lt;/strong&gt; Modo di locomozione caratteristico di molti animali, sia invertebrati che vertebrati (in molti rettili, in particolare i serpenti), per cui il corpo striscia sul suolo e non è sollevato sugli arti, che mancano o sono rudimentali.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Gibboso:&lt;/strong&gt; Che porta una gobba.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cicaleccio:&lt;/strong&gt; Il cicalare di più persone insieme; chiacchierio frivolo.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solipsizzata:&lt;/strong&gt; Immersa in una visione solipsistica, isolata nella propria soggettività, come se tutto il resto fosse irrilevante o inaccessibile.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Abbarbicato:&lt;/strong&gt; Radicato saldamente.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Preprandiale:&lt;/strong&gt; Che precede il pranzo.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“Io non progettavo di sposare la povera Charlotte per poi eliminarla in un modo volgare, ripugnante e pericoloso, come metterle cinque compresse di bicloruro di mercurio nello sherry preprandiale o qualcosa del genere…”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Farmacopeico:&lt;/strong&gt; Che si riferisce alla farmacopea, ovvero l&amp;#39;insieme ufficiale di norme riguardanti la preparazione, il controllo e l’uso dei farmaci.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Nevralgica:&lt;/strong&gt; Pervasa da un malessere acuto, come il dolore lungo il decorso di un nervo.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Blusa:&lt;/strong&gt; Camiciotto di tela usato dagli operai e dai pittori durante il lavoro.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Canuto:&lt;/strong&gt; Dai capelli bianchi.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Rotocalco:&lt;/strong&gt; Periodico, rivista.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Scriminatura:&lt;/strong&gt; La linea che segna la spartizione dei capelli.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Serica:&lt;/strong&gt; Di seta, simile alla seta o legato alla seta.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Mefitici:&lt;/strong&gt; Che hanno odore fetido, irrespirabile, malsano.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Smargiasseria:&lt;/strong&gt; Chi si vanta di qualità che non ha e di poter fare cose di cui non è capace.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Enfia:&lt;/strong&gt; Rigonfia, tumefatta.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Berciava:&lt;/strong&gt; Urlava sguaiatamente.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Nerboruto:&lt;/strong&gt; Muscoloso, vigoroso, robusto.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Umbratile:&lt;/strong&gt; Ombreggiato, ombroso.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Incartapecorita:&lt;/strong&gt; Che ha assunto, per decrepitezza, aspetto e consistenza paragonabile alla cartapecora; raggrinzito, rugoso.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Muliebre:&lt;/strong&gt; Della donna, relativo alla donna, con riferimento alle sue qualità, alla dignità del suo ruolo.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Esecrabili:&lt;/strong&gt; Meritevoli di condanna.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Bilioso:&lt;/strong&gt; Pieno di bile, e per estensione irritabile, collerico.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Azzimato:&lt;/strong&gt; Adornato, abbellito con molta cura.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Dedalogia&lt;/strong&gt;: Lo studio e alla teoria dei labirinti o delle strutture complesse e intricate.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Logomanzia:&lt;/strong&gt; Pratica divinatoria che si basa sull&amp;#39;interpretazione di parole, frasi o suoni per prevedere il futuro o ottenere risposte&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“Aveva letto molto. Sapeva il francese. Era versato in dedalogia e logomanzia.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Ondinista:&lt;/strong&gt; Chi crede o pratica la culto delle ondine, figure mitologiche legate all&amp;#39;acqua, spesso rappresentate come spiriti o divinità acquatiche simili a ninfe.&lt;/p&gt;
&lt;/div&gt;</content:encoded></item><item><title>H. P. Lovecraft - Michel Houellebecq</title><link>https://scotto.me/blog/2024-10-24-h-p-lovecraft-houellebecq/</link><guid isPermaLink="true">https://scotto.me/blog/2024-10-24-h-p-lovecraft-houellebecq/</guid><description>Against the World, Against Life.</description><pubDate>Thu, 24 Oct 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I found a new literary genre with which I feel particularly aligned: biographies of writers written by other writers. By calling it &amp;quot;new,&amp;quot; I don&amp;#39;t mean it&amp;#39;s an emerging trend, but rather a type of novel whose evocative power I had never experienced before. I started with &lt;strong&gt;Philip Dick&amp;#39;s&lt;/strong&gt; science fiction when I read the book about him by Emmanuel Carrère, which I liked so much that it made me passionate about both writers. Now, thanks to Michel Houellebecq&amp;#39;s biography of H. P. Lovecraft, which I just finished, I cannot wait to dive into the renowned &lt;em&gt;Necronomicon&lt;/em&gt;, also known as the Book of the Dead.&lt;/p&gt;
&lt;p&gt;Houellebecq&amp;#39;s work is not a complete account of the author&amp;#39;s life, like Carrère&amp;#39;s work on Dick, but rather an analysis of the most significant events of his existence, which, in Lovecraft&amp;#39;s case, are quite few. From a young age, he read horror novels and developed a great passion for Edgar Allan Poe, to the point of starting to write stories himself. He had a &amp;quot;nervous&amp;quot; breakdown just as he reached adulthood, which forced him to withdraw from university and lock himself up at home for several years, during which time he did nothing but read. He came from a once-wealthy family that had fallen into ruin, and after the death of his parents, he found himself with a small inheritance, just enough to live without having to work. Lovecraft devoted himself entirely to writing, sending his stories to publishers without asking for payment. He engaged in hundreds of correspondences and managed to create a small circle of admirers of his works. He married an attractive woman, but the initially happy marriage fell apart after a few years due to financial instability and the lack of a steady job—Lovecraft found no stable employment in New York. He returned alone to Providence, to the family residence, and spent his final years in poverty with his sister, working as a ghostwriter and writing his best works. He died of cancer at 46, practically destitute. Success came too late, but when it came, it was magnificent.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/lovecraft.jpeg&quot; alt=&quot;H. P. Lovecraft&quot; title=&quot;H. P. Lovecraft&quot;&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;The one thing I never do is sit down and seize a pen with the deliberate intention of writing a story. Nothing but hack work ever comes of that. The only stories I write are those whose central ideas, pictures, and moods occur to me spontaneously.”
— &lt;strong&gt;H. P. Lovecraft&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Lovecraft appeared to be a bland, calm, and reserved individual, but in reality, he led a double life. In his horror stories, his vivid imagination was inspired by the deep hatred he felt for the inept bureaucrats who couldn’t give him an honest job, for the Black people who infested New York like monsters, and for a society so complex and deeply flawed that it made him feel like a misfit and a failure. Lovecraft was a misanthrope who spent much of his life as a recluse, writing horror stories. His upper-class bourgeois upbringing had taught him to despise not only money but also all classes or races that weren’t up to his standards. In New York, his hatred and disgust for the people of color who crowded the city grew, something he wasn’t accustomed to, coming from the provinces. When he returned home, these experiences of hatred that overwhelmed him became the source of inspiration for his terrifying and monstrous stories, where the protagonists, usually white and refined scholars, are cruelly attacked without any hope of salvation.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“Reading Lovecraft offers a paradoxical relief to all those who, for one reason or another, have come to feel a genuine aversion to life in all its forms.” 
— &lt;strong&gt;Michel Houellebecq&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In New York, Lovecraft sought work, responding to hundreds of ads and attending hundreds of interviews, only to meet with complete failure. Not finding work made him increasingly disillusioned with life, precisely at the moment when he had married the only woman who had ever loved him, with whom he had imagined a &amp;quot;normal&amp;quot; future together, and perhaps a family. The job market rejected him because he lacked the skills and experience, even though he had an academic education and intellectual abilities above the norm. To him, his inadequacy remained a mystery. I want to quote here an excerpt from a circular he sent to multiple employers: &lt;em&gt;&amp;quot;The concept that a cultured and intelligent person could not quickly acquire any skill in a field slightly outside their habits seems to me at least naive; however, a series of recent events has unequivocally demonstrated to me how widespread this superstition is.&amp;quot;&lt;/em&gt; The elegance with which he highlights the irrational stupidity of these employers is remarkable. They don’t see individual potential unless it is certified by some kind of institution.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“Howard Phillips Lovecraft serves as an example for anyone who wishes to fail in life and, eventually, succeed in art.” 
— &lt;strong&gt;Michel Houellebecq&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Lovecraft failed in life, but succeeded in writing. Houellebecq didn’t choose Lovecraft just because his stories fascinated him as a boy. He chose Lovecraft because, like him he doesn’t feel part of this world, like him he harbors a deep anger toward a society that doesn’t understand him, and both choose to fight it through literature. One thing I like about biographies written by good writers is when they include personal references in the story. In Carrère&amp;#39;s case, the allusions to himself are more explicit, while in Houellebecq’s book, knowing today the future themes of his literary production, we can see the conclusions about Lovecraft’s work, expressed with intense passion, as veiled allusions to the feelings the two writers share. Houellebecq writes about Lovecraft because he recognizes in him the same fate, the same force that will push him to make his life a work of art through dissident literature.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“Writers of the fantastic are generally reactionaries, simply because they are particularly, or one might say professionally, conscious of the existence of Evil.” 
— &lt;strong&gt;Michel Houellebecq&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This short essay on Lovecraft’s work and life offers a glimpse into his psychology that we couldn’t capture through the reading of his books alone. Houellebecq, as a fervent admirer, offers us a suggestive analysis capable of making us feel both pity and respect for the writer from Providence, while encouraging us, through Lovecraft’s exemplary work, to also oppose the hostility of modern life toward true artists.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“Therein lies the deep secret of Lovecraft&amp;#39;s genius, and the pure source of his poetry: he succeeded in transforming his disgust for life into active hostility. To offer an alternative to life in all its forms, to build a permanent opposition, a permanent remedy to life: this is the highest mission of the poet. This mission Howard Phillips Lovecraft accomplished.” 
— &lt;strong&gt;Michel Houellebecq&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The very fitting cover of this English edition deserves a mention, unfortunately abandoned in subsequent ones. With about sixty years between them, the two artists are united by the inner malaise that drives them to want to take a stand, with their work, against the world and against life itself.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/Lovecraft_Against_the_World_Against_Life.png&quot; alt=&quot;H. P. Lovecraft book cover&quot; title=&quot;Lovecraft and Houellebecq, against the world, against life.&quot;&gt;&lt;/p&gt;
</content:encoded></item><item><title>Primer - Shane Carruth</title><link>https://scotto.me/blog/2024-08-20-primer/</link><guid isPermaLink="true">https://scotto.me/blog/2024-08-20-primer/</guid><description>A time-travel thriller.</description><pubDate>Tue, 20 Aug 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;As a first movie on the blog I decided to review perhaps my all-time favorite title: &lt;em&gt;Primer&lt;/em&gt;, the 2004 debut film by Shane Carruth. It’s a psychological science-fiction film in which the two protagonists find themselves confronting the ability to travel through time.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/Primer_poster.jpg&quot; alt=&quot;Primer&apos;s poster&quot; title=&quot;Primer&amp;#39;s poster&quot;&gt;&lt;/p&gt;
&lt;p&gt;The movie was an independent project that succeeded for several reasons, including the choice not to use special effects — a rare thing for a sci-fi movie — and the fact that Carruth did everything on his own. He wrote the script, composed the soundtrack, directed the movie, produced it, filmed it by renting a film camera, and acted as the lead. If that wasn’t enough, the entire project was accomplished on a budget of just $7,000 (in 2004), with friends and family recruited as actors. Filming was so tough for Carruth that he considered quitting multiple times, and it took him two years to complete the post-production. Carruth, a mathematician who worked as a programmer, was inspired by his academic passion for imagining and writing screenplays. A passion that, luckily for us, he decided to pursue to the end, partly financing the project with his savings.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/carruth_in_primer.png&quot; alt=&quot;Shane Carruth in Primer&quot; title=&quot;Shane Carruth in Primer&quot;&gt;&lt;/p&gt;
&lt;p&gt;What fascinated me most about the movie is its complex and simultaneously thrilling plot, which requires the viewer to watch the movie multiple times to fully appreciate it.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Primer&lt;/em&gt; is about two American engineers, Abe and Aaron, who build a strange machine in the garage, having gathered the necessary funding from acquaintances. It’s a device the size of a pillow inserted into a box, capable of creating an energy field through an electronic circuit connected to an argon tank. After several failed attempts, the two engineers discover that the machine can make whatever enters its field travel through time. Realizing the potential, they decide to build a human-sized version of it and use it to go back in time to trade stocks and easily make money, knowing the future market valuations.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/primer_machines.jpg&quot; alt=&quot;&quot;A scene from the movie&quot;&quot; title=&quot;A scene from the movie&quot;&gt;&lt;/p&gt;
&lt;p&gt;The machine works ingeniously, or rather, exactly as one might expect such a device to function. When something enters the field generated by the machine, it travels back to the moment when the machine was first turned on. For example, if a person turns on the machine in the morning and decides to enter in the evening, it means they will travel back in time to the morning. Time travel means moving in a space-time continuum, which means the past is a portion formed by a certain time and space within our reality. Therefore, in the film, it is revealed that when you travel through time, two versions of you exist during the interval you traveled, one unaware version that will eventually enter the machine to disappear, and one aware version that has already experienced everything. Every time the machine is used, a new timeline is created in which two individuals coexist for a certain period.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://upload.wikimedia.org/wikipedia/commons/8/84/Time_Travel_Method-2.svg&quot; alt=&quot;&quot;How time travel works&quot;&quot; title=&quot;How time travel works&quot;&gt;&lt;/p&gt;
&lt;p&gt;One of the most memorable scenes in the movie is when Abe and Aaron see a copy of Abe enter the garage holding a gas cylinder, and following him, they discover that the copy disappears by entering the machine; from that moment on, only one Abe will live in the present.&lt;/p&gt;
&lt;p&gt;If the mechanism isn’t clear, that’s normal; not many grasp it the first time they watch the movie. Fortunately, some enthusiasts on YouTube have created &lt;a href=&quot;https://www.youtube.com/watch?v=-sf9fChyRoc&quot;&gt;video explanations&lt;/a&gt; with timelines that help clarify what really happens in the movie.&lt;/p&gt;
&lt;p&gt;Initially, the plan devised by the two engineers to make quick money works, as they buy and sell stocks using their knowledge of the future market trends. The problem arises when the two realize they can do more than just bet by traveling through time. From here on, the plot of the movie becomes more complicated, with the characters making several time travels, leading to physical damage like sudden blood loss from the ears or a degradation of writing abilities. The viewer ends up losing count of how many trips the characters make, eventually wondering if some scenes they’re watching have already happened before.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Primer&lt;/em&gt; is a movie that plays with logic through its scenes, leaving the viewer the task of reconstructing a linear plot based on what they’ve seen and imagining the existence of missing scenes. Indeed, the plot appears chaotic, with some scenes that don’t seem to follow a linearity or where unexplained things happen if it’s unclear what’s going on. This is because the characters are traveling through time and altering reality. What seems like confusion turns out to be Carruth’s intention to leave elements unresolved, a sort of stylistic signature that he will repeat in his subsequent work. The entire script, Carruth revealed, was adapted to the limited budget he had, demonstrating that you don’t need large capital to make an intriguing and complex movie, just intellect and motivation.&lt;/p&gt;
&lt;p&gt;What fascinates about the movie’s plot is how it presents a much more realistic time travel scenario compared to other works on the same theme. Most stories use time machines that allow characters to go back in history or move forward into the future, developing the plot around the paradoxes that time travel might create. For example, what would happen if, by going back in time, someone altered the course of events preventing their own birth?&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/Stewies-Time-Machine.png&quot; alt=&quot;Stewie Griffin&apos;s time machine&quot; title=&quot;Stewie Griffin&amp;#39;s time machine&quot;&gt;&lt;/p&gt;
&lt;p&gt;Several &lt;a href=&quot;https://en.m.wikipedia.org/wiki/Hawking&apos;s_time_traveller_party&quot;&gt;scientists&lt;/a&gt; have spoken out about the impossibility of humans traveling through time, even though science admits the &lt;a href=&quot;https://www.scientificamerican.com/article/is-time-travel-possible/&quot;&gt;theoretical possibility&lt;/a&gt;. But what if time travel didn’t mean going back hundreds or thousands of years? In &lt;em&gt;Primer&lt;/em&gt;, the machine allows you to travel back in time only to the moment it was first turned on. This eliminates the possibility of going back in history and leaves open the chance that this type of travel might become feasible in the future.&lt;/p&gt;
&lt;p&gt;The plot of &lt;em&gt;Primer&lt;/em&gt; plays with logical paradoxes where the characters, unknowingly, alter the sequence of events, creating multiple versions of themselves that coexist permanently in reality. Aaron and Abe gas their copies and lock them in storage rooms, try to prevent Mr. Granger from using the machine, and end up reliving the same scenes multiple times. Aaron even records an audio description of what happened in the future and what is about to happen to his own copy, trying to prevent new alterations to reality. Aaron’s recording becomes the background voice that Carruth inserts into the film to provide more context to the story, which begins with a phone call. What would we think if we received a recorded phone call from ourselves that we don’t remember, describing exactly what’s about to happen? Would we believe it?&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Primer&lt;/em&gt; is the story of how using technology without fully considering the risks can have disastrous consequences. A sci-fi retelling of the &lt;a href=&quot;https://en.wikipedia.org/wiki/Icarus&quot;&gt;myth of Icarus&lt;/a&gt;.&lt;/p&gt;
</content:encoded></item><item><title>Beautiful star - Yukio Mishima</title><link>https://scotto.me/blog/2024-08-09-beautiful-star/</link><guid isPermaLink="true">https://scotto.me/blog/2024-08-09-beautiful-star/</guid><description>An alien family dealing with the atomic bomb.</description><pubDate>Fri, 09 Aug 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;This is a 1962 work by Yukio Mishima, Japan&amp;#39;s greatest author of the last century, and falls within his most mature period. The plot initially tells the story of an unusual Japanese family, the Ōsugi, who discover they have alien origins. Witnessing various UFO sightings, the family members agree not to reveal their extraterrestrial nature, avoiding unwanted attention. Each family member comes from a different planet, and each begins to internalize their alien identity, associating various aspects of their character with their home planet. The daughter, Akiko, comes from Venus and is therefore exceptionally beautiful, while her brother, Kazuo, comes from Mercury, making him a young man full of hope in the eyes of others. Each family member feels special, different from the &amp;quot;terrestrial&amp;quot; humans living around them. This uniqueness, however, eventually makes the father feel responsible towards the planet that hosts them. Their mission becomes one of bringing peace to Earth through concrete actions, such as writing letters to the Soviet Prime Minister asking him to abandon nuclear weapons, or intervening at the Association of Friends of the Universe to report UFO sightings and information on extraterrestrial activities. From here on, the characters reveal rather human traits. For example, they will witness new UFO sightings and signals from space, Akiko will become pregnant with a playboy&amp;#39;s child, and a group of frustrated adults, led by an unbalanced university professor, will discover the family&amp;#39;s secret and show up at their doorstep.&lt;/p&gt;
&lt;p&gt;In the final chapters, a discussion emerges regarding one of the novel&amp;#39;s themes: what must be done to save a planet dominated by individualistic humans who only think about material pleasures. On one hand, there are three frustrated men who see salvation in the total destruction of humanity through nuclear weapons. They have no real plan, but superficially discuss why humanity is full of flaws and therefore should not be saved. These men are motivated by resentment born from deep-seated disillusionments in their lives, whether towards women who have always rejected and snubbed them, or towards anyone who is not their beloved family, whom they love and constantly remind their companions they intend to save from the massacre. On the other hand, there is the father, Jūichirō Ōsugi, who agrees with the three men that humanity is not headed in the right direction, especially due to the risk of nuclear conflict that could destroy the planet. However, unlike the group, the father wants to save the planet and feels that his goal, as an extraterrestrial being, is to help humans avoid making mistakes.The book&amp;#39;s conclusion focuses on the father&amp;#39;s reflection on his unfulfilled life and the vain sacrifice he made to communicate the dangers that humanity faced if it continued to be reckless.&lt;/p&gt;
&lt;p&gt;Throughout the plot, between UFOs and philosophical discussions on how humans and aliens perceive time differently, Mishima inserts historical references that dominated the political scene of those years, such as Kennedy&amp;#39;s America and Khrushchev&amp;#39;s Soviet Union. The three men in the story consider themselves aliens, superior beings capable of knowing and deciding the fate of humanity, and would not hesitate to listen to their irrational side if they were in front of the button that could launch a nuclear attack. Who gives permission to certain individuals to press that button? When our leaders wage wars and launch bombs on civilians, do they feel like superior beings, extraterrestrials, or simply egoistic and power-hungry humans? Fortunately, the unbalanced individuals in the book do not have the power to destroy humanity, because they would not hesitate to do so for frivolous reasons. The question that arises from the long discussion between the men and the father is: if we had that button in front of us, how would we behave?&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/mishima_rose.png&quot; alt=&quot;Yukio Mishima&quot; title=&quot;Yukio Mishima&quot;&gt;&lt;/p&gt;
&lt;p&gt;The story stems from the fear of nuclear conflict that dominated the Cold War era, where a reckless behavior by a single country could have ruined the beauty of our planet forever.&lt;/p&gt;
&lt;p&gt;Mishima also includes the theme of the meaning of death, which is so important in his works that it drove him to seek a glorious end for himself. In this book, death is a symbol that puts all humans on the same level. Even those who consider themselves aliens cannot escape a terrestrial event that can strip away the veil and reveal the fragile human side of the characters. The father of the family, terrestrial like the others, would perhaps be willing to die to save the planet from destruction and reveal to humans how to make the Earth a wonderful star. This gives rise to a reflection on life rather than death. What is its meaning? What do we live for? Where can we find meaning within it without relying on religious justifications? An important reflection that catches civilization in a dark period where leaders seem to have forgotten the true value of human life.&lt;/p&gt;
</content:encoded></item><item><title>Time Out of Joint - Philip K. Dick</title><link>https://scotto.me/blog/2024-07-31-time-out-of-joint/</link><guid isPermaLink="true">https://scotto.me/blog/2024-07-31-time-out-of-joint/</guid><description>The original Truman Show.</description><pubDate>Wed, 31 Jul 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Published in 1959, &lt;a href=&quot;https://en.wikipedia.org/wiki/Time_Out_of_Joint&quot;&gt;&lt;em&gt;Time Out of Joint&lt;/em&gt;&lt;/a&gt; is a science fiction novel by Philip K. Dick. The protagonist is Ragle Gumm, a man who lives with his sister Margo&amp;#39;s family and makes a living by answering a daily quiz called “Where Will the Little Green Man Appear?” published in a newspaper. The game consists of a large grid where Ragle have to guess in which square the little green man will appear in each day. Ragle is the undisputed champion of the contest, an extraordinary result achieved thanks to his ability to quickly identify patterns that lead him to the solution.&lt;/p&gt;
&lt;p&gt;The mystery in the novel begins when Vic, the husband of Ragle&amp;#39;s sister Margo, goes to the bathroom in his house during a poker game and tries to pull a chain hanging from the ceiling to turn on the light. He discovers that the chain does not exist but that there is a switch on the wall to turn on the light. From this event, the reality in which the novel is set begins to falter, raising doubts among the characters, who continue the story in a climax of shocking revelations.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/pkd.png&quot; alt=&quot;Philip K. Dick&quot; title=&quot;Philip K. Dick&quot;&gt;&lt;/p&gt;
&lt;p&gt;Following Philip Dick&amp;#39;s narrative style, the characters are minimally characterized, the setting is a 1950s American town, and the protagonists are fearful of the threats of those years, such as the atomic conflict. The entire story serves as a backdrop for the science fiction theater that Dick stages, creating a suspense that keeps readers glued to the pages.&lt;/p&gt;
&lt;p&gt;One last curiosity is that the plot of &lt;em&gt;The Truman Show&lt;/em&gt;, a 1998 film, was inspired by the novel. But in the book case, it&amp;#39;s not about a TV show.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;Spoilers ahead.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The references in this story are diverse. Dick tried a new formula for the novel’s plot, compared to his previous works: everyone knows except the protagonist. In fact, more than halfway through the work, it becomes apparent that the reality constructed around Ragle&amp;#39;s life is fictitious. When he escapes from the town, the protagonist discovers he is more famous than he thought, even though he doubted himself because, still unmarried, he lived at his sister&amp;#39;s house. Ragle, by solving the green man competition in a newspaper, is the one who helps discover where the enemy missiles will fall. Unknowingly, he is an essential part of the defense project, and the government uses his sophisticated analyses to protect the planet. What Ragle does in life is extremely useful to humanity, engaged in an interplanetary war, only he couldn’t realize it before.&lt;/p&gt;
&lt;p&gt;Thanks to the biography of Philip Dick curated by Emmanuel Carrère titled &lt;a href=&quot;https://en.wikipedia.org/wiki/I_Am_Alive_and_You_Are_Dead_(book)&quot;&gt;&lt;em&gt;I Am Alive and You Are Dead&lt;/em&gt;&lt;/a&gt;, we discover that Ragle is actually Dick’s alter ego, who spent his days writing science fiction books for children to barely make a living, instead of dedicating himself to greater works he hoped to write one day. Ragle dedicates himself to finding the position of the green man, and the green men were precisely the beings that appeared in the science fiction booklets published in the 1950s, considered minor literature at the time, not worthy of standalone volumes. Ragle solves competitions about green men, Dick writes stories about green men; both follow a passion instead of engaging in real work like responsible adults as society wants them to.&lt;/p&gt;
&lt;p&gt;The episode of the cord, mentioned above, is a real event in Dick&amp;#39;s life. As his biographer Carrère says, while normal people when something unexpected happens say: &amp;quot;How strange,&amp;quot; and don&amp;#39;t think about it anymore, Dick kept thinking about it and wondering if there were any hidden meanings. The chain he remembered being in the bathroom could have been some part of his memory that was compromised, a past memory that, for some reason, now reappeared; a &lt;em&gt;glitch&lt;/em&gt; in reality, we would say today.&lt;/p&gt;
&lt;p&gt;What matters to us is that Dick did an extraordinary job of writing down these delusional obsessions that made him famous. Whether he was right or wrong, we still cannot know with absolute certainty; maybe we are really living in a simulation. Dick always thought of himself as a &amp;quot;chosen one&amp;quot;, someone who saw reality differently, and had the need to communicate it to us. He, unlike Ragle, knew, while everyone else was in the dark.&lt;/p&gt;
</content:encoded></item><item><title>Rust 101</title><link>https://scotto.me/blog/2024-04-10-rust-101/</link><guid isPermaLink="true">https://scotto.me/blog/2024-04-10-rust-101/</guid><description>Rust 101</description><pubDate>Wed, 10 Apr 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I’ve recently had the chance to try Rust for a project and it has been a surprising pleasant experience. Rust is a modern language and I felt quire familiar with it in a few days. It has a simple and effective design and thanks to that, it gets frequently mentioned as a successor to old low level languages C like. Rust is &lt;em&gt;fast&lt;/em&gt; and, in a lot of benchmarks, the compiled code performance is comparable to C and C++. I don’t have experience yet with other similar low-level languages as &lt;em&gt;&lt;a href=&quot;https://nim-lang.org/&quot;&gt;Nim&lt;/a&gt;&lt;/em&gt; or &lt;em&gt;&lt;a href=&quot;https://ziglang.org/&quot;&gt;Zig&lt;/a&gt;&lt;/em&gt; but I believe that there’s a reason why Rust got extremely &lt;a href=&quot;https://survey.stackoverflow.co/2023/#section-admired-and-desired-programming-scripting-and-markup-languages&quot;&gt;popular&lt;/a&gt; in the last few years.&lt;/p&gt;
&lt;p&gt;In this article I’ll write down a quick overview of the most important concept that I found make Rust a different and more evolved language compared to it’s predecessor. The Rust &lt;a href=&quot;https://doc.rust-lang.org/book/&quot;&gt;documentation&lt;/a&gt; is really well written with a lot of example and it will allow you to use the language in a very short time.&lt;/p&gt;
&lt;h2&gt;Memory Safety&lt;/h2&gt;
&lt;p&gt;Rust is a memory &lt;em&gt;safe&lt;/em&gt; language which means that it’s design prevent the programmer to do operation that could provoke memory faults and crashes of the program. If you ever wrote C or C++ you know what kind of bugs I’m talking about. This kind of problems are hard to spot and debug and in complex programs, it gets easy to use an already free memory or to forget to free one.&lt;/p&gt;
&lt;p&gt;There have been two main ways to manage program memory. One is letting the memory management in the hands of the programmer (as C, C++), and the other is using a Garbage Collector that will clean the unused allocated memory portions for you (as Lisp, Java, Python, JS). Manually freeing the memory can get complicated with large and complex programs, and automatic garbage collection can slow down your execution at random, and it’s not that easy to control. &lt;/p&gt;
&lt;p&gt;Rust bring a different approach; writing programs that are actually memory safe by design. It does that by not exposing the memory management functions, without using an external tool to do the job. It introduces the concept of &lt;em&gt;ownership&lt;/em&gt;, a set of rules that check your code at &lt;em&gt;compile time&lt;/em&gt; to prevent you to do  operations that break the ownership of a variable.&lt;/p&gt;
&lt;h3&gt;Ownership&lt;/h3&gt;
&lt;p&gt;This are the ownership rules:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Each value in Rust has an &lt;em&gt;owner&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;There can only be one owner at a time.&lt;/li&gt;
&lt;li&gt;When the owner goes out of scope, the value will be &lt;em&gt;dropped&lt;/em&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-rust&quot;&gt;let s1 = String::from(&amp;quot;hello&amp;quot;); // s1 is the owner of the String
let s2 = s1; // s2 becomes the new owner, and s1 is invalidated
println!(&amp;quot;{}, world!&amp;quot;, s1); // This will cause a compile-time error because s1 is no longer valid
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The previous code will not compile. The compiler would even give you suggestion to what caused the error: &lt;code&gt;error[E0382]: borrow of moved value: s1&lt;/code&gt;. One may think that the string s1 should still be there, but in reality Rust already called &lt;code&gt;drop&lt;/code&gt; on the string structure, deallocating the memory segment and making it no longer valid.&lt;/p&gt;
&lt;p&gt;Rust is getting in the way of the programmer for a good reasons; following this rules will prevent problems with memory deallocation, like forgetting to deallocate something, accessing a resource already deallocated, or double freeing a variable. In exchange, Rust is enforcing some patterns and providing some data structure to solve all ownership problems. The following is a useful schema I found on reddit, that quickly points you to which data structure is better to use for each scenario (&lt;code&gt;T&lt;/code&gt; is the generic data type).&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/nhhxzcwqd6q61.png&quot; alt=&quot;rust ownership diagram&quot; title=&quot;source: https://www.reddit.com/r/rust/comments/mgh9n9/ownership_concept_diagram/&quot;&gt;&lt;/p&gt;
&lt;h3&gt;Borrowing&lt;/h3&gt;
&lt;p&gt;Borrowing is a mechanism that allows you to create references to data owned by another variable, enabling multiple parts of your code to access and potentially modify the same data without transferring ownership.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-rust&quot;&gt;fn main() {
    let mut s = String::from(&amp;quot;hello&amp;quot;);

    change(&amp;amp;mut s);
}

fn change(some_string: &amp;amp;mut String) {
    some_string.push_str(&amp;quot;, world&amp;quot;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the code above, I&amp;#39;ve just created an &lt;em&gt;mutable reference&lt;/em&gt; to a &lt;code&gt;String&lt;/code&gt; object, and passed it to a function that modify the string. This behaviour it&amp;#39;s called borrowing, since we &lt;em&gt;borrow&lt;/em&gt; the value, and then give it back to the caller when finished using it.&lt;/p&gt;
&lt;p&gt;In Rust, we cannot borrow as &lt;em&gt;mutable&lt;/em&gt; variable more than once. This restriction of preventing multiple mutable references to the same data, helps preventing &lt;a href=&quot;https://en.wikipedia.org/wiki/Race_condition#Data_race&quot;&gt;&lt;em&gt;data races&lt;/em&gt;&lt;/a&gt; at compile time.&lt;/p&gt;
&lt;h2&gt;Structs and objects&lt;/h2&gt;
&lt;p&gt;Rust allows the creation of custom data types using &lt;code&gt;struct&lt;/code&gt; and &lt;code&gt;enum&lt;/code&gt;. A struct is between a C &lt;em&gt;struct&lt;/em&gt; and a C++ &lt;em&gt;class&lt;/em&gt;. It can be used as object and have access to &lt;code&gt;self&lt;/code&gt;, but it’s missing a full support for &lt;em&gt;inheritance&lt;/em&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-rust&quot;&gt;struct Rectangle {
    width: u32,
    height: u32,
}

impl Rectangle {
    fn new(w: u32, h: u32) -&amp;gt; Rectangle {
        Rectangle {
            width: w,
            height: h,
        }
    }

    fn area(&amp;amp;self) -&amp;gt; f64 {
        (self.width * self.height) as f64
    }
}

fn main() {
    let mut rect = Rectangle::new(3, 4);
    println!(&amp;quot;Area: {}&amp;quot;, rect.area());
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A new struct &lt;code&gt;Rectangle&lt;/code&gt; has been defined, with a simple &lt;code&gt;area&lt;/code&gt; method which access the property using the reference to itself.&lt;/p&gt;
&lt;p&gt;When a new struct is defined inside a file, it can be &lt;em&gt;encapsulated&lt;/em&gt; simply by avoiding the use of &lt;code&gt;pub&lt;/code&gt; on the methods. This way, they will not be visible from outside but still accessible from inside.&lt;/p&gt;
&lt;h3&gt;Traits&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Polymorphism&lt;/em&gt; can be pefrormed by defining a &lt;code&gt;Trait&lt;/code&gt; which adds the possibility to have shared behaviour between structures. &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-rust&quot;&gt;trait Area {
    fn area(&amp;amp;self) -&amp;gt; f64;
}

impl Area for Circle {
    fn area(&amp;amp;self) -&amp;gt; f64 {
        std::f64::consts::PI * self.radius * self.radius
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here I&amp;#39;ve defined a trait &lt;code&gt;Area&lt;/code&gt; which every shape struct can implement in it’s own way. The trait it’s only the function signature, with parameters and expected return type.&lt;/p&gt;
&lt;h3&gt;Enum&lt;/h3&gt;
&lt;p&gt;Enum are just a way of define a set of values that a variable of that type can take. It’s similar to &lt;code&gt;struct&lt;/code&gt; in the sense that accept the use of &lt;code&gt;impl&lt;/code&gt; with custom methods and traits.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-rust&quot;&gt;enum Animal {
    Bird,
    Insect,
    Fish,
    Mammal,
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Pattern matching&lt;/h2&gt;
&lt;p&gt;Pattern matching is a construct that is essential in the Rust design. It allows to automatically match the value of a variable using it’s possible states, similar to the statement &lt;code&gt;case&lt;/code&gt; in other languages. I use the operator &lt;code&gt;match&lt;/code&gt; that receives the variable and give the possibility to execute code when a value is matching.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-rust&quot;&gt;impl Animal {
    fn can_fly(&amp;amp;self) -&amp;gt; bool {
        match self {
            Animal::Bird =&amp;gt; true,
            Animal::Insect =&amp;gt; true,
            _ =&amp;gt; false, // Covers Fish and Mammal
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For example, here it&amp;#39;s matching all the possible states that a variable of type &lt;code&gt;Animal&lt;/code&gt; can have. The option &lt;code&gt;_&lt;/code&gt; is a catch-all pattern, representing all the other possible states that the variable can take.&lt;/p&gt;
&lt;h2&gt;Result and Option&lt;/h2&gt;
&lt;p&gt;Two enumerated types that are part of the Rust standard library are &lt;code&gt;Result&lt;/code&gt; and &lt;code&gt;Option&lt;/code&gt;. They’re values used to deal with errors that need to be managed and potentially absent values. To access the value, the pattern matching method shown above is required.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Result&lt;/code&gt; is used in case a function may fail and there&amp;#39;s a need to grab the exception and handle it. Rust allows functions to throw errors and then catch them from the caller by performing a &lt;code&gt;match&lt;/code&gt; on the function&amp;#39;s returned value.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-rust&quot;&gt;use std::fs::File;
use std::io;

fn read_file(path: &amp;amp;str) -&amp;gt; Result&amp;lt;String, io::Error&amp;gt; {
    let file = File::open(path)?;
    let mut contents = String::new();
    file.read_to_string(&amp;amp;mut contents)?;
    Ok(contents)
}

fn main() {
    match read_file(&amp;quot;example.txt&amp;quot;) {
        Ok(contents) =&amp;gt; println!(&amp;quot;File contents: {}&amp;quot;, contents),
        Err(error) =&amp;gt; println!(&amp;quot;Error reading file: {}&amp;quot;, error),
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;?&lt;/code&gt; is a special operator in Rust that allows to return the error directly, saving you the boilerplate of writing another match.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Option&lt;/code&gt; instead is used to return an optional value, since Rust doesn’t have the concept of &lt;code&gt;null&lt;/code&gt; (and no Null Pointer Exception).&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-rust&quot;&gt;fn find_first_even(numbers: &amp;amp;[i32]) -&amp;gt; Option&amp;lt;i32&amp;gt; {
    for num in numbers {
        if num % 2 == 0 {
            return Some(*num);
        }
    }
    None
}

fn main() {
    let numbers = vec![1, 3, 5, 7, 8];
    match find_first_even(&amp;amp;numbers) {
        Some(even) =&amp;gt; println!(&amp;quot;First even number: {}&amp;quot;, even),
        None =&amp;gt; println!(&amp;quot;No even numbers found&amp;quot;),
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Functional&lt;/h2&gt;
&lt;p&gt;Rust took &lt;em&gt;closures&lt;/em&gt; and &lt;em&gt;iterators&lt;/em&gt; from functional programming. It&amp;#39;s easy to write inline functions and iterate over array with the set of functions available for functional programming.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-rust&quot;&gt;let numbers = vec![1, 2, 3, 4, 5];
let doubled: Vec&amp;lt;_&amp;gt; = numbers.iter().map(|x| { x * 2 }).collect();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the code above I&amp;#39;m using &lt;code&gt;map&lt;/code&gt; over a list of numbers, and running the lambda function &lt;code&gt;|x| x * 2&lt;/code&gt; on it, in fact creating a closure. If you need to add the possibility to add iteraction support to a struct, you would need to implement the &lt;code&gt;Iterator&lt;/code&gt; trait, as shown &lt;a href=&quot;https://doc.rust-lang.org/rust-by-example/trait/iter.html&quot;&gt;in the docs&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Analyzer&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/rust-lang/rust-analyzer&quot;&gt;rust-analyzer&lt;/a&gt; is what is going to help you understanding Rust and the patterns that the language is guiding you to use. When integrated inside your favourite editor (I’m using &lt;a href=&quot;https://zed.dev/&quot;&gt;Zed&lt;/a&gt; right now), you will see warning and errors generated directly when saving a file.&lt;/p&gt;
&lt;p&gt;Let’s try to analyse some broken code&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-rust&quot;&gt;fn main() {
    let s1 = String::from(&amp;quot;hello&amp;quot;);
    let s2 = s1;
    println!(&amp;quot;{}&amp;quot;, s1);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Why is this code broken?&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-rust&quot;&gt;error[E0382]: borrow of moved value: `s1`
  --&amp;gt; src/main.rs:4:20
   |
65 |     let s1 = String::from(&amp;quot;hello&amp;quot;);
   |         -- move occurs because `s1` has type `String`, which does not implement the `Copy` trait
66 |     let s2 = s1;
   |              -- value moved here
67 |     println!(&amp;quot;{}&amp;quot;, s1);
   |                    ^^ value borrowed here after move
   |
   = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider cloning the value if the performance cost is acceptable
   |
66 |     let s2 = s1.clone();
   |                ++++++++
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Rust is telling that when the code does &lt;code&gt;s2 = s1&lt;/code&gt;, it moves the value &lt;code&gt;s1&lt;/code&gt; so it cannot be used anymore in the &lt;code&gt;println&lt;/code&gt; call. A solution is to &lt;em&gt;clone&lt;/em&gt; &lt;code&gt;s1&lt;/code&gt; into &lt;code&gt;s2&lt;/code&gt; so it will then have two independent instances of the string. Pretty handy to find a quick solution, especially for beginners. The Rust team did a great job for creating high quality error messages to guide the user to find a solution.&lt;/p&gt;
&lt;h2&gt;Macros&lt;/h2&gt;
&lt;p&gt;Rust supports different types of macros: &lt;em&gt;declarative&lt;/em&gt; and &lt;em&gt;procedural&lt;/em&gt;. Macro helps extending the language by removing boilerplate code and even extending programs with external code (e.g. plugins).&lt;/p&gt;
&lt;p&gt;Declarative macros are called like functions, they just append &lt;code&gt;!&lt;/code&gt; to their name.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-rust&quot;&gt;#[macro_export]
macro_rules! vec {
    ( $( $x:expr ),* ) =&amp;gt; {
        {
            let mut temp_vec = Vec::new();
            $(
                temp_vec.push($x);
            )*
            temp_vec
        }
    };
}

let v = vec![1, 2, 3, 4]; // Creates a new vec inline
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;My suggestion is to avoid using macros and always prefer functions where possible. Macros are hard to understand, maintain and document when they get complex.&lt;/p&gt;
&lt;h2&gt;Cargo and packages&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;cargo&lt;/code&gt; is the official package manager for Rust. It downloads the dependencies and keep track of the Rust version the project is supporting. It can be used for all the task related to the project, like running, building it, generating the documentations, etc. The package registry is &lt;a href=&quot;https://crates.io/&quot;&gt;crates.io&lt;/a&gt; which counts more than 140K packages as today.&lt;/p&gt;
&lt;h2&gt;Tests&lt;/h2&gt;
&lt;p&gt;Rust provides a test framework directly in the language which supports both &lt;em&gt;unit&lt;/em&gt; and &lt;em&gt;integration&lt;/em&gt; tests. &lt;code&gt;cargo test&lt;/code&gt; is how to run all the tests for a project.&lt;/p&gt;
&lt;p&gt;This is a unit test example, included in the same file of the function implementation.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-rust&quot;&gt;#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
        let result = 2 + 2;
        assert_eq!(result, 4);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;When to use Rust&lt;/h2&gt;
&lt;p&gt;Rust got really popular in the last few years, but it&amp;#39;s not a solution for all coding problems, nor a suitable alternative for all cases. When performance is a requirement, instead of using C or C++, Rust can provide much nicer usability and ergonomics, since it&amp;#39;s nearly as fast as C but definitely safer, and the choice will pay off in the long run. &lt;a href=&quot;https://discord.com/blog/why-discord-is-switching-from-go-to-rust&quot;&gt;Big companies&lt;/a&gt; have started adopting Rust effectively with great results and enough performance gains in critical parts of their applications to justify the choice.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/u80ujhbe23rc1.png&quot; alt=&quot;rust nation uk&quot; title=&quot;Rust Nation UK on Youtube&quot;&gt;&lt;/p&gt;
</content:encoded></item><item><title>Humankind - Rutger Bregman</title><link>https://scotto.me/blog/2024-04-06-humankind-rutger-bregman/</link><guid isPermaLink="true">https://scotto.me/blog/2024-04-06-humankind-rutger-bregman/</guid><description>Una nuova storia (non cinica) dell&apos;umanità.</description><pubDate>Sat, 06 Apr 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;/assets/img/humankind.png&quot; alt=&quot;humankind&quot; title=&quot;Humankind&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Humankind&lt;/em&gt; (in italiano &amp;quot;Una nuova storia (non cinica) dell&amp;#39;umanità&amp;quot;) è stata una lettura che mi ha sconvolto. Consiglio di astenersi dal leggerlo a chi vuole rimanere fedele a vecchie ideologie del secolo scorso, perché questo libro potrebbe far cambiare radicalmente idea sul genere umano e sulla società che abbiamo creato negli ultimi secoli. Se anche voi, come me, dopo aver letto &lt;em&gt;Sapiens&lt;/em&gt; di Harari, avete pensato che le recenti scoperte scientifiche confermino l&amp;#39;idea che l&amp;#39;essere umano sia per natura egoista, cinico e perverso, &lt;em&gt;Humankind&lt;/em&gt; vi farà cambiare opinione. Il libro inizia mettendo in discussione il dogma che l&amp;#39;uomo sia per natura &lt;em&gt;egoista&lt;/em&gt;, fondandosi sulle opere di pensatori come Machiavelli, Hobbes, Nietzsche, Freud, Dawkins e molti altri che hanno diffuso questa convinzione in Occidente. Questo mito viene sfatato dall&amp;#39;autore, che usa le ultime ricerche scientifiche per smentire le prove che sono state usate nella storia per sostenere la vecchia ideologia.&lt;/p&gt;
&lt;p&gt;Rutger Bregman, filosofo e giornalista olandese classe &amp;#39;88, torna agli inizi del XVIII secolo quando &lt;em&gt;Hobbes&lt;/em&gt;, in Inghilterra, credeva che l&amp;#39;uomo nasca cattivo ed egoista e la società sia ciò che lo salva dai suoi istinti bestiali. Mentre nello stesso periodo in Francia, &lt;em&gt;Rousseau&lt;/em&gt; era convinto del contrario, ossia che per istinto l&amp;#39;uomo è buono e che la civiltà moderna lo abbia invece danneggiato. Il libro si pone di dare una risposta alla domanda su quale delle due idee contenga la verità, facendo una ricerca che parte dall&amp;#39;evoluzione umana, e ripercorre le tappe che hanno preceduto l&amp;#39;evento che ha dato inizio alla storia della nostra civiltà: la privatizzazione dei terreni. L&amp;#39;autore argomenta, con molti esempi anche recenti, che quell&amp;#39;evento è stata la fonte di molti problemi che ancora oggi affliggono l&amp;#39;uomo, tra cui spicca l&amp;#39;egoismo generato dalla disuguaglianza tra chi possedeva molto e chi nulla.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;A meno di tre anni, i bambini dividono equamente una torta; a sei anni, preferiscono buttarne via una parte piuttosto che dare a uno solo una fetta più grande.&amp;quot; - Rutger Bregman&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;La risposta che dà Bregman è chiara. L&amp;#39;uomo è un animale altamente sociale, evoluto per essere compassionevole con i membri della sua specie; è in grado di ottenere enormi vantaggi applicando questo comportamento, tra i quali spicca l&amp;#39;abilità di apprendere rapidamente dagli altri. Questo è il fattore che ha fatto sì che l&amp;#39;homo sapiens sia stato in grado di sopravvivere e di diffondersi al posto delle altre specie di ominidi. A quanto pare &lt;em&gt;homo homini lupus&lt;/em&gt; è stato un errore grossolano perpetrato per secoli.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;Per il 95 per cento della nostra storia abbiamo vissuto in un mondo relativamente pacifico ed egualitario. Ci siamo evoluti per collaborare e prenderci cura gli uni degli altri.&amp;quot; - Rutger Bregman&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Come mai l&amp;#39;uomo ha accettato di passare da vivere un&amp;#39;esistenza da cacciatore-raccoglitore a vivere stabilmente coltivando la terra? Come mai abbiamo accettato la civiltà e idee come il denaro? Cosa rende alcune persone più capaci a comandare rispetto agli altri? Sono molte le domande a cui il libro si pone, evitando risposte ciniche e guardando in modo oggettivo ai risultati delle ricerche scientifiche degli ultimi anni. Bregman in molti casi racconta di aver creduto in prima persona a idee sbagliate, anche a causa di intellettuali odierni come Noah Harari, Malcolm Gladwell e Richard Dawkins, i quali, pur avendo scritto bestseller, non hanno sempre verificato in maniera approfondita la validità delle fonti da cui hanno attinto.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;Dagli studi psicologici, infatti, risulta che chi si sente impotente è più insicuro; esita prima di esprimere la propria opinione; in un gruppo, si fa più piccolo. Si sente più stupido di quanto sia in realtà. Sono sentimenti che ai potenti fanno comodo. Persone che dubitano di se stesse non si ribellano.&amp;quot; - Rutger Bregman&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;La cosa più notevole del libro, oltre alle sorprendenti conclusioni che ribaltano il pensiero dominante sulla specie umana, è la consapevolezza costante che inculca nel lettore che l&amp;#39;uomo è un animale buono. Concetti come la fiducia reciproca, l&amp;#39;imparzialità, il coraggio, la generosità e la compassione per gli altri, sono stati fin dall&amp;#39;inizio dei secoli elementi fondamentali per l&amp;#39;evoluzione dell&amp;#39;uomo e, conclude Bregman, devono tornare a essere priorità nella nostra vita.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;Come la maggior parte di noi diventerebbe vegetariana all&amp;#39;istante se dovesse macellare da sé una mucca, così la maggior parte dei soldati diventa obiettore di coscienza appena il nemico si avvicina troppo.&amp;quot; - Rutger Bregman&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Nella seconda parte, il libro racconta di casi in cui sono stati usati degli approcci fuori dal comune, in campi come la gestione aziendale, l&amp;#39;istruzione, la politica e gli istituti penitenziari. Essi diventano esempi e strategie concrete e attuabili per migliorare una società globale che tutti concordano non stia oggi lavorando nell&amp;#39;interesse dell&amp;#39;umanità. &lt;em&gt;Humankind&lt;/em&gt; è stato uno di quei libri che tengono incollati e mi ha fatto venire voglia di far sapere a tutti ciò che rivela. È una visione diversa e più positiva di simili autori di bestseller - forse per questo l&amp;#39;autore non viene invitato spesso a parlare con i &amp;quot;big&amp;quot; del presente. &amp;quot;È possibile cambiare il presente, ecco perché farlo e da dove potremmo partire&amp;quot;, questo è il tema del libro. Bregman è molto convincente, scrive molto bene e ha idee uniche da cui partire per ragionare su come potremmo cambiare il sistema in cui viviamo, partendo dal basso. Ci vuole coraggio per andare contro alle ideologie che dominano i nostri tempi. Consigliato.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;Quelle che noi chiamiamo le &amp;quot;pietre miliari della civiltà&amp;quot; – l&amp;#39;invenzione del denaro, della scrittura e della giustizia – furono, in origine, le pietre miliari dell&amp;#39;oppressione.&amp;quot; - Rutger Bregman&lt;/p&gt;
&lt;/blockquote&gt;
</content:encoded></item><item><title>Un indovino mi disse - Tiziano Terzani</title><link>https://scotto.me/blog/2024-04-03-un-indovino-mi-disse-terzani/</link><guid isPermaLink="true">https://scotto.me/blog/2024-04-03-un-indovino-mi-disse-terzani/</guid><description>Racconto del suo viaggio in Asia.</description><pubDate>Wed, 03 Apr 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;/assets/img/terzani3.webp&quot; alt=&quot;Tiziano Terzani&quot; title=&quot;Tiziano Terzani&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Un indovino mi disse&lt;/em&gt;, racconta il viaggio che Tiziano Terzani compì attraverso l’Asia all’inizio degli anni novanta, evitando gli aerei per sfuggire alla morte, come gli era stato suggerito di fare da un veggente. Con la scusa di consultare gli indovini più rinomati in tutti i paesi in cui si ferma, Terzani mostra i cambiamenti che il continente ha subito negli ultimi anni a causa della ricerca smodata di modernità. Molte città si stavano trasformando da paradisi di pace e tranquillità in metropoli occidentali, i colletti bianchi e l’abbigliamento alla moda stavano sostituendo gli abiti tradizionali e i sandali, mentre grattacieli sorgevano in pochi mesi al posto di luoghi sacri e giardini centenari. Terzani intuisce le conseguenze che una corsa sconsiderata al progresso avrebbe lasciato su un continente antico come l’Asia e sulla sua popolazione inadeguata al cambiamento; la scomparsa delle culture e delle tradizioni, lo sfruttamento del lavoro e delle risorse naturali, il turismo aggressivo che avrebbe rovinato l’unicità e la sacralità di molti luoghi rendendoli uguali a qualsiasi altra attrazione nel resto del mondo. Secondo Terzani, l’Asia avrebbe presto perso quella magia che la rendeva speciale.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;Tutti corrono, ma verso dove? Perché? Molti sentono che questo correre non ci si addice e che ci fa perdere tanti vecchi piaceri.&amp;quot; - Tiziano Terzani&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Nel viaggio avventuroso tra i molteplici paesi del continente, Terzani viene a contatto con diverse persone che include nel racconto; venditori mongoli con il vizio del vino, dittatori che gestiscono traffici di droga, benefattori e studiosi che lo spronano e lo aiutano nella sua ricerca degli indovini. Sono soprattutto le parole dei veggenti che risaltano tra le pagine del libro, alcuni facevano previsioni strampalate, mentre altri, ricevendo data e ora di nascita, erano in grado di descrivere in modo sorprendente il passato e il futuro di chi li consultava. Terzani riporta le parti essenziali di queste conversazioni, farcendole sempre con la giusta dose di scetticismo che ci si aspetta da un giornalista europeo. L&amp;#39;autore dimostra inoltre di avere una mente aperta, al punto da riuscire a comprendere cambiamenti politici complessi, come il motivo per cui la Malesia si fosse aggrappata a sostenere un nuovo fondamentalismo islamico per porre un freno all’invasione del materialismo cinese. Il reportage del viaggio è ricco di aneddoti e di riferimenti ad altri autori le cui opere lo accompagnano sui treni e sulle navi che prende. Terzani parla della sua vita privata e della sua famiglia, e inserisce riferimenti alla sua carriera e alla scelta di abbandonare un posto fisso stabile e remunerato per ottenere la libertà di poter viaggiare dove gli piaceva. Come gli dicono molti gli indovini, “non diventerà ricco, ma farà successo”, e che era molto “fortunato”. Che avesse dubbi in merito, poco importa; il libro ha oggi superato le 800 mila copie e credo di poterlo aggiungere alla mia lista di opere che mi hanno lasciato un segno.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;Dopo il Medioevo del materialismo, l’umanità dovrà ricominciare a mettere altri valori nella propria esistenza.&amp;quot; - Tiziano Terzani&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;em&gt;Tutti corrono, ma verso dove?&lt;/em&gt; Terzani non parla solo della corsa al progresso o della corsa al successo, ma anche di quanto vanno di corsa i turisti. Arrivano in massa sugli aerei e in due settimane pretendono di viaggiare in tre paesi diversi e vivere tutte le esperienze possibili, vedere tutte le attrazioni disponibi, scattare centinaia di inutili foto per mostrare a tutti che anche loro si possono permettere di viaggiare. All’apparenza non c’è nulla di male; chi dice che non si può prendere un aereo per andare ovunque nel mondo? Esistono tanti servizi fatti apposta per questo, come B&amp;amp;B, tour operator, viaggi last-minute, è così che viaggiano tutti. La verità è semplicemente che il turismo di massa è diventata un&amp;#39;altra manifestazione del consumismo. È irrealistico pretendere di conoscere un paese e la sua tradizione in soli dieci giorni di viaggio, soprattutto se tutto è già stato organizzato. Si tende a visitare le principali attrazioni turistiche, vivendo un&amp;#39;esperienza superficiale. Non si riesce a comprendere appieno la vita quotidiana e il pensiero degli abitanti locali, né ci si avvicina (e forse neanche si desidera farlo) alla vera diversità culturale che si trova al di là delle immagini condivise sui social media. Terzani, nel libro, viene a conoscenza di molte curiosità proprio perché sceglie di usare treni e navi, dove è costretto a condividere il viaggio, ricevendo in regalo del tempo per parlare con le persone che incontra. Tutto questo in aereo non accade perché si attende in areoporti affollati, circondati da negozi che vendono di tutto, e spesso non si tende a condividere &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/terzani.jpg&quot; alt=&quot;Terzani in viaggio&quot; title=&quot;Terzani in viaggio&quot;&gt;&lt;/p&gt;
&lt;p&gt;I paesi ricchi dispongono di organizzazioni che promuovono la tutela del territorio come risorsa per il futuro, mentre nei paesi poveri i viaggiatori devono confrontarsi con gli effetti distruttivi che il turismo di massa ha prodotto. Chi crede di fare del bene portando denaro nei paesi poveri, in realtà finisce per arricchire solo una piccola parte della popolazione, accentuando una disuguaglianza che, prima dell’arrivo della modernità e del capitalismo totalitario, era meno evidente. Erano tutti più poveri e, allo stesso tempo, più ricchi: così li descrive Terzani. Molti dei paesi orientali presenti nel libro hanno una storia e una mentalità uniche, e prima del cambiamento moderno alla popolazione non interessavano sviluppo e progresso. La modernità è stata imposta, la popolazione indottrinata, e molti luoghi storici e sacri hanno finito per perdere il loro fascino. Presto ci si accorgerà del valore perduto di una natura intatta e incontaminata di cui molti paesi del terzo mondo disponevano gratuitamente.&lt;/p&gt;
</content:encoded></item><item><title>Lolita - Vladimir Nabokov</title><link>https://scotto.me/blog/2024-02-04-lolita-nabokov-ita/</link><guid isPermaLink="true">https://scotto.me/blog/2024-02-04-lolita-nabokov-ita/</guid><description>Il capolavoro di Nabokov.</description><pubDate>Sun, 04 Feb 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Alla domanda su cos’è che rende un libro un successo, Ken Follett &lt;a href=&quot;https://www.youtube.com/watch?v=1Q1NEmOZdgw&quot;&gt;ha risposto&lt;/a&gt; che il fattore chiave è la capacità dello scrittore di far condividere al lettore le emozioni che vivono i personaggi. Per questo motivo Lolita è da considerarsi uno dei romanzi più importanti del XX secolo. Perché farci immergere nella mente di un pedofilo, e farci provare emozioni come empatia, pena, rabbia, per un protagonista maledetto, è una delle fatiche più ardue che un scrittore possa compiere. E se ciò non fosse abbastanza, pensate a quanto coraggio possa servire per pubblicare un libro del genere.&lt;/p&gt;
&lt;p&gt;Se pensiamo per un attimo alle storie più macabre che conosciamo, è probabile che ci vengano in mente soggetti come tossicodipendenti, assassini, truffatori e traditori. E se il narratore è stato abile, siamo riusciti a instaurare una connessione emotiva con le vicende di questi personaggi. Nessuno però, prima di Lolita, aveva rotto il tabù della sessualità tra un uomo adulto e una ragazzina agli inizi dell’adolescenza. Non a caso il libro fu più volte rifiutato dagli editori americani, per poi essere pubblicato a Parigi da una casa editrice di romanzi erotici. Lolita venne respinto - causa possibili censure - allo stesso modo in cui vennero scartate le opere di Proust, Joyce, Hemingway, che una volta ripescate divennero dei capolavori pubblicati ancora oggi. Lolita aveva sollevato una questione morale per gli editori. Non era solo un libro osceno: spingeva la trasgressione ben oltre ciò che la società americana degli anni Cinquanta, conservatrice e puritana, era disposta a tollerare.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://upload.wikimedia.org/wikipedia/commons/thumb/c/c1/Lolita_%281962_film_poster%29.jpg/256px-Lolita_%281962_film_poster%29.jpg?20200320191304&quot; alt=&quot;Lolita&apos;s Movie Cover&quot; title=&quot;“Come sono riusciti a fare un film su Lolita?”, il poster del film.&quot;&gt;&lt;/p&gt;
&lt;p&gt;Il racconto è la confessione dei crimini commessi da Humbert Humbert, mentre si trova in una cella carceraria in attesa di giudizio per omicidio e pedofilia. Nabokov scelse di raccontare in prima persona per creare un resoconto dei fatti realistico, al punto che in alcuni momenti il narratore e lo scrittore paiono sovrapporsi. La scrittura è raffinata, artistica, nitida, e combacia con il profilo del protagonista professore universitario, risaltando le sue ossessioni e il suo spirito romantico -- a suo modo. Perché tra i sentimenti che appaiono nel libro, spicca soprattuto l’amore. Un amore perverso, frutto di un capriccio non esaudito in gioventù, sfociato col tempo in un desiderio morboso per le giovani ragazzine che rispettano certi standard - che Humbert chiama &lt;em&gt;ninfette&lt;/em&gt;. Quando incontra Dolores, la sua Lolita, rivede in lei i tratti dell’adolescente di cui si era invaghito anni prima. Lolita gli appare così perfetta da voler far di lei la sua ninfetta, era l&amp;#39;occasione che aspettava, un vero dono del destino.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“Devi capire che il viaggiatore incantato, posseduto da una ninfetta e a lei asservito, sta, per così dire, oltre la felicità. Nulla al mondo, infatti, dà tanta beatitudine quanto accarezzare una ninfetta.”
— &lt;strong&gt;Vladimir Nabokov&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Un amore folle, nocivo, e non corrisposto, rende Humbert cieco di fronte ai disagi patiti dalla ragazzina per i continui abusi, i ricatti e le menzogne da lui perpetrati. Un amore distruttivo nel quale tutte le persone coinvolte finiscono per esserne danneggiate.
All’inizio del romanzo, Humbert sembra quasi simpatico con la sua ironia forbita, ma quando la narrazione entra nel vivo, gradualmente la figura si sgretola e capiamo che i suoi non sono solamente dei capricci sentimentali; Humbert sarebbe disposto a tutto per avere Lolita tutta per se. Diventa quindi un personaggio snob che giudica chiunque incontri, cinico quando mente alla ragazzina in cambio di favori sessuali, e comprandole qualsiasi cosa desidera quando lei prova a ribellarsi al gioco perverso in cui lui l’ha condotta, abusando dell’innocenza di lei.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“Sapevo di essermi innamorato di Lolita per sempre; ma sapevo anche che lei non sarebbe stata per sempre Lolita” 
— &lt;strong&gt;Vladimir Nabokov&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Il libro non cade nella descrizione di scene erotiche; Nabokov non cercava lo scandalo per ottenere fama e vendere copie. L’anatomia della ragazzina è abbozzata con dei dettagli innocenti che il protagonista annota nella sua mente. È una tecnica che aveva già sperimentato in precedenza in altre sue opere, come &lt;em&gt;Una risata nel buio&lt;/em&gt;, dove una giovane e attraente ragazza porta alla rovina un adulto facoltoso ma sprovveduto. Non è la prima volta che Nabokov affronta una storia d’amore travagliata, con differenze d’età tra gli amanti. L’idea stessa di Lolita, ci racconta Nabokov, era nata molti anni prima e più volte tentò di abbozzare la storia e per poco non ne distrusse i manoscritti. 
Lolita, nella storia, diventa qualcosa in più dell’oggetto del desiderio. Come suggerisce Stefano Bartezzaghi in &lt;a href=&quot;https://www.raicultura.it/letteratura/articoli/2019/12/Lolita-storia-di-un-amore-senza-tempo-cf282257-8ee0-4144-b675-89a5986ff0f2.html&quot;&gt;un intervista&lt;/a&gt; su Rai Cultura, Nabokov fa si che Lolita giochi il ruolo della madeleine per Humbert Humbert, perché riesce a fargli riscoprire l’amore perduto in gioventù. Il concetto di memoria nel libro venne sicuramente influenzato dagli scritti di Proust, tanté che Nabokov tenne tenne &lt;a href=&quot;https://it.wikipedia.org/wiki/Lezioni_di_letteratura&quot;&gt;delle lezioni&lt;/a&gt; sullo scrittore francese quand&amp;#39;era professore di lettere in America.&lt;/p&gt;
&lt;p&gt;Il compito più difficile nel leggere Lolita è interpretarne il significato. Nabokov, nella postfazione, afferma che il libro non ha nessuna morale ma che l’unico scopo sia quello di provocare nel lettore ciò che chiama la “voluttà estetica”, ossia entrare in contatto con altri stati dell’essere dove l’arte è la norma. Anche se lo scrittore abbia ideato la trama senza appropriargli un significato, non implica che il testo sia privo di senso. Il protagonista vive in America nell’epoca del trionfo capitalista del dopoguerra, in cui l’ideologia dominante affermava che il verso e ultimo scopo della vita è quello di soddisfare i propri desideri. In Humbert riecheggia questo pensiero, tramite la figura di un uomo egocentrico e poco empatico. Forse possiamo trovare un senso in questo racconto degli impulsi fisiologici di un pervertito, quello di leggere i desideri nascosti della società perbene del tempo.
A questo proposito, nel documentario della BBC del 2009 &lt;a href=&quot;https://www.youtube.com/watch?v=JGnH64PU4Lk&amp;t=179s&quot;&gt;How Do You Solve A Problem Like Lolita?&lt;/a&gt;, Stephen Smith, ripercorrendo i luoghi in Nabokov aveva vissuto, parla di come lo scrittore, quando era ancora in Russia, componeva racconti e poesie d’amore. Lolita invece appartiene ad un Nabokov oramai maturo; l’amore diventa un sentimento corrotto e perverso, forse inconsapevolmente contaminato dai cambiamenti culturali avvenuti nel tempo.&lt;/p&gt;
</content:encoded></item><item><title>Lolita&apos;s incipit</title><link>https://scotto.me/blog/2023-12-20-lolita-a-perfect-incipit/</link><guid isPermaLink="true">https://scotto.me/blog/2023-12-20-lolita-a-perfect-incipit/</guid><description>Lolita - A perfect incipit</description><pubDate>Wed, 20 Dec 2023 00:00:00 GMT</pubDate><content:encoded>&lt;div class=&quot;video-container flex justify-center mb-10&quot;&gt;
  &lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/8171K40pJho?si=JXqMtij9d-Iiehqp&amp;amp;start=226&amp;amp;end=246&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; allowfullscreen&gt;&lt;/iframe&gt;
&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;“Lolita, light of my life, fire of my loins. My sin, my soul. Lo-lee-ta: the tip of the tongue taking a trip of three steps down the palate to tap, at three, on the teeth. Lo. Lee. Ta. She was Lo, plain Lo, in the morning, standing four feet ten in one sock. She was Lola in slacks. She was Dolly at school. She was Dolores on the dotted line. But in my arms she was always Lolita.” — &lt;strong&gt;Vladimir Nabokov&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
</content:encoded></item><item><title>We will need writers who can remember freedom</title><link>https://scotto.me/blog/2023-12-13-we-will-need-writers-who-can-remember-freedom---ursula-k-le-guin/</link><guid isPermaLink="true">https://scotto.me/blog/2023-12-13-we-will-need-writers-who-can-remember-freedom---ursula-k-le-guin/</guid><description>Ursula K. Le Guin receiving The National Book Foundation Medal</description><pubDate>Wed, 13 Dec 2023 00:00:00 GMT</pubDate><content:encoded>&lt;div class=&quot;video-container flex justify-center mb-10&quot;&gt;
  &lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/Et9Nf-rsALk?si=aoV79erEbxLYtAJA&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; allowfullscreen&gt;&lt;/iframe&gt;
&lt;/div&gt;



&lt;p&gt;I just wanted to share this speech by &lt;a href=&quot;https://en.wikipedia.org/wiki/Ursula_K._Le_Guin&quot;&gt;Ursula K. LeGuin&lt;/a&gt; (1929 - 2018). It expresses a point of view that inspires hope in literature as a way to imagine alternative worlds to the one we live in today. Art has the power of not having to submit to anyone&amp;#39;s will other than its creator. And literature will lose this advantage that sets it apart from the rest of entertainment if it&amp;#39;s used merely as a product to make money.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“Hard times are coming, when we’ll be wanting the voices of writers who can see alternatives to how we live now, can see through our fear-stricken society and its obsessive technologies to other ways of being, and even imagine real grounds for hope. We’ll need writers who can remember freedom — poets, visionaries — realists of a larger reality.”
— &lt;strong&gt;U. K. Le Guin&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Transcript available &lt;a href=&quot;https://www.ursulakleguin.com/nbf-medal&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
</content:encoded></item><item><title>Common Lisp data structures</title><link>https://scotto.me/blog/2023-12-12-common-lisp-data-structures/</link><guid isPermaLink="true">https://scotto.me/blog/2023-12-12-common-lisp-data-structures/</guid><description>Common Lisp data structures</description><pubDate>Tue, 12 Dec 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Quick reference for the main data structures in Common Lisp. The code has been tested using &lt;em&gt;SBCL&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Some good rules for Common Lisp that I found say:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Use the appropriate data structure for the situation.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Favor iteration over recursion. Recursion is good for recursive data structures.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;List&lt;/h2&gt;
&lt;p&gt;Lists are used when you need to store a &lt;em&gt;sequence&lt;/em&gt; of elements. It supports different data types. They are particularly useful when you need to perform operations that involve recursion or iteration. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Key points&lt;/strong&gt;: ordered, flexible size, efficient for traversal, slow for random access&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-lisp&quot;&gt;;; Declaration
cl-user&amp;gt; (defparameter *list* &amp;#39;(1 2 3 4))
*list*
cl-user&amp;gt; (list 1 2 3 4) ; alternative
(1 2 3 4)

;; Access
cl-user&amp;gt; (nth 3 *list*) ; not performant for long lists
4 (3 bits, #x4, #o4, #b100)
cl-user&amp;gt; (first *list*)
1 (1 bit, #x1, #o1, #b1)

;; Adding
cl-user&amp;gt; (push &amp;#39;0 *list*)
(0 1 2 3 4)

;; Deleting
cl-user&amp;gt; (setf *list* (remove 1 *list*))
(0 2 3 4)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Association list - alist&lt;/h2&gt;
&lt;p&gt;Association lists are lists, implemented using cons cells, which are used to store key-value pairs where the key is a symbol. They are slower than hash-tables for large amount of data.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Key points&lt;/strong&gt;: key-value pairs, simple structure, inefficient for large datasets&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-lisp&quot;&gt;;; Declaration
cl-user&amp;gt; (defparameter *alist* &amp;#39;((:a . 1) (:b . 2)))
*alist*

;; Access
cl-user&amp;gt; (assoc :a *alist*)
(A . 1)
cl-user&amp;gt; (cdr (assoc :a *alist*))
1

;; Adding
cl-user&amp;gt; (push &amp;#39;(:c . 3) *alist*)
((C . 3) (A . 1) (B . 2))

;; Deleting
cl-user&amp;gt; (setf *alist* (remove :c *alist* :key #&amp;#39;car))
((A . 1) (B . 2))
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Property list - plist&lt;/h2&gt;
&lt;p&gt;Property are used when you need to store key-value pairs and the keys are symbols. They are simpler than hash tables and association lists but can be slower for large amounts of data.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Key points&lt;/strong&gt;: key-value pairs, lightweight, inefficient for large datasets&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-lisp&quot;&gt;;; Declaration
cl-user&amp;gt; (defparameter *plist* &amp;#39;(:key1 value1 :key2 value2))
*plist*

;; Access
cl-user&amp;gt; (getf *plist* :key1)
value1

;; Adding
cl-user&amp;gt; (setf (getf *plist* :new-key) &amp;#39;new-value)
new-value

;; Deleting
cl-user&amp;gt; (remf *plist* :key1)
t
cl-user&amp;gt; *plist*
(:new-key new-value :key2 value2)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Hash table&lt;/h2&gt;
&lt;p&gt;Hash tables store key-value pairs and provide efficient lookup and storage. They are highly efficient for large datasets.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Key points&lt;/strong&gt;: key-value pairs, fast lookups, mutable&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-lisp&quot;&gt;;; Declaration
cl-user&amp;gt; (defparameter *hash-table* (make-hash-table))
*hash-table*

;; Adding
cl-user&amp;gt; (setf (gethash &amp;#39;key1 *hash-table*) &amp;#39;value1)
value1

;; Access
cl-user&amp;gt; (gethash &amp;#39;key1 *hash-table*)
value1

;; Deleting
cl-user&amp;gt; (remhash &amp;#39;key1 *hash-table*)
t
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Array&lt;/h2&gt;
&lt;p&gt;Arrays are multidimensional data structures that hold elements accessible by indices. Arrays are faster than lists for random access, but slower for operations that involve adding or removing elements. Arrays have a fixed size upon creation, but they can be resized using &lt;code&gt;adjust-array&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Key points&lt;/strong&gt;: multidimensional, fixed size, efficient access by index&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-lisp&quot;&gt;;; Declaration
cl-user&amp;gt; (defparameter *array* (make-array 4 :initial-contents &amp;#39;(1 2 3 4)))
*array*

;; Access
cl-user&amp;gt; (aref *array* 2)
3

;; Modifying
cl-user&amp;gt; (setf (aref *array* 1) 5)
5

;; Extending/Shrinking
cl-user&amp;gt; (setf *array* (adjust-array *array* 6 :initial-element 0))
#(1 5 3 4 0 0)

;; Deleting
;; To delete elements, consider creating a new array without the unwanted elements.
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Vector&lt;/h2&gt;
&lt;p&gt;A vector is a one-dimensional array. Vectors are similar to arrays but can dynamically grow and shrink using functions like &lt;code&gt;vector-push&lt;/code&gt; and &lt;code&gt;vector-pop&lt;/code&gt;. Vectors are particularly useful when you need a sequence that can change size dynamically.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Key points&lt;/strong&gt;: one-dimensional, dynamic size, efficient access by index&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-lisp&quot;&gt;;; Declaration
cl-user&amp;gt; (defparameter *vector* #(1 2 3 4))
*vector*

;; Access
cl-user&amp;gt; (elt *vector* 0)
1

;; Modifying
cl-user&amp;gt; (setf (elt *vector* 3) 5)
5

;; Adding elements
cl-user&amp;gt; (vector-push-extend 6 *vector*)
4
cl-user&amp;gt; *vector*
#(1 2 3 5 6)

;; Removing elements
cl-user&amp;gt; (vector-pop *vector*)
6
cl-user&amp;gt; *vector*
#(1 2 3 5)

;; Converting to a list
cl-user&amp;gt; (coerce *vector* &amp;#39;list)
(1 2 3 5)

;; Shrinking/Extending
cl-user&amp;gt; (setf (fill-pointer *vector*) 2)
2
cl-user&amp;gt; *vector*
#(1 2)

;; Push extending
cl-user&amp;gt; (vector-push-extend 7 *vector*)
2
cl-user&amp;gt; *vector*
#(1 2 7)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Structure&lt;/h2&gt;
&lt;p&gt;Structures are user-defined data structures created using &lt;code&gt;defstruct&lt;/code&gt;, allowing the grouping of different data types together.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Key points&lt;/strong&gt;: user-defined, structured, efficient access&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-lisp&quot;&gt;;; Declaration
cl-user&amp;gt; (defstruct person name age)
person

;; Creating
cl-user&amp;gt; (make-person :name &amp;#39;Alice :age 30)
#S(PERSON :NAME ALICE :AGE 30)

cl-user&amp;gt; (defvar *person* (make-person :name &amp;#39;Bob :age 25))
*PERSON*

;; Access
cl-user&amp;gt; (person-name *person*)
BOB

;; Modifying
cl-user&amp;gt; (setf (person-age *person*) 40)
40

;; Deleting
cl-user&amp;gt; (makunbound &amp;#39;*person*)
*PERSON*
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/foxsae/The-One-True-Lisp-Style-Guide&quot;&gt;https://github.com/foxsae/The-One-True-Lisp-Style-Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://lispcookbook.github.io/cl-cookbook/data-structures.html#sequences&quot;&gt;https://lispcookbook.github.io/cl-cookbook/data-structures.html#sequences&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>How to add a Clojure REPL to a web page</title><link>https://scotto.me/blog/2023-03-24-how-to-add-clojure-repl-to-webpage/</link><guid isPermaLink="true">https://scotto.me/blog/2023-03-24-how-to-add-clojure-repl-to-webpage/</guid><description>How I created TryClojure.org</description><pubDate>Fri, 24 Mar 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;One of the advantages of working with Clojure is that it can be used on top of the JVM as well as in the browser. This is possible thanks to the Clojurescript compiler, which takes your &lt;code&gt;.cljs&lt;/code&gt; files and turns them into optimized Javascript with the help of the &lt;a href=&quot;https://github.com/google/closure-compiler&quot;&gt;Google Closure compiler&lt;/a&gt;, ready to be embedded into a webpage. Since Clojurescript translate Clojure code to Javascript, in theory, it should be possible to run Clojurescript directly in the browser, since Javascript interpreter is exposed to the user.&lt;/p&gt;
&lt;p&gt;I got inspired after experimenting with a cool project to present the Haskell language called &lt;a href=&quot;https://tryhaskell.org/&quot;&gt;Try Haskell&lt;/a&gt;, which allows to run Haskell in the browser. It made me thinking about how I could replicate it using Clojure, so that users can type in a REPL on a web page. I started searching for a way to embed a working Clojure REPL in a small web app and this is what I found. There are various way to achieve this. The old method was using the  &lt;a href=&quot;https://code.thheller.com/blog/shadow-cljs/2017/10/14/bootstrap-support.html&quot;&gt;self-hosted cljs compiler&lt;/a&gt;, but there&amp;#39;s a simpler approach. Thanks to SCI, the &lt;a href=&quot;https://github.com/babashka/sci&quot;&gt;Small Clojure Interpreter&lt;/a&gt; is now possible to write and execute Clojurescript code on top of Javascript; this means it can be executed in the browser.&lt;/p&gt;
&lt;p&gt;The simplest way to try it is to add the library via CDN. Just include &lt;a href=&quot;https://github.com/babashka/scittle&quot;&gt;Scittle&lt;/a&gt; library, same as &lt;em&gt;SCI&lt;/em&gt; but loaded with a script tag into a webpage. It doesn&amp;#39;t need any additional library or Clojurescript.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;lt;script
  type=&amp;quot;text/javascript&amp;quot;
  src=&amp;quot;https://cdn.jsdelivr.net/npm/scittle@0.5.14/dist/scittle.js&amp;quot;
&amp;gt;&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then you can write your Clojure code into a script tag, or load a clojurescript file.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;lt;script type=&amp;quot;application/x-scittle&amp;quot;&amp;gt;
  (println &amp;quot;Hello Wolrd&amp;quot;)
&amp;lt;/script&amp;gt;
&amp;lt;!-- or --&amp;gt;
&amp;lt;script src=&amp;quot;app.cljs&amp;quot; type=&amp;quot;application/x-scittle&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For the rest of the tutorial, I&amp;#39;ll be using &lt;em&gt;SCI&lt;/em&gt; so the library get&amp;#39;s loaded via Clojurescript. Refer to &lt;em&gt;SCI&lt;/em&gt; docs to learn how to do it.&lt;/p&gt;
&lt;p&gt;You can &lt;em&gt;try&lt;/em&gt; the Clojure REPL with a tutorial at &lt;a href=&quot;https://tryclojure.org/&quot;&gt;TryClojure.org&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;SCI&lt;/h2&gt;
&lt;p&gt;The core of the app is the integration of SCI. It essentially provide a way to safely &lt;strong&gt;evaluate&lt;/strong&gt; the strings that the user input in the REPL. I said &amp;quot;safe&amp;quot; since it creates a sandboxed environment where we can run our code. The Clojure interpreter runs directly in the browser&amp;#39;s JavaScript engine, offering the same functionalities of the developer console.&lt;/p&gt;
&lt;p&gt;We can create a SCI &lt;strong&gt;context&lt;/strong&gt; by using the function &lt;code&gt;sci/init&lt;/code&gt; with some initialization options.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-clojure&quot;&gt;(ns app.sci
  (:require [sci.core :as sci]))
   
(defonce context (atom (sci/init init-opts)))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I&amp;#39;m, using an &lt;code&gt;atom&lt;/code&gt; since it lets me add options during execution by updating the context, as shown in the following function.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-clojure&quot;&gt;(defn extend-ctx
  &amp;quot;Extend default sci context merging `opts`.&amp;quot;
  [opts]
  (reset! context (sci/merge-opts @context opts)))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I set a custom print function, by changing the default binding of &lt;code&gt;print-fn&lt;/code&gt; for sci.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-clojure&quot;&gt;(defn set-print-fn
  &amp;quot;Setup a custom `print-fn` for sci.&amp;quot;
  [f]
  (sci/alter-var-root sci/print-fn (constantly f)))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I created a wrapper around &lt;code&gt;eval-string*&lt;/code&gt; for better error management. The &lt;code&gt;error/error-handler&lt;/code&gt; function prints errors to console along with the stacktrace. This is the core function of the app: SCI &lt;strong&gt;evaluates a string&lt;/strong&gt; and returns the output of the execution.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-clojure&quot;&gt;(defn eval-string
  &amp;quot;Evaluate `source` using the sci interpreter and return its output.
   If an error occurs during evaluation, raise an exception.&amp;quot;
  [source]
  (try (sci/eval-string* @context source)
       (catch :default e
         (error/error-handler e (:src context))
         (let [sci-error? (isa? (:type (ex-data e)) :sci/error)]
           (throw (if sci-error?
                    (or (ex-cause e) e)
                    e))))))
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;REPL&lt;/h2&gt;
&lt;p&gt;I created a custom function &lt;code&gt;write-repl!&lt;/code&gt;, to print the evaluation output. It appends the value to a vector that stores the output history.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-clojure&quot;&gt;(ns app.repl.core
  (:require [reagent.core :as r]
            [app.sci :as sci]))
  
(defonce repl-history (r/atom []))
  
(defn- write-repl!
  &amp;quot;Append `s` to the REPL history.
  Optional keyword `k` to use as a type.&amp;quot;
  ([s]
   (write-repl! s :output))
  ([s k]
   (swap! repl-history conj {:type k :value s})))

(sci/set-print-fn (fn [s] (write-repl! s)))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I extended the context by adding a few functions to the &lt;code&gt;user&lt;/code&gt; default namespace. This functions can be called in the REPL, and they&amp;#39;re able to interact with the webpage. For example changing some environment variables like prompt symbol color, the current user name, or interacting with the tutorial steps.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-clojure&quot;&gt;(sci/extend-ctx
 {:namespaces {&amp;#39;user {&amp;#39;start start-tutorial
                      &amp;#39;clear clear-repl
                      &amp;#39;restart restart-tutorial
                      &amp;#39;my-name set-name
                      &amp;#39;next-step inc-step!
                      &amp;#39;prev-step dec-step!
                      &amp;#39;set-step (when DEBUG set-step)
                      &amp;#39;set-prompt set-prompt
                      &amp;#39;more (fn [] true)
                      &amp;#39;help print-help}}})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For example the &lt;code&gt;clear-repl&lt;/code&gt; function resets the history to an empty vector, returning &lt;code&gt;nil&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-clojure&quot;&gt;(defn clear-repl []
  (reset! repl-history [])
  nil)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;All the Clojurescript code is evaluated using &lt;code&gt;eval-string&lt;/code&gt;. The typical way to do this is when the user press &amp;quot;Enter&amp;quot; in the REPL HTML input element, but we can also use it to import an entire namespace.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-clojure&quot;&gt;;; Import `repl` namespace helper functions 
(sci/eval-string &amp;quot;(require &amp;#39;[clojure.repl :refer :all])&amp;quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Colophon&lt;/h2&gt;
&lt;p&gt;I released &lt;a href=&quot;https://tryclojure.org/&quot;&gt;TryClojure&lt;/a&gt; more than a year ago but I didn&amp;#39;t write any content on how I made it. It&amp;#39;s a frontend-only app served by Netlify, with no backend since all the code runs in the browser. I&amp;#39;ve used a few libraries to build the app. The build process is managed with &lt;a href=&quot;https://github.com/thheller/shadow-cljs&quot;&gt;shadow-cljs&lt;/a&gt;, I&amp;#39;ve used &lt;a href=&quot;https://tailwindcss.com&quot;&gt;Tailwind&lt;/a&gt; for styles, and &lt;a href=&quot;https://reagent-project.github.io/&quot;&gt;Reagent&lt;/a&gt; for creating UI components.&lt;/p&gt;
</content:encoded></item><item><title>The missing ClojureScript re-frame Quick Start Tutorial</title><link>https://scotto.me/blog/2023-03-18-re-frame-quickstart/</link><guid isPermaLink="true">https://scotto.me/blog/2023-03-18-re-frame-quickstart/</guid><description>A quick guide to use Clojurescript re-frame</description><pubDate>Sat, 18 Mar 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;strong&gt;Re-frame lacks a quick start guide, so this is my attempt to create one, including a TodoMVC tutorial.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;When I discovered &lt;strong&gt;Clojurescript&lt;/strong&gt; and started to play around with it, the first library that I used was &lt;a href=&quot;https://reagent-project.github.io/&quot;&gt;Reagent&lt;/a&gt;.  Essentially, it&amp;#39;s a wrapper around React, allowing us to write components as Clojurescript functions and instead of JSX, using vectors and keywords[^helix] for the syntax. It has been pretty easy to start with, since I already known how React works and I was comfortable with the Clojure syntax. Like its parent library, it&amp;#39;s basically offers a way to define reusable component, with internal state and props received from the parent components.&lt;/p&gt;
&lt;p&gt;Since React and Reagent are UI libraries, the application state management is left to the programmer, and that&amp;#39;s where something like &lt;a href=&quot;http://day8.github.io/re-frame/re-frame/&quot;&gt;re-frame&lt;/a&gt; comes handy. It implements a &lt;strong&gt;model, view, update&lt;/strong&gt; paradigm using Reagent under the hood, and help separating the state management (model, update) from the UI components (view).  The library is similar to Redux having a &lt;strong&gt;single central store&lt;/strong&gt; for state and &lt;strong&gt;unidirectional data flow&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;The problem I found with re-frame, although it&amp;#39;s actually a simple library, is that the &lt;strong&gt;documentation doesn&amp;#39;t provide a quick start page&lt;/strong&gt; like Reagent. Instead, it only offers a long, detailed explanation (which is still a recommended reading for fully comprehend how to architecture large apps). If you&amp;#39;re already familiar with similar paradigms, a quick guide would be enough to get started with it.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-clojure&quot;&gt;;; Importing the library
(:require [re-frame.core :as rf])
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;App-db&lt;/h2&gt;
&lt;p&gt;The entire &lt;strong&gt;application state&lt;/strong&gt; is saved inside a Reagent version of a single Clojure &lt;a href=&quot;https://clojure.org/reference/atoms&quot;&gt;atom&lt;/a&gt; called &lt;code&gt;app-db&lt;/code&gt;. It&amp;#39;s just a &lt;code&gt;map&lt;/code&gt;, initially empty, similar to the following one.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-clojure&quot;&gt;(def app-db ; will be called db from now on 
  {})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Re-frame stores the app state in a single source of truth, which, like all Clojure data structures, is immutable and updated using pure functions. This pattern makes state management flow simple to understand, ensures changes in state are &lt;strong&gt;predictable&lt;/strong&gt;, and makes &lt;em&gt;debugging&lt;/em&gt; easier.&lt;/p&gt;
&lt;p&gt;This is a great explanation on how &lt;code&gt;app-db&lt;/code&gt; works, directly from the re-frame README: &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;at any one time, the value in app-db is the result of performing a reduce over the entire collection of events dispatched in the app up until that time. The combining function for this reduce is the set of registered event handlers.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Re-frame progress in time applying the event handler functions to the previous state of the app. This means that the collection of events is &lt;strong&gt;replay-able&lt;/strong&gt; from the beginning of time, step by step; a dream for debugging an app. To achieve this, it&amp;#39;s important that all the event handlers are pure functions (without side-effects).&lt;/p&gt;
&lt;h2&gt;Dispatch&lt;/h2&gt;
&lt;p&gt;To modify the user name value inside the &lt;em&gt;app state&lt;/em&gt;, one needs to &lt;strong&gt;dispatch&lt;/strong&gt; a new event. So, simply call the dispatch function with a vector containing the event name &lt;code&gt;:user/update-name&lt;/code&gt; and the new value for the user name.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-clojure&quot;&gt;(rf/dispatch [:user/update-name new-user-name])
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The dispatch function sends the event in the re-frame event-loop for async processing. It can be used from anywhere in the application, so in this case it would most likely happen in a reaction to a click event on a &amp;quot;Save&amp;quot; button.&lt;/p&gt;
&lt;h2&gt;Events&lt;/h2&gt;
&lt;p&gt;Now, it&amp;#39;s necessary to define a new re-frame &lt;strong&gt;event handler&lt;/strong&gt; using &lt;code&gt;reg-event-db&lt;/code&gt; which updates the user name inside the app db. The event handler function receives the current state (db) and the triggering event as arguments. The event is a vector containing the event name (as a keyword) and the parameters.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-clojure&quot;&gt;(rf/reg-event-db
  :user/update-name
  (fn [db [event-kw new-user-name]]
    (assoc-in db [:user :name] new-user-name)))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now our &lt;code&gt;app-db&lt;/code&gt; will look like the following:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-clojure&quot;&gt;{:user {:name &amp;quot;admin&amp;quot;}}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;An event handler should be a &lt;strong&gt;pure function&lt;/strong&gt; which returns a new version of the db, only based on its &lt;em&gt;input parameters&lt;/em&gt; and the &lt;em&gt;previous state&lt;/em&gt; of the app. Again, it should be free from &lt;em&gt;side-effects&lt;/em&gt;. A function is considered &lt;em&gt;pure&lt;/em&gt; if a given input maps to the same output all the time.&lt;/p&gt;
&lt;h2&gt;Subscriptions&lt;/h2&gt;
&lt;p&gt;To show the user name inside a component, create a re-frame subscription called &lt;code&gt;:user/name&lt;/code&gt; that extract the value of &lt;code&gt;:name&lt;/code&gt; relative to the current &lt;code&gt;:user&lt;/code&gt; in the state. &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-clojure&quot;&gt;(rf/reg-sub
  :user/name
  (fn [db query-v]
    (get-in db [:user :name]])))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The handler function receives the app-db and &lt;code&gt;query-v&lt;/code&gt; as parameters. &lt;code&gt;query-v&lt;/code&gt; is the vector supplied to the subscription. In this case above, it&amp;#39;s quite simple, and it&amp;#39;s not using it. It&amp;#39;s just doing an &lt;strong&gt;extraction&lt;/strong&gt; of a value from the state.&lt;/p&gt;
&lt;p&gt;The new subscription can be connected to a Reagent component using &lt;code&gt;subscribe&lt;/code&gt;, which accepts a vector where the first element is the name of the subscription, and the rest other possible parameters.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-clojure&quot;&gt;(defn user-name []
  ;; Returns an atom that needs to be dereferenced
  (let [username @(rf/subscribe [:user/name])]
    [:h1 username]))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now every time the value of &lt;code&gt;[:user :name]&lt;/code&gt; changes in the db, the related subscription function will re-run, and the new value will be &lt;strong&gt;propagated&lt;/strong&gt; to the views depending on them, &lt;strong&gt;updating&lt;/strong&gt; the Reagent component. We don&amp;#39;t have to care about state management if the component mount/refresh because it&amp;#39;s &lt;strong&gt;all delegated to re-frame&lt;/strong&gt;. No more large props cascade, no context/provider pattern. A single map contains the entire app state that refreshes the view when gets updated.&lt;/p&gt;
&lt;p&gt;Re-frame is implementing a pattern called &lt;strong&gt;unidirectional data flow&lt;/strong&gt;,  where the application state can only be modified with dispatched actions. These actions trigger event handler functions that update the state. Than, the changes propagate consistently throughout the application. There is only one way to update the view. As a result, our view is a deterministic function of the data, making the data flow more predictable.&lt;/p&gt;
&lt;p&gt;Subscriptions are not only used as extractors but they can also &lt;strong&gt;compute derived data&lt;/strong&gt; from other subscriptions. For example, the user name can be returned in &lt;em&gt;uppercase&lt;/em&gt; or &lt;em&gt;lowercase&lt;/em&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-clojure&quot;&gt;(rf/reg-sub
  :user/name-uppercase
  ;; signals function
  (fn [query-v]
    (rf/subscribe [:user/name]))
  ;; computation function
  (fn [username query-v]
    (string/upper-case username)))
    
(rf/reg-sub
  :user/name-lowercase
  (fn [query-v]
    (rf/subscribe [:user/name]))
  (fn [username query-v]
    (string/lower-case username)))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this case our subscription recevies two functions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A &lt;code&gt;signals&lt;/code&gt; function that returns one or more subscriptions. It can return either a single signal, a vector of signals, or a map where the values are the signals.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A &lt;code&gt;computation&lt;/code&gt; function that takes the input values provided by the &lt;code&gt;signals&lt;/code&gt; function, supplied as the first argument, and produces a new derived value, which will be the output of the node.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Another subscription that receives a parameter can be created easily.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-clojure&quot;&gt;(rf/reg-sub
  :user/name-prefix-case
  (fn [[_ prefix str-case]]
    (case str-case     ; don&amp;#39;t get confused
      :upper (rf/subscribe [:user/name-uppercase])
      :lower (rf/subscribe [:user/name-lowercase])
      (rf/subscribe [:user/name])))
  (fn [username [_ prefix str-case]]
    (str prefix &amp;quot;: &amp;quot; username)))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And it would be invoked as:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-clojure&quot;&gt;(rf/subscribe [:user/name-prefix-case &amp;quot;Username&amp;quot; :lower])
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Co-Effects&lt;/h2&gt;
&lt;p&gt;In case something else is required, other than update the &lt;em&gt;state&lt;/em&gt;, such as storing data asynchronously, the event handler need to cause side effects. To do this the previous handler defined with &lt;code&gt;reg-event-db&lt;/code&gt; must be replaced with &lt;code&gt;reg-event-fx&lt;/code&gt;. When to use one or the other? &lt;code&gt;reg-event-db&lt;/code&gt; when only updating the state, &lt;code&gt;reg-event-fx&lt;/code&gt; when side effects are needed (mostly defined with &lt;code&gt;:fx&lt;/code&gt;); The latter can be seen as a wrapper of the former. Why using a separate function for side-effects? Because our event handler functions have to be pure, to keep the ability to have the state update history as a sequence of changes over time.&lt;/p&gt;
&lt;p&gt;In the following code, we replaced the event handler to return a map with &lt;code&gt;:db&lt;/code&gt; as the new app state and &lt;code&gt;:fx&lt;/code&gt; a vector telling re-frame to dispatch asynchronously another event &lt;code&gt;:user/save-asynch&lt;/code&gt; that would save the new user name somewhere like in the database with a server call.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-clojure&quot;&gt;(rf/reg-event-fx
  :user/update-name
  (fn [{db :db} [_ new-user-name_]] ; 1st arg is coeffects, which contains the db
    {:db (assoc-in db [:user :name] new-user-name)
     :fx [[:dispatch [:user/save-asynch]]]}))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;:dispatch&lt;/code&gt; is a built-in &lt;strong&gt;effect&lt;/strong&gt; used to dispatch a single event. One can even create new custom effects, that are performing side-effects, after the app state ad been updated. This one will show an annoying alert to the user.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-clojure&quot;&gt;(rf/reg-fx
  :alert
  (fn [s] (js/alert s))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To use it, modify the map returned before:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-clojure&quot;&gt;{:db (assoc-in db [:user :name] new-user-name)
 :fx [[:dispatch [:user/save-asynch]]
      (when (&amp;gt; (count new-user-name) 10)
        [:alert &amp;quot;What a long name!&amp;quot;])]
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;TodoMVC tutorial&lt;/h2&gt;
&lt;p&gt;For the one of you, like me, who prefer learning with a &lt;strong&gt;practical examples&lt;/strong&gt;, here&amp;#39;s a working example of TodoMVC created with &lt;em&gt;Reagent&lt;/em&gt; and &lt;em&gt;re-frame&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;First I initialized the &lt;code&gt;app-db&lt;/code&gt; state with empty values using a new event handler called &lt;code&gt;:initialize-db&lt;/code&gt;, which returns a new &lt;code&gt;:db&lt;/code&gt; set the initial &lt;em&gt;state&lt;/em&gt; of the app.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-clojure&quot;&gt;(rf/reg-event-fx
 :initialize-db
 (fn [_ _]
   {:db {:todo {:items {} :filter :all}}}))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the app initialization, I dispatched the event &lt;strong&gt;synchronously&lt;/strong&gt; to set the initial state, blocking the event loop. This call must run only once during app loading. &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-clojure&quot;&gt;(rf/dispatch-sync [:initialize-db])
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I access both the items and the filter with two subscriptions that simply extract the values.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-clojure&quot;&gt;(rf/reg-sub
 :todo/items
 (fn [db _]
   (get-in db [:todo :items])))

(rf/reg-sub
 :todo/filter
 (fn [db _]
   (get-in db [:todo :filter])))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;An &lt;code&gt;item&lt;/code&gt; is a map composed as &lt;code&gt;{:id uuid :content text :active true}&lt;/code&gt;, while the &lt;code&gt;filter&lt;/code&gt; is a keyword that accepts &lt;code&gt;[:active :completed :all]&lt;/code&gt; as value. &lt;/p&gt;
&lt;p&gt;When the user presses &lt;em&gt;Enter&lt;/em&gt; on the todo input, the Reagent component adds a item to the collection using the following event handler. It accepts a non-empty string as a parameter.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-clojure&quot;&gt;(rf/reg-event-db
 :todo/add-item
 (fn [db [_ text]]
   (let [id (js/crypto.randomUUID)]
     (if (not (string/blank? text))
       (assoc-in db [:todo :items id] 
                 {:id id :content text :active true})
       db))))
       
;; Usage 
;; (rf/dispatch [:todo/add-item &amp;quot;write a re-frame tutorial&amp;quot;])
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I defined other simple actions for todo items.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-clojure&quot;&gt;(rf/reg-event-db
 :todo/remove-item
 (fn [db [_ id]]
   (update-in db [:todo :items] dissoc id)))

(rf/reg-event-db
 :todo/toggle-item
 (fn [db [_ id]]
   (update-in db [:todo :items id :active] not)))

(rf/reg-event-db
  :todo/set-item-content
  (fn [db [_ id text]]
    (assoc-in db [:todo :items id :content] text)))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I defined a similar action for setting the filter content (without performing a value check).&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-clojure&quot;&gt;(rf/reg-event-db
 :todo/set-filter
 (fn [db [_ filter-value]]
   (assoc-in db [:todo :filter] filter-value)))
   
;; Usage 
;; (rf/dispatch [:todo/set-filter :completed])
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;At this point, I&amp;#39;m able to add/remove/toggle items, update the content, and set a new filter. The next step is defining a new subscription that returns a filtered list of items. When the user clicks one of the filters in the UI, the list of items will be automatically filtered.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-clojure&quot;&gt;(rf/reg-sub
 :todo/visible-items
 :&amp;lt;- [:todo/items] ; syntactic sugar for the signal function
 :&amp;lt;- [:todo/filter] 
 (fn [[items todo-filter] _]
   (when (and (map? items) (keyword? todo-filter))
    (let [filter-fn (case todo-filter
                      :active    :active
                      :completed (complement :active)
                      :all       identity)]
      (filter filter-fn (vals items))))))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Another computed subscription is the count of active items left.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-clojure&quot;&gt;(rf/reg-sub
 :todo/active-items-count
 :&amp;lt;- [:todo/items]
 (fn [items _]
   (-&amp;gt; (filter :active (vals items))
       (count))))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What&amp;#39;s left to complete the TodoMVC features are two actions: clearing the completed items and toggling all of them. We need two new event handlers to work on the list of items, either removing the ones that are completed or changing the state of all of them.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-clojure&quot;&gt;(rf/reg-event-db
 :todo/clear-completed
 (fn [db _]
   (let [items         (get-in db [:todo :items])
         ;; Extract active items ids and remove them from the items map
         cleaned-items (-&amp;gt;&amp;gt; (vals items)
                            (filter (complement :active))
                            (map :id)
                            (reduce dissoc items))]
     (assoc-in db [:todo :items] cleaned-items))))

(rf/reg-event-db
  :todo/toggle-all
  (fn [db _]
    (let [items         (get-in db [:todo :items])
          ;; Is there any active item?
          active        (not-every? (complement :active) (vals items))
          ;; Set toggles as completed or not, updating the items object
          updated-items (reduce (fn [acc id]
                                  (assoc-in acc [id :active] (not active)))
                                items
                                (keys items))]
      (assoc-in db [:todo :items] updated-items))))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can explore the entire source code in &lt;code&gt;app.cljs&lt;/code&gt; after opening the sandbox.&lt;/p&gt;
&lt;iframe
  src=&quot;https://codesandbox.io/embed/reagent-re-frame-todomvc-z5d3cw?fontsize=14&amp;hidenavigation=1&amp;theme=dark&amp;view=preview&quot;
  loading=&quot;lazy&quot;
  style=&quot;width:100%; height:500px; border:0; border-radius: 4px; overflow:hidden;&quot;
  title=&quot;reagent+re-frame TodoMVC&quot;
  allow=&quot;accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking&quot;
  sandbox=&quot;allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts&quot;
&gt;&lt;/iframe&gt;

&lt;h2&gt;Extra - Debugging re-frame&lt;/h2&gt;
&lt;p&gt;As React provide it&amp;#39;s own Developer Tools with a Chrome extension, re-frame offers some integrated dashboards as libraries like &lt;a href=&quot;https://github.com/day8/re-frame-10x&quot;&gt;re-frame-10x&lt;/a&gt; or &lt;a href=&quot;https://github.com/flexsurfer/re-frisk&quot;&gt;re-frisk&lt;/a&gt; that are capable to provide a UI to explore the application state, show the events history and even navigate back in time reversing the app state to previous versions. Not bad!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/re-frame-10x.png&quot; alt=&quot;re-frame-10x&quot; title=&quot;re-frame-10x dashboard&quot;&gt;&lt;/p&gt;
&lt;p&gt;[^helix]: An alternative library which supports the modern way to write React functional components is called &lt;a href=&quot;https://github.com/lilactown/helix&quot;&gt;Helix&lt;/a&gt;.&lt;/p&gt;
</content:encoded></item></channel></rss>