diff --git a/.gitignore b/.gitignore
index 613f8e7..2c28aab 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,4 +6,6 @@ node_modules
.venv
venv
-*/**/__pycache__
\ No newline at end of file
+*/**/__pycache__
+
+*/**/.env
\ No newline at end of file
diff --git a/chunker/chunks.jsonl b/chunker/chunks.jsonl
deleted file mode 100644
index 9540736..0000000
--- a/chunker/chunks.jsonl
+++ /dev/null
@@ -1,1574 +0,0 @@
-{"id": null, "metadata": {"Header 1": "My Digital Garden", "Header 2": "What is a Digital Garden?", "path": "../pages/digitalGarden/index.mdx"}, "page_content": "A digital garden is a mix between a notebook and a blog, it is a place to share thoughts and cultivate them into a garden.\nIt also allows me to have a place where I can store my notes/summaries/tutorials for my studies. \nThe main difference to a blog is that a blog has articles and publication dates and never changes after it has been\npublished, whereas a digital garden is a place where the written content can be continuously edited and refined. The\nnotes are also very free flowing they can span from just a short cheatsheet to a full set of notes on an entire subject\nwhere you go into every nitty-gritty detail. \nAnother key difference is the navigation. A blog is usually read in chronological order but a digital garden can be read\nin any order you want and uses lots of internal links to connect all the notes into a Network (although this can be\nquite hard to diligently do). \nIf you are interested in learning more about digital gardens I can recommend the following\n[article by Maggie Appleton](https://maggieappleton.com/garden-history).", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "My Digital Garden", "Header 2": "How is my Garden Built?", "path": "../pages/digitalGarden/index.mdx"}, "page_content": "The current iteration of my digital garden is built using [Nextra](https://nextra.site/). Nextra is a static site\ngenerator that is built on top of Next.js and MDX. This allows me to write my notes in markdown and also use the MDX\nformat to write JSX in my markdown files. These markdown files are then converted into static HTML files using Next.js\nand can be hosted on any static site hosting service such as [Vercel](https://vercel.com/).", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "My Digital Garden", "Header 2": "The Features", "path": "../pages/digitalGarden/index.mdx"}, "page_content": "In this section I briefly go over some of the features that are supported by my digital garden and how to use them.", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "My Digital Garden", "Header 2": "The Features", "Header 3": "Markdown", "path": "../pages/digitalGarden/index.mdx"}, "page_content": "Markdown is supported out of the box. Anything that is supported by markdown can be used in the notes. This includes but\nis not limited to: \n- Headers\n- Lists\n- Links\n- Images\n- Code Blocks\n- Tables\n- Blockquotes \nFor a full list of markdown features check out the [Markdown Guide](https://www.markdownguide.org/).", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "My Digital Garden", "Header 2": "The Features", "Header 3": "MDX", "path": "../pages/digitalGarden/index.mdx"}, "page_content": "In addition to the normal markdown format, Nextra also supports the MDX format which allows you to write JSX, i.e. react code in a\nmarkdown file. To find out more about MDX check out the [official MDX documentation](https://mdxjs.com/). \n#### Admonitions / Callouts \nAdmonitions aren't included in standard markdown but have become very popular. Recently GitHub has also added support for\nadmonitions in markdown FileSystem, however they call them alerts. \nAdmonitions are very useful to highlight certain text and add a category to the text. I have added a custom component that\nbuilds on nextra's callouts to be able to add custom callout types. To use callouts in a MDX file you can use the following syntax: \n```\n\nThis Is a big scary warning.\n\n``` \nRenders to: \n\nThis Is a big scary warning.\n \nYou can also change the title of the banner: \n```\n\ninfo, warning, error, example, todo\n\n``` \n\ninfo, warning, error, example, todo\n \nThe default callout type uses the websites primary color, a rocket icon and has no title: \n\nThis is a default callout.\n", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "My Digital Garden", "Header 2": "The Features", "Header 3": "Jupyter Notebooks", "path": "../pages/digitalGarden/index.mdx"}, "page_content": "\nTODO add how the hound works and how to use it.\n", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "My Digital Garden", "Header 2": "The Features", "Header 3": "LaTeX", "path": "../pages/digitalGarden/index.mdx"}, "page_content": "It has recently become very popular to write LaTeX equations in markdown. Nextra supports this by using [KaTeX](https://katex.org/).\nYou can render LaTeX content either inline between `$\\LaTeX$` $\\LaTeX$ or as a block between `$$I = \\int_0^{2\\pi} \\sin(x)\\,dx$$`: \n$$\nI = \\int_0^{2\\pi} \\sin(x)\\,dx\n$$ \nAnnoyingly Jupyter Notebooks use MathJax to render LaTeX content in the same way instead of KaTeX. This means that KaTeX\nsupports some things and MathJax supports other things. Importantly however is that the Jupyter Notebooks get converted\nto Markdown and therefore in the end it will only be rendered in KaTeX. \nTherefore, if something is written that is supported in MathJax but not in KaTeX it might look okay but in the end,\nit will not be rendered by KaTeX. This leads to [my LaTeX Notation Guideline](./maths/latexGuidelines) to avoid\nconflicts whilst still keeping nice Formulas. \nYou can see what is supported by KaTeX [here,](https://katex.org/docs/supported.html) and you can see what is supported\nby MathJax [here](https://docs.mathjax.org/en/latest/input/tex/macros/index.html).", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "My Digital Garden", "Header 2": "The Features", "Header 3": "PlantUML", "path": "../pages/digitalGarden/index.mdx"}, "page_content": "If you ever need to create diagrams and especially UML diagrams, PlantUML is the way to go. I started with Mermaid\nto create UML diagrams but swapped to PlantUML for the additional features and the ability to create custom themes\n(so everything can be minimalist and purple :D). \nTo render PlantUML diagrams the [Remark plugin Simple PlantUML](https://github.com/akebifiky/remark-simple-plantuml) is\nused which uses the official PlantUML server to generate an image and then adds it. \nAn Example can be seen below, on the [official website](https://plantuml.com/) and also on [REAL WORLD PlantUML](https://real-world-plantuml.com/?type=class). \n```plantuml\n@startuml\n\ninterface Command {\nexecute()\nundo()\n}\nclass Invoker{\nsetCommand()\n}\nclass Client\nclass Receiver{\naction()\n}\nclass ConcreteCommand{\nexecute()\nundo()\n}\n\nCommand <|-down- ConcreteCommand\nClient -right-> Receiver\nClient --> ConcreteCommand\nInvoker o-right-> Command\nReceiver <-left- ConcreteCommand\n\n@enduml\n``` \nTo use my custom theme you can use the following line at the beginning of the PlantUML file: \n```\n@startuml\n!theme purplerain from http://raw.githubusercontent.com/LuciferUchiha/georgerowlands.ch/main\n\n...\n\n@enduml\n``` \nHowever, it seems like when using a custom theme There can not be more then one per page? My custom theme also has some processes built in for simple text coloring for example in cases of success, failure etc. \n```plantuml\n@startuml\n!theme purplerain from http://raw.githubusercontent.com/LuciferUchiha/georgerowlands.ch/main\n\nBob -> Alice : normal\nBob <- Alice : $success(\"success: Hi Bob\")\nBob -x Alice : $failure(\"failure\")\nBob ->> Alice : $warning(\"warning\")\nBob ->> Alice : $info(\"finished\")\n\n@enduml\n```", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "My Digital Garden", "Header 2": "How can I Contribute?", "path": "../pages/digitalGarden/index.mdx"}, "page_content": "Do you enjoy the content and want to contribute to the garden by adding some new plants or watering the existing ones?\nThen feel free to make a pull request. There are however some rules to keep in mind before adding or changing content. \n- Markdown filenames and folders are written in camelCase.\n- Titles should follow the\n[IEEE Editorial Style Manual](https://www.ieee.org/content/dam/ieee-org/ieee/web/org/conferences/style_references_manual.pdf).\nThey should also be added to the markdown file and specified in the `_meta.json` which maps files to titles and is also\nresponsible for the ordering.\n- LaTeX should conform with my notation and guideline, if something is not defined there you can of course add it.", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Computer Systems", "path": "../pages/digitalGarden/cs/computerArchitecture/computerSystems.mdx"}, "page_content": "This Page is meant as a brief introduction to the types of computer systems there are and how they are made and the issues we have faced with making improvements to our computer systems over the years.", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Computer Systems", "Header 2": "Types of Computer Systems", "path": "../pages/digitalGarden/cs/computerArchitecture/computerSystems.mdx"}, "page_content": "Let us first answer the question of what is a computer. What is the difference between a computer and just any other machine. A Computer is a programmable machine. Meaning that it can change its behavior and functionality, unlike other simple machines. \nMost commonly Computers are split up into the following types: \n- Personal Computer, short PC. The PC is the type of computer most people use and think of when talking about a computer. It serves a very general purpose and offers a wide variety of software to solve problems in our day-to-day life. In more recent years this type has also seen the addition of personal mobile devices (PMD) or more commonly known as smartphones and tablets. These devices are meant for the average consumer which makes subjects them to cost/performance tradeoffs.\n- Server computers or also just servers are computers that are usually accessed only over a network (Internet or LAN). Servers are built from the same basic technology as personal computers but with more performance and storage capabilities. Since they are also used by multiple people and are used to communicate between different applications and/or networks they have to be reliable to mitigate downtime.\n- Supercomputers, these computers represent the peak of what can be done with computers and are mainly used for research and academic purposes. You can find out more about the top supercomputers [here](https://www.top500.org/).\n- Embedded computers are the most used computers but people would never think so as they are usually hidden. They have a very wide range of applications and performances for example being part of your car to optimize fuel efficiency down to controlling the temperature in your coffee machine.", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Computer Systems", "Header 2": "Components of a Computer", "path": "../pages/digitalGarden/cs/computerArchitecture/computerSystems.mdx"}, "page_content": "\nCPU = Control + Datapath\nMemory\nIO\n", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Computer Systems", "Header 2": "How are Chips made", "path": "../pages/digitalGarden/cs/computerArchitecture/computerSystems.mdx"}, "page_content": "blbabla silicon and moores law. yield etc. \n", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Computer Systems", "Header 2": "The Power Wall", "path": "../pages/digitalGarden/cs/computerArchitecture/computerSystems.mdx"}, "page_content": "As transistors get smaller, their power density stays constant. power wall and denard scaling\ncant reduce voltage because of noise => bits getting flipped and cant cool \nlead to hift to Multicore Processors \nblabla amhdals law, cant infinetly speeedup there is some limit.", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Computer Systems", "Header 2": "Programming a Computer", "path": "../pages/digitalGarden/cs/computerArchitecture/computerSystems.mdx"}, "page_content": "blabla high level, compiler assembler instruciton sets", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Working with Numbers", "path": "../pages/digitalGarden/cs/computerArchitecture/workingWithNumbers.mdx"}, "page_content": "Working with numbers on computer systems is slightly more complex then one would think due to the fact that computers work only with the binary numbers 1 and 0.", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Working with Numbers", "Header 2": "Integers", "Header 3": "Unsigned Integers", "path": "../pages/digitalGarden/cs/computerArchitecture/workingWithNumbers.mdx"}, "page_content": "with n bits we can represent $2^n$ things. Encoding unsigned integers, i.e integers with no sign so positive numbers is pretty simple. The first bit called the LSB corresponds to $2^0$, the second one $2^1$. If that bit is set to 1 we add the value corresponding to that bit and receive the result. So if we have 32 bits we can represent $2^32$ things, so if we start at 0 we can represent the range from 0 to $2^32-1$. \nThis can also be described mathematically as followed if we denote our binary representation as $B=b_{n-1},b_{n-2},..,b_0$ and the function $D(B)$ which maps the Binary representation to its corresponding value. \n$$\nD(B)= \\sum_{i=0}^{n-1}{b_i \\cdot 2^i}\n$$", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Working with Numbers", "Header 2": "Signed Integers", "path": "../pages/digitalGarden/cs/computerArchitecture/workingWithNumbers.mdx"}, "page_content": "When we involve signed integers it gets a bit more complex since now we also want to deal with negative numbers. In history there have been a few representations for encoding signed integers which often get forgotten.", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Working with Numbers", "Header 2": "Signed Integers", "Header 3": "Sign Magnitude", "path": "../pages/digitalGarden/cs/computerArchitecture/workingWithNumbers.mdx"}, "page_content": "The idea for the sign and magnitude representation is a very simple one. You have a bit (the MSB) that represents the sign, 1 for negative, 0 for positive. All the other bits are the magnitude i.e. the value. \n$$\nD(B)= (-1)^{b_{n-1}} \\cdot \\sum_{i=0}^{n-2}{b_i \\cdot 2^i}\n$$ \n \n\n$$\n\\begin{align*}\n0000\\,1010_2 &= 10 \\\\\n1000\\,1010_2 &= -10\n\\end{align*}\n$$\n \nSeems pretty simple. However, there are two different representations for 0 which isn't good since computers often make comparisons with 0. This could potentially double the number of comparisons needed to be made which is one reason why this sign magnitude representation is not optimal.", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Working with Numbers", "Header 2": "Signed Integers", "Header 3": "One's Complement", "path": "../pages/digitalGarden/cs/computerArchitecture/workingWithNumbers.mdx"}, "page_content": "The idea of the one's complement is also very simple, it is that we want to quickly find the negative number of the same positive value by just flipping all the bits. In other words: \n$$\n-B=\\,\\sim B\n$$ \nAnd mathematically defined: \n$$\nD(B)= -b_{n-1}(2^{n-1}-1) + \\sum_{i=0}^{n-2}{b_i \\cdot 2^i}\n$$ \n \n\n$$\n\\begin{align*}\n0000\\,1010_2 &= 10 \\\\\n1111\\,0101_2 &= -10\n\\end{align*}\n$$\n \nhowever just like the sign magnitude representation the one's complement has the issue of having 2 representations for 0.", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Working with Numbers", "Header 2": "Signed Integers", "Header 3": "Two's Complement", "path": "../pages/digitalGarden/cs/computerArchitecture/workingWithNumbers.mdx"}, "page_content": "Finally, we have the representation that is used nowadays, the two's complement. This representation solves the issue of the double representation of 0 whilst still being able to quickly tell if a number is positive or negative. It does however lead to there not being a positive value corresponding to the lowest negative value. \n$$\nD(B)= -b_{n-1}(2^{n-1}) + \\sum_{i=0}^{n-2}{b_i \\cdot 2^i}\n$$ \n \n\n$$\n\\begin{align*}\n0000\\,1010_2 &= 10 \\\\\n1111\\,0110_2 &= -10\n\\end{align*}\n$$\n \nAny easy way to calculate the negative value of a given value with the two's complement representation is the following: \n$$\n\\sim B + 1 \\Leftrightarrow -B\n$$ \n#### Sign Extension \nWhen using the two's complement we do need be aware of something when converting a binary number with $n$ bits to a binary number with $n+k$ bits and it is called sign extension. Put simply for the value of binary number to stay the same we need to extend the sign bit. \n \n\n$$\n\\begin{align*}\n10:&\\, 0000\\,1010_2 \\Rightarrow 0000\\,0000\\,0000\\,1010_2 \\\\\n-10:&\\, 1111\\,0110_2 \\Rightarrow 1111\\,1111\\,1111\\,0110_2\n\\end{align*}\n$$\n", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Working with Numbers", "Header 2": "Real Numbers", "path": "../pages/digitalGarden/cs/computerArchitecture/workingWithNumbers.mdx"}, "page_content": "Representing real numbers can be pretty hard as you can imagine since real numbers can be infinite numbers such as $\\pi = 3.14159265358979323846264338327950288...$ but we only have finite resources and bits to represent them for example 4 or 8 bytes. Another problem is that often times when working with real numbers we find ourselves using very small or very large numbers such as $1$ Lightyear $=9'460'730'472'580.8\\,km$ or the radius of a hydrogen atom $0.000000000025\\,m$.", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Working with Numbers", "Header 2": "Real Numbers", "Header 3": "Binary Fractions", "path": "../pages/digitalGarden/cs/computerArchitecture/workingWithNumbers.mdx"}, "page_content": "One way, but not a very good way to represent real numbers is to use binary fractions. Binary fractions are a way to extend the unsigned integer representation by adding a so-called binary/zero/decimal point. To the left of the binary point, we have just like with the unsigned representation the powers of 2. To the right, we now also use the powers of 2 with negative numbers to get the following structure: \n$$\nB = b_{i},b_{i-1},..,b_0\\,.\\,b_{-1},...,b_{-j+1},b_{-j}\n$$ \nAnd Formula: \n$$\nD(B) = \\sum_{k=-j}^{i}{b_k \\cdot 2^k}\n$$ \n \n\n$$\n\\begin{align*}\n5 \\frac{3}{4} &= 0101.1100_2 \\\\\n2 \\frac{7}{8} &= 0010.1110_2 \\\\\n\\frac{63}{64} &= 0.1111110_2\n\\end{align*}\n$$\n \nFrom the above examples we can make 3 key observations the first 2 might already know if you have been programming for a long time. \n- Dividing by powers of 2 can be done with shifting right $x / 2^y \\Leftrightarrow x >> y$\n- Multiply with powers of 2 can be done with shifting left $x \\cdot 2^y \\Leftrightarrow x << y$ \nThis representations does have its limits since we can only represent numbers of the form $\\frac{x}{s^k}$ other numbers such as $\\frac{1}{3}$ have repeating bit representations.", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Working with Numbers", "Header 2": "Real Numbers", "Header 3": "Fixed Points", "path": "../pages/digitalGarden/cs/computerArchitecture/workingWithNumbers.mdx"}, "page_content": "The fixed-point representation or also called $p.q$ fixed-point representation extends the idea of binary fractions by adding a sign bit making the left part of the binary point the same as the two's complement. The right part is the same fractional part. The number of bits for the integer part (including the sign) bit corresponds to $p$ the number of bits for the fractional part corresponds to $q$, 17.14 being the most popular format. \n$$\nD(P)=-b_p \\cdot 2^p + \\sum_{k=-q}^{p-1}{b_k \\cdot 2^k}\n$$ \n \nThis representation has many pros, it is simple we can use simple arithmetic operations and don't need special floating-point hardware which is why it is commonly used in many low-cost embedded processors. The only con is that we can not represent a wide range of numbers which we will fix with the next and last representation.", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Working with Numbers", "Header 2": "Real Numbers", "Header 3": "Floating Points", "path": "../pages/digitalGarden/cs/computerArchitecture/workingWithNumbers.mdx"}, "page_content": "In 1985 the [IEEE standard 754](https://standards.ieee.org/ieee/754/993/) was released and quickly adapted as the standard for so-called floating-point arithmetic. In 1989, William Kahan, one of the primary architects even received the Turing Award, which is like the noble prize for computer science. The floating-point representation builds on the ideas of the fixed-point representation and [scientific notation](../../Mathematik/scientificNotation). \nFloating-point representation consists of 3 parts, the sign bit, and like the scientific notation an exponent and mantissa. \n \nWe most commonly use the following sizes for the exponent and mantissa: \n- Single precision: 8 bits for the exponent, 23 bits for the mantissa making a total of 32 bits with the sign bit.\n- Double precision: 11 bits for the exponent, 52 bits for the mantissa making a total of 64 bits. It doesn't offer much of a wider range then the single precision however, it does offer more precision, hence the name. \nIn 2008 the IEEE standard 754 was revised with the addition of the following sizes: \n- Half precision: 5 bits for the exponent, 10 bits for the mantissa making a total of 16 bits.\n- Quad precision: 15 bits for the exponent, 112 bits for the mantissa making a total of 32 bits. \nWith the rise of artificial intelligence and neural networks, smaller representations have gained popularity for quantization. This popularity introduced the following so-called minifloats consisting of 8 bits in total: \n- E4M3: as the name suggests 4 bits for the exponent and 3 bits for the mantissa.\n- E5M2: 5 bits for the exponent and 2 bits for the mantissa. \nThe brain floating point which was developed by Google Brain is also very popular for AI as it has the same range as single precision due to using the same amount of bits for the exponent but with less precision.", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Working with Numbers", "Header 2": "Real Numbers", "Header 3": "Floating Points", "path": "../pages/digitalGarden/cs/computerArchitecture/workingWithNumbers.mdx"}, "page_content": "The brain floating point which was developed by Google Brain is also very popular for AI as it has the same range as single precision due to using the same amount of bits for the exponent but with less precision. \nThe floating-point representation used however normalized values just like the scientific notation. Meaning the mantissa is normalized to the form of \n$$\n1.000010010...110_2\n$$ \nSo, in reality, we are not actually storing the mantissa but only the fraction part which is why it is also commonly referred to as the fraction. This leads to two things, we get an extra bit for free since we imply that the first bit is 1, but we can no longer represent the value 0. We will however see later how we can solve the problem of representing 0. \nWe also do not store the exponent using the two's complement. Instead, we use the so-called biased notation for the simple reason of wanting to compare values quickly with each other. To do this we want a form where the exponent with all zeros $0000\\,0000$ is smaller than the exponent with all ones $1111\\,1111$ which wouldn't be the case when using the two's complement. Instead, we use a bias. To calculate the bias we use the number of bits used to represent the exponent $k$. For single precision $k=8$, the bias for single precision is $127$ calculated using the formula: \n$$\nbias = 2^{k-1}-1\n$$ \n\nNow that we understand the form of the floating-point representation let us look at an example. We want to store the value $2022$ using single precision floating-point. First, we set the sign bit in this case $0$. Then we convert the value to a binary fraction. Then we normalize it whilst keeping track of the exponent. Then lastly we store the fraction part and the exponent + the bias. \n$$\n\\begin{align}\n2022 &= 11111100110._2 \\cdot 2^0 & \\text{Convert to binary fraction} \\\\\n&= 1.1111100110_2 \\cdot 2^{10} & \\text{Shift binary point to normalize} \\\\\nM &= 1.1111100110_2 & \\text{Mantissa} \\\\\nFraction &= 1111100110_2 & \\text{Fraction} \\\\", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Working with Numbers", "Header 2": "Real Numbers", "Header 3": "Floating Points", "path": "../pages/digitalGarden/cs/computerArchitecture/workingWithNumbers.mdx"}, "page_content": "$$\n\\begin{align}\n2022 &= 11111100110._2 \\cdot 2^0 & \\text{Convert to binary fraction} \\\\\n&= 1.1111100110_2 \\cdot 2^{10} & \\text{Shift binary point to normalize} \\\\\nM &= 1.1111100110_2 & \\text{Mantissa} \\\\\nFraction &= 1111100110_2 & \\text{Fraction} \\\\\nE &= 10 & \\text{Exponent} \\\\\nExp &= E + bias = 10 + 127 = 1000\\,1001_2 & \\text{Biased Exponent}\n\\end{align}\n$$ \n| Sign | Exponent | Fraction |\n| ---- | --------- | ---------------------------- |\n| 0 | 1000 1001 | 1111 1001 1000 0000 0000 000 |\n \n#### Denormalized values \nAs mentioned above we can't represent the value $0$ using the normalized values. For this, we need to use denormalized values or also often called subnormal. For this, in the case of single precision, we reserve the exponent that consists of only zeros so has the biased value $0$ and therefore the exponent $1-bias$, for single precision this would be $-126$. If the fraction also consists of all zeros then we have a representation for the value $0$. If it is not zero then we just have evenly distributed values close to 0. \n\n| Value | Sign | Exponent | Fraction |\n| ------------------------------------------------- | ---- | --------- | ---------------------------- |\n| 0 | 0 | 0000 0000 | 0000 0000 0000 0000 0000 000 |\n| -0 | 1 | 0000 0000 | 0000 0000 0000 0000 0000 000 |\n| $0.5 \\cdot 2^{-126} \\approx 5.877 \\cdot 10^{-39}$ | 0 | 0000 0000 | 1000 0000 0000 0000 0000 000 |\n| $0.99999 \\cdot 2^{-126}$ | 0 | 0000 0000 | 1111 1111 1111 1111 1111 111 |\n \n#### Special Numbers", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Working with Numbers", "Header 2": "Real Numbers", "Header 3": "Floating Points", "path": "../pages/digitalGarden/cs/computerArchitecture/workingWithNumbers.mdx"}, "page_content": "| $0.5 \\cdot 2^{-126} \\approx 5.877 \\cdot 10^{-39}$ | 0 | 0000 0000 | 1000 0000 0000 0000 0000 000 |\n| $0.99999 \\cdot 2^{-126}$ | 0 | 0000 0000 | 1111 1111 1111 1111 1111 111 |\n \n#### Special Numbers \nFor some cases we want to be able to store some special values such as $\\infty$ if we do $1.0 / 0.0$ or $NaN$ when doing $\\sqrt{-1}$ or $\\infty - \\infty$. Just like with solving the issue of representing $0$, to represent special values we can reserve an exponent, in the case of single precision this is the exponent consisting of only ones. If the fraction only consists of zeros then it represents the value $\\infty$ otherwise if the fraction is not all zeros it represents $NaN$. \n| Value | Sign | Exponent | Fraction |\n| --------- | ---- | --------- | ---------------------------- |\n| $\\infty$ | 0 | 1111 1111 | 0000 0000 0000 0000 0000 000 |\n| $-\\infty$ | 1 | 1111 1111 | 0000 0000 0000 0000 0000 000 |\n| $NaN$ | 0 | 1111 1111 | 1000 0000 0000 0000 0000 000 |\n| $NaN$ | 1 | 1111 1111 | 1111 1111 1111 1111 1111 111 | \nFor other representations such as the E4M3, E5M2 or bfloat16 the handling of special numbers can be different. This comes down to there being less bits and therefore each bit having more meaning so reserving an entire exponent range just to represent $NaN$ would be a big waste: \n|| E4M3 | E5M2 |\n| ------------------ | ---------------- | ------------------------ |\n| $-\\infty / \\infty$ | N/A | $S\\,11111\\,00_2$ |\n| $NaN$ | $S\\,1111\\,111_2$ | $S\\,11111\\,{01,10,11}_2$ |\n| $-0/0$ | $S\\,0000\\,000_2$ | $S\\,00000\\,00_2$ | \n#### Precision \nAs mentioned at the beginning of the floating-point section Real numbers are in theory infinite however we can not represent an infinite amount of numbers with a finite number of bits. Below you can see an estimated visualization of what values can actually be represented. \n \nAt a closer look, we can also see how the representations are distributed with the values close to zero being very precise. \n \nThis issue can however cause problems of imprecision if a certain number can not be represented and is rounded to the closest number that can be represented. For example in C we can do the following: \n```c\n#include \nint main ()\n{\ndouble d;\nd = 1.0 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1;\nprintf (“d = %.20f\\n”, d); // Not 2.0, outputs 2.00000000000000088818\n}\n``` \n#### Rounding \nThe IEEE standard 754 defines four rounding modes: \n- Round-up\n- Round-down\n- Round-toward-zero, i.e truncate, which is commonly done when converting from integer to floating point.\n- Round-to-even, the most common but also the most complicated of the four modes. \nI will not go into detail of the first three modes as they are self-explanatory. Let us first look at why we need to round-to-even. The reason is actually pretty simple, normal rounding is not very fair. \n\n$$\n\\begin{align*}\n& &0.5+1.5+2.5+3.5 &= 8 \\\\\n\\text{Rounded: }& &1+2+3+4 &= 10 \\\\\n\\text{Round-to-even: }& &0 + 2 + 2 + 4 &= 8\n\\end{align*}\n$$\n \n\nThis part is not correct.\n \nWhen working with round-to-even we need to keep track of 3 things: \n- Guard bit: The LSB that is still part of the fraction.\n- Round bit: The first bit that exceeds the fraction.\n- Sticky bit: A bitwise OR of all the remaining bits that exceed the fraction. \nSo if we only have a mantissa of 4 bits, i.e a fraction with 3 bits then it could look like this: \n \nNow we have 3 cases: \n- If $GRS=0xx$ we round down, i.e do nothing since the LSB is already $0$.\n- If $GRS=100$ this is a so-called tie, if the bit before the guard bit is $1$ we round the mantissa up otherwise we round down i.e set the guard bit to $0$", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Working with Numbers", "Header 2": "Real Numbers", "Header 3": "Floating Points", "path": "../pages/digitalGarden/cs/computerArchitecture/workingWithNumbers.mdx"}, "page_content": "Now we have 3 cases: \n- If $GRS=0xx$ we round down, i.e do nothing since the LSB is already $0$.\n- If $GRS=100$ this is a so-called tie, if the bit before the guard bit is $1$ we round the mantissa up otherwise we round down i.e set the guard bit to $0$\n- For all other cases $GRS=110$, $GRS=101$ and $GRS=111$ we round up. \n\nAfter rounding, you might have to normalize and round again for example if we have $1.1111\\,1111|11$ with $GRS=111$ and Biased exponent $128$, i.e $2^1$. We have to round up and get $11.0000\\,0000$ therefore we need to increase the exponent by $1$ to normalize again. This also means that after rounding we can produce a over or underflow to infinity.\n \n#### Addition/Subtraction \n#### Multiplication", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Memory Hierarchy", "path": "../pages/digitalGarden/cs/computerArchitecture/memoryHierarchy.mdx"}, "page_content": "\nTo do about caches registers misses etc.\n", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "What is RISC-V?", "path": "../pages/digitalGarden/cs/computerArchitecture/riscV/riscV.mdx"}, "page_content": "RISC-V is an open standard instruction set architecture that has been developed at the University of California, Berkeley since 1981 and is based on the established RISC principles which we will see when diving deeper.", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "What is RISC-V?", "Header 2": "CISC vs RISC", "path": "../pages/digitalGarden/cs/computerArchitecture/riscV/riscV.mdx"}, "page_content": "Up until about 1986 most chip manufacturers were using the CISC (Complex Instruction Set Computers) Architecture, the most common example of this being the Intel x86 ISA which is widely used nowadays. However, they realized that it makes building the chips more complicated and slows down potential improvements. This brought on the switch to RISC (Reduced Instruction Set Computers) which focuses on having a small number of simple instructions and then letting the compilers resolve complexity. Some of the most common examples of RISC are MIPS, AMD ARM and the open-source RISC-V which is what we will be looking at. \nHowever, you might have realized that most computers that you interact with use x86, doesn't that mean that you aren't getting the best performance that you could? This is actually not true, almost all chips nowadays use the RISC architecture, including x86 chips. But I just said that x86 uses CISC? This is true for the early x86 chips, the x86 chips nowadays are hybrid chips. They support CISC instructions for backward compatibility as a lot of devices were already using CISC, however, inside the chips they convert the CISC instructions to RISC instructions and execute them, which makes them have a \"RISC\" core.", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "What is RISC-V?", "Header 2": "Extensions", "path": "../pages/digitalGarden/cs/computerArchitecture/riscV/riscV.mdx"}, "page_content": "RISC-V aims to be as lightweight as possible which is why it allows for extensions to be added for certain functionalities. This allows chip manufacturers to only add what they need and not have instructions that they never intend to use or support. We will mainly be focusing on the `RV32IG` variant which is equivalent to `RV32IMAFD`. \n", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "What is RISC-V?", "Header 2": "Register Layout", "path": "../pages/digitalGarden/cs/computerArchitecture/riscV/riscV.mdx"}, "page_content": "RISC-V has 32 (or 16 in the embedded variant) integer registers and with the floating-point extension another separate 32 floating-point registers. Since our focus is on the 32-bit variation each register can store 32 bits. These registers are essential to the CPU as it can only work with data that is in a register it can not work on data in main memory. So if we want to manipulate data that is in the main memory we need to first transfer the data from the main memory to a register. \nCertain registers have restrictions or should be used in a certain way. Most notable is that the first register will always store the value 0. \n", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Procedure Calls", "path": "../pages/digitalGarden/cs/computerArchitecture/riscV/procedureCalls.mdx"}, "page_content": "A procedure or function is one of the key building blocks for programmers as it allows them to create understandable and reusable code. It also a way to add abstraction and simplify a program. In simple a procedure works as follows: \n1. Put the parameters in a place the procedure (callee) can access them.\n2. Transfer control to the procedure.\n3. Acquire the storage resources needed for the procedure.\n4. Perform the task.\n5. Put the result of the task in a place the caller can access them.\n6. Return control to the caller. \nFor the first and fifth point, we have the registers `x10-x17`. So that we know where to return to in step 6 we store the caller address in `x1`, this would be done when transferring control to the procedure with the `jal x1, Label` instruction.", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Procedure Calls", "Header 2": "Using More Registers", "path": "../pages/digitalGarden/cs/computerArchitecture/riscV/procedureCalls.mdx"}, "page_content": "But what if the 8 registers for the arguments are not enough to complete our task. We can use other registers as long as we clean up after ourselves, meaning we can spill registers to memory and then restore the registers before returning control. This leads us to the idea of the stack. In RISC-V we keep track of a stack pointer in `x2` and push and pop data to the stack. Important here is however that the stack grows from high to low addresses meaning when updating the stack pointer we need to subtract. \nFor this we also remember that the registers `x5-x7` and `x28-x31` are temporary registers and do not need to be restored before returning control but the registers `x8-x9` and `x18-x27` are saved registers and do need to be restored. \n\nIn the below example we could just use the temporary registers to store the temporary values but instead, we will spill some registers to the stack to demonstrate how this could be done. \n```c\n// g in x10, h in x11, i in x12, j in x13\nint leaf( int g, int h, int i, int j) {\nint f;\nf = (g + h) – (i + j);\nreturn f;\n}\n``` \n```assembly\nleaf:\naddi sp, sp, -12 # make space on stack for 12 bytes 3x 32 bits\nsw x5,8(sp) # save x5\nsw x6,4(sp) # save x6\nsw x7,0(sp) # save x7\nadd x5,x10,x11 # x5 <- g + h\nadd x6,x12,x13 # x6 <- i + j\nsub x7,x5,x6 # x7 <- x5 - x6\naddi x10,x7,0 # write result to x10 <- x7\nlw x7,0(sp) # restore x7\nlw x6,4(sp) # restore x6\nlw x5,8(sp) # restore x5\naddi sp,sp,12 # adjust stack\njalr x0,0(x1) # return to caller\n```\n", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Procedure Calls", "Header 2": "Using More Registers", "Header 3": "Nested Procedures", "path": "../pages/digitalGarden/cs/computerArchitecture/riscV/procedureCalls.mdx"}, "page_content": "Procedures that do not call other procedures are called leaf procedures. But these are very rarely seen in programs, much more often we see nested procedures or even recursive procedures which need a lot of care when working with registers. For example, imagine the Procedure $A$ is called and the argument 3 is stored in `x10` and return address in `x1`. If $A$ then wants to call the procedure $B$ the argument in `x10` and return address in `x1` must be overwritten. So to prevent these collisions we must carefully push data to the stack and retrieve it again at a later time. \nTo aid this tricky task of keeping track of the local data of a procedure some RISC-V compilers use a frame pointer `fp` which is stored in the register `x8`. As the stack pointer can always change the frame pointer offers a stable base register for local memory references. \n \n\n```c\nint fact(int n)\n{\nif (n < 1)\nreturn 1;\nelse\nreturn n * fact(n-1);\n}\n``` \n```assembly\nfact:\naddi sp, sp, -8 # make space for 8 bytes\nsw x1, 4(sp) # save return address\nsw x10, 0(sp) # save n\naddi x11, x10, -1 # x11 <- n - 1\nbge x11, zero, L1 # if (x11 >= 0), goto L1\naddi x10, zero, 1 # x10 <- 1 (retval)\naddi sp, sp, 8 # adjust stack\njalr zero, 0(x1) # return\nL1:\naddi x10, x10, -1 # x10 <- n - 1\njal x1, fact # call fact(n-1)\naddi t1, x10, 0 # t1 <- fact(n-1)\nlw x10, 0(sp) # restore n\nlw x1, 4(sp) # restore return address\naddi sp, sp, 8 # adjust stack pointer\nmul x10, x10, t1 # x10 <- n * t1 (retval)\njalr zero, 0(x1) # return\n```\n", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Pseudo Instructions", "path": "../pages/digitalGarden/cs/computerArchitecture/riscV/pseudoInstructions.mdx"}, "page_content": "As I have already mentioned multiple times, some RISC-V implementations also offer pseudo instructions which are like aliases for other instructions but make the assembly code easier to read and understand. \n", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Data Transfer Operations", "path": "../pages/digitalGarden/cs/computerArchitecture/riscV/dataTransfer.mdx"}, "page_content": "Just using registries to store data is not enough which is why we also have main memory and secondary memory. Main memory is especially useful when working with composite data such as data structures or dynamic data. \nAs mentioned previously we can not directly work on data that is stored in memory, the CPU can only work on data that is in a registry. This leads us to load and store data between the registries and the main memory. \nEach byte in memory has an address. For composite data, RISC-V uses the little endian byte ordering meaning that the LSB byte is at the smallest address. \nRISC-V defines a word as data that consists of 32 bits this corresponds to the size of the registry and is the most common size to read and write to and from memory. However, we can also only read a byte which is useful since ASCII only uses a byte. RISC-V also supports reading a so-called halfword which corresponds to 16 bits which is useful when working with Unicode characters. \nWe do however need to keep in mind that in memory we only store the value, no context. So if we want a word to be handled like an unsigned integer we also need to specify that otherwise, it will treat it by default as a signed integer. \n| Instruction | Type | Example | Meaning |\n| ---------------------- | ---- | -------------------- | ------------------------------------------------ |\n| Load word | I | `lw rd, imm12(rs1)` | `R[rd] = Mem4[R[rs1] + SignExt(imm12)]` |\n| Load halfword | I | `lh rd, imm12(rs1)` | `R[rd] = SignExt(Mem2[R[rs1] + SignExt(imm12)])` |\n| Load byte | I | `lb rd, imm12(rs1)` | `R[rd] = SignExt(Mem1[R[rs1] + SignExt(imm12)])` |\n| Load word unsigned | I | `lwu rd, imm12(rs1)` | `R[rd] = ZeroExt(Mem4[R[rs1] + SignExt(imm12)])` |\n| Load halfword unsigned | I | `lhu rd, imm12(rs1)` | `R[rd] = ZeroExt(Mem2[R[rs1] + SignExt(imm12)])` |", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Data Transfer Operations", "path": "../pages/digitalGarden/cs/computerArchitecture/riscV/dataTransfer.mdx"}, "page_content": "| Load word unsigned | I | `lwu rd, imm12(rs1)` | `R[rd] = ZeroExt(Mem4[R[rs1] + SignExt(imm12)])` |\n| Load halfword unsigned | I | `lhu rd, imm12(rs1)` | `R[rd] = ZeroExt(Mem2[R[rs1] + SignExt(imm12)])` |\n| Load byte unsigned | I | `lbu rd, imm12(rs1)` | `R[rd] = ZeroExt(Mem1[R[rs1] + SignExt(imm12)])` |\n| Store word | S | `sw rs2, imm12(rs1)` | `Mem4[R[rs1] + SignExt(imm12)] = R[rs2]` |\n| Store halfword | S | `sh rs2, imm12(rs1)` | `Mem2[R[rs1] + SignExt(imm12)] = R[rs2](15:0)` |\n| Store byte | S | `sb rs2, imm12(rs1)` | `Mem1[R[rs1] + SignExt(imm12)] = R[rs2](7:0)` |", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Data Transfer Operations", "Header 2": "Loading With Pointers", "path": "../pages/digitalGarden/cs/computerArchitecture/riscV/dataTransfer.mdx"}, "page_content": "Pointers in C are nothing else but memory addresses which means we can also load data from and to them. The most simple use of pointers is to swap to values: \n```c\n// x in a0, y in a1\nvoid swap(int *x, int *y)\n{\nint temp_x = *x;\nint temp_y = *y;\n*x = temp_y;\n*y = temp_x;\n}\n``` \nAnd as we can see we can use addresses stored in registries to load and write data: \n```assembly\nlw a4, 0(a0)\nlw a5, 0(a1)\nsw a5, 0(a0)\nsw a4, 0(a1)\n```", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Data Transfer Operations", "Header 2": "Loading Sequential Data", "path": "../pages/digitalGarden/cs/computerArchitecture/riscV/dataTransfer.mdx"}, "page_content": "When reading sequential data we do need to keep in mind that each address only corresponds to a byte. This leads us to make \"jumps\" of size 4. \n\n```c\n// h in x21, base address of A in x22\nA[9] = h + A[8]\n``` \n```assembly\nlw x9, 32(x22)\nadd x9, x21, x9\nsw x9, 46(x22)\n```\n", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Control Transfer Operations", "path": "../pages/digitalGarden/cs/computerArchitecture/riscV/controlTransfer.mdx"}, "page_content": "When programming we often find ourselves using control structures like if and else this creates branches in our program where we either go down one or the other branch. RISC-V offers so-called branch instructions which in most cases take 2 operands and a Label to jump to after checking the condition. Labels are not some magic keywords, they are just an offset off the program counter, PC that is automatically handled by the assembler. \n| Instruction | Type | Example | Meaning |\n| ------------------------------------- | ---- | ---------------------- | ------------------------------------------------------- |\n| Branch equal | SB | `beq rs1, rs2, imm12` | `if (R[rs1] == R[rs2]) pc = pc + SignExt(imm12 << 1)` |\n| Branch not equal | SB | `bne rs1, rs2, imm12` | `if (R[rs1] != R[rs2]) pc = pc + SignExt(imm12 << 1)` |\n| Branch greater than or equal | SB | `bge rs1, rs2, imm12` | `if (R[rs1] >= R[rs2]) pc = pc + SignExt(imm12 << 1)` |\n| Branch greater than or equal unsigned | SB | `bgeu rs1, rs2, imm12` | `if (R[rs1] >=u R[rs2]) pc = pc + SignExt(imm12 << 1)` |\n| Branch less than | SB | `blt rs1, rs2, imm12` | `if (R[rs1] < R[rs2]) pc = pc + SignExt(imm12 << 1)` |\n| Branch less than unsigned | SB | `bltu rs1, rs2, imm12` | `if (R[rs1] < u R[rs2]) pc = pc + SignExt(imm12 << 1)` | \nIn RISC-V you might notice that there is no greater then or less than or equal. This is because we can emulate these by just switching the operands, however, most CPUs have pseudo instructions to make the assembly code more readable. \n\n```c\n// i in x22, j in x23, f in x19, g in x20, h in x21\nif (i == j)\nf = g + h;\nelse\nf = g – h;\n```", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Control Transfer Operations", "path": "../pages/digitalGarden/cs/computerArchitecture/riscV/controlTransfer.mdx"}, "page_content": "\n```c\n// i in x22, j in x23, f in x19, g in x20, h in x21\nif (i == j)\nf = g + h;\nelse\nf = g – h;\n``` \nIn the code below we can also see a so-called unconditional branch meaning we always jump to the given Label. This unconditional branch makes us of the register `x0` always holding the value 0. \n```assembly\nbne x22, x23, L1\nadd x19, x20, x21\nbeq x0, x0, Exit # unconditional", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Control Transfer Operations", "path": "../pages/digitalGarden/cs/computerArchitecture/riscV/controlTransfer.mdx"}, "page_content": "L1:\nsub x19, x20, x21\nExit:\n```\n", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Control Transfer Operations", "Header 2": "Basic Blocks", "path": "../pages/digitalGarden/cs/computerArchitecture/riscV/controlTransfer.mdx"}, "page_content": "A basic block is a small building block for a program. It is a sequence of instructions that has no branch calls except for at the end and no has no branch target apart from at the beginning. A goal of the compiler to make as many big basic blocks as it can as this is better for optimization and reusability. \n\nLet us compare to different assembler outputs for the same code and look at their basic blocks. Our code does the following: \n```c\nint fact_while (int x) {\nint result = 1;\nwhile (x > 1) {\nresult *= x;\nx = x – 1;\n}\nreturn result;\n}\n``` \nIt is common to rewrite loops as goto commands when trying to convert high-level code to assembler code. \n```c\nint fact_while (int x) {\nint result = 1;\nLoop:\nif (x <= 1) goto Exit;\nresult = result * x;\nx = x – 1;\ngoto Loop;\nExit:\nreturn result;\n}\n``` \n```assembly\nfact_while:\naddi a5, a0, 0 # a5 = x (x)\naddi a0, zero, 1 # a0 = 1 (result)\nLoop:\naddi a4, zero, 1 # a4 = 1\nble a5, a4, Exit # if (x <= 1) goto Exit\nmul a0, a0, a5 # result *= x\naddi a5, a5, -1 # x = x – 1\nbeq zero, zero, Loop # goto Loop\nExit:\n``` \nThe assembly code above has 3 small basic blocks but if we convert the C code to this structure we can decrease the amount of basic blocks and increase their size. \n```c\nint fact_while2 (int x) {\nint result = 1;\nif (x <= 1) goto Exit;\nLoop:\nresult = result * x;\nx = x – 1;\nif (x != 1) goto Loop;\nExit:\nreturn result;\n}\n``` \n```assembly\nfact_while2:\naddi a5, a0, 0 # a5 = x (x)\naddi a4, zero, 1 # a4 = 1\naddi a0, zero, 1 # a0 = 1 (result)\nble a5, a4, Exit # if (x <= 1) goto Exit\nLoop:\nmul a0, a0, a5 # result *= x\naddi a5, a5, -1 # x = x – 1\nbne a5, a4, Loop # if (x != 1) goto Loop\nExit:\n```\n", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Control Transfer Operations", "Header 2": "Target Adressing", "path": "../pages/digitalGarden/cs/computerArchitecture/riscV/controlTransfer.mdx"}, "page_content": "When jumping using the branch instructions most jumps are not very far. As mentioned before the label is like an immediate offset meaning it can be up to 12 bits long. If we want to jump further we can use one of the commands below. The `jal` instruction stands for jump and link, we jump using the passed offset which can now be 20 bits long. We also store the current PC i.e the return address into the corresponding `rd` register. If we want to jump even further then we can load a large immediate into a temporary register using the `lui` instruction and then add the remaining 12 bits and jump at the same time using the `jalr` instructions which also lets us read the offset from a register. \n| Instruction | Type | Example | Meaning |\n| ------------------------------------- | ---- | ---------------------- | ------------------------------------------------------- |\n| Jump and link | UJ | `jal rd, imm20` | `R[rd] = pc + 4; pc = pc + SignExt(imm20 << 1)` |\n| Jump and link register | I | `jalr rd, imm12(rs1)` | `R[rd] = pc + 4; pc = (R[rs1] + SignExt(imm12)) & (~1)` | \n\nWe can also use the `jal` instruction as an unconditional branch by using the zero register as the return address, which is the same as discarding it: \n```assembly\njal x0, Label\n```\n", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Arithmetic and Logical Operations", "path": "../pages/digitalGarden/cs/computerArchitecture/riscV/arithmeticLogical.mdx"}, "page_content": "Arithmetic and logical operations are some of the key building blocks for writing any program as almost any functionality boils down to them.", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Arithmetic and Logical Operations", "Header 2": "Arithmetic Operations", "path": "../pages/digitalGarden/cs/computerArchitecture/riscV/arithmeticLogical.mdx"}, "page_content": "In RISC-V all arithmetic operations have the same form, two sources (b and c) and one destination (a). Later on, we will learn more forms of operations and also how these operations are encoded to machine code, i.e to binary digits. \n```assembly\nadd x20, x21, x20\n``` \nThis is in aid of the first design principle of RISC-V \n> Simplicity favors regularity. \n\nIf we have the following C code \n```c\n// f in x19, g in x20, h in x21\n// i in x22, j in x23\nf = (g + h) – (i + j);\n``` \nand we compile it we can expect that the following RISC-V code will be assembled. \n```assembly\nadd x5, x20, x21\nadd x6, x22, x23\nsub x19, x5, x6\n``` \nHere we make use of the temporary registers `x5` and `x6`.\n \nWe will see what the immediate instructions are for further down. \n| Instruction | Type | Example | Meaning |\n| -------------------------------- | ---- | ---------------------- | ------------------------------------------- |\n| Add | R | `add rd, rs1, rs2` | `R[rd] = R[rs1] + R[rs2]` |\n| Subtract | R | `sub rd, rs1, rs2` | `R[rd] = R[rs1] – R[rs2]` |\n| Add immediate | I | `addi rd, rs1, imm12` | `R[rd] = R[rs1] + SignExt(imm12)` |\n| Set less than | R | `slt rd, rs1, rs2` | `R[rd] = (R[rs1] < R[rs2])? 1 : 0` |\n| Set less than immediate | I | `slti rd, rs1, imm12` | `R[rd] = (R[rs1] < SignExt(imm12))? 1 : 0` |\n| Set less than unsigned | R | `sltu rd, rs1, rs2` | `R[rd] = (R[rs1] Make the common case fast. \nImmediate operands are faster as they avoid a load instruction. However, due to the way instructions are encoded we can only use constants that use up to 12 bits. However, later on, we will see how we can work with larger constants. \n```assembly\naddi x22, x22, 4\n```", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Arithmetic and Logical Operations", "Header 2": "Logical Operations", "path": "../pages/digitalGarden/cs/computerArchitecture/riscV/arithmeticLogical.mdx"}, "page_content": "We also often find ourselves manipulating or working with bits which is what the logical operations are for. They are in most high-level programming languages the same with the most common exception being for the arithmetic or logical shift right operation. The key difference between these 2 is that the arithmetic version fills the left with zeros where as the logical version fills it with the sign bit resulting in a sign-extension to preserve the decimal value. \n| Instruction | Type | Example | Meaning |\n| -------------------------------- | ---- | --------------------- | --------------------------------------- |\n| AND | R | `and rd, rs1, rs2` | `R[rd] = R[rs1] & R[rs2]` |\n| OR | R | `or rd, rs1, rs2` | `R[rd] = R[rs1] | R[rs2]` |\n| XOR | R | `xor rd, rs1, rs2` | `R[rd] = R[rs1] ^ R[rs2]` |\n| AND immediate | I | `andi rd, rs1, imm12` | `R[rd] = R[rs1] & SignExt(imm12)` |\n| OR immediate | I | `ori rd, rs1, imm12` | `R[rd] = R[rs1] | SignExt(imm12)` |\n| XOR immediate | I | `xori rd, rs1, imm12` | `R[rd] = R[rs1] ^ SignExt(imm12)` |\n| Shift left logical | R | `sll rd, rs1, rs2` | `R[rd] = R[rs1] << R[rs2]` |\n| Shift right arithmetic | R | `sra rd, rs1, rs2` | `R[rd] = R[rs1] >> R[rs2] (arithmetic)` |\n| Shift right logical | R | `srl rd, rs1, rs2` | `R[rd] = R[rs1] >> R[rs2] (logical)` |\n| Shift left logical immediate | I | `slli rd, rs1, shamt` | `R[rd] = R[rs1] << shamt` |\n| Shift right logical immediate | I | `srli rd, rs1, shamt` | `R[rd] = R[rs1] >> shamt (logical` |\n| Shift right arithmetic immediate | I | `srai rd, rs1, shamt` | `R[rd] = R[rs1] >> shamt (arithmetic)` |", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Arithmetic and Logical Operations", "Header 2": "Logical Operations", "path": "../pages/digitalGarden/cs/computerArchitecture/riscV/arithmeticLogical.mdx"}, "page_content": "| Shift right logical immediate | I | `srli rd, rs1, shamt` | `R[rd] = R[rs1] >> shamt (logical` |\n| Shift right arithmetic immediate | I | `srai rd, rs1, shamt` | `R[rd] = R[rs1] >> shamt (arithmetic)` | \nIf we look at the RISC-V logical operations there isn't anything special apart from there not being a NOT operation. This is because it can be simply implemented by using the XOR operation which sets a bit to 1 if the bits are different and otherwise a 0. To be more precise we XOR with the value that only consists of positive bits to simulate a NOT operation. However, we will come across pseudo instructions where there will be a NOT operation.", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Arithmetic and Logical Operations", "Header 2": "Operations With Large Constants", "path": "../pages/digitalGarden/cs/computerArchitecture/riscV/arithmeticLogical.mdx"}, "page_content": "If we want to work with constants larger than 12 bits we need to do use the following instruction: \n```assembly\nlui x19, 0x003D0\n``` \nThis instruction stands for load upper immediate and allows us to load the 20 most significant bits into a registry. The 12 remaining bits will be set to 0 but we can also set these by either adding or using an OR operation. \n", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Arithmetic and Logical Operations", "Header 2": "Assembly Optimization", "path": "../pages/digitalGarden/cs/computerArchitecture/riscV/arithmeticLogical.mdx"}, "page_content": "One of the main goals of a compiler is to optimize the program when writing the assembly code. \n```c\n// x in a0, y in a1\nint logical (int x, int y) {\nint t1 = x ^ y;\nint t2 = t1 >> 17;\nint mask = (1 << 8) – 7;\nint rval = t2 & mask;\nreturn rval;\n}\n``` \n```assembly\nxor a0, a0, a1 # a0 = x ^ y (t1)\nsrai a0, a0, 17 # a0 = t1 >> 17 (t2)\nandi a0, a0, 249 # a0 = t2 & ((1 << 8) – 7)\n``` \nIn the above example, we can see that a few simple optimizations have been made: \n- Because x is only needed once we can use its registry to store the result of the first line instead of having to use a separate temporary registry\n- The calculation of the mask only consists of constants, which means it can be calculated at runtime. This results in the last two statements being combined into one instruction. \n```c\n// x in a0, y in a1, z in a2\nint arith (int x, int y, int z) {\nint t1 = x + y;\nint t2 = z + t1;\nint t3 = x + 4;\nint t4 = y * 48;\nint t5 = t3 + t4;\nint rval = t2 - t5;\nreturn rval;\n}\n``` \n```assembly\nadd a5, a0, a1 # a5 = x + y (t1)\nadd a2, a5, a2 # a2 = t1 + z (t2)\naddi a0, a0, 4 # a0 = x + 4 (t3)\nslli a5, a1, 1 # a5 = y * 2\nadd a1, a5, a1 # a1 = a5 + y\nslli a5, a1, 4 # a5 = a1 * 16 (t4)\nadd a0, a0, a5 # a0 = t3 + t4 (t5)\nsub a0, a2, a0 # a0 = t2 – t5 (rval)\n``` \nIn this example the assembly code is actually longer then the C code. However, it has been optimzed, length of code does not correspond to efficiency. To be more precise the multiplication has been optimized because multiplicaitons are very slow. So instead of multiplying the compiler tries to make use of bit shifts which are much fast. So `y * 48` becomes `(3y) << 4`. Another example of this would be replacint `7 * x` with `8 * x - x` which can be translated to `(x << 3) - x`.", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Template method", "path": "../pages/digitalGarden/cs/patterns/templateMethod.mdx"}, "page_content": "The intent of the template method pattern is to define a skeleton of an algorithm in the superclass but lets subclasses override specific steps of the algorithm without changing itsstructure.", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Template method", "Header 2": "Structure", "path": "../pages/digitalGarden/cs/patterns/templateMethod.mdx"}, "page_content": "```mermaid\nclassDiagram\nAbstractClass <|-- ConcreteClass1\nAbstractClass <|-- ConcreteClass2\nAbstractClass <|-- ConcreteClass3\nclass AbstractClass{\n+algorithm()\n+step1()\n+step2()\n}\nclass ConcreteClass1{\n+step1()\n+step2()\n}\nclass ConcreteClass2{\n+step1()\n+step2()\n}\nclass ConcreteClass3{\n+step2()\n}\n```", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Composite", "path": "../pages/digitalGarden/cs/patterns/composite.mdx"}, "page_content": "The intent of the composite pattern is to represent a recursive tree like structures where individual objects or compositions of objects should be treated uniformly. The most common example is your file structure you have folders and files and folders with files inside other folders etc. You can the perform operations like delete or move on either a single file or folder.", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Composite", "Header 2": "Structure", "path": "../pages/digitalGarden/cs/patterns/composite.mdx"}, "page_content": "```mermaid\nclassDiagram\nComponentInterface <--o Composite\nComponentInterface <|-- Leaf\nComponentInterface <|-- Composite\nclass ComponentInterface{\n+execute()\n}\nclass Leaf{\n+execute()\n}\nclass Composite{\n-children: Component[]\n+add()\n+remove()\ngetChildren()\nexecute() // delegates all work to children\n}\n```", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Composite", "Header 2": "Things to be aware of", "Header 3": "Placement of managing functions", "path": "../pages/digitalGarden/cs/patterns/composite.mdx"}, "page_content": "There are 2 possibilities to place the managing functions(add, remove etc.) either in the Component or in the composite. If you place them in the Composite (Safe) there is a clear separation of tasks and are only defined where they are usable, however you might have to make type casts. If you place them in the Component (Transparent) you have a unified look however have to provide the functionality for all components which might not necessarly make sense.", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Composite", "Header 2": "Things to be aware of", "Header 3": "No cycles", "path": "../pages/digitalGarden/cs/patterns/composite.mdx"}, "page_content": "To make sure that one element is not in 2 composites or that there are cycles (a composite is in a higher composite but the higher composite is also in the lower composite). We can add a flag to the abstract class Component to solve this. When adding to a composite we can then make the following checks: \n```java\npublic void addFigure(Figure f) {\nif (f.contained)\nthrow new IllegalArgumentException();\nif (contains(f, this)) {\nthrow new IllegalArgumentException();\n}\nfigures.add(f);\nf.contained = true;\n}\n\nprivate boolean contains(Figure g1, GroupFigure g2) {\nif (g1 == g2) {\nreturn true;\n} else if (g1 instanceof GroupFigure) {\nfor (Figure f : ((GroupFigure) g1).figures) {\nif (contains(f, g2))\nreturn true;\n}\n} return false;\n}\n```", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Strategy", "path": "../pages/digitalGarden/cs/patterns/strategy.mdx"}, "page_content": "The intent of the strategy pattern is to be able to define a family of algorithms that are interchangable and we can easly add more algorithms if needed. So we also want to be able to change behavior just like in the state pattern. For example we want to support multiple different de/encryption methods. If the algorithm only changes based in its parameters we are not speaking of the strategy pattern.", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Strategy", "Header 2": "Structure", "path": "../pages/digitalGarden/cs/patterns/strategy.mdx"}, "page_content": "We can see that the Class Diagram is very similiar to that of the state pattern. Importantly here is that the interface is powerful enough to support all current algorithms and also those in the future. \n```mermaid\nclassDiagram\nStrategyInterface <--o Context\nStrategyInterface <|-- VariantA\nStrategyInterface <|-- VariantB\nclass Context{\n}\nclass StrategyInterface{\nalgorithm()\n}\nclass VariantA{\nalgorithm()\n}\nclass VariantB{\nalgorithm()\n}\n```", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Strategy", "Header 2": "Example", "path": "../pages/digitalGarden/cs/patterns/strategy.mdx"}, "page_content": "```java\npublic class SecureChannel{\npublic interface Algorithm{\npublic int[] encrypt(byte[] key, int[] plain);\npublic int[] decrypt(byte[] key, int[] encrypted);\n}\nprivate Algorithm algorithm;\npublic void setAlgorithm(Algorithm algorithm) {\nif (algorithm == null) throw new IllegalArgumentException();\nthis.algorithm= algorithm;\n}\npublic void send(byte[] key, int[] plain) {\nwrite(algorithm.encrypt(key, plain));\n}\npublic int[] receive(byte[] key) {\nreturn algorithm.decrypt(key, read());\n}\n}\n```", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Prototype", "path": "../pages/digitalGarden/cs/patterns/prototype.mdx"}, "page_content": "The intent of the prototype pattern is to be able to create new objects by cloning/copying prototype objects.", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Prototype", "Header 2": "Structure", "path": "../pages/digitalGarden/cs/patterns/prototype.mdx"}, "page_content": "```mermaid\nclassDiagram\nPrototypeInterface <|-- ConcretePrototype\nConcretePrototype <|-- SubClassPrototype\nclass PrototypeInterface{\nclone()\n}\nclass ConcretePrototype{\nclone()\n}\nclass SubClassPrototype{\nclone()\n}\n```", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Prototype", "Header 2": "Solutions", "Header 3": "Cloning based on Object.clone()", "path": "../pages/digitalGarden/cs/patterns/prototype.mdx"}, "page_content": "In java the following clone method is defined. \n```java\nclass Object {\nprotected Object clone() throws CloneNotSupportedException\n...\n}\n}\n``` \nThe protected visibility means it can not be invoked on objects of static type and can only be invoked if clone is overridden in a subclass with a suitable visibility. \n1. It is checked whether the class implements interface Cloneable (which is only a marker interface). If this is not the case, a CloneNotSupportedException is thrown.\n2. A new instance is created, i.e. as much memory as used by the original object is allocated however no constructor is invoked.\n3. Instead, the memory of the original object is copied byte by byte into the new instance (a so called memory copy) this means that all attributes are copied over into the new instance if there are fields that are not value types like int etc. but Objects like string etc. then the references are copied resulting in a shallow copy. \nIf you wish for it not to be a shallow copy you have to override the clone method and clone all the object attributes correctly. When overriding the clone method you can strengthen the result type i.e not returning Object but the correct type. Final fields will just be copied they can not be changed if this is needed then you need to use copy constructors.", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Prototype", "Header 2": "Solutions", "Header 3": "Cloning based on copy constructors", "path": "../pages/digitalGarden/cs/patterns/prototype.mdx"}, "page_content": "Copy constructors are constructors that receive an instance of their own type as parameter. They then initialize the new instance with the same values as the prototype passed.", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Prototype", "Header 2": "Solutions", "Header 3": "Cloning based on serialization", "path": "../pages/digitalGarden/cs/patterns/prototype.mdx"}, "page_content": "If all the classes to be cloned are serializable (implement the Serializable interface), cloning can also be implemented with the help of Java serialization. The clone method which follows this approach looks as follows \n```java\nObject clone() {\nByteArrayOutputStream baos = new ByteArrayOutputStream();\nObjectOutputStream oos = new ObjectOutputStream(baos);\noos.writeObject(this);\noos.close();\nbyte buf[] = baos.toByteArray();\nByteArrayInputStream bais = new ByteArrayInputStream(buf);\nObjectInputStream ois = new ObjectInputStream(bais);\nObject c = ois.readObject();\nreturn c;\n}\n```", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "OOP Design Principles", "Header 2": "SOLID", "path": "../pages/digitalGarden/cs/patterns/oopDesignPrinciples.mdx"}, "page_content": "The SOLID principles are a set of five design principles that help software developers create more maintainable,\nflexible, and robust code. They were frist introduced by Robert C. Martin \"Uncle Bob\" in his book \"Agile Software\nDevelopment, Principles, Patterns, and Practices\".", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "OOP Design Principles", "Header 2": "SOLID", "Header 3": "Single Responsibility Principle", "path": "../pages/digitalGarden/cs/patterns/oopDesignPrinciples.mdx"}, "page_content": "A class/method should only have a single purpose/responsibility and therefore only one reason to change. \n", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "OOP Design Principles", "Header 2": "SOLID", "Header 3": "Open/Closed Principle", "path": "../pages/digitalGarden/cs/patterns/oopDesignPrinciples.mdx"}, "page_content": "Classes should be open for extension but closed for modification. To extend the behavior, new code should be added however old code should not have to be modified. This then prevents situations in which a change to classes also requires adaption of all depending classes. This is achieved with interfaces which allow different implementations by keep the same API. \n", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "OOP Design Principles", "Header 2": "SOLID", "Header 3": "Liskov Substitution Principle", "path": "../pages/digitalGarden/cs/patterns/oopDesignPrinciples.mdx"}, "page_content": "Subtypes should be substitutable for their base types. \n", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "OOP Design Principles", "Header 2": "SOLID", "Header 3": "Interface Segregation Principle", "path": "../pages/digitalGarden/cs/patterns/oopDesignPrinciples.mdx"}, "page_content": "Make fine-grained interfaces that are client specific instead of general purpose interfaces (Which slightly contradicts the strategy pattern). Clients should not be forced to depend on methods that they do not use. \n", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "OOP Design Principles", "Header 2": "SOLID", "Header 3": "Dependency Inversion Principle", "path": "../pages/digitalGarden/cs/patterns/oopDesignPrinciples.mdx"}, "page_content": "Depend on Abstractions not on concrete classes etc. \n", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "OOP Design Principles", "Header 2": "Other Good Coding Principles", "Header 3": "Favor Composition over Inheritance", "path": "../pages/digitalGarden/cs/patterns/oopDesignPrinciples.mdx"}, "page_content": "By using composition for example in the strategy pattern instead of inheritance it allows us to be flexible at runtime.", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "OOP Design Principles", "Header 2": "Other Good Coding Principles", "Header 3": "Program to an interface, not and implementation", "path": "../pages/digitalGarden/cs/patterns/oopDesignPrinciples.mdx"}, "page_content": "Avoid referencing concrete classes, declare interfaces instead as then implementations are easily switched out.", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "OOP Design Principles", "Header 2": "Other Good Coding Principles", "Header 3": "Encapsulate what varies", "path": "../pages/digitalGarden/cs/patterns/oopDesignPrinciples.mdx"}, "page_content": "By encapsulating/hiding the parts that can vary for example implementations behind interfaces we can minimize the impact\nof that code because thanks to the interface we have a unified API.", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "OOP Design Principles", "Header 2": "Other Good Coding Principles", "Header 3": "KISS", "path": "../pages/digitalGarden/cs/patterns/oopDesignPrinciples.mdx"}, "page_content": "Keep it simple stupid. The simpler the code the easier it is to maintain and understand.", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Factory", "path": "../pages/digitalGarden/cs/patterns/factory.mdx"}, "page_content": "Factory patterns are so called creational patterns meaning their intent is to abstract/hide how objects are created. Which in return allows the client to be in independent of how its objects are created.", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Factory", "Header 2": "Factory method", "path": "../pages/digitalGarden/cs/patterns/factory.mdx"}, "page_content": "The factory method pattern delegates the instantiation of objects to a method in either subclasses or a static method. The disadvantage of having the factory method as a static method is it can not be subclassed to change the behavior however you don't need to create an object to make use of the method.", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Factory", "Header 2": "Factory method", "Header 3": "Structure", "path": "../pages/digitalGarden/cs/patterns/factory.mdx"}, "page_content": "```mermaid\nclassDiagram\nCreator <|-- ConcreteCreator\nCreator --> ProductInterface\nProductInterface <|-- ConcreteProduct\nclass Creator{\n+someOperation()\n+createProduct(): Product\n}\nclass ProductInterface{\n}\nclass ConcreteProduct{\n}\nclass ConcreteCreator{\n+createProduct(): Product\nreturns a ConcreteProduct\n}\n```", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Factory", "Header 2": "Factory method", "Header 3": "Example", "path": "../pages/digitalGarden/cs/patterns/factory.mdx"}, "page_content": "", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Factory", "Header 2": "Abstract factory", "path": "../pages/digitalGarden/cs/patterns/factory.mdx"}, "page_content": "The factory method pattern delegates the instantiation of object familys to a another object.", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Factory", "Header 2": "Abstract factory", "Header 3": "Structure", "path": "../pages/digitalGarden/cs/patterns/factory.mdx"}, "page_content": " \nA big question here is where is the concrete Factory so they can all have acces to it. Often this is done in it's own class \n```java\npublic class CurrentFactory {\nprivate CurrentFactory() { }; // prevents instantiation\nprivate static Factory fac = null;\npublic static Factory getFactory() { return fac; }\npublic static void setFactory(Factory f) {\nif (f == null) throw new NullPointerException();\nfac = f;\n}\n}\n```", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Factory", "Header 2": "Abstract factory", "Header 3": "Example", "path": "../pages/digitalGarden/cs/patterns/factory.mdx"}, "page_content": "", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Iterators", "path": "../pages/digitalGarden/cs/patterns/iterator.mdx"}, "page_content": "Often times you find yourself traversing/iterating over a [collection](../algorithmsDataStructures/collections). The iterator pattern encapsulates this functionality without exposing its underlying representation of the collection. In java this pattern is used to implement the enhanced for or also called for-each loop. Under the hood all the for each loop does is get an iterator instance and iterate over it step by step, this is also why you can only use the for-each loop on collections that actually implement the [`Iterable`](https://docs.oracle.com/javase/8/docs/api/java/lang/Iterable.html) interface. \nWhy is this pattern useful? \n- Because depending on the collection there might be different ways to traverse it, for example [binary trees can be traversed in many orders](../algorithmsDataStructures/trees/binaryTrees#traversal-orders) but the methods you call to traverse the collection should be the same. We want a common interface for traversing different collections in different ways.\n- Also, because the iterator object holds all the details regarding the traversal of the collection, several iterators can go through the same collection at the same time, independently of each other as long as they don't change the underlying collection, if they do it gets a bit complicated with [mutexes](../concurrentProgramming/locking#locks). \n", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Iterators", "Header 2": "Structure", "path": "../pages/digitalGarden/cs/patterns/iterator.mdx"}, "page_content": "The `Iterable` interface defines the method `Iterator iterator()`, or `Iterator createIterator()`which is responsible for creating and returning the [iterator interface](https://docs.oracle.com/javase/8/docs/api/java/util/Iterator.html) that can then be used to traverse the collection containing elements of type `T`. \nAn iterator always holds the value of the next element, apart from at the beginning of an iteration, where it holds a reference to the first element. In java the iterator instance returned must implement the `Iterator` interface which declares the operations required for traversing the collection. \n\nAn animation of the iterator moving through a linked list would be cool.\n \n\nWhen implementing an iterator it is recommended to do so in an internal private final class in the collection class as you then have access to the internal structure of the collection without having to make all the details public.\n \nThe pattern then has an overall structure that can look something like this: \n```plantuml\n@startuml\n!theme purplerain from https://raw.githubusercontent.com/LuciferUchiha/nextra-garden/main\ninterface \"Iterable\" as Iterable {\nIterator iterator()\n}\n\ninterface \"Iterator\" as Iterator {\nT next()\nboolean hasNext()\n}\nclass \"ConcreteIterator\" as ConcreteIterator {\nT next()\nboolean hasNext()\n}\nclass \"Collection\" as Collection {\nIterator iterator()\n}\n\nCollection --|> Iterable\nConcreteIterator --|> Iterator\nCollection --> ConcreteIterator\nIterable --> Iterator\n@enduml\n``` \n- The `T next()` method returns the element the iterator is currently pointing to and advances the iterator to the next element.\n- The `boolean hasNext()` method returns false once the iterator has reached the end of the collection, otherwise true.", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Iterators", "Header 2": "ListIterator", "path": "../pages/digitalGarden/cs/patterns/iterator.mdx"}, "page_content": "In Java, there is also the [`ListIterator`](https://docs.oracle.com/javase/8/docs/api/java/util/ListIterator.html) interface which extends the `Iterator` interface. This interface adds functionality that allows for iteration in both directions with `T next()` and `T previous()`. Matchingly it also offers a `boolean hasPrevious()` to the `boolean hasNext()` method. One can imagine that ListIterator has no current element, its position is always between the element that would be returned by a call to `previous()` and the element that would be returned by a call to `next()`. \nBecause the iterator traverses a collection like a list it also works and assigns an index to each element which can be fetched.", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Iterators", "Header 2": "Removing Elements", "path": "../pages/digitalGarden/cs/patterns/iterator.mdx"}, "page_content": "The iterator interface also defines an optional `void remove()` method, that removes the most recently returned element from the iterator. \n \nHowever, when removing elements whilst other iterators are also traversing the collection, for example in a concurrent program some problems can occur, mainly in consistent state and iterator pointers getting cut of from iterating further. One way of solving these problems is by using a modification counter (modCount) which is incremented whenever the underlying collection is changed, for example when adding or removing an element. When an iterator is instantiated the modCount is copied and continuously checked if it is the same as the underlying modCount of the collection if not then a `ConcurrentModificationException` is thrown. How this works for different collections in java is [explained here](https://stackoverflow.com/a/5847949/10994912).", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Iterators", "Header 2": "Implementation", "path": "../pages/digitalGarden/cs/patterns/iterator.mdx"}, "page_content": "A possible implementation for an iterator over a [linked list](../algorithmsDataStructures/linkedLists) could look like this: \n```java\n\nclass SomeCollection implements Iterable {\n\n//implementation of other functions and internal state\n\n@Override\npublic Iterator iterator() {\nreturn new MyIterator();\n}\n\nprivate final class MyIterator implements Iterator {\n// p and pp keeps track of the previous elements to be able to remove\nprivate Node next = first, p = null, pp = null;\nprivate int myModCount = modCount; // copy the modCount of the collection\nprivate boolean mayRemove = false;\n\n@Override\npublic boolean hasNext() {\nreturn next != null;\n}\n\n@Override\npublic T next() {\nif (modCount != myModCount)\nthrow new ConcurrentModificationException();\nif (next == null)\nthrow new NoSuchElementException();\nT elem = next.elem;\nif (p != null) pp = p;\np = next;\nnext = next.next;\nmayRemove = true;\nreturn elem;\n}\n\n@Override\npublic void remove() {\nif (modCount != myModCount)\nthrow new ConcurrentModificationException();\nif (!mayRemove)\nthrow new IllegalStateException();\nif (pp != null) pp.next = next;\nelse first = next;\nif (next == null) last = pp;\np = pp;\nmayRemove = false;\nsize--;\nmodCount++;\nmyModCount = modCount;\n}\n}\n}\n```", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Singleton", "path": "../pages/digitalGarden/cs/patterns/singleton.mdx"}, "page_content": "The intent of the singleton pattern is that a class only has a single instance which is accessed over a global point. For example config classes should only exist once. You can do this by making the class final to stop inheritance, by making the constructor private so no instance can be created and adding a static method that creates the one instance if not already and returns it. It should either not support cloning or return the same instance(this).", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Singleton", "Header 2": "Things to be aware of", "Header 3": "Eager and lazy initialization", "path": "../pages/digitalGarden/cs/patterns/singleton.mdx"}, "page_content": "Eager means the instance is created as soon as the class is first initialized form for example other methods in the class which could use a lot of memory allthough it is not needed. \n```java\npublic final class Singleton {\nprivate Singleton(){}\nprivate static Singleton instance = new Singleton();\npublic static Singleton getInstance(){}\nreturn instance;\n}\n}\n``` \nLazy means it is created when the getInstance functions is accessed this can however cause issues with multithreading which is why you need to synchronize the method. \n```java\npublic final class Singleton {\nprivate Singleton(){}\nprivate static Singleton instance = null;\npublic static synchronized Singleton getInstance(){\nif(instance == null) instance = new Singleton();\nreturn instance;\n}\n}\n```", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Singleton", "Header 2": "Things to be aware of", "Header 3": "Garbage collection", "path": "../pages/digitalGarden/cs/patterns/singleton.mdx"}, "page_content": "Instance cannot be reclaimed by the garbage collector as they are static. So you should either use `WeakReference`(removed when not referenced by strong references) or `SoftReference`(removed when system is short of memory).", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Singleton", "Header 2": "Things to be aware of", "Header 3": "Serialization", "path": "../pages/digitalGarden/cs/patterns/singleton.mdx"}, "page_content": "Deserialization of a serialized singleton instance may lead to several singleton instances to avoid this we can do the following \n```java\npublic final class Singleton implements Serializable {\nprivate Singleton(){ }\nprivate static Singleton instance = null;\npublic static synchronized Singleton getInstance(){\nif(instance == null) instance = new Singleton();\nreturn instance;\n}\npublic Object readResolve(){\nreturn getInstance();\n}\n}\n```", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Singleton", "Header 2": "Things to be aware of", "Header 3": "Singelton with Demand Holder Idiom", "path": "../pages/digitalGarden/cs/patterns/singleton.mdx"}, "page_content": "You can also create a Singelton the following way. This solution is thread-safe and is lazy. Important is that the construction of Singelton does not fail (exceptions). \n```java\npublic class Singleton {\nprivate Singleton() {}\n\nprivate static class LazyHolder {\nstatic final Singleton INSTANCE = new Singleton();\n}\n\npublic static Singleton getInstance() {\nreturn LazyHolder.INSTANCE;\n}\n}\n```", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Singleton", "Header 2": "Things to be aware of", "Header 3": "Singelton with Enum", "path": "../pages/digitalGarden/cs/patterns/singleton.mdx"}, "page_content": "You can also create a Singelton with an Enum. It is easy, thread safe and provides the Serialization for free. However it can not be extended to multiple instances and the fields can not be serialized. \n```java\npublic enum SingletonDriver implements Driver {\nINSTANCE;\npublic String toString () { return \"Singleton \";\npublic void playSong(File file ) { ... }\n}\n```", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Command", "path": "../pages/digitalGarden/cs/patterns/command.mdx"}, "page_content": "The intent of the command pattern is to turn commands into stand-alone objects so that the object invoking the command does not need to worry about how the command is done. By doing so you can delay, queue, undo commands.", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Command", "Header 2": "Structure", "path": "../pages/digitalGarden/cs/patterns/command.mdx"}, "page_content": "```plantuml\n@startuml\n!theme purplerain from https://raw.githubusercontent.com/LuciferUchiha/georgerowlands.ch/main\n\nCommand <-- Invoker : calls\nCommand <|-- CommandImpl\nReceiver <-- CommandImpl : calls\n\nclass Invoker {\nvoid setCommand(Command c)\nvoid execute()\n}\n\ninterface Command{\nvoid execute()\nvoid undo()\n}\n\nclass Receiver{\naction()\n}\n\n@enduml\n```", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Command", "Header 2": "Example", "path": "../pages/digitalGarden/cs/patterns/command.mdx"}, "page_content": "```java\n// Client\npublic class CommandPatternDemo {\npublic static void main(String[] args) {\nStock abcStock = new Stock();\n\nBuyStock buyStockOrder = new BuyStock(abcStock);\nSellStock sellStockOrder = new SellStock(abcStock);\n\nBroker broker = new Broker();\nbroker.takeOrder(buyStockOrder);\nbroker.takeOrder(sellStockOrder);\n\nbroker.placeOrders();\n}\n}\n// Command Interface\npublic interface Order {\nvoid execute();\n}\n// Receiver\npublic class Stock {\nprivate String name = \"ABC\";\nprivate int quantity = 10;\n\npublic void buy(){\nSystem.out.println(\"Stock [ Name: \"+name+\",\nQuantity: \" + quantity +\" ] bought\");\n}\npublic void sell(){\nSystem.out.println(\"Stock [ Name: \"+name+\",\nQuantity: \" + quantity +\" ] sold\");\n}\n}\n// ConcreteCommands\npublic class BuyStock implements Order {\nprivate Stock abcStock;\n\npublic BuyStock(Stock abcStock){\nthis.abcStock = abcStock;\n}\n\npublic void execute() {\nabcStock.buy();\n}\n}\npublic class SellStock implements Order {\nprivate Stock abcStock;\n\npublic SellStock(Stock abcStock){\nthis.abcStock = abcStock;\n}\n\npublic void execute() {\nabcStock.sell();\n}\n}\n// Invoker\npublic class Broker {\nprivate List orderList = new ArrayList();\n\npublic void takeOrder(Order order){\norderList.add(order);\n}\n\npublic void placeOrders(){\nfor (Order order : orderList) {\norder.execute();\n}\norderList.clear();\n}\n}\n```", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Decorator", "path": "../pages/digitalGarden/cs/patterns/decorator.mdx"}, "page_content": "The intent of the decorator pattern is to give objects new responsibilities without overusing inheritance and therefore creating a bunch of classes. Instead Components get decorated to further enhance objects.", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Decorator", "Header 2": "Structure", "path": "../pages/digitalGarden/cs/patterns/decorator.mdx"}, "page_content": "```mermaid\nclassDiagram\nComponent <|-- IDecorator\nComponent <|-- ConcreteComponent\nIDecorator <|-- ConcreteDecoratorA\nIDecorator <|-- ConcreteDecoratorB\nComponent <-- IDecorator\nclass Component {\n+operationA()\n+operationB()\n}\nclass IDecorator {\nComponent wrappedObj\n+operationA()\n+operationB()\n}\nclass ConcreteDecoratorA{\nObject newState // can extend state\n+operationA()\n+operationB()\n}\n\nclass ConcreteDecoratorB{\n+operationA()\n+operationB()\n+newBehavior() // can add new\n}\n\nclass ConcreteComponent {\n+operationA()\n+operationB()\n}\n``` \nWith this structure you can do things in the decorator before after calling wrappedObj.operationA().", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Decorator", "Header 2": "Example", "path": "../pages/digitalGarden/cs/patterns/decorator.mdx"}, "page_content": "```java\npublic abstract class Beverage {\nString description = \"Unknown Beverage\";\n\npublic String getDescription() {\nreturn description;\n}\n\npublic abstract double cost();\n}\npublic abstract class CondimentDecorator extends Beverage {\npublic abstract String getDescription();\n}\npublic class Espresso extends Beverage {\n\npublic Espresso() {\ndescription = \"Espresso\";\n}\n\npublic double cost() {\nreturn 1.99;\n}\n}\npublic class Milk extends CondimentDecorator {\nBeverage beverage;\n\npublic Milk(Beverage beverage) {\nthis.beverage = beverage;\n}\n\npublic String getDescription() {\nreturn beverage.getDescription() + \", Milk\";\n}\n\npublic double cost() {\nreturn .10 + beverage.cost();\n}\n}\n```", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Observer", "path": "../pages/digitalGarden/cs/patterns/observer.mdx"}, "page_content": "The intent of the Observer Pattern is that there a dependant objects of another object and that these dependent objects can be notified of changes without the other object knowing of the dependent objects and the connection between the the cooperating objects being to tight. The Observer Pattern is also commonly know as listener or Publish-Subscribe pattern. \nYou can find a good detailed description [here](https://refactoring.guru/design-patterns/observer)", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Observer", "Header 2": "Structure", "path": "../pages/digitalGarden/cs/patterns/observer.mdx"}, "page_content": "```mermaid\nclassDiagram\nSubjectInterface <|-- ConcreteSubject\nSubjectInterface --> ObserverInterface\nObserverInterface <|-- ConcreteObserver\nConcreteObserver --> ConcreteSubject\nclass SubjectInterface{\n+registerObserver()\n+removeObserver()\n+notifyObservers()\n}\nclass ConcreteSubject{\n-state\n+registerObserver()\n+removeObserver()\n+notifyObserver()\n+getState()\n+setState()\n}\nclass ObserverInterface{\n+update()\n}\nclass ConcreteObserver{\n-observedObject\n+update()\n}\n``` \nOften instead of a interface for subject abstract classes are used as the behaviour for the 3 functions is always the same and you can add the data structure for storing the observers. \nIn java you can use the provided `java.util.Observable` and `java.util.Observer` but is often not recommended.", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Observer", "Header 2": "Things to be aware of", "Header 3": "How to notify", "path": "../pages/digitalGarden/cs/patterns/observer.mdx"}, "page_content": "There are a few ways to notify the observers. \nFirstly there is the question of when to notify observers. Either they are notified when the `setState` function is called which is in most cases the way to go and the easiest to implement however it can lead to lots of updates. Or you can explicitly call the update function when you think it is needed, you just need to make sure you don't forget. \nThen there is the question of what should a notification look like. We can differentiate between 2 models, push and pull. With pull the object is just notified that there has been a change and then has to get (pull) the actually changes itself. \n- `update()` without any parameters. \nOr there is the push option where you tell the observer what and where has been changed. This can be done in multiple ways. \n- `update(Subject s, Color c)` with sender and/or the exact data that changed. Is easy but can be hard when multiple things changed.\n- `update(Subject s, Object args)` with sender and/or Object containing the the changes or the new state, as often seen in C#.\n- `update(Event e)` an event object that contains everything as seen in JavaFx or Swing.", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Observer", "Header 2": "Things to be aware of", "Header 3": "Other small things", "path": "../pages/digitalGarden/cs/patterns/observer.mdx"}, "page_content": "There is clearly loose coupling between the subject and the observer as the subject does not know any concrete observers only the interface. \nA notification is broadcast, meaning it is sent to all registered observers. It is then up to the observer how it handles notifications. \nA simple change of the subjects state can cause a cascade of updates and therefore then multiple notifications. \nYou must be aware careful that you do not create infinite loops by changing the state in the update function as this will cause the observer to be notified again. \nIt is good practice to make sure the state really has changed before notifying all the observers and to also not allow the same listener to be added multliple times. \nIn java you can use a `CopyOnWriteArrayList` as the data structure as it can happen that observers detach in the update method which would change the loop that you iterate over in `notifyObservers()`", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Observer", "Header 2": "Example", "path": "../pages/digitalGarden/cs/patterns/observer.mdx"}, "page_content": "This example is without the Subject interface however if could be added especially if there will be multiple subjects. \n```java\npublic class NewsAgency{\nprivate String news;\nprivate List channels = new ArrayList<>();\n\npublic void addObserver(Observer channel) {\nthis.channels.add(channel);\n}\n\npublic void removeObserver(Observer channel) {\nthis.channels.remove(channel);\n}\n\npublic void setNews(String news) {\nthis.news = news;\nfor (Observer channel : this.channels) {\nchannel.update(this.news);\n}\n}\n}\n\npublic class NewsChannel implements Observer {\nprivate String news;\n\n@Override\npublic void update(Object news) {\nthis.setNews((String) news);\n}\n}\n\npublic interface Observer {\npublic void update(Object o);\n}\n```", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "State", "path": "../pages/digitalGarden/cs/patterns/state.mdx"}, "page_content": "The intent of the state pattern is that we can alter a programs behaviour (just like the strategy pattern) when its internal state changes and outsource the state-dependent behavior. A common example is some sort of dispenser machine that has multiple different states and depending on actions changes its state. For example a ticketmachine can be in the state \"INIT\" and when the action \"enterMoney\" is executed the machine changes to the state \"MONEY_ENTERED\".", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "State", "Header 2": "Structure", "path": "../pages/digitalGarden/cs/patterns/state.mdx"}, "page_content": "```mermaid\nclassDiagram\nStateInterface <-- Context\nStateInterface <|-- ConcreteStateA\nStateInterface <|-- ConcreteStateB\nclass Context{\nrequest() = currentState.handle()\n}\nclass StateInterface{\nhandle()\n}\nclass ConcreteStateA{\nhandle()\n}\nclass ConcreteStateB{\nhandle()\n}\n``` \nThe hardest part of implementing the state pattern is defining the state interface. The easiest way to do so is to draw a state diagram of the system. All the actions are then the methods in the interface and all the states are the concreteStates.", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "State", "Header 2": "Things to be aware of", "Header 3": "State Transition", "path": "../pages/digitalGarden/cs/patterns/state.mdx"}, "page_content": "There are a few ways how state transition can be done. \nDecentralized = may be initiated by state objects. For that the state must know its succesors, needs access to a state transition method in the context `context.setState(s);` or return the new state which is then set by the context. \nParameterized = may be signaled by state, executed by context i.e by returning a key e.g a string or int. Association between, keys and states is held in the context. \nCentralized = initiated by the context, state should be informed if it is activated or deactivated.", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "State", "Header 2": "Creation of state objects", "path": "../pages/digitalGarden/cs/patterns/state.mdx"}, "page_content": "Created when needed = `c.setState(new StateB());` when state changes are rare.\nCreation ahead of time = `c.setState(c.STATE_B);` states have to be stored in context.", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "State", "Header 2": "Example", "path": "../pages/digitalGarden/cs/patterns/state.mdx"}, "page_content": "```java\npublic class TicketMachine{\nprivate int destination;\nprivate boolean firstClass, dayTicket, halfPrice;\nprivate double price, enteredMoney;\nprivate interface State {\nvoid setDestination(intdestination);\nvoid setFirstClass(booleanfirstClass);\nvoid setDayTicket(booleandayTicket);\nvoid setHalfPrice(booleanhalfPrice);\nvoid enterMoney(double amount);\nvoid cancel();\n}\nprivate final State INIT = new StateInit();\nprivate final State DEST_SELECTED = new StateDestSelected();\nprivate final State MONEY_ENTERED = new StateMoneyEntered();\nprivate State state = INIT;\n\npublic void enterMoney(double amount) {\nstate.enterMoney(amount);\n}\n// etc...\nabstract class AbstractState implements State {\npublic void setDestination(intdestination) {\nthrow new IllegalStateException(); }\npublic void setFirstClass(booleanfirstClass) {\nthrow new IllegalStateException(); }\npublic void setDayTicket(booleandayTicket) {\nthrow new IllegalStateException(); }\npublic void setHalfPrice(booleanhalfPrice) {\nthrow new IllegalStateException(); }\npublic void enterMoney(double amount) {\nthrow new IllegalStateException(); }\npublic void cancel() { state = INIT; }\n}\nclass StateDestSelected extends AbstractState{\npublic void setFirstClass(boolean fc) {\nfirstClass= fc;\nprice = calculatePrice(destination, firstClass);\n}\npublic void enterMoney(double amount) {\nstate= MONEY_ENTERED; state.enterMoney(amount);\n}\n}\nclass StateMoneyEntered extends AbstractState{\npublic void enterMoney(double amount) {\nenteredMoney += amount;\nif (enteredMoney>= price) {\nprintTicketWithChange(destination, price, firstClass);\nstate = INIT;\n}\n}\n}\n}\n```", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Fluent in Python", "path": "../pages/digitalGarden/cs/python/fluent.mdx"}, "page_content": "Some key notes and takeaways from the book Fluent Python by Luciano Ramalho.", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Fluent in Python", "Header 2": "Chapter 1: The Python Data Model", "path": "../pages/digitalGarden/cs/python/fluent.mdx"}, "page_content": "- Make use of it, it's there for a reason. It make implementing collections and classes easier.\n- Implement the special/magic/dunder methods to make your classes behave like built-in types.\n- Don't call special methods directly, use built-in functions instead like `len()`, `iter()`, `str()`, etc. rather than\n`obj.__len__()`, `obj.__iter__()`, `obj.__str__()`, etc.\n- collections.namedtuple is a great way to create a class that is just a collection of attributes.\n- ABC = Abstract Base Class\n- `__repr__` is for developers, `__str__` is for end users. If you only implement one, implement `__repr__`.\n- By default custom classes are truthy, unless you implement `__bool__` or `__len__` and return `False` or `0` respectively.\n- For numpy and some built-in types like list or str that are implemented in C, `__len__` is a C function that returns\nthe value of the `ob_size` field in the `PyObject` struct that represents any variable in the CPython implementation.\nThis is done for performance reasons. Is it important to know this? Probably not, but it's interesting. \n```python\nimport collections\n\nCard = collections.namedtuple('Card', ['rank', 'suit'])\n\nclass FrenchDeck:\nRANKS = [str(n) for n in range(2, 11)] + list('JQKA')\nSUIT_VALUES = {'Spades': 3, 'Hearts': 2, 'Diamonds': 1, 'Clubs': 0}\n\ndef __init__(self):\n# cartesian product of ranks and suits using listcomps\nself._cards = [Card(rank, suit) for suit in self.SUIT_VALUES\nfor rank in self.RANKS]\n\ndef __len__(self):\nreturn len(self._cards)\n\ndef __getitem__(self, position):\nreturn self._cards[position]\n\ndef card_value(self, card):\nrank_value = self.RANKS.index(card.rank)\nreturn rank_value * len(self.SUIT_VALUES) + self.SUIT_VALUES[card.suit]\n\ndeck = FrenchDeck()\nsorted_deck = sorted(deck, key=deck.card_value)\n```", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Fluent in Python", "Header 2": "Chapter 2: An Array of Sequences", "path": "../pages/digitalGarden/cs/python/fluent.mdx"}, "page_content": "- Listcomps are faster than map and filter, and more readable than the equivalent for loop.\n- Generator expressions are memory efficient and can be used as function arguments. `tuple(ord(symbol) for\nsymbol in symbols)`\n- Tuples are immutable, but the objects they contain may be mutable!\n- Tuples don't need to be seen as immutable lists, they can be used as records with no field names.\n- Unpacking can be used to swap variables `a, b = b, a` or to discard values `_, b = (1, 2)` or to split a list into\nhead and tail `head, *tail = [1, 2, 3, 4]` or return multiple values from a function `return a, b`.\n- The `*` operator can be used to grab excess items, kind of a wild card.\n- Pattern matching is cool and generally simple. But some patterns can be complex and hard to read.\n- `collections.deque` is a great data structure for implementing a queue. It's a doubly linked list with O(1) time\ncomplexity for adding or removing items from either end. Where as a list needs to shift all the items.\n- `collections.deque` can be used to implement a bounded queue i.e. fixed size queue by passing a `maxlen` argument to\nthe constructor.\n- slices are objects and can be used as arguments to functions and stored in variables.\n- lists can be manipulated in place using slice assignment `l[2:5] = [20, 30]` or `del l[5:7]`.\n- Memory views seem complicated and I don't really understand them yet.\n- `array.array` is a great way to store a large number of numerical values. It's more efficient than a list of ints\nbut can only store one type of value.\n- there is also the bisect module which provides binary search and insertion into sorted sequences which can be handy.", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Actor Model", "path": "../pages/digitalGarden/cs/distributedSystems/actorModel.mdx"}, "page_content": "The actor model is not just good for concurrent programming but also for distributed systems as the actors can be on different systems and still communicate with each other.", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Actor Model", "Header 2": "Java Akka", "path": "../pages/digitalGarden/cs/distributedSystems/actorModel.mdx"}, "page_content": "We will be using the Akka framework again but instead of using the [Scala version of Akka](../Concurrent%20Programming/13-actorModel.md) we will be using the java version which is very similar.", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Actor Model", "Header 2": "Java Akka", "Header 3": "Creating an Actor", "path": "../pages/digitalGarden/cs/distributedSystems/actorModel.mdx"}, "page_content": "In Java, actors extend the AbstractClass and must implement the `Receive createReceiver()` method. The following actor discards all received messages because no matching is done. \n```java\npublic class PrintActor extends AbstractActor {\n@Override\npublic Receive createReceiver() {\nreturn receiveBuilder().build();\n}\n}\n``` \nTo react to messages we can use pattern matching like the example below: \n```java\npublic class PrintActor extends AbstractActor {\nprivate int cnt = 0;\n@Override\npublic Receive createReceive() {\nreturn receiveBuilder().matchAny(t -> onReceive(t)).build();\n}\nprivate void onReceive(Object msg) {\ncnt++;\nif (msg instanceof String) {\nSystem.err.println(cnt + \": received message \" + msg);\n} else {\nSystem.err.println(cnt + \": received unknown message\");\n}\n}\n}\n``` \nThe actual actor objects are then created and started asychnronsly by using the actor system. Just like in Scala when trying to create and actor object using `new` an `ActorInitializationException` is thrown. \n```java\npublic static void main(String[] args) throws Exception {\nActorSystem as = ActorSystem.create();\nActorRef actor = as.actorOf(\nProps.create(PrintActor.class),\n\"Printer\" // name is optional and must be unique\n); // returns an immutable reference\n// ActorRef print = as.actorOf(Props.create(PrintActor.class, \"Msg:\")); For non default constructor actors\n}\n```", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Actor Model", "Header 2": "Java Akka", "Header 3": "Sending Messages", "path": "../pages/digitalGarden/cs/distributedSystems/actorModel.mdx"}, "page_content": "In the scala version of Akka messages could be sent using the tell operator `!`. However, this is not possible in Java for syntax reasons so instead, messages can be sent to an actor by calling a member method on the receiving actor. Just like in Scala the message is guaranteed to be delivered at most once. \n```java\nreceivingActor.tell(msg, ActorRef.noSender()) // ActorRef.noSender() is same as null\n```", "type": "Document"}
-{"id": null, "metadata": {"Header 1": "Actor Model", "Header 2": "Java Akka", "Header 3": "Receiving Messages", "path": "../pages/digitalGarden/cs/distributedSystems/actorModel.mdx"}, "page_content": "In Java there are the following methods that can be used for pattern matching: \n- `matchAny(UnitApply