<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[matt brandly]]></title><description><![CDATA[ ]]></description><link>https://mattbrandly.com/</link><image><url>https://mattbrandly.com/favicon.png</url><title>matt brandly</title><link>https://mattbrandly.com/</link></image><generator>Ghost 3.0</generator><lastBuildDate>Wed, 04 Mar 2026 16:22:10 GMT</lastBuildDate><atom:link href="https://mattbrandly.com/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Project Euler Level 2]]></title><description><![CDATA[<p><a href="https://projecteuler.net/about">Project Euler</a> is a site with a long list of problems to solve. The problems usually focus on some mathematical idea. Most people use a programming language to solve them, but some try with just a pencil and paper.</p><p>When I first fell in love with programming, I didn't know</p>]]></description><link>https://mattbrandly.com/project-euler-level-2/</link><guid isPermaLink="false">60ce133de80c700705023ffc</guid><dc:creator><![CDATA[Matthew Brandly]]></dc:creator><pubDate>Sun, 20 Jun 2021 20:32:56 GMT</pubDate><content:encoded><![CDATA[<p><a href="https://projecteuler.net/about">Project Euler</a> is a site with a long list of problems to solve. The problems usually focus on some mathematical idea. Most people use a programming language to solve them, but some try with just a pencil and paper.</p><p>When I first fell in love with programming, I didn't know what to do with it, so I started trying to solve these problems. All I knew was a little C++, so I used that until a friend introduced me to Python. I also had no sense of runtime complexity, so it was surprising when my code would seemingly just hang instead of producing an answer.</p><p>My limited skills allowed me to solve some problems, and the fake internet points felt rewarding. The site also let me know that I had much left to learn since the list of problems was long and mostly unapproachable.</p><p>More recently, I returned to the site and was able to solve another ~20 problems in JavaScript without too much effort. Years ago, those problems probably felt out of reach. Of course <em>I know</em> I've gotten more capable since those early days, but it was nice to really <em>feel it</em>.</p><!--kg-card-begin: markdown--><p><img src="https://projecteuler.net/profile/brandly.png" alt="brandly on Project Euler"></p>
<!--kg-card-end: markdown--><p>Solving 50 problems advanced me to Level 2! As of this moment, I've solved 52 problems which puts me in the 95th percentile of all registered users who've solved at least one problem. If you're logged in, you can <a href="https://projecteuler.net/problem_analysis">view those stats here</a>.</p><p>Some people use these kinds of problems to explore a new language, but my recent solutions were written in JavaScript, a language I know well. Even then, <code>BigInt</code>s aren't very familiar to me, but I needed them occasionally in this context. But for most problems up to this point, basic floating-point numbers and data structures like objects, arrays, and sets are enough to get the job done.</p><p>These solutions should only take a moment to run through some combination of mathematical insight and using the right data structures, but I wrote one solution that took ~10 minutes to run. When that problem was written in 2007, the brute force solution would've been further out of reach, but now I can just grind out an answer in JS on a laptop.</p><p>Each problem has a difficulty rating. I'm not sure how they're calculated, but most of the problems I've solved have the lowest difficulty rating of 5%. The hardest one of I've solved is titled <a href="https://projecteuler.net/problem=96">Su Doku</a> and has a difficulty of 25%. I wrote <a href="https://github.com/brandly/js-sudoku">a sudoku solver</a> a while back, so all that was left for my solution was some basic glue code.</p><p>If you also like solving little puzzles, give Project Euler a try. <a href="http://rosalind.info/problems/list-view/">Rosalind</a> is another list of problems focused on bioinformatics, and <a href="https://adventofcode.com/">Advent of Code</a> is a nice, seasonal one. They're all pretty fun and might expose you to some new ideas.</p>]]></content:encoded></item><item><title><![CDATA[Lax Reaches 100 Stars]]></title><description><![CDATA[<p><a href="https://github.com/brandly/Lax">Lax</a> is an IRC client built with React and Electron. Shortly after its 6th birthday, it received its 100th star on GitHub. It's not a huge milestone, but it's a good excuse to write about the project.</p><p>Back in 2015, I discovered React and was looking for a project to</p>]]></description><link>https://mattbrandly.com/lax-reaches-100-stars/</link><guid isPermaLink="false">608599cee80c700705023eda</guid><dc:creator><![CDATA[Matthew Brandly]]></dc:creator><pubDate>Sun, 25 Apr 2021 19:38:23 GMT</pubDate><content:encoded><![CDATA[<p><a href="https://github.com/brandly/Lax">Lax</a> is an IRC client built with React and Electron. Shortly after its 6th birthday, it received its 100th star on GitHub. It's not a huge milestone, but it's a good excuse to write about the project.</p><p>Back in 2015, I discovered React and was looking for a project to stretch my understanding. Around that time, I downloaded a few IRC clients and didn't like any of them. This seemed like an opportunity to explore some new technologies while creating something I'd like to use.</p><p>The <a href="https://github.com/brandly/Lax/commit/1c0b4c6145784d60761238bccfc3607af4a292e3">first commit</a> shows its humble beginnings. It only handles a single IRC connection. The styles are in a single CSS file. It uses <code>node-webkit</code> instead of <code>electron</code> and <code>flux</code> instead of <code>redux</code>. It looks like, even with <code>babel</code>, I was calling <code>React.createClass</code> instead of defining JS classes. It was a different world back then.</p><p>Here's the earliest pic I could find.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://mattbrandly.com/content/images/2021/04/5bc7fa34-2154-11e6-8b27-a861e80dd2fd.png" class="kg-image"><figcaption>May 24, 2016 - A year into the project</figcaption></figure><p>I don't work on Lax with any consistency. Occasionally, I get inspired to add features or update the tech under the hood. For example, I started toying with Elm in 2017. I had written a lot of code using Redux, but using Elm's type system allowed me to <em>really</em> understand Redux. Later that year, I <a href="https://github.com/brandly/Lax/pull/3">overhauled the entire project</a> introducing Redux, testing reducers with Jest, and using <a href="https://flow.org/">Flow's</a> type system. That pull request laid the foundation to handle multiple connections, which were <a href="https://github.com/brandly/Lax/pull/23">introduced a few months later</a>.</p><p>That work is all generally still in place today. Here's a screenshot at that time.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://mattbrandly.com/content/images/2021/04/36403462-01aac900-15b3-11e8-801b-e2b61b966a83.png" class="kg-image"><figcaption>Feb 19th, 2018</figcaption></figure><p>Around that time, more people started to pay attention to the project. These technologies are all buzzwords, so the traffic came naturally from Google searches. I started receiving issues and pull requests from other people, and one guy <a href="https://github.com/brandly/Lax/pull/44">added dark mode</a>. These moments felt motivating.</p><p>But overall, the repo serves more as a learning environment than anything, and the app itself suffers as a result. Longstanding issues, like <a href="https://github.com/brandly/Lax/issues/7">recovering from network disconnection</a>, stay open. The build system could use <a href="https://github.com/brandly/Lax/issues/101">another overhaul</a> – some shortcomings seen in that first commit are still in the app today. While much could be improved, I usually find myself chatting on Slack and Discord instead.</p><p>The future of Lax is uncertain! I'm intrigued by <a href="https://github.com/tauri-apps/tauri">Tauri</a>, but <a href="https://github.com/brandly/Lax/issues/101">this issue</a> lays out a plan that involves more stable technologies. <a href="https://github.com/brandly/Lax/issues">Open issues</a> include some bugs and many new features. If you're interested in any of this or have thoughts to share, write <a href="https://github.com/brandly/Lax/issues/new">a new issue</a>, and I'll be sure to respond. And please, give <a href="https://github.com/brandly/Lax">the repo</a> a star – it would sure be embarrassing if it fell below 100!</p>]]></content:encoded></item><item><title><![CDATA[Rap Lyrics and GPT-3]]></title><description><![CDATA[<p>We're increasingly surrounded by AI, from Siri who understands our voices to Facebook who automatically recognizes our friends' faces in photos. These systems are trained on an enormous amount of data and perform incredibly well on a single, focused task.</p><p>Recent research from <a href="https://openai.com/\">OpenAI</a> has created a system called GPT-3</p>]]></description><link>https://mattbrandly.com/rap-lyrics-and-gpt-3/</link><guid isPermaLink="false">5f2ad879e80c7007050238ef</guid><dc:creator><![CDATA[Matthew Brandly]]></dc:creator><pubDate>Thu, 13 Aug 2020 19:34:55 GMT</pubDate><content:encoded><![CDATA[<p>We're increasingly surrounded by AI, from Siri who understands our voices to Facebook who automatically recognizes our friends' faces in photos. These systems are trained on an enormous amount of data and perform incredibly well on a single, focused task.</p><p>Recent research from <a href="https://openai.com/\">OpenAI</a> has created a system called GPT-3 that has "learned to learn" tasks related to human language. While it <em>was</em> trained on a ton of data, it wasn't trained for a focused task. Instead, you provide a short description in English of what you would like it to do, or maybe just a few examples, and it immediately performs well on a range of tasks like <a href="https://twitter.com/michaeltefula/status/1285505897108832257">simplifying legal documents</a> and <a href="https://twitter.com/QasimMunye/status/1288912561178640385">writing short stories</a>.</p><p>Let's show it some rap lyrics and see if it's able to explain them in more detail.</p><h2 id="genius">Genius</h2><p><a href="https://genius.com/">Genius</a> provides song lyrics, and users provide annotations to those lyrics in a Wikipedia-like fashion. The site was <a href="https://techcrunch.com/2015/04/08/annotate-this/">originally focused on rap lyrics</a>, so we'll stick to those.</p><p>To start, I took <a href="https://genius.com/Drake-the-motto-lyrics">a Drake song</a> and grabbed a couple lines that already had good annotations. GPT-3 is given a short description of what's expected and a single example, with both the song lyric and the human-written annotation from Genius. It's then given another lyric, and hopefully it writes a description of that lyric.</p><blockquote><strong>The following is a conversation with an AI assistant, Genius. The assistant is insightful, clever, and a hip-hop head.</strong></blockquote><blockquote><strong>Drake: Tell Uncle Luke I'm out in Miami, too<br>Genius: Southern rap pioneer, former 2 Live Crew impresario and former Miami mayoral candidate Luther “Luke” Campbell recently put a few hip-hop personalities on blast for living in Miami while not giving back to the community. If they don’t change their ways by January 2012, Luke threatens to have their “Miami cards” revoked. Luke lost the election. The open letter mentions “Lil Wayne, DJ Khaled, Puff Daddy, and all their boys” – Drake apparently feels like he was worthy of inclusion by name as well.</strong></blockquote><blockquote><strong>Drake: Wrist bling, got a condo up in Biscayne<br>Genius:</strong></blockquote><p>GPT-3 is given the above text, and in a matter of seconds, it writes the following:</p><blockquote>Drizzy has been co-owner of WAM, a Miami/Boca Raton development, since 2007. The downtown Brickell building is only 20 stories tall, with condos in the $700,000 to $1.2 million range. In January 2011, Drake purchased another condo in Miami’s Biscayne Boulevard. A “condo” is a type of building in which ownership shares in the structure provide access to an exclusive environment; as opposed to an apartment or single-family residence.</blockquote><p>Incredible! It referred to Drake by a nickname, gave us some financial figures, and even defined "condo." You can compare it to the <a href="https://genius.com/425975">best annotation on Genius for that line</a>.</p><p>Now, these lyrics are both by Drake, in the same song, and only a few lines apart. I really didn't know where Biscayne was located, but it likely benefits from the original line talking about Miami. We could give it more difficult examples to work with, but even these initial results should make you pause for a moment.</p><p>If you saw these sentences out of context, you would assume they were written by a human. Moreover you would have no reason to doubt what they said, but searching around the internet, I can't find anything tied to Drake called "WAM." While the sentences are well-formed and in a natural order, it lied to us right out of the gate!</p><p>To show it more variety, let's give it a classic example by one artist and see how it handles another artist. The text provided to GPT-3 is <strong>bold</strong>, including a two sentence description, a human-annotated lyric, and a second lyric on its own. GPT-3's output immediately follows.</p><blockquote><strong>The following is a conversation with an AI assistant, Genius. The assistant is insightful, clever, and a hip-hop head.</strong></blockquote><blockquote><strong>Lil Wayne: Bitch, real Gs move in silence like lasagna</strong><br><strong>Genius: When you pronounce “lasagna,” the G is silent (although it wouldn’t have the “yuh” sound at the end if the G wasn’t there). Real gangsters (Gs) move in silence too, i.e. they keep their hustles on the low.</strong><br><br><strong>Kanye: Mayonnaise colored Benz, I push Miracle Whips</strong><br><strong>Genius:</strong> “Miracle Whip” is a brand of mayonnaise. A Maybach is a Mercedes Benz. When mayonnaise comes out the top of the bottle it looks kind of white, like Miracle Whip. But I don’t think that’s what Kanye is talking about here. Instead, he’s referring to a custom paint job called “liquid white” (a.k.a. “mayonnaise white”).</blockquote><p>This isn't quite <a href="https://genius.com/32273">what a human would write</a>. I tried this one a few times, and it consistently seems focused on a Maybach for some reason. It doesn't seem to understand that "whip" refers to a nice car either. GPT-3 recognizes the basics of these lyrics, while the wordplay that ties the two lines together slips right past it.</p><p>Again, the <strong>bold</strong> text above is all it has to work with. It doesn't know I'm writing a blog post and has completely forgotten about the earlier Drake lyrics. I think it's interesting to compare the example its given and note how it mimicked the generous use of quotes and parentheses. In many ways, it does a great job of learning by example, but in other ways it misses the forest for the trees.</p><p>Let's try some more wordplay. In 2011, long before Childish Gambino was making <a href="https://www.youtube.com/watch?v=ezbsbkqoRrs">soul/funk/psychedelia</a>, he put out an album called Camp that's littered with puns. Here are some lines from <a href="https://genius.com/Childish-gambino-bonfire-lyrics">Bonfire</a>.</p><blockquote><strong>The following is a conversation with an AI assistant, Genius. The assistant is insightful, clever, and a hip-hop head.</strong><br><br><strong>Childish Gambino: Okay, it's Childish Gambino, homegirl drop it like the NASDAQ</strong><br><strong>AI: As of the song’s release, the NASDAQ (the electronic market, mainly for tech stocks) was dropping. Childish Gambino’s girl drops her ass low much like the NASDAQ drops (or has dropped). Of course, now that the tech sector is so frothy, this line has little resonance (too late, CG!).</strong><br><br><strong>Childish Gambino: In Adidas, with some short shorts, B-O-O all over me</strong><br><strong>AI: Childish has long lauded his affinity for Rod Lavers and often wears shorts of <em>vintage</em> nature whose hemline is way above the knees. B-O-O stands for Band of Outsiders, a male clothing line that makes ties. Boo is also a pet name for a woman, so the line is a double entendre.</strong><br><br><strong>Childish Gambino: My dick is like an accent mark, it's all about the over E's</strong><br><strong>AI:</strong> An accent mark, called a tilde, has the shape of an "n" with a bar over it. The line, then, is about Childish Gambino's dick, which means it’s a double entendre. The "n" stands for his penis and the bar represents the female pubic region. E’s stands for ecstasy. The line is a nod to rap group Bone Thugs-N-Harmony. They began rapping about their “Accent Marks” and celebrating excess in the 1995 song "East 1999 Eternal". This is also a reference to "The Whiteness Project," a series of videos produced by Complex Magazine on white privilege.</blockquote><p>I'll give it some creativity points for this one. While it definitely <a href="https://genius.com/296121">missed the mark</a>, it "wants" to find the double entendre. "[T]he bar represents the female pubic region" is accurate, but it doesn't grasp the "ovaries" homophone.</p><p>I also did some experiments with rhyming, to see if I could give it a leading line and it would complete the bar. The results weren't very exciting so I left them out of this post. Any wordplay involving how the word sounds, rather than the text itself, seems out of GPT-3's reach.</p><p>Finally, let's look at some well known Kanye lines. This time, it has a few examples to work with no but no leading description of what's expected.</p><blockquote><strong>Kanye: The plan was to drink until the pain over. But what's worse, the pain or the hangover?</strong><br><strong>Genius: Ye tries to block out the problems with drinking, but realizes delaying them will only make it worse. This is one of the most oft-asked questions of an addict when they reach the point of rock bottom. What causes them more physical and mental anguish? Continuing their addiction and dealing with the consequences, or dealing with the actual issues at hand without the use of a masking agent? This could be a double entendre in the line “The plan was to drink until the pain over”. This could be interpreted as pain being short for champagne, meaning he would drink until the champagne was gone.</strong><br><br><strong>Kanye: What you think I rap for, to push a fuckin' Rav 4?</strong><br><strong>Genius: He raps to ball hard, not to drive some shitty Toyota SUV. This line was inspired by a guy who was working on Kanye’s album in Hawaii who also drove Kanye around Hawaii in a Rav 4.</strong><br><br><strong>Kanye: Couldn't afford a car, so she named her daughter Alexis</strong><br><strong>Genius: She named her daughter “Alexis” so that she could still claim to own “a Lexus,” showing her materialistic desires outwinning her maternal love. In the seventh song of the album, “Jesus Walks” Kanye also talks about people stealing a Lexus. Saying she couldn’t ‘afford’ a car could be a reference to ‘a Ford,’ which is another popular car brand.</strong><br><br><strong>Kanye: "Oh my god, is that a black card?" I turned around and replied, "Why yes But I prefer the term African American Express"</strong><br><strong>Genius:</strong> Kanye compares himself to a Black Card, a type of American Express credit card given exclusively to people in the entertainment industry, but he calls it the "African American Express" instead to say that although he's rich, he still considers himself black and knows the history of blacks in this country.</blockquote><p>It does <em>okay</em> on <a href="https://genius.com/30976">this one</a>. These lines are all Kanye but from various songs and albums. Rap verses often focus on some theme(s), so with more of the song's surrounding lines, it could infer more from the given context.</p><h2 id="looking-forward">Looking Forward</h2><p>OpenAI is a company based in San Francisco, California, whose <a href="https://openai.com/charter/">mission</a> is to create Artificial General Intelligence (AGI) in a safe manner that benefits everyone. You've likely heard of AI, since even rapper <a href="https://youtu.be/9tucY7Jhhs4">Common is preaching about how AI empowers us</a>, but the term AGI refers to something on par with human intelligence, as opposed to current AI software that only does <em>one thing</em> really well.</p><p>For example, the best <a href="https://www.theguardian.com/technology/2017/dec/07/alphazero-google-deepmind-ai-beats-champion-program-teaching-itself-to-play-four-hours">chess</a>, <a href="https://www.theverge.com/2019/11/27/20985260/ai-go-alphago-lee-se-dol-retired-deepmind-defeat">Go</a>, and <a href="https://www.theverge.com/2019/10/30/20939147/deepmind-google-alphastar-starcraft-2-research-grandmaster-level">StarCraft</a> players have all been beaten by AI. Rather than studying the masters and learning from their games, the AI is trained on many of years of gameplay in a short amount of time, allowing it to discover ever more powerful strategies on its own. Since the "training data" is generated on the fly while playing, there's essentially unlimited data to work with, and AI will continue to dominate more and more arenas where that holds true.</p><p>OpenAI's results on GPT-3 are astounding, not only because it can learn from a few examples but because it shows no signs of slowing down. It's estimated <a href="https://lambdalabs.com/blog/demystifying-gpt-3/">around $5 million</a> was spent on <em>just computing power</em> to train this thing. While such an expense is outside of my budget, a tech giant like <a href="https://ycharts.com/companies/GOOG/r_and_d_expense">Google spends over $2 <em>billion</em> on research and development <em>every month</em></a><em>.</em> They have likely already created more impressive technology behind closed doors.</p><h2 id="conclusion">Conclusion</h2><p>GPT-3 generally writes sentences that make sense, although it doesn't always understand the true intent of the lyrics. It seems to be excellent at pulling in "facts" about the world that might be relevant, but it appears to struggle with wordplay.</p><p>Again the technological advance here is that the model was built for general language purposes and only applied to rap lyrics after the fact. OpenAI is sharing this with people to discover the full <a href="https://twitter.com/search?q=GPT-3">variety of tasks</a> it can accomplish. On <a href="https://arr.am/2020/07/09/gpt-3-an-ai-thats-eerily-good-at-writing-almost-anything/">some writing tasks</a>, it performs better than others. Some of its output is pretty indistinguishable from something written by a human, which is concerning when the Web is already overrun with clickbait and fake news. For a look at some poetry and a more in-depth analysis, check out <a href="https://www.gwern.net/GPT-3">Gwern's post on the topic</a>.</p><p>I hope you found this enjoyable! <a href="mailto:matt@brandly.me">Send me an email</a> if you have any thoughts or would like me to try some other examples. I would love to automate the process and let people freely explore lyrics, but the <a href="https://docs.genius.com/">Genius API</a> doesn't appear to supply lyrics or annotations. Maybe someone at Genius will see this and can give me greater access!</p>]]></content:encoded></item><item><title><![CDATA[MIT Press Open Access]]></title><description><![CDATA[<p>The MIT Press offers open access to <a href="https://mitpress.mit.edu/mit-press-open">some of their books</a>, allowing anyone to read them for free. Although I knew about OpenCourseWare and that books like <a href="https://mitpress.mit.edu/sites/default/files/sicp/index.html">SICP</a> were freely available, I wasn't aware of just how much they offer.</p><p>The fact that a book is freely available might not</p>]]></description><link>https://mattbrandly.com/mit-press-open-access/</link><guid isPermaLink="false">5f126267e80c70070502386a</guid><dc:creator><![CDATA[Matthew Brandly]]></dc:creator><pubDate>Sat, 18 Jul 2020 03:18:11 GMT</pubDate><content:encoded><![CDATA[<p>The MIT Press offers open access to <a href="https://mitpress.mit.edu/mit-press-open">some of their books</a>, allowing anyone to read them for free. Although I knew about OpenCourseWare and that books like <a href="https://mitpress.mit.edu/sites/default/files/sicp/index.html">SICP</a> were freely available, I wasn't aware of just how much they offer.</p><p>The fact that a book is freely available might not be immediately apparent. In his post on software safety, <a href="https://www.hillelwayne.com/post/stamping-on-eventstream/#conclusions">Hillel Wayne</a> mentions <a href="https://mitpress.mit.edu/books/engineering-safer-world">a book</a> and says, "In the lower-left sidebar there’s an option to download the book for free. Most people miss that." Even seeing this message, it took a minute to find the download link – it's now behind the <em>Open Access</em> tab.</p><p>Some books are available as a single PDF which I prefer over the others that are often a collection of PDFs or HTML files. It takes a couple clicks to see if the book is a big PDF, and then the back button would take me all the way back to the first page.</p><p>Publishing these books for free is a tremendously generous act, but I was slightly frustrated by the website. I gathered all the direct links on a single page for quick browsing. Check out <a href="https://github.com/brandly/mit-press-open-access#readme"><strong>all the open access books from MIT Press</strong></a>.</p>]]></content:encoded></item><item><title><![CDATA[Visualizing Every Elm Package]]></title><description><![CDATA[<p>Recently, I came across <a href="http://anvaka.github.io/pm/">Code Galaxies</a>, a website that visualizes several popular package managers. Every published package is displayed as an orb in 3D space with lines connecting the packages to their dependencies. Arrow keys are used to fly around the packages, similar to flying a spaceship in a video</p>]]></description><link>https://mattbrandly.com/every-elm-package/</link><guid isPermaLink="false">5e4ddb54e80c700705022d47</guid><dc:creator><![CDATA[Matthew Brandly]]></dc:creator><pubDate>Tue, 07 Apr 2020 14:38:56 GMT</pubDate><content:encoded><![CDATA[<p>Recently, I came across <a href="http://anvaka.github.io/pm/">Code Galaxies</a>, a website that visualizes several popular package managers. Every published package is displayed as an orb in 3D space with lines connecting the packages to their dependencies. Arrow keys are used to fly around the packages, similar to flying a spaceship in a video game. Great idea!</p><p>Each of these orbs is a package that someone took the time write and publish. Zooming out such that all packages are within view reveals a unique shape for each package manager, reflecting the shape of the community.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://mattbrandly.com/content/images/2020/04/Screen-Shot-2020-04-05-at-4.16.23-PM-1.png" class="kg-image"></figure><p>Take a look at <a href="http://anvaka.github.io/pm/#/galaxy/bower">Bower</a>, which aims to be "a package manager for the web." Having such a broad, inclusive goal, you'll see all kinds of variety in the packages, and you'll quickly find distinct communities around jQuery and AngularJS. You might also find smaller communities like Polymer and PureScript, disconnected from the broader community and hurtling off into space. </p><p>Elm is a small community with its own package manager. It aims to be "a delightful language for reliable webapps." That reliability comes from static types, which are also used by the language's tooling to enforce a great deal of homogeneity, in addition to their <a href="https://package.elm-lang.org/help/design-guidelines">Design Guidelines</a> which are "meant to promote consistency and quality across all Elm packages." We should expect something far more uniform than Bower.</p><p>In this post, I'll walk through the key steps in adding Elm's packages to Code Galaxies which include scraping the necessary package data, building the dependency graph, and positioning these packages in 3D space. </p><p>tl;dr: <a href="http://anvaka.github.io/pm/#/galaxy/elm">Explore all of Elm's packages</a>.</p><h2 id="crawling-packages">Crawling Packages</h2><p>Elm has an official package manager that is primarily used with commands like <code>elm install</code> and <code>elm publish</code>. <a href="https://package.elm-lang.org/">Elm Packages</a> also provides access to these packages and their documentation. </p><p>All packages are published with a JSON file describing the package and listing its <code>dependencies</code>. Prior to <code>v0.19</code>, this file was named <code>elm-package.json</code>, but now, every package is published with an <code>elm.json</code>. Here's an example of an <code>elm.json</code> file.</p><pre><code class="language-json">{
    "type": "package",
    "name": "brandly/elm-dot-lang",
    "summary": "Parse DOT Language files",
    "license": "BSD-3-Clause",
    "version": "1.1.3",
    "exposed-modules": [
        "DotLang"
    ],
    "elm-version": "0.19.0 &lt;= v &lt; 0.20.0",
    "dependencies": {
        "elm/core": "1.0.0 &lt;= v &lt; 2.0.0",
        "elm/parser": "1.0.0 &lt;= v &lt; 2.0.0",
        "hecrj/html-parser": "2.3.0 &lt;= v &lt; 3.0.0"
    },
    "test-dependencies": {
        "elm-explorations/test": "1.2.1 &lt;= v &lt; 2.0.0"
    }
}</code></pre><p>Each dependency is listed with a range of supported versions <sup><a href="#foot-semver">[1]</a></sup>. Each package range can be resolved to a specific package version, and those packages have their own dependencies, forming a sprawling graph. Acquiring the <code>elm.json</code> or <code>elm-package.json</code> file from each and every package would provide full knowledge of this dependency graph.</p><p>The Elm Package website is <a href="https://github.com/elm/package.elm-lang.org">open-source</a>, and its server provides an API that responds with JSON. The <code><a href="https://package.elm-lang.org/all-packages">/all-packages</a></code> endpoint delivers details about the package registry including package names and published versions. In addition, adding <code>?elm-package-version=0.18</code> to the request retrieves packages for older versions of Elm. Finding unique package names in both lists results in a combined total of 2,123 packages.</p><p>The API responses are structured differently, but they both provide package names and a list of available version numbers for each package. To boost the size of the graph, every <em>major</em> version release of each package will be included in the final graph, and every node will be connected to a compatible version of each of its dependencies.</p><p><a href="https://developer.github.com/v3/repos/contents/#get-contents">GitHub's API</a> is used to download an <code>elm.json</code> file for a given package <code>name</code> and <code>version</code>. This works because every Elm package is first tagged and pushed to GitHub before getting added to the package manager.</p><pre><code class="language-js">const getFileAtVersion = async (repo, filename, version) =&gt; {
  const url = `https://api.github.com/repos/${repo}/contents/${filename}?ref=${version}&amp;access_token=${token}`
  const res = await axios.get(url)
  return Buffer.from(res.data.content, 'base64').toString('utf-8')
}

