<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Stefano Fago</title>
    <description>The latest articles on DEV Community by Stefano Fago (@stefanofago73).</description>
    <link>https://dev.to/stefanofago73</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F28134%2F25a0fef6-70e2-421f-9b07-9f581b14c24f.jpeg</url>
      <title>DEV Community: Stefano Fago</title>
      <link>https://dev.to/stefanofago73</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/stefanofago73"/>
    <language>en</language>
    <item>
      <title>Clean Design, Strong Client: The way of the Elasticsearch's Java SDK</title>
      <dc:creator>Stefano Fago</dc:creator>
      <pubDate>Sun, 21 Sep 2025 19:08:06 +0000</pubDate>
      <link>https://dev.to/stefanofago73/clean-design-strong-client-the-way-of-the-elasticsearchs-java-sdk-14nn</link>
      <guid>https://dev.to/stefanofago73/clean-design-strong-client-the-way-of-the-elasticsearchs-java-sdk-14nn</guid>
      <description>&lt;p&gt;Java has a vast ecosystem of APIs, not all of which are effective or easy to learn. Developing a good API is not trivial: misdesigning key elements, defining simple abstractions, and threading models are among the themes that must be addressed. The official Elasticsearch Java SDK is a project with a design effort that has been made to address these elements.&lt;/p&gt;

&lt;p&gt;Recently, this project surprised me, and I tried to examine the design ideas that make it interesting and effective, while also having some inevitable trade-offs to be aware of.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code generation and the single source of truth
&lt;/h2&gt;

&lt;p&gt;The Elastic Java SDK is not totally handwritten: it is generated from a canonical &lt;a href="https://github.com/elastic/elasticsearch-specification" rel="noopener noreferrer"&gt;API specification&lt;/a&gt;, developed in Typescript, but there are also handcrafted artifacts. The client generation pipeline produces the Java model classes, builders, serializers, and the top-level namespace methods from this specification. This generated approach explains the consistency of naming, shape, and coverage across hundreds of endpoints and multiple language clients. The handcrafted (by Elastic engineers) parts are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Transport integration with the Low Level REST Client (LLRC)&lt;/li&gt;
&lt;li&gt;Core infrastructure: authentication, TLS, retries, test harnesses, Continuous Integration, JSON mapper setup.&lt;/li&gt;
&lt;li&gt;API ergonomics: builder patterns, nullability conventions, naming.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/elastic/elasticsearch-java/tree/main/docs/design" rel="noopener noreferrer"&gt;ADR-driven decisions&lt;/a&gt;: Handcrafted parts are backed by &lt;a href="https://adr.github.io/" rel="noopener noreferrer"&gt;Architecture Decision Records&lt;/a&gt;, documenting why certain design choices were made.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Builder Pattern Done (Mostly) Right
&lt;/h2&gt;

&lt;p&gt;The Elasticsearch SDK leans heavily on the Builder Pattern: it's expressed in a base &lt;code&gt;ObjectBuilder&amp;lt;T&amp;gt;&lt;/code&gt; interface with a single &lt;code&gt;build()&lt;/code&gt; method. You're building search queries, index mappings, bulk operations, etc. Without builders, it'd be chaos.&lt;/p&gt;

&lt;p&gt;The SDK provides builder-lambda overloads (&lt;em&gt;e.g.&lt;/em&gt;, &lt;code&gt;() -&amp;gt; ObjectBuilder&amp;lt;T&amp;gt;&lt;/code&gt;) so nested objects can be constructed inline with type-safe closures; these overloads are visible in the public Javadocs as function-typed builder setters. Internally, the generated builders inherit from &lt;code&gt;ObjectBuilderBase&lt;/code&gt;, which enforces single-use via a &lt;a href="https://artifacts.elastic.co/javadoc/co/elastic/clients/elasticsearch-java/8.2.0/co/elastic/clients/util/ObjectBuilderBase.html#_checkSingleUse()" rel="noopener noreferrer"&gt;_checkSingleUse()&lt;/a&gt; when a call to the &lt;code&gt;build()&lt;/code&gt; method is needed.&lt;/p&gt;

&lt;p&gt;Once you call &lt;code&gt;build()&lt;/code&gt;, you're done. Reusing the builder is considered unsafe because internal structures, especially collections, may be shared between the builder and the built object. Mutating one could silently corrupt the other. So they close the gate after construction with a clean contract: configure it once, build, and forget. Every request and response class follows this pattern.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;SearchRequest&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SearchRequest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;index&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"products"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;q&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;match&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;field&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"laptop"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At first glance, this resembles a lambda-heavy mess. But what it's doing is chaining a set of typed, nested DSL constructs. The &lt;code&gt;of(...)&lt;/code&gt; is a &lt;code&gt;static&lt;/code&gt; shortcut that instantiates the builder, applies a configuration function, and finalizes the build. You're writing declarative Java code that directly mirrors the Elasticsearch query DSL.&lt;/p&gt;

&lt;h2&gt;
  
  
  DSL-Style Lambdas That Actually Work
&lt;/h2&gt;

&lt;p&gt;These lambdas provide an effective and IDE-friendly implementation, and make it easier to author deeply nested DSL structures while remaining strongly typed. Java isn't a functional language: different idioms are supported, but its nature is that of an object-oriented language. The SDK still manages to create an idiomatic syntax using lambdas, which leads to an easy declaration of the developer's intentions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;search&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;index&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"products"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;q&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;bool&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;must&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;match&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;
                    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;field&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"description"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"wireless"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each lambda represents a nested configuration step, with type-safe closures. You're not passing in strings or magic maps. You're composing a statically typed tree. That's the win. It avoids a common anti-pattern: chaining &lt;code&gt;.withX()&lt;/code&gt;, &lt;code&gt;.setY()&lt;/code&gt; methods on dozens of mutable objects, with nulls lurking everywhere. Here, each level is scoped, focused, and immutable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tagged Unions and Type-Safe Variants
&lt;/h2&gt;

&lt;p&gt;Let's talk polymorphism. Elasticsearch queries aren't flat structuresthey're variant types. A &lt;code&gt;Query&lt;/code&gt; can be a &lt;code&gt;MatchQuery&lt;/code&gt;, &lt;code&gt;BoolQuery&lt;/code&gt;, &lt;code&gt;RangeQuery&lt;/code&gt;, etc. The SDK models this with a &lt;a href="https://en.wikipedia.org/wiki/Tagged_union" rel="noopener noreferrer"&gt;Tagged Union&lt;/a&gt; pattern.&lt;/p&gt;

&lt;p&gt;A tagged union is a data structure that can hold values of different data types, but only one at a time. It's similar to a regular union, but includes a tag (or discriminator) that shows which data type is currently stored. This tag allows type-safe access to the stored value, preventing accidental data misuse.&lt;/p&gt;

&lt;p&gt;The client implements a generalized &lt;code&gt;TaggedUnion&lt;/code&gt; pattern for many of these variant domains (queries, aggregations, analyzers, etc.). A &lt;code&gt;TaggedUnion&lt;/code&gt; exposes the current &lt;code&gt;kind&lt;/code&gt; and the strongly typed value; the builders expose explicit methods for each variant, making discovery and correctness easier. This pattern trades a small amount of indirection for compiler-enforced exhaustiveness for better discoverability in the IDE.&lt;/p&gt;

&lt;p&gt;Each such union implements:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;TaggedUnion&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Tag&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&amp;gt;,&lt;/span&gt; &lt;span class="nc"&gt;BaseType&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Tag&lt;/span&gt; &lt;span class="nf"&gt;_kind&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="nc"&gt;BaseType&lt;/span&gt; &lt;span class="nf"&gt;_get&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You inspect the &lt;code&gt;_kind()&lt;/code&gt; to figure out what it is, then call &lt;code&gt;_get()&lt;/code&gt; and cast it safely:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Query&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Query&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;q&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;match&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;field&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"title"&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"elasticsearch"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;_kind&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nc"&gt;Query&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Kind&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Match&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;MatchQuery&lt;/span&gt; &lt;span class="n"&gt;match&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MatchQuery&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;_get&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="c1"&gt;// Work with match safely&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This design solution allows reasoning with the union construct even without the syntactic support of the most recent versions of Java, while maintaining backward compatibility with those who already used Elastic products in previous installations. Starting with Java 16+, we have a taste of structural pattern matching that could be used in the future for an evolution of the SDK; for example, a first step could be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;_kind&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;Match&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;MatchQuery&lt;/span&gt; &lt;span class="n"&gt;match&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MatchQuery&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;_get&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="c1"&gt;// use match&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;Term&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;TermQuery&lt;/span&gt; &lt;span class="n"&gt;term&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;TermQuery&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;_get&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="c1"&gt;// use term&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Modular by Design: The Namespace Client Pattern
&lt;/h2&gt;

&lt;p&gt;Elasticsearch's API is wide. It has search, index management, mapping, ingest pipelines, security, cluster health, and more endpoints. Cramming all of this into one class would be a nightmare.&lt;/p&gt;

&lt;p&gt;Instead, the SDK scopes things by domain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;ElasticsearchClient&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ElasticsearchClient&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;transport&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;indices&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;index&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"catalog"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;search&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;index&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"products"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;match&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;field&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"laptop"&lt;/span&gt;&lt;span class="o"&gt;)))&lt;/span&gt;
&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each sub-DSL node (&lt;code&gt;indices()&lt;/code&gt;, &lt;code&gt;search()&lt;/code&gt;, etc.) exposes only the relevant operations for its context. This is an effective support for both IDEs and our brains. It maps directly to the REST API structure (&lt;code&gt;/_search&lt;/code&gt;, &lt;code&gt;/_indices&lt;/code&gt;, etc.), making it easier to reason what goes where. It also makes &lt;a href="https://www.elastic.co/guide/en/elasticsearch/client/java-api-client/8.19/package-structure.html" rel="noopener noreferrer"&gt;the SDK highly maintainable&lt;/a&gt;. Adding new API groups becomes simple: no giant, god-interfaces to refactor.&lt;/p&gt;

&lt;p&gt;Targeting a full-featured Java network SDK that must support:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;per-connection configuration (auth, headers, timeouts)&lt;/li&gt;
&lt;li&gt;multiple concurrent clients&lt;/li&gt;
&lt;li&gt;good testability and DI
&lt;/li&gt;
&lt;li&gt;an ergonomic developer experience&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The namespaced instance client pattern is a rational trade-off. You face slightly more ceremony and many small classes, but supporting modularity under the hood while giving a single discoverable root object to users.&lt;/p&gt;

&lt;h2&gt;
  
  
  Immutability and Transport Abstraction
&lt;/h2&gt;

&lt;p&gt;Request objects don't change. Builders build once. You pass data, not behavior: the SDK is inherently thread-safe and predictable.&lt;/p&gt;

&lt;p&gt;Transport concerns are separated from typed models: by default, the Java client delegates protocol handling to a RestClientTransport, which itself uses a low-level HTTP client (for example, the Apache HTTP client) to manage connections, pooling, retries, and node discovery. This separation enables the Java client to focus on typed request/response modeling and (de)serialization while the transport handles operational concerns.&lt;br&gt;
The transport is pluggable, allowing the client's configuration to adapt to different HTTP stacks when needed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;ElasticsearchTransport&lt;/span&gt; &lt;span class="n"&gt;transport&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;RestClientTransport&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;restClient&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;JacksonJsonpMapper&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;span class="nc"&gt;ElasticsearchClient&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ElasticsearchClient&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;transport&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This separation of concerns makes the SDK easier to test, extend, and debug.&lt;/p&gt;

&lt;h2&gt;
  
  
  Could It Be Better?
&lt;/h2&gt;

&lt;p&gt;The presence of many immutable elements impacts memory usage. Therefore, it becomes necessary to understand how to avoid building too many objects that push the developer to consider advanced constructs of the product, such as bundles, data sharing, use of temporal entities, and/or paging the data themselves.&lt;/p&gt;

&lt;p&gt;A measurable trade-off of immutability and single-use builders is short-lived object allocation. In most applications, this overhead is negligible; in very hot loops or high-throughput pipelines, you should benchmark and, if necessary, build reusable immutable fragments or tune bulk/batching strategies. Also consider the overhead of serialization: the client provides hooks to use different &lt;code&gt;JsonpMapper&lt;/code&gt; implementations (for example, Jackson-based mappers) if you need custom parsing or to send pre-serialized payloads.&lt;/p&gt;

&lt;p&gt;Today, Java offers more constructs: records, structural pattern matching with sealed classes, and deconstruction of &lt;code&gt;instanceof&lt;/code&gt;; this would have also meant continuous refactoring of the SDK by chasing Java features over time.&lt;/p&gt;

&lt;p&gt;This SDK strikes a balance between being long-lasting and developer-friendly without altering the knowledge of previous Elastic products.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;What can you learn from this SDK? Here is a summary table of the main concepts that could be useful for your next project. If you're building a client libraryor even just a public-facing APIyou could do worse than borrowing a few ideas from this one. No magic. Just good design... but beware: The Context is the King!&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pattern&lt;/th&gt;
&lt;th&gt;What It Solves&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Builder (Single-Use)&lt;/td&gt;
&lt;td&gt;Safer immutable construction, avoids shared mutable state&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fluent Interface (Lambdas)&lt;/td&gt;
&lt;td&gt;Declarative, nested, type-safe request definitions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tagged Union Pattern&lt;/td&gt;
&lt;td&gt;Models Elasticsearch variant types safely and explicitly&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Namespace Client Pattern&lt;/td&gt;
&lt;td&gt;Logical API grouping aligns with the REST structure&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Transport Abstraction&lt;/td&gt;
&lt;td&gt;Swappable HTTP and serialization layers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Functional Thinking&lt;/td&gt;
&lt;td&gt;Fewer side effects, fewer temporary variables, more declarative code&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

</description>
      <category>api</category>
      <category>design</category>
      <category>java</category>
    </item>
    <item>
      <title>Clean your Memory: From Finalize to Cleaner</title>
      <dc:creator>Stefano Fago</dc:creator>
      <pubDate>Sun, 30 Mar 2025 16:27:12 +0000</pubDate>
      <link>https://dev.to/stefanofago73/clean-your-memory-from-finalize-to-cleaner-3lm8</link>
      <guid>https://dev.to/stefanofago73/clean-your-memory-from-finalize-to-cleaner-3lm8</guid>
      <description>&lt;p&gt;Garbage collection in Java manages memory but does not clean up non-memory resources like sockets or file handles. Resource leaks may occur without proper management, leading to performance degradation or crashes. Java’s &lt;a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/ref/Cleaner.html" rel="noopener noreferrer"&gt;Cleaner API&lt;/a&gt;, introduced in Java 9, provides a modern and efficient mechanism for resource cleanup when objects are no longer reachable. It addresses the shortcomings of the deprecated finalize() method, offering a predictable and efficient way to manage non-memory resources: so let's take a short trip on clean memory from finalize to Cleaner API.&lt;/p&gt;

&lt;h2 id="_why_is_the_finalize_method_deprecatedremoved"&gt;Why is the finalize() method deprecated/removed?&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://openjdk.org/jeps/421" rel="noopener noreferrer"&gt;finalize()&lt;/a&gt; method was initially introduced in Java to provide a way for objects to perform cleanup actions before they are garbage collected. It belongs to &lt;code&gt;java.lang.Object&lt;/code&gt; and can be overridden by subclasses to release resources like file handles or network sockets. Why was this approach problematic?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Unpredictable Execution&lt;/strong&gt;: The &lt;code&gt;finalize()&lt;/code&gt; method is invoked at an undetermined time when GC decides to collect the object.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Performance Overhead&lt;/strong&gt;: Objects with a &lt;code&gt;finalize()&lt;/code&gt; method take longer to collect, as they must go through an extra GC cycle.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Memory Leaks&lt;/strong&gt;: If an object is unintentionally retained (e.g., due to an exception in &lt;code&gt;finalize()&lt;/code&gt;), it may never be garbage collected.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Finalization Queue Mechanism&lt;/strong&gt;: &lt;code&gt;finalize()&lt;/code&gt; execution happens in a separate thread(the Finalizer Thread), which can lead to thread contention and delays.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id="_how_does_cleaner_relate_to_java_reference_classes"&gt;How does Cleaner relate to Java Reference classes?&lt;/h2&gt;

