<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Sean Williams</title>
    <description>The latest articles on DEV Community by Sean Williams (@armousness).</description>
    <link>https://dev.to/armousness</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F883628%2F3526a207-3483-4f71-ac24-bc4fdf134b90.jpg</url>
      <title>DEV Community: Sean Williams</title>
      <link>https://dev.to/armousness</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/armousness"/>
    <language>en</language>
    <item>
      <title>A cool programming-based game</title>
      <dc:creator>Sean Williams</dc:creator>
      <pubDate>Tue, 02 Aug 2022 23:27:56 +0000</pubDate>
      <link>https://dev.to/armousness/a-cool-programming-based-game-3lcc</link>
      <guid>https://dev.to/armousness/a-cool-programming-based-game-3lcc</guid>
      <description>&lt;p&gt;The game is called &lt;a href="https://danielyxie.github.io/bitburner/"&gt;Bitburner&lt;/a&gt;, and I have no affiliation with it. I just think it's cool.&lt;/p&gt;

&lt;p&gt;You mostly play the game through a terminal, which allows you to create files and run JavaScript programs. It contains a JavaScript interpreter, but also allows you to run scripts natively. (I think this is done similarly to "bookmarklets.") Native scripts mainly have the drawback of being able to hang the game, so you have to be diligent about explicit sleeping in long loops.&lt;/p&gt;

&lt;p&gt;Anyway, the game provides an API that allows you to take game actions (otherwise you write straight JavaScript, so you have its control flow and collections and the like), and as you get further in you get access to more APIs that let you automate more and more things.&lt;/p&gt;

&lt;p&gt;It seems to me like a fun way of working on your programming skills.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>Meditations on concurrency</title>
      <dc:creator>Sean Williams</dc:creator>
      <pubDate>Tue, 26 Jul 2022 23:01:58 +0000</pubDate>
      <link>https://dev.to/armousness/meditations-on-concurrency-3cbn</link>
      <guid>https://dev.to/armousness/meditations-on-concurrency-3cbn</guid>
      <description>&lt;p&gt;My business is auto repair, which has been a bit of a journey from computer science. On the other hand, auto repair is a surprisingly software-reliant field. I don't just mean this in the sense that cars have more computational elements in them, though that's an issue too.&lt;/p&gt;

&lt;p&gt;Many business &lt;em&gt;could&lt;/em&gt; be run with just paper, though it would be burdensome. Auto repair has a few special problems, though.&lt;/p&gt;

&lt;p&gt;First, job times are standardized. Nearly every job that could be done to nearly every car has a benchmark time it should take a competent technician to complete. This means, if your shop is legitimate, the price of a job should be: the book time for the job * the shop's labor rate + the cost of parts required to do the job * (1 + the shop's parts markup) + nominal overhead.&lt;/p&gt;

&lt;p&gt;Second, every car is different, often in bizarre ways. In the old days there were big service manuals for every year for every make and model—these still exist, but in practice they've been displaced by software. Even if you can figure out how to do a job on your own, you often need specs—how much to torque down a bolt, how much fluid to add, that sort of stuff.&lt;/p&gt;

&lt;p&gt;Third, if you're good enough to do electrical diagnosis and repair, you need wiring diagrams.&lt;/p&gt;

&lt;p&gt;Yes, auto repair preexists computers, but cars were a lot simpler in those days. Not surprisingly, the currently available software for running an auto repair shop—isn't great. Our biggest problem is one of concurrency: Our current software can be run in a client/server mode over a local network. When a work order is up on one computer, other computers are fully locked out.&lt;/p&gt;

&lt;p&gt;This has led to me thinking a lot about how concurrency should be handled in this situation, since I'll soon start writing our own shop management software.&lt;/p&gt;

&lt;h2&gt;
  
  
  Race conditions
&lt;/h2&gt;

&lt;p&gt;The principal issue is what we call "race conditions." Imagine you have a shared variable &lt;code&gt;x&lt;/code&gt;, initially &lt;code&gt;0&lt;/code&gt;, and five threads all run &lt;code&gt;x++&lt;/code&gt;. What happens? It's tricky because the definition of &lt;code&gt;x++&lt;/code&gt; looks more like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;load x into register1
add 1 to register1
store register1 into x
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The final value of &lt;code&gt;x&lt;/code&gt; could be anything between 1 and 5, depending on how instructions interleave. For example, just looking at two threads, you could have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;thread 1: load x [r = 0]
thread 1: add 1 [r = 1]
thread 1: store x [x = 1]
thread 2: load x [r = 1]
thread 2: add 1 [r = 2]
thread 2: store x [x = 2]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case, &lt;code&gt;x&lt;/code&gt; is 2. The instructions could also play out like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;thread 1: load x [r = 0]
thread 2: load x [r = 0]
thread 1: add 1 [r = 1]
thread 2: add 1 [r = 1]
thread 1: store x [x = 1]
thread 2: store x [x = 1]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case, &lt;code&gt;x&lt;/code&gt; is 1.&lt;/p&gt;