const repo = 'brandly/elm-dot-lang'
const version = '1.1.3'
const elmJson = await getFileAtVersion(repo, 'elm.json', version)

// If it were an older package...
const elmPackageJson = await getFileAtVersion(repo, 'elm-package.json', version)</code></pre><p>Every package, its major versions, and each of their package definitions are now within reach. The <a href="https://github.com/brandly/allelm/blob/master/index.js">rest of the logic</a> is the orchestration of these requests to download the files into <code>./packages</code>, resulting in an organized tree.</p><pre><code class="language-shell">$ tree packages 
packages
├── 0ui
│   └── elm-task-parallel@1.0.1.json
├── 1602
│   ├── elm-feather@1.0.2.json
│   ├── elm-feather@2.3.5.json
...
└── zwilias
    ├── elm-avl-dict-exploration@1.2.2.json
    ├── elm-bytes-parser@1.0.0.json
    ...
    ├── json-decode-exploration@6.0.0.json
    └── json-encode-exploration@1.0.0.json

814 directories, 3875 files</code></pre><p>Due to how these files are laid out, those numbers at the bottom indicate that 814 unique accounts have published 3,875 major package releases.</p><h2 id="connecting-the-dots">Connecting the Dots</h2><p>Code Galaxies is built on top of <code>ngraph</code>, a suite of graph-related tools. These tools help build a pipeline of sorts, taking the downloaded packages and transforming them into the format the app expects.</p><p>With the downloaded JSON files, each file represents a node in the graph and contains a list of dependencies, linking the node to some number of other nodes. This information needs to be plugged into <code>ngraph</code>. I'll highlight the interesting bits. </p><p>First, the list of files is piped into a script.</p><pre><code class="language-shell">$ find ./packages -name '*.json' | node build-graph.js</code></pre><p><code>find</code> spits out a list of filenames, each on their own line. This list is consumed by the script, and the lines are chopped up into an array of file paths.</p><pre><code class="language-js">const fs = require('fs')