&lt;p&gt;In Java, there are four types of references differentiated by the way by which they are garbage collected:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Strong References&lt;/strong&gt;: objects having an active, strong reference are not eligible for garbage collection. The object is garbage collected only when the variable, which was strongly referenced, points to null.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Weak References&lt;/strong&gt;: the objects referenced by a weak reference do not prevent their referents from being made finalizable, finalized, and reclaimed.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Soft References&lt;/strong&gt;: the objects which are being referenced by soft reference, even if the object is free for garbage collection, it’s not garbage collected until JVM needs memory badly&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Phantom References&lt;/strong&gt;: the objects referenced by phantom references are eligible for garbage collection, but before removing them, the JVM puts them in the "reference queue".&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5vltzuuexc14p3lr7kj5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5vltzuuexc14p3lr7kj5.png" alt="Image description" width="721" height="372"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The logic that guides how they are collected is always related to the concept of &lt;a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/ref/package-summary.html#reachability" rel="noopener noreferrer"&gt;reachability&lt;/a&gt;, as described in the related Javadoc. Java Reference classes are not easy to use, and the resulting &lt;a href="https://www.baeldung.com/java-phantom-reference" rel="noopener noreferrer"&gt;code&lt;/a&gt; is sometimes complicated.
We must also consider that in the case of a Phantom Reference, once the Referent is registered, the reference always returns &lt;code&gt;null&lt;/code&gt;, making it seem useless, but it is not!&lt;/p&gt;

&lt;p&gt;Here’s an example of &lt;code&gt;PhantomReference&lt;/code&gt;:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.lang.ref.PhantomReference&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.lang.ref.Reference&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.lang.ref.ReferenceQueue&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.HashMap&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.Map&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UsingPhantomRef&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Resource&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;cleaning&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"cleaning"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="nf"&gt;ResourceHolder&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Resource&lt;/span&gt; &lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt; &lt;span class="n"&gt;lookup&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;ReferenceQueue&lt;/span&gt; &lt;span class="n"&gt;queue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ReferenceQueue&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;holder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ResourceHolder&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Resource&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
        &lt;span class="n"&gt;lookup&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PhantomReference&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;holder&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;queue&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="n"&gt;holder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;resource&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;

        &lt;span class="n"&gt;holder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;gc&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="nc"&gt;Reference&lt;/span&gt; &lt;span class="n"&gt;element&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;queue&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;poll&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"wating for GC"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"GCollected!"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;lookup&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;remove&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;cleaning&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Cleaner&lt;/code&gt; shares similarities with Java’s reference classes, but it is more efficient for managing external resources. While PhantomReference enables cleanup logic, &lt;code&gt;Cleaner&lt;/code&gt; adds an abstraction layer, making it easier to implement and manage. Internally, &lt;code&gt;Cleaner&lt;/code&gt; uses a phantom reference behind the scenes to detect when an object becomes unreachable.&lt;/p&gt;

&lt;p&gt;Here’s an example of &lt;code&gt;Cleaner&lt;/code&gt;:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.lang.ref.Cleaner&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BasicCleanerExample&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Cleaner&lt;/span&gt; &lt;span class="n"&gt;cleaner&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Cleaner&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

    &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CleaningAction&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Runnable&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nd"&gt;@Override&lt;/span&gt;
        &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Resource cleaned up!"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ManagedObject&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Cleaner&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Cleanable&lt;/span&gt; &lt;span class="n"&gt;cleanable&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

        &lt;span class="nc"&gt;ManagedObject&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;cleanable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cleaner&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;register&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;CleaningAction&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ManagedObject&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;gc&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;pause&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2 id="_behind_the_scenes_of_cleaner"&gt;Behind the scenes of Cleaner&lt;/h2&gt;

&lt;p&gt;The implementation behind Cleaner is not trivial. It leverages a combination of the Java &lt;code&gt;PhantomReference&lt;/code&gt; and a background daemon thread. Let’s explore the inner workings:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Registration with Cleaner&lt;/strong&gt;: an object registered with a &lt;code&gt;Cleaner&lt;/code&gt; is associated with a &lt;code&gt;Cleanable&lt;/code&gt; task. The object is essentially "watched" by a background daemon thread.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Phantom Reference Management&lt;/strong&gt;: Under the hood, &lt;code&gt;Cleaner&lt;/code&gt; uses a &lt;code&gt;PhantomReference&lt;/code&gt; to track the object’s reachability.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Daemon Thread for Cleanup&lt;/strong&gt;: The Cleaner framework uses a dedicated daemon thread (normally named Common-Cleaner) that monitors registered objects. Once an object becomes unreachable, the cleanup task for that object is queued for execution in this background thread.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdfwu0rkoqbmhrdzu9c5v.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdfwu0rkoqbmhrdzu9c5v.jpg" alt="Image description" width="800" height="386"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The following snippet uses a &lt;code&gt;Cleaner&lt;/code&gt; to manage files.&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.io.File&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.io.FileWriter&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.io.IOException&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.lang.ref.Cleaner&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FileCleanerExample&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Cleaner&lt;/span&gt; &lt;span class="n"&gt;cleaner&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Cleaner&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

    &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FileResource&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Runnable&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

        &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;File&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

        &lt;span class="nc"&gt;FileResource&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;File&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;printf&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"resource create with temporary file: %s%n"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getAbsolutePath&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="nd"&gt;@Override&lt;/span&gt;
        &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;exists&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;printf&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"temporary file deleted: %s%n"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;delete&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ManagedFile&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Cleaner&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Cleanable&lt;/span&gt; &lt;span class="n"&gt;cleanable&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

        &lt;span class="nc"&gt;ManagedFile&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;IOException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;File&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;cleanable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cleaner&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;register&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FileResource&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
            &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;FileWriter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;write&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Temporary data"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;IOException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;managed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ManagedFile&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"temp.txt"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;managed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;gc&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;pause&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2 id="_cleaner_vs_try_with_resources"&gt;Cleaner vs. try-with-resources&lt;/h2&gt;

&lt;p&gt;The example with a file might suggest a more idiomatic solution using the &lt;code&gt;try-with-resources&lt;/code&gt; construct. It may be a real solution but is less so if we consider particular resources such as images or memory buffers directly mapped to memory. As a last note, we also need to consider that &lt;code&gt;Autocloseable&lt;/code&gt; can be used with &lt;code&gt;Cleanable&lt;/code&gt;, invoking the &lt;code&gt;clean()&lt;/code&gt; method from the &lt;code&gt;close()&lt;/code&gt; one, having the same effect as a GC operation.
Here’s a dedicated example.&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.lang.ref.Cleaner&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CleanerWithCloseExample&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Cleaner&lt;/span&gt; &lt;span class="n"&gt;cleaner&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Cleaner&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

    &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CleaningAction&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Runnable&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nd"&gt;@Override&lt;/span&gt;
        &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Resource cleaned up!"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ManagedObject&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;AutoCloseable&lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Cleaner&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Cleanable&lt;/span&gt; &lt;span class="n"&gt;cleanable&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

        &lt;span class="nc"&gt;ManagedObject&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;cleanable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cleaner&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;register&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;CleaningAction&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="nd"&gt;@Override&lt;/span&gt;
        &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="o"&gt;(){&lt;/span&gt;
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"close invoked!"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;cleanable&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;clean&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;object&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ManagedObject&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;printf&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"using: %s%n"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The following table allows us to summarize the tools presented and choose the one that best suits our purposes.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;colgroup&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;
&lt;/colgroup&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;try-with-resources&lt;/th&gt;
&lt;th&gt;Cleaner&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;Resource Type&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Autocloseable&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;It also works with no Autocloaseable object&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;Cleanup Timing&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Immediate&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Deferred, asynchronous&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;Use Case&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;When precise cleanup timing is required&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;When working with external resources or objects without explicit close methods&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;Overhead&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Minimal&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Higher due to the background thread&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2 id="_avoid_overusing_cleaner"&gt;Avoid overusing Cleaner&lt;/h2&gt;

&lt;p&gt;Using &lt;code&gt;Cleaner&lt;/code&gt; is more straightforward than using references. Still, we must exercise caution when using this kind of resource: only use &lt;code&gt;Cleaner&lt;/code&gt; when the runtime can’t release resources via &lt;code&gt;try-with-resources&lt;/code&gt; or explicit &lt;code&gt;close()&lt;/code&gt; calls.
We also need to consider that we create new elements, and sometimes it’s better to use one &lt;code&gt;Cleaner&lt;/code&gt; for multiple resources or to listen to the cleaning action.
More aspects need our attention, as for cleaning action, following some rules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Avoid using lambda because it risks capturing the object reference by referring to fields of the object being cleaned, preventing the object from becoming phantom reachable.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Cleaning actions can be invoked concurrently with other cleaning actions. They should be swift to execute and not block: it may delay processing other cleaning actions registered to the same cleaner.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;We can also consider executing a cleaning action and delegating it to another thread pool, but this idea can involve more complexity and not solve concurrency issues.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id="_conclusion"&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Java’s Cleaner API provides a modern, efficient approach to resource management, addressing the limitations of &lt;code&gt;finalize()&lt;/code&gt;. By leveraging &lt;code&gt;Cleaner&lt;/code&gt;, developers can ensure that non-&lt;code&gt;AutoCloseable&lt;/code&gt; resources, such as native memory and caches, are properly cleaned up when no longer needed. However, you should always prefer try-with-resources when possible for deterministic resource management.&lt;/p&gt;

&lt;p&gt;By understanding when and how to use &lt;code&gt;Cleaner&lt;/code&gt;, developers can write more reliable, high-performance, and memory-efficient Java applications. Mastering these best practices will be essential for building robust, scalable software as Java evolves.&lt;/p&gt;

&lt;h2 id="_further_resources"&gt;Further Resources&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://www.infoworld.com/article/2334445/how-to-handle-java-errors-and-cleanup-without-finalize.html" rel="noopener noreferrer"&gt;How to handle Java errors and cleanup without finalize&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://inside.java/2022/05/25/clean-cleaner/" rel="noopener noreferrer"&gt;Replacing Finalizers with Cleaners&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://dev.to/ahmedjaad/java-cleaners-the-modern-way-to-manage-external-resources-4d4" rel="noopener"&gt;Java Cleaners: The Modern Way to Manage External Resources&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://softwareengineering.stackexchange.com/questions/348770/cleaner-code-practices-for-java-programming" rel="noopener noreferrer"&gt;Cleaner code practices for Java programming&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>programming</category>
      <category>tutorial</category>
      <category>java</category>
      <category>memory</category>
    </item>
    <item>
      <title>The FizzBuzz: a branchless version with Java</title>
      <dc:creator>Stefano Fago</dc:creator>
      <pubDate>Sat, 22 Mar 2025 19:38:27 +0000</pubDate>
      <link>https://dev.to/stefanofago73/the-fizzbuzz-a-branchless-version-with-java-3hk4</link>
      <guid>https://dev.to/stefanofago73/the-fizzbuzz-a-branchless-version-with-java-3hk4</guid>
      <description>&lt;p&gt;Let dissect a Java program that implements the &lt;strong&gt;FizzBuzz&lt;/strong&gt; problem with a &lt;code&gt;branchless&lt;/code&gt; style, using a mix of bitwise operations, lambdas, and an optimized loop. Let's break it down step by step:&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Overview of FizzBuzz Rules&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  Print numbers from 1 to 100.&lt;/li&gt;
&lt;li&gt;  If a number is divisible by &lt;strong&gt;3&lt;/strong&gt;, print &lt;code&gt;"Fizz"&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  If a number is divisible by &lt;strong&gt;5&lt;/strong&gt;, print &lt;code&gt;"Buzz"&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  If a number is divisible by &lt;strong&gt;both 3 and 5&lt;/strong&gt;, print &lt;code&gt;"FizzBuzz"&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  Otherwise, print the number itself.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Code Breakdown&lt;/strong&gt;
&lt;/h3&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;1. Defining an Interface for Lambda Expressions&lt;/strong&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;Provider&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;value&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;  An &lt;strong&gt;interface &lt;code&gt;Provider&lt;/code&gt;&lt;/strong&gt; is needed since generic array are not possible, so Function or other functional interface are non allowed.&lt;/li&gt;
&lt;li&gt;  It has a single method &lt;code&gt;value(int i)&lt;/code&gt;, which will be implemented using lambda expressions.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;2. Creating an Array of &lt;code&gt;Provider&lt;/code&gt; Lambdas&lt;/strong&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Provider&lt;/span&gt; &lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;provider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;valueOf&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="o"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;  This array holds three lambda expressions:

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;i -&amp;gt; String.valueOf(i)&lt;/code&gt;: Returns the number as a string.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;i -&amp;gt; ""&lt;/code&gt;: Returns an empty string.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;i -&amp;gt; ""&lt;/code&gt;: Another empty string (used later for Fizz/Buzz handling).&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;3. Defining Text Segments&lt;/strong&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;textSegment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="s"&gt;"FizzBuzz"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="s"&gt;"Buzz"&lt;/span&gt;&lt;span class="o"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;  This array maps to different text outputs:

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;textSegment[0] = ""&lt;/code&gt; (for numbers that aren't Fizz or Buzz)&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;textSegment[1] = "Fizz"&lt;/code&gt; (for numbers divisible by 3)&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;textSegment[2] = "FizzBuzz"&lt;/code&gt; (for numbers divisible by both 3 and 5)&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;textSegment[3] = "Buzz"&lt;/code&gt; (for numbers divisible by 5)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;4. Using StringBuilder for Efficient String Concatenation&lt;/strong&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;StringBuilder&lt;/span&gt; &lt;span class="n"&gt;sb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;StringBuilder&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;newline&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;lineSeparator&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;StringBuffer&lt;/code&gt; is used for efficient string concatenation.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;newline&lt;/code&gt; stores the platform-specific line separator.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;5. Main Loop with Bitwise Operations&lt;/strong&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;providerIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;segmentIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; 
     &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; 
     &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++,&lt;/span&gt;
     &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="mi"&gt;528&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
     &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;((-&lt;/span&gt;&lt;span class="mi"&gt;2128340926&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
     &lt;span class="n"&gt;providerIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
     &lt;span class="n"&gt;segmentIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;sb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;append&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;textSegment&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;segmentIndex&lt;/span&gt;&lt;span class="o"&gt;])&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;append&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;provider&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;providerIndex&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;append&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;newline&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This loop iterates from &lt;code&gt;i = 1&lt;/code&gt; to &lt;code&gt;100&lt;/code&gt; and performs the following calculations:&lt;/p&gt;

&lt;h5&gt;
  
  
  &lt;strong&gt;(1) Calculating &lt;code&gt;a&lt;/code&gt; - 5 Multiples&lt;/strong&gt;
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="mi"&gt;528&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;528&lt;/code&gt; (binary: &lt;code&gt;100001000010000&lt;/code&gt;) is a &lt;strong&gt;bitmask&lt;/strong&gt; that identifies numbers divisible by 5.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;(i % 15 - 1)&lt;/code&gt; is used to shift the bitmask.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;&amp;amp; 1&lt;/code&gt; extracts whether the bit is set.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;&amp;lt;&amp;lt; 2&lt;/code&gt; makes sure that if it's Fizz, &lt;code&gt;a&lt;/code&gt; is 4, otherwise &lt;code&gt;a&lt;/code&gt; is 0.&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  &lt;strong&gt;(2) Calculating &lt;code&gt;b&lt;/code&gt; - 3 and 15 Multiples&lt;/strong&gt;
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;((-&lt;/span&gt;&lt;span class="mi"&gt;2128340926&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;-2128340926&lt;/code&gt; (binary: &lt;code&gt;100000010000001000000100000010&lt;/code&gt;) is a &lt;strong&gt;bitmask&lt;/strong&gt; that identifies numbers divisible by 3 or 15.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;((i % 15) &amp;lt;&amp;lt; 1)&lt;/code&gt; is used to shift the bitmask.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;&amp;amp; 3&lt;/code&gt; ensures only relevant bits are taken.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;&amp;lt;&amp;lt; 2&lt;/code&gt; scales &lt;code&gt;b&lt;/code&gt; properly.&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  &lt;strong&gt;(3) Determining &lt;code&gt;providerIndex&lt;/code&gt;&lt;/strong&gt;
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;providerIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;providerIndex&lt;/code&gt; determines whether to print the number (&lt;code&gt;provider[0]&lt;/code&gt;) or an empty string (&lt;code&gt;provider[1]&lt;/code&gt; or &lt;code&gt;provider[2]&lt;/code&gt;) since provides the values: 0,1,2.&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  &lt;strong&gt;(4) Determining &lt;code&gt;segmentIndex&lt;/code&gt;&lt;/strong&gt;
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;segmentIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;segmentIndex&lt;/code&gt; selects the correct FizzBuzz text from &lt;code&gt;textSegment&lt;/code&gt; since provides the values: 0,1,2,3.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;6. Appending the Result&lt;/strong&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;sb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;append&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;textSegment&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;segmentIndex&lt;/span&gt;&lt;span class="o"&gt;])&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;append&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;provider&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;providerIndex&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;append&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;newline&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;  The correct Fizz/Buzz text (&lt;code&gt;textSegment[segmentIndex]&lt;/code&gt;) is added.&lt;/li&gt;
&lt;li&gt;  The number (or an empty string) is determined by &lt;code&gt;provider[providerIndex]&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  A newline is appended.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;7. Printing the Final Output&lt;/strong&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sb&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;  The entire FizzBuzz output is printed at once.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Key Takeaways&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Uses bitwise operations for efficient FizzBuzz checking.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Avoids multiple if-else conditions.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Optimizes string concatenation with &lt;code&gt;StringBuilder&lt;/code&gt;.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Lambda functions simplify number/string selection.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are more solutions about FizzBuzz, and maybe the code can be optimized further, but this code is funny and didactic enough to implement FizzBuzz in Java!&lt;/p&gt;

</description>
      <category>programming</category>
      <category>java</category>
      <category>learning</category>
      <category>performance</category>
    </item>
    <item>
      <title>Experimenting around FP in PHP</title>
      <dc:creator>Stefano Fago</dc:creator>
      <pubDate>Mon, 18 Dec 2023 13:23:01 +0000</pubDate>
      <link>https://dev.to/stefanofago73/experimenting-around-fp-in-php-5ek6</link>
      <guid>https://dev.to/stefanofago73/experimenting-around-fp-in-php-5ek6</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Warn&lt;/strong&gt;: in this Post, it's tried to use as much typing as possible also if sometimes this means to take some distance from official documentation &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The evolution of the PHP language has had an effective contribution from some powerful specifications:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the &lt;a href="https://www.php.net/manual/en/language.types.callable.php"&gt;Callable&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;the &lt;a href="https://www.php.net/manual/en/functions.anonymous.php"&gt;Anonymous Function&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;the &lt;a href="https://www.php.net/manual/en/class.closure.php"&gt;Closure&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are now enriched by new RFC:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the &lt;a href="https://www.php.net/manual/en/language.oop5.anonymous.php"&gt;Anonymous Classes&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;the &lt;a href="https://www.php.net/manual/en/functions.arrow.php"&gt;Arrow Functions&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;the &lt;a href="https://www.php.net/manual/en/functions.first_class_callable_syntax.php"&gt;First Class Callable Syntax&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: These RFCs make possible a lot of different constructs that go further than what will be exposed in this Post: remember that the "White Rabbit hole" is deep!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Callable, Anonymous Function, Closure, and FP!
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Callables&lt;/em&gt;&lt;/strong&gt; are generally used as the main type hint to define callbacks: a summary of how they can be defined/used can be seen in the &lt;a href="https://www.php.net/manual/en/language.types.callable.php#118032"&gt;official documentation&lt;/a&gt;. Introducing the &lt;strong&gt;&lt;em&gt;__invoke&lt;/em&gt;&lt;/strong&gt; function, even at the interface or anonymous class level, makes it possible to manage an object as a function transforming it into a Callable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Butterfly&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__invoke&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"flying..."&lt;/span&gt;&lt;span class="p"&gt;;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nv"&gt;$butterfly&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Butterfly&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nv"&gt;$butterfly&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// flying...&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;Closure&lt;/em&gt;&lt;/strong&gt; is the class used to represent anonymous functions: this kind of construct, also in the form of &lt;strong&gt;&lt;em&gt;arrow&lt;/em&gt;&lt;/strong&gt; function, is really useful not only as a callback, in place of a callable, but also more usage since the ability to capture a different scope or to simulate FP constructs such as &lt;a href="https://en.wikipedia.org/wiki/Currying"&gt;currying&lt;/a&gt; like in the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                     &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                     &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$familyName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                     &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$age&lt;/span&gt;&lt;span class="p"&gt;){}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;&lt;span class="nc"&gt;\Closure&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="k"&gt;return&lt;/span&gt; 
          &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="nc"&gt;\Closure&lt;/span&gt;
          &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$familyName&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="nc"&gt;\Closure&lt;/span&gt;
            &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$age&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="kt"&gt;Person&lt;/span&gt;
             &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;$familyName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;$age&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nv"&gt;$person&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;()(&lt;/span&gt;&lt;span class="s1"&gt;'Frank'&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="s1"&gt;'Jamison'&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The introduction of &lt;strong&gt;&lt;em&gt;First-Class Callable Syntax&lt;/em&gt;&lt;/strong&gt; makes it possible to create Closure from any kind of function, defining a sort of &lt;strong&gt;&lt;em&gt;function reference&lt;/em&gt;&lt;/strong&gt; usable in places different from the definition (what follows reuse the example seen above)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;
&lt;span class="nv"&gt;$personBuilder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;...&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nv"&gt;$frank&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$personBuilder&lt;/span&gt;&lt;span class="p"&gt;()(&lt;/span&gt;&lt;span class="s1"&gt;'Frank'&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="s1"&gt;'Jamison'&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="mi"&gt;45&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nv"&gt;$john&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$personBuilder&lt;/span&gt;&lt;span class="p"&gt;()(&lt;/span&gt;&lt;span class="s1"&gt;'John'&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="s1"&gt;'Smith'&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Arrays, arrays functions, and the anonymous functions
&lt;/h2&gt;

&lt;p&gt;The use of anonymous functions is particularly useful when we refer to native functions on arrays: the potential is notable and makes the use of &lt;a href="https://szymonkrajewski.pl/why-you-should-use-array-functions-instead-of-basic-loops/"&gt;loops superfluous&lt;/a&gt; as in the following code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$stock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'Phone'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'qty'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'Notebook'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'qty'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'SDD Drive'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'qty'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'HDD Drive'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'qty'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="nv"&gt;$inStock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;array_filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$stock&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'qty'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Native functions on arrays bring out the functional world when it comes down to it to the &lt;strong&gt;&lt;em&gt;fold operation&lt;/em&gt;&lt;/strong&gt; (the &lt;a href="https://www.php.net/manual/en/function.array-reduce.php"&gt;array_reduce&lt;/a&gt; function) that allows us to be a point on which to build other fundamental functions such as &lt;strong&gt;&lt;em&gt;map&lt;/em&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;em&gt;filter&lt;/em&gt;&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;
&lt;span class="cd"&gt;/**
 *
 *@template T
 *@template R
 *@param array&amp;lt;T&amp;gt; $data
 *@param callable(T):R $mapper
 *@return array&amp;lt;R&amp;gt;
 *
 */&lt;/span&gt;
&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;callable&lt;/span&gt; &lt;span class="nv"&gt;$mapper&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;array_reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
&lt;span class="cd"&gt;/** @param T $element */&lt;/span&gt; 
&lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$accumulator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$element&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$mapper&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
             &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="nv"&gt;$accumulator&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$mapper&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$element&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
              &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$accumulator&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="cd"&gt;/**
 *
 *@template T
 *@param array&amp;lt;T&amp;gt; $data
 *@param callable(T):bool $predicate
 *@return array&amp;lt;T&amp;gt;
 *
 */&lt;/span&gt;
&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;callable&lt;/span&gt; &lt;span class="nv"&gt;$predicate&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;array_reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
&lt;span class="cd"&gt;/** @param T $element */&lt;/span&gt; 
&lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$accumulator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$element&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$predicate&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;                    
      &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$predicate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$element&lt;/span&gt;&lt;span class="p"&gt;)){&lt;/span&gt;   
        &lt;span class="nv"&gt;$accumulator&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$element&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; 
 &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$accumulator&lt;/span&gt;&lt;span class="p"&gt;;},[]);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The improved performance on arrays, starting from PHP 7.X, and the handling of anonymous functions are convenient from both a performance and memory consumption point of view although the practice of only using arrays sometimes doesn't make you consider the multiple benefits of alternative data structures.&lt;/p&gt;

