<?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>Forem: Maow</title>
    <description>The latest articles on Forem by Maow (@maow).</description>
    <link>https://forem.com/maow</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%2F176130%2F73c40bf3-4da8-4f8c-9737-6d48fccc82f6.png</url>
      <title>Forem: Maow</title>
      <link>https://forem.com/maow</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/maow"/>
    <language>en</language>
    <item>
      <title>Computers, explained by a nerd.</title>
      <dc:creator>Maow</dc:creator>
      <pubDate>Thu, 04 Apr 2024 12:50:40 +0000</pubDate>
      <link>https://forem.com/maow/computers-explained-by-a-nerd-2abp</link>
      <guid>https://forem.com/maow/computers-explained-by-a-nerd-2abp</guid>
      <description>&lt;p&gt;Today, a close friend of mine asked me a compelling question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How the &lt;em&gt;F***&lt;/em&gt; did we make tiny patterns of electricity do all of &lt;em&gt;THIS.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I answered with a tangent about the foundations of computer systems. This is that, but I felt it necessary to be more eloquent.&lt;/p&gt;

&lt;p&gt;All jokes aside, welcome to the world of computing! It's the closest thing we have to magic in this world; it's just that we use numbers instead of mana... &lt;em&gt;lots of numbers.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Circuitry
&lt;/h2&gt;

&lt;p&gt;Everything complex starts from something simple. Everything simple hides a deep complexity. The fundamental components of computers are electronic circuits, devices comprised of their own components, such as logic gates.&lt;/p&gt;

&lt;p&gt;Logic gates allow electrical signals to make decisions. An "AND" gate is referred to as such because it receives two signals and produces a signal if given both signal 1 &lt;em&gt;AND&lt;/em&gt; signal 2. A "NOT" gate will produce the opposite of what it is given. And so on.&lt;/p&gt;

&lt;p&gt;Complex devices, such as latches and multiplexers, can be formed through logic gates. Logic gates and signals are, in fact, at the core of how computers work with numbers and arithmetic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Numbers and Arithmetic
&lt;/h2&gt;

&lt;p&gt;As you're likely aware, Western cultures use the decimal number system, also known as "base 10." This means we use &lt;em&gt;ten&lt;/em&gt; unique digits to represent our numbers: 0 to 9. Computers, on the other hand, use binary, or "base 2." They only have 0 and 1.&lt;/p&gt;

&lt;p&gt;The reason is simple. Think about a computer; it has only two states: On or off. This is a &lt;em&gt;binary&lt;/em&gt; state. An electrical signal can be present or absent.&lt;/p&gt;

&lt;p&gt;In binary, we form weightier numbers by joining bits. Each bit represents a number, and we add the number of every "present" bit together. Specifically, we start with the least significant bit, which has the value of &lt;em&gt;one&lt;/em&gt; when present and is the rightmost bit; therefore, we read from right to left.&lt;/p&gt;

&lt;p&gt;With computers, we group bits into octets, pairs of eight, and we refer to these as bytes. A byte is the tiniest unit of information we can save or retrieve, but not the only unit. By grouping &lt;em&gt;bytes&lt;/em&gt;, higher capacity numbers are made.&lt;/p&gt;

&lt;p&gt;Since our numbers are bits, we can manipulate them like electrical signals. Through logic gates, we can create adders. Adders, as the name implies, add bits.&lt;/p&gt;

&lt;h2&gt;
  
  
  Components of a Computer
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Central Processing Unit (CPU), or &lt;strong&gt;processor&lt;/strong&gt;: The CPU is the brain and nervous system of the computer. It does most of the complex work and coordinates most components together.&lt;/li&gt;
&lt;li&gt;Motherboard: The motherboard is a large circuit board that serves as the "body" of the computer. It allows parts to communicate with one another, like nerves, and it provides system information and firmware.

&lt;ul&gt;
&lt;li&gt;Firmware is a bundle of code given to the processor by the motherboard when the computer powers on. It sets up the machine so the operating system, e.g. Windows or macOS, can begin operating.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Random Access Memory (RAM) or &lt;strong&gt;memory&lt;/strong&gt;: Cards that comprise the computer's working memory. Memory is a huge list of bytes, where each byte has a position, also known as an "address," like a person's particular home address. When visiting certain, special addresses, signals may be redirected to other components by the motherboard. This is known as "memory-mapped input/output" and is how the processor communicates with much of the system. RAM is volatile, meaning when it loses power, its contents are lost.&lt;/li&gt;
&lt;li&gt;Storage Disk, or &lt;strong&gt;disk&lt;/strong&gt;: Disks contain memory, similar to RAM, but with the added benefit that their memory is persistent. However, disks are often slower for the processor to access than RAM since the signals must travel farther.&lt;/li&gt;
&lt;li&gt;Graphics Processing Unit (GPU), or &lt;strong&gt;graphics processor&lt;/strong&gt;: The GPU helps display graphics on your screens by performing many operations simultaneously. It isn't as sophisticated as the CPU, but it &lt;em&gt;is&lt;/em&gt; faster at simple operations. It has its own memory, "video RAM."&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Instructions
&lt;/h2&gt;

&lt;p&gt;For a computer to be useful, we need the ability to give instructions to the processor. To do so, we provide a group of bytes subject to a specialized format known as an &lt;em&gt;instruction set architecture.&lt;/em&gt; For educational purposes, I'll be working with a fictional, simplified architecture.&lt;/p&gt;