const filePaths = fs
  .readFileSync(0)
  .toString()
  .trim()
  .split('\n')</code></pre><p>These files are read into memory and looped over, building up the graph data structure.</p><pre><code class="language-js">const createGraph = require('ngraph.graph')
const graph = createGraph()

// For each package
const node = `${package.name}@${package.version}`
graph.addNode(node)

// For each dependency in a package
graph.addLink(node, dependency)</code></pre><p>At this point, <code>graph</code> holds the connections between all available Elm packages! </p><h2 id="moving-in">Moving In</h2><p>In the app, each node sits somewhere in space. These locations are <a href="https://en.wikipedia.org/wiki/Force-directed_graph_drawing">calculated</a> by simulating a physical system, with a force pushing nodes away from one another, like reverse gravity, while the links in the graph tie dependent nodes together. The outcome is that packages with common dependencies end up near one another.</p><p>The app isn't a live simulation however. The positions are calculated upfront, and these fixed values are used in the app. Calculating these positions is once again made simple with <code>ngraph</code>.</p><pre><code class="language-js">const layout = require('ngraph.offline.layout')(graph)
layout.run()

const save = require('ngraph.tobinary')
save(graph, {
  outDir: './data'
})</code></pre><p>This writes a variety of files to <code>./data</code> describing every detail about the graph, but the app only cares about a few of them: <code>labels.json</code>, <code>links.json</code>, and <code>positions.json</code>. Feeding these files into Code Galaxies reveals the relationship between <a href="http://anvaka.github.io/pm/#/galaxy/elm">every published Elm package</a>. (On mobile, hold two fingers to zoom out.)</p><!--kg-card-begin: html--><iframe src="https://anvaka.github.io/pm/#/galaxy/elm"></iframe>
<!--kg-card-end: html--><p>What a view! Every Elm package depends on <code>elm/core</code> (formerly <code>elm-lang/core</code>) which forms the backbone of this structure. The core has been updated as the language has evolved creating a series of clustered packages like moments on a timeline. Some rare packages are tied to multiple versions of this core chaining the clusters together. Each cluster is bigger than the last as the Elm community continues to grow!</p><p>Within a cluster, the <code>core</code> is the dominant node alongside other sizable nodes like <code>elm/html</code>, <code>elm/json</code>, and <code>elm/browser</code>. These general packages dwarf the size of most other packages. Due to Elm's focus on building web apps, this is no surprise.</p><p>Elm strives for consistency in everything from <a href="https://package.elm-lang.org/help/design-guidelines">API design</a> to <a href="https://package.elm-lang.org/help/documentation-format">documentation formatting</a>, encouraging package authors to publish general, stable solutions for well-defined problems. As a result, packages don't often "compete" with one another, and the community doesn't fracture easily. This, combined with the common core package, results in the latest cluster forming a fairly uniform ball.</p><h2 id="conclusion">Conclusion</h2><p>The Elm Package API provides a complete list of packages, and the mapping between an Elm package and a GitHub repo supplies the necessary JSON package definitions. The data is large enough to show something interesting, but still small enough that it can be explored with some <code>for</code> loops. <code>ngraph</code> handles all the graph-related details.</p><p>The resulting visualization looks great and is fun to explore! The structure reflects the history of major Elm updates and the growing community around it. The other package managers likely tell their own stories as this is a great way to explore graphs that should be applied to other datasets.</p><p>Take a look for yourself, and let me know if you find anything interesting!</p><p><em>Special thanks to <a href="https://github.com/anvaka">Andrei Kashcha</a> for creating <code><a href="https://github.com/anvaka/ngraph">ngraph</a></code> and <a href="https://github.com/anvaka/pm">Code Galaxies</a>.</em></p><p><em>View the <a href="https://github.com/brandly/allelm">full source code</a> and the <a href="http://anvaka.github.io/pm/#/galaxy/elm">resulting visualization</a> featured in this post.</em></p><hr><h3 id="notes">Notes</h3><!--kg-card-begin: markdown--><div id="foot-semver"><p>
    <strong>1.</strong> Elm follows <a href="https://semver.org/">SemVer</a> where new functionality can be added in a minor version but any breaking change requires a new major version. As a result, these ranges tend begin at a minor version and end before the next major version. Elm's tooling can guarantee that packages follow SemVer (to some degree) since the exposed interface is statically typed.