&lt;p&gt;Anonymous functions and closures are easy to distinguish given the &lt;strong&gt;&lt;em&gt;use clause&lt;/em&gt;&lt;/strong&gt; that allows you to capture elements from outside the given anonymous function. The value of the captured element is defined when the closure is declared and cannot be changed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="mf"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;    

&lt;span class="k"&gt;final&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PriceRange&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

   &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="nv"&gt;$minimumValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="nv"&gt;$maximumValue&lt;/span&gt;&lt;span class="p"&gt;){}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                     &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="nv"&gt;$minimumValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                     &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="nv"&gt;$maximumValue&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;PriceRange&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PriceRange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$minimumValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;$maximumValue&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;priceFilter&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;&lt;span class="nc"&gt;\Closure&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Product&lt;/span&gt; &lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; 
               &lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;price&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;minimumValue&lt;/span&gt; 
                             &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
               &lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;price&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;maximumValue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="cd"&gt;/** @var array&amp;lt;Product&amp;gt; $prodcuts */&lt;/span&gt;
&lt;span class="nv"&gt;$products&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="mf"&gt;...&lt;/span&gt; &lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="nv"&gt;$range&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;PriceRange&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;5.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;10.0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nb"&gt;array_filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$products&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$range&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;priceFilter&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Closures are still handy in design where you want to isolate the visibility of data, always in the light of the FP paradigm, as in the following example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;
&lt;span class="cd"&gt;/** @return \Closure():int */&lt;/span&gt;
&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;rndNumber&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;&lt;span class="nc"&gt;\Closure&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;rand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nb"&gt;getrandmax&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="cd"&gt;/** @return \Closure():int */&lt;/span&gt;
&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;rndConstant&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;&lt;span class="nc"&gt;\Closure&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$constant&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;rand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nb"&gt;getrandmax&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$constant&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nv"&gt;$rnd1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;rndNumber&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nv"&gt;$c1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;rndConstant&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nv"&gt;$c2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;rndConstant&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$rnd1&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// 505035335&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$rnd1&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// 1353685165&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$c1&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;   &lt;span class="c1"&gt;// 2030702172&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$c1&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;   &lt;span class="c1"&gt;// 2030702172&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These possibilities are also useful in approaching internal domain-specific languages (&lt;strong&gt;&lt;em&gt;DSL&lt;/em&gt;&lt;/strong&gt;) or adopting the &lt;strong&gt;&lt;em&gt;higher-order function&lt;/em&gt;&lt;/strong&gt; (in FP slang): the &lt;a href="https://www.oreilly.com/library/view/design-patterns-and/9781786463593/56585929-d828-45ce-9a91-648ad0dd4823.xhtml"&gt;Loan&lt;/a&gt; Pattern and the &lt;a href="https://www.dontpanicblog.co.uk/2020/11/28/execute-around-idiom-in-java/"&gt;Execute Around&lt;/a&gt; Pattern are examples of this concept.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;//&lt;/span&gt;
&lt;span class="c1"&gt;//Example of Execute-Around...&lt;/span&gt;
&lt;span class="c1"&gt;// ...also used in DSL definition for nested-dsl&lt;/span&gt;
&lt;span class="c1"&gt;//&lt;/span&gt;
 &lt;span class="nc"&gt;MailSender&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Mail&lt;/span&gt; &lt;span class="nv"&gt;$config&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="kt"&gt;Mail&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
            &lt;span class="nv"&gt;$config&lt;/span&gt;
                    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;From&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"john.black@kmail.com"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;To&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"jack.white@jmail.com"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;Subject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Test message"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Hello World!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;//&lt;/span&gt;
&lt;span class="c1"&gt;// Example of Load Pattern&lt;/span&gt;
&lt;span class="c1"&gt;//&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ToyBox&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;

   &lt;span class="mf"&gt;...&lt;/span&gt;

    &lt;span class="cd"&gt;/**
     * 
     * @param \Closure(ToyBox):ToyBox $boxFillerPolicy
     * @param \Closure(ToyBox):ToyBox $playActions
     * @return \Closure():void
     */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;final&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;play&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;\Closure&lt;/span&gt; &lt;span class="nv"&gt;$boxFillerPolicy&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;\Closure&lt;/span&gt; &lt;span class="nv"&gt;$playActions&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="nc"&gt;\Closure&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$boxFillerPolicy&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;$playActions&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;   
                  &lt;span class="nv"&gt;$box&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ToyBox&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                  &lt;span class="nv"&gt;$box&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;Open&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                  &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                      &lt;span class="nv"&gt;$box&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$boxFillerPolicy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$box&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                      &lt;span class="nv"&gt;$box&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$playActions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$box&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                  &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="k"&gt;finally&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                      &lt;span class="nv"&gt;$box&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                          &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;CleanUpToys&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                  &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="mf"&gt;...&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;nextToy&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;&lt;span class="kt"&gt;ToyBox&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="mf"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;addToy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$toyName&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="kt"&gt;ToyBox&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="mf"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;    
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;Usage&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$refill&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;ToyBox&lt;/span&gt; &lt;span class="nv"&gt;$box&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="kt"&gt;ToyBox&lt;/span&gt;
           &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;$box&lt;/span&gt;
             &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;addToy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"lego"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
             &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;addToy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"mechano"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
             &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;addToy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"laser"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="nv"&gt;$play&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;ToyBox&lt;/span&gt; &lt;span class="nv"&gt;$box&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="kt"&gt;ToyBox&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$box&lt;/span&gt;
            &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;nextToy&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;nextToy&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;nextToy&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="nv"&gt;$playSession&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ToyBox&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;play&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$refill&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$play&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;       
        &lt;span class="nv"&gt;$playSession&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Scope element in Closures
&lt;/h2&gt;