&lt;p&gt;At the beginning of our instruction, we have a byte specifying the instruction we're dealing with. This is known as the "opcode." Let's introduce the basic opcodes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0 = Add      ("add")
1 = Subtract ("sub")
2 = Multiply ("mul")
3 = Divide   ("div")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, these instructions need some numbers to work with. Addition is a binary operation, meaning it requires two numbers. Let's put them directly after the opcode:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"1 + 1" correlates to: [0, 1, 1]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can now provide this to our processor and it will handle our instruction. Where does the sum go, though? Simple!&lt;/p&gt;

&lt;h2&gt;
  
  
  Registers
&lt;/h2&gt;

&lt;p&gt;The processor has several "registers," which are memory cells capable of keeping a single value. When the processor performs an operation, the result of that operation is likely to go into a register. Some registers are also used for special purposes, but we'll cover those more soon.&lt;/p&gt;

&lt;p&gt;Let's say that the sum of our previous addition operation ended up in an "accumulator" register. We'll label it &lt;code&gt;ACC&lt;/code&gt;. We can use registers within instructions, extracting their values.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"2 * ACC" correlates to: [2, 2, ACC]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since the product is stored in &lt;code&gt;ACC&lt;/code&gt;, &lt;code&gt;ACC&lt;/code&gt; is now &lt;code&gt;4&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If we want to store more than just a few bytes but rather a collection of subsequent bytes, we'll have to use something with a much higher capacity, like memory.&lt;/p&gt;

&lt;h2&gt;
  
  
  Memory
&lt;/h2&gt;

&lt;p&gt;Let's say we have a person and this person has a name and age. We can represent this person with bytes by breaking them down into a "name" and "age" value.&lt;/p&gt;

&lt;p&gt;First, to store their name, we need a text encoding. A text encoding is a format of storing letters, numbers, symbols, etc. as bytes for use in computer programs.&lt;br&gt;
Commonly, we use ASCII or Unicode, but let's just say 0 to 25 represents the letters of the Latin alphabet, where a byte corresponds to a letter, i.e. &lt;code&gt;0 = A&lt;/code&gt;, &lt;code&gt;1 = B&lt;/code&gt;, and so on. This series of bytes is usually referred to as an "array."&lt;/p&gt;

&lt;p&gt;Additionally, we need some way to say how long our text is. So, let's just store the length directly as a prefix!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"MAOW" correlates to [4, 12, 0, 14, 22]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the person's age, let's just use a normal byte for simplicity.&lt;/p&gt;

&lt;p&gt;And so, with all that in mind, if we were to store the person in memory we would just store their name and then subsequently their age, right? Correct. Let's give the age the label of "age" and the name "name."&lt;/p&gt;

&lt;p&gt;But wait... if we have the address of "name," the byte at its beginning, then we actually have the memory address of the person, since name is at the beginning of the person.&lt;/p&gt;

&lt;p&gt;This means that this person we've been talking about is a &lt;em&gt;struct.&lt;/em&gt; A struct, short for structure, is a group of fields, which are named values. By composing structs, we can represent complex concepts with bytes!&lt;/p&gt;

&lt;h2&gt;
  
  
  Jumping!
&lt;/h2&gt;

&lt;p&gt;If the instructions we give to a processor are bytes, then does that mean we can store instructions in memory? Yes, absolutely. In fact, operating systems copy-paste programs into memory and then provide the processor with their addresses, allowing the processor to read instruction by instruction like a list.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tangent:&lt;/strong&gt; Any data that the program might need to operate correctly is also stored as part of the program if not as a separate file. The data just lives outside of the "code section" of the file, which has our instructions, and instead in the "data section." This is what an &lt;code&gt;.exe&lt;/code&gt; file facilitates, if you've ever wondered.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Each instruction begins at a certain address, and we can use that to our advantage by introducing new "jump" instructions. A jump simply tells the processor to jump forward or backwards to a different instruction using the address of that instruction.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;4 = Jump ("jmp")
5 = Jump If Not Zero ("ifnz")
6 = Jump If Zero ("ifz")
7 = Test ("test")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Hold on, wait. What're those "if" and "test" instructions?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Let's back up just a bit (badum tss). First, we covered logic gates a while ago, but I neglected to mention we can use operations like "AND" with bytes. These are referred to as "bitwise operations," since they work with the bits of the byte, rather than the byte itself. AND-ing a byte with another byte simply lines the bytes up and applies the AND to each pair of bits.&lt;/p&gt;

&lt;p&gt;Secondly, one of the special registers that a processor might have is the FLAGS register, which states a bunch of useful "flags" usually related to an operation or the processor itself. To set these flags, we'll be using the test instruction.&lt;/p&gt;

&lt;p&gt;The test instruction ANDs two numbers and produces flags from the result of that AND. If we provide the test instruction with the same number twice, we can simply get the flags for that number as the AND won't affect it.&lt;/p&gt;

&lt;p&gt;The main flag we're after is the zero flag, which states whether the tested number was zero. This is how "jump if not zero" works! That instruction will only jump to the specified instruction address if the zero flag didn't return positive. This is called a conditional branch, or just condition, and is essential for complex tasks.&lt;/p&gt;

&lt;h2&gt;
  
  
  (Sub)routines
&lt;/h2&gt;

&lt;p&gt;Somewhere in our journey, we migrated from the realm of circuitry to the realm of software. Everything you run on your computer is software, including your operating system which helps manage your applications and system resources, and as defined before, a program is a list of instructions, but the proper term for this would be a "routine."&lt;/p&gt;

&lt;p&gt;Therefore, what's a &lt;em&gt;subroutine?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A subroutine is a routine that within a routine, usually to isolate some code so we can jump to it to re-use it at any time, rather than repeating the same code over and over.&lt;/p&gt;