</p></div><!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Pillars of Programming]]></title><description><![CDATA[<p>I've been helping <a href="http://josephostrow.com/">a friend</a> learn some things about programming recently, which has reminded me of all the hurdles you need to get over to get a simple program to run. Repeatedly, he'll run into trouble and, although the solution is apparent to me, he'll be unaware of the full</p>]]></description><link>https://mattbrandly.com/pillars-of-programming/</link><guid isPermaLink="false">5db1f67ce80c7007050229cc</guid><dc:creator><![CDATA[Matthew Brandly]]></dc:creator><pubDate>Sat, 03 Oct 2015 16:10:00 GMT</pubDate><content:encoded><![CDATA[<p>I've been helping <a href="http://josephostrow.com/">a friend</a> learn some things about programming recently, which has reminded me of all the hurdles you need to get over to get a simple program to run. Repeatedly, he'll run into trouble and, although the solution is apparent to me, he'll be unaware of the full toolbox that's available to him.</p><p>When a new programmer is getting started, they don't have the bearings they need to know where to search for answers. When someone shows them a solution, it's hard for them to hold on to the answer, since they haven't built a framework in their mind for thinking about programming.</p><p>Programming knowledge seems to fall into a few categories. I think recognizing these categories early on helps a young programmer organize the things they're learning.</p><h2 id="learn-syntax">Learn Syntax</h2><p>This is probably how someone who doesn't write code views programming. You learn what these symbols mean. You type them in bright colors on your computer. You're a programmer.</p><p>Learning systems, like <a href="https://www.codecademy.com/">Codecademy</a>, seem to handle this step of the learning process well. They demystify some syntax and show you relatively simple examples, but they don't quite give you enough to allow you to go independently start writing software. I've seen several people go through long stretches of learning like this, but they still feel lost.</p><p>However, these systems are still very valuable. The more comfortable one can become at looking at a block of code and understanding what the syntax means, the closer they are to writing software. For this reason, I think beginners should start with just one language and learn as much about that language as possible, instead of gaining cursory knowledge of a list of languages.</p><p>For an experienced software developer, the raw syntax, in a language they're fluent in, is something that's rarely even thought about. The same way one's able to read a book and see the fantasy world the author's describing, a well-written program should, when read by a fluent developer, create rich imagery in the reader's mind. What they're imagining is nothing like syntax, but it's an abstract view of how data is flowing through the program, which brings me to the next topic of learning.</p><h2 id="learn-how-data-flows">Learn How Data Flows</h2><p>All software programs take some input data, manipulate it, and output some result. Input data may come from a file, a web server, or direct user input. Similarly, the output may be written to a file, sent to a server, or simply displayed in front of the user.</p><p>For a simple software program, these three steps will be small and simple, e.g. read data from a file, combine some values, and output the combined values to the user. As a software developer learns more, they'll be able to handle data from multiple locations, perform complex manipulations, and output multiple results to multiple locations.</p><p>The main role of a software developer is to leverage the syntax of their language of choice to manage the vast complexity of the software they write. This is the hardest part of programming and something that programmers continue to learn, no matter how many years they've spent programming.</p><p>Certain languages and tools are more fit for certain kinds of manipulations. For a beginner, they need to first learn one language well, so they can discover what it's good for, before branching out and discovering new tools.</p><p>Nowadays, programmers don't fly solo. No matter what language they're using, they're standing on the shoulders of the giants before them who built these languages and designed these toolsets.</p><h2 id="learn-the-context">Learn the Context</h2><p>The software one writes executes against some compiler or interpreter. Usually, this execution context provides information about the computer the code is running on, access to the filesystem, access to the internet via HTTP, etc.</p><p>Depending on the language and the environment that language is executing within, these contexts can vary greatly. Initially, programmers will discover this context one Google search at a time, but eventually, they'll start to be able to visualize the context itself. A more experienced programmer will actually browse the documentation for their context of choice and further discover more details about their tools.</p><p>Although I've only used "context" to mean the literal execution environment, I think it also includes third-party libraries from sites like <a href="https://github.com/">GitHub</a>, which provide readily available, open source code anyone can use. Knowledge of these free libraries can greatly increase the efficiency and capability of a software developer.</p><hr><p>Learning programming is hard. Building a foundation of knowledge takes time. Grouping one's learning into syntax, data flow, and context can help them build a sturdy foundation and grow their skills more quickly.</p>]]></content:encoded></item><item><title><![CDATA[Using Git Aliases]]></title><description><![CDATA[<p>I often spend my days writing code and committing it to a git repository. I love git. It makes me fearless and leaves me wondering how I did anything before we met. I hope you at least like git a little bit.</p><p>However, git isn't known for its beautiful interface.</p>]]></description><link>https://mattbrandly.com/using-git-aliases/</link><guid isPermaLink="false">5db1f67ce80c7007050229cd</guid><dc:creator><![CDATA[Matthew Brandly]]></dc:creator><pubDate>Sat, 20 Dec 2014 19:35:00 GMT</pubDate><content:encoded><![CDATA[<p>I often spend my days writing code and committing it to a git repository. I love git. It makes me fearless and leaves me wondering how I did anything before we met. I hope you at least like git a little bit.</p><p>However, git isn't known for its beautiful interface. Certain commands are oddly named, have a long list of options, and are capable of doing multiple, seemingly unrelated actions.</p><p>There is hope. Git can learn new commands, allowing you to define a more convenient interface that fits nicely into your workflow. Lengthy commands that are difficult to remember can be given simple names, and common commands that are used frequently can be aliased with shortcuts. After hours at a keyboard, those keystrokes will really add up, man.</p><p>I know how exciting this sounds, so let's get to it.</p><h2 id="show-me-the-money">show me the money</h2><p>Remember how I mentioned commands aren't always easy to remember? Let's look at how to define your first alias.</p><pre><code class="language-shell">$ git config --global alias.st 'status -sb'
</code></pre><p>Neat. Take a moment for that to sink in, and try running <code>git st</code> on one of your repos. If we had left out the <code>--global</code> flag, this command would only work in your local repo, but it seems more likely that you would want this shortcut for all your projects.</p><p>Now, when we type <code>git st</code>, git will do the exact same action as if we had done <code>git status -sb</code>. This command is one of my favorites, since it can be typed more quickly than <code>git status</code> and the output is a bit nicer.</p><h2 id="-gitconfig">.gitconfig</h2><p>Despite popular belief, computers are not magical devices. When we teach git a new trick, it needs to hold onto that information somewhere. In fact, it does so in a small file. Let's go track it down.</p><pre><code class="language-shell">$ cd ~
$ ls -a
</code></pre><p>At this point, I'm sure you're looking at a number of files, but the one we care about is called <code>.gitconfig</code>. If you open that file in your favorite text editor, you should at least see a couple lines that look like this.</p><pre><code class="language-bash">[alias]
  st = status -sb