&lt;p&gt;Closures can refer to different scopes than those in which they were created thanks to the &lt;strong&gt;&lt;em&gt;bind&lt;/em&gt;&lt;/strong&gt; functions. The possibilities of closures become considerable and they could replace the use of &lt;strong&gt;&lt;em&gt;Reflection&lt;/em&gt;&lt;/strong&gt; since they can access the private state of objects: this, however, has limitations in the presence of static analysis infrastructures such as PHPStan and PSALM which highlight &lt;em&gt;abuses of closures&lt;/em&gt; as in the following example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SimpleClass&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$privateData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nv"&gt;$simpleClosure&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;privateData&lt;/span&gt;&lt;span class="p"&gt;;};&lt;/span&gt;
&lt;span class="nv"&gt;$instance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;SimpleClass&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nv"&gt;$resultClosure&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;\Closure&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                       &lt;span class="nv"&gt;$simpleClosure&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                       &lt;span class="nv"&gt;$instance&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                       &lt;span class="nc"&gt;SimpleClass&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$resultClosure&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;?-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;$resultClosure&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="mf"&gt;...&lt;/span&gt;
&lt;span class="c1"&gt;//&lt;/span&gt;
&lt;span class="c1"&gt;//PSALM Output&lt;/span&gt;
&lt;span class="c1"&gt;//  &lt;/span&gt;
&lt;span class="c1"&gt;// ERROR: InvalidScope - Invalid reference to $this in a &lt;/span&gt;
&lt;span class="c1"&gt;//          non-class context&lt;/span&gt;
&lt;span class="c1"&gt;// INFO: MixedInferredReturnType - Could not verify the  return &lt;/span&gt;
&lt;span class="c1"&gt;// type 'int' for...&lt;/span&gt;
&lt;span class="c1"&gt;//&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's however possible to find ways to overcome these problems and exploit appropriately the potential of the closures from the outside of a class. A possible trick is to define a &lt;strong&gt;&lt;em&gt;bridge operation&lt;/em&gt;&lt;/strong&gt; (a protected function, also &lt;em&gt;static&lt;/em&gt; if needed) to use when the Closure is created, as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SimpleClass&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$privateData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="kt"&gt;final&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; 
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;privateData&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;    
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nv"&gt;$instance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;SimpleClass&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// @phpstan-ignore return.unusedType&lt;/span&gt;
&lt;span class="nv"&gt;$accessTo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$bridgeOperation&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="nc"&gt;\Closure&lt;/span&gt;
   &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="nc"&gt;\Closure&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;SimpleClass&lt;/span&gt; &lt;span class="nv"&gt;$instance&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$bridgeOperation&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="cd"&gt;/** @var callable():int $operation */&lt;/span&gt; 
            &lt;span class="nv"&gt;$operation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$instance&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;$bridgeOperation&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$operation&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="kc"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nc"&gt;SimpleClass&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="cd"&gt;/** @var null|\Closure(SimpleClass):int $resultClosure **/&lt;/span&gt;
&lt;span class="nv"&gt;$resultClosure&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$accessTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"privateData"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$resultClosure&lt;/span&gt;&lt;span class="o"&gt;===&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;?-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;$resultClosure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$instance&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// 2&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This approach seems more verbose but we can make it reusable and it passes static analysis given also more strong typing. It's also an example of how we can approach the FP concept of &lt;a href="https://medium.com/@gcanti/introduction-to-optics-lenses-and-prisms-3230e73bfcfe"&gt;Optics&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The importance of the exposed specifications is not only in having introduced types for the different elements but it's also in the new design possibilities. They have also brought PHP even closer to natively approaching Functional Programming: so it's important to study and experiment also with static analysis enabled! It is worth noticing that with PHP you can approach FP both in a more function-oriented way or in a more object-oriented way using generics and advanced techniques thanks also to PHPStan or PSALM.&lt;/p&gt;

&lt;h2&gt;
  
  
  To Go Furter
&lt;/h2&gt;

&lt;p&gt;More elements need to be considered, here not exposed as for the design consequences of &lt;strong&gt;&lt;em&gt;read-only&lt;/em&gt;&lt;/strong&gt; constructs or the &lt;strong&gt;&lt;em&gt;Generators&lt;/em&gt;&lt;/strong&gt;, but also if not adopted, it's useful to consider these concepts to enrich our ability to design Clean Software! &lt;/p&gt;

&lt;p&gt;Other resources allow the adoption of functional idioms/constructs and to study the concepts and approaches presented in this post: so... Happy Learn!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.infoq.com/articles/php7-function-improvements/"&gt;https://www.infoq.com/articles/php7-function-improvements/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/fp4php/functional"&gt;https://github.com/fp4php/functional&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/haskellcamargo/php-partial-function-application"&gt;https://github.com/haskellcamargo/php-partial-function-application&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/marcosh/lamphpda"&gt;https://github.com/marcosh/lamphpda&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/phunkie/phunkie"&gt;https://github.com/phunkie/phunkie&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/functional-php"&gt;https://github.com/functional-php&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/widmogrod/php-functional"&gt;https://github.com/widmogrod/php-functional&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/loophp/collection"&gt;https://github.com/loophp/collection&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://leanpub.com/thinking-functionally-in-php"&gt;https://leanpub.com/thinking-functionally-in-php&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.phparch.com/books/functional-programming-in-php/"&gt;https://www.phparch.com/books/functional-programming-in-php/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://link.springer.com/book/10.1007/978-1-4842-2958-3"&gt;https://link.springer.com/book/10.1007/978-1-4842-2958-3&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Designing with PHP 8.1 Enumerations</title>
      <dc:creator>Stefano Fago</dc:creator>
      <pubDate>Sun, 03 Dec 2023 17:08:36 +0000</pubDate>
      <link>https://dev.to/stefanofago73/designing-with-php-81-enumerations-33o8</link>
      <guid>https://dev.to/stefanofago73/designing-with-php-81-enumerations-33o8</guid>
      <description>&lt;h2&gt;
  
  
  PHP 8.1: The Rise of Enumeration
&lt;/h2&gt;

&lt;p&gt;PHP 8.1 introduces the syntax for the &lt;a href="https://www.php.net/manual/en/language.enumerations.php"&gt;Enumeration&lt;/a&gt;. I was curious about the argument and before PHP 8.1 there were more experimental implementations but no direct support. Now Enumeration is here and is a native construct that makes code much more expressive and gives a new way to model software design.&lt;/p&gt;

&lt;p&gt;The Enumeration in PHP now has an implicit family where the basic &lt;a href="https://www.php.net/manual/en/class.unitenum.php"&gt;UnitEnum&lt;/a&gt; with a minimal contract:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;UnitEnum&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="cm"&gt;/* Functions */&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;cases&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;array&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;a href="https://www.php.net/manual/en/class.backedenum.php"&gt;BackedEnum&lt;/a&gt; extends the UnitEnum making it possible to relate primitive values (int or string) to enumeration instances.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;BackedEnum&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;UnitEnum&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt; 
   &lt;span class="cm"&gt;/* Functions */&lt;/span&gt;
   &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;int&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt;
   &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;tryFrom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;int&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="k"&gt;static&lt;/span&gt;

   &lt;span class="cm"&gt;/* Inherited Functions */&lt;/span&gt;
   &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;UnitEnum&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;cases&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;array&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Note:&lt;br&gt;
These elements are interfaces but not in DEV Space since are used by the PHP Engine, introduced for type checking. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I've always seen Enumeration as &lt;strong&gt;&lt;em&gt;Domain Symbols&lt;/em&gt;&lt;/strong&gt; ( a limited set of symbols) but the PHP RFC is enough to define some use cases that can be useful to express more design.&lt;/p&gt;

&lt;h2&gt;
  
  
  PHP Enumeration: some Anti-Pattern!
&lt;/h2&gt;

&lt;p&gt;Before continuing, I want to present some bad ideas in using Enumerations but remain at a high level of abstraction.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Confusing Constant
&lt;/h3&gt;

&lt;p&gt;It's possible to declare some constants inside an enumeration but the declared constant is not a &lt;em&gt;case&lt;/em&gt; of the enumeration. It can be useful to have some edge values inside the enumeration but we need, however, remember to avoid confusing the Devs. Consider also that constants can hide &lt;em&gt;callables&lt;/em&gt;!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="n"&gt;enum&lt;/span&gt; &lt;span class="nc"&gt;Size&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;Small&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;Medium&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;Large&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="no"&gt;Huge&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nc"&gt;Large&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="no"&gt;Max_For_Large_Size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="no"&gt;Cases&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'cases'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="no"&gt;Size&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="mf"&gt;...&lt;/span&gt;

&lt;span class="nb"&gt;var_export&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Size&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nc"&gt;Huge&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// alias for Size::Large&lt;/span&gt;
&lt;span class="nb"&gt;var_export&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Size&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Max_For_Large_Size&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 100&lt;/span&gt;
&lt;span class="nb"&gt;var_export&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Size&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Cases&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// array (0 =&amp;gt; Size::Small,1 =&amp;gt;Size::Medium,2 =&amp;gt; Size::Large,)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The Empty Enumeration
&lt;/h3&gt;

&lt;p&gt;It's possible to write an enumeration without any case ( also backed )&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="n"&gt;enum&lt;/span&gt; &lt;span class="nc"&gt;TheEmptyEnum&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;int&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So we have &lt;em&gt;TheEmptyEnum::cases&lt;/em&gt; as an empty array while, in our example, no instances are available, and &lt;em&gt;TheEmptyEnum::tryFrom&lt;/em&gt; returns null!&lt;/p&gt;

&lt;h3&gt;
  
  
  The Commodity Enumeration
&lt;/h3&gt;

&lt;p&gt;Since Enumeration can host function and since the Empty Enumeration, it's possible to write an enumeration that plays the role of a &lt;em&gt;Commodity Class&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="n"&gt;enum&lt;/span&gt; &lt;span class="nc"&gt;Calculator&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$b&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$a&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nv"&gt;$b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="nc"&gt;Calculator&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 3 &lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The Singleton Anti-Pattern(?)
&lt;/h3&gt;

&lt;p&gt;It is possible to use Enumeration to define the concept of the Singleton.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="n"&gt;enum&lt;/span&gt; &lt;span class="nc"&gt;Runtime&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="no"&gt;INSTANCE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;elapsed&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;&lt;span class="kt"&gt;float&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="mf"&gt;...&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;   
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="mf"&gt;...&lt;/span&gt;
&lt;span class="nc"&gt;Runtime&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;INSTANCE&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;elapsed&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Enumerations, Template &amp;amp; Constant Expression
&lt;/h3&gt;

&lt;p&gt;Nowadays, enumeration can't be defined as generics by using docblock template and also if a case can be used as constant, it can't be some element coming from the enumeration function.&lt;/p&gt;

&lt;h2&gt;
  
  
  Interesting Design Aspect of Enumerations
&lt;/h2&gt;

&lt;p&gt;We can have the following interesting usage of enumeration remembering always the concept that they are enumerable elements.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Interface Friend
&lt;/h3&gt;

&lt;p&gt;An enumeration can implement an interface; it's interesting to notice that, more than the obligation of the contract, we obtain protection from the fact that what we consider enumerable today, tomorrow will be not but we don't need to change the signature of the functions.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Trait Friend
&lt;/h3&gt;

&lt;p&gt;An enumeration is a more constrained environment and using traits can be a way to enhance some enumeration abilities, coming from the new PHP 8.X features, as we can see in these projects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/Elao/PhpEnums"&gt;https://github.com/Elao/PhpEnums&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/josezenem/php-enums-extended"&gt;https://github.com/josezenem/php-enums-extended&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dive-be/php-enum-utils"&gt;https://github.com/dive-be/php-enum-utils&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Enumeration State Machine
&lt;/h3&gt;

&lt;p&gt;A state machine has an enumerable set of states so it's possible to use the new RFC and a UnitEnum to define a functioning State Machine&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;
&lt;span class="n"&gt;enum&lt;/span&gt; &lt;span class="nc"&gt;PeachesPipe&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="no"&gt;WASH&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="no"&gt;PEEL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="no"&gt;CUT&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="no"&gt;PUT_IN_JAR&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="no"&gt;READY&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;&lt;span class="kt"&gt;PeachesPipe&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;]();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;


    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;WASH&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;&lt;span class="kt"&gt;PeachesPipe&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="kc"&gt;PHP_EOL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;PeachesPipe&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;PEEL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;PEEL&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;&lt;span class="kt"&gt;PeachesPipe&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="kc"&gt;PHP_EOL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;PeachesPipe&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;CUT&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;CUT&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;&lt;span class="kt"&gt;PeachesPipe&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="kc"&gt;PHP_EOL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;PeachesPipe&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;PUT_IN_JAR&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;PUT_IN_JAR&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;&lt;span class="kt"&gt;PeachesPipe&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="kc"&gt;PHP_EOL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;PeachesPipe&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;READY&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="mf"&gt;...&lt;/span&gt;
&lt;span class="nv"&gt;$pipeline&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;PeachesPipe&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;WASH&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$pipeline&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nc"&gt;PeachesPipe&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;READY&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$pipeline&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$pipeline&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;process&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// WASH&lt;/span&gt;
&lt;span class="c1"&gt;// PEEL&lt;/span&gt;
&lt;span class="c1"&gt;// CUT&lt;/span&gt;
&lt;span class="c1"&gt;// PUT_IN_JAR&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The Enumeration Strategy Pattern
&lt;/h3&gt;

&lt;p&gt;We can use an enumerable set of algorithms related to a specific Domain, defining related strategies inside an enumeration.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;
&lt;span class="n"&gt;enum&lt;/span&gt; &lt;span class="nc"&gt;Currency&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="no"&gt;EUR&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="no"&gt;USD&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="k"&gt;final&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Item&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Stringable&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
               &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$quantity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
               &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$price&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
               &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kt"&gt;Currency&lt;/span&gt; &lt;span class="nv"&gt;$currency&lt;/span&gt;&lt;span class="p"&gt;){}&lt;/span&gt;

   &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__toString&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;
   &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s1"&gt;'[ id:'&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;
              &lt;span class="s1"&gt;', quantity: '&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;quantity&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;
              &lt;span class="s1"&gt;', price:'&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;currency&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="s1"&gt;' ]'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="k"&gt;final&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Basket&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Stringable&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cd"&gt;/** @param list&amp;lt;Item&amp;gt; $items **/&lt;/span&gt;
   &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$items&lt;/span&gt;&lt;span class="p"&gt;){}&lt;/span&gt;

    &lt;span class="cd"&gt;/** @return list&amp;lt;Item&amp;gt; **/&lt;/span&gt;
   &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt;
   &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
   &lt;span class="p"&gt;}&lt;/span&gt;

   &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__toString&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;
   &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s1"&gt;'(Basket: '&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;var_export&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="s1"&gt;')'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="n"&gt;enum&lt;/span&gt; &lt;span class="nc"&gt;DiscountType&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;int&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="no"&gt;BRONZE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="no"&gt;SILVER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="no"&gt;GOLD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;apply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Basket&lt;/span&gt; &lt;span class="nv"&gt;$basket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;DiscountType&lt;/span&gt; &lt;span class="nv"&gt;$discount&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="kt"&gt;Basket&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$factor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$discount&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;$items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;array_map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                   &lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Item&lt;/span&gt; &lt;span class="nv"&gt;$item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
                         &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$item&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                  &lt;span class="nv"&gt;$item&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$item&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="nv"&gt;$item&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nv"&gt;$factor&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
                                  &lt;span class="nv"&gt;$item&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;currency&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                  &lt;span class="nv"&gt;$basket&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                &lt;span class="p"&gt;);&lt;/span&gt;
       &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Basket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$items&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="nv"&gt;$items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
       &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'az123'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nc"&gt;Currency&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;EUR&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
       &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'azBCV'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nc"&gt;Currency&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;EUR&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
       &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'azKJI'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;150&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nc"&gt;Currency&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;EUR&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nv"&gt;$basket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Basket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$items&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nv"&gt;$basket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;DiscountType&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;apply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$basket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nc"&gt;DiscountType&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;BRONZE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The Enumeration Factory Pattern
&lt;/h3&gt;