&lt;p&gt;Some subroutines expect us to provide them with values prior to running them, much like instructions do, and some subroutines will provide us with values once they've finished running.&lt;/p&gt;

&lt;p&gt;To provide these values we store them either in general-purpose processor registers or in memory. Once a subroutine is done, it will do the same with its return values and then jump back &lt;em&gt;to&lt;/em&gt; where we jumped &lt;em&gt;from.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Programming Languages
&lt;/h2&gt;

&lt;p&gt;To sum them up briefly: Code written in a language is simply specially formatted bytes that get interpreted by another program which generates a program the processor can actually read. By representing these complicated "features" in text, we make it much more approachable and understandable for humans, as well as potentially safer and faster.&lt;/p&gt;

&lt;p&gt;All programming languages are different in some way, just like all natural languages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing
&lt;/h2&gt;

&lt;p&gt;Aren't computers really f***ing cool? We've gotten to a point in history where we don't even realize everything happening in our metal boxes is just electrical signals.&lt;/p&gt;

&lt;p&gt;These signals represent numbers, which are used to represent abstract concepts and data. Images and sounds become numbers, which we can transmit to people hundreds of kilometers away through the internet.&lt;/p&gt;

&lt;p&gt;Hope you had fun :D&lt;/p&gt;

</description>
      <category>programming</category>
      <category>beginners</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Alternative Views of Software Ecosystems</title>
      <dc:creator>Maow</dc:creator>
      <pubDate>Wed, 20 Sep 2023 11:07:58 +0000</pubDate>
      <link>https://forem.com/maow/alternative-views-of-software-ecosystems-1792</link>
      <guid>https://forem.com/maow/alternative-views-of-software-ecosystems-1792</guid>
      <description>&lt;p&gt;For the longest time, software ecosystems have been dominated by one concept. &lt;strong&gt;Libraries.&lt;/strong&gt; There is nothing wrong with the concept of redistributable packages. Such an idea is what allows any developer to build almost any application...&lt;/p&gt;

&lt;p&gt;but is there a better way? That's what I wish to share my thoughts on: &lt;em&gt;the idea that we can build any application with ease, as long as we think about our ecosystems the right way.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Abstractions
&lt;/h2&gt;

&lt;p&gt;Abstractions are one of the most core concepts when it comes to software, the idea of taking complex, sometimes unintuitive logic and providing a view of it which is simple and intuitive.&lt;/p&gt;

&lt;p&gt;This is most prevalent as &lt;em&gt;programming languages&lt;/em&gt;, which give us developers the ability to fluently, easily express our logic and data types, minimizing errors, oversights, and difficulties.&lt;/p&gt;

&lt;p&gt;I believe there are multiple types of abstractions in today's environment.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hardware Abstractions:&lt;/strong&gt; Abstracting over low-level hardware calls. Examples include graphics drivers, kernels, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Platform Abstractions:&lt;/strong&gt; Abstracting over the user's platform elements, e.g. architecture and operating system. Examples include graphics APIs (DirectX, Metal), windowing libraries (&lt;a href="https://www.libsdl.org"&gt;SDL&lt;/a&gt;, &lt;a href="https://github.com/rust-windowing/winit"&gt;winit&lt;/a&gt;), programming languages, etc. These can allow developers to write &lt;em&gt;cross-platform software.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Software Abstractions:&lt;/strong&gt; Abstracting over platform abstractions or, in a recursive fashion, software abstractions. Examples include GUI libraries (&lt;a href="https://www.qt.io"&gt;Qt&lt;/a&gt;, &lt;a href="https://www.gtk.org"&gt;GTK&lt;/a&gt;), HTTP servers, etc. These can allow developers to write &lt;em&gt;simple software,&lt;/em&gt; and also serve &lt;em&gt;cross-platform software.&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Monolithic Libraries
&lt;/h2&gt;

&lt;p&gt;Abstractions are often &lt;strong&gt;monolithic.&lt;/strong&gt; This means they are singular units that cover a large surface area. The most prevalent form of monolithic library is a framework.&lt;/p&gt;

&lt;h3&gt;
  
  
  Problems
&lt;/h3&gt;

&lt;p&gt;Say you wanted to write your own HTTP server that supports HTTP/1, HTTP/2, HTTP/3, TLS, etc.? This is &lt;em&gt;quite&lt;/em&gt; the feat! You would need to write much code yourself, and HTTP grows larger and larger by the day, so your library would eventually grow too outdated if left unmaintained.&lt;/p&gt;

&lt;p&gt;It is &lt;em&gt;much&lt;/em&gt; more convenient to work with libraries that provide a fully-fledged, albeit somewhat complex HTTP server, and to build a software abstraction over that server.&lt;/p&gt;

