{"id":832,"date":"2024-12-18T11:07:55","date_gmt":"2024-12-18T11:07:55","guid":{"rendered":"https:\/\/blog.67bricks.com\/?p=832"},"modified":"2024-12-18T11:07:55","modified_gmt":"2024-12-18T11:07:55","slug":"wishing-upon-a-star","status":"publish","type":"post","link":"https:\/\/blog.67bricks.com\/?p=832","title":{"rendered":"Wishing upon a star"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">When I was a boy, many years ago&#8230;<\/h2>\n\n\n\n<p>&#8230;I used to like building polyhedron models out of card. Here is a photo of me, probably around 1987ish, spray-painting a <a rel=\"noreferrer noopener\" href=\"https:\/\/en.wikipedia.org\/wiki\/Compound_of_ten_tetrahedra\" target=\"_blank\">compound of ten tetrahedra<\/a>. Evidently the photographer had partially obscured the aperture with their finger, but there were no digital cameras back in those days, you only found out your mistakes when you had the picture developed!<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"529\" height=\"718\" src=\"https:\/\/blog.67bricks.com\/wp-content\/uploads\/2024\/12\/boy.jpg\" alt=\"The author, as a boy, spray-painting a compound of 10 tetrahedra.\" class=\"wp-image-840\" srcset=\"https:\/\/blog.67bricks.com\/wp-content\/uploads\/2024\/12\/boy.jpg 529w, https:\/\/blog.67bricks.com\/wp-content\/uploads\/2024\/12\/boy-221x300.jpg 221w\" sizes=\"auto, (max-width: 529px) 85vw, 529px\" \/><figcaption>The artist at work<\/figcaption><\/figure><\/div>\n\n\n\n<p>Making a model out of card was a long and laborious process. First, armed with a protractor and ruler, one had to draw the <a rel=\"noreferrer noopener\" href=\"https:\/\/en.wikipedia.org\/wiki\/Net_(polyhedron)\" target=\"_blank\">net<\/a> on card, making sure there were tabs in the right place to glue the thing together. Then it had to be cut out, and the intended folds scored very carefully with a craft knife (you need them to fold cleanly, but if you cut through the card you&#8217;ll have to start again). Finally, it had to be glued together to give it three-dimensional form, a process which got increasingly fiddly as access to the interior became harder.<\/p>\n\n\n\n<!--more-->\n\n\n\n<h2 class=\"wp-block-heading\">This being the season of goodwill and all that&#8230;<\/h2>\n\n\n\n<p>&#8230;I thought I&#8217;d make a Christmas star decoration out of card. My plan was to make what was essentially an <a rel=\"noreferrer noopener\" href=\"https:\/\/en.wikipedia.org\/wiki\/Icosahedron\" target=\"_blank\">icosahedron<\/a> but with pointy triangular pyramids on each face (a bit like a stellated icosahedron). I figured that I could save time on the net construction by creating them in SVG and laser-printing them onto card. I scribbled onto a convenient piece of paper my plan for the net:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1008\" height=\"756\" src=\"https:\/\/blog.67bricks.com\/wp-content\/uploads\/2024\/12\/draft.jpg\" alt=\"Pencil sketch of the net of the star.\" class=\"wp-image-841\" srcset=\"https:\/\/blog.67bricks.com\/wp-content\/uploads\/2024\/12\/draft.jpg 1008w, https:\/\/blog.67bricks.com\/wp-content\/uploads\/2024\/12\/draft-300x225.jpg 300w, https:\/\/blog.67bricks.com\/wp-content\/uploads\/2024\/12\/draft-768x576.jpg 768w\" sizes=\"auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><figcaption>One fifth of the net for the star<\/figcaption><\/figure><\/div>\n\n\n\n<p>One of those, I figured, would fold to make a chain of four pyramids, and five such chains could be joined together to make the final shape. The big question was &#8211; how pointy should I make the pyramids? Too pointy, and they&#8217;d be really tricky to glue together. Not pointy enough and the star would look a bit rubbish. Also, I needed to make each net as big as possible while still being printable onto an A4-sized piece of card. I could obviously prototype this by drawing something in <a rel=\"noreferrer noopener\" href=\"https:\/\/inkscape.org\/\" data-type=\"URL\" data-id=\"https:\/\/inkscape.org\/\" target=\"_blank\">Inkscape<\/a>, but I didn&#8217;t fancy the faff of having to edit it and make sure all of the angles came out right. So, naturally, I started to wonder how I could write something to generate the SVG for me, allowing me to tweak angles and regenerate at will (it didn&#8217;t have to solve the problem completely; I could always scale and rotate in Inkscape to make best use of the card).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Cometh the hour&#8230;<\/h2>\n\n\n\n<p>&#8230;cometh the libraries. Two of them, in fact. To handle the geometry, I remembered that years and years ago I&#8217;d written a silly math library in <a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/danielrendall\/JavaMathLib\" target=\"_blank\">Java<\/a>, and happily I&#8217;d written something similar in <a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/danielrendall\/ScalaMathLib\" target=\"_blank\">Scala<\/a> (neither of these is to be taken seriously as a proper library &#8211; do not use them!). That handles points, vectors, lines and so on. But then I wanted a way to describe the net in terms of &#8220;this is how you make a triangle with a base angle of x degrees, so draw one, rotate a bit, draw another one, now do another of these shapes but flipped&#8230;&#8221; and so on.<\/p>\n\n\n\n<p>Basically, this would be something a bit like <a rel=\"noreferrer noopener\" href=\"https:\/\/en.wikipedia.org\/wiki\/Logo_(programming_language)\" target=\"_blank\">Logo<\/a>, where there&#8217;s a notional &#8220;turtle&#8221; that exists on the plane somewhere, and can be told to go forward, or turn through some angle, with a pen that&#8217;s either down or up so it may or may not draw a line when it moves. So at any moment, there&#8217;s some &#8220;state&#8221; in the system (the set of lines drawn so far on the canvas, the location and orientation of the turtle) and I want to be able to issue commands that update the state or rather, since this is Scala, we want the state to be immutable and commands will return an updated copy of it.<\/p>\n\n\n\n<p>So a first stab (in pseudocode) at something to draw an isoceles triangle with a particular base length and opposite angle might look something like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">def triangle(currentState: State, baseLength: Double, oppositeAngle: Rad): (State, Point) {\n  val equalAngle: Rad = (Rad.PI - oppositeAngle) \/ 2.0\n  val equalSide = baseLength \/ (2 * Math.cos(equalAngle))\n  val currentlyFacing = getCurrentDirectionFromState(currentState) \/\/ because we'll want to use this later\n  val (stateAfterDrawingBaseLine, endPointOfBaseLine) = drawLineAndMove(currentState, baseLength)\n  val stateAfterRotatingTheFirstTime = rotateBy(getCurrentDirectionFromState, Rad.PI - equalAngle)\n  val stateAfterDrawingTheFirstEqualSide = drawLineAndMove(stateAfterRotatingTheFirstTime, equalSide)\n  \/\/ ... you get the idea\n} yield endOfBase\n\n<\/code><\/pre>\n\n\n\n<p>There are at least three problems with this approach:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>We keep having to return an updated state, which needs to be passed on to the next instruction for it to operate on, which means we have to get creative with variable names. I could have used <code>state1<\/code>, <code>state2<\/code>, <code>state3<\/code> and so on, but it&#8217;s still a bit ugly, and easy to use the wrong state somewhere leading to mysterious bugs.<\/li><li>Sometimes we want to return something additional to the new state (e.g. the end point of the line we&#8217;ve just drawn). We can either invent a bunch of case classes for this, or return a <code>Tuple(State, something else)<\/code>, but the lack of uniformity of return types seems a bit inelegant.<\/li><li>We&#8217;re not handling errors anywhere.<\/li><\/ol>\n\n\n\n<p>We can do something about &#8220;3&#8221; easily, at least &#8211; if we define methods to return <code>Try[(State, other, things)]<\/code> then we can use a for-comprehension and potentially deal with errors using the usual <code>.recover<\/code>, <code>.recoverWith<\/code> combinators. But the first two issues still rankle.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The second library&#8230;<\/h2>\n\n\n\n<p>&#8230;and the subject of this blogpost after an extended scene-setting introduction, is a library for sequencing computations (internal to 67 Bricks, I&#8217;m afraid, so no link!) which I wrote a few years inspired by exercises in the book <a rel=\"noreferrer noopener\" href=\"https:\/\/www.manning.com\/books\/functional-programming-in-scala\" target=\"_blank\">Functional Programming in Scala<\/a> (looking around my office, I can&#8217;t see it anywhere, which makes me wonder if I lent it to someone).<\/p>\n\n\n\n<p>Let us cut to the chase, and see what the <code>triangle<\/code> method looks like, and then try to understand it.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">def triangle(baseLength: Double,\n             oppositeAngle: Rad): Computation[Canvas, Point, DrawFailure] = {\n  val equalAngle: Rad = (Rad.PI - oppositeAngle) \/ 2.0\n  val equalSide = baseLength \/ (2 * Math.cos(equalAngle))\n  for {\n    facing &lt;- getFacing\n    endOfBase &lt;- drawLineAndMove(baseLength)\n    _ &lt;- rotateBy(Rad.PI - equalAngle)\n    _ &lt;- drawLineAndMove(equalSide)\n    _ &lt;- rotateBy(Rad.PI - oppositeAngle)\n    _ &lt;- drawLineAndMove(equalSide)\n    _ &lt;- moveTo(endOfBase)\n    _ &lt;- rotateTo(facing)\n  } yield endOfBase\n}\n<\/code><\/pre>\n\n\n\n<p>So, it is a for-comprehension, and it&#8217;s all quite easy to follow, but where on earth has the state gone? There&#8217;s no state being passed into the method, and we appear to be ignoring the return values from many of the methods (assigning to <code>_<\/code>). And what is that <code>Computation[Canvas, Point, DrawFailure]<\/code>?<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Computations, and their outcomes<\/h2>\n\n\n\n<p>The computation library has a trait <code>Computation[S, +A, +F]<\/code>, and a sealed trait <code>ComputationResult[S, +A, +F]<\/code> defined as follows:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">trait Computation[S, +A, +F] {\n\n  def run: S =&gt; ComputationResult[S, A, F]\n\n  def map[B](fn: A =&gt; B): Computation[S, B, F] = ... \/\/ details omitted\n\n  def flatMap[B, G :&gt; F](fn: A =&gt; Computation[S, B, G]): Computation[S, B, G} = ...\n\n}\n\nobject Computation {\n\n  private class ComputationImpl[S, +A, +F](override val run: S =&gt; ComputationResult[S, A, F]) extends Computation[S, A, F]\n\n  \/\/ Constructor for Computations, transforming a suitable function into a Computation\n  def apply[S, A, F](run: S =&gt; ComputationResult[S, A, F]): Computation[S, A, F] = new ComputationImpl(run)\n\n}\n\nsealed trait ComputationResult[S, +A, +F]\n\ncase class Ongoing[S, +A, +F](state: S, result: A) extends ComputationResult[S, A, F]\n\ncase class Failed[S, +A, +F](error: F) extends ComputationResult[S, A, F]\n<\/code><\/pre>\n\n\n\n<p>A <code>Computation[S, A, F]<\/code> is basically a function, which takes some kind of &#8220;state&#8221; (represented by the type <code>S<\/code>), and must return a <code>ComputationResult<\/code> of which there is a choice of two; either an <code>Ongoing<\/code> encapsulating an updated state <code>S<\/code> and possibly some kind of observable result of type <code>A<\/code>, or a <code>Failed<\/code> which holds an error of type <code>F<\/code>. In the <code>triangle<\/code> example above, we have the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>The &#8220;state&#8221; was a class called <code>Canvas<\/code> which basically holds a list of all lines drawn so far plus the current location and orientation of the &#8220;turtle&#8221;<\/li><li>The return type of that particular function (the <code>A<\/code>) was <code>Point<\/code>, being the point at the end of the baseline of the triangle<\/li><li>The &#8220;error&#8221; type was a case class called <code>DrawFailure<\/code> (which was basically a wrapper around a <code>Throwable<\/code>)<\/li><\/ul>\n\n\n\n<p>So where is the state in the <code>triangle<\/code> function? Where does the drawing happen? The answer is that the <code>triangle<\/code> function by itself doesn&#8217;t really do anything immediately when it is called. The <code>Computation[Canvas, Point, DrawFailure]<\/code> it returns can be thought of as function which, when called with a suitable <code>Canvas<\/code>, will return an updated <code>Canvas<\/code> with the lines of a triangle drawn on it. Since it has been written as a for-comprehension over other <code>Computation<\/code>s, it doesn&#8217;t immediately look like it&#8217;s a function, and neither do the things it calls, and in fact we have to explore a little way into the nest of <code>Computation<\/code>-returning functions until we find something that isn&#8217;t implemented as a for-comprehension but actually looks like it contains a function, for example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">def addLine(newLine: Line): Computation[Canvas, Unit, DrawFailure] = Computation(c =&gt; Ongoing(c.addLine(newLine)), ())\n<\/code><\/pre>\n\n\n\n<p>This, finally, returns a function which, when called with a <code>Canvas<\/code>, will call the <code>addLine<\/code> method on <code>Canvas<\/code> (which returns an updated <code>Canvas<\/code>), and parcels this up in an <code>Ongoing<\/code> with <code>Unit<\/code> (<code>()<\/code>) as the return value.<\/p>\n\n\n\n<p>The things that makes the magic happen are the <code>map<\/code> and <code>flatMap<\/code> functions defined in the <code>Computation<\/code> trait, the existence of which enables the use of for-comprehensions. The <code>map<\/code> method simply allows the return type of the <code>Computation<\/code> to be changed from <code>A<\/code> to <code>B<\/code>, given a function <code>A =&gt; B<\/code>. If you had a <code>Computation[S, String, F]<\/code> you could append <code>.map(_.length)<\/code> to convert it to a <code>Computation[S, Int, F]<\/code> returning the length of the computed <code>String<\/code> but not changing the state in any way (or the fact that the result was <code>Ongoing<\/code>). The <code>flatMap<\/code> function is more powerful; it allows a new <code>Computation<\/code> to be created based on the returned result (the <code>A<\/code>) of the current <code>Computation<\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Why use the library?<\/h2>\n\n\n\n<p>The example above was basically a bit of fun &#8211; a case of me finding uses for a couple of things I&#8217;d previously written, hacking something together to solve a problem. The final code used to create the net looked something like this, where <code>fan<\/code> drew a three-triangle structure  like the structure at the top of my sketch above:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">val baseLength = 100.0\nval baseAngle = Rad.PI \/ 6\n\nval doFan =  fan(baseLength, baseAngle, 3)\n\nval twoFans = for {\n  _ &lt;- doFan\n  _ &lt;- rotateBy(Rad.PI)\n  _ &lt;- doFan\n} yield ()\n\nval program = for {\n  _ &lt;- moveTo(Point(105.0, 148))\n  _ &lt;- twoFans\n  _ &lt;- moveBy(-baseLength)\n  _ &lt;- twoFans.flipped\n  result &lt;- getResult\n} yield result\n<\/code><\/pre>\n\n\n\n<p>Writing the individual parts of this as computations made them really easy to combine, and easy to think about. I think that if this had been written in an imperative style (mutating the <code>Canvas<\/code> as we go along), or using something like the <code>Try<\/code> or <code>Either<\/code> monad in a for-comprehension, it would have been quite complicated to make all the parts fit together nicely. As it is, because passing around the state is taken care of behind your back there&#8217;s much less clutter in the code, and it&#8217;s very easy to build up a complicated <code>Computation<\/code> out of smaller parts.<\/p>\n\n\n\n<p>The initial impetus for writing the computation library was when I was writing something to handle serializing arbitrary objects as <code>String<\/code>s through the use of the <a rel=\"noreferrer noopener\" href=\"https:\/\/en.wikipedia.org\/wiki\/Type_class\" target=\"_blank\">typeclass pattern<\/a>. I modeled the parsing of a <code>String<\/code> as a state containing the <code>String<\/code> being parsed, and the index of the character being processed; it was then possible to implement simple computations (e.g. &#8220;read a character&#8221;, &#8220;read a character that is expected to be a digit&#8221;) and build up via intermediate computations (&#8220;read an Int, then read a &#8216;|&#8217;, then read that many characters&#8221;) to complicated  things (&#8220;to read a <code>List[Foo]<\/code>, run the computation to read a <code>Foo<\/code> repeatedly until it fails&#8221;).<\/p>\n\n\n\n<p>I would certainly recommend the challenge of writing such a library; it&#8217;s not too difficult (the <code>Computation<\/code> and <code>ComputationResult<\/code> traits above might be a useful basis), and the mental exercise involved is stimulating. When you have something working, you can try adding additional combinators to <code>Computation<\/code> e.g <code>orElse<\/code> to try running the current computation falling back to an alternative if it fails. In use, you may find it helps to use type aliases (e.g. in my &#8220;star&#8221; project, I used <code>DrawComputation[T]<\/code> as an alias for <code>Computation[Canvas, T, DrawFailure]<\/code> and a <code>DrawComputation<\/code> object with an <code>apply<\/code> method for &#8220;bootstrapping&#8221; the low level computations e.g. <code>addLine<\/code>).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">&#8230;and how did the star turn out?<\/h2>\n\n\n\n<p>I was quite pleased with the end result. After fiddling with parameters, and figuring out how to generate the appropriate SVG (another long story&#8230;) I settled on the following net.<\/p>\n\n\n\n<div data-wp-interactive=\"core\/file\" class=\"wp-block-file\"><object data-wp-bind--hidden=\"!state.hasPdfPreview\" hidden class=\"wp-block-file__embed\" data=\"https:\/\/blog.67bricks.com\/wp-content\/uploads\/2024\/12\/star_net.pdf\" type=\"application\/pdf\" style=\"width:100%;height:200px\" aria-label=\"Embed of Embed of star_net..\"><\/object><a href=\"https:\/\/blog.67bricks.com\/wp-content\/uploads\/2024\/12\/star_net.pdf\">star_net<\/a><a href=\"https:\/\/blog.67bricks.com\/wp-content\/uploads\/2024\/12\/star_net.pdf\" class=\"wp-block-file__button\" download>Download<\/a><\/div>\n\n\n\n<p>Here are the nets cut out and partially scored:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"756\" height=\"1008\" src=\"https:\/\/blog.67bricks.com\/wp-content\/uploads\/2024\/12\/work_in_progress_star.jpg\" alt=\"Cut-out card nets\" class=\"wp-image-846\" srcset=\"https:\/\/blog.67bricks.com\/wp-content\/uploads\/2024\/12\/work_in_progress_star.jpg 756w, https:\/\/blog.67bricks.com\/wp-content\/uploads\/2024\/12\/work_in_progress_star-225x300.jpg 225w\" sizes=\"auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px\" \/><figcaption>Nets, and a snazzy tablecloth<\/figcaption><\/figure>\n\n\n\n<p>&#8230;and here the final star, after being sprayed gold and having its tips spread with glue and dipped in glitter.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"768\" height=\"768\" src=\"https:\/\/blog.67bricks.com\/wp-content\/uploads\/2024\/12\/finished_star.jpg\" alt=\"A glittery gold star\" class=\"wp-image-847\" srcset=\"https:\/\/blog.67bricks.com\/wp-content\/uploads\/2024\/12\/finished_star.jpg 768w, https:\/\/blog.67bricks.com\/wp-content\/uploads\/2024\/12\/finished_star-300x300.jpg 300w, https:\/\/blog.67bricks.com\/wp-content\/uploads\/2024\/12\/finished_star-150x150.jpg 150w\" sizes=\"auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px\" \/><figcaption>The finished product.<\/figcaption><\/figure>\n\n\n\n<p>Merry Christmas!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>When I was a boy, many years ago&#8230; &#8230;I used to like building polyhedron models out of card. Here is a photo of me, probably around 1987ish, spray-painting a compound of ten tetrahedra. Evidently the photographer had partially obscured the aperture with their finger, but there were no digital cameras back in those days, you &hellip; <a href=\"https:\/\/blog.67bricks.com\/?p=832\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Wishing upon a star&#8221;<\/span><\/a><\/p>\n","protected":false},"author":5,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[21],"tags":[100,99,98],"class_list":["post-832","post","type-post","status-publish","format-standard","hentry","category-scala","tag-christmas","tag-creative","tag-icosahedron"],"_links":{"self":[{"href":"https:\/\/blog.67bricks.com\/index.php?rest_route=\/wp\/v2\/posts\/832","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.67bricks.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.67bricks.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.67bricks.com\/index.php?rest_route=\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.67bricks.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=832"}],"version-history":[{"count":14,"href":"https:\/\/blog.67bricks.com\/index.php?rest_route=\/wp\/v2\/posts\/832\/revisions"}],"predecessor-version":[{"id":860,"href":"https:\/\/blog.67bricks.com\/index.php?rest_route=\/wp\/v2\/posts\/832\/revisions\/860"}],"wp:attachment":[{"href":"https:\/\/blog.67bricks.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=832"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.67bricks.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=832"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.67bricks.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=832"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}