&lt;p&gt;An enumerable set of elements can be created from a function hidden in a specific backed enumeration&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;
&lt;span class="k"&gt;final&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Topping&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Stringable&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="p"&gt;){}&lt;/span&gt;

    &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__toString&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s1"&gt;'Topping('&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="s1"&gt;')'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="k"&gt;final&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Cake&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Stringable&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kt"&gt;CakeType&lt;/span&gt; &lt;span class="nv"&gt;$type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                         &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kt"&gt;Topping&lt;/span&gt; &lt;span class="nv"&gt;$top&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                         &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$weight&lt;/span&gt;&lt;span class="p"&gt;){}&lt;/span&gt;

    &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__toString&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s1"&gt;'Cake('&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="s1"&gt;','&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;top&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="s1"&gt;', '&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;weight&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="s1"&gt;')'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;CakeFactory&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;&lt;span class="kt"&gt;Cake&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;enum&lt;/span&gt; &lt;span class="nc"&gt;CakeType&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;int&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;CakeFactory&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="no"&gt;CHOCOLATE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="no"&gt;VANILLA&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2200&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="no"&gt;FROSTED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2500&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;&lt;span class="kt"&gt;Cake&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="nc"&gt;CakeType&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;CHOCOLATE&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Cake&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Topping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Glazed Choco'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
         &lt;span class="nc"&gt;CakeType&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;VANILLA&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Cake&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Topping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Glazed White'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
         &lt;span class="nc"&gt;CakeType&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;FROSTED&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Cake&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Topping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Cherries'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="mf"&gt;...&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nc"&gt;CakeType&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;VANILLA&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Cake(VANILLA,Topping(Glazed White), 2200)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's also possible to introduce some laziness using closure instead of simple functions and playing with the concept of private const (callable) and/or supplier closure.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Processor Set Pattern
&lt;/h3&gt;

&lt;p&gt;An enumerable set of processors can be expressed thank to an enumeration also using a touch of FP.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;
&lt;span class="n"&gt;enum&lt;/span&gt; &lt;span class="nc"&gt;Operation&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;int&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="no"&gt;SUM&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="no"&gt;SUB&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="no"&gt;MUL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="no"&gt;DIV&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

   &lt;span class="cd"&gt;/** @return callable(Operation):callable(int,int):int **/&lt;/span&gt;
   &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;processorsMap&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;&lt;span class="kt"&gt;callable&lt;/span&gt;
   &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nv"&gt;$processors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nc"&gt;Operation&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;SUM&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$b&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;$a&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nv"&gt;$b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nc"&gt;Operation&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;SUB&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$b&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;$a&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;$b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nc"&gt;Operation&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;MUL&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$b&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;$a&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nv"&gt;$b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nc"&gt;Operation&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;DIV&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$b&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="nv"&gt;$a&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nv"&gt;$b&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="cd"&gt;/** @psalm-suppress PossiblyUndefinedIntArrayOffset */&lt;/span&gt; 
     &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Operation&lt;/span&gt; &lt;span class="nv"&gt;$opKey&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;$processors&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$opKey&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="mf"&gt;...&lt;/span&gt;
&lt;span class="nv"&gt;$processors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Operation&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;processorsMap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$processors&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Operation&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 4&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The Conditional Processor Pattern
&lt;/h3&gt;

&lt;p&gt;We can have an enumerable set of flags conditioning a specific processing operation and we can use an enumeration for that.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;
&lt;span class="n"&gt;enum&lt;/span&gt; &lt;span class="nc"&gt;EventType&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;int&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="no"&gt;CLICKED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="no"&gt;FOCUSED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="no"&gt;EXECUTED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="no"&gt;BLURRED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;eventsCombining&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;EventType&lt;/span&gt; &lt;span class="mf"&gt;...&lt;/span&gt; &lt;span class="nv"&gt;$type&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="nv"&gt;$values&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;array_map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;EventType&lt;/span&gt; &lt;span class="nv"&gt;$eventType&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;$eventType&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;$type&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
     &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;array_reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$values&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                               &lt;span class="cd"&gt;/** 
                                * @param int|null $carry
                                * @param int $val
                                * @return int */&lt;/span&gt; 
&lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$carry&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;$val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$carry&lt;/span&gt;&lt;span class="o"&gt;===&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="nv"&gt;$val&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$carry&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nv"&gt;$val&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; 
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="mf"&gt;...&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'events set: '&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;EventType&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;eventsCombining&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                        &lt;span class="nc"&gt;EventType&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;CLICKED&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  
            &lt;span class="nc"&gt;EventType&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;FOCUSED&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="nc"&gt;EventType&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;EXECUTED&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="nc"&gt;EventType&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;BLURRED&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                     &lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="kc"&gt;PHP_EOL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// events set: 15&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An interesting and more complex example comes from this project:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/framjet/php-enum-bitmask"&gt;https://github.com/framjet/php-enum-bitmask&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Enumeration Random Generator
&lt;/h3&gt;

&lt;p&gt;It's also possible to extract randomly from enumeration instances as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;
 &lt;span class="cd"&gt;/**
  * @template T of \UnitEnum
  * @param class-string&amp;lt;T&amp;gt; $enumType
  * @return callable():T
  **/&lt;/span&gt;
&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;randomEnumGenerator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$enumType&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="kt"&gt;callable&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="cd"&gt;/** @var array&amp;lt;T&amp;gt; $cases **/&lt;/span&gt; &lt;span class="nv"&gt;$cases&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$enumType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;"cases"&lt;/span&gt;&lt;span class="p"&gt;]();&lt;/span&gt;
 &lt;span class="nv"&gt;$len&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$cases&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$cases&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;rand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;$len&lt;/span&gt;&lt;span class="p"&gt;)];&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="n"&gt;enum&lt;/span&gt; &lt;span class="nc"&gt;Direction&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;North&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;South&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;East&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;West&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="mf"&gt;...&lt;/span&gt;
&lt;span class="nv"&gt;$gen&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;randomEnumGenerator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Direction&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nb"&gt;var_export&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$gen&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// Direction::West&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Note: Here are used Template e Template Class to force typing&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  To Go Further
&lt;/h2&gt;

&lt;p&gt;More are not happy with this kind of design but I hope You can find some useful use cases. We need always to use some &lt;strong&gt;discipline&lt;/strong&gt;, and remember the real meaning of an enumeration!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://aye.sh/files/talks/2021/PHP-Enums-MidwestPHP/PHP-Enums.pdf"&gt;https://aye.sh/files/talks/2021/PHP-Enums-MidwestPHP/PHP-Enums.pdf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Seldaek/monolog/blob/3.0.0/src/Monolog/Level.php"&gt;https://github.com/Seldaek/monolog/blob/3.0.0/src/Monolog/Level.php&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=5Cgio2OfOYk"&gt;https://www.youtube.com/watch?v=5Cgio2OfOYk&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stitcher.io/blog/php-enums"&gt;https://stitcher.io/blog/php-enums&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.amitmerchant.com/native-enumerations-are-coming-in-php-81/"&gt;https://www.amitmerchant.com/native-enumerations-are-coming-in-php-81/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://goatreview.com/using-php-8-1-enumerations-in-symfony/"&gt;https://goatreview.com/using-php-8-1-enumerations-in-symfony/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bestofphp.com/repo/bpolaszek-doctrine-native-enums-php-miscellaneous"&gt;https://bestofphp.com/repo/bpolaszek-doctrine-native-enums-php-miscellaneous&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>php</category>
      <category>learning</category>
      <category>designpatterns</category>
      <category>enumeration</category>
    </item>
    <item>
      <title>Lists: do you know the nature of yours? The strange story of a data container in Java</title>
      <dc:creator>Stefano Fago</dc:creator>
      <pubDate>Thu, 23 Nov 2023 16:50:58 +0000</pubDate>
      <link>https://dev.to/stefanofago73/lists-do-you-know-the-nature-of-yours-the-strange-story-of-a-data-container-in-java-2col</link>
      <guid>https://dev.to/stefanofago73/lists-do-you-know-the-nature-of-yours-the-strange-story-of-a-data-container-in-java-2col</guid>
      <description>&lt;h2&gt;
  
  
  Foreword
&lt;/h2&gt;

&lt;p&gt;Lists are among the most used data structures in various programs but, in Java, the choices are limited even if the evolution of the language has led to new elements. To date, the main type of list used is the &lt;a href="https://docs.oracle.com/en/java/javase/18/docs/api/java.base/java/util/ArrayList.html" rel="noopener noreferrer"&gt;ArrayList&lt;/a&gt;. Other types of lists would also be present (such as &lt;a href="https://it.wikipedia.org/wiki/Skip_list" rel="noopener noreferrer"&gt;SkipLists&lt;/a&gt;) but they have been used for different purposes and, given their nature, to effectively build other types of &lt;a href="https://docs.oracle.com/en/java/javase/18/docs/api/java.base/java/util/concurrent/ConcurrentSkipListSet.html" rel="noopener noreferrer"&gt;data&lt;/a&gt; &lt;a href="https://docs.oracle.com/en/java/javase/18/docs/api/java.base/java/util/concurrent/ConcurrentSkipListMap.html" rel="noopener noreferrer"&gt;structures&lt;/a&gt;. Still others such as elements deriving from the Dynamic Arrays are hidden in the &lt;a href="https://github.com/openjdk/jdk17/blob/master/src/java.base/share/classes/java/util/stream/SpinedBuffer.java" rel="noopener noreferrer"&gt;internals&lt;/a&gt; of the JDK!&lt;/p&gt;

&lt;h2&gt;
  
  
  How many lists we can find in Java?
&lt;/h2&gt;

&lt;p&gt;The concept of List is part of the Java Collection Framework (&lt;strong&gt;&lt;em&gt;JCF&lt;/em&gt;&lt;/strong&gt;) and starts from the &lt;a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" rel="noopener noreferrer"&gt;List interface&lt;/a&gt; that is a direct extension of two concepts: Collection and Iterable (so a provider of external Iterator but also an entry point to stream).&lt;/p&gt;

&lt;p&gt;We can briefly summarize JCF with the following image:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbgjk1xpc8ry81vhtczpn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbgjk1xpc8ry81vhtczpn.png" alt="Java Collection Framework structure"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We have public classes that express the main list data structure available in Java:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Vector.html" rel="noopener noreferrer"&gt;Vector&lt;/a&gt; (legacy data structure)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Stack.html" rel="noopener noreferrer"&gt;Stack&lt;/a&gt; (legacy data structure and direct subclass of Vector) &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/ArrayList.html" rel="noopener noreferrer"&gt;ArrayList&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/LinkedList.html" rel="noopener noreferrer"&gt;LinkedList&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/concurrent/CopyOnWriteArrayList.html" rel="noopener noreferrer"&gt;CopyOnWriteArrayList&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The most used list in Java is ArrayList which makes it possible to express the concept of the &lt;em&gt;list based on an array implementation&lt;/em&gt;: this realization is more effective than the LinkedList as stated in different &lt;a href="https://stuartmarks.wordpress.com/2015/12/18/some-java-list-benchmarks/" rel="noopener noreferrer"&gt;tests&lt;/a&gt; ( caused also by CPU and Memory mechanics)&lt;br&gt;
An ArrayList makes it possible to have random access to the element of the list since it's also an implementation of interface &lt;a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/RandomAccess.html" rel="noopener noreferrer"&gt;RandomAccess&lt;/a&gt;; this implies that &lt;strong&gt;&lt;em&gt;having a reference to a List, we can test if we can use the get([index]) method or not&lt;/em&gt;&lt;/strong&gt;. ( e.g. ArrayList vs LinkedList)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ifNullThrows&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;IllegalArgumentException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
         &lt;span class="s"&gt;"Collection contains null values "&lt;/span&gt;
         &lt;span class="o"&gt;+(&lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="o"&gt;==-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="s"&gt;" at idx: "&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;  
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;checkNullElements&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                           &lt;span class="nc"&gt;Collection&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;collection&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nc"&gt;RandomAccess&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; 
        &lt;span class="n"&gt;collection&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&amp;gt;)&lt;/span&gt;&lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
             &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt; 
             &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; 
             &lt;span class="n"&gt;ifNullThrows&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
             &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;  
    &lt;span class="o"&gt;}&lt;/span&gt; 
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;element&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;ifNullThrows&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="o"&gt;,-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  In how many ways You can build a List?
&lt;/h2&gt;

&lt;p&gt;At the moment I'm writing, if we talk about the &lt;em&gt;List interface&lt;/em&gt; and we don't consider public classes, we can obtain an instance using different invocations as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Arrays.asList&lt;/li&gt;
&lt;li&gt;Collections.unmodifiableList&lt;/li&gt;
&lt;li&gt;Collections.nCopies&lt;/li&gt;
&lt;li&gt;Collections.emptyList / Collections.EMPTY_LIST&lt;/li&gt;
&lt;li&gt;Stream.toList&lt;/li&gt;
&lt;li&gt;Collectors.toUnmodifiableList&lt;/li&gt;
&lt;li&gt;List.of&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once You have a reference List to manage how can You say what characteristics are owned? &lt;br&gt;
Or more simply how can You say if the List can mutate or not? And How? And... &lt;br&gt;
When designing software, what kind of list You'll return, and how will be created?&lt;/p&gt;
&lt;h2&gt;
  
  
  Why is it a Problem?
&lt;/h2&gt;

&lt;p&gt;The first problem is at the level of Type System, given that a situation more correct would allow us to distinguish through the Collection Type which abstraction we are operating with, species if definable as &lt;strong&gt;&lt;em&gt;mutable or immutable&lt;/em&gt;&lt;/strong&gt;. &lt;br&gt;
The JCF was born at a time when great care was taken to offer immediate operational data structures, and with &lt;em&gt;attention to performance&lt;/em&gt;, but with less attention to constructs or uses that are now seen as common.&lt;br&gt;
These concepts have been taken up by other infrastructures from which we certainly cannot fail to mention: &lt;a href="https://eclipse.dev/collections/" rel="noopener noreferrer"&gt;Eclipse Collection&lt;/a&gt;, &lt;a href="https://github.com/google/guava" rel="noopener noreferrer"&gt;Guava Collections&lt;/a&gt;, and &lt;a href="https://www.vavr.io/" rel="noopener noreferrer"&gt;VAVR&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A second aspect arises from the fact that immutable data structures generally support a &lt;a href="https://en.wikipedia.org/wiki/Fluent_interface" rel="noopener noreferrer"&gt;fluent API&lt;/a&gt;; this style of API allows for better development in the presence of functional programming constructs, as in the following example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;flattenListsWithMilestone&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                                 &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                                 &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;milestone&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
             &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
              &lt;span class="o"&gt;{&lt;/span&gt; 
               &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;milestone&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
               &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
              &lt;span class="o"&gt;})&lt;/span&gt;
         &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;flatMap&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;List:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
         &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;collect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;toList&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;     
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Even if this code is a bit contrived, it demonstrates how, without fluent API, as for Scala, we are forced to use lambda with a body, a style which is generally not a good practice and which does not allow us to make the code more readable thanks, also, to the possible use of a &lt;em&gt;reference method&lt;/em&gt;. ( Oh Yes, You can however use a private commodity method as a surrogate!)&lt;/p&gt;

&lt;p&gt;Another problem is that the differentiation of data structures allows the implementation of specific design and optimization strategies for the given structure. This aspect is evident if we consider the new lists that derive from the &lt;strong&gt;List.of&lt;/strong&gt; factory methods. The JCF allows the creation of any new data structure, in our case a list, but always of a mutable nature rather than a general vision.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mutable, Immutable, Not Modifiable List
&lt;/h2&gt;