&lt;p&gt;This opens up into a whole lot of other stuff: mutual exclusion (mutex) locks, semaphores, transactions... You introduce special processor instructions, like "atomic check and set," which can do&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if(x == 0) {
  x = 1;
  return true;
}
else {
  return false;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;in a single cycle. This lets you start doing stuff like,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;int lock = 0;

void foo() {
  while(!atomic_check_and_set(lock)) {
    sleep(100);
  }
  // Do some stuff, knowing that other threads won't interfere
  lock = 0;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This requires a lot of diligence to get right; it's very easy to hang your program by improperly handling locks. This is also why focus has shifted to "safer" things like promises and work queues.&lt;/p&gt;

&lt;p&gt;There's one other problem with locking that's worth mentioning. Locking should have some level of granularity, where there are different locks for different data. What if a thread needs three locks? More importantly, what if multiple threads need overlapping subsets of locks? One thing you absolutely should not do is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;int lock1 = lock2 = lock3 = 0;

void foo() {
  while(!atomic_check_and_set(lock1)) sleep(100);
  while(!atomic_check_and_set(lock2)) sleep(100);
  while(!atomic_check_and_set(lock3)) sleep(100);
  // do stuff
  lock1 = lock2 = lock3 = 0;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If there's another function that looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;void bar() {
  while(!atomic_check_and_set(lock3)) sleep(100);
  while(!atomic_check_and_set(lock2)) sleep(100);
  while(!atomic_check_and_set(lock1)) sleep(100);
  // do stuff
  lock1 = lock2 = lock3 = 0;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you can run into a situation where a thread executing &lt;code&gt;foo&lt;/code&gt; takes &lt;code&gt;lock1&lt;/code&gt;, while a thread executing &lt;code&gt;bar&lt;/code&gt; takes &lt;code&gt;lock3&lt;/code&gt;. One of them will then take &lt;code&gt;lock2&lt;/code&gt;, but at this point both threads will hang indefinitely.&lt;/p&gt;

&lt;h2&gt;
  
  
  Time scales
&lt;/h2&gt;

&lt;p&gt;The issue exposed by our shop management software is the problem of time scales. Holding a lock for 200 ms is fine in smaller-scale environments. Holding a lock for eight hours will piss people off. This is the difference between "batch processing" speeds, versus user interface speeds.&lt;/p&gt;

&lt;p&gt;The obvious lesson is that you should avoid holding locks while waiting for user input. Among other things, you don't know if the user is even at the computer!&lt;/p&gt;

&lt;p&gt;The above discussion about locks is apparently nowadays called "pessimistic concurrency control." The alternative that gets suggested is "optimistic concurrency control," in which you allow concurrent memory access to proceed but roll back or merge in case of conflicts.&lt;/p&gt;

&lt;p&gt;This approach makes sense in situations with very high utilization. At the smaller scale, especially a smaller scale where the users are auto mechanics, I think it's a bad idea to drag in merge semantics. I mean, programmers themselves already have significant heartburn with Git merge—subjecting auto mechanics to merging sounds inhuman.&lt;/p&gt;

&lt;h2&gt;
  
  
  Live updates
&lt;/h2&gt;

&lt;p&gt;I decided to approach this problem, not as a programmer, but as a normal person. Nearly everything in computing is some sort of metaphor for real life: there's a reason the base of most graphical operating systems is called a "desktop," and that "files" are stored in "folders." Even the older term "directory" is—well, for the youngsters out there, you used to use directories to look up phone numbers.&lt;/p&gt;

&lt;p&gt;The main reason for this is, you ought to try and make computing intuitive. That means having a handle on intuition: what will people find intuitive? Conflict merging in the real world is incredibly tedious, and made up of judgment calls and "who has final authority?"&lt;/p&gt;

&lt;p&gt;What about the more basic question: what are real-world situations in which we have concurrent access to a shared medium? I realized, that happens all the time, it's so common that it's nearly invisible. Namely, having a conversation. People manage conversations not through complicated technical rules, but through—for lack of better words—courtesy and willpower. You and I talk at the same time. Do I stop speaking, do you? If we both stop, who starts talking? If we both keep talking, who blinks first?&lt;/p&gt;

&lt;p&gt;For the purposes of concurrent access, these questions don't need to be answered—it suffices that people manage conversations, and we call that management "social convention." This made me realize, smaller-scale concurrent access can be handled with live updates, like Google Docs.&lt;/p&gt;

&lt;p&gt;That is, commit changes as they're made, and have those changes immediately reflected to other users. Yes, users can create race conditions, but this isn't a technical problem—it's a social problem. Users will instinctively see the possibility of race conditions (without knowing that term) because they'll see what other users are working on. Prosocial users will avoid conflicting changes; antisocial users can be disciplined.&lt;/p&gt;

&lt;p&gt;There are some algorithmic problems with doing this well, and I'll post about them later. You still need to do three-way merging, for example, and you need to keep the text input cursor in a reasonable place. But this solution does bring locking back to the batch processing timescale, in a way that ought to be intuitive to normal people.&lt;/p&gt;

&lt;p&gt;This is a work in progress, of course, but I think it's interesting enough to be worth posting about.&lt;/p&gt;

</description>
      <category>computerscience</category>
      <category>discuss</category>
    </item>
    <item>
      <title>What is a computer?</title>
      <dc:creator>Sean Williams</dc:creator>
      <pubDate>Tue, 12 Jul 2022 21:39:48 +0000</pubDate>
      <link>https://dev.to/armousness/what-is-a-computer-3k41</link>
      <guid>https://dev.to/armousness/what-is-a-computer-3k41</guid>
      <description>&lt;p&gt;At the close of the 19th Century, it was thought that math and science were about to be "solved," and all that remained was cleaning up some of the details. The famous mathematician David Hilbert posed what he considered the last big questions. One of them was called the &lt;em&gt;Entscheidungsproblem&lt;/em&gt;, meaning Decision Problem. The question was:&lt;/p&gt;

&lt;p&gt;Given a set of axioms in first-order logic, can you create a mechanical process for deciding whether a particular proposition is true?&lt;/p&gt;

&lt;p&gt;The first step in solving this problem was to figure out what constitutes a mechanical process for solving logic problems. Two great mathematicians came to the fore: Alonzo Church and Alan Turing. Church came up with a mathematically oriented process, called lambda calculus, and Turing came up with a mechanically oriented process, the Universal Turing Machine.&lt;/p&gt;

&lt;p&gt;Both mathematicians proved that, for the problem-solving processes they devised, the answer to the Decision Problem is "no." They got to this answer through another, better known problem:&lt;/p&gt;

&lt;p&gt;Given an algorithm and a set of inputs, can you prove whether the algorithm will fall into an infinite loop?&lt;/p&gt;

&lt;p&gt;What they actually proved is that the answer to this question, the Halting Problem, is "no." The undecidability of the Decision Problem is an extension of the undecidability of the Halting Problem.&lt;/p&gt;

&lt;p&gt;Indeed, this is one way of defining computers: a computer is a machine for which the Halting Problem is undecidable.&lt;/p&gt;

&lt;h2&gt;
  
  
  The limits of analysis
&lt;/h2&gt;

&lt;p&gt;One of the more eye-opening things for me, as a computer science student, came from the required graduate-level theory course. We looked at proofs about the behavior of computer programs. Proofs generally work by substituting things for equivalent things, to change the form of some logical statement into a form you're happier with.&lt;/p&gt;

&lt;p&gt;When it comes to computer programs, this breaks down once you have a loop. What's the value of a loop? Sometimes you can work this out; sometimes you can prove that a loop "reduces its problem space" with each iteration until you collapse down to a particular value. OpenMP, a sort of extension library for C/C++, allows you to automatically parallelize loops that take on certain "canonical forms." The strange programming language Idris automatically detects certain recursive patterns that are guaranteed to produce a value.&lt;/p&gt;

&lt;p&gt;But for the most part, the value of a loop is unknowable. After all, outside certain special cases, you can't prove whether a loop will take on any value at all. Computer scientists have a special name for this: bottom, indicated by the symbol ⊥. ⊥ is the value of a "divergent computation," or, one for which we don't know if it'll ever actually produce a value. (⊥ is also the value of exceptions.)&lt;/p&gt;

&lt;p&gt;The most obvious consequence of this is quite simple: a computer program cannot robustly write another computer program. In order to write a robust program-writing-program, you need to understand what the inputs and outputs of each piece of the program will be—just as normal programming is about understanding the flow of input and output.&lt;/p&gt;

&lt;p&gt;If we try to model a computer program, which is the first step in writing a program to write programs, most of the inputs and outputs will be ⊥, and you can't analyze ⊥. After all, ⊥ isn't any particular value; there's no equivalent thing you can substitute into the proof. It's a sort of logical black hole, an immovable logical object.&lt;/p&gt;

&lt;p&gt;The other obvious consequence of this is that we are nothing like computers. The Halting Problem presents some obstacles to programming, or rather to testing, but we can look at looping code and figure out what it's supposed to do. We also have problem solving intuitions that let us sort out when the loop isn't doing what it's supposed to, and bring it more into line. I don't know what problem solving intuition is, but I know for a fact that it isn't computation.&lt;/p&gt;

&lt;p&gt;What about compiler optimization? The truth is, compiler optimization starts by breaking your code down into "basic blocks," which are runs of code that contain no branching. No ifs, no loops, no function calls. Basic blocks can be robustly analyzed, but they're also not Turing complete.&lt;/p&gt;

&lt;p&gt;This is also the reason that the dream of "programming for business managers" has never worked out (despite &lt;em&gt;decades&lt;/em&gt; of trying). Once your needs exceed the walled garden of curated functionality you can mix and match in a reasonably safe way, you're back to normal programming.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a computer isn't
&lt;/h2&gt;

&lt;p&gt;Another dream that hasn't panned out very well is declarative programming. Prolog is a language that purports to allow you to answer questions in propositional logic. Of course, computing began with the fact that you can't do that.&lt;/p&gt;

&lt;p&gt;Indeed, Prolog programs are highly sensitive to the order in which statements are presented. This is because Prolog programs are still dynamical processes: there's still an evaluation system that does recursive descent to determine the truth of the logic you present it.&lt;/p&gt;

&lt;p&gt;This gets to the most important point of what computers aren't: they are not logic machines. They contain integrated circuits that are designed from logical principles, but that no more makes them logic machines than the presence of silicon makes a beach a computer.&lt;/p&gt;

&lt;p&gt;Similarly, the standard engineering tool for complex math used to be the slide rule. A slide rule is based on a more fundamental principle of what addition is: if you walk forward 6 feet, then you walk forward 3 feet, you've walked forward 6 + 3 = 9 feet. Is walking forward the essence of arithmetic?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KzIoBrpc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r9u9bfjm6njlnxucr2lj.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KzIoBrpc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r9u9bfjm6njlnxucr2lj.jpg" alt="Keuffel &amp;amp; Esser Model 4081-3 slide rules, taken from Wikimedia Commons" width="640" height="490"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Physically, a slide rule is just one bar that's allowed to slide between two other bars. You do addition by sliding the inner rule such that its 0 mark lines up with the left operand on the outer rule, going forward on the inner rule a distance equal to the right operand, and reading the value at the same place on the outer bar. This acts like doing addition with a tape measure: to do 6 + 3, start from a wall and measure out 6 feet and mark the position. Measure an additional 3 feet from your mark, and mark that position. Now measure the distance from the wall to the second mark.&lt;/p&gt;

&lt;p&gt;Slide rules do another trick, though. Knowing that log(a * b) = log(a) + log(b), you can logarithmically scale the tick marks and thereby add log(a) to log(b). Look up the position of log(a) + log(b) on the same logarithmic scale, and the result is a * b.&lt;/p&gt;

&lt;p&gt;Does this mean that arithmetic is the essence of tape measures and slide rules—that a couple of sticks with notches on them "do" math? In a certain sense the answer is "yes," but accepting that answer also forces math to come down from the mountaintops and linger with us commoners.&lt;/p&gt;

&lt;p&gt;In terms of Plato's cave, though, the answer is obviously "no." Adding some transistors doesn't make computers any more of "mathematical entities" or "pure abstracta" than tape measures.&lt;/p&gt;

&lt;h2&gt;
  
  
  What computers are
&lt;/h2&gt;

&lt;p&gt;A friend of mine has the best, but also most obtuse, characterization of computers: he says they're instruments for which we control the output. With most instruments, a voltmeter for example, the output is some sort of fact of the world. Also, instruments are &lt;em&gt;calibrated&lt;/em&gt; to react to the world in certain predictable ways, but it's the world that determines how far the needle moves.&lt;/p&gt;

&lt;p&gt;Computers are a strange situation in which we condition the input and control the output. In my experience, this means computers only have two fundamental uses: accounting and control.&lt;/p&gt;

&lt;p&gt;Accounting is a situation where we've created a system for ourselves, and we've set up the rules about how inputs should be conditioned (debits = credits) and what the outputs should look like (e.g., profit and loss statement). If the output were a fact of the world, it would be unnecessary to use a computer. This shows us another fact of computing: a bug is when the computer produces the wrong output.&lt;/p&gt;

&lt;p&gt;This is the most fundamental problem with artificial intelligence, by the way. One thing that's very clear about AI research is, it has no interest in relinquishing control over the output—after all, AI is joined at the hip with "model validation." But then again, there isn't really such a thing as a computer for which the programmers don't control the output. This is, in my opinion, a rather meager view of "intelligence."&lt;/p&gt;

&lt;p&gt;Control is a situation where you want to drive some real-world process according to rules you've set up. Cruise control is meant to keep your car's speed in a range around some set point, and it does that by adjusting the throttle. We still control the output in this situation, but the output is not the car's speed—it's how open the throttle is. Controlling speed is the &lt;em&gt;goal&lt;/em&gt;, but it isn't what the program &lt;em&gt;does&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Anyway, most computer programs you and I write are reskinned accounting systems. Video games are accounting systems, just with much fancier user interfaces. Even large scientific simulations are no different: almost all of the actual work in simulation design goes into having it produce correct output. If this sounds anathema to your understanding of the scientific method, then I'm sorry to be the bearer of bad news.&lt;/p&gt;

&lt;p&gt;You should, though, feel better about the fact that it's provably impossible for you to optimize yourself out of the job, at least in the aggregate.&lt;/p&gt;

</description>
      <category>computerscience</category>
    </item>
    <item>
      <title>How to Do Away with Floating Points</title>
      <dc:creator>Sean Williams</dc:creator>
      <pubDate>Fri, 08 Jul 2022 01:29:46 +0000</pubDate>
      <link>https://dev.to/armousness/how-to-do-away-with-floating-points-3b1m</link>
      <guid>https://dev.to/armousness/how-to-do-away-with-floating-points-3b1m</guid>
      <description>&lt;p&gt;Don't get me wrong, floating points are good for a lot of things, but their inaccuracy is well known. The basic issue is that floating points are based on a m*2^p approach. If p is negative you get fractions, since for example 2^-1 = 0.5, 2^-2 = 0.25, and so on.&lt;/p&gt;

&lt;p&gt;The reason you can get funky behavior with floats is because the denominator must always be a power of two, so denominators that aren't powers of two are approximated. This is why you can compute something that should be 0.3, but end up with 0.29999999999999.&lt;/p&gt;

&lt;p&gt;I took some accounting classes after I pivoted into business, and got madder and madder about having to round my own fractions when using a REPL as a calculator. Eventually I sat down and wrote a precise fractional calculator. Which is harder than it seems.&lt;/p&gt;

&lt;p&gt;As a brief reminder, a rational number is a pair of integers p ÷ q, for example, ½. Integers are also rationals, with q = 1. They're called rationals because they express a ratio, if you were wondering.&lt;/p&gt;

&lt;p&gt;Floating-point is technically a rational number format, but it's often used to approximate real numbers. Real numbers include those that can't be represented as a fraction of integers, like π and sqrt(2).&lt;/p&gt;

&lt;p&gt;To finalize the intuition about why floating-point "drift" occurs, consider that decimal is also a rational number system. However, decimal only allows a finite representation of rational numbers for which the prime factorization of the denominator only contains 2 and 5.&lt;/p&gt;

&lt;h2&gt;
  
  
  Explicit Rationals
&lt;/h2&gt;

&lt;p&gt;Another approach to rational numbers is to store them as a pair of integers. I'll quickly lay out the algorithms for doing this:&lt;/p&gt;

&lt;h3&gt;
  
  
  Prime Factorizing: x
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;factors = []
limit = floor(sqrt(x))
for d in 2 to limit:
  while x &amp;gt; 0 and x % d = 0:
    factors.append(d)
    x = x / d
  if x == 0:
    break
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Putting into Lowest Terms: p / q
&lt;/h3&gt;

&lt;p&gt;Compute the prime factors of p and q. For each factor f present in both, divide both p and q by f. Alternatively, divide p and q by the product of their common factors.&lt;/p&gt;

&lt;h3&gt;
  
  
  Addition: p1/q1 + p2/q2
&lt;/h3&gt;

&lt;p&gt;Compute the prime factors of q1 and q2, call them f1 and f2. For each factor f in f1 that isn't also in f2, multiply p2 and q2 by f. For each factor f in f2 that isn't also in f1, multiply p1 and q1 by f.&lt;/p&gt;

&lt;p&gt;This has the effect of setting q1 = q2. The result is (p1 + p2) / q1, but for housekeeping purposes you should put this into lowest terms.&lt;/p&gt;

&lt;h3&gt;
  
  
  Subtraction: p1/q1 - p2/q2
&lt;/h3&gt;

&lt;p&gt;Multiply p2 by -1, then apply the addition algorithm.&lt;/p&gt;

&lt;h3&gt;
  
  
  Multiplication: (p1/q1) * (p2/q2)
&lt;/h3&gt;

&lt;p&gt;This is much easier, it's just (p1 * p2) / (q1 * q2), put into lowest terms.&lt;/p&gt;

&lt;h3&gt;
  
  
  Division: (p1/q1) / (p2/q2)
&lt;/h3&gt;

&lt;p&gt;This is equal to (p1/q1) * (q2/p2).&lt;/p&gt;

&lt;h3&gt;
  
  
  Find a library for the above
&lt;/h3&gt;

&lt;p&gt;You can probably find a library that implements all of this, but it's worth spelling it out so you can see what working with rationals is like. For example, Rust has a &lt;code&gt;num_rational&lt;/code&gt; crate.&lt;/p&gt;

&lt;h3&gt;
  
  
  Parsing a rational
&lt;/h3&gt;

&lt;p&gt;If you have a decimal number, say 0.25, this is equivalent to 25/100, which reduces to 1/4. (factors of 25: 5, 5; factors of 100: 2, 2, 5, 5; common factors: 5, 5 = 25; 25 / 25 = 1; 100 / 25 = 4.) So for example, you can get the numerator by removing the dot and parsing it as an integer, and if there are d digits after the dot, the denominator is 10^d.&lt;/p&gt;

&lt;h3&gt;
  
  
  Displaying a rational
&lt;/h3&gt;

&lt;p&gt;This is the hardest part by far, and the real reason behind this post. The trivial way of displaying a rational is as &lt;code&gt;p.to_str_radix(10) + "/" + q.to_str_radix(10)&lt;/code&gt;. If q is 1, the number is an integer so really you should only display &lt;code&gt;p.to_str_radix(10)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;What about decimal expansion? In theory there are two cases: finite and infinite. Infinite expansions are periodic, for example, 1/3 = 0.(3), and 1/6 = 0.1(6). In practice, there's a third case: periodic expansions can be very, very long, and displaying thousands of digits for a correct expansion isn't very helpful.&lt;/p&gt;

&lt;p&gt;Figuring out whether you're in a finite or infinite case is easy: a rational with a finite expansion for decimal output is one where the prime factors of q contains only 2 and 5. In that case, we can work out the expansion using long division (here I'm calling the terms of the rational n and d, for numerator and denominator):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fn unsafe_bigint(x: i32) -&amp;gt; BigInt {
    x.to_bigint().unwrap()
}

fn long_divide_finite(n: BigInt, d: &amp;amp;BigInt) -&amp;gt; String {
    let zero = Zero::zero();
    let ten = unsafe_bigint(10);
    let mut n = n;
    let mut result = String::new();
    loop {
        if n == zero {
            return result;
        }
        let (q, r) = n.div_rem(&amp;amp;d);
        result.push(digit_to_char(&amp;amp;q));
        n = r * &amp;amp;ten;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Though it may be strange to see it written out like this, you learned this algorithm in like third or fourth grade.&lt;/p&gt;

&lt;p&gt;Now, infinite expansions are trickier. An infinite decimal expansion consists of two parts: a fixed prefix, and an infinitely repeated periodic section. For example, in 1/3, the prefix is empty, and the periodic section is just 3. In 1/7, the prefix is empty, and the periodic section is 142875. In 1/6, the prefix is 1, and the periodic section is 6.&lt;/p&gt;

&lt;p&gt;It turns out, there's a formula of sorts for calculating the length of the prefix, which we'll call s, and the length of the periodic section, which we'll call t. The formula is: 10^s is congruent to 10^(s + t) (mod d). Another way of writing this is, we need to find the values of s and t that satisfy: (10^s - 10^(s + t)) mod d = 0.&lt;/p&gt;

&lt;p&gt;Because of the third case, we need to figure out the largest s + t we're willing to accept. You don't have to do this, and you can just write a loop of the form,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;for s in 0..infinity:
  for t in 1..s:
    if (10^s - 10^(s + t)) mod d == 0:
      return (s, t)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It can just take a long time, and give you an unsatisfying result. My way looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;static MAX_EXPANSION: usize = 50;

fn prefix_and_period(d: &amp;amp;BigInt) -&amp;gt; Option&amp;lt;(usize, usize)&amp;gt; {
    let zero = Zero::zero();
    let ten = unsafe_bigint(10);
    let mut s_pow: BigInt = One::one();
    for s in 0..MAX_EXPANSION {
        let mut t_pow: BigInt = unsafe_bigint(10);
        for t in 1..(MAX_EXPANSION + 1 - s) {
            if (&amp;amp;s_pow - &amp;amp;s_pow * &amp;amp;t_pow).mod_floor(&amp;amp;d) == zero {
                return Some((s, t));
            }
            t_pow = t_pow * &amp;amp;ten;
        }
        s_pow = s_pow * &amp;amp;ten;
    }
    None
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If this returns &lt;code&gt;Some&lt;/code&gt;, then we have a feasible infinite expansion, and we again do long division: after reaching the decimal place, expand out s times, then insert a '(', then expand out t times, then insert a ')', and we're done.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fn long_divide_infinite(n: BigInt, d: &amp;amp;BigInt, s: usize, t: usize) -&amp;gt; String {
    let ten = unsafe_bigint(10);
    let mut n = n;
    let mut s = s;
    let mut t = t;
    let mut result = String::new();
    if s == 0 {
        result.push('(');
    }
    loop {
        if t == 0 {
            result.push(')');
            return result;
        } else {
            let (q, r) = n.div_rem(&amp;amp;d);
            result.push(digit_to_char(&amp;amp;q));
            n = r * &amp;amp;ten;
            if s == 0 {
                t = t - 1;
            } else if s == 1 {
                result.push('(');
                s = 0;
            } else {
                s = s - 1;
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a very long expansion, we just expand it out MAX_EXPANSION times and add a "..." to the end, so we know this was a truncated expansion:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fn long_divide_infinite_trunc(n: BigInt, d: &amp;amp;BigInt) -&amp;gt; String {
    let ten = unsafe_bigint(10);
    let mut n = n;
    let mut result = String::new();
    for _ in 0..MAX_EXPANSION {
        let (q, r) = n.div_rem(&amp;amp;d);
        result.push(digit_to_char(&amp;amp;q));
        n = r * &amp;amp;ten;
    }
    result + "..."
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The functions above only expanded the fractional portion of a number—the part that comes after the decimal point. The case breakdown looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fn show_rational(x: &amp;amp;BigRational) -&amp;gt; String {
    let one = One::one();
    let ten = unsafe_bigint(10);
    let a = x.abs();
    let n = a.numer();
    let d = a.denom();
    let negative = x &amp;lt; &amp;amp;a;
    let mut result = String::new();
    if negative {
        result.push('-');
    }
    result = result + &amp;amp;n.to_str_radix(10);
    if d == &amp;amp;one {
        return result;
    }
    let (ipart, fpart) = n.div_rem(d);
    result.push('/');
    result = result + &amp;amp;d.to_str_radix(10);
    if is_finite(&amp;amp;d) {
        result = result + " = ";
        if negative {
            result.push('-');
        }
        result = result + &amp;amp;ipart.to_str_radix(10);
        result.push('.');
        return result + &amp;amp;long_divide_finite(&amp;amp;fpart * &amp;amp;ten, &amp;amp;d);
    } else {
        match prefix_and_period(&amp;amp;d) {
            Some((s, t)) =&amp;gt; {
                result = result + " = ";
                if negative {
                    result.push('-');
                }
                result = result + &amp;amp;ipart.to_str_radix(10);
                result.push('.');
                return result + &amp;amp;long_divide_infinite(&amp;amp;fpart * &amp;amp;ten, &amp;amp;d, s, t);
            }
            None =&amp;gt; {
                result = result + " \u{2248} ";
                if negative {
                    result.push('-');
                }
                result = result + &amp;amp;ipart.to_str_radix(10);
                result.push('.');
                return result + &amp;amp;long_divide_infinite_trunc(&amp;amp;fpart * &amp;amp;ten, &amp;amp;d);
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Unicode \u2248 is ≈, again to make sure we know this is only approximate. But this gives us the results we'd hope for...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;5
5/2 = 2.5
5/3 = 1.(6)
5/6 = 0.8(3)
5/7 = 0.(714285)
5/1003 ≈ 0.00498504486540378863409770687936191425722831505483...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now just make a simple REPL, and you can do your accounting homework in peace, knowing your numbers will always be accurate.&lt;/p&gt;

</description>
      <category>computerscience</category>
      <category>programming</category>
      <category>rust</category>
    </item>
    <item>
      <title>The Strange Art of Code Reuse, Part 3</title>
      <dc:creator>Sean Williams</dc:creator>
      <pubDate>Tue, 05 Jul 2022 23:41:20 +0000</pubDate>
      <link>https://dev.to/armousness/the-strange-art-of-code-reuse-part-3-1fdf</link>
      <guid>https://dev.to/armousness/the-strange-art-of-code-reuse-part-3-1fdf</guid>
      <description>&lt;p&gt;The first two parts of this series talked about &lt;a href="https://dev.to/armousness/the-strange-art-of-code-reuse-part-1-dbc"&gt;dynamic typing&lt;/a&gt;, then &lt;a href="https://dev.to/armousness/the-strange-art-of-code-reuse-part-2-h39"&gt;object-oriented programming&lt;/a&gt;. Along the way, I tried to get across some notions of what polymorphism is. When you have a function take an argument of some type, there are two issues: first, what operations can be done with that type, and second, what are the semantics of that type?&lt;/p&gt;

&lt;p&gt;The semantics of primitive types have been ingrained in us since elementary school. Integers are for counting, rational numbers are for ratios, booleans are for logic, and strings are for reading and writing. Once you start structuring data, you need to come up with your own semantics: vec3 is a position in a three-dimensional vector space, array is an ordered list of things, Person is information about a person in the real world.&lt;/p&gt;

&lt;p&gt;I dislike dynamic typing because it has sloppy semantics, and you can even see that at the primitive level. JavaScript coerces all numbers to &lt;code&gt;double&lt;/code&gt;, which degrades its use for counting. This also means that you don't know off hand whether a number in JavaScript is for counting or for ratios.&lt;/p&gt;

&lt;p&gt;Object-oriented programming encodes semantics, particularly for structured data, into a sort of data taxonomy. If your data don't rigidly conform to your taxonomy, then you either have to refactor, or you have to hack. Interfaces ease the restrictiveness of class hierarchies, but in my experience this fact isn't appreciated as much as it should be. Even then, interfaces have the problem that you can't generally tack them onto classes you bring in from the outside (i.e., from an API).&lt;/p&gt;

&lt;p&gt;This brings us to Haskell, the ivory tower of programming languages. It's &lt;a href="https://www.idris-lang.org/"&gt;not the tallest tower out there&lt;/a&gt;, but that doesn't make it any less ivory.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;eat :: ∀t, t ∈ Edible: t → IO ()&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;For lack of a better term, I'll be referring to the Haskell-style type system as category programming. At first blush, category programming is focused on interfaces, though they're called typeclasses. The caveat is that interfaces can be implemented on existing types, including primitive types. For example, the Haskell analog of &lt;code&gt;ToString&lt;/code&gt; is a typeclass called &lt;code&gt;Show&lt;/code&gt;, defined as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Show t where
    show :: t -&amp;gt; String
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While the syntax may be unfamiliar, you probably already know everything going on here. &lt;code&gt;t&lt;/code&gt; is a generic type parameter, much like &lt;code&gt;std::vector&amp;lt;'t&amp;gt;&lt;/code&gt; in C++ or &lt;code&gt;List&amp;lt;'t&amp;gt;&lt;/code&gt; in C#. Like interfaces, the typeclass &lt;code&gt;Show&lt;/code&gt; defines one or more function "templates," so all we specify here is a signature. &lt;code&gt;::&lt;/code&gt; is a type annotation, and &lt;code&gt;-&amp;gt;&lt;/code&gt; indicates a function.&lt;/p&gt;

&lt;p&gt;So &lt;code&gt;Show&lt;/code&gt; is a typeclass containing one function, &lt;code&gt;show&lt;/code&gt;, which takes a value of type &lt;code&gt;t&lt;/code&gt; and returns a &lt;code&gt;String&lt;/code&gt;. We can then add types to a typeclass with &lt;code&gt;instance&lt;/code&gt;. For example,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-- Define a Vec2 type, which just contains two doubles
-- Don't stress the syntax right now
data Vec2 = Vec2 Double Double

instance Show Vec2 where
    show (Vec2 a b) = "(" ++ show a ++ ", " ++ show b ++ ")"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The basic Haskell library already implements &lt;code&gt;Show&lt;/code&gt; on many types, including &lt;code&gt;Double&lt;/code&gt;—much like how Dotnet defines &lt;code&gt;ToString&lt;/code&gt; on &lt;code&gt;double&lt;/code&gt;. Let's dive into the original example problem, of making a generic function to add elements to a collection:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}
import Data.Set as Set

class AddToCollection c e where
   add_to_collection :: e -&amp;gt; c e -&amp;gt; c e

instance AddToCollection [] t where
    add_to_collection e c = e : c

instance Ord t =&amp;gt; AddToCollection Set t where
    add_to_collection e c = Set.insert e c
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Okay so there's a lot going on here. Let's agree to ignore &lt;code&gt;FlexibleInstances&lt;/code&gt; and &lt;code&gt;MultiParamTypeClasses&lt;/code&gt; and focus on the meat. First and foremost, we had no difficulty putting basic API types into this class, which is great. But what's going on with these type signatures?&lt;/p&gt;

&lt;p&gt;Let's start from a more basic point, which is "currying." In ML-style languages (including Haskell and F#), you don't surround arguments to function calls in parentheses. Instead, functions have "free variables," and applying a value to a function "closes" one of them. So &lt;code&gt;Set.insert&lt;/code&gt; is a function with two free variables, &lt;code&gt;t -&amp;gt; Set t -&amp;gt; Set t&lt;/code&gt;. We apply a value &lt;code&gt;e&lt;/code&gt; to it, which closes it to &lt;code&gt;Set t -&amp;gt; Set t&lt;/code&gt;, then we apply a value &lt;code&gt;c&lt;/code&gt; to it, which closes it all the way to just &lt;code&gt;Set t&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This same logic applies to types. Dotnet &lt;code&gt;Generic.List&lt;/code&gt; is a &lt;em&gt;type function&lt;/em&gt;, while &lt;code&gt;Generic.List&amp;lt;int&amp;gt;&lt;/code&gt; is a type. &lt;code&gt;Generic.List&lt;/code&gt; has a free type parameter; passing it the type &lt;code&gt;int&lt;/code&gt; gives us a concrete type. Dotnet requires you to surround type arguments in angle-brackets, while Haskell allows type arguments to be curried.&lt;/p&gt;

&lt;p&gt;So let's look at&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class AddToCollection c e where
   add_to_collection :: e -&amp;gt; c e -&amp;gt; c e
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;again. &lt;code&gt;c&lt;/code&gt; is a type function, and &lt;code&gt;e&lt;/code&gt; is a concrete type. The &lt;code&gt;add_to_collection&lt;/code&gt; function takes an element (of type &lt;code&gt;e&lt;/code&gt;), and a collection (of type &lt;code&gt;c e&lt;/code&gt;). At this point, this isn't very different from a C# function taking arguments of type &lt;code&gt;int&lt;/code&gt; and &lt;code&gt;List&amp;lt;int&amp;gt;&lt;/code&gt;. The difference is, to my knowledge, C# doesn't let you define interfaces with type functions as generics.&lt;/p&gt;

&lt;p&gt;And what about this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;instance Ord t =&amp;gt; AddToCollection Set t where
    add_to_collection e c = Set.insert e c
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The default &lt;code&gt;Data.Set&lt;/code&gt; is tree-based, and operations on sorted trees require the elements of the tree to be comparable, with &lt;code&gt;&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;&lt;/code&gt;. Since Haskell was made by mathematicians, the class of types that define less-than and greater-than is called ordinal, meaning, they can be ordered. &lt;code&gt;Ord t&lt;/code&gt; is a type constraint: we say that &lt;code&gt;t&lt;/code&gt; must be ordinal.&lt;/p&gt;

&lt;p&gt;This also lets us take a glimpse at the formality behind all of this. The reason we need the &lt;code&gt;Ord t&lt;/code&gt; constraint is because of the type of &lt;code&gt;Set.insert&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;insert :: Ord t =&amp;gt; t -&amp;gt; Set t -&amp;gt; Set t
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;add_to_collection&lt;/code&gt; function, as defined for &lt;code&gt;Set t&lt;/code&gt;, applies the &lt;code&gt;Set.insert&lt;/code&gt; function to &lt;code&gt;e&lt;/code&gt; and &lt;code&gt;c&lt;/code&gt;. &lt;code&gt;Set.insert&lt;/code&gt; requires that its first argument be of an ordinal type, and that its second argument be a &lt;code&gt;Set&lt;/code&gt; of ordinal types. This requirement gets re-imposed on our function, &lt;code&gt;add_to_collection&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now, what exactly is &lt;code&gt;t&lt;/code&gt;? Let's again compare it to something more familiar: what is an integer, or maybe, what is a 32-bit integer? The answer to that is, it's a whole number between -2,147,483,648 and 2,147,483,647. So int32 isn't a particular value, but it's a range of values. Better said, int32 is a &lt;em&gt;set&lt;/em&gt;, and a value of type int32 is a member of that set.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;t&lt;/code&gt; is similar: &lt;code&gt;t&lt;/code&gt; is the set of all possible types. &lt;code&gt;Ord t =&amp;gt;&lt;/code&gt; narrows this down, where &lt;code&gt;t&lt;/code&gt; is any type in the set &lt;code&gt;Ord&lt;/code&gt;. Remember, &lt;code&gt;Ord&lt;/code&gt; is a typeclass, and types can be added to a typeclass with &lt;code&gt;instance&lt;/code&gt;. Many types are in there by default (including &lt;code&gt;Int&lt;/code&gt; and &lt;code&gt;Char&lt;/code&gt;), and we can add any other types we want.&lt;/p&gt;

&lt;p&gt;Earlier we defined a type of two-dimensional vectors. As it stands, this doesn't work:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;data Vec2 = Vec2 Double Double

vec2set = add_to_collection (Vec2 5 2) Set.empty
-- error: No instance for (Ord Vec2) arising from a use of 'add_to_collection'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Okay, so we need &lt;code&gt;Vec2&lt;/code&gt; to provide an instance of &lt;code&gt;Ord&lt;/code&gt;...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;instance Ord Vec2 where
    compare (Vec2 a1 b1) (Vec2 a2 b2) =
        if a1 == a2 then compare b1 b2 else compare a1 a2
-- error: No instance for (Eq Vec2) arising from the superclasses of an instance declaration
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It turns out, classes can require other classes, and &lt;code&gt;Ord&lt;/code&gt; requires &lt;code&gt;Eq&lt;/code&gt;, which defines equality. Okay, so...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;instance Eq Vec2 where
    (Vec2 a1 b1) == (Vec2 a2 b2) = a1 == a2 &amp;amp;&amp;amp; b1 == b2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And now we're good, we can now have a &lt;code&gt;Set&lt;/code&gt; of &lt;code&gt;Vec2&lt;/code&gt; since we've satisfied all the requirements (including the earlier definition of &lt;code&gt;Show&lt;/code&gt;, which is required to pass something to &lt;code&gt;print&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;main :: IO ()
main = print (add_to_collection (Vec2 5 2) Set.empty)
-- output: fromList [(5.0, 2.0)]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This probably shows you why Haskell has the reputation it does: To explain object-oriented programming, I just gestured at the idea of taxonomy and your intuition did the rest of the work. To really explain category programming, we had to get knee-deep in theory. The plus side is, this is a system of such staggering flexibility that, as long as you keep your distance from the &lt;a href="https://en.wikipedia.org/wiki/Entscheidungsproblem"&gt;Entscheidungsproblem&lt;/a&gt;, you can do nearly anything you want.&lt;/p&gt;

&lt;p&gt;I'm going to close out on one cool feature that you kind of need this level of complexity to tackle. I mentioned way back at the beginning that dictionaries are weird. If you have a dictionary that contains an entry &lt;code&gt;"a": 5&lt;/code&gt; and you add &lt;code&gt;"a": 3&lt;/code&gt;, what's the correct thing to do? As usual this depends on your dictionary's semantics, but often the best thing to do is to set &lt;code&gt;"a"&lt;/code&gt; to &lt;code&gt;8&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;But let's think big: what I'm really talking about is having insertion semantics that are specific to the type of the dictionary's values. The dictionary type in Haskell is called &lt;code&gt;Map&lt;/code&gt;, and as in Dotnet's &lt;code&gt;Generic.Dictionary&lt;/code&gt;, it has two type parameters. Because of this, let's sidestep an even more obscure issue called "higher-kinded polymorphism" and define a new typeclass:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class AddToMap k v where
    add_to_map :: k -&amp;gt; v -&amp;gt; Map k v -&amp;gt; Map k v
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Map&lt;/code&gt; defines a function &lt;code&gt;insertWith&lt;/code&gt;: we pass it a function, and if a key is already present in the Map, it combines the old and new values using that function; otherwise it inserts the value. We can use it to create instances of &lt;code&gt;AddToMap&lt;/code&gt; that are specialized to particular value types:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;instance Ord k =&amp;gt; AddToMap k String where
    add_to_map k v c = Map.insertWith (++) k v c

instance Ord k =&amp;gt; AddToMap k Int where
    add_to_map k v c = Map.insertWith (+) k v c
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;++&lt;/code&gt; is string/list concatenation, while &lt;code&gt;+&lt;/code&gt; has the usual meaning. So if we have a Map of Strings, overwriting an existing key instead concatenates, while if we have a Map of Ints, overwriting an existing key instead adds:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;main :: IO ()
main = do
    print (add_to_map "a" (5::Int) (add_to_map "a" 3 Map.empty))
    print (add_to_map "message" "hello" (add_to_map "message" " world" Map.empty))

-- output:
-- fromList [("a",8)]
-- fromList [("message","hello world")]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;There's no question that category polymorphism is the most powerful of the type systems considered here. This doesn't mean I think everyone should use Haskell, or that you should try to convince your company to switch to Haskell, or anything like that. The point of this series was to be informative, not persuasive. Indeed, in practice, there are enormous drawbacks to using Haskell, but &lt;em&gt;understanding&lt;/em&gt; Haskell can teach you a lot about computer science.&lt;/p&gt;

&lt;p&gt;That is the one thing I'll definitively say about all this: I don't care whether you &lt;em&gt;use&lt;/em&gt; Haskell, but you should absolutely &lt;em&gt;learn&lt;/em&gt; it. I mean, I hardly ever use it, but the knowledge I gained from learning it is indispensable.&lt;/p&gt;

&lt;p&gt;This is also the core reason that Rust is my current favorite language: Rust's traits are very similar to Haskell's typeclasses, but I think Rust has better handling of other stuff, particularly mutable state. Also Rust is incredibly fast.&lt;/p&gt;

&lt;p&gt;Now all it needs is a good GUI library...&lt;/p&gt;

&lt;p&gt;In any case, if you made it through all this, I hope you gained a deeper appreciation for polymorphism, and the three-way trade-off between code reusability, semantic stability, and language complexity.&lt;/p&gt;

</description>
      <category>computerscience</category>
    </item>
    <item>
      <title>The Strange Art of Code Reuse, Part 2</title>
      <dc:creator>Sean Williams</dc:creator>
      <pubDate>Sun, 03 Jul 2022 20:05:04 +0000</pubDate>
      <link>https://dev.to/armousness/the-strange-art-of-code-reuse-part-2-h39</link>
      <guid>https://dev.to/armousness/the-strange-art-of-code-reuse-part-2-h39</guid>
      <description>&lt;p&gt;Fundamentally, the problem of code reuse is this: when you have structured data—collections, structs, objects, discriminated unions, whatever—and you have a function that takes structured data as an argument, which structured types are allowed?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/armousness/the-strange-art-of-code-reuse-part-1-dbc"&gt;Part one&lt;/a&gt;, besides talking about what this looks like in dynamic typing, also revealed some of the intuition behind this question. It really comes down to what your function is going to do with your data. Part three will formalize this idea—it turns out that you can pose this as a logic problem, which was demonstrated way back in 1969—but we're not quite there yet.&lt;/p&gt;

&lt;p&gt;In dynamic typing, "what you can do with an object" really comes down to "what methods are defined on that object." Dynamically typed languages are generally based on the idea that objects are dictionaries. A "length" method on an object is just something like,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;obj.length = function() { ... }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;though doing this correctly requires using a constructor to do a lexical closure on the object self-reference, as in,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function make_obj() {
    obj = { ... };
    obj.length() = { obj.something_or_other };
    return obj;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These languages then allow you to do dictionary lookup with "dot notation," where &lt;code&gt;obj.length()&lt;/code&gt; is equivalent to &lt;code&gt;obj["length"]()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Anyway, my criticism of this approach is that two methods having the same name does not imply they have the same semantics. It's worth throwing in an important caveat, though: computers are not semantic machines. The only thing you can do to improve programming is to have more disciplined programmers, but language design has a role to play in instilling or "normalizing" discipline. So really my problem with dynamically typed languages is that they encourage sloppiness.&lt;/p&gt;

&lt;p&gt;Anyway, we're done with dynamic typing. Now that we're into static typing, it's time to talk about the most popular form of code reuse.&lt;/p&gt;

&lt;h1&gt;
  
  
  Hot Dogs and Other Sandwiches
&lt;/h1&gt;

&lt;p&gt;While the base requirement for code reuse is that we have a shared set of operations we can do with our function arguments, what we really want is shared semantics. In a sense, this is a philosophical problem. The most popular answer, both in CS and out in the world generally, is &lt;em&gt;taxonomy&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Taxonomy is where you create conceptual parent-child relationships between categories. Scientists have created elaborate taxonomies for all sorts of things in the natural world: the kingdom-phylum-class-order-family-genus-species categorization of life, for example, or the Berzelian classification system for minerals.&lt;/p&gt;

&lt;p&gt;Of course, I'm talking about object-oriented programming. The core feature of OOP is &lt;em&gt;inheritance&lt;/em&gt;, which says that a class is a more specialized version of another class. If you have parent class &lt;code&gt;A&lt;/code&gt; and child class &lt;code&gt;B&lt;/code&gt;, then &lt;code&gt;B&lt;/code&gt; must provide an implementation of all properties and methods on &lt;code&gt;A&lt;/code&gt;—and it can provide some more methods and properties if it wants to. Of course, if &lt;code&gt;A&lt;/code&gt; is a concrete class, &lt;code&gt;B&lt;/code&gt; starts out with default implementations for everything on &lt;code&gt;A&lt;/code&gt;, namely, the implementations provided on &lt;code&gt;A&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Because of this, if a function expects an argument of type &lt;code&gt;A&lt;/code&gt;, then it can also take an argument of type &lt;code&gt;B&lt;/code&gt;. Taking a type &lt;code&gt;A&lt;/code&gt; argument means that you'll only be able to access properties and methods specified on &lt;code&gt;A&lt;/code&gt;, which as I said, &lt;code&gt;B&lt;/code&gt; must also provide by virtue of being a child.&lt;/p&gt;

&lt;p&gt;The example problem in the first part is in one sense easy to solve in OOP, but in the real world usually ends up requiring some bizarre hacks.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;abstract class Collection&amp;lt;'t&amp;gt; {
    public abstract void Add('t);
}

public class List&amp;lt;'t&amp;gt; : Collection&amp;lt;'t&amp;gt; {
    // implementation details

    public void Add(element) {
        // implementation details
    }
}

public class Set&amp;lt;'t&amp;gt; : Collection&amp;lt;'t&amp;gt; {
    // implementation details

    public void Add(element) {
        // implementation details
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now a function can take a &lt;code&gt;Collection&lt;/code&gt;, and it's guaranteed that you can &lt;code&gt;Add&lt;/code&gt; an element to it. If you pass a &lt;code&gt;List&lt;/code&gt;, it'll put it on the end; if you pass a &lt;code&gt;Set&lt;/code&gt;, it'll add it if it isn't already present. Under the hood this is called "dynamic dispatch." Objects have tables of function pointers to their specific methods, so method invocation involves looking up the correct function pointer in the actual object being operated on and calling that.&lt;/p&gt;

&lt;p&gt;How do we do dictionaries? Probably the most sensible answer is to create a helper class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class KeyValuePair&amp;lt;'k,'v&amp;gt; {
    private 'k _key;
    private 'v _value;

    public KeyValuePair('k key, 'v value) {
        _key = key;
        _value = value;
    }

    public 'k Key {
        get { return _key; }
    }
    private 'v Value {
        get { return _value; }
    }
}

public class Dictionary&amp;lt;'k,'v&amp;gt; : Collection&amp;lt;KeyValuePair&amp;lt;'k,'v&amp;gt;&amp;gt; {
    // implementation details
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So far so good, but there's a big problem still. Let's consider Windows Presentation Foundation, one of Microsoft's many application libraries. There's a class for text boxes, &lt;code&gt;System.Windows.Controls.TextBox&lt;/code&gt;, and there's a lightweight rich text label, &lt;code&gt;System.Windows.Controls.TextBlock&lt;/code&gt;. &lt;code&gt;TextBox&lt;/code&gt; is a &lt;code&gt;Control&lt;/code&gt;, since it's used to provide input, while &lt;code&gt;TextBlock&lt;/code&gt; is not.&lt;/p&gt;

&lt;p&gt;Both classes have a property for controlling word wrapping, &lt;code&gt;TextWrapping&lt;/code&gt;. Even though both classes have the same property of the same type (&lt;code&gt;System.Windows.TextWrapping&lt;/code&gt;, an enumeration of word wrapping styles), it isn't derived from a base class. The parent of &lt;code&gt;TextBlock&lt;/code&gt; is &lt;code&gt;FrameworkElement&lt;/code&gt;, which covers anything that can be laid out and rendered, so it would be inappropriate for it to define &lt;code&gt;TextWrapping&lt;/code&gt;—that would put a spurious property on all sorts of classes, most of which don't have any text at all!&lt;/p&gt;

&lt;p&gt;Instead, the two classes independently define their own &lt;code&gt;TextWrapping&lt;/code&gt; property. This means that, at first blush, it's impossible to write a function &lt;code&gt;SetTextWrapping&lt;/code&gt; that works on both &lt;code&gt;TextBox&lt;/code&gt; and &lt;code&gt;TextBlock&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The obvious solution to this problem is allowed in C++, and disallowed in basically every object-oriented language since:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;abstract class TextElement {
    private System.Windows.TextWrapping _wrap_mode;
    // other implementation details
}

public class TextBlock : FrameworkElement, TextElement {
    // implementation details
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is called multiple inheritance, and it's verboten because it's complicated. The best demonstration of the problem is called "diamond inheritance":&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;

class A {
  public:
    virtual void foo();
};

class B: public A {
  public:
    B() { }
    void foo() {
        std::cout &amp;lt;&amp;lt; "Called foo on B" &amp;lt;&amp;lt; std::endl;
    }
};

class C: public A {
  public:
    C() { }
    void foo() {
        std::cout &amp;lt;&amp;lt; "Called foo on C" &amp;lt;&amp;lt; std::endl;
    }
};

class D: public B, public C {
  public:
    D() { }
};

int main() {
    D* d = new D();
    d-&amp;gt;foo();
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What does this program print? Nowadays you get this compiler error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;member 'foo' found in multiple base classes of different types
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;but most languages just don't allow multiple inheritance in the first place. Back when compilers allowed this, I honestly can't remember what it would have printed. Indeed, embedding multiple inheritance into a GUI library would be a maintainability disaster.&lt;/p&gt;

&lt;p&gt;Interfaces allow multiple implementation, which is fine because interfaces don't provide any implementations themselves. This means the interface inheritance scheme will never create ambiguities: interface implementations will only ever be inherited through the single-inheritance class hierarchy.&lt;/p&gt;

&lt;p&gt;So why aren't there interfaces for these orphaned properties in WPF? I don't have an answer. Maybe some Microsoft engineer out there could answer it, but I don't imagine I'd find the answer very satisfying.&lt;/p&gt;

&lt;p&gt;This also gets us back around to the problem of a generic add-to-collection function. Arguably the biggest weakness of object-oriented programming, as it's done today, is that interfaces have to be implemented as part of the class definition. So what if we wanted to allow, say, Dotnet's &lt;code&gt;System.Collections.Generic.List&amp;lt;'t&amp;gt;&lt;/code&gt; into our scheme?&lt;/p&gt;

&lt;p&gt;We can't go back and edit Dotnet's definition of &lt;code&gt;List&amp;lt;'t&amp;gt;&lt;/code&gt;, so the only real answer is inheritance. This means that our &lt;code&gt;Collection&amp;lt;'t&amp;gt;&lt;/code&gt; class has to become an interface. Now if someone takes our code and wants to extend the functionality further, they have to go through the same trouble: define their functionality as an interface, and inherit our &lt;code&gt;List&amp;lt;'t&amp;gt;&lt;/code&gt; to tack on their interface implementation.&lt;/p&gt;

&lt;p&gt;To summarize object-oriented programming, then...&lt;/p&gt;

&lt;p&gt;We do get some semantic discipline, since it pushes programmers to think taxonomically. We have reasonable assurance that &lt;code&gt;Collection.Add&lt;/code&gt; has consistent meaning, since a sane person isn't going to stick a non-collection class in the &lt;code&gt;Collection&lt;/code&gt; interface. It also makes the intentions of our arguments clearer, for the same reasons: type names, at the very least, clue programmers in to our intended semantics.&lt;/p&gt;

&lt;p&gt;The problem, and this is why the fictional Carnap &lt;a href="https://existentialcomics.com/comic/268"&gt;had so much trouble&lt;/a&gt; classifying sandwiches and hot dogs, is that the world is not taxonomical. Any taxonomy is inherently inadequate, which does two things to class hierarchies: first, they get bloated, and second, you end up having to hack around their limitations. So we get deranged stuff like the "composition pattern," and needless inheritance, and "extension methods," and the like.&lt;/p&gt;

&lt;p&gt;In the next and final episode I'll talk about Haskell. I'm no theory zealot, and I don't think type classes are the end all and be all, but I do think they're a huge step up from all of this.&lt;/p&gt;

</description>
      <category>computerscience</category>
    </item>
    <item>
      <title>The Strange Art of Code Reuse, Part 1</title>
      <dc:creator>Sean Williams</dc:creator>
      <pubDate>Fri, 01 Jul 2022 17:26:15 +0000</pubDate>
      <link>https://dev.to/armousness/the-strange-art-of-code-reuse-part-1-dbc</link>
      <guid>https://dev.to/armousness/the-strange-art-of-code-reuse-part-1-dbc</guid>
      <description>&lt;p&gt;When I try to explain programming to a non-programmer, I go to an old standby: how do you make a sandwich? Sometimes they'll ask the first most important question: what kind of sandwich? I'll say something like, "that's a very good question, but for now, pick one."&lt;/p&gt;

&lt;p&gt;After all, you don't want to do too much too quickly. More to the point, you don't want to immediately muddy the waters with the most important ontological question, &lt;a href="https://existentialcomics.com/comic/268"&gt;is a hot dog a sandwich&lt;/a&gt;? At some point, though, you move on from primitive types and enter the wild world of polymorphism—or maybe you never learned a (mostly) monomorphic language like C or FORTRAN.&lt;/p&gt;

&lt;p&gt;Anyway, the art of code reuse is defining what's common about heterogeneous data. The end goal is answering the question, in what situations can these data stand in for those data—or to be more concrete, what's required for this type to be a valid parameter to this function? Having functions that can operate on a wide range of types is called polymorphism, "having many shapes."&lt;/p&gt;

&lt;p&gt;As a starting point, C has very little support for polymorphism, though clever programmers can hack it in using macros—which is the real reason it's called C++. But even basic C still has a dash of hard-coded polymorphism in the form of +, -, *, /, and the like. The compiler does some work to cast arithmetic operands into the same type, and then emits assembly based on that type.&lt;/p&gt;

&lt;p&gt;This also helps illustrate what polymorphism really is: + is well-defined for all primitive numeric types, and importantly, it has the same semantics for all primitive numeric types. Conversely, the (hardware) implementation of floating-point addition is vastly different and more complicated than integer addition. This is basically where polymorphism starts from, though: a situation where you have an operation with substantially similar semantics over a wide range of types, but in which the implementations are all over the place.&lt;/p&gt;

&lt;p&gt;The big question is, how do we define "substantially similar semantics?" There are basically three standard answers, and you're likely familiar with at least one of them.&lt;/p&gt;

&lt;p&gt;Let's consider an artificial but illustrative problem: how could we write a function that, given two collections, joins them together? The meaning of "join" is specific to each collection type, so we would concatenate lists and union sets. Dictionaries are more complicated, and will be a crack in the door to much more advanced topics in static typing.&lt;/p&gt;

&lt;h1&gt;
  
  
  If It Quacks
&lt;/h1&gt;

&lt;p&gt;Dynamic typing is used in languages like JavaScript, Python, and Lua. Most interpreted languages are dynamically typed, which has its own technical reasons. The style of dynamic typing you typically run into is also sometimes called "duck typing," as in, "if it quacks like a duck, waddles like a duck, and floats like a duck, it's close enough to being a duck for our purposes."&lt;/p&gt;

&lt;p&gt;First and foremost, primitive data in these languages are still typed. In my experience, these languages nowadays tend to have all numbers be doubles, and all chars be strings, but a primitive is still a number, a string, or possibly a boolean. They often use implicit coercion, meaning that &lt;code&gt;"hello " + 5&lt;/code&gt; will convert &lt;code&gt;5&lt;/code&gt; to &lt;code&gt;"5"&lt;/code&gt; to produce &lt;code&gt;"hello 5"&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Structured data are, conceptually, dictionaries. They may or may not support lists/arrays—if they don't, then lists are dictionaries with indexes as keys.&lt;/p&gt;

&lt;p&gt;In terms of joining collections, let's look at JavaScript. It basically has two collection types: Arrays and Objects (which are dictionaries). Our function might look like this, though there are other possible implementations...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function join(a, b) {
    if(a.constructor === Array &amp;amp;&amp;amp; b.constructor === Array) {
        return a.concat(b);
    }
    if(a.constructor === Object &amp;amp;&amp;amp; (b.constructor === Array || b.constructor === Object)) {
        return Object.assign({}, a, b);
    }
    return null;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Maybe there's a better implementation, I'm not really a JavaScript guy, but it gets at the core of duck typed polymorphism: enumerating types.&lt;/p&gt;

&lt;p&gt;The other rider in this apocalypse is looking for the presence of dictionary keys. After all, objects are dictionaries, which means methods are functions keyed off their name (sometimes with additional magic to get a self-reference). For example, let's say we want to be able to add an element onto either an Array or an Object. We might do this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function make_addable_array(a) {
    a.add = function(x) { a[a.length] = x; };
    return a;
}

// e.g., arr = make_addable_array([1, 2, 3]);
// arr.add(4);
// - [1, 2, 3, 4]

function make_addable_object(o) {
    o.add = function(x) {
        idx = 0;
        for(k in o) {
            if(Number(k) &amp;gt;= idx) {
                idx = Number(k) + 1;
            }
        }
        o[idx] = x;
    };
    return o;
}

// e.g., obj = make_addable_object({"hello": "world", 1: 5});
// obj.add(3);
// - {"hello": "world", 1: 5, 2: 3}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We could now write a trivial function to add an element onto a collection created this way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function add_element(collection, element) {
    if(collection.add) {
        collection.add(element);
    }
    else {
        console.log("invalid collection passed to add_element");
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We're actually making a tragically strong assumption in the definition of &lt;code&gt;add_element&lt;/code&gt;: that an object having a key/member named &lt;code&gt;add&lt;/code&gt; means the same thing for all collections that are passed to &lt;code&gt;add_element&lt;/code&gt;. This is the big tradeoff with dynamic typing, though: you give up semantic guarantees in exchange for simpler syntax. Not a tradeoff I like, which is why I personally avoid dynamically typed languages.&lt;/p&gt;

&lt;p&gt;Anyway, this is a lot of trouble! Will other styles of polymorphism be any easier? This post is already getting too long, so I'll pick it up next time with a study of the taxonomy of sandwiches.&lt;/p&gt;

</description>
      <category>computerscience</category>
    </item>
    <item>
      <title>Generating hashed passwords for PostgreSQL</title>
      <dc:creator>Sean Williams</dc:creator>
      <pubDate>Tue, 28 Jun 2022 20:25:30 +0000</pubDate>
      <link>https://dev.to/armousness/generating-hashed-passwords-for-postgresql-2ai6</link>
      <guid>https://dev.to/armousness/generating-hashed-passwords-for-postgresql-2ai6</guid>
      <description>&lt;p&gt;This is a quickie, but can be incredibly useful. For the background, in case you don't know, it's a very very bad idea to store passwords. The first change is storing the hash of a password. A hash is just a function that's given some bytes and deterministically produces some other bytes, but it's very hard to go the other way. That is, if you have &lt;code&gt;password_hash = hash(password)&lt;/code&gt; (where &lt;code&gt;password&lt;/code&gt; is just the user's plaintext password), you can't easily derive &lt;code&gt;password&lt;/code&gt; from &lt;code&gt;password_hash&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Because of this, you only need to store password hashes. A user sends a password, you hash it, and see if the hashes match. For a good hashing algorithm, the probability of two passwords producing the same hash is minuscule. If your database is broken into, attackers will only get the hashes, not the passwords.&lt;/p&gt;

&lt;p&gt;This gave rise to "rainbow table attacks," in which you precompute hashes for a lot of common passwords for common hashing functions. If you get a dump of password hashes, you see if any of the hashes are present in the rainbow table. For any hashes that show up, now you've got their password.&lt;/p&gt;

&lt;p&gt;The defense against this is called "salting." You generate a random string, called the &lt;code&gt;salt&lt;/code&gt;, and you compute &lt;code&gt;salted_hash = hash(password + salt)&lt;/code&gt; (plus being string/array concatenation). You then store &lt;code&gt;salt&lt;/code&gt; and &lt;code&gt;salted_hash&lt;/code&gt;, so you can repeat the calculation when a user goes to log in. It's fine if the salts are leaked, because again the only thing we're actually defending against here is rainbow tables: an attacker can't precompute the hash of common passwords concatenated with all possible salts.&lt;/p&gt;

&lt;p&gt;Anyway, Postgres lets you provide a salted, hashed password when creating a user. The issue with providing a hashed password to someone else's system is that you need to follow exactly the same steps they do: this whole song and dance is about being able to reproduce the same hashes from the same passwords. Being a little bit wrong on the hash you provide will make logins fail.&lt;/p&gt;

&lt;p&gt;I did way too much digging to figure out how to reproduce the Postgres password hashing algorithm (particularly digging through the Postgres and Npgsql sources), so hopefully this'll save someone from the same trouble:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let password_hash (password: string) =
    let normalized = System.Text.Encoding.UTF8.GetBytes(password.Normalize(System.Text.NormalizationForm.FormKC))
    let salt_len = 16
    let default_iterations = 4096

    let salt = System.Security.Cryptography.RandomNumberGenerator.GetBytes(salt_len)
    let mutable salt1 = Array.create (salt.Length + 4) 0uy

    let hmac = new System.Security.Cryptography.HMACSHA256(normalized)
    System.Buffer.BlockCopy(salt, 0, salt1, 0, salt.Length)
    salt1[salt1.Length - 1] &amp;lt;- 1uy

    let mutable hi = hmac.ComputeHash(salt1)
    let mutable u1 = hi

    for _ in 1 .. default_iterations - 1 do
        let u2 = hmac.ComputeHash(u1)
        for i in 0 .. hi.Length - 1 do
            hi[i] &amp;lt;- hi[i] ^^^ u2[i]
        u1 &amp;lt;- u2

    let client_key = (new System.Security.Cryptography.HMACSHA256(hi)).ComputeHash(System.Text.Encoding.UTF8.GetBytes("Client Key"))
    let stored_key = (System.Security.Cryptography.SHA256.Create()).ComputeHash(client_key)
    let server_key = (new System.Security.Cryptography.HMACSHA256(hi)).ComputeHash(System.Text.Encoding.UTF8.GetBytes("Server Key"))

    let builder = new System.Text.StringBuilder()
    builder.Append("'SCRAM-SHA-256$").Append(default_iterations.ToString()).Append(":").Append(System.Convert.ToBase64String(salt)).Append("$")
        .Append(System.Convert.ToBase64String(stored_key)).Append(":").Append(System.Convert.ToBase64String(server_key)).Append("'").ToString()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, within a CREATE ROLE query, you just use,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"ENCRYPTED PASSWORD " + password_hash password
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>dotnet</category>
      <category>fsharp</category>
      <category>postgres</category>
    </item>
    <item>
      <title>Picking colors in WPF</title>
      <dc:creator>Sean Williams</dc:creator>
      <pubDate>Mon, 27 Jun 2022 22:24:30 +0000</pubDate>
      <link>https://dev.to/armousness/picking-colors-in-wpf-3e4o</link>
      <guid>https://dev.to/armousness/picking-colors-in-wpf-3e4o</guid>
      <description>&lt;p&gt;Since I've been working in WPF a lot, it's jumped out at me how many features are conspicuously missing. The feature I'll talk about today is color picking. I'll start with the final dialog box, since I'll be referring to it later:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zL074at7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/44luoty3u20kbprpc4oc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zL074at7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/44luoty3u20kbprpc4oc.png" alt="The final color picker dialog box" width="294" height="354"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Computer color is a three-dimensional space, not least because there are three colors of filters in your monitor. The simpler color space is the colors of those filters—red, green, and blue—but it's also the hardest to work with. For normal use, we typically use a different three-dimensional space, of hue, saturation, and value.&lt;/p&gt;

&lt;p&gt;Hue is your position on the rainbow, so values of hue go through red-orange-yellow-green-blue-violet. Saturation is the "whiteness" of your color, and value is the "blackness." When picking HSV colors, the standard is to have a two-dimensional selector (a rectangle) and a one-dimensional selector (a line). I followed Gimp's example, with saturation and value as the 2D selection, and hue as the 1D. Refer to the above image to see what I mean: you pick a hue in the small box on the right, then the big box on the left shows you all possible saturation-value combinations for that hue.&lt;/p&gt;

&lt;p&gt;The first thing we need, then, is functions to convert between RGB and HSV colors:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let inline hsv_to_rgb h s v =
    let i = int (h * 6.) % 6
    let f = h * 6. - System.Math.Floor(h * 6.)

    let v = v * 255.
    let p = byte (v * (1. - s))
    let q = byte (v * (1. - f * s))
    let t = byte (v * (1. - (1. - f) * s))
    let v = byte v

    if (i = 0) then (v, t, p)
    else if (i = 1) then (q, v, p)
    else if (i = 2) then (p, v, t)
    else if (i = 3) then (p, q, v)
    else if (i = 4) then (t, p, v)
    else (v, p, q)

let inline rgb_to_hsv r g b =
    let v = max r &amp;lt;| max g b
    let delta = float (v - (min r &amp;lt;| min g b))

    let s = if v = 0uy then 0. else delta / (float v)

    let h =
        if s = 0. then 0.
        else
            if r = v then (float g - float b) / delta
            else if g = v then 2. + (float b - float r) / delta
            else 4. + (float r - float g) / delta
    let h = if h &amp;lt; 0. then h + 6. else h
    (h / 6., s, (float v) / 255.)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, HSV is three floats in the range [0, 1], while RGB is three bytes (so the range is [0, 255]). Hue gets scaled out to six, for the three primary (red, green, blue) and three secondary (yellow, cyan, magenta) colors, but to me it makes more sense for everything to be in the same range outside these functions.&lt;/p&gt;

&lt;p&gt;Now we get into WPF weirdness. As far as I can tell, Brushes are really not configurable. While there is a LinearGradientBrush, the linear gradient is in RGB space. The only real answer I could find to make a hue spectrum is to make an image. You could make this by hand if you want, and Gimp or Photoshop will probably help you out, but we can also just do this in code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let hue_gradient =
    let bitmap = new System.Windows.Media.Imaging.WriteableBitmap(1, 360, 96., 96., System.Windows.Media.PixelFormats.Pbgra32, null)
    let colors = [|
            for i in 0u .. 359u -&amp;gt;
                let y = 359u - i
                let i = y / 60u
                let h = ((y % 60u) * 255u) / 60u

                if i = 0u then
                    (h &amp;lt;&amp;lt;&amp;lt; 8) ||| (255u &amp;lt;&amp;lt;&amp;lt; 16) ||| (255u &amp;lt;&amp;lt;&amp;lt; 24)
                else if i = 1u then
                    (255u &amp;lt;&amp;lt;&amp;lt; 8) ||| ((255u - h) &amp;lt;&amp;lt;&amp;lt; 16) ||| (255u &amp;lt;&amp;lt;&amp;lt; 24)
                else if i = 2u then
                    h ||| (255u &amp;lt;&amp;lt;&amp;lt; 8) ||| (255u &amp;lt;&amp;lt;&amp;lt; 24)
                else if i = 3u then
                    255u ||| ((255u - h) &amp;lt;&amp;lt;&amp;lt; 8) ||| (255u &amp;lt;&amp;lt;&amp;lt; 24)
                else if i = 4u then
                    255u ||| (h &amp;lt;&amp;lt;&amp;lt; 16) ||| (255u &amp;lt;&amp;lt;&amp;lt; 24)
                else
                    (255u - h) ||| (255u &amp;lt;&amp;lt;&amp;lt; 16) ||| (255u &amp;lt;&amp;lt;&amp;lt; 24)
        |]
    bitmap.WritePixels(System.Windows.Int32Rect(0, 0, 1, 360), colors, 4, 0, 0)
    bitmap.Freeze()
    new System.Windows.Media.ImageBrush(bitmap)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There's a lot of things to say about this function. The image this produces is 1 pixel wide and 360 pixels tall. This is just following the convention that hue is a circle, and there are 360° in a circle, but you could make it bigger if you need more color resolution.&lt;/p&gt;

&lt;p&gt;The calculations here are really just an integer-only reformulation of &lt;code&gt;hsv_to_rgb&lt;/code&gt; above, except that saturation and value are always 1. The other big thing here is, this writes out one pixel at a time: the type of &lt;code&gt;colors&lt;/code&gt; is &lt;code&gt;uint32[]&lt;/code&gt;. In F#, &lt;code&gt;|||&lt;/code&gt; is the bitwise-or operator, and &lt;code&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/code&gt; is the bitshift-left operator.&lt;/p&gt;

&lt;p&gt;This brings us to the issue that most computers eat eggs from the little end: "A little-endian system, in contrast, stores the least-significant byte at the smallest address" (from Wikipedia). Least significant means highest value, hence the pixel ordering in memory is in fact ARGB, for a pixel format called BGRA. Meaning, if a color byte is not shifted, that's the blue channel, then an 8-bit shift is green, 16 bits is red, and 24 bits is alpha.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;hue_gradient&lt;/code&gt; is an ImageBrush, so it can be used as the Fill of a rectangle. We still need a callback, but that'll only make sense in the context of saturation and value.&lt;/p&gt;

&lt;p&gt;This is where things get a bit mathematical. The box for saturation and value needs to be updated whenever a new hue is selected, but generating a new image on every mouse move event wouldn't be great. It turns out, we can do this entirely with alpha blending.&lt;/p&gt;

&lt;p&gt;The way RGBA transparency works is quite simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;blended_color =
    foreground_alpha * foreground_color +
        (1 - foreground_alpha) * background_color
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Looking back at the HSV to RGB conversion, we had,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let v = v * 255.
let p = byte (v * (1. - s))
let q = byte (v * (1. - f * s))
let t = byte (v * (1. - (1. - f) * s))
let v = byte v
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;p&lt;/code&gt;, &lt;code&gt;q&lt;/code&gt;, and &lt;code&gt;t&lt;/code&gt; are used to set color channels: &lt;code&gt;q&lt;/code&gt; and &lt;code&gt;t&lt;/code&gt; for secondary channels, and &lt;code&gt;p&lt;/code&gt; is for an "unused" channel. For example, in the case where we're moving from red to yellow, the RGB color is &lt;code&gt;(v, t, p)&lt;/code&gt;: &lt;code&gt;v&lt;/code&gt;, pure value, sets the amount of red, while "leftover" hue (&lt;code&gt;f&lt;/code&gt;) is combined with saturation and value to set yellow, while just saturation and value set blue.&lt;/p&gt;

&lt;p&gt;The more important point here is, this looks a lot like the equation for alpha blending. I worked this all out numerically, so I don't have a full derivation here (exercise for the reader?), but it turns out you can make a saturation-value selector by overlaying three Brushes on top of each other, from bottom to top:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A SolidColorBrush, which contains an HSV color of the form (H, 1, 1)—we'll call this the &lt;code&gt;color_background_brush&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;A LinearGradientBrush, which goes horizontally from the RGBA color (255, 255, 255, 255) to (255, 255, 255, 0)—that is, opaque white to transparent white&lt;/li&gt;
&lt;li&gt;A LinearGradientBrush, which goes vertically from the RGBA color (0, 0, 0, 0) to (0, 0, 0, 255)—that is, transparent black to opaque black, also note the alpha values are reversed here since in WPF going down is an increase in y, in other words, we want this brush to be opaque at the &lt;em&gt;bottom&lt;/em&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When a new color is selected, we just have to update the SolidColorBrush to the new hue, and the whole SV color space is updated automatically. Or if that's too mystical for you, it gets updated by fragment composition in the rendering pipeline.&lt;/p&gt;

&lt;p&gt;Now all that's left is a couple events:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    let mutable (h, s, v) = (0., 1., 1.)
    let mutable (r, g, b) = hsv_to_rgb h s v

    let hue_bar_drag _ (args: System.Windows.Input.MouseEventArgs) =
        if args.LeftButton = System.Windows.Input.MouseButtonState.Pressed then
            h &amp;lt;- 1. - args.GetPosition(hue_bar).Y / (float color_box_height)
            let (r', g', b') = hsv_to_rgb h 1. 1.
            color_background_brush.Color &amp;lt;- System.Windows.Media.Color.FromRgb(r', g', b')
            let (r', g', b') = hsv_to_rgb h s v
            r &amp;lt;- r'
            g &amp;lt;- g'
            b &amp;lt;- b'
            color_preview_brush.Color &amp;lt;- System.Windows.Media.Color.FromRgb(r, g, b)
    hue_bar.MouseLeftButtonDown.AddHandler(hue_bar_drag)
    hue_bar.MouseMove.AddHandler(hue_bar_drag)

    let sv_bar_drag _ (args: System.Windows.Input.MouseEventArgs) =
        if args.LeftButton = System.Windows.Input.MouseButtonState.Pressed then
            s &amp;lt;- args.GetPosition(value_mask).X / (float color_box_height)
            v &amp;lt;- 1. - args.GetPosition(value_mask).Y / (float color_box_height)
            let (r', g', b') = hsv_to_rgb h s v
            r &amp;lt;- r'
            g &amp;lt;- g'
            b &amp;lt;- b'
            color_preview_brush.Color &amp;lt;- System.Windows.Media.Color.FromRgb(r, g, b)
    value_mask.MouseLeftButtonDown.AddHandler(sv_bar_drag)
    value_mask.MouseMove.AddHandler(sv_bar_drag)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;color_box_height&lt;/code&gt;, of course, is just the size (in pixels) of the hue and saturation-value selection boxes. I've got it set to 256 in the above image.&lt;/p&gt;

&lt;p&gt;After this you just have to configure the UI as you'd like it: &lt;code&gt;color_preview_brush&lt;/code&gt; is a SolidColorBrush applied to the rectangle along the bottom, which displays the currently selected color. You'll need to use a Grid to properly overlay &lt;code&gt;color_background_brush&lt;/code&gt; (or rather, a Rectangle with that as its Fill) with the saturation and value masks. You could also add a few Lines or Circles to show the positions of the selected color if you're so inclined. But you know, I'm not going to tell you how to make your dialog boxes. Finally, the constantly-updated &lt;code&gt;(r, g, b)&lt;/code&gt; values are the return.&lt;/p&gt;

&lt;p&gt;Anyway, that's how you can make a color picker dialog. I mean sure you could download a library for it, but isn't it more interesting figuring out how they work?&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>wpf</category>
      <category>fsharp</category>
    </item>
  </channel>
</rss>