&lt;p&gt;This is the approach followed nowadays by libraries like Express (built on top of Node.js's &lt;code&gt;http&lt;/code&gt; module), and Rust's own HTTP ecosystem, most of which is built on the Tower middleware system and Hyper client/server implementation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But... what if we decided we wanted to customize the HTTP parser?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Depending on the library, this is possible, but wouldn't it just be easier to tweak the existing parser a little, or perhaps replace it with one that is more suited to our needs? Unfortunately, this means we would either need some type of plugin system (which can cause our program to become slower and possibly more complex) or we would need to &lt;em&gt;fork the project&lt;/em&gt; which incurs a higher maintenance cost as we would need to be up-to-date with upstream!&lt;/p&gt;

&lt;h2&gt;
  
  
  Component Libraries
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Component libraries&lt;/strong&gt; are a concept that would help us achieve this goal. Rather than create an HTTP framework that includes parsing, writing, transport, routing, etc. We split each feature into a component library, i.e. a &lt;strong&gt;non-monolithic&lt;/strong&gt; software abstraction, meaning it does one thing, does it well, and can be swapped out by a library consumer.&lt;/p&gt;

&lt;p&gt;Rather than creating frameworks, we are essentially delegating the work of combining each component to the library consumer, i.e. a person developing a &lt;strong&gt;monolithic library&lt;/strong&gt; (monolithic software abstraction) or an application developer.&lt;/p&gt;

&lt;p&gt;This may sound complicated, as we are requiring our library consumers to put in more work, but it's actually the contrary. As implied in the last sentence, monolithic libraries exist for general-purpose needs, i.e. when someone just needs something to work.&lt;/p&gt;

&lt;p&gt;Additionally, the combination of these component libraries should be simple enough! Almost comparable to just using a regular monolithic library, even. If we need more complexity, i.e. the existing options just don't cut it in terms of features, we can replace a component library with a lower level abstraction or even our own.&lt;br&gt;
As software abstractions can be abstractions &lt;em&gt;of&lt;/em&gt; software abstractions, we can even make a component &lt;em&gt;more simple&lt;/em&gt; rather than &lt;em&gt;more complex&lt;/em&gt; if we really want to.&lt;/p&gt;

&lt;p&gt;In theory, you could create a lightweight, simple, and perfect (for your needs) HTTP server by just importing the required components, e.g. router, parser, writer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Swappable Libraries
&lt;/h2&gt;

&lt;p&gt;In the Linux ecosystem, there exists multiple different sound server projects (ALSA, JACK, PulseAudio, and PipeWire). It's common for a user to need multiple of these sound servers as different programs require different APIs, although...&lt;/p&gt;

&lt;p&gt;It is possible to replace ALSA, JACK, and PulseAudio with a PipeWire-based implementation of their APIs. This unifies all APIs to one sound server, meaning your system is more cohesive and you can benefit from PipeWire's improved latency regardless of the program.&lt;/p&gt;

&lt;p&gt;This is all possible due to C/C++'s "header" system, something dropped in more modern programming languages. This is, in a way, an example of the facade design pattern. Facades are also commonly used by logging libraries, i.e. Java's SLF4J and Rust's &lt;code&gt;log&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Logging facades allow developers to use one API while swapping out the implementation dependent on their program's needs, like how SLF4J has a "no-op" logger that doesn't actually log messages, a "simple" logger for those who don't need a heavily customizable logger, and etc.&lt;/p&gt;

&lt;p&gt;It is inevitable that we will run into a situation where you want to use a monolithic library but it uses an abstraction you &lt;em&gt;can't&lt;/em&gt; because it just conflicts with another library in your dependencies. So, rather than have a library dependent directly on that abstraction, why not have it depend on an &lt;em&gt;interface?&lt;/em&gt; This would allow program developers to select which implementation they want for that interface across all dependencies, keeping the project &lt;em&gt;cohesive.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Applications
&lt;/h2&gt;

&lt;p&gt;Nowadays, we run into an issue where software we're using is lacking features we want... or has features we really don't want. There is no &lt;em&gt;perfect software,&lt;/em&gt; just &lt;em&gt;good enough,&lt;/em&gt; and to get to something that is perfect (a subjective matter), we need to write our own.&lt;/p&gt;

&lt;p&gt;But this is not always an easy task. Look at digital audio workstations, integrated development environments, browsers, game engines, command-line shells/terminal emulators, and operating systems! These are all hard projects to work on because there exists &lt;em&gt;many&lt;/em&gt; features that a developer is forced to implement, sometimes complex features (especially with OSes), even though they exist in other projects anyway.&lt;/p&gt;

&lt;p&gt;It is simply not possible for someone to make a set of software that is perfect for them within a reasonable set of time... but what if it was?&lt;/p&gt;

&lt;p&gt;The ideal software ecosystem is one where we can have each feature for each of these different applications all existing as their own component libraries, so developers can take what they need, avoid what they don't, reimplement what they require, and perhaps even make monolithic libraries so other developers can benefit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing Notes
&lt;/h2&gt;

&lt;p&gt;What if we lived in a world where it was possible to make your own Unix-like &lt;em&gt;within a week?&lt;/em&gt; Where you could have a program that &lt;em&gt;perfectly&lt;/em&gt; fit your workflow, needs, wants, ideals, etc. because &lt;em&gt;you made it?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;As time goes on, we become more dependent on the simple options regardless of whether or not they are the right ones. We also become more dependent on software that belongs to organizations that we do not agree with, which strive for profit rather than consumer happiness. Things go closed-source out of nowhere, horrible pricing models are introduced, and management conflicts with community. We need to take back control of our software.&lt;/p&gt;

&lt;p&gt;I do not suggest that this "alternative view" is perfect, but I do think it's a step in the right direction.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>opensource</category>
      <category>design</category>
      <category>architecture</category>
    </item>
    <item>
      <title>What Websites Have Become (and what they could be)</title>
      <dc:creator>Maow</dc:creator>
      <pubDate>Wed, 03 May 2023 18:22:05 +0000</pubDate>
      <link>https://forem.com/maow/what-websites-have-become-and-what-they-could-be-2k04</link>
      <guid>https://forem.com/maow/what-websites-have-become-and-what-they-could-be-2k04</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The World Wide Web,&lt;/strong&gt; or just "the Web," is an increasingly complex set of technologies that allows us to communicate and share information all over the world.&lt;br&gt;
It's existed for generations, and only gotten more and more advanced as time has gone on due to various safety, performance, and usability additions.&lt;/p&gt;

&lt;p&gt;In the modern day and age, websites have slowly transitioned from being focused around sharing text, files, and links, and more towards intricate services; &lt;strong&gt;web applications.&lt;/strong&gt;&lt;br&gt;
In this article, I'd like to illustrate what makes web applications convenient, what we could learn from desktop applications to improve web applications, and what my personal proposal is for the future of the web.&lt;/p&gt;




&lt;h2&gt;
  
  
  Web Applications vs. Desktop Applications
&lt;/h2&gt;




&lt;h3&gt;
  
  
  Discovery, Bookmarking, and Package Managers
&lt;/h3&gt;

&lt;p&gt;Finding an app is the first step to using it. Web applications are usually quite easy to find, only requiring you to use a search engine. People can also share links to the app. While these things are still &lt;em&gt;true&lt;/em&gt; with desktop apps, as they'd have their own site, there's the problem of having to download, possibly install, and then run a program.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Although,&lt;/em&gt; desktop apps benefit from package managers, app launchers, and start menus which all help the user install, uninstall, update, and access desktop apps.&lt;br&gt;
The only issue is that package managers and app launchers are primarily found in the Linux community, as package managers are usually command-line apps (that's not to say Windows doesn't have one, it's just scarcely used) and other operating systems do not need app launchers. In the browser world, the closest thing to a package manager is the bookmarks bar, as that allows you to save links for quick access.&lt;/p&gt;




&lt;h3&gt;
  
  
  Sandboxing, Safety, and Malware
&lt;/h3&gt;

&lt;p&gt;One of the immediate benefits of the Web is that many websites are secured with TLS, meaning all HTTP requests sent to those websites are encrypted. In a desktop app, this is something a developer has to go out of their way to implement, and many independent developers have limited experience with cybersecurity.&lt;br&gt;
Adding to this, desktop programs have the ability to execute any code. There are plenty of viruses that have circumvented the need for permissions, and it's not even necessary to have permissions to wreak havoc. Attackers find new ways to exploit processors and operating systems to circumvent safety patches, precautions, and anti-malware programs. There is a constant arms race.&lt;/p&gt;

&lt;p&gt;With new web technologies, such as &lt;strong&gt;WebAssembly&lt;/strong&gt; (WASM) and &lt;strong&gt;WebGPU,&lt;/strong&gt; we have the ability to make performant and modern apps in a completely sandboxed environment. WebAssembly &lt;em&gt;has&lt;/em&gt; to be safe, considering it takes advantage of the end-user's processor. This is effectively remote code execution, which would be terrible with unregulated, malicious code, but WebAssembly is designed to not be capable of such code.&lt;br&gt;
Better yet, you can compile to WebAssembly from various desktop programming languages, like C, C++, and Rust. This is not only beneficial for developers who want to work with lower level code than JavaScript, usually for performance benefits, but it also means we can develop applications for both web and desktop platforms with relative ease.&lt;/p&gt;

&lt;p&gt;That's not to say that websites are perfectly safe. Many will make you download malware, steal credentials by posing as real sites, or scam you with misleading pop-ups. Cautious users will learn to recognize fake looking URLs and suspicious websites, and browsers combat these by showing warnings, though not all of them are blocked. The issue here is that search engines will show anything they can find. A lot of these malicious sites are not exactly front page, but it's still harmful to display them to unsuspecting users in any way.&lt;/p&gt;




&lt;h3&gt;
  
  
  Bundling and Binaries
&lt;/h3&gt;

&lt;p&gt;One of the issues many front-end web developers run into is making their site load quickly. The cause of this is usually due to sites serving large files or, more often, &lt;em&gt;many&lt;/em&gt; files. Many tools and services were designed to combat this issue; CDNs cache commonly used CSS and JS libraries, bundlers minimize and bundle code and assets into easily cache-able segments. WebAssembly even aids smaller download sizes as it is a bytecode language, meaning it is compiled and stored as a series of bytes, rather than as text, like JavaScript. There's even been changes made to HTTP to help with this problem.&lt;/p&gt;

&lt;p&gt;The issue here is that we are putting a lot of work into something that desktop apps have no issue with, as many do not need to load anything, and if they do, it's usually just from the filesystem, which is a lot faster than downloading multiple files from an HTTP connection. Where desktop apps fail is in downloading them. A lot of apps come with heavy file sizes, usually due to the libraries they require, or their assets. This means you might have to download a couple &lt;em&gt;hundred&lt;/em&gt; megabytes for &lt;em&gt;one app.&lt;/em&gt; A lot of these apps are actually Electron instances. Electron is a framework that lets you make desktop apps with web technologies using Node.js and a version of the Chromium browser, the backbone of Chrome, Edge, Opera, and various other browsers. Many apps you know of, including but not limited to Discord, Steam, and Spotify, all render their interface using browsers, either partially or fully. This allows for flexible, modern visuals with CSS, but it has a major impact on memory usage and file size.&lt;/p&gt;




&lt;h2&gt;
  
  
  A Proposal for the Web
&lt;/h2&gt;

&lt;p&gt;As you can tell, both desktop and web have pros and cons. There isn't much we can do to help with the issues surrounding desktop, but we can improve the web, we do it all the time. Not only could we make it even safer, but we could make it easier to discover and manage apps as well as easier to load them. We could even decouple HTML, CSS, JS, and more from browsers, so developers have a choice over what they can use, and users can be given the most effective, fast software.&lt;/p&gt;




&lt;h3&gt;
  
  
  Ditch Web Browsers!
&lt;/h3&gt;

&lt;p&gt;This is going to spark a lot of mixed reactions: I personally think that we need to abandon the old web if we want to truly improve. Web browsers are insanely complex pieces of software, they are focused on many different things from accessibility to responsive web apps to video and audio playback to high-performance web games. We could simplify things. Backwards compatibility is a strange focus of web browsers. Many developers take the time to make their sites compatible with &lt;em&gt;Internet Explorer,&lt;/em&gt; a heavily outdated, slow, and all around terrible browser you can't even use anymore.&lt;/p&gt;

&lt;p&gt;We can keep the good ideas, but there will be a lot of rewriting bad ideas if we want things to be vastly improved.&lt;/p&gt;




&lt;h3&gt;
  
  
  Web Executables
&lt;/h3&gt;

&lt;p&gt;Instead of web browsers, I propose we have an app that has the ability to load &lt;em&gt;web bundles&lt;/em&gt; (AKA web executables). They would use an archive format that is easy to compress and verify but also fast to traverse, allowing our new web browser to easily find and read resources. When our browser receives a bundle, it will find &lt;em&gt;specifically&lt;/em&gt; WebAssembly code to execute on a new thread. This code will handle rendering, page events, and various other things. The "WebAssembly first" approach decouples code execution from JavaScript. JS would stop being a primary focus of browsers, perhaps having its own runtime alongside WebAssembly, but more likely, it or a derivative of it would be compiled to WebAssembly.&lt;/p&gt;

&lt;h4&gt;
  
  
  Rendering
&lt;/h4&gt;

&lt;p&gt;Don't be worried, this concept doesn't entail forcing everyone to write low-level WebGPU code. We &lt;em&gt;will&lt;/em&gt; allow that, but frameworks will exist to render pages in a more traditional way, possibly even allowing developers to load CSS resources. This completely decouples rendering from CSS and gives people more freedom to make their own formats and frameworks. No longer would you need a tool for transpiling SASS or LESS, just the library for it.&lt;/p&gt;




&lt;h3&gt;
  
  
  App Discovery
&lt;/h3&gt;

&lt;p&gt;Not only can you access apps via a URL, but our browser will have first-party support for "app discovery portals." Think app stores but without the monetization. The keen amongst you will notice the plural, "portals." Yes, decentralization.&lt;br&gt;
Now, an issue arises when you allow people to create their own portals. It goes from an app store to more of a repository, which is alright, but it does complicate the &lt;em&gt;discovery&lt;/em&gt; part. I don't want to think about an "app discovery portal discovery portal," so the alternative is going to derive from the old web: Word of mouth! If you want your portal to be found, make it worth finding. Link to your portal from your high-quality web app.&lt;/p&gt;




&lt;h3&gt;
  
  
  Access Protocol
&lt;/h3&gt;

&lt;p&gt;The pattern of decoupling the web continues as HTTP will stop being the primary way to retrieve resources. It would still be possible to use HTTP, but you would require an HTTP client/server library.&lt;/p&gt;

&lt;p&gt;The alternative to HTTP is a very simple protocol designed &lt;em&gt;just&lt;/em&gt; for requesting and retrieving bundles as well as accessing app discovery portals. You visit a &lt;code&gt;web://&lt;/code&gt; link and it either brings you to an app (via downloading a bundle) or a discovery portal (via downloading some metadata). In our browser, we'd even allow for saving portals and apps to our homepage.&lt;/p&gt;

&lt;h4&gt;
  
  
  Sockets
&lt;/h4&gt;

&lt;p&gt;With the removal of HTTP, you gain the benefit of &lt;em&gt;sockets,&lt;/em&gt; allowing you to send packets, rather than just make requests to an HTTP server.&lt;/p&gt;

&lt;p&gt;A bit of work would have to go into making these sockets safe for the end-user. We obviously can't use plain TCP sockets since an attacker could make an app that makes the end-user send malicious packets. Regardless, the work is worth it. The amount of potential this gives developers is astonishing.&lt;/p&gt;




&lt;h2&gt;
  
  
  Closing
&lt;/h2&gt;

&lt;p&gt;There's a lot we can do to improve the web. Speed, safety, and usability are the primary factors in designing an application, and as such, are the focus of my set of improvements. I do also believe in developer experience. Modern programming languages have not only shifted towards better user experience, but better dev experience too, and it's why I designed a lot of this around giving developers more choices and power.&lt;/p&gt;

&lt;p&gt;You don't have to agree with all of the ideas I've presented. In fact, if you have anything to say, I'd highly recommend doing so! Feel free to comment, tell me this is stupid, or whatever. I thank you for sticking to the end.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>webdev</category>
      <category>writing</category>
      <category>opensource</category>
    </item>
    <item>
      <title>A Deep Dive into Lambdas</title>
      <dc:creator>Maow</dc:creator>
      <pubDate>Sun, 05 Feb 2023 16:44:36 +0000</pubDate>
      <link>https://forem.com/maow/a-deep-dive-into-lambdas-6bh</link>
      <guid>https://forem.com/maow/a-deep-dive-into-lambdas-6bh</guid>
      <description>&lt;p&gt;Introduced in Java 1.8, the &lt;strong&gt;lambda expression&lt;/strong&gt; &lt;em&gt;(a.k.a. closure, anonymous function)&lt;/em&gt; is an important piece of syntax for code cleanliness, reduced repetition, and functionality.&lt;/p&gt;

&lt;p&gt;It provides the language—and its siblings, like Kotlin and Scala—with the ability to store a function as a value, which can also then be used to implement &lt;em&gt;higher-order functions&lt;/em&gt;, i.e. functions that take or return other functions.&lt;/p&gt;

&lt;p&gt;But how does it all work underneath the surface?&lt;/p&gt;

&lt;h2&gt;
  
  
  Functional Interfaces
&lt;/h2&gt;

&lt;p&gt;As Java is a statically typed language, a lambda needs to have a type. The type of a lambda includes its parameters and its return type, which can be seen with &lt;em&gt;functional interfaces&lt;/em&gt; like &lt;code&gt;Function&amp;lt;String, String&amp;gt;&lt;/code&gt;, analogous to &lt;code&gt;String function(String)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What exactly makes a functional interface so special?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;They have a single restriction: They may contain multiple default or static methods, but only &lt;em&gt;one&lt;/em&gt; abstract method. This is why functional interfaces are sometimes referred to as "SAM (Single Abstract Method) interfaces."&lt;/p&gt;

&lt;p&gt;This restriction exists precisely because the compiler needs to know which method will be implemented to create the lambda, for instance, &lt;code&gt;get&lt;/code&gt; in &lt;code&gt;Supplier&lt;/code&gt; or &lt;code&gt;apply&lt;/code&gt; in &lt;code&gt;Function&lt;/code&gt;. With multiple abstract methods, any of them could be implemented when writing a lambda.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Small example of a custom functional interface:&lt;/em&gt;&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="c1"&gt;// The @FunctionalInterface annotation is&lt;/span&gt;
&lt;span class="c1"&gt;// used to tell the compiler to enforce the SAM restriction.&lt;/span&gt;
&lt;span class="nd"&gt;@FunctionalInterface&lt;/span&gt;
&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;TokenProvider&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;ApiToken&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;h2&gt;
  
  
  The Low-Level
&lt;/h2&gt;

&lt;p&gt;In order to talk about how lambdas &lt;em&gt;really&lt;/em&gt; work, we need to give a brief explanation of the &lt;strong&gt;Java Virtual Machine&lt;/strong&gt; (hereby referred to as the JVM).&lt;/p&gt;

&lt;p&gt;When a JVM-based language (Java, Kotlin, etc.) is compiled, it outputs a file with the .class extension. Class files contain what is called &lt;em&gt;bytecode.&lt;/em&gt; Bytecode is a term used to describe any compiled code made of raw bytes that is executed by a virtual machine rather than your CPU.&lt;/p&gt;

&lt;p&gt;A virtual machine (not to be confused with VirtualBox, VMware, QEMU, and etc.) is a program that processes and executes bytecode, with the optional step of transforming that bytecode into optimized machine code, which is ran on the CPU. Each virtual machine handles a different bytecode language, i.e. the JVM handles JVM bytecode, which is designed specially for the Java platform and contains information about classes, fields, methods, and etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bytecode Instructions
&lt;/h2&gt;

&lt;p&gt;In the JVM, code is split up into single-purpose functions called "instructions." Instructions have a "mnemonic" and set of arguments, the mnemonic being the name of that specific instruction in the bytecode language.&lt;/p&gt;

&lt;p&gt;For a simple example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ldc "Hello, World!"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a single instruction with the mnemonic &lt;code&gt;ldc&lt;/code&gt;, short for "load constant."&lt;br&gt;
When it's run, it takes the first argument (which must be some kind of constant value, such as a string, int, or float) and pushes it onto the "operand stack," a stack data structure used for performing operations on values.&lt;/p&gt;

&lt;p&gt;When your code is compiled, it is turned into a list of instructions. When your code is run, the JVM starts at the first instruction and makes its way down until it reaches the end or reaches a jump (like an if statement) which makes the JVM jump to a different instruction and begin reading down the list.&lt;/p&gt;
&lt;h2&gt;
  
  
  Lambda Bodies
&lt;/h2&gt;

&lt;p&gt;You would probably be surprised to learn that the body of each lambda you declare in a class actually becomes a private method in that class. These lambda body methods are generated by the compiler and contain all the code placed in your lambda body.&lt;br&gt;
They follow a specific naming scheme: &lt;code&gt;lambda$&amp;lt;originating method&amp;gt;$&amp;lt;index&amp;gt;&lt;/code&gt;&lt;br&gt;
So, the first lambda in your &lt;code&gt;main&lt;/code&gt; method would have its body become the &lt;code&gt;lambda$main$0&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;Keep all of this in mind! It will be very important later on.&lt;/p&gt;
&lt;h2&gt;
  
  
  Method Handles and &lt;code&gt;java.lang.invoke&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Java's &lt;strong&gt;Invocation API&lt;/strong&gt; (&lt;a href="https://docs.oracle.com/en/java/javase/18/docs/api/java.base/java/lang/invoke/package-summary.html" rel="noopener noreferrer"&gt;&lt;code&gt;java.lang.invoke&lt;/code&gt;&lt;/a&gt;) was introduced back in Java 1.7. It allows you to create &lt;a href="https://docs.oracle.com/en/java/javase/18/docs/api/java.base/java/lang/invoke/MethodHandle.html" rel="noopener noreferrer"&gt;"method handles,"&lt;/a&gt; which are invokable references to a method or constructor. These differ from the Reflection API in many ways, the most well-known difference being that access checks are performed on method handle creation, rather than on each call like with Reflection.&lt;/p&gt;

&lt;p&gt;An additional type provided by the Invocation API is &lt;a href="https://docs.oracle.com/en/java/javase/18/docs/api/java.base/java/lang/invoke/CallSite.html" rel="noopener noreferrer"&gt;&lt;code&gt;CallSite&lt;/code&gt;&lt;/a&gt;, which holds a method handle. Despite the simplicity of this, &lt;code&gt;CallSite&lt;/code&gt; is very important for reasons that will be explained shortly.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;code&gt;invokedynamic&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;The core component of lambdas is the &lt;strong&gt;&lt;code&gt;invokedynamic&lt;/code&gt;&lt;/strong&gt; instruction. It, like all other &lt;code&gt;invoke-&lt;/code&gt; instructions, invokes/calls a method.&lt;/p&gt;

&lt;p&gt;However, the difference between it and other &lt;code&gt;invoke-&lt;/code&gt; instructions is that the first time that &lt;code&gt;invokedynamic&lt;/code&gt; is run, it will invoke a "bootstrap method." This is a method that returns a &lt;code&gt;CallSite&lt;/code&gt; object that is "bound" to that &lt;code&gt;invokedynamic&lt;/code&gt; instruction, meaning it only needs to be retrieved once. After the &lt;code&gt;CallSite&lt;/code&gt; is retrieved, its underlying method handle is invoked and, assuming the method handle returns a value, the returned value is pushed to the operand stack.&lt;/p&gt;

&lt;p&gt;This instruction allows us to essentially &lt;em&gt;receive&lt;/em&gt; functions that are to be invoked while avoiding performance downsides and compatibility issues.&lt;/p&gt;

&lt;p&gt;But, &lt;code&gt;invokedynamic&lt;/code&gt; is not the only piece of the puzzle.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Lambda Metafactory
&lt;/h2&gt;

&lt;p&gt;Under &lt;code&gt;java.lang.invoke&lt;/code&gt; exists a highly low-level class called &lt;a href="https://docs.oracle.com/en/java/javase/18/docs/api/java.base/java/lang/invoke/LambdaMetafactory.html" rel="noopener noreferrer"&gt;&lt;code&gt;LambdaMetafactory&lt;/code&gt;&lt;/a&gt;. This class is used to create method handles that return "function objects," which are objects that implement functional interfaces.&lt;/p&gt;

&lt;p&gt;The way this is done is somewhat complicated, so bear with me.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;LambdaMetafactory&lt;/code&gt; has a function named &lt;a href="https://docs.oracle.com/en/java/javase/18/docs/api/java.base/java/lang/invoke/LambdaMetafactory.html#metafactory(java.lang.invoke.MethodHandles.Lookup,java.lang.String,java.lang.invoke.MethodType,java.lang.invoke.MethodType,java.lang.invoke.MethodHandle,java.lang.invoke.MethodType)" rel="noopener noreferrer"&gt;&lt;code&gt;metafactory&lt;/code&gt;&lt;/a&gt; that returns a &lt;code&gt;CallSite&lt;/code&gt; after being given the following parameters (with only a few excluded for simplicity):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The name of the method to be implemented, for instance, "get" when implementing a &lt;code&gt;Supplier&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The descriptor of the method to be implemented, meaning the return type and parameter types. For a &lt;code&gt;Supplier&amp;lt;String&amp;gt;&lt;/code&gt;'s method, there would be a &lt;code&gt;String&lt;/code&gt; return type but no parameter types.&lt;/li&gt;
&lt;li&gt;The descriptor of the &lt;code&gt;CallSite&lt;/code&gt;, where the parameter types are the captured local variables and the return type is the interface that should be implemented.&lt;/li&gt;
&lt;li&gt;A handle to the implementation method, which is called in the interface's method. This is equivalent to the lambda body.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The most interesting part is what the method handle the lambda metafactory creates is. &lt;/p&gt;

&lt;p&gt;It &lt;em&gt;generates bytecode at runtime.&lt;/em&gt; This bytecode instantiates a new function object that calls the lambda body method with any necessary parameters, and then creates a new method handle that calls that bytecode before returning it in a call site.&lt;/p&gt;

&lt;p&gt;The bytecode generation is done via the help of a third-party library called &lt;a href="https://asm.ow2.io" rel="noopener noreferrer"&gt;ObjectWeb ASM&lt;/a&gt; that allows you to parse and write JVM bytecode very easily. The standard library uses it in this situation due to its performance and feature-completeness.&lt;/p&gt;

&lt;p&gt;Finally, a real example of what one of these function objects looks like:&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;final&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Test&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;$Lambda&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Supplier&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="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;String&lt;/span&gt; &lt;span class="n"&gt;arg&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="mi"&gt;1&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;Test&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;$Lambda&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="mi"&gt;1&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;arg&lt;/span&gt;&lt;span class="err"&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="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;arg&lt;/span&gt;&lt;span class="err"&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;arg&lt;/span&gt;&lt;span class="err"&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="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&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;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Test&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;lambda&lt;/span&gt;&lt;span class="n"&gt;$main&lt;/span&gt;&lt;span class="err"&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;arg&lt;/span&gt;&lt;span class="err"&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;span class="c1"&gt;// Oh no, it's hideous.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That function object was generated from 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;class&lt;/span&gt; &lt;span class="nc"&gt;Test&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="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Hello, World!"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="nc"&gt;Supplier&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="n"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;()&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="n"&gt;msg&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="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;
  
  
  End
&lt;/h2&gt;

&lt;p&gt;That is basically all there is to the creation and invocation of lambdas. I'm personally compelled by the unexpected complexity of Java's lambdas and the wonderful design that went into its dynamic invocations, so I felt the need to share this information in a (somewhat) easy to digest way.&lt;/p&gt;

&lt;p&gt;I hope you found this either fun, interesting, or useful. Bye!&lt;/p&gt;

</description>
      <category>devrel</category>
      <category>announcement</category>
      <category>devto</category>
      <category>royalties</category>
    </item>
  </channel>
</rss>