&lt;p&gt;It's easy to find out that mutable lists are ArrayList, LinkedList, and with specific concurrency support, Vector, Stack, and CopyOnWriteArrayList but what can say of the other kind of List&amp;lt;T&amp;gt;?&lt;br&gt;
As a preamble about Immutability, we need to accept that &lt;strong&gt;&lt;em&gt;in Java we have unmodifiable lists more than properly immutable ones&lt;/em&gt;&lt;/strong&gt;, and than things can be &lt;a href="https://nipafx.dev/immutable-collections-in-java/" rel="noopener noreferrer"&gt;difficult to change&lt;/a&gt;. So let's explore the ways of creating List with the different invocations!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Arrays.asList&lt;/em&gt;&lt;/strong&gt; returns a fixed-size list backed by the specified array. The returned list is serializable and implements RandomAccess. Changes to the returned list write through to the array. It seems unmodifiable but, also if You can't use add method, You can use List.set changing element at the given index. The inner class used is called ArrayList but is not the public one as the following signature:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;E&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;AbstractList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;E&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;RandomAccess&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;java&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;io&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Serializable&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We also need to notice that the generic signature of asList create problems/ambiguities with arrays of primitive types, like for int[] that can't be passed to Arrays.asList to obtain a  List&amp;lt;Integer&amp;gt;. In the future, the support of primitive in generics will change more things but today a safer way to bypass the problem is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;[]{&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;};&lt;/span&gt;
   &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;numberList&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 
        &lt;span class="nc"&gt;Arrays&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
              &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;boxed&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
              &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toList&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;but can be also useful to use &lt;strong&gt;&lt;em&gt;Collectors.toCollection([Supplier])&lt;/em&gt;&lt;/strong&gt; since base implementation of Stream.toList:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;toList&lt;/span&gt;&lt;span class="o"&gt;(){&lt;/span&gt; 
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;)&lt;/span&gt; &lt;span class="nc"&gt;Collections&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;unmodifiableList&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                         &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;(&lt;/span&gt;
                         &lt;span class="nc"&gt;Arrays&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;asList&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toArray&lt;/span&gt;&lt;span class="o"&gt;())));&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;Collections.emptyList&lt;/em&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;em&gt;Collections.nCopies&lt;/em&gt;&lt;/strong&gt; are commodities methods that return specialized unmodifiable lists. All modification methods will throw Exceptions. &lt;strong&gt;&lt;em&gt;Collections.nCopies&lt;/em&gt;&lt;/strong&gt; is a lazy list where only the original element is used and repeated only in the case of &lt;em&gt;toArray&lt;/em&gt; methods (logically the copy of provided elements in construction is a reference copy)&lt;br&gt;
&lt;strong&gt;&lt;em&gt;Collections.unmodifiableList&lt;/em&gt;&lt;/strong&gt; is similar to the other methods, returning a specialized unmodifiable list; a decoration approach is used by design and all modification methods will throw Exceptions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;unmodifiableList&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                               &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt; 
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nc"&gt;RandomAccess&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt;
             &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;UnmodifiableRandomAccessList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt;
             &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;UnmodifiableList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;Stream.toList&lt;/em&gt;&lt;/strong&gt; create unmodifiable list, also If Javadoc ask to not make any assumption on the nature of the list, and remember that a better control on the result is in using &lt;strong&gt;&lt;em&gt;Collectors.toCollection([supplier])&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;List.of&lt;/em&gt;&lt;/strong&gt; represent a set of static method that uses package class &lt;strong&gt;&lt;em&gt;ImmutableCollections.java&lt;/em&gt;&lt;/strong&gt;: this class hosts different inner implementation returning fixed-size list backed by a specified array. All modification methods will throw Exceptions. Some aspects need to be considered or reiterated:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;wrapping class as Arrays.asList, Collections.unmodifiableList can be modified by altering the original collection or array used in construction&lt;/li&gt;
&lt;li&gt;It is possible to obtain an empty list in many ways while actually obtaining different types of lists by:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Arrays&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;asList&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
&lt;span class="nc"&gt;Collections&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;emptyList&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
&lt;span class="nc"&gt;Collections&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;EMPTY_LIST&lt;/span&gt;
&lt;span class="nc"&gt;Collections&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;nCopies&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="o"&gt;])&lt;/span&gt;
&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On this last topic, the singletons &lt;strong&gt;&lt;em&gt;Collections.emptyList()&lt;/em&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;em&gt;Collections.EMPTY_LIST&lt;/em&gt;&lt;/strong&gt; are conceptually aliases that allow a performance gain in returning an empty list but it should be considered whether it is always correct to use these elements rather than returning a new empty list immutable or not, or create, in a specific namespace, another singleton based on one of the above invocations.&lt;/p&gt;

&lt;h2&gt;
  
  
  ...but what if you wanted to recognize the nature of a list?
&lt;/h2&gt;

&lt;p&gt;How can I recognize if a list &lt;strong&gt;&lt;em&gt;is mutable or not modifiable?&lt;/em&gt;&lt;/strong&gt; Let's say that from a pure design point of view it shouldn't interest us because by playing on typing it should be possible to act differently but this is not the situation. &lt;em&gt;As a pure exercise let's try to see some solutions&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;&lt;em&gt;first approach&lt;/em&gt;&lt;/strong&gt; can be very simple and take advantage of the basic knowledge we have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;isMutable&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;subject&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;subject&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;  &lt;span class="o"&gt;||&lt;/span&gt; 
         &lt;span class="n"&gt;subject&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nc"&gt;LinkedList&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; 
         &lt;span class="n"&gt;subject&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nc"&gt;Vector&lt;/span&gt;     &lt;span class="o"&gt;||&lt;/span&gt; 
         &lt;span class="n"&gt;subject&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nc"&gt;CopyOnWriteArrayList&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A &lt;strong&gt;&lt;em&gt;second solution&lt;/em&gt;&lt;/strong&gt;, a little more elaborate, could be to memorize the reference classes of the various possible lists and take advantage of the instance-of operator:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;HashSet&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Class&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;static&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;
   &lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HashSet&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;   
   &lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;getClass&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
   &lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;getClass&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
   &lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Collections&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;emptyList&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getClass&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
   &lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Collections&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;nCopies&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;getClass&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
   &lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Collections&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;unmodifiableList&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                           &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;()).&lt;/span&gt;&lt;span class="na"&gt;getClass&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
   &lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Arrays&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;asList&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getClass&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;isMutable&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;subject&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;anyMatch&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;clazz&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;subject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getClass&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                              &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isAssignableFrom&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;clazz&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt; 
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Note: ...what will happen when having Structural Pattern Matching? We can derive some solutions?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A &lt;strong&gt;&lt;em&gt;third solution&lt;/em&gt;&lt;/strong&gt; takes advantage of the fact that the main unmodifiable classes are actually inner classes unlike the mutable ones which are top classes; using this knowledge we can write the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;isMutable&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;subject&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;subject&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
         &lt;span class="n"&gt;subject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getClass&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getEnclosingClass&lt;/span&gt;&lt;span class="o"&gt;()==&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An interesting proposition, to make things compatible with the actual List interface, comes from Java Guru &lt;a href="https://www.javaspecialists.eu/" rel="noopener noreferrer"&gt;Heinz Kabutz&lt;/a&gt;: adding default method &lt;code&gt;characteristics&lt;/code&gt; as for &lt;a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Spliterator.html" rel="noopener noreferrer"&gt;Spliterator&lt;/a&gt;, it would be possible to understand the nature of the given List implementation.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are my dreams about Lists?
&lt;/h2&gt;

&lt;p&gt;The Java Collection Framework has a high level of extensibility but its design is based on hierarchically defined relationships with interfaces, which define roles of data structures, and abstract classes that act as extension hot spots. In the near future, it will be &lt;a href="https://openjdk.org/jeps/431" rel="noopener noreferrer"&gt;further modified&lt;/a&gt; to meet the needs of well-established use cases.&lt;/p&gt;

&lt;p&gt;My personal view is to have a different packaging of data structures to allow for better isolation of them since not all of them are used in all applications, even with the current JCF design.&lt;/p&gt;

&lt;p&gt;In relation to the lists it would be nice to have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Unrolled_linked_list" rel="noopener noreferrer"&gt;unrolled linked list&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Hashed_array_tree" rel="noopener noreferrer"&gt;hashed array tree&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;to complete the set of array-based dynamic lists, so as to improve performance in the light of mechanical sympathy or optimization of memory use.&lt;/p&gt;

&lt;p&gt;It would be useful to have &lt;a href="https://en.wikiversity.org/wiki/Self_organizing_list" rel="noopener noreferrer"&gt;self-organizing lists&lt;/a&gt; to approximate use cases such as local caches and allow some sorting of data, based on customizable logic. This in conjunction with use with other data structures would be a way to expand the JCF power and modeling possibilities without resorting to many infrastructures outside the JDK.&lt;/p&gt;

&lt;p&gt;Immutable lists should probably appear in a dedicated package and it should be really nice to have &lt;a href="https://en.wikipedia.org/wiki/Persistent_data_structure" rel="noopener noreferrer"&gt;persistent data structures&lt;/a&gt; to have: the advantages of immutability, a set of fluent APIs, the optimizations in the use of the memory, normally present for this type of data structures.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;There are no perfect solutions but perfectible solutions are possible. When choosing a data structure it is necessary to take a moment to reflect on the choice made. In the case of lists, most part of the use cases are covered by what is offered by the JDK.&lt;/p&gt;

&lt;p&gt;Logically in the ecosystem of open source projects, there are good frameworks that make it possible to further meet the needs of the day by day (both OO and FP).&lt;/p&gt;

&lt;h3&gt;
  
  
  What can we learn from what we examined?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;To date, we cannot tell if a list is idiomatically mutable or not.&lt;/li&gt;
&lt;li&gt;To date, in the design of an API we need to understand when it is possible to reduce the abstraction level or widen it using Iterable or list implementation types, to avoid creating confusion with the only concept of List (however in many cases unavoidable)&lt;/li&gt;
&lt;li&gt;Always use Javadoc to be able to describe the type of lists actually returned or that you want to manage in the various functional elements&lt;/li&gt;
&lt;li&gt;We can certainly say that Arrays.asList as well as the lists deriving from the Collections class must be used in testing contexts and only as commodities elements and, therefore, their use-cases seem to see them hidden in internal portions of higher-level implementations or realizations.&lt;/li&gt;
&lt;li&gt;It is possible to use more structured or effective frameworks, for performance or definition of types, present in the open source world, taking care not to leak anything of the specific framework on the boundaries of a system or in any case on the interfacing elements of the realizations: this to avoid to find our-self with problems of dependencies and inconvenient or "sticky" maintenance&lt;/li&gt;
&lt;li&gt;Currently, the lists deriving from List.of must be the ones to be used in case of unmodifiable needs (and check for the absence of nulls), to make fallback on the composition of lists in situations of aggregate fragments of lists from different points of the system.&lt;/li&gt;
&lt;li&gt;Consider that the various types of lists are serializable: this possibility must further reflect on what we are offering to a third party. This must bring to reason when, whether or not to actually use an aggregate type instead of a generic data container.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>java</category>
      <category>datastructures</category>
      <category>softwareengineering</category>
      <category>learning</category>
    </item>
    <item>
      <title>Problem Details for HTTP APIs - RFC 7807 is dead, long live RFC 9457</title>
      <dc:creator>Stefano Fago</dc:creator>
      <pubDate>Thu, 23 Nov 2023 15:27:34 +0000</pubDate>
      <link>https://dev.to/stefanofago73/problem-details-for-http-apis-rfc-7807-is-dead-long-live-rfc-9457-1lc1</link>
      <guid>https://dev.to/stefanofago73/problem-details-for-http-apis-rfc-7807-is-dead-long-live-rfc-9457-1lc1</guid>
      <description>&lt;p&gt;The positive experience of RFC 7807, whose journey began in 2016, is concluded (&lt;em&gt;deprecation&lt;/em&gt;) but also confirmed with a new official proposition: the RFC 9457.&lt;br&gt;
The changes made are small but it is a suitable opportunity to analyze the evolution of this topic.&lt;/p&gt;
&lt;h2&gt;
  
  
  Context
&lt;/h2&gt;

&lt;p&gt;The RFC 7807, and now the RFC 9457 which perfects it, was born after a period in which the Internet Companies have made it clear that the integration of the business, the eventual transformation of the company services into a platform and a part of the organizational flexibility can pass from using the API.&lt;/p&gt;

&lt;p&gt;The lack of references and the need to be time-to-market has meant that these same entities &lt;em&gt;pollute&lt;/em&gt; the panorama of approaches and implementations in a set of non-interoperable solutions directing to some effects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;invalidating, in part, the effectiveness of the API&lt;/li&gt;
&lt;li&gt;creating the need to define alternative tools&lt;/li&gt;
&lt;li&gt;defining the need for standards to have a more effective and evolving product, consultancy, and research market over time&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Problem Details for HTTP APIs
&lt;/h2&gt;

&lt;p&gt;The motivation leading to these RFCs is the impossibility of expressing errors, both semantically and in terms of &lt;em&gt;contents&lt;/em&gt;, using only HTTP Status Codes.&lt;br&gt;
This premise does not mean that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HTTP status codes are bad&lt;/li&gt;
&lt;li&gt;HTTP status codes are not useful&lt;/li&gt;
&lt;li&gt;HTTP status codes need to be replaced&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Why are we talking about &lt;em&gt;HTTP API&lt;/em&gt;?&lt;br&gt;
&lt;em&gt;HTTP API&lt;/em&gt; means the possibility of communications machine to machine, implemented upon the HTTP protocol thanks to modular elements defined by specific RFCs. So we are not talking about REST but about a more open superset in favor of large-scale developments.&lt;/p&gt;

&lt;p&gt;This RFC therefore offers the benefit of allowing information to be conveyed for both humans and machines: this paves the way for the creation of better related tools.&lt;br&gt;
It is not, however, the goal of the RFC to provide an application debugging tool.&lt;br&gt;
All this is summarized in the specification document of which important sentences are as follows:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;...This specifcation's aim is to define common error formats for applications that need one so that they aren't required to define their own or, worse, tempted to redefine the semantics of existing HTTP status codes. Even if an application chooses not to use it to convey errors, reviewing its design can help guide the design decisions faced when conveying errors in an existing format...&lt;/p&gt;

&lt;p&gt;...Problem details are not a debugging tool for the underlying implementation; rather, they are a way to expose greater detail about the HTTP interface itself...&lt;/p&gt;

&lt;p&gt;...truly generic problems -- i.e., conditions that might apply to any resource on the Web -- are usually better expressed as plain status codes...&lt;/p&gt;

&lt;p&gt;...an application might have a more appropriate way to carry an error in a format that it already defines. Problem details are intended to avoid the necessity of establishing new "fault" or "error" document formats, not to replace existing domain-specific formats...&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Communication aspects
&lt;/h2&gt;