</code></pre><p>We could have manually edited this file, and git would have been perfectly happy. In fact, let's try that out.</p><p>Right below the <code>st</code> definition, scribble down a line like this and save the file. Make sure to use a single tab character for the indentation.</p><pre><code class="language-bash">[alias]
  st = status -sb
  co = checkout
</code></pre><p>Now, when you run something like <code>git co master</code>, git will peek at this file, find out you really meant <code>git checkout master</code>, and take care of business.</p><h2 id="more-examples">more examples</h2><pre><code class="language-bash">[alias]
  cob = checkout -b
  cm = commit -m
  di = diff
  purr = pull --rebase
  who = shortlog -n -s --no-merges
  lg = log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)&lt;%an&gt;%Creset' --abbrev-commit
</code></pre><p>The first few just save keystrokes, but those last two are a bit fancier. I learned about <code>git lg</code> <a href="https://coderwall.com/p/euwpig/a-better-git-log">over here</a>, and it's much nicer than a standard <code>git log</code>. I didn't even know about <code>git shortlog</code> until I discovered the <code>git who</code> alias, thanks to <a href="http://robots.thoughtbot.com/streamline-your-git-workflow-with-aliases">thoughtbot</a>.</p><p>Personally, I find these aliases useful, but don't be afraid to write your own. Take the things I've taught you and build a deep relationship with git that stands the test of time.</p>]]></content:encoded></item><item><title><![CDATA[It Begins]]></title><description><![CDATA[<p>I've been telling myself for ages to start a blog. On occasion, I've gotten quite close, but I usually end up paralyzed by the number of options available.</p><p>I decided to the bite the bullet and just deploy <em>something</em>. I wanted to get up and running quickly but leave room</p>]]></description><link>https://mattbrandly.com/first/</link><guid isPermaLink="false">5db1f67ce80c7007050229cb</guid><dc:creator><![CDATA[Matthew Brandly]]></dc:creator><pubDate>Sat, 25 Oct 2014 18:42:00 GMT</pubDate><content:encoded><![CDATA[<p>I've been telling myself for ages to start a blog. On occasion, I've gotten quite close, but I usually end up paralyzed by the number of options available.</p><p>I decided to the bite the bullet and just deploy <em>something</em>. I wanted to get up and running quickly but leave room for plenty of control and customization later. Let's take a quick look at where I landed.</p><h2 id="ghost">Ghost</h2><p><a href="https://ghost.org/">Ghost</a> is "just a blogging platform." It seems like a more contemporary WordPress, and it runs on Node.js which is good for me, since I'm more familiar with JavaScript than most things. I'm also writing this post in <a href="http://daringfireball.net/projects/markdown/syntax">Markdown</a>, which I enjoy.</p><p>Ghost has <a href="https://ghost.org/pricing/">a few paid options</a> where they'll host an instance for you, but I ended up deploying it to <a href="https://www.digitalocean.com/">DigitalOcean</a>. They make it stupid simple to <a href="https://www.digitalocean.com/community/tutorials/how-to-use-the-digitalocean-ghost-application">get started</a>, but I can still <code>ssh</code> in and do whatever I please.</p><p>After searching for "ghost themes," I found an abundance of options. <a href="http://marketplace.ghost.org/themes/free/">Some</a> are free. <a href="http://themeforest.net/category/blogging/ghost-themes">Some</a> are not. It was quite easy to <a href="https://www.digitalocean.com/community/tutorials/how-to-change-themes-and-adjust-settings-in-ghost">install themes</a>, so I tried a few out before sticking with a free one called <a href="https://github.com/kathyqian/crisp-ghost-theme">Crisp</a>, by <a href="http://kathyqian.com/">Kathy Qian</a>. It seemed like a simple jumping-off point that I could tweak to my liking.</p><p>It turns out it's far more difficult to write a quality blog post than it is to start a blog, so we'll see what happens next.</p>]]></content:encoded></item></channel></rss>