&lt;p&gt;In the context of HTTP, the first element to consider is the proper representation of the type of information transported:&lt;br&gt;
this also means having a reference to the REST approach and Hypermedia.&lt;br&gt;
The specification adopts two specific media types as representation indicators, also considering the most used standards at the moment, for data transport, namely JSON and XML;&lt;br&gt;
resulting in two registered media types:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;application/problem+json&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;application/problem+xml&lt;/code&gt;
The RFC does not offer particular recommendations for managing other types of media, even if it proposes the concept of "encapsulating information" in other representations, where possible.
This is, for example, the case of HTML5 which has more possibilities for hosting metadata not directly related to rendering web pages (scripts, as for the example that follows, or &lt;a href="http://microformats.org/" rel="noopener noreferrer"&gt;microformats&lt;/a&gt; or &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Microdata" rel="noopener noreferrer"&gt;microdata&lt;/a&gt;).
Here's an example:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"application/problem+json"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt; 
 &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://example.com/probs/out-of-credit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;You do not have enough credit.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;detail&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Your current balance is 30, but that costs 50.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;instance&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/account/12345/msgs/abc&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;balance&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;accounts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/accounts/12345&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/account/67890&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The RFC confirms the use of the &lt;a href="https://www.rfc-editor.org/rfc/rfc9110#section-12.1" rel="noopener noreferrer"&gt;proactive content negotiation&lt;/a&gt; approach.&lt;br&gt;
The communication includes the main HTTP headers valid for content negotiation such as &lt;code&gt;Content-Type&lt;/code&gt;, &lt;code&gt;Accept&lt;/code&gt; but also &lt;code&gt;Accept-Language&lt;/code&gt;, aiming to provide non-binding hints on the language for the texts present in the HTTP responses.&lt;/p&gt;
&lt;h2&gt;
  
  
  What happened to the header problem? A curiosity
&lt;/h2&gt;

&lt;p&gt;One draft of the new specification, initially called RFC 7807bis, introduced the Problem HTTP Header: this would allow a Problem to be shown according to the specification bypassing a response body.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="k"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt; &lt;span class="m"&gt;200&lt;/span&gt; &lt;span class="ne"&gt;OK&lt;/span&gt;
&lt;span class="na"&gt;Content-Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;application/json&lt;/span&gt;
&lt;span class="na"&gt;Problem&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;type="https://example.net/problems/almost-out", title="you're almost out of credit", credit_left=20&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This idea has not been approved, even because it could have introduced protocol inconsistency, &lt;em&gt;e.g.&lt;/em&gt;, what concerning the media type? What concerning the representation: is it an error or an answer?&lt;br&gt;
An alternative to the Problem Header can be the embedding approach or the consideration that the specification does not force migration if a previous solution is already present or the possibility of creating customized problem types.&lt;/p&gt;
&lt;h2&gt;
  
  
  The response body
&lt;/h2&gt;

&lt;p&gt;The specification requires structured content to convey information about errors;&lt;br&gt;
it's worth noting that the non-understanding information, expressed in the body, must not block the activity of a generic HTTP software receiving data, permitting the latter to skip the information unknown.&lt;br&gt;
Different attributes are offered:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbydgjqosbnwluh0jc2bo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbydgjqosbnwluh0jc2bo.png" alt="RFC9457 Body Attributes"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can then have specification-compliant dialogs like in the following example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="nf"&gt;POST&lt;/span&gt; &lt;span class="nn"&gt;/purchase&lt;/span&gt; &lt;span class="k"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt;
&lt;span class="na"&gt;Host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;store.example.com&lt;/span&gt;
&lt;span class="na"&gt;Content-Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;application/json&lt;/span&gt;
&lt;span class="na"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;application/json, application/problem+json&lt;/span&gt;
&lt;span class="s"&gt;{&lt;/span&gt;
&lt;span class="s"&gt; "items": 123456,&lt;/span&gt;
&lt;span class="s"&gt; "quantity": 2&lt;/span&gt;
&lt;span class="s"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="k"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt; &lt;span class="m"&gt;403&lt;/span&gt; &lt;span class="ne"&gt;Forbidden&lt;/span&gt;
&lt;span class="na"&gt;Content-Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;application/problem+json&lt;/span&gt;
&lt;span class="na"&gt;Content-Language&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;en&lt;/span&gt;
&lt;span class="s"&gt;{&lt;/span&gt;
&lt;span class="s"&gt; "type": "https://example.com/probs/out-of-credit",&lt;/span&gt;
&lt;span class="s"&gt; "title": "You do not have enough credit.",&lt;/span&gt;
&lt;span class="s"&gt; "detail": "Your current balance is 30, but that costs 50.",&lt;/span&gt;
&lt;span class="s"&gt; "instance": "/account/12345/msgs/abc",&lt;/span&gt;
&lt;span class="s"&gt; "balance": 30,&lt;/span&gt;
&lt;span class="s"&gt; "accounts": ["/accounts/12345",&lt;/span&gt;
&lt;span class="s"&gt; "/account/67890"]&lt;/span&gt;
&lt;span class="s"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An interesting aspect of the specification is the definition of a default type in case you simply want to report the status code information but in the format provided by the RFC:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;about:blank &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;status&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt; &lt;span class="nx"&gt;related&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;specific&lt;/span&gt; &lt;span class="nx"&gt;HTTP&lt;/span&gt; &lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="nx"&gt;code&lt;/span&gt; &lt;span class="p"&gt;],&lt;/span&gt;
 &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="nx"&gt;related&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;specific&lt;/span&gt; &lt;span class="nx"&gt;HTTP&lt;/span&gt; &lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="nx"&gt;code&lt;/span&gt; &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that the "type" attribute, if not specified, acquires the value &lt;code&gt;about:blank&lt;/code&gt; with all that follows.&lt;br&gt;
The response body of this RFC may have extensions discussed later.&lt;/p&gt;

&lt;h3&gt;
  
  
  The type attribute
&lt;/h3&gt;

&lt;p&gt;It is a mandatory attribute, expressed as a URI that identifies the type of problem.&lt;br&gt;
The value of this attribute can be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;about:blank&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;&lt;code&gt;URI Locator&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;URI Tag&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the attribute value is a URI Locator, then it is strongly recommended that dereferencing it results in human-readable documentation for the type of problem.&lt;br&gt;
Clients should not dereference the locator automatically but only as needed to provide documentation to developers.&lt;br&gt;
If the attribute value is a Tag URI, &lt;em&gt;e.g.&lt;/em&gt;, &lt;code&gt;tag:example@example.org,2021-09-17:OutOfLuck&lt;/code&gt;, it is not dereferenceable and uniquely represents the different types of problems.&lt;br&gt;
Using a URI to have a unique ID is not recommended especially from the point of view of integration and use of tools for which providing further information at the Developer Experience level is a fundamental objective.&lt;br&gt;
The locator must use absolute rather than relative URIs to avoid confusion and malfunctions&lt;/p&gt;

&lt;h3&gt;
  
  
  The status attribute
&lt;/h3&gt;

&lt;p&gt;It is an optional attribute that has an informative nature.&lt;br&gt;
When created it must report the same status code defined in the HTTP response and its purpose is to allow Consumers to be aware of the original status code possibly modified by an HTTP intermediary.&lt;br&gt;
Being a duplicate in the HTTP response code value, this attribute can be a point of attack if used without awareness.&lt;/p&gt;

&lt;h3&gt;
  
  
  The title attribute
&lt;/h3&gt;

&lt;p&gt;It is a mandatory attribute that has an informative nature for all those users who do not know or cannot know the semantics of the problem expressed by the URI of the type attribute.&lt;br&gt;
The value of this attribute is strongly recommended to remain constant between one occurrence and another of the problem, except for possible localization needs.&lt;/p&gt;

&lt;h3&gt;
  
  
  The detail attribute
&lt;/h3&gt;

&lt;p&gt;It is an optional attribute containing a human-readable explanation of the specific occurrence of the problem.&lt;br&gt;
It’s highly recommended that the value of this attribute does not contain technical information for debugging purposes which instead can be introduced in extension attributes: this attribute should therefore not be subject to particular manipulations.&lt;br&gt;
This is also a point to remember for security purposes to reduce the amount of information in transit that aids API attacks.&lt;/p&gt;

&lt;h3&gt;
  
  
  The instance attribute
&lt;/h3&gt;

&lt;p&gt;It is an optional attribute containing a URI that identifies the specific occurrence of the problem.&lt;br&gt;
The value of this attribute can be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;URI Locator&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;URI Tag&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When the URI is a dereferenceable locator, the problem details object can be retrieved from it.&lt;br&gt;
It may also return information about the problem occurrence in other formats through the use of proactive content negotiation.&lt;br&gt;
When the URI is a Tag (non-dereferenceable), it serves as a unique identifier for the problem occurrence which may be meaningful to the server but is opaque to the client.&lt;br&gt;
As for the type attribute, absolute rather than relative addresses are to be preferred.&lt;/p&gt;

&lt;h3&gt;
  
  
  Extension members
&lt;/h3&gt;

&lt;p&gt;It is possible to customize the body of a response with other attributes that offer more details about the problem that has occurred.&lt;br&gt;
The specification does not contain particular rules to limit these extensions, except for adherence to the media type and relative naming of reference, but it highlights how these can be entirely avoided by a client:&lt;br&gt;
unrecognized extensions must be ignored and therefore not block management of the answer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Handling multiple problems
&lt;/h2&gt;

&lt;p&gt;What does multiple problems mean? Who are they referring to? Can they happen?&lt;/p&gt;

&lt;p&gt;The answers come from analyzing some coordinates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To what (which is the subject) the errors found refer&lt;/li&gt;
&lt;li&gt;How to represent a set of errors&lt;/li&gt;
&lt;li&gt;Which errors are priority or not&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;RFC 9457 clarifies and responds with simple and immediately adoptable concepts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A response of type Problem Details refers to a specific type,  declared in the same, for which there may be multiple problems that must refer to the same resource (type) of the issued request.
The presence of JSON among the main formats allows support for &lt;a href="https://www.rfc-editor.org/info/rfc6901" rel="noopener noreferrer"&gt;JSON Pointers&lt;/a&gt; to highlight the parts of the Json document that are affected by errors.&lt;/li&gt;
&lt;li&gt;A set of errors defined, in the reference media type, thanks to the  concept of body extensions (Extension Members): those additional  attributes of the response body, are possible in the respect of the specification itself
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="nf"&gt;POST&lt;/span&gt; &lt;span class="nn"&gt;/details&lt;/span&gt; &lt;span class="k"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt;
&lt;span class="na"&gt;Host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;account.example.com&lt;/span&gt;
&lt;span class="na"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;application/json&lt;/span&gt;
&lt;span class="s"&gt;{&lt;/span&gt;
&lt;span class="s"&gt; "age": 42.3,&lt;/span&gt;
&lt;span class="s"&gt; "profile": { "color": "yellow" }&lt;/span&gt;
&lt;span class="s"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="k"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt; &lt;span class="m"&gt;422&lt;/span&gt; &lt;span class="ne"&gt;Unprocessable Content&lt;/span&gt;
&lt;span class="na"&gt;Content-Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;application/problem+json&lt;/span&gt;
&lt;span class="na"&gt;Content-Language&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;en&lt;/span&gt;
&lt;span class="s"&gt;{&lt;/span&gt;
&lt;span class="s"&gt; "type": "https://example.net/validation-error",&lt;/span&gt;
&lt;span class="s"&gt; "title": "Your request is invalid.",&lt;/span&gt;
&lt;span class="s"&gt; "errors": [&lt;/span&gt;
&lt;span class="s"&gt;   { "detail": "must be a positive integer", "pointer": "#/age" },&lt;/span&gt;
&lt;span class="s"&gt;   { "detail": "must be 'green', 'red' or 'blue'", "pointer": "#/profile/color" }&lt;/span&gt;
&lt;span class="s"&gt;  ]&lt;/span&gt;
&lt;span class="s"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The creation of a set of errors that do not concern the same type becomes strongly discouraged;
this implies that of the possible errors, relating to different types, only the one considered a priority (relevant or urgent) is reported consistently with the above.
It should also be remembered that if a format already exists for specific application needs, it is not required to convert to the RFC format.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The proposed vision, in the presence of multiple problems, may seem limiting but it is a balancing point between protocol cleanliness, representation effectiveness, and tool support.&lt;/p&gt;

&lt;p&gt;In the deprecated RFC 7807, the use of the HTTP 207 status code was proposed, which allows you to report multiple statuses and errors in the same body. This solution, technically convenient, can lead to ambiguity and also reopens the issue of multi-request and multi-response which are not concepts natively provided for in the HTTP protocol.&lt;/p&gt;

&lt;h2&gt;
  
  
  The importance of the type
&lt;/h2&gt;

&lt;p&gt;The specification highlights the idea of type related to a specific problem thus allowing two essential evolutions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The ability to define custom types&lt;/li&gt;
&lt;li&gt;The possibility of recording types of Problems in favor of their reuse where appropriate&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The concept of type is significant and requires careful planning and the need to follow rules.&lt;br&gt;
Such perspective leads to a balanced use of the specification and the possibility of improving and enriching the automation, and therefore supporting with products, of API design.&lt;/p&gt;

&lt;p&gt;Defining custom problems involves documenting:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A specific URI that is relative to the type, this URI is preferable to be a locator and therefore dereferenceable in the documentation that indicates how to approach the problem&lt;/li&gt;
&lt;li&gt;A title that briefly and appropriately describes the problem&lt;/li&gt;
&lt;li&gt;The indication of the HTTP status code with which the type of problem is supposed to be related.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A custom type can have extensions (which must follow naming rules) and can use the Retry-After response header (if appropriate). The reference to Web Linking is interesting as a possibility to be used in extensions to refer to other resources and address the problem in question.&lt;/p&gt;

&lt;p&gt;The registration of a new problem, in the registry provided for this specification at the address &lt;a href="https://iana.org/assignments/http-problem-types" rel="noopener noreferrer"&gt;https://iana.org/assignments/http-problem-types&lt;/a&gt;, involves the use of a reference template, a possibly usable prefix URI, and the submission of a request to a group of experts for the validation of the proposition.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This new specification defines better support to obtain the order, conceptual cleanliness, and appeal in the significant market of APIs. RFC 9457 is conceptually simple but offers the elements to operate on almost all the use cases that can be experienced. It’s one of more components, the HTTP API RFCs, that should not be seen in isolation but moved in the continuous trade-off of own development/integration needs and efforts to be open and flexible in a market full of initiatives and possible new tools.&lt;/p&gt;

&lt;h3&gt;
  
  
  to go further
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://datatracker.ietf.org/doc/rfc9457/" rel="noopener noreferrer"&gt;RFC 9457&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://datatracker.ietf.org/doc/rfc7807/" rel="noopener noreferrer"&gt;RFC 7807 (previous RFC)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ietf.org/archive/id/draft-ietf-httpapi-rfc7807bis-04.html" rel="noopener noreferrer"&gt;RFC 7807bis &amp;amp; The Problem Header&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.frankel.ch/structured-errors-http-apis/" rel="noopener noreferrer"&gt;Structured error messages for HTTP APIs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.rfc-editor.org/info/rfc4151" rel="noopener noreferrer"&gt;Tag URI Scheme&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://datatracker.ietf.org/doc/rfc8141/" rel="noopener noreferrer"&gt;URN RFC&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.rfc-editor.org/rfc/rfc9110" rel="noopener noreferrer"&gt;HTTP Semantics RFC&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://evertpot.com/http/207-multi-status" rel="noopener noreferrer"&gt;HTTP Status Code 207&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=UNdUjBqsUqg" rel="noopener noreferrer"&gt;Representing Problem Details in HTTP APIs: An Introduction to RFC 7807&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/zalando/problem" rel="noopener noreferrer"&gt;Zalando RFC 7807 Java Implementation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>rfc</category>
      <category>api</category>
      <category>http</category>
    </item>
    <item>
      <title>A Retrospective on Error Management: Where Do We Go From Here?</title>
      <dc:creator>Stefano Fago</dc:creator>
      <pubDate>Tue, 21 Nov 2023 09:18:42 +0000</pubDate>
      <link>https://dev.to/stefanofago73/a-retrospective-on-error-management-where-do-we-go-from-here-4ffn</link>
      <guid>https://dev.to/stefanofago73/a-retrospective-on-error-management-where-do-we-go-from-here-4ffn</guid>
      <description>&lt;p&gt;Error management is a fact of life in software development as it is often &lt;em&gt;inevitable&lt;/em&gt; and generated by different causes that also include &lt;em&gt;incorrect or incomplete understanding of the requirements&lt;/em&gt; or even lack of knowledge of some tools or elements used during development.&lt;/p&gt;

&lt;p&gt;Let’s go on a &lt;em&gt;small trip&lt;/em&gt; into the evolutions and different concepts related to error management, analyzing why it is difficult and why we are going in new directions after the moment of Exceptions in programming languages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Error management philosophy in the ages
&lt;/h2&gt;

&lt;p&gt;In languages such as C and C++, error handling was primarily based on return codes: specific values indicate the &lt;em&gt;success&lt;/em&gt; or &lt;em&gt;failure&lt;/em&gt; (&lt;strong&gt;sentinel value&lt;/strong&gt;). This approach required the caller to check the return code, which could be ignored explicitly, and the control flow became convoluted due to the numerous checks scattered throughout the code base.&lt;/p&gt;

&lt;p&gt;The notion of exception was introduced to address these challenges. The idea was to transfer the responsibility of error handling from the caller to a designated exception handler. When an exceptional situation arises, the runtime system throws an exception, which must be caught and handled by appropriate code. The introduction of already allocated exception handlers, like in Java, made it possible to catch/process Exceptions even if the system runs out of memory.&lt;/p&gt;

&lt;p&gt;In recently defined programming languages (&lt;em&gt;i.e.,&lt;/em&gt;, Rust, Go, Zig), we return to the dichotomy: &lt;em&gt;exception vs. error&lt;/em&gt;. The distinction between &lt;strong&gt;recoverable&lt;/strong&gt; and &lt;strong&gt;non-recoverable&lt;/strong&gt; errors is considered.&lt;br&gt;
Unrecoverable ones lead to unmanageable software crashes. Those defined as recoverable return to being values, not primitive types, managed in the standard functionality code. There are no exceptions to throw, the&lt;br&gt;
compiler forces handling, and no longer specific scopes to place management code. These values are supported by dedicated constructs and, in some cases, strongly inspired by functional programming.&lt;/p&gt;

&lt;p&gt;The transition to the Cloud has also altered the vision of error management. From the concept of robustness, we have increasingly migrated to considerations linked to the resilience of a system.&lt;br&gt;
Furthermore, the usefulness of stack traces has been partly questioned: more distributed code, as well as the emphasis on &lt;strong&gt;Observability&lt;/strong&gt;, makes simpler and more timely information necessary compared to the&lt;br&gt;
habit of examining &lt;strong&gt;deep stack traces&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why Exceptions aren’t enough?
&lt;/h2&gt;

&lt;p&gt;When we think about using exceptions, there’s the habit of considering different problems to address:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;If generated by the runtime, we must catch them to avoid the collapse&lt;br&gt;
of the system&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Some exceptions become part of the signature of a method or function,&lt;br&gt;
also defining an increase in the coupling level to consider&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;By its nature, the handling of an exception breaks the flow of&lt;br&gt;
execution. Without the right design, the specialized handler increases&lt;br&gt;
cognitive overload or lowers the readability of the code base.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can open a parenthesis relating to the widespread adoption of Runtime exceptions compared to other types, especially in general-purpose frameworks. It may be a misstep justified by the typical design of the frameworks themselves: operating with &lt;em&gt;decoration&lt;/em&gt; or &lt;em&gt;proxying&lt;/em&gt; patterns seems a natural choice for the use of &lt;em&gt;Runtime exceptions&lt;/em&gt; also if it pushes for a precise knowledge of the framework, &lt;strong&gt;increasing the cognitive load&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: &lt;br&gt;
The need to reduce the exceptions thrown directly by the runtime is addressed today in new languages in the continuous effort to limit low-level error conditions linked to memory usage, concurrency, or I/O. We have safer languages but also the promise of evolution &lt;a href="https://thenewstack.io/bjarne-stroustrups-plan-for-bringing-safety-to-c/"&gt;regarding languages such as C++&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  But is it all the fault of the Exceptions?
&lt;/h2&gt;

&lt;p&gt;What is our role, as software creators, about Errors?&lt;/p&gt;

&lt;p&gt;An intriguing &lt;a href="https://www.youtube.com/watch?v=AnZ0uTOerUI"&gt;sentence comes from Michael Feathers&lt;/a&gt; reporting that Errors are just conditions we refuse to take seriously. So, what is the percentage value dedicated to the study error conditions and/or error management?&lt;/p&gt;

&lt;p&gt;To understand what is occurring, we should consider that error management is conditioned by &lt;em&gt;macroscopic aspects&lt;/em&gt;, that we often don’t think about holistically, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The analysis of requirements and their level of volatility&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How we design for software modularity (decoupling and cohesion)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Performance and the impact of error management on it&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The development experience, and therefore the readability of the code&lt;br&gt;
base, but also the awareness of the context in which it is being&lt;br&gt;
produced&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Another classification we often don’t notice is the one that sees error management &lt;strong&gt;locally&lt;/strong&gt; or &lt;strong&gt;at the edges of a system&lt;/strong&gt;. Software design continuously alternates a &lt;strong&gt;complexity seen locally&lt;/strong&gt; (a class, for example) or that &lt;strong&gt;is seen at the system level&lt;/strong&gt; or between different systems.&lt;/p&gt;
&lt;h2&gt;
  
  
  Exceptions are for exceptional cases
&lt;/h2&gt;

&lt;p&gt;When should exceptions be used? The classical answer is: &lt;strong&gt;&lt;em&gt;In the presence of exceptional cases!&lt;/em&gt;&lt;/strong&gt; But what does it mean? The sentence is &lt;em&gt;cryptic&lt;/em&gt; from a practical point of view, and when it is our duty, it becomes rather complicated.&lt;/p&gt;

&lt;p&gt;If we consider &lt;strong&gt;&lt;em&gt;Modularity&lt;/em&gt;&lt;/strong&gt;, we should have exceptions strictly linked to the dysfunctions that classes can present within a single module. At the same time, if we assume the collaboration between multiple modules, the errors we wanted to define must be part of something shared between the various modules. It’s necessary to study which are those cases where the stability of an ecosystem is disturbed by invalid states and express them accordingly.&lt;/p&gt;

&lt;p&gt;If we consider &lt;strong&gt;&lt;em&gt;Performance&lt;/em&gt;&lt;/strong&gt;, we should strive to have a limited number of exceptions thrown: creating and processing Exceptions can be expensive, mainly if they occur too frequently. Defining all error situations only on Exceptions does not consider the performance aspects, as well as increasing the cognitive load factor, and it is for this reason that the advice &lt;strong&gt;&lt;em&gt;&lt;em&gt;not to use the exception for the control flow&lt;/em&gt;&lt;/em&gt;&lt;/strong&gt; is invoked.&lt;/p&gt;

&lt;p&gt;Another hint comes from Bertrand Meyer, who reports to &lt;em&gt;**use exceptions when you cannot know whether a call/invocation will succeed or fail&lt;/em&gt;&lt;em&gt;. This vision justifies the adoption of a &lt;a href="https://en.wikipedia.org/wiki/Design_by_contract"&gt;&lt;strong&gt;&lt;em&gt;design-by-contract&lt;/em&gt;&lt;/strong&gt;&lt;/a&gt; where we consider preconditions, invariants, and post-conditions and where exceptions occur due to their violation. For example, software that delivers a protocol as the target is related to the *&lt;/em&gt;&lt;em&gt;design-by-contract&lt;/em&gt;*&lt;em&gt;; the idea of a *&lt;em&gt;formal contract&lt;/em&gt;&lt;/em&gt; between parts, as &lt;a href="https://www.youtube.com/watch?v=TTM_b7EJg5E"&gt;explained by Joe Armstrong&lt;/a&gt;, can be an influential adoption in defining error conditions in distributed systems.&lt;/p&gt;

&lt;p&gt;It is worth noting that &lt;strong&gt;&lt;em&gt;adopting formal methods&lt;/em&gt;&lt;/strong&gt; to model error conditions is increasing for large-scale system concurrency, and the &lt;a href="https://www.amazon.com/Practical-TLA-Planning-Driven-Development/dp/1484238281/"&gt;adoption of TLA+&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A criterion that we should use, but which we often forget, is to understand the usefulness and objectives of the system: why are we creating this software? &lt;br&gt;
For example, &lt;a href="https://blog.ploeh.dk/2023/06/26/validation-and-business-rules/"&gt;data entry validation can be considered different from applying business rules&lt;/a&gt;: in the first subject, we can avoid exceptions, and in the second subject, we have specific exceptions related to the entities of that domain, and we need to reason about when to stop error management.&lt;/p&gt;
&lt;h2&gt;
  
  
  Start to migrate: what are good practices for Exceptions?
&lt;/h2&gt;

&lt;p&gt;What we have discussed may be valid in general as well as for exceptions, but we can deduce some general suggestions from the book: &lt;a href="https://www.amazon.it/Philosophy-Software-Design-John-Ousterhout/dp/1732102201"&gt;&lt;strong&gt;&lt;em&gt;A Philosophy of Software Design&lt;/em&gt;&lt;/strong&gt; by John Ousterhout&lt;/a&gt;. Summarizing what is proposed by the text, we can distinguish the following cases:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Masking exceptions&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
encapsulating the management of exceptions where they occur so that there is no propagation and so that possible corrective action takes place promptly&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Aggregate the exceptions&lt;/strong&gt;&lt;br&gt;
in contrast to what was said before, it’s suggested to place the actions that can define similar exceptions together to have blocks of instructions to manage in individual handlers&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Not using exceptions&lt;/strong&gt; &lt;br&gt;
avoiding the use of exceptions means replacing them with return values and with explicit management of the returned values&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Eliminate exceptional cases&lt;/strong&gt; &lt;br&gt;
avoid having conditional logic for special cases, &lt;em&gt;i.e.&lt;/em&gt;, for those values &lt;em&gt;at the edges of a domain&lt;/em&gt; or introduced to make up for a sudden requirement. These can lead to unexpected errors and increase the code base's cognitive load.&lt;/p&gt;
&lt;h2&gt;
  
  
  Coordinates to migrate from Exceptions
&lt;/h2&gt;

&lt;p&gt;The last two points start from what we see as a move away from exceptions.&lt;/p&gt;

&lt;p&gt;In this context, Michael Feathers indicates the need to &lt;a href="https://www.youtube.com/watch?v=3RtLCav0Bp4"&gt;&lt;em&gt;extend our domain&lt;/em&gt;&lt;/a&gt; to avoid the use of exceptions: this means reworking the problem to bypass or limit the presence of errors as much as possible thanks to hints like &lt;a href="https://medium.com/vattenfall-tech/tell-dont-ask-learn-to-talk-to-your-objects-45d7c4aa61fe"&gt;&lt;em&gt;Tell don't Ask&lt;/em&gt;&lt;/a&gt;. As an example, the author reformulates the suggestion from a data point of view, revealing that "asking for data" can fail while providing it, when we have it, cannot!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Source&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;withData&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;ID&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;someOperation&lt;/span&gt;&lt;span class="o"&gt;(...))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can see that error handling is hidden and has a limited scope due to how we operate on the data.&lt;/p&gt;

&lt;p&gt;It becomes essential again to have a way to express the error condition without taking control away from the Developer. For this purpose, it is&lt;br&gt;
reasonable to rely on the &lt;strong&gt;Type System&lt;/strong&gt; and support for &lt;strong&gt;Generics&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Avoiding the use of null both as a return value and as a sentinel value, patterns such as the &lt;strong&gt;NullObject&lt;/strong&gt;, containers such as &lt;strong&gt;Optionals&lt;/strong&gt;, use&lt;br&gt;
of &lt;strong&gt;Default Values&lt;/strong&gt; or functions, and encapsulating communications in an &lt;strong&gt;event approach&lt;/strong&gt; are starting points that need to be revised.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Constructs from Functional Programming&lt;/strong&gt; have been embraced in&lt;br&gt;
programming languages (Optional, Either, Try Monad, &lt;a href="https://fsharpforfunandprofit.com/rop/"&gt;Railway Oriented&lt;br&gt;
Programming&lt;/a&gt;, Structural Pattern Matching) where the importance of expressions is highlighted compared to statements.&lt;/p&gt;

&lt;p&gt;We can see more of the concepts exposed in the Rust language.&lt;/p&gt;

&lt;p&gt;The Result type is not only a Union Type but supports a series of methods that allow error management to be expressed as a &lt;strong&gt;Fluent API&lt;/strong&gt; and to &lt;strong&gt;transform&lt;/strong&gt; the &lt;em&gt;Result&lt;/em&gt; outcome in an Optional or using mapping function. &lt;br&gt;
An interesting aspect is that there is a compiler enforcement on this type that needs to be managed to avoid compilation warnings.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;
&lt;span class="nn"&gt;io&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;stdin&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.read_line&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
           &lt;span class="nf"&gt;.ok&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// We have the new line&lt;/span&gt;
           &lt;span class="nf"&gt;.expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Failed to read a line!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// no new line so we crash with a message&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, to avoid having too much code, the Rust syntax allows you to take advantage of specialized operators to synthesize error expressions, It is also possible to have structured pattern-matching to manage unions or closures to specialize or nest the processing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;greeting_file_result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;File&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hello.txt"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;greeting_file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;greeting_file_result&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nd"&gt;panic!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Problem opening the file: {:?}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compiler support in the case of Rust is also an essential ingredient for error propagation mechanisms and for defining code optimized for example, the presence or absence of stack traces.&lt;/p&gt;

&lt;h2&gt;
  
  
  No Exception at all?
&lt;/h2&gt;

&lt;p&gt;In everyday life, there may be situations where interrupting the flow of an execution can be helpful.&lt;br&gt;
It is interesting what is suggested in the Rust documentation, talking about the use of the &lt;em&gt;panic macro&lt;/em&gt; (which defines a software crash):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;it is acceptable in defining code examples, prototype code, and tests&lt;/li&gt;
&lt;li&gt;it is acceptable when your code can lead to a "bad state". From a design-by-contract perspective, an invalid state occurs when some assumptions, guarantees, contracts, or invariants have been broken:
invalid, contradictory, or missing values are passed to the code.&lt;/li&gt;
&lt;li&gt;it is acceptable for security reasons due to the inappropriate state of the program.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Error management requires attention and care equal to that used to define business logic. It is a complex task, but many reference points and different conceptual tools exist. &lt;br&gt;
Leaving aside trends and partisan discussions, it is better to consider the evolution of the design of error management because they are supported or because they can be adopted by one's language, paying attention to the limits of one's domain and rationalizing the effort in favor of the actual usefulness of the own software.&lt;/p&gt;

&lt;h3&gt;
  
  
  to go further
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt; &lt;a href="https://blog.frankel.ch/error-handling/"&gt;Error handling across different languages&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt; &lt;a href="https://thenewstack.io/bjarne-stroustrups-plan-for-bringing-safety-to-c/"&gt;Bjarne Stroustrup’s Plan for Bringing Safety to C++&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt; &lt;a href="https://www.youtube.com/watch?v=AnZ0uTOerUI"&gt;Unconditional Code&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt; &lt;a href="https://www.youtube.com/watch?v=3RtLCav0Bp4"&gt;Error Elimination as a Design Driver - Michael Feathers&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt; &lt;a href="https://en.wikipedia.org/wiki/Design_by_contract"&gt;Design By Contract (Wikipedia)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt; &lt;a href="https://www.youtube.com/watch?v=TTM_b7EJg5E"&gt;The Do's and Don'ts of Error Handling&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt; &lt;a href="https://www.amazon.com/Practical-TLA-Planning-Driven-Development/dp/1484238281/"&gt;"Practical TLA+: Planning Driven Development"&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt; &lt;a href="https://www.amazon.it/Philosophy-Software-Design-John-Ousterhout/dp/1732102201"&gt;A Philosophy of Software Design&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt; &lt;a href="https://medium.com/vattenfall-tech/tell-dont-ask-learn-to-talk-to-your-objects-45d7c4aa61fe"&gt;"Tell, Don’t Ask - Learn to Talk to Your Objects"&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt; &lt;a href="https://fsharpforfunandprofit.com/rop/"&gt;Railway Oriented Programming&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt; &lt;a href="https://doc.rust-lang.org/book/ch09-00-error-handling.html"&gt;Error Handling in Rust&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt; &lt;a href="https://www.youtube.com/watch?v=G4CNV2ctpzo"&gt;"Always Be Running: Long-Running and Fault-Tolerant Java Services"&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt; &lt;a href="https://medium.com/@tyrion85/monadic-error-handling-in-java-a207ce01559"&gt;Monadic Error Handling in Java&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt; &lt;a href="https://www.youtube.com/watch?v=rJ-Ihh7RNao"&gt;"Exceptions: I’m Telling You for the Last Time"&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>design</category>
      <category>errormanagment</category>
      <category>languages</category>
      <category>learning</category>
    </item>
  </channel>
</rss>
