<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>Sophia Turner&#x27;s Blog</title>
    <link rel="self" type="application/atom+xml" href="https://www.sophiajt.com/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://www.sophiajt.com"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2025-11-20T00:00:00+00:00</updated>
    <id>https://www.sophiajt.com/atom.xml</id>
    <entry xml:lang="en">
        <title>I wrote a book!</title>
        <published>2025-11-20T00:00:00+00:00</published>
        <updated>2025-11-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/i-wrote-a-book/"/>
        <id>https://www.sophiajt.com/i-wrote-a-book/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/i-wrote-a-book/">&lt;p&gt;Last month, the micropress I co-founded with my partner released our first full-length novel.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;machines_of_consent.png&quot; alt=&quot;Image of Machines of Consent&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Available on: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;transistance.itch.io&#x2F;machines-of-consent&quot;&gt;Itch&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.com&#x2F;Machines-Consent-Sophia-Turner-ebook&#x2F;dp&#x2F;B0FSGGRDSR&quot;&gt;Amazon&lt;&#x2F;a&gt;, and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;transistance.press&#x2F;links&#x2F;&quot;&gt;more&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;And yes, I&#x27;m proud to say, that is my name on the cover.&lt;&#x2F;p&gt;
&lt;p&gt;One of the hobbies that I picked up with a vengeance coming out trans is returning to my love of the written word. At first, I inhaled everything I could get my hands on written by trans women. Largely, these were what is colloquially known as &quot;eggfic&quot;. That is, fiction specifically about the early days of being trans. The journey to coming out, coming out, learning to be in the world right after coming out.&lt;&#x2F;p&gt;
&lt;p&gt;That fit me to a T. I wanted those stories because I was very much going through that part of the journey myself.&lt;&#x2F;p&gt;
&lt;p&gt;Along with the renewed interest in reading came a rebirth of my desire to write. In my 20s, I fancied myself a bit of a writer, though back then I couldn&#x27;t shake that I hadn&#x27;t really &lt;em&gt;lived&lt;&#x2F;em&gt;, yet. So, while I could write pretty words, they didn&#x27;t have any gravity to them.&lt;&#x2F;p&gt;
&lt;p&gt;Now, as a 40-something trans woman, once the stories found they were free to roam, I quickly took up my pen (or, my keyboard) and went to work. Authors like Issy Waldrom helped me get my early legs, and with time and lots of practice, the lessons from before came back to me.&lt;&#x2F;p&gt;
&lt;p&gt;Bit by bit, I built a toolbox of ideas.&lt;&#x2F;p&gt;
&lt;p&gt;One of these ideas blossomed into the book above: Machines of Consent. Rather than being about the early days of being trans, it includes seasoned trans women living their lives. As the title hints, it&#x27;s a story about consent in various forms and how we navigate it. It&#x27;s also a celebration of being a trans lesbian, both in love and in lust.&lt;&#x2F;p&gt;
&lt;p&gt;The story follows two women. One, a scientist who is both celebrated as a genuine inventor of a device that can transmit the wearer&#x27;s consent to the viewer. The other, a parkour expert who works as part of the underground delivering messages. The stories follows them as both are put into danger by a force outside of their control.&lt;&#x2F;p&gt;
&lt;p&gt;As tempting as it is to break the book down into the themes I cover, I think I&#x27;ll leave that as an exercise to the reader. Art, after all, is a two-person endeavour. I put my heart in. And the reader sees what they see in the result. In this, we communicate -- and hopefully entertain.&lt;&#x2F;p&gt;
&lt;p&gt;I will say that the end result was a thrill to put together. A lot of hard work, to be sure. But a joy to watch the pieces fall into place. Only in software have I ever felt something similar.&lt;&#x2F;p&gt;
&lt;p&gt;For folks who pick it up, I&#x27;d love to hear from you!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Bottom Surgery at WIH</title>
        <published>2025-07-08T00:00:00+00:00</published>
        <updated>2025-07-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/bottom-surgery-at-wih/"/>
        <id>https://www.sophiajt.com/bottom-surgery-at-wih/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/bottom-surgery-at-wih/">&lt;p&gt;On the 5th of June of this year, I had bottom surgery at &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.wihhospital.com&quot;&gt;WIH in Thailand&lt;&#x2F;a&gt;. It still doesn&#x27;t feel real. This post will hopefully help me process it, and with luck, help it feel more real as a result.&lt;&#x2F;p&gt;
&lt;p&gt;First off, if you haven&#x27;t had a look, the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.google.com&#x2F;document&#x2F;d&#x2F;1eQhJvkB_0WHu40vKJeVGlwCkQWbHbTYHBQ47rn4HKRw&#x2F;edit?tab=t.0#heading=h.fg7692c87zhe&quot;&gt;Opinionated Guide to SRS with Dr. Chet&lt;&#x2F;a&gt; has some good info. NB: Dr. Chet recently changed his name, so I&#x27;ll use the short form he uses that covers both.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-did-we-get-here&quot;&gt;How did we get here?&lt;&#x2F;h2&gt;
&lt;p&gt;Before I talk about the surgery itself, I should probably first talk a bit about how I got to this point. Something I talk about in my &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;sophiajt.itch.io&#x2F;taking-the-road-barefoot&quot;&gt;recent poetry collection&lt;&#x2F;a&gt; a few times is how long I&#x27;ve had bottom dysphoria. Like other kinds of dysphoria, bottom dysphoria is the disconnection between what you see and feel between your legs and yourself. For me, it started around 10 years old. At 23, I started looking up surgery options. By 30, I was actively talking about not wanting what I had anymore.&lt;&#x2F;p&gt;
&lt;p&gt;This is both a blessing and a curse. Waiting so long means that the amount of negative thoughts and feelings surrounding what I had impacted me and my relationships. It also meant that when I would have surgery, that I&#x27;d have to deal with a set of side effects as a result -- but let&#x27;s not jump ahead.&lt;&#x2F;p&gt;
&lt;p&gt;The treatment for bottom dysphoria is surgery. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ustranssurvey.org&quot;&gt;Satisfaction levels of 97%&lt;&#x2F;a&gt; for gender-affirming surgery put it as a clear solution for those who have access to it. The bittersweet thought that carried with me through the whole process was that it isn&#x27;t available for everyone who needs it, something which I hope changes as medical care improves and anti-trans sentiment recedes.&lt;&#x2F;p&gt;
&lt;p&gt;But surgery isn&#x27;t a button you press and come out with something different and go about your life. In this post, I&#x27;ll be giving a frank account of my experiences in the hopes they&#x27;re helpful.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why-wih&quot;&gt;Why WIH?&lt;&#x2F;h2&gt;
&lt;p&gt;Here in Oceania (specifically Australia&#x2F;New Zealand), we don&#x27;t have ready access to good quality surgeons for bottom surgery. Instead, we look to other countries. Very quickly, both through searches and in talking to girls who have gotten surgery, you learn that Thailand is the home of some of the best surgeons available. For us, that&#x27;s about an 8ish hour flight, which is certainly doable for something this big.&lt;&#x2F;p&gt;
&lt;p&gt;WIH provides both good accomodations as well as a full 30-day hospital&#x2F;long-term stay so that if you have any complications, they can attempt to catch them and fix them before you leave. For me, and other girls, this was quite helpful.&lt;&#x2F;p&gt;
&lt;p&gt;WIH, and Dr. Chet specifically, also worked on a number of girls I had a chance to talk to. Knowing they were largely happy with his work, aesthetics, and function meant that I had a decent chance of similar experience myself. As with anything, picking your surgeon is a calculated risk.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;which-surgery&quot;&gt;Which surgery?&lt;&#x2F;h2&gt;
&lt;p&gt;At the time of this writing, WIH offers four main styles of bottom surgery for transfeminine patients:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Non-PI (Dr. Chet style scrotal graft)&lt;&#x2F;li&gt;
&lt;li&gt;Laproscopic colon&lt;&#x2F;li&gt;
&lt;li&gt;Laproscopic peritoneal&lt;&#x2F;li&gt;
&lt;li&gt;Zero-depth&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Each style has its advantages&#x2F;disadvantages, including a pretty wide range in cost of the operation.&lt;&#x2F;p&gt;
&lt;p&gt;For mine, I chose the laproscopic peritoneal version, sometimes abbreviated PPT. I wanted natural lubrication and hopefully long-term healthy flora, though these certainly came with a much higher price tag than the non-PI surgery.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;pre-surgery-prep&quot;&gt;Pre-surgery prep&lt;&#x2F;h2&gt;
&lt;p&gt;In addition to the battery of tests you need to go through, there are multiple psych evals and bottom hair removal.&lt;&#x2F;p&gt;
&lt;p&gt;The psych evals were at times unnerving, touching on parts of my life I don&#x27;t often share. I saw them the same way I saw other stuff: working through the steps to get to the goal.&lt;&#x2F;p&gt;
&lt;p&gt;By far the hardest prep was bottom hair removal. I spent many sessions over a year and a half getting ready, and even then was unable to fully get all the hair permanently removed.&lt;&#x2F;p&gt;
&lt;p&gt;Dr. Chet now offers an additional surgery you can add on that is full electrolysis under general anaesthesia. It&#x27;s not cheap, but if you haven&#x27;t quite finished, for me at least it was a no-brainer. Better to have no hair than hair growing inside your vagina.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;bringing-someone&quot;&gt;Bringing someone&lt;&#x2F;h2&gt;
&lt;p&gt;I opted to bring a friend of mine who I&#x27;d been friends with for fifteen years. I&#x27;m trying to imagine what this would have been like without familiar support there.&lt;&#x2F;p&gt;
&lt;p&gt;Even still, it was rough. Rough to the point my friend and I decided to not chat for a while after the month had finished because of the strain on our relationship. To call it a trial-by-fire feels like a bit of an understatement.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;more-pre-surgery-prep&quot;&gt;More pre-surgery prep&lt;&#x2F;h2&gt;
&lt;p&gt;Once I was through the homework and pre-paid for the surgery, I was good to go. We flew into Bangkok and then met up with our ride to the hospital. We got settled into our room, and I started sleeping where I&#x27;d sleep for the next 30 days: and electronic hospital bed. I had to learn quickly how to get comfortable.&lt;&#x2F;p&gt;
&lt;p&gt;Right after getting there, they also put me on the cleanse I&#x27;d need for surgery: a multi-day liquid diet and bowel cleanse. And when I say cleanse, I mean it. By the last day the nurses were checking to make sure what came out of me was nearly transparent.&lt;&#x2F;p&gt;
&lt;p&gt;I found the liquid diet to not be too bad, but the cleanse itself rather taxing. I had to push a &lt;em&gt;lot&lt;&#x2F;em&gt; of water and laxatives to get to the state they wanted.&lt;&#x2F;p&gt;
&lt;p&gt;Finally, after the hard work, I got the a-okay for surgery the next day.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;surgery-day&quot;&gt;Surgery day&lt;&#x2F;h2&gt;
&lt;p&gt;Surgery day started off simply: no food no drink. After four days of strict diet this almost just felt like more diet. I pushed a bit extra right before the cut-off time and then just... waited. And waited. Terrified.&lt;&#x2F;p&gt;
&lt;p&gt;See, I may sound a bit nonchalant in the recounting, but the entire idea of surgery has always been scary to me. Would I die? Would I have life-long complications? Would I have to get a painful revision? Would I no longer be able to orgasm?&lt;&#x2F;p&gt;
&lt;p&gt;All of these worries tumbled around in my head as I waited for the hour of surgery, try though I might to distract myself.&lt;&#x2F;p&gt;
&lt;p&gt;When the hour finally came, I felt myself get pulled into a well-oiled machine. They took me on the gurney bed. Through the halls to another bed. Through many more halls. To the point where I was so dizzy and turned around when we finally got into the operating theatre.&lt;&#x2F;p&gt;
&lt;p&gt;I was in. I was committed. And scared to death.&lt;&#x2F;p&gt;
&lt;p&gt;I will say, the anaesthetist was a sweetheart. Very gentle. Very friendly. He helped put my mind at ease, giving me something to help calm me. Then, a few moments later, letting me know it was time to put me out.&lt;&#x2F;p&gt;
&lt;p&gt;The next thing I remember was waking up to &quot;you&#x27;re all done&quot;. Luckily no nausea. I laid in an observation room for two hours before they wheeled me back into our room.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;initial-recovery&quot;&gt;Initial recovery&lt;&#x2F;h2&gt;
&lt;p&gt;Initial recovery from surgery was absolute hell. Coming off general anaesthesia while having a fever made me hallucinate. During the surgery, my tailbone got re-injured (sadly a recurring injury I&#x27;ve had to deal with for years), so I kept having to ask the nurses to help position me to relieve tension on it. On and on.&lt;&#x2F;p&gt;
&lt;p&gt;While I managed to sleep the first night immediately after surgery, I stayed awake all of the second night. My brain was stuck in a state of permanent panic, assuming that if I let myself relax, I would die. I wish that were hyperbole, but it was quite real. I had trouble breathing, which kept recurring, and the whole experience wound me up incredibly tight emotionally.&lt;&#x2F;p&gt;
&lt;p&gt;Dr. Chet came to see me the day after my insomnia to see how I was going, and I admitted to not being able to sleep. He gave me something for it, which was quite effective. Again, a good reminder not to hide symptoms from the staff but to instead let them treat you. Sleep was important not just for my physical recovery, but for my emotional ability to get through what I was going through.&lt;&#x2F;p&gt;
&lt;p&gt;As part of the post-surgery setup, they also strapped automatic massage devices on my legs to help prevent blood clots while I was immobile. I hated them, but my friend hated them even more as they were loud enough to interrupt her sleep.&lt;&#x2F;p&gt;
&lt;p&gt;The first few days were them fighting my fever, checking my drain tubes, emptying my catheter bag, and checking my blood pressure. Rinse and repeat. It was clear they knew what they were doing and had done it many times before.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;next-recovery-stage&quot;&gt;Next recovery stage&lt;&#x2F;h2&gt;
&lt;p&gt;After the initial recovery, which took roughly a week, they began removing things they&#x27;d put on me after surgery. Some of them were the drain tubes from the surgical sight. One of them, I &lt;em&gt;think&lt;&#x2F;em&gt; was some kind of stress monitor. I remember this thing beeping at me when I&#x27;d push myself too much to adjust in bed or move a pillow.&lt;&#x2F;p&gt;
&lt;p&gt;As part of this, the packaging got removed. After this, dilations began. I remember still having my catheter in while having to do my first dilations.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;dilations&quot;&gt;Dilations&lt;&#x2F;h2&gt;
&lt;p&gt;Dilations. The &quot;flossing your teeth&quot; maintenance that I was going to have to do for the rest of my life. Even knowing what I was in for didn&#x27;t really prepare me. Though, let&#x27;s be honest, I&#x27;d never had a vagina before, how would I actually know what to expect?&lt;&#x2F;p&gt;
&lt;p&gt;The dilators are hard tubes with rounded fronts that you insert for some number of minutes to help stretch and keep both depth and width of your vagina. For the first few years, you have to do this pretty religiously (though some folks find their own rhythms much sooner than that). After that, a few times a week, you dilate.&lt;&#x2F;p&gt;
&lt;p&gt;Dr. Chet&#x27;s dilation schedule is... brutal. I&#x27;ll just be honest. After a few days of doing it, I was already holding in the dilator for 120 minutes at a time before switching to morning&#x2F;evening dilations.&lt;&#x2F;p&gt;
&lt;p&gt;Something I hadn&#x27;t known going in was that the PPV meant dilations were going to be significantly more difficult. The peritoneal donor tissue sits at the back of the vagina and is prone to scarring pretty quickly. My initial depth was 6 1&#x2F;2&quot;, but we never managed to dilate that far.&lt;&#x2F;p&gt;
&lt;p&gt;Which brings me to a story. When I first started dilating, the nurses would largely do it for me to show me how it was done. When the nurse working on me hit the back pocket of the PPV I started shaking and told her to stop immediately. In &lt;em&gt;theory&lt;&#x2F;em&gt;, I should have been able to push the dilator in to get the full depth. But I physically and emotionally just couldn&#x27;t do it. So, rather quickly, I lost half an inch of depth from not dilating in that area.&lt;&#x2F;p&gt;
&lt;p&gt;(Worth a note: because of travel and being inable to always achieve full depth, I&#x27;ve lost another half an inch and am down to 5 1&#x2F;2&quot;. I continue to work at this hoping to find a way to fix this, but I seem to just heal quickly.)&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m still trying to learn the lessons about how best to dilate, so I don&#x27;t feel ready to give tips here other than to say: breathe, listen to your body, and use good lube.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;getting-around-again&quot;&gt;Getting around again&lt;&#x2F;h2&gt;
&lt;p&gt;Noticing that my emotional state was bad and that I had a series of physical discomforts, Dr. Chet had the nurses get me standing and walking early. This was a mixed bag. I hadn&#x27;t really eaten any real food in a week at that point, perhaps longer, so just the act of standing was rather taxing.&lt;&#x2F;p&gt;
&lt;p&gt;By the second day of trying I was able to take some steps and then soon was back to walking and being able to empty the catheter bag on my own. Just this bit of mobility helped my mental state noticeably.&lt;&#x2F;p&gt;
&lt;p&gt;It was slow going, though. Get up and walk to the bathroom a few times a day was plenty. Little by little I could go further, but if I pushed it, I&#x27;d have to take a day to rest.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;getting-discharged&quot;&gt;Getting discharged&lt;&#x2F;h2&gt;
&lt;p&gt;Finally getting the catheter out (which hurt like hell), I could be discharged from the hospital to the long-stay. Nurses would still come by, but only twice a day, to check on me. At this point I was to ramp back up onto solid food, be dilating to the schedule, and be managing pretty much everything else -- including the pain and anxiety medication they gave me.&lt;&#x2F;p&gt;
&lt;p&gt;It felt like switching from one set of priorities to another. Working on walking, recovering my energy, eating, restarting my digestive system, hydrating, dilating, trying to stay positive, etc.&lt;&#x2F;p&gt;
&lt;p&gt;I wish I could say that at this point things felt like they were looking up, but I was still struggling with anxiety. I was still very much &quot;white-knuckling&quot; my way through, trying to get through each day so that I could go home.&lt;&#x2F;p&gt;
&lt;p&gt;My friend managed to get me out a few times to go to the market, or the mall, which was good. I needed that. But more than anything, I wanted to go home.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;trying-to-go-home-early&quot;&gt;Trying to go home early&lt;&#x2F;h2&gt;
&lt;p&gt;Word got back to the nurses that I wanted to go home early, which then brought Dr. Chet. He wanted to give me a thorough check to see if I could get cleared. For that, they brought me into the operating room again, which pushed my anxiety sky high. I lasted as long as I could, but the pain and pressure of the speculum on top of my anxiety made me beg for them to stop the examination. Luckily, he had what he needed, so we wrapped and then I got the news.&lt;&#x2F;p&gt;
&lt;p&gt;Nope, I wasn&#x27;t ready.&lt;&#x2F;p&gt;
&lt;p&gt;I had some unexpected swelling in my labia, which he wanted to treat through medicine first, and then surgery if that didn&#x27;t work. Back on antibiotics I went, with a new set of cleaning tasks the nurses would help with.&lt;&#x2F;p&gt;
&lt;p&gt;You do it because it needs to get done. At least that&#x27;s what I told myself.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;finally-going-home&quot;&gt;Finally going home&lt;&#x2F;h2&gt;
&lt;p&gt;Day by day, we managed. Finally, at last, it came time to go home. I woke up incredibly early (2am), dilated, then got ready for flying.&lt;&#x2F;p&gt;
&lt;p&gt;Flying sucked. Even though I knew it would and got us business class tickets, so I could recline the seat. I can&#x27;t imagine flying after surgery with a seat that doesn&#x27;t lean back far enough to take the pressure off the surgery site. Lots of drugs and bleeding it sounds like from other folks.&lt;&#x2F;p&gt;
&lt;p&gt;I also made sure I had wheelchair service. That ended up becoming importamt because I was coming to grips with a fact of life: I am now disabled. And will be for a few months.&lt;&#x2F;p&gt;
&lt;p&gt;My partner met me at the international hub in Australia and helped me get the rest of the way home and has since been my carer. It&#x27;s been an adjustment.&lt;&#x2F;p&gt;
&lt;p&gt;Things we&#x27;ve had to figure out so far:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;How and where to buy lube that works well&lt;&#x2F;li&gt;
&lt;li&gt;How to sleep in a way that doesn&#x27;t cause additional pain&lt;&#x2F;li&gt;
&lt;li&gt;How to get in some affection with my limited mobility&lt;&#x2F;li&gt;
&lt;li&gt;How much I can reasonably do for myself and how much I can offload onto her&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;All of these things are on-going adjustments.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;where-i-m-at-now&quot;&gt;Where I&#x27;m at now&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;dysphoria&quot;&gt;Dysphoria&lt;&#x2F;h3&gt;
&lt;p&gt;I wish I could say getting surgery cured my bottom dysphoria. It has to, right? Isn&#x27;t that what it&#x27;s for?&lt;&#x2F;p&gt;
&lt;p&gt;Yet, that&#x27;s still a process. Seeing my reflection &lt;em&gt;does&lt;&#x2F;em&gt; help. But all the nerves still send signals that my brain processes to be the thing that used to be there, not what&#x27;s there now. I still feel what was there, like a phantom limb. This takes a while to improve, I know from talking to other girls, but it&#x27;s left me feeling more than a little disoriented.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;pain&quot;&gt;Pain&lt;&#x2F;h3&gt;
&lt;p&gt;Pain and discomfort are regular guests, and ones I try to manage by finding healthy ways to rest. I also have to learn how much I can do before I have to stop. I don&#x27;t use the meds often, but I will from time to time to help.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;emotional-state&quot;&gt;Emotional state&lt;&#x2F;h3&gt;
&lt;p&gt;Going through surgery, and the resulting anxiety, was not without emotional cost. I&#x27;m still trying to pay that down. I still wrestle some with anxiety, though luckily far less now. I&#x27;m wrestling with other aspects of emotional health, too. Knowing that surgery isn&#x27;t a fix-all and coming to terms with it. Knowing that I&#x27;ll need to faithfully dilate as well is something I&#x27;m also coming to terms with.&lt;&#x2F;p&gt;
&lt;p&gt;Recovery definitely puts a strain on my body, which puts a strain on my mind and emotions. I&#x27;m still learning how to manage this, but it&#x27;s very easy to see why depression can hit after you get home. It&#x27;s a lot.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;was-it-worth-it&quot;&gt;Was it worth it?&lt;&#x2F;h2&gt;
&lt;p&gt;A question like this is far too early to ask. I still have months before the stitches come out. I&#x27;m still in the early stages of dilation training. I still regularly deal with pain and discomfort.&lt;&#x2F;p&gt;
&lt;p&gt;In short, I feel like I&#x27;m still &lt;em&gt;in&lt;&#x2F;em&gt; surgery and haven&#x27;t fully come out, yet. I don&#x27;t know what I have, I just know what I have to care for.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;day-at-a-time&quot;&gt;Day at a time&lt;&#x2F;h2&gt;
&lt;p&gt;Just as last month and going through surgery prep and surgery, I continue to get through each day one at a time. I believe that things will get better. I look forward to all of this feeling more natural as my brain rewires. More than that, I&#x27;m looking forward to it all just becoming second nature.&lt;&#x2F;p&gt;
&lt;p&gt;We&#x27;ll get there. It&#x27;ll take time, but we&#x27;ll get there.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Two years on HRT</title>
        <published>2025-03-23T00:00:00+00:00</published>
        <updated>2025-03-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/two-years-on-hrt/"/>
        <id>https://www.sophiajt.com/two-years-on-hrt/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/two-years-on-hrt/">&lt;p&gt;As I start this post, I feel the need to say that being trans and going down the path of intentionally changing my body, the way I&#x27;m perceived in the world, and the way I see myself hasn&#x27;t been an easy journey. But what I can say from here, with what I&#x27;ve experienced, I would never trade it.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;d love for this look at two years on HRT to strike that balance. To be honest about the challenges and the rewards.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;an-eye-on-the-horizon&quot;&gt;An eye on the horizon&lt;&#x2F;h2&gt;
&lt;p&gt;If it&#x27;s not already obvious, I feel like I&#x27;m entering a different phase of being trans. That early enthusiasm and those early wins have passed. Now, we&#x27;re in the long game. We have to wait for whatever changes come now, which may take their time. As best as I can, I try to remind myself that cis women do not look the same at two years into puberty what they will look like, say, ten years passed the start of puberty.&lt;&#x2F;p&gt;
&lt;p&gt;Something else has come into view over the last year: medical knowledge of inducing a second puberty chemically is very limited. Doctors routinely use things like WPATH and similar to inform their decisions, but anyone trained with a science background that goes and reads those papers will have a migraine. The science is dreadfully bad. Huge parts of the story are missing. Doctors often treat trans women as cis women going through menopause, even though there is limited similarity between the two. Papers written about cis women 60 years old get applied to trans women in their 30s. It&#x27;s nonsense. Yet, that&#x27;s where we are.&lt;&#x2F;p&gt;
&lt;p&gt;Instead of trusting a doctor, we become our own amateur endocrinologists. We print out papers and take them in. We fight for ways to experiment on ourselves to help the changes along, and in the end that&#x27;s really what it is: an experiment. We have no idea why, for example, progesterone works so well for some trans women and doesn&#x27;t absolutely nothing for others.&lt;&#x2F;p&gt;
&lt;p&gt;So we hack ourselves and find out what it will do for us.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;weathering-the-storm&quot;&gt;Weathering the storm&lt;&#x2F;h2&gt;
&lt;p&gt;Medical frustrations form a part of a larger picture, I&#x27;m afraid. The further in I get, the more the word &quot;transmisogyny&quot; blazes in my mind. God, I wish I could say that wasn&#x27;t true. That somehow people didn&#x27;t treat trans women, trans politics, and women in general as largely disposable or at least more than objects.&lt;&#x2F;p&gt;
&lt;p&gt;We become othered. Through a thousand cuts it becomes painfully clear you are no longer seen as valuable anymore. I&#x27;ve lost so many friends. Well, people I thought of as my friends for years. It was too easy for them to reject trans people. The implications was that I could stick around if I let it happen, but why would I do that? Why would I work for people who wanted me to shut up about the on-going oppression of people like myself? I open my mouth and immediately fall victim to the same oppression I was pushing back against.&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s so obvious and so clear. And yet, so easy for others to ignore. People can focus on their reputations and the status quo and no one around them is encouraging them to do otherwise. What could be wrong if everyone else is doing it?&lt;&#x2F;p&gt;
&lt;p&gt;What do you do when folks turn their backs? You seek out folks who don&#x27;t. Naturally many of the friends I&#x27;ve made in the last year are trans. Without community, I would fall, without a doubt. I&#x27;m thankful that community is there, and that mutual support is strong. Because as anyone who has watched the news has seen, trans folks are very much at the forefront of a culture war we never asked to be part of.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;if-it-s-hard-why-do-it&quot;&gt;If it&#x27;s hard, why do it?&lt;&#x2F;h2&gt;
&lt;p&gt;Despite all of the external forces, it&#x27;s worth it. I sit here writing this, alive. I&#x27;m not dying on the inside anymore. The hard choices and the hard road doesn&#x27;t make the results less important.&lt;&#x2F;p&gt;
&lt;p&gt;My brain is clearer. I&#x27;ve taken control of my life in ways I never was able to before. I&#x27;ve distanced myself from my abusers. My backbone is stronger, and when necessary I stand up for myself and others more than I ever have before.&lt;&#x2F;p&gt;
&lt;p&gt;And, let&#x27;s put false humility aside for a second. I&#x27;m cuter. I glow. Estrogen works for me.&lt;&#x2F;p&gt;
&lt;p&gt;I may not have all the curves I want, but HRT is building a woman out of my body and mind.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-changes&quot;&gt;The changes&lt;&#x2F;h2&gt;
&lt;p&gt;My breasts have grown only very little in the last year (which are actually closer to a B-cup, now that I know better ways to measure). My skin feels nicer. My face is more feminine and goes especially well with glasses.&lt;&#x2F;p&gt;
&lt;p&gt;Most of my body has shifted only slightly from where I started.&lt;&#x2F;p&gt;
&lt;p&gt;If I look at just body changes, I&#x27;d get frustrated. And honestly, some days that&#x27;s exactly what happens.&lt;&#x2F;p&gt;
&lt;p&gt;The real changes, though, for me have been mental ones. The open sky feeling. The access to emotions. Feeling where I&#x27;m afraid. Feeling where I&#x27;m happy. Where I&#x27;m sad. They&#x27;re all there, like instruments in an orchestra.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;passing&quot;&gt;Passing&lt;&#x2F;h2&gt;
&lt;p&gt;Yes, from time to time, I now get ma&#x27;amed. It&#x27;s nice. I have a decent idea what I need to do on my side to get it more often.&lt;&#x2F;p&gt;
&lt;p&gt;Having said that, I fight back. I resist that this is a thing worth doing. I still intentionally go out wearing something comfortable rather than trying to be as pretty as I can.&lt;&#x2F;p&gt;
&lt;p&gt;Not that I don&#x27;t have my pretty days. I love looking pretty. I just don&#x27;t want it to be a requirement. Doing things for the sole purpose of them being expected of you quickly becomes tiring.&lt;&#x2F;p&gt;
&lt;p&gt;When I get misgendered wearing a shapely bra, a girls t-shirt, girl&#x27;s pants, etc. I just kinda shake my head. People will just people. They&#x27;re on auto pilot.&lt;&#x2F;p&gt;
&lt;p&gt;Passing is playing for an audience that doesn&#x27;t pay attention to the world around them. Why worry too much about it?&lt;&#x2F;p&gt;
&lt;p&gt;(Unless of course, you are doing it to stealth for survival.)&lt;&#x2F;p&gt;
&lt;h2 id=&quot;art&quot;&gt;Art&lt;&#x2F;h2&gt;
&lt;p&gt;Instead, why not play for an audience that does appreciate the details? Heck, sharing a selfie where I&#x27;m feeling particularly cute and getting lots of good feedback doesn&#x27;t hurt either.&lt;&#x2F;p&gt;
&lt;p&gt;Part of community is lifting each other up and listening to each other.&lt;&#x2F;p&gt;
&lt;p&gt;There&#x27;s something deeper there, though. Many of my friends these days are part of the trans literature community. Most are authors. It&#x27;s a kind of closeness I never felt before, certainly not as a programmer in open source.&lt;&#x2F;p&gt;
&lt;p&gt;It quickly became so important to me that I co-created a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;transistance.press&quot;&gt;publishing press&lt;&#x2F;a&gt; with my partner focused on publishing trans work. It&#x27;s still very early days for it, but we wanted somewhere safe from American oppression that could continue to make sure trans voices were heard.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;love&quot;&gt;Love&lt;&#x2F;h2&gt;
&lt;p&gt;Speaking of my partner... This past year, I fell in love with a beautiful Aussie trans woman. Hard.&lt;&#x2F;p&gt;
&lt;p&gt;I ended up asking her out in October because the sensation in my chest had grown to near bursting. I literally was walking around my apartment repeating out loud &quot;well, at least she&#x27;ll know, even if she doesn&#x27;t say yes&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;She did, thankfully, say yes. We&#x27;ve been thick ever since. Not that we haven&#x27;t had times where we dealt with stuff. I&#x27;ve been through a lot from past relationships - sexual abuse, emotional abuse, etc. That stuff still comes up from time to time, and we&#x27;re learning how to best work through it.&lt;&#x2F;p&gt;
&lt;p&gt;Being able to be in a relationship on HRT, feeling my feelings and being able to share and communicate better than I ever have? I highly recommend it. I don&#x27;t want to go backward. I don&#x27;t want to feel discomfort and have no idea how to address it.&lt;&#x2F;p&gt;
&lt;p&gt;Doesn&#x27;t hurt that I&#x27;m not trying to be a man in a relationship anymore... What a total waste of energy.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-path-ahead-is-covered-in-fog&quot;&gt;The path ahead is covered in fog&lt;&#x2F;h2&gt;
&lt;p&gt;I would never have been able to predict where things are today a year ago. I have no doubt that the coming year might be similar. The initial changes have happened, but now the new waves of social, interpersonal, and internal changes have begun. The only way to know what will happen is to experience it.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m looking forward to the journey ahead. May it be a healing journey. And, if we&#x27;re lucky, an empowering one.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>I stopped believing in America</title>
        <published>2025-02-27T00:00:00+00:00</published>
        <updated>2025-02-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/stopped-believing-in-america/"/>
        <id>https://www.sophiajt.com/stopped-believing-in-america/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/stopped-believing-in-america/">&lt;p&gt;Somewhere along the way, I stopped believing in America.&lt;&#x2F;p&gt;
&lt;p&gt;I moved to New Zealand over eight years ago. At first, all I noticed were the similarities to the place I&#x27;d lived for nearly 40 years of my life. Then, little by little, I noticed the differences. The fact that ambition didn&#x27;t permeate every aspect of life here. That family was more important than work.&lt;&#x2F;p&gt;
&lt;p&gt;Yesterday, I renounced my US citizenship.&lt;&#x2F;p&gt;
&lt;p&gt;In this post, I want to unpack how I got there, in part to help me process, but perhaps to help anyone reading this to also process their own thoughts about America.&lt;&#x2F;p&gt;
&lt;p&gt;You grow up being told that America is the land of opportunity. That it&#x27;s a place you can make your way. When I look at it now, from the 10,000km away, I see something else. I see a place that lied to its people, that didn&#x27;t tell them that such dreams were meant only for the blessed, lucky few.&lt;&#x2F;p&gt;
&lt;p&gt;I also see an America that lies to itself about how it got there. How many indigenous peoples were killed to make space for the Europeans? How many slaves were brought over and tortured to generate wealth? How many prisons were built to continue slavery after it was formally abolished? I&#x27;m not saying anything new here. The work to illuminate these facts comes from folks working in America to help show the problems that persist.&lt;&#x2F;p&gt;
&lt;p&gt;These problems feel woven into the American way of thinking for so many folks. The promises carry with them the need to continue the system as it is, with all its flaws.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;But, Soph!&lt;&#x2F;em&gt; I hear folks say. &lt;em&gt;Other countries have problems, too!&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Of course they do. Yet that fact doesn&#x27;t stop America&#x27;s problems from being profound.&lt;&#x2F;p&gt;
&lt;p&gt;Watching America be consumed by corporate power feels like watching a massive conflagration. Nothing seems to be spared the flames. As if exhaling a long-held breath, corporations let go of their DEI initiatives, whole groups of employees trying to secure equality for LGBTQ+ folx in the company, and progressively anyone and everyone who would stand in the way of unfettered sights of the free market.&lt;&#x2F;p&gt;
&lt;p&gt;In short, anyone who might remind the company it needed to have a conscience.&lt;&#x2F;p&gt;
&lt;p&gt;Yet America has looked on for decades as it built these giants. Corporations, after all, are merely the offspring of the American dream, the product of the successes of capitalism. The line must go up, both legally and &quot;morally&quot;, and so everyone salutes them. They invest in them and hope the windfall carries them into retirement. They work for them and help them grow, often as a means to survive.&lt;&#x2F;p&gt;
&lt;p&gt;The separation of church and state felt like a noble effort. Keep those with one kind of power away from those with another kind of power. Corporations, America&#x27;s real church, has managed to shrug off any such shackles to grab the reins of governance for themselves.&lt;&#x2F;p&gt;
&lt;p&gt;When I say that I stopped believing in America, it is that we are all watching this happen, but I don&#x27;t think Americans will stand up against it. Will Americans support dissolving monopolies? Will they remove corporate interests from politics? Will they disallow billionaires from forming?&lt;&#x2F;p&gt;
&lt;p&gt;Such possibilities feel counter to what has become the American way. It would require a complete rethink of everything. Admitting that everything for decades (well, centuries, really) was based on hurting others to get on top.&lt;&#x2F;p&gt;
&lt;p&gt;America would have to admit that it &lt;em&gt;isn&#x27;t&lt;&#x2F;em&gt; the best. And has never been. That would be a big pill to swallow.&lt;&#x2F;p&gt;
&lt;p&gt;Having said all that - renouncing my citizenship gives me mixed feelings. You can&#x27;t forget the moments of joy on the soil America was founded on. A fertile place that did indeed have promise. The place that held you as you took your first steps. Had your first kiss. It&#x27;s bittersweet to see those superimposed over everything else that has happened, and continues to happen, on that same soil.&lt;&#x2F;p&gt;
&lt;p&gt;After eight years here of detoxing from the American way, of living and working differently, I realised that I&#x27;m just not an American anymore. I&#x27;ve changed. When I visit the US, I feel like an outsider. I listen to people, and I don&#x27;t understand their motivations. Even the accent sounds strange.&lt;&#x2F;p&gt;
&lt;p&gt;I feel like an alien to how America works and how many Americans act. I don&#x27;t want to move back. I don&#x27;t want to try to reintegrate. I want instead to respect the journey I&#x27;m on, one that&#x27;s made me significantly more healthy than I was before. To do so, sometimes we must leave our motherland behind.&lt;&#x2F;p&gt;
&lt;p&gt;I just got a call. My renunciation will misgender me because of the recent policy changes. The person I talked to even mentioned &quot;I bet this is part of the reason you made this decision.&quot; Yeah, you don&#x27;t say.&lt;&#x2F;p&gt;
&lt;p&gt;Do I believe America will eventually remove the boot from the backs of minorities? Yes, but only to move it to the next minority in line. Any pause seems only long enough to congratulate itself for its liberality, and then at the next opportunity to plant its heel again.&lt;&#x2F;p&gt;
&lt;p&gt;I don&#x27;t want to be a part of it. It&#x27;s time for divorce. If things deeply change. If America repents and actually makes amends for its original sins so that it can put itself on the path of being an actual land of opportunity for everyone. If all this happens and more, will I reconsider? Will I find it in my heart to fall back in love, decades from now? Perhaps.&lt;&#x2F;p&gt;
&lt;p&gt;But first, it&#x27;s got to do something it&#x27;s never done before as a society: to care.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Trans Lesbian Book List</title>
        <published>2024-11-22T00:00:00+00:00</published>
        <updated>2024-11-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/trans-lesbian-list/"/>
        <id>https://www.sophiajt.com/trans-lesbian-list/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/trans-lesbian-list/">&lt;p&gt;Below Dani Finn, Issy Waldrom, and myself compiled a list of trans lesbian books. If this list is missing entries, please let me know!&lt;&#x2F;p&gt;
&lt;p&gt;Just to be clear on the terms we&#x27;re using for the list:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;trans - the main character, or at least one significant POV, must be trans&lt;&#x2F;li&gt;
&lt;li&gt;lesbian - the main character, or at least one significant POV, must be lesbian&lt;&#x2F;li&gt;
&lt;li&gt;also, there are no romantic&#x2F;sexual encounters with men&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Title&lt;&#x2F;th&gt;&lt;th&gt;Author&lt;&#x2F;th&gt;&lt;th&gt;Second Author&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;NEED&lt;&#x2F;td&gt;&lt;td&gt;Abbott, Elena&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Pack of Her Own&lt;&#x2F;td&gt;&lt;td&gt;Abbott, Elena&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;The Revenge of Captain Vessia&lt;&#x2F;td&gt;&lt;td&gt;Allen, Leslie&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Temptation at Randy&#x27;s&lt;&#x2F;td&gt;&lt;td&gt;Alter, Emily&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;A Sea of Silence&lt;&#x2F;td&gt;&lt;td&gt;Atkinson, Kay&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Nibbled Bookmark&lt;&#x2F;td&gt;&lt;td&gt;Avant, Melody&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Galaxy: The Prettiest Star&lt;&#x2F;td&gt;&lt;td&gt;Axelrod, Jadzia&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Confluence: A Person-Shaped Story&lt;&#x2F;td&gt;&lt;td&gt;Bakkalian, Nyri&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Grey Dawn**&lt;&#x2F;td&gt;&lt;td&gt;Bakkalian, Nyri&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Any Other Name**&lt;&#x2F;td&gt;&lt;td&gt;Bambust, Ela&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Horns in the Library&lt;&#x2F;td&gt;&lt;td&gt;Bambust, Ela&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Nexus Alpha&lt;&#x2F;td&gt;&lt;td&gt;Bambust, Ela&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Dulhaniyaa&lt;&#x2F;td&gt;&lt;td&gt;Bhatt, Talia&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Nevada**&lt;&#x2F;td&gt;&lt;td&gt;Binnie, Imogen&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Rhapsody&lt;&#x2F;td&gt;&lt;td&gt;Bragg, Molly J&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Transistor&lt;&#x2F;td&gt;&lt;td&gt;Bragg, Molly J&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Magica Riot&lt;&#x2F;td&gt;&lt;td&gt;Buchanan, Kara&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Princess Fox and Iron Wolf&lt;&#x2F;td&gt;&lt;td&gt;Chaos, Liliana&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;The Price on Her Head&lt;&#x2F;td&gt;&lt;td&gt;Clay, Suzanne&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Ghost Flower**&lt;&#x2F;td&gt;&lt;td&gt;Conwell, Jessica&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Dreadnought&lt;&#x2F;td&gt;&lt;td&gt;Daniels, April&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Sovereign&lt;&#x2F;td&gt;&lt;td&gt;Daniels, April&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;She Who Earned Her Wings&lt;&#x2F;td&gt;&lt;td&gt;Denarr, Vaela&lt;&#x2F;td&gt;&lt;td&gt;Iannandrea, Micah&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Seasons of Fools&lt;&#x2F;td&gt;&lt;td&gt;Doerner, Morrigan&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Catnip&lt;&#x2F;td&gt;&lt;td&gt;Durav, Vyria&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Hatchling&lt;&#x2F;td&gt;&lt;td&gt;Durav, Vyria&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Wyrmheart&lt;&#x2F;td&gt;&lt;td&gt;Durav, Vyria&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Sundered Moon&lt;&#x2F;td&gt;&lt;td&gt;Fae&#x27;rynn&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Stray Dogs (1st book in series)&lt;&#x2F;td&gt;&lt;td&gt;Faust, Freya&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;The World Within&lt;&#x2F;td&gt;&lt;td&gt;Finn, Dani&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Scales of Seduction&lt;&#x2F;td&gt;&lt;td&gt;Gray, Rien&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Seure the Tempered&lt;&#x2F;td&gt;&lt;td&gt;Gray, Rien&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Valerin the Fair&lt;&#x2F;td&gt;&lt;td&gt;Gray, Rien&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;(kimmy)***&lt;&#x2F;td&gt;&lt;td&gt;Greaves, Alyson&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Cora Christensen&lt;&#x2F;td&gt;&lt;td&gt;Howsden, Tanner&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;JUNKER SEVEN&lt;&#x2F;td&gt;&lt;td&gt;Kelley, Olive J.&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Ransom to Love&lt;&#x2F;td&gt;&lt;td&gt;Keto, Chloe&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Huntress of the Night: In Cold Embrace**&lt;&#x2F;td&gt;&lt;td&gt;Leonard, Gwen&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Make Room for Love&lt;&#x2F;td&gt;&lt;td&gt;Liao, Darcy&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Not Just Best Friends&lt;&#x2F;td&gt;&lt;td&gt;Liao, Darcy&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Beauty&#x27;s Beast&lt;&#x2F;td&gt;&lt;td&gt;Lynn, S.T.&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Cinder Ella**&lt;&#x2F;td&gt;&lt;td&gt;Lynn, S.T.&lt;&#x2F;td&gt;&lt;td&gt;Veldura, Tami&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Mer Made&lt;&#x2F;td&gt;&lt;td&gt;Lynn, S.T.&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Ghostkin&lt;&#x2F;td&gt;&lt;td&gt;Mellor, Ellen&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;You Kiss Like a Rocket&lt;&#x2F;td&gt;&lt;td&gt;MsJuniper&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Revolution of Wild Magic&lt;&#x2F;td&gt;&lt;td&gt;Quill, Katie&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;The Red Satin Collection&lt;&#x2F;td&gt;&lt;td&gt;Renarde, Giselle&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Brainwyrms**&lt;&#x2F;td&gt;&lt;td&gt;Rumfitt, Allison&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Imposters&lt;&#x2F;td&gt;&lt;td&gt;Sandwich, Cassie&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Fake It&lt;&#x2F;td&gt;&lt;td&gt;Seabrooke, Lily&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Not Like Before&lt;&#x2F;td&gt;&lt;td&gt;Seabrooke, Lily&lt;&#x2F;td&gt;&lt;td&gt;Ramsden, Jacqueline&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Us&lt;&#x2F;td&gt;&lt;td&gt;Soler, Sara&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;To Own the Libs&lt;&#x2F;td&gt;&lt;td&gt;Storm, Zoe&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Wayward Fairy&lt;&#x2F;td&gt;&lt;td&gt;Sutton, Mackenzie&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Blood of Gorgon&lt;&#x2F;td&gt;&lt;td&gt;Tang, Selene&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Shadow of Gorgon&lt;&#x2F;td&gt;&lt;td&gt;Tang, Selene&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;As Happy as Pirates or Burglars&lt;&#x2F;td&gt;&lt;td&gt;Topaz, Jemma&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Captains of a Tyrant Fate&lt;&#x2F;td&gt;&lt;td&gt;Topaz, Jemma&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Our Monsters&lt;&#x2F;td&gt;&lt;td&gt;Topaz, Jemma&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;The Brute of Greengrave&lt;&#x2F;td&gt;&lt;td&gt;Topaz, Jemma&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Pride, Pain, and Petticoats volume 1&lt;&#x2F;td&gt;&lt;td&gt;Trusity, Abby&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Pride, Pain, and Petticoats volume 2&lt;&#x2F;td&gt;&lt;td&gt;Trusity, Abby&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Against Fearful Lies (The Amelia Temple Series Book 2)&lt;&#x2F;td&gt;&lt;td&gt;Valentine, Vivian&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Beneath Strange Lights (The Amelia Temple Series Book 1)&lt;&#x2F;td&gt;&lt;td&gt;Valentine, Vivian&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Best Friends&#x27; Promise&lt;&#x2F;td&gt;&lt;td&gt;Waldrom, Issy&lt;&#x2F;td&gt;&lt;td&gt;Sutton, Mackenzie&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Dawn Weaver&lt;&#x2F;td&gt;&lt;td&gt;Waldrom, Issy&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Esper and the Witch&lt;&#x2F;td&gt;&lt;td&gt;Waldrom, Issy&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Heart&#x27;s Claim&lt;&#x2F;td&gt;&lt;td&gt;Waldrom, Issy&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Soul Flames Volume 1&lt;&#x2F;td&gt;&lt;td&gt;Waldrom, Issy&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Soul Flames Volume 2&lt;&#x2F;td&gt;&lt;td&gt;Waldrom, Issy&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Soul Flames Volume 3&lt;&#x2F;td&gt;&lt;td&gt;Waldrom, Issy&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Soul Flames Volume 4&lt;&#x2F;td&gt;&lt;td&gt;Waldrom, Issy&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;The Grace of Sorcerers&lt;&#x2F;td&gt;&lt;td&gt;Ying, Maria&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;The Gunrunner and her Hound&lt;&#x2F;td&gt;&lt;td&gt;Ying, Maria&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;The Hades Calculus&lt;&#x2F;td&gt;&lt;td&gt;Ying, Maria&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;The Might of Monsters&lt;&#x2F;td&gt;&lt;td&gt;Ying, Maria&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;The Ruin of Beasts&lt;&#x2F;td&gt;&lt;td&gt;Ying, Maria&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;The Serpent of the House of Hua&lt;&#x2F;td&gt;&lt;td&gt;Ying, Maria&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;The Spy and her Serpent&lt;&#x2F;td&gt;&lt;td&gt;Ying, Maria&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;The Vela&lt;&#x2F;td&gt;&lt;td&gt;Yoon, Ha Lee&lt;&#x2F;td&gt;&lt;td&gt;Chambers, Becky; Huang, S. L.; Solomon, Rivers&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;ul&gt;
&lt;li&gt;(*) - Collection of stories&lt;&#x2F;li&gt;
&lt;li&gt;(**) - Needs to be double-checked&lt;&#x2F;li&gt;
&lt;li&gt;(***) - Includes rape or other sexual assault by a man&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Sharing Trans Femme Lit</title>
        <published>2024-11-04T00:00:00+00:00</published>
        <updated>2024-11-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/sharing-trans-femme-lit/"/>
        <id>https://www.sophiajt.com/sharing-trans-femme-lit/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/sharing-trans-femme-lit/">&lt;p&gt;&lt;em&gt;Co-authored with &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;bsky.app&#x2F;profile&#x2F;demongrrl.gay&quot;&gt;Aurora Foo&lt;&#x2F;a&gt;&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We just finished reading &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;kaichengthom.substack.com&#x2F;p&#x2F;how-to-read-a-trans-fem-writer&quot;&gt;&quot;How to Read a Trans Fem Writer&quot;&lt;&#x2F;a&gt;. The article is written generally for readers from outside the queer (and specifically the trans femme) community who might not be used to engaging in this type of art, and has lots of good tips for how to engage with our art. We&#x27;d encourage folks to read the essay and reflect. This is especially important because of the volume of negative comments many trans femme authors get on their work. Helping readers have a keener eye and not fall into patterns and expectations that are hurtful to those authors is important.&lt;&#x2F;p&gt;
&lt;p&gt;As someone inside the trans femme community, it also brought up additional questions about the art that we create and our responsibilities we have to each other.&lt;&#x2F;p&gt;
&lt;p&gt;The first that needs to be said and repeated: we should make the art we want to make. It&#x27;s vitally important. Having articles like this one help people navigate the art that we&#x27;re creating.&lt;&#x2F;p&gt;
&lt;p&gt;Having said that, there&#x27;s a conversation we should have amongst each other about how we as a community can better share our art.&lt;&#x2F;p&gt;
&lt;p&gt;Trans femmes, as a community, experience a profound amount of collective trauma. As individuals also, ourselves included, have more than our share of trauma. Art can stir up that trauma because it reaches inside of us. Art that does so should let us know the topics it will cover so that we can be better informed as readers.&lt;&#x2F;p&gt;
&lt;p&gt;Recently, Soph finished reading &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;alysongreaves.itch.io&#x2F;kimmy&quot;&gt;(kimmy)&lt;&#x2F;a&gt;. It&#x27;s brilliant. It&#x27;s clever. It&#x27;s everything folks lauding it say it is. And it&#x27;s also horribly triggering and in its current version has an incomplete content warning list. Aurora saw firsthand the effect it had, following along on Soph&#x27;s reading journey. A book with the themes and content that (kimmy) has needs to throughly warn its readers, to ensure people aren&#x27;t re-traumatised by its content and can make an informed decision about choosing to read it. That was not the case in our experience, and Soph took emotional damage as a result of reading the book.&lt;&#x2F;p&gt;
&lt;details&gt; 
  &lt;summary&gt;Additional (kimmy) warnings&lt;&#x2F;summary&gt;
   Repeated rape, forced incest, nonconsensual mind control, and ego&#x2F;identity death.
&lt;&#x2F;details&gt;
&lt;p&gt;We then went on social media to see people breathlessly praising this work without warning anyone about its contents. It&#x27;s undoubtedly brilliant, but it&#x27;s also painful, and discusses at length things that could be potentially triggering for a lot of trans femmes out there. Going on about how everyone should read it, without stopping to warn folks reading your post to take care, feels irresponsible.&lt;&#x2F;p&gt;
&lt;p&gt;To reiterate: we firmly believe we should make the art we want to make. Make it messy if you want to make it messy. Make it challenging. Make it dark. Give it all the sharp edges you feel you need to in making the art that feels honest and true.&lt;&#x2F;p&gt;
&lt;p&gt;Once you do, let folks know what those sharp edges are. As readers and promoters, it&#x27;s the responsible thing to let other folks know so they can make better informed choices. It is more than responsible, though, it&#x27;s the kind thing to do. As a community, we need to take care of each other, and when we share these often brilliant works of art that explore traumatic content, we need to ensure that people go into them with informed consent.&lt;&#x2F;p&gt;
&lt;p&gt;We need to be better at not &lt;strong&gt;uncritically&lt;&#x2F;strong&gt; promoting work that has the potential to re-traumatise our peers. That&#x27;s not to say we shouldn&#x27;t share our praise and love for our art - we absolutely should! We just need to be better at balancing our (perfectly valid) enthusiasm for works with making sure the people we broadcast our thoughts to don&#x27;t develop an incorrect picture, only to be blindsided by potentially triggering content.&lt;&#x2F;p&gt;
&lt;p&gt;We need to be better, because our work deserves it. As a community, the creation of trans femme art is vitally important. It can be a cathartic experience to create, and it can be a carthartic experience to consume. However, we must remember the context in which we exist as a community, and ensure we discuss our art with care and consideration for our fellow sisters.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Following new paths ahead</title>
        <published>2024-06-04T00:00:00+00:00</published>
        <updated>2024-06-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/following-new-paths-ahead/"/>
        <id>https://www.sophiajt.com/following-new-paths-ahead/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/following-new-paths-ahead/">&lt;p&gt;Hi all! Wow, the last month has been quite the rollercoaster. In that short time, I announced June publicly and, on a sad note, also had its funding pulled.&lt;&#x2F;p&gt;
&lt;p&gt;The end result was a feeling of whiplash that I needed to recover from. After taking a break, here are my plans going forward.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;nushell&quot;&gt;Nushell&lt;&#x2F;h1&gt;
&lt;p&gt;Nushell has been a pride and joy for many years, though for many months I&#x27;ve very much been in the background while others led the project. After watching my friend Andreas &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;awesomekling.substack.com&#x2F;p&#x2F;forking-ladybird-and-stepping-down-serenityos&quot;&gt;step down from Serenity&lt;&#x2F;a&gt; (EDIT: please note, Andreas and I are no longer friends), I knew it was time for me to do the same for Nushell.&lt;&#x2F;p&gt;
&lt;p&gt;Effective today, I&#x27;m no longer part of the Nushell administration team and have handed those responsibilities off to other members of the team.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;june&quot;&gt;June&lt;&#x2F;h1&gt;
&lt;p&gt;After announcing June and then losing funding for it, I took a step back from it.&lt;&#x2F;p&gt;
&lt;p&gt;There are some hard truths about programming languages and open source. It&#x27;s a difficult path to travel, and it takes a long time. A good language can take 6+ years to mature to the point it&#x27;s ready for users to trust it. Open source itself requires that you&#x27;re ready to weather the burden of maintenance.&lt;&#x2F;p&gt;
&lt;p&gt;When I look at this, in light of having to self-fund the project, I know that I don&#x27;t have the focus nor the energy to pull it off. That&#x27;s not a knock against June. More, it&#x27;s an admission about understanding how I work - especially in the light of being autistic and having to listen to where my drive is. The thing is, you can&#x27;t fake drive. If you try to, you can easily burnout.&lt;&#x2F;p&gt;
&lt;p&gt;With this in mind, I&#x27;m archiving &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sophiajt&#x2F;june&quot;&gt;June&lt;&#x2F;a&gt; and setting it to not-maintained. I&#x27;m also doing likewise for another project called &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sophiajt&#x2F;truffle&quot;&gt;Truffle&lt;&#x2F;a&gt; that I released along the same time.&lt;&#x2F;p&gt;
&lt;p&gt;Having done this, I&#x27;ll be able to let my creativity come back and go where it wants to go. This will be healthier for me and also will let me continue to make art that makes me, and hopefully others, happy.&lt;&#x2F;p&gt;
&lt;p&gt;For those of you who believed in the June message - thank you! I would love to see motivated people take it and fork it and carry it on. I&#x27;d also love to see other languages spring up which evolved the ideas further.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>The search for easier safe systems programming</title>
        <published>2024-05-08T00:00:00+00:00</published>
        <updated>2024-05-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/search-for-easier-safe-systems-programming/"/>
        <id>https://www.sophiajt.com/search-for-easier-safe-systems-programming/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/search-for-easier-safe-systems-programming/">&lt;p&gt;I&#x27;ve been involved in the Rust project in some form or another since 2016, and it&#x27;s a language I&#x27;m very comfortable using. Many Rust programmers could &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blog.rust-lang.org&#x2F;2024&#x2F;02&#x2F;19&#x2F;2023-Rust-Annual-Survey-2023-results.html&quot;&gt;say the same&lt;&#x2F;a&gt;. But, if we take a step back and are honest with ourselves, we&#x27;d admit that the road to getting to that level of comfort was difficult.&lt;&#x2F;p&gt;
&lt;p&gt;I taught Rust professionally for two years. Watching the faces of people trying to learn Rust for the first time reminded me just how hard this language is to learn.&lt;&#x2F;p&gt;
&lt;p&gt;After two years of that, I wanted to answer a question I wasn&#x27;t entirely sure had an answer: &lt;em&gt;Is it possible to make an easy-to-use, easy-to-learn, and easy-to-teach safe systems language?&lt;&#x2F;em&gt; Could I put my career working on programming languages (TypeScript, Rust, Nushell, etc) to use and find a solution?&lt;&#x2F;p&gt;
&lt;h1 id=&quot;enter-june&quot;&gt;Enter June&lt;&#x2F;h1&gt;
&lt;p&gt;For the last year and a half, I and my recently-added collaborator Jane Losare-Lusby have been working in secret on a safe systems language that could be learned about as quickly as one can learn Go. I think we might have something worth exploring.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;changing-how-we-think-of-memory&quot;&gt;Changing how we think of memory&lt;&#x2F;h2&gt;
&lt;p&gt;In Rust, we think of each piece of memory as having its own lifetime. Each of these lifetimes must be tracked, sometimes leading to rather complex code, complex error messages, and&#x2F;or complex mental models of what is happening. The complexity of course comes with the benefit of being highly precise about each and every piece of memory and its reclamation.&lt;&#x2F;p&gt;
&lt;p&gt;Using a Rust example:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;struct Node {
    data1: &amp;amp;Data,
    data2: &amp;amp;Data,
    data3: &amp;amp;Data,
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Rust developers will spot right away that this is an incomplete example. We need two more things: Lifetime Parameters and Lifetime Annotations. Adding those, we get:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;struct Node&amp;lt;&amp;#39;a, &amp;#39;b, &amp;#39;c&amp;gt; {
    data1: &amp;amp;&amp;#39;a Data,
    data2: &amp;amp;&amp;#39;b Data,
    data3: &amp;amp;&amp;#39;c Data,
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The concept count for this example ends up being pretty substantial. Counting them off, we get:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Lifetimes&lt;&#x2F;li&gt;
&lt;li&gt;Lifetime annotations&lt;&#x2F;li&gt;
&lt;li&gt;Lifetime parameters&lt;&#x2F;li&gt;
&lt;li&gt;Ownership and borrowing&lt;&#x2F;li&gt;
&lt;li&gt;Generics&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;When I showed examples like this to my class when I taught Rust, I had to walk them through each of those concepts first before I could show the full example.&lt;&#x2F;p&gt;
&lt;p&gt;The question then is: can we make this easier?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-if-memory-was-grouped&quot;&gt;What if memory was grouped?&lt;&#x2F;h2&gt;
&lt;p&gt;What if instead of having to track every piece of memory&#x27;s lifetime separately, we let groups of related allocations share a lifetime?&lt;&#x2F;p&gt;
&lt;p&gt;Effectively, this would mean that a data structure, like a linked list, would have a pointer pointing to the head which has a lifetime, and then every node in the list you can reach from that head has the same lifetime.&lt;&#x2F;p&gt;
&lt;p&gt;There are some benefits to this approach, as well as a few drawbacks. Let&#x27;s take a look at the benefits first.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;benefits-of-grouped-allocations&quot;&gt;Benefits of grouped allocations&lt;&#x2F;h2&gt;
&lt;p&gt;Exploring grouped allocations, we noticed some immediate benefits. The first is that we could treat all user-defined values as pointers, and these pointers could also represent their own lifetimes (without needing lifetime parameters). This makes the code feel quite a bit lighter:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;struct Node {
    data: i64
    next: Node?
}

let n = new Node(data: 123, next: none)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Since all user data is pointers, we can use the name of the type to mean &quot;pointer to this structured data&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;The next thing we noticed is that both lifetimes and inference for lifetimes becomes significantly simpler.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s take a variation of the example above:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;struct Node {
    data: i64
    next: Node?
}

fun do_this() {
    let n = new Node(data: 123, next: none)
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We can infer that the allocation that creates &lt;code&gt;new Node(...)&lt;&#x2F;code&gt; has a lifetime and what it is. Because this allocation never &quot;escapes&quot; the function - that is, it never leaves the function in any way - then we can call its lifetime &quot;Local&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;As we&#x27;ll find out, each of the lifetime possibities is a readable name that we can show the user in error messages. It also makes things significantly easier to teach.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s look at another example to see a different lifetime.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;struct Stats {
    age: i64
}

struct Employee {
    name: c_string,
    stats: Stats,
}

fun set_stats(mut employee: Employee) {
    employee.stats = new Stats(age: 33)
}

fun main() {
    mut employee = new Employee(name: c&amp;quot;Soph&amp;quot;, stats: new Stats(age: 22))
    set_stats(employee)
    println(employee.stats.age)
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;A bit of a longer example this time, but let&#x27;s focus on this function:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;fun set_stats(mut employee: Employee) {
    employee.stats = new Stats(age: 33)
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;What&#x27;s the lifetime of this &lt;code&gt;new Stats(..)&lt;&#x2F;code&gt; allocation? In this example, we do see the new pointer escape the function via a parameter. We can also give this a readable lifetime: &lt;code&gt;Param(employee)&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In all, we have three lifetimes an allocation can have:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Local&lt;&#x2F;li&gt;
&lt;li&gt;Param(xxxx)&lt;&#x2F;li&gt;
&lt;li&gt;Return&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;any-data-structure-you-want&quot;&gt;Any data structure you want&lt;&#x2F;h2&gt;
&lt;p&gt;Another big advantage of grouping our allocations is that we no longer have to worry about a drop order. This means we can think of the whole thing as dropping all at once. For large structures, that can be a speed-up over languages with a required drop order.&lt;&#x2F;p&gt;
&lt;p&gt;Additionally, we get another major benefit. We can now create arbitrary data structures.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;struct Node {
    data: i64
    next: Node?
}

mut node3 = new Node(data: 3, next: none)
let node2 = new Node(data: 2, next: node3)
let node1 = new Node(data: 1, next: node2)

node3.next = node1
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And just like that, we&#x27;ve made a circular linked list. Creating a similar example in Rust is certainly more of a challenge.&lt;&#x2F;p&gt;
&lt;p&gt;But, something fishy is going on here.&lt;&#x2F;p&gt;
&lt;p&gt;To make the above work, we&#x27;re using shared, mutable pointers. This is explicitly forbidden in Rust. Why is it okay here?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-dangers-of-shared-mutable-pointers&quot;&gt;The dangers of shared, mutable pointers&lt;&#x2F;h2&gt;
&lt;p&gt;Rust disallows holding two mutable references to the same memory location and for good reason. Well, multiple reasons actually.&lt;&#x2F;p&gt;
&lt;p&gt;First, having two copies of a mutable pointer where two separate threads each hold a copy means we have the possibility for a race condition. This can leave us with incoherent data that&#x27;s difficult to debug.&lt;&#x2F;p&gt;
&lt;p&gt;Second, even if these two multiple pointers are limited to the same thread, we get what we might call &quot;spooky action at a distance&quot;. The modification of one pointer is then visible to the holder of the other pointer, which might be far away from the source of the mutation.&lt;&#x2F;p&gt;
&lt;p&gt;For us to reasonably use shared, mutable pointers, we need to tame both of these. The first issue, the race condition, is easy enough: we prevent sending shared, mutable pointers between threads. This limits them to a single thread.&lt;&#x2F;p&gt;
&lt;p&gt;The second issue is decidedly harder. There have been many attempts at ways of handling this through rules enforced by the type system.&lt;&#x2F;p&gt;
&lt;p&gt;In June, we&#x27;re trying something a bit different. We&#x27;ll let developers use shared, mutable pointers, but then offer a &quot;carrot&quot; to opt-in to restrictions around using them. The carrot ends up pulling from a classic technique of software engineering: encapsulation.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-full-power-of-encapsulation&quot;&gt;The full power of encapsulation&lt;&#x2F;h2&gt;
&lt;p&gt;In traditional encapsulation, programmers make a kind of &quot;best effort&quot; to hide implementation details from the world around them. Keeping private state private grants the benefits of better code reuse, ease of updating implementation details, and more.&lt;&#x2F;p&gt;
&lt;p&gt;But as often is the case, if that kind of rule isn&#x27;t enforced, over time APIs get designed where internal implementation details leak out.&lt;&#x2F;p&gt;
&lt;p&gt;Something very interesting happens if we don&#x27;t allow this to happen. If an encapsulation can be checked by the compiler, and the compiler enforces that no private details leak, we have what you might call &quot;full encapsulation&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;These kinds of encapsulations wouldn&#x27;t allow any aliasing of pointers into them. They&#x27;d have their internal pointers fully isolated from the rest of the program.&lt;&#x2F;p&gt;
&lt;p&gt;Once we have this, some new capabilities start opening up:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;We can &quot;fence off&quot; our shared, mutable pointers, making it possible to create single-owner encapsulations that can be sent safely between threads.&lt;&#x2F;li&gt;
&lt;li&gt;We can lean people in the direction of cleaner API design, as now we have a way to truly keep private implementation details private.&lt;&#x2F;li&gt;
&lt;li&gt;We can handle some of the drawbacks of grouped allocations.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;What kind of drawbacks, you might ask? It&#x27;s high time we talked about them.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;drawbacks-of-grouped-allocations&quot;&gt;Drawbacks of grouped allocations&lt;&#x2F;h2&gt;
&lt;p&gt;If we go back to our earlier example and look carefully, we&#x27;ll notice something:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;fun set_stats(mut employee: Employee) {
    employee.stats = new Stats(age: 33)
}

fun main() {
    mut employee = new Employee(name: c&amp;quot;Soph&amp;quot;, stats: new Stats(age: 22))
    set_stats(employee)
    println(employee.stats.age)
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The question is: what happened to the &lt;code&gt;new Stats(age: 22)&lt;&#x2F;code&gt; allocation?&lt;&#x2F;p&gt;
&lt;p&gt;Remembering that June is a systems language, we can&#x27;t say &quot;the garbage collector handled it&quot; because we have no garbage collector. Nor can we say &quot;the refcount hit zero, so we reclaimed it&quot; as we don&#x27;t use refcounting. As a systems language, we can&#x27;t allow hidden or difficult-to-predict overhead to happen.&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s not actually leaked either, as even the memory it occupies will be reclaimed once the entire group is reclaimed. For all intents and purposes, though, it&#x27;s lost to the user until the group is no longer live. It&#x27;s a kind of &quot;memory bloat&quot; that happens if we group our allocations.&lt;&#x2F;p&gt;
&lt;p&gt;To handle this, we&#x27;ll need some way of recycling that memory. I say &quot;recycling&quot; specifically because in June we can&#x27;t free the memory, as the group is treated together as a single entity where all the allocations in the group are freed at once. If we instead recycle the memory, we can reuse that same memory while the group is live.&lt;&#x2F;p&gt;
&lt;p&gt;Techniques to do this have been around for decades, and often people use &quot;free lists&quot; to keep a list of nodes that have been recycled, so they can be reused when the next allocation happens.&lt;&#x2F;p&gt;
&lt;p&gt;The problem with free lists is that they aren&#x27;t safe. If you&#x27;re not careful, you&#x27;ll create a security vulnerability and&#x2F;or an incredibly hard bug to find.&lt;&#x2F;p&gt;
&lt;p&gt;Instead, we need to build in a safe way of recycling memory into the language.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;safe-memory-recycling&quot;&gt;Safe memory recycling&lt;&#x2F;h2&gt;
&lt;p&gt;Using the idea of full encapsulation from earlier, we can create &quot;fenced in&quot; sets of pointers that we know aren&#x27;t shared with the rest of the world. Once we have them, it&#x27;s possible to track the pointers inside. These pointers can get a &quot;copy count&quot;, so we know how many copies are live at any point in time (not dissimilar from a refcount, though this has no automatic reclamation).&lt;&#x2F;p&gt;
&lt;p&gt;Once we have a copy count for each internal pointer, we can give developers a built-in &lt;code&gt;recycle&lt;&#x2F;code&gt; command.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;let x = new Foo()
recycle x
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Recycling would start at the given pointer and would check the pointers reachable from it. Each pointer it finds that it can recycle would go into the safe free list.&lt;&#x2F;p&gt;
&lt;p&gt;You might wonder &quot;why not do this automatically?&quot;. There are a couple reasons:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The operation is linear time based on your transitively-reachable pointers. This means you may incur a noticeable overhead when recycling&lt;&#x2F;li&gt;
&lt;li&gt;Because of the first point, it&#x27;s important to make places where this occurs visible&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;If this sounds like a kind of manual garbage collection, you&#x27;re right. My collaborator Jane calls this &quot;semi-automatic&quot; memory reclamation. You ask once, and when you ask you get a kind of highly focused mark and sweep for that single pointer and the pointers reachable from it.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Note: this feature is not yet in the reference compiler. We&#x27;re hoping to implement it in the coming weeks.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;more-work-ahead&quot;&gt;More work ahead&lt;&#x2F;h2&gt;
&lt;p&gt;We have a way of simplifying lifetimes, making for readable code that people from various languages should be able to understand and use. We can also give clear, easy-to-understand lifetime errors when they arise.&lt;&#x2F;p&gt;
&lt;p&gt;Having safe memory recycling gives us a way to keep groups and still offer things like &lt;code&gt;delete&lt;&#x2F;code&gt; in a linked list abstraction. It&#x27;s convenient but not so automatic that we lose the visibility into the costs of memory management.&lt;&#x2F;p&gt;
&lt;p&gt;That said, there are still some challenge ahead that will need to be solved in the language design and tooling. For example, how do you know when the program is bloating memory? We&#x27;ll need some way of doing a memory trace when the program is running to detect this and warn the developer.&lt;&#x2F;p&gt;
&lt;p&gt;I see this in a way as a more incremental&#x2F;prototype-friendly way of development. June is always memory safe, but the first version of a program may not be as efficient as it could be in terms of memory usage. That&#x27;s a process we often go through as developers. First, we &quot;make it work&quot; before we &quot;make it good&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;In June, we keep it lightweight as we keep your programs memory safe, and then we provide tools and support for incrementally improving code.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;future-possibilities&quot;&gt;Future possibilities&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;relationship-to-rust&quot;&gt;Relationship to Rust&lt;&#x2F;h3&gt;
&lt;p&gt;June has a real opportunity to be a good complement to Rust. Rust&#x27;s focus on embedded and system&#x27;s development is a core strength. June, on the other hand, has a lean towards application development with a system&#x27;s approach. This lets both co-exist and offer safe systems programming to a larger audience.&lt;&#x2F;p&gt;
&lt;p&gt;An even better end state requires Rust to have a stable ABI. Once it does, June will be able to call into Rust crates to get the benefits of Rust&#x27;s substantial crate ecosystem. We&#x27;re looking forward to collaborating on this in the future.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;going-beyond-oop&quot;&gt;Going beyond OOP&lt;&#x2F;h3&gt;
&lt;p&gt;OOP has for decades been the way many applications are written, but it&#x27;s not without its flaws. Many OOP languages allow programmers to freely break good rules of thumb, like the Liskov substitution principle, or to create a mess of interwoven code between parent and child classes that&#x27;s difficult to maintain.&lt;&#x2F;p&gt;
&lt;p&gt;We&#x27;re currently investigating other ways of making code reuse easier, more modular, and more composible. We&#x27;re not quite ready to talk about this, though we hope to soon.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;exploring-related-work&quot;&gt;Exploring related work&lt;&#x2F;h3&gt;
&lt;p&gt;Over the years, there have been a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;verdagon.dev&#x2F;grimoire&#x2F;grimoire&quot;&gt;number of memory management techniques tried&lt;&#x2F;a&gt;, including many that lie outside of the ones commonly found in languages today. We&#x27;d like to explore these more deeply to see which, if any, may help June.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;acknowledgements&quot;&gt;Acknowledgements&lt;&#x2F;h2&gt;
&lt;p&gt;We had the help of dozens of experts in various fields as we brainstormed the initial design for June, and for their contributions, we&#x27;re thankful. We&#x27;d especially like to thank the collaborators who went above and beyond with their time across multiple brainstorming sessions to help June grow to where it is.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Andreas Kling&lt;&#x2F;li&gt;
&lt;li&gt;Doug Gregor&lt;&#x2F;li&gt;
&lt;li&gt;Jason Turner&lt;&#x2F;li&gt;
&lt;li&gt;Mads Torgersen&lt;&#x2F;li&gt;
&lt;li&gt;Mae Milano&lt;&#x2F;li&gt;
&lt;li&gt;Steve Francia&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Also, special thanks to our private beta testers for testing out June and giving us feedback.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;checking-it-out&quot;&gt;Checking it out&lt;&#x2F;h2&gt;
&lt;p&gt;Documentation on the June language and the June reference compiler are now available via the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sophiajt&#x2F;june&quot;&gt;June repo&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Please note: the reference compiler is pre-alpha quality.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Worst part of being trans</title>
        <published>2024-03-25T00:00:00+00:00</published>
        <updated>2024-03-25T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/worst-part-of-being-trans/"/>
        <id>https://www.sophiajt.com/worst-part-of-being-trans/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/worst-part-of-being-trans/">&lt;p&gt;I&#x27;m sitting here, reading a book, thinking about the road ahead for me as a trans woman. It feels like I can already tell what&#x27;s likely the worst part of being trans, at least so far.&lt;&#x2F;p&gt;
&lt;p&gt;You might think it&#x27;s the bullying. I definitely experienced some of that.&lt;&#x2F;p&gt;
&lt;p&gt;Or maybe it&#x27;s friction with the family. I definitely experienced that, too.&lt;&#x2F;p&gt;
&lt;p&gt;For me, though, the worst part is time.&lt;&#x2F;p&gt;
&lt;p&gt;Estrogen does what it does. And then you wait.&lt;&#x2F;p&gt;
&lt;p&gt;I got hair replacement surgery. It takes months to even start growing. And then you wait.&lt;&#x2F;p&gt;
&lt;p&gt;Start a series of electrolysis, going regularly. And then you wait (and keep going until it&#x27;s done).&lt;&#x2F;p&gt;
&lt;p&gt;Schedule surgeries. And then you wait.&lt;&#x2F;p&gt;
&lt;p&gt;Recover from those surgeries. And recovery takes time. So you wait.&lt;&#x2F;p&gt;
&lt;p&gt;The trick is to learn how to be good at waiting. I&#x27;ll admit, I kinda suck at it. I&#x27;ve been checking my head everyday to see if I can see changes. I don&#x27;t recommend this.&lt;&#x2F;p&gt;
&lt;p&gt;For a while there I was measuring my chest almost every day. I don&#x27;t recommend this, either.&lt;&#x2F;p&gt;
&lt;p&gt;I guess the lesson I&#x27;m trying to learn here is to ignore it. I&#x27;ll still very likely be on this path tomorrow. And the next week. And the next month. It&#x27;s perfectly okay not to watch the grass grow and just be myself and see how things are coming along later. Just find a rhythm, don&#x27;t stress.&lt;&#x2F;p&gt;
&lt;p&gt;Still, that desire to have the magic button you can press and then wake up fully-transitioned is so strong. Or a button that if you press it you can jump ahead 6 months each time you press it.&lt;&#x2F;p&gt;
&lt;p&gt;We get the days we get. It&#x27;s up to us to make the most of them. And, if I&#x27;m honest with myself, it&#x27;s up to us to not fill them with stress about what happens today or tomorrow.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m learning. I&#x27;ll get there. But it&#x27;s going to take some practice.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>One year on HRT</title>
        <published>2024-03-23T00:00:00+00:00</published>
        <updated>2024-03-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/one-year-on-hrt/"/>
        <id>https://www.sophiajt.com/one-year-on-hrt/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/one-year-on-hrt/">&lt;p&gt;Today marks one year on HRT. A year ago, I remember nervously sitting across from my doctor as she typed up the script that I&#x27;d pick up minutes later. I remember the fear of getting started, the trepidation of putting new chemicals into my body with unknown consequences. Along with that fear, a kind of hope also dared to show its head. What if HRT was good for me? What if it helped?&lt;&#x2F;p&gt;
&lt;p&gt;A year later, I can look back and say without any hesitation that going on HRT was one of the best decisions I&#x27;ve ever made.&lt;&#x2F;p&gt;
&lt;p&gt;In this post, I share my reasons why. I don&#x27;t mean for this post to be any kind of medical advice for anyone else. Rather, I&#x27;d like it to be a record for other folks who are curious about the journey.&lt;&#x2F;p&gt;
&lt;p&gt;For me, HRT has affected a lot of how my body and mind work, so I&#x27;m going to try to create different sections to cover the different kinds of changes I see.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;mind-changes&quot;&gt;Mind changes&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;mental-calm&quot;&gt;Mental calm&lt;&#x2F;h3&gt;
&lt;p&gt;I mentioned in &lt;a href=&quot;..&#x2F;happy-pride-im-trans&quot;&gt;Happy Pride, I&#x27;m trans&lt;&#x2F;a&gt; that the early changes to the brain were eye-opening. I felt a sense of pleasant calm. The background static in my brain went down in volume, and I felt a kind of openness. I wasn&#x27;t sure at the time if this would continue, and I&#x27;m happy to report it has.&lt;&#x2F;p&gt;
&lt;p&gt;If HRT only did this part and nothing else, it would be well worth it.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;mood&quot;&gt;Mood&lt;&#x2F;h3&gt;
&lt;p&gt;I&#x27;ve been tracking my mood everyday for over an year now. It&#x27;s great data to see that my mental health is indeed quite a bit better. I still have bad days, to be sure, but my overall mood is quite a bit better than it was before I started HRT.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;access-to-emotions&quot;&gt;Access to emotions&lt;&#x2F;h3&gt;
&lt;p&gt;This one gets talked about quite a bit in regard to HRT. You cry a lot more. Like, a &lt;em&gt;lot&lt;&#x2F;em&gt; more. That&#x27;s not a universally true thing, but does seem to be quite common.&lt;&#x2F;p&gt;
&lt;p&gt;I now keep a box of tissues where I&#x27;m reading or watching tv because at any point something might catch me. Crying can be a few tears or it can last for many hours or anything in-between.&lt;&#x2F;p&gt;
&lt;p&gt;More than just feeling sadness more clearly, I feel everything more clearly. If I want to sit and reflect on how I feel about something, I can. Those feelings are things I can access and explore. When I was working my way to coming out as a trans woman, I spent a lot of time &quot;peeling the onion&quot; while exploring my inner world. It meant feeling my way through some pretty uncomfortable feelings, but I have no doubt HRT was making things visible that I wouldn&#x27;t have been able to easily see and feel before.&lt;&#x2F;p&gt;
&lt;p&gt;On a related note, the biggest of the emotional changes for me has definitely been the head-to-heart connection, so let&#x27;s talk about the heart changes.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;heart-changes&quot;&gt;Heart changes&lt;&#x2F;h2&gt;
&lt;p&gt;I&#x27;ve asked around to a few of my trans femme friends if they&#x27;ve experienced what I&#x27;m about to talk about in this section. To date, I haven&#x27;t met anyone else who has. There are a few theories here that&#x27;ll share at the end of the section, but first let me just write down what I experienced.&lt;&#x2F;p&gt;
&lt;p&gt;At about the 6 month mark, I started consuming trans and sapphic book content. Much of what I read were romances. It was like I couldn&#x27;t get enough of them.&lt;&#x2F;p&gt;
&lt;p&gt;I didn&#x27;t think much of it, it was just hitting the right buttons, so I was going with it.&lt;&#x2F;p&gt;
&lt;p&gt;Then, I noticed I was feeling this tug in my heart as I read the stories. At first, it was noticeable but not terribly strong, and then it got stronger. I started pulling for these women to get together and felt joy when they did.&lt;&#x2F;p&gt;
&lt;p&gt;This went on for months. It was like having a very personal conversation with my heart.&lt;&#x2F;p&gt;
&lt;p&gt;You see, for my adult life up until taking HRT I&#x27;d dated dozens of people, but if I&#x27;m being really honest with myself, I have to admit I never fell in love with any of them. I&#x27;ll go a step further and say I&#x27;m not even sure I had the capacity to. I remember years ago wondering to myself if I was aromantic. That maybe I just wasn&#x27;t wired for the romance part and that staying in a relationship long-term was something that wasn&#x27;t natural to me.&lt;&#x2F;p&gt;
&lt;p&gt;Fast forward to October of last year where I&#x27;m lying on the couch, bawling my eyes out at some novel I just finished, going through tissue after tissue because my heart just felt like it was overflowing.&lt;&#x2F;p&gt;
&lt;p&gt;Something had changed.&lt;&#x2F;p&gt;
&lt;p&gt;In the past year, I had other firsts. My first crush on HRT felt nothing like I&#x27;ve ever experienced before. It was like a bowling ball compared to what I had before, which was more like a marble. The intensity, the overwhelm, and the sheer hyperfocus had me begging for some kind of escape by the end. When I compared notes with my close friends, their help amounted to &quot;welcome to being a girl and having a girl crush. Remember to breathe.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;Something had definitely changed.&lt;&#x2F;p&gt;
&lt;p&gt;Somehow, my brain and heart had &quot;rewired&quot;. In chatting with other trans folks, we came up with two possible reasons why it was happening:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;HRT is having some kind of mood-altering effect that is giving me access to my romantic side in a way I could not access before.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;or&lt;&#x2F;p&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;By transitioning, I&#x27;m now more comfortable in my body. As a result, I&#x27;m open to feeling romantic in a way I wasn&#x27;t before. This is because I can actually share my real self with others.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Whether it&#x27;s #1 or #2, or even some unknown #3 option, I don&#x27;t know.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sexuality-changes&quot;&gt;Sexuality changes&lt;&#x2F;h2&gt;
&lt;p&gt;I&#x27;d been warned that this could happen.&lt;&#x2F;p&gt;
&lt;p&gt;First off, this year I went through an expected dip in sex drive. Right after starting HRT and blocking my T, my sex drive vanished. It was almost completely gone for about 8-9 months.&lt;&#x2F;p&gt;
&lt;p&gt;When it came back, I was different. Everything about my sexuality felt different.&lt;&#x2F;p&gt;
&lt;p&gt;How do I even explain. Let me explain this by talking about the obvious one first.&lt;&#x2F;p&gt;
&lt;p&gt;When the libido returned, I&#x27;d lost all interest in anything other than queer relationships. Before HRT, I was pansexual. I could happily enjoy various straight and queer content. Afterward, I just had no interest in cis straight anything.&lt;&#x2F;p&gt;
&lt;p&gt;As I explored a bit and let things settle down it became clear that I&#x27;m a lesbian. I might find other things interesting, but when I asked myself what I wanted, I had no doubts.&lt;&#x2F;p&gt;
&lt;p&gt;As a side note: it reminded me of being in my 20s watching L Word for the first time going &quot;wow, why does this make so much sense to me?&quot;. You poor egg you. At least now I know why.&lt;&#x2F;p&gt;
&lt;p&gt;Other things related to sexuality have also changed. I won&#x27;t go into a lot of details here, but I&#x27;ll mention that being attracted to another person isn&#x27;t largely a visual thing anymore. It is much more sensual and about the connection to the other person and wanting to feel closer to them.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;relationship-changes&quot;&gt;Relationship changes&lt;&#x2F;h2&gt;
&lt;p&gt;Oh I love this part. My connection to my friends has deepened noticeably. When we spend time sharing heart-to-heart about something, we can go to a much more satisfying place, making room for uncomfortable emotions and feelings to be talked about.&lt;&#x2F;p&gt;
&lt;p&gt;In short, the level of intimacy possible is deeper and more nourishing.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;romantic-relationship-changes&quot;&gt;Romantic relationship changes&lt;&#x2F;h2&gt;
&lt;p&gt;I&#x27;m writing this section as a bit of a placeholder, as I&#x27;m not yet ready to fill it in. I&#x27;m curious if other things have changed. Before HRT, I&#x27;d spent the last few decades monogamous. Now, with the connection to my heart being so different, I&#x27;m not sure where I fall. To know, I&#x27;ll have to experiment.&lt;&#x2F;p&gt;
&lt;p&gt;The more fundamental shift is being ready to be in relationships again. I&#x27;d checked out of them for the three years leading up to HRT so that I could figure out what was going on. Coming to the conclusion that I&#x27;m trans and needed to start that journey explained quite a lot of things.&lt;&#x2F;p&gt;
&lt;p&gt;What will relationships look like now? I&#x27;m eager to find out.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;body-changes&quot;&gt;Body changes&lt;&#x2F;h2&gt;
&lt;p&gt;Yeah, this is a big one for a lot of folks. Estrogen does whatever it does, and you get whatever it gives you. Everyone seems to be different. Here&#x27;s what I got:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Skin: Wow, very little psoriasis now. Also more and more my skin is getting softer and nicer to touch.&lt;&#x2F;li&gt;
&lt;li&gt;Breasts: Currently 38D in the American system. They are perky. I&#x27;m eager for them to fill out a bit. Also, I&#x27;m regularly tender. It&#x27;s something I have to be careful of.&lt;&#x2F;li&gt;
&lt;li&gt;Hips: At around the 11 month mark, my hips shifted. This changes your gait, giving you more swing in the hips as you walk. It also changes your body to make your hips a bit more pronounced.&lt;&#x2F;li&gt;
&lt;li&gt;Temperature regulation: What temperature regulation? E giveth and E taketh away.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;voice-changes&quot;&gt;Voice changes&lt;&#x2F;h2&gt;
&lt;p&gt;Haha, if only HRT helped with this. It sadly does not. I have been practicing regularly for the last 6 months, which has helped a bunch. But wow, it&#x27;s work work work.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;passing&quot;&gt;Passing&lt;&#x2F;h2&gt;
&lt;p&gt;An earlier draft of this post didn&#x27;t include this section, but after writing it and having breakfast, I wanted to say something here. HRT does not allow me to be read as a woman. It&#x27;s done many things to make parts of me more feminine, but I&#x27;ve never once been correctly gendered in public.&lt;&#x2F;p&gt;
&lt;p&gt;For some trans women, they&#x27;re lucky in that regard. After a few months on HRT, their already-feminine features are enough with a bit of help to appear feminine enough to be regularly gendered correctly.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m on the other end. My face is a bit androgynous naturally, but things like my baldness, and perhaps other characteristics like shoulders, will lead me to be read as masculine.&lt;&#x2F;p&gt;
&lt;p&gt;My goal in this regard is to be a trans woman. What I am as a trans woman. To be myself, basically, and to grow and change to be more myself. To do that, rather than to try to fit into a box that wasn&#x27;t made for me. If at some point in the future, I happen to fit into such a box, then it will be a happy accident.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;worth-it&quot;&gt;Worth it&lt;&#x2F;h1&gt;
&lt;p&gt;HRT has been without a doubt thoroughly worth it. I&#x27;m healthier. I&#x27;m heading in a healthier direction. My connections to my friends has gotten deeper. My connection to my inner world has likewise also gotten deeper.&lt;&#x2F;p&gt;
&lt;p&gt;I can&#x27;t imagine ever going back. I feel like I stepped through a portal and behind me a set of doors closed. In front of me, a set of new doors opened.&lt;&#x2F;p&gt;
&lt;p&gt;I can&#x27;t wait to explore the doors ahead.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Books read in 2023</title>
        <published>2023-12-31T00:00:00+00:00</published>
        <updated>2023-12-31T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/books-read-in-2023/"/>
        <id>https://www.sophiajt.com/books-read-in-2023/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/books-read-in-2023/">&lt;p&gt;2023 was the year I managed to rediscover my love of books and reading. Once I got turned on to the array of trans and sapphic books available, it was like I couldn&#x27;t get enough.&lt;&#x2F;p&gt;
&lt;p&gt;Below is the list of the books I read this year, sorted by author, loosely in the order I read them.&lt;&#x2F;p&gt;
&lt;p&gt;One note before I begin: a lot of the books below deal with trauma of some form or another. If you&#x27;re sensitive to this, please look into the book you&#x27;re interested in first.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;stephen-king&quot;&gt;Stephen King&lt;&#x2F;h2&gt;
&lt;p&gt;Before we get into the trans&#x2F;sapphic stuff, the first author I turned to this year was Stephen King. This is largely because in &lt;a href=&quot;..&#x2F;youtube-addiction&quot;&gt;recovering from online addiction&lt;&#x2F;a&gt;, I wanted to read through stories of other people dealing with addiction. I ended up picking three Stephen King books.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;misery&quot;&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;10614.Misery&quot;&gt;Misery&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;This is the main book King cites when he mentions books he&#x27;s written about addiction. According to him, this book is about his struggle with cocaine.&lt;&#x2F;p&gt;
&lt;p&gt;Perhaps so, but the interplay at the heart of this book is definitely the reason to read it. It&#x27;s so tense, and it works really well.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;christine&quot;&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;10629.Christine&quot;&gt;Christine&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Addiction to independence, maybe? I remembered this story fondly though after reading it I think I may have preferred the movie more.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-shining&quot;&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;11588.The_Shining&quot;&gt;The Shining&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Addiction to spirits. Interesting book - I think this was the first time I&#x27;d read it, despite having seen the movie a handful of times.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;april-daniels&quot;&gt;April Daniels&lt;&#x2F;h2&gt;
&lt;p&gt;Now we get into the trans and sapphic books. April was the first trans author I read. She wrote two books about a trans superhero. After I read those, I was hooked and kept looking for more.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;dreadnought-and-sovereign&quot;&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;30279514-dreadnought&quot;&gt;Dreadnought&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;32565582-sovereign&quot;&gt;Sovereign&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;A two book series about a trans superhero. April doesn&#x27;t shy away from some harsh topics and situations, giving the stories quite a bit of grit in parts. The end of the second book, Sovereign, definitely had me wanting more in the series.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sakaomi-yuzaki&quot;&gt;Sakaomi Yuzaki&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;she-loves-to-cook-and-she-loves-to-eat-vol-i-iii&quot;&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;series&#x2F;333505&quot;&gt;She Loves To Cook, and She Loves To Eat (Vol I-III)&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;I didn&#x27;t read much manga this year, but this was a fun read that deals with aro(?) connection between two women and how they discover who they are and what they want together.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;meredith-russo&quot;&gt;Meredith Russo&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;if-i-was-your-girl&quot;&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;26156987-if-i-was-your-girl&quot;&gt;If I Was Your Girl&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Coming of age story about a trans girl. Not bad though I think I prefer Russo&#x27;s follow up book, which is...&lt;&#x2F;p&gt;
&lt;h3 id=&quot;birthday&quot;&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;39863399-birthday&quot;&gt;Birthday&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;If people are looking for a good young adult (YA) coming of age&#x2F;coming out story with a bit of a romantic twist, this is one of the books I&#x27;d hand them. It&#x27;s solid, deals with some real issues, and pulled me along to the end.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;julie-anne-peters&quot;&gt;Julie Anne Peters&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;luna&quot;&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;316445.Luna&quot;&gt;Luna&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;I... did not like this one. It doesn&#x27;t feel like a relatable trans experience. The main character, Luna, feels drawn from details that matched more closely to maybe female impersonators rather than being trans.&lt;&#x2F;p&gt;
&lt;p&gt;Still, it&#x27;s no doubt remarkable both for its age and for the fact it was a trailblazer as the first mass market YA book with a trans main character.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;vyria-durav&quot;&gt;Vyria Durav&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;the-hatchling&quot;&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;61198898-the-hatchling&quot;&gt;The Hatchling&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;This book initially felt like it was for a YA audience. All up, not a bad first effort, but truly overshadowed by Vyria&#x27;s follow-up effort...&lt;&#x2F;p&gt;
&lt;h3 id=&quot;catnip&quot;&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;61937916-catnip&quot;&gt;Catnip&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;My god, this book is so good. It&#x27;s like a warm bath in trans-affirming goodness. I&#x27;ve read it twice so far and no doubt will read it again soon.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;molly-j-bragg&quot;&gt;Molly J. Bragg&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;heart-of-heroes-series-scatter-transistor-aether&quot;&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;series&#x2F;340988-hearts-of-heroes&quot;&gt;Heart of Heroes series (Scatter, Transistor, Aether)&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;This three book series is tied together with recurring characters though each book is very distinct tonally and thematically from each other. Of the three, I think I liked the first one the best because of the focus and the mind-bending romance&#x2F;erotica.&lt;&#x2F;p&gt;
&lt;p&gt;Transistor is also notable for having a trans main character.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;blood-of-the-basilisk&quot;&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;63210099-blood-of-the-basilisk&quot;&gt;Blood of the Basilisk&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Loved this one. Slow burn sapphic romance with an adorable dragon makes this one a clear fave of the year.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;mail-order-bride&quot;&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;60675530-mail-order-bride&quot;&gt;Mail Order Bride&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;My god, this book is cute. Wholesome sapphic romance in space. I finished it and was so sad that it was over I just started re-reading it immediately. I wish Molly had more with these characters.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-inevitable-singularity&quot;&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;175418285-the-inevitable-singularity&quot;&gt;The Inevitable Singularity&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;I... wasn&#x27;t so sure about this one. It has elements of romance, though the main threads revolves around prophesy, predestination, and a kind of psychic-meets-pseudoscience fabric woven throughout. At times I found it difficult to read, both because of the density of what was being described but also because giving too much of the future plot away ruins a bit of the book&#x27;s magic.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;tiffany-e-taylor&quot;&gt;Tiffany E. Taylor&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;coven&quot;&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;152201469-coven&quot;&gt;Coven&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Please avoid. I... yeah, it just reads too much like it was written in the 90s without any of the benefit of modern thought. Was not my thing.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;akwaeke-emezi&quot;&gt;Akwaeke Emezi&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;pet&quot;&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;43568395-pet&quot;&gt;Pet&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;There are a small handful of masterworks on my list, and this is one of them. I&#x27;ve recommended it to friends and family.&lt;&#x2F;p&gt;
&lt;p&gt;I &lt;em&gt;think&lt;&#x2F;em&gt; to get the most out of it you need to have been brought up religious, but I don&#x27;t think that&#x27;s a requirement. It&#x27;s written with beautiful prose with a lovely handling of trans-affirmation in the near-future.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;casey-plett&quot;&gt;Casey Plett&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;a-safe-girl-to-love&quot;&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;22050397-a-safe-girl-to-love&quot;&gt;A Safe Girl to Love&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;A collection of short stories. I found them to be a bit too focused on 20-somethings by a 20-something to be really relatable.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;a-dream-of-a-woman&quot;&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;57286652-a-dream-of-a-woman&quot;&gt;A Dream of a Woman&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Seven years later, and her powers as an author are noticeably sharper. Her themes more on point and more mature. It feels like she&#x27;s reaching to learn and yet be honest with the journey.&lt;&#x2F;p&gt;
&lt;p&gt;The stories in this one are also much more relatable. The first story in the collection, Hazel &amp;amp; Christopher, is worth the price of the book alone.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;alison-rumfitt&quot;&gt;Alison Rumfitt&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;brainwyrms&quot;&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;65212043-brainwyrms&quot;&gt;Brainwyrms&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Not a fan of this one. It felt too much like a trans remix of Things Have Gotten Worse Since Last We Spoke. Some good ideas here and there but tried far too hard to be edgy for me.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;silvia-shaw&quot;&gt;Silvia Shaw&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;rand-books-1-2-and-4&quot;&gt;Rand books &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;series&#x2F;340315-imperial-rand&quot;&gt;1, 2&lt;&#x2F;a&gt;, and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;series&#x2F;375428-shadow-makers&quot;&gt;4&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Yes, you read that correctly. I accidentallly read these out of order. In my defence, the fourth book says &quot;Book 1&quot; on the cover and is indeed the first book of a new series in the same world as the original series.&lt;&#x2F;p&gt;
&lt;p&gt;These are solidly plotted, well-written sapphic fantasy novels. I&#x27;m looking forward to getting back around and reading the 3rd one when the mood hits. Of the ones I&#x27;ve read so far, I think the 4th book (Daughter of the Light) was the best.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;issy-waldrom-and-mackenzie-sutton&quot;&gt;Issy Waldrom and Mackenzie Sutton&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;best-friends-promise&quot;&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;193789338-best-friends-promise&quot;&gt;Best Friends&#x27; Promise&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Trans sapphic vampire romance. It&#x27;s exactly what it says on the cover. An enjoyable ride, and one that I recently re-read and still enjoyed.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;ela-bambust&quot;&gt;Ela Bambust&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;any-other-name&quot;&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;61143642-any-other-name&quot;&gt;Any Other Name&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Loved this one. Magic school meets Beetlejuice in a trans&#x2F;queer-affirming way? Yes, please. Tightly plotted and well-written.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-principles-of-non-euclidean-romance&quot;&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;75539335-principles-of-non-euclidean-romance&quot;&gt;The Principles of Non-Euclidean Romance&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;One part Groundhog Day, one part eldritch-flavoured romance? I have no idea how to describe this. I liked some parts more than others, though I think preferred the tighter feel of Any Other Name over this one.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rosemary-kirsten&quot;&gt;Rosemary Kirsten&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;the-steerswoman&quot;&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;793297.The_Steerswoman&quot;&gt;The Steerswoman&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Wow, we actually took a quick detour away from trans and sapphic books for a minute to read this one because friends kept asking us what we thought.&lt;&#x2F;p&gt;
&lt;p&gt;I think my short summary is: it&#x27;s well done. It&#x27;s nice that it has some clearly autistic spectrum characters in it, and their unique view of the world matters deeply. I just found myself wishing that there was more queerness among the characters.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;maria-ying&quot;&gt;Maria Ying&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;the-grace-of-sorcerers&quot;&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;60665292-the-grace-of-sorcerers&quot;&gt;The Grace of Sorcerers&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;This took me a couple tries to fall into, but after I did was richly rewarding. The prose is stellar, and the characters build as you progress.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;andrew-joseph-white&quot;&gt;Andrew Joseph White&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;the-spirit-bares-its-teeth&quot;&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;89144437-the-spirit-bares-its-teeth&quot;&gt;The Spirit Bares Its Teeth&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;My god. Here&#x27;s another masterwork. That&#x27;s not to say it&#x27;ll be an easy read for anyone. Andrew is steeped in the dark Southern history of literature, and it&#x27;s pretty clear. I&#x27;m actually speechless as I write this, as I truly have no idea how I might do this book justice.&lt;&#x2F;p&gt;
&lt;p&gt;If you can make your way through it, I think the book richly pays for your investment. Especially, after the end when you find out what the book is based on. That killed me. I just walked around the house in a daze.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;kai-cheng-thom&quot;&gt;Kai Cheng Thom&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;falling-back-in-love-with-being-human&quot;&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;63018965-falling-back-in-love-with-being-human&quot;&gt;Falling Back in Love with Being Human&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;I laughed. I cried. I... honestly just wanted to take Kai out for coffee after reading this. Just to sit across the table from someone else who wanted to marry being honest about pain with desperately looking to find ways to forgive and heal.&lt;&#x2F;p&gt;
&lt;p&gt;The book is made up of letters to various people who had done harmful things in Kai&#x27;s life, including to people like Jesus and JK Rowling. At times poetic, it flows from the heart with a keen edge.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;mel-e-lemon&quot;&gt;Mel E. Lemon&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;violet-moon&quot;&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;200236067-violet-moon&quot;&gt;Violet Moon&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Slow burn werewolf sapphic romance. I&#x27;m looking forward to reading more in the series as they become available.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;zoe-storm&quot;&gt;Zoe Storm&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;the-bradford-mckinley-chronicles-books-1-4&quot;&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;series&#x2F;347352-the-bradford-mckinley-chronicles&quot;&gt;The Bradford McKinley Chronicles (books 1-4)&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Zoe is one of my go-to authors for coming of age&#x2F;coming out trans books. These are the kinds of books I would hand other newly-out trans folks, or folks who are questioning whether or not they&#x27;re trans.&lt;&#x2F;p&gt;
&lt;p&gt;The 4th book in the series especially is quite good. It deals more directly with dysphoria and how to work through it, and for that reason alone will be something I recommend to others as they deal with their own dysphoria.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-enchanted-forest&quot;&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;202031416-the-enchanted-forest-and-other-stories&quot;&gt;The Enchanted Forest&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;A collection of five trans-focused short stories. Some of these stories, like the vampire-themed one, really feel like they want to grow to be their own larger work.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;avery-arden&quot;&gt;Avery Arden&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;blood-mistress-1-2-3&quot;&gt;Blood Mistress (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;58475308-claimed-by-the-countess&quot;&gt;1&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;58656312-collared-by-the-countess&quot;&gt;2&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;60626131-changed-by-the-countess&quot;&gt;3&lt;&#x2F;a&gt;)&lt;&#x2F;h3&gt;
&lt;p&gt;So you say the other things I have listed so far are a bit tame? You want something a bit spicier? Yes, come feast at this three novella set (which I think of as one novel). Spicy sapphic vampire erotica with heart. The third book especially definitely fills out this world and makes it more alive, which I enjoyed.&lt;&#x2F;p&gt;
&lt;p&gt;Oh, and it actually emphasises consent. Thank goodness.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sd-simper&quot;&gt;SD Simper&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;carmilla-and-laura&quot;&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;42602313-carmilla-and-laura&quot;&gt;Carmilla and Laura&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;I loved this. More vampire goodness. Honestly, it feels like the third masterwork in our list. It so deftly allows the readers to watch the characters grow, come into their own, and discover themselves. It&#x27;s erotic but also has so much heart to go along with it. Definitely one I&#x27;m looking forward to re-reading.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;may-peterson&quot;&gt;May Peterson&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;calyx-charm&quot;&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;55509324-the-calyx-charm&quot;&gt;Calyx Charm&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;I saw this book called out by a few folks as one of their faves. I was quite a bit more mixed on it. I struggled with the narration style through a lot of the book, as the plot would slip from present day, to past, to possible future without much indication as to where you were.&lt;&#x2F;p&gt;
&lt;p&gt;That said, it has by far some of the hottest trans erotic scenes I read this year.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;elena-abbott-lily-hardt&quot;&gt;Elena Abbott&#x2F;Lily Hardt&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;pack-of-her-own-and-mate-of-her-own&quot;&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;63947982-pack-of-her-own&quot;&gt;Pack of Her Own&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;123104027-mate-of-her-own&quot;&gt;Mate of Her Own&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Elena&#x27;s werewolf series with strong trans representation and sapphic romance&#x2F;erotic elements. I quite enjoyed this, though I&#x27;d recommend spacing them out a bit. Elena isn&#x27;t afraid of dealing with different aspects of trauma in her work, and I definitely noticed feeling overwhelm after I finished the second book.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;need-as-lily-hardt&quot;&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;book&#x2F;show&#x2F;60402885-need&quot;&gt;Need (as Lily Hardt)&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;BDSM and trans? Yes. Dealing with internalised trauma? That, too. This book is erotic but it&#x27;s really more about healing.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;that-s-wrap&quot;&gt;That&#x27;s wrap&lt;&#x2F;h2&gt;
&lt;p&gt;And that&#x27;s it for my list. If any of you have reading recommendations that fall along with this list, let me know! I got turned on to a lot of authors that I&#x27;ll be watching in the coming year(s).&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Becoming Sophia</title>
        <published>2023-12-08T00:00:00+00:00</published>
        <updated>2023-12-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/becoming-sophia/"/>
        <id>https://www.sophiajt.com/becoming-sophia/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/becoming-sophia/">&lt;p&gt;I started thinking this year what a &quot;Year in Review&quot; might look like, but to be honest, I&#x27;ve had one bright theme running through it that I kept coming back to: being trans. This post then will be some reflections of the year with that in mind.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;getting-clean&quot;&gt;Getting clean&lt;&#x2F;h2&gt;
&lt;p&gt;The year started off with me realising I had a &lt;a href=&quot;..&#x2F;youtube-addiction&quot;&gt;massive YouTube addiction&lt;&#x2F;a&gt; and facing it head-on. This helped me put to rest a struggle I&#x27;d had for 12 years. I could tell that I&#x27;d been using the addiction to numb something painful, but since I kept numbing, I wasn&#x27;t able to figure out what it was.&lt;&#x2F;p&gt;
&lt;p&gt;My goal after getting clean was to figure out what I&#x27;d been so desperate to numb.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;looking-in-a-mirror&quot;&gt;Looking in a mirror&lt;&#x2F;h2&gt;
&lt;p&gt;Between January and March, I did a lot of soul-searching. Actually, that was a big theme this year. I tried whenever I could to reach far back into my life and connect to younger versions of myself, to ask them what they needed, and to see if I could meet them in the present day.&lt;&#x2F;p&gt;
&lt;p&gt;One way I started doing this might sound a bit silly: every day, I turned my phone to selfie mode, looked at myself, and repeated &quot;I love you&quot; until I could feel something. At first, I just felt stupid, but I kept going because I knew that if I wasn&#x27;t going to be my own advocate and my own support, I was just going to fall back into addiction and lose sight of actually trying to take care of myself.&lt;&#x2F;p&gt;
&lt;p&gt;I didn&#x27;t feel any changes from doing this daily practice, but I kept going. I figured if it did anything, it&#x27;d take a long time. While I didn&#x27;t feel any different, in hindsight I can safely say that it was doing something. It was getting me to see myself as a person worthy of protecting and supporting.&lt;&#x2F;p&gt;
&lt;p&gt;That plus doing the &quot;eat the frog&quot; practice of making a list of things you&#x27;re avoiding&#x2F;afraid of and then one by one going after them let me slowly move away from hiding from myself, to working on myself.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;hormones&quot;&gt;Hormones&lt;&#x2F;h2&gt;
&lt;p&gt;By March, I&#x27;d &lt;a href=&quot;..&#x2F;happy-pride-im-trans&quot;&gt;started hormones&lt;&#x2F;a&gt;. I&#x27;ll let the post talk about the benefits of going on hormones for me, but it opened my eyes to feeling noticeably better than I ever have. It wasn&#x27;t just in my head, either. I had been using &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.moodflow.co&#x2F;&quot;&gt;moodflow&lt;&#x2F;a&gt; to track my mood every day for months before starting hormones, and you can watch the shift happen around March. My mood significantly got better and stayed better after March.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;covid&quot;&gt;COVID&lt;&#x2F;h2&gt;
&lt;p&gt;This July was the first time I&#x27;ve ever gotten COVID, and it hit me pretty hard. I spent weeks barely able to get off the couch. At one point in those weeks, I got up and made it to the laptop at the kitchen table and quickly typed up a list of things I wanted to do with my life. When I was done, there were only two items on it:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Have a healthy transition&lt;&#x2F;li&gt;
&lt;li&gt;Finish &quot;secret project&quot;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;I&#x27;m not talking about #2, yet, so let&#x27;s talk about #1. I was just shocked looking at it I only really cared to focus long-term energy in two places, especially when my energy was so low (at the time). As I started recovering, I dove further into transition. How to do it, but also, searching to understand what I wanted. Up to this point I thought &quot;oh, I&#x27;ll just get on hormones&quot; and not think too hard about what happens after that. After getting COVID, I knew it meant far more to me than that.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rekindling-my-love-of-books&quot;&gt;Rekindling my love of books&lt;&#x2F;h2&gt;
&lt;p&gt;On a whim, I start picking up trans YA (young adult) books. I couldn&#x27;t tell you exactly why, other than I wanted something to read and seeing what was available sounded fun. This sent me deep down the rabbit hole. Now, dozens of books later, I can say that I&#x27;ve had quite the journey with not only trans YA books but trans books generally. I&#x27;ve laughed, cried, and saw parts of myself that I&#x27;d tried to keep safely hidden since I was 5-6 years old.&lt;&#x2F;p&gt;
&lt;p&gt;Before I move on, here are some of my current recommendations (this set is all YA or YA-adjacent):&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Birthday, A Novel by Meredith Russo - a read a few trans coming of age&#x2F;coming out books, and this one stood out to me.&lt;&#x2F;li&gt;
&lt;li&gt;Dreadnaught and Sovereign by April Daniels - Two book series about a trans superhero.&lt;&#x2F;li&gt;
&lt;li&gt;Pet by Akwaeke Emezi - Trans protagonist, near-future with a fantastical twist.&lt;&#x2F;li&gt;
&lt;li&gt;Any Other Name by Ela Bambust - Magic school meets a bit of Beetlejuice. Bonus: see how many digs against JKR&#x27;s world you can find 🙂&lt;&#x2F;li&gt;
&lt;li&gt;Bradford McKinley Chronicles by Zoe Storm - Easy to read set of coming out&#x2F;trans-focused books. The 4th in the series is surprisingly good.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;love-and-support&quot;&gt;Love and support&lt;&#x2F;h2&gt;
&lt;p&gt;In October, a dear friend of mine came to visit. By this time, I knew I was a trans woman but was only out to a few friends. She took me shopping, gave me loads of hand-me-down outfits, and just generally was a dear support during the week she was here. While she was here, I woke up one night at 2am, after finally breaking through my dysphoria enough to know that it was time to come out publicly. The led to me pouring my heart out in a letter to my immediate family.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-letter&quot;&gt;The letter&lt;&#x2F;h2&gt;
&lt;p&gt;Copied below is the letter I sent my family. I put it here for other trans folks, and potential trans folks, as data they can use in their own journeys.&lt;&#x2F;p&gt;
&lt;p&gt;&quot;I&#x27;m writing an email to you all to put everything in one place about what&#x27;s going on with me. I hope you don&#x27;t mind the length of the email, but there&#x27;s a lot to talk about, and I want to give you the full story.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ll also say before I start that I hope you all will read this with an open heart. This stuff took me a long time and a lot of work to figure out. I&#x27;m sharing them because I don&#x27;t want to hide. I know in our family we don&#x27;t often talk about &quot;the hard stuff&quot;, but in my experience not talking about it makes things so much worse.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve always known I was different from other people. A bit of a black sheep. I didn&#x27;t really understand why, I just knew that how I thought about things always felt out-of-step with people around me. One of my earliest memories of this goes back to being 5 or 6. I was at church, playing house with a girl my age. After we were done she was so happy to have pretended to play the wife role, and I just felt... strange. The chaperone there said how cute it was that we could play so well together and I remember just looking at them, wanting the praise, but also being struck that these weren&#x27;t my dreams.&lt;&#x2F;p&gt;
&lt;p&gt;I remember learning to sew, knit, and crochet in California. I remember Dad saying he didn&#x27;t want me to be a sissy. I tried to live up to what he wanted and make Dad proud. But it&#x27;s hard when what comes naturally to you brings disdain and ridicule. You learn to push it down, to hide who you are from the world. So that&#x27;s what I did.&lt;&#x2F;p&gt;
&lt;p&gt;It was in my teen years when it first hit me hard. It felt like someone had punched a hole through my heart. I could feel it inside me, a deep pit that felt like it had no bottom. I thought it was just teen stuff. They tell you that depression and anxiety is normal for teens, so I thought maybe I&#x27;d grow out of it. Little did I know that this hole would follow me for the next 30 years.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;d grow older, go to college, date and watch my friends form serious relationships, get married, and have children. But I never went that path. When I would date, that hole in my heart would eat at me. I knew each relationship was going to end, regardless of how nice the person I was with was. I didn&#x27;t understand it, and at the time I just thought I hadn&#x27;t found the right person, yet. So I just kept looking and breaking hearts as I went.&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s not that I didn&#x27;t try to figure it out. I spent years in therapy with different therapists, I went to churches and talked to pastors, I meditated, you name it. I just kept going still thinking when I met the right person it would all fall into place.&lt;&#x2F;p&gt;
&lt;p&gt;I kept moving, literally, and at each place I kept looking.&lt;&#x2F;p&gt;
&lt;p&gt;I had a therapist one time tell me that &quot;you can keep running, but you know it will follow you wherever you go, right?&quot; I didn&#x27;t really appreciate at the time how right she would be.&lt;&#x2F;p&gt;
&lt;p&gt;In January of this year, I was talking to a dear friend and off-handedly mentioned that I watched a lot of YouTube. She asked how much, so I went and added it up and then stared at the result. For the three days prior, I&#x27;d average eight and a half hours a day. And that didn&#x27;t count the other content, like Netflix, that I&#x27;d watched. I couldn&#x27;t remember how long it&#x27;d been like that, but it quickly sunk in that it had been months, and likely years. I knew I had a problem. I could feel that I wasn&#x27;t using it for entertainment anymore. I was using it to numb myself so I wouldn&#x27;t have to feel. I saw in myself what I&#x27;d seen in my friends who struggled with alcohol and drugs. The desire to drown out something that I was afraid to face. I quit and then immediately started reaching out for help. My doctor connected me to addiction services, who connected me to a counsellor who could help me. And he did. He got me to slow down and start facing those things I was afraid to face.&lt;&#x2F;p&gt;
&lt;p&gt;Working to face my fears eventually landed me back in the doctor&#x27;s office trying to address mental health issues that had been a constant part of my life. The symptoms matched a cluster of symptoms often associated with dysphoria, specifically dysphoria associated with being transgender. In March of this year, I mentioned this to my doctor, and then asked if we should explore treating it. She heartily agreed and put me on my first prescription for hormone replacement. Within two weeks I knew I&#x27;d made the right choice. I could feel the improvements almost immediately. My brain was clearer. I had less background noise. I felt so much better that I thought the hole in my heart was starting to heal.&lt;&#x2F;p&gt;
&lt;p&gt;But what did it mean? At first I was content just to enjoy my improved health, but then I started to ask questions. Why was estrogen so much better for me? Why did testosterone hurt me?&lt;&#x2F;p&gt;
&lt;p&gt;So I started to dig. Like putting a puzzle together without knowing what the puzzle was supposed to look like. I just started pulling the pieces out, trying to make sense of them.&lt;&#x2F;p&gt;
&lt;p&gt;I also was afraid of what was underneath all those layers, too. After all, I&#x27;d tried so hard through my life to bury whatever it was and to pretend it didn&#x27;t exist. What I&#x27;d buried though was an enormous amount of pain. I didn&#x27;t want it to swallow me, so I had to deal with it.&lt;&#x2F;p&gt;
&lt;p&gt;I once had a friend of mine ask me &quot;if you had a button that you could press and wake up as a woman, would you?&quot; I didn&#x27;t have to think about the answer. I blurted out &quot;of course, but everyone would do that&quot; She just gave me a knowing look.&lt;&#x2F;p&gt;
&lt;p&gt;I mean, everyone would push the button, right?&lt;&#x2F;p&gt;
&lt;p&gt;It took a while for it to really sink in what the ramifications of my answer were. I&#x27;ll admit it, I can be a bit dim sometimes.&lt;&#x2F;p&gt;
&lt;p&gt;As I put the puzzle pieces together it started to paint the picture. I didn&#x27;t fit in the male world. I never have, and I never would.&lt;&#x2F;p&gt;
&lt;p&gt;I looked instead to what brought me joy. Not a surface level joy, but the kind that would touch deep inside. I know that if who I am doesn&#x27;t spring from that place, it will never be fully authentic. I tried to ask that part of me what it wanted, but at first it didn&#x27;t answer.&lt;&#x2F;p&gt;
&lt;p&gt;I waited and instead asked other questions. As the months passed, the hormones started to have an effect on more than just my brain. My body, too, began to shift and change. I asked myself if this is what I wanted and got a resounding &quot;yes!&quot; from deep within.&lt;&#x2F;p&gt;
&lt;p&gt;Trying to listen for that small voice inside takes care and time, so I let it speak, and I would listen when it did. Bit by bit, I saw enough of myself reflected back to me that I knew what I was looking at.&lt;&#x2F;p&gt;
&lt;p&gt;I am a trans woman, meaning that the deepest part of me isn&#x27;t male -- it&#x27;s female. And the journey I&#x27;m on is one of transition, shifting from outwardly being male to outwardly being female. This kind of transition isn&#x27;t something that happens overnight. Instead, it happens slowly over months and years.&lt;&#x2F;p&gt;
&lt;p&gt;If you&#x27;re surprised by what I&#x27;m saying, don&#x27;t worry, you&#x27;re in good company. Had someone told me years ago this is what would happen this year, I&#x27;m not sure I would have believed them. Truth be told, I wasn&#x27;t really ready then to face it.&lt;&#x2F;p&gt;
&lt;p&gt;But now I am, and I&#x27;m going to lean into being who I am. I hope to have your support. I know the path ahead won&#x27;t be easy, but I can tell you from the deepest part of me that it&#x27;s the right thing to do.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m not entirely sure how to sign this email, as I don&#x27;t know what my name will be. So, I&#x27;ll sign it with a name that means one of my favorite things in the world: wisdom. Who knows, perhaps the name will stick.&lt;&#x2F;p&gt;
&lt;p&gt;-- Sophia&quot;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;speedrunning-wisdom&quot;&gt;Speedrunning wisdom&lt;&#x2F;h2&gt;
&lt;p&gt;It&#x27;s now December and Sophia, as a name, stuck. Sophia June Turner is what I moved to, and I&#x27;ve begun the many (many) processes to change my name in all the places I can.&lt;&#x2F;p&gt;
&lt;p&gt;The bigger change, though, was how I viewed my transition. I know who I am. I know where I want to go. I told some friends that I went from &quot;hormones are helping&quot; to &quot;how do I speedrun transition&quot; in eight months. That&#x27;s not far from the truth.&lt;&#x2F;p&gt;
&lt;p&gt;Here are some on-going and upcoming things I&#x27;m working on:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Regular conversational voice practice. I&#x27;m able to hold femme range and head voice, but I still need to work on femme cadence and inflection. Yesterday, I managed over 6 hours of practice, which is a huge step up from where I was a month ago, when I barely had the courage to practice at all.&lt;&#x2F;li&gt;
&lt;li&gt;Next week, I&#x27;m having my first large effort electrolysis with a place that uses the modern electrolysis machines. The new machines should move a bit quicker, and in theory should be less painful, than the old machines. All up, I have 6 hours of electrolysis planned over 3 sessions. We&#x27;ll see if I can take it.&lt;&#x2F;li&gt;
&lt;li&gt;Next month, I have my first major surgery: hair transplantation. They&#x27;re moving follicles from the back of my head to the front and top using a class of techniques that fall under FUE. As part of this, they&#x27;ll be sculpting a more feminine hairline as well.&lt;&#x2F;li&gt;
&lt;li&gt;I&#x27;m still trying to figure out how and when to get back to the States for my official name change, but once I figure that out I&#x27;ll kick that process off.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;the-road-ahead-takes-work&quot;&gt;The road ahead takes work&lt;&#x2F;h2&gt;
&lt;p&gt;There&#x27;s a lot of work ahead of me as I transition, but I think of it like walking a long distance. I can do it. I&#x27;ll have to rest from time to time. I&#x27;ll hit obstacles I have to find a solution for. But, I&#x27;m going to keep going. That&#x27;s the promise I made myself. The joy I feel every time I hear my name, my pronouns, or feel a change in my body as I go are just signs along the way I&#x27;m heading the right direction.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>The case for Nushell</title>
        <published>2023-08-30T00:00:00+00:00</published>
        <updated>2023-08-30T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/case-for-nushell/"/>
        <id>https://www.sophiajt.com/case-for-nushell/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/case-for-nushell/">&lt;p&gt;Recently, I had a chat with some of my friends about Nushell and why they stuck with traditional shells like bash&#x2F;zsh or the &quot;new&quot; hotness like fish rather than using Nushell. After chatting with them, my brain kept bubbling away at the state of how folks were using their terminals and the end result is this blog post.&lt;&#x2F;p&gt;
&lt;p&gt;In this post, I make the case for really taking a hard look at Nushell and also for generally asking the question: &quot;can the state of shells be improved enough to overcome the inertia of sticking to what you know?&quot;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-lay-of-the-land&quot;&gt;The lay of the land&lt;&#x2F;h2&gt;
&lt;p&gt;Let&#x27;s take a look at some of the offerings out there that people are using everyday.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;bash-zsh&quot;&gt;Bash&#x2F;zsh&lt;&#x2F;h3&gt;
&lt;p&gt;Bash, originally a set of improvements on the Bourne shell, has grown to be the default shell for almost all Linux distros. That&#x27;s generally people&#x27;s first experience when they hit the terminal. It&#x27;s what they see when they log into a remote machine. It&#x27;s reached the definition of ubiquitous.&lt;&#x2F;p&gt;
&lt;p&gt;I also throw &#x27;zsh&#x27; in here as well. Apple&#x27;s macOS switched from bash to zsh, an operationally similar shell but created a bit more recently.&lt;&#x2F;p&gt;
&lt;p&gt;Bash at this point has become so well known that people often confuse support for bash-isms as part of the POSIX standard, but we&#x27;ll talk about that later.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Pros:&lt;&#x2F;strong&gt; it&#x27;s everywhere. Learn once, run anywhere.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Cons:&lt;&#x2F;strong&gt; as a language, bash&#x2F;zsh feels a bit too retro. It doesn&#x27;t offer any of the modern programming language style, tool support, etc folks would be used to from other languages. In truth, bash was never really meant for writing the kind of large scripts that people are maintaining today.&lt;&#x2F;p&gt;
&lt;p&gt;Example for loop in bash:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;bash&quot;&gt;#!&#x2F;bin&#x2F;bash
for i in `seq 1 10`;
do
        echo $i
done
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;fish&quot;&gt;Fish&lt;&#x2F;h3&gt;
&lt;p&gt;As fish&#x27;s website says: &quot;Finally, a command line shell for the 90s&quot;&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s enough to elicit a smirk, because you know it&#x27;s a bit true. The bash&#x2F;zsh style shells are getting left behind by something that feels a bit nicer, has nicer completions, looks nicer (you can get similar improvements out of bash if you work at it, but fish ships with them out of the box)&lt;&#x2F;p&gt;
&lt;p&gt;Fish also bravely steps away from the shell scripting form of bash to something a bit more readable.&lt;&#x2F;p&gt;
&lt;p&gt;Example for loop in fish:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;fish&quot;&gt;for i in (seq 1 10);
    echo $i;
end
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;Pros:&lt;&#x2F;strong&gt; the interactive experience of fish does feel quite a bit nicer that bash&#x2F;zsh out of the box. Scripting is a bit nicer.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Cons:&lt;&#x2F;strong&gt; As it says on the tin, it&#x27;s a shell for the 90s. It ain&#x27;t the 90s anymore.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;powershell&quot;&gt;PowerShell&lt;&#x2F;h3&gt;
&lt;p&gt;Coming into 1.0 at 2006, PowerShell is one of the first shells to really draw a line in the sand to say &quot;enough, we&#x27;re going to do things differently&quot;. The unix style of pipelines, where commands communicate via text to each other was replaced by a .NET engine that passed objects between commands.&lt;&#x2F;p&gt;
&lt;p&gt;The impact wasn&#x27;t immediately obvious but as devops folks (and others) discovered what was possible when you have ways to work with data directly a fanbase grew.&lt;&#x2F;p&gt;
&lt;p&gt;Example of a for(each) loop in PowerShell:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;powershell&quot;&gt;foreach ($i in 1..10) {
    echo $i
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;PowerShell came with an opinionated design that focused on verb-noun naming, improvements to shell syntax, and a vast set of functionality drawn from the .NET ecosystem.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Pros:&lt;&#x2F;strong&gt; it&#x27;s a structured shell - you can actually work with objects rather than text. Powerful set of tools and capabilities taken from .NET.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Cons:&lt;&#x2F;strong&gt; I&#x27;ll go ahead and say it: PowerShell was never really designed to be a language first. The verb-noun convention forces a style that feels very awkward coming from other languages. Worth a mention: earlier versions of PowerShell were Windows-only and modern crossplatform support lacks some of the features of the earlier versions.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;other-shells&quot;&gt;Other shells&lt;&#x2F;h3&gt;
&lt;p&gt;When I was coming up, there were a lot of other shells, including the csh&#x2F;tcsh family. Having said that, I don&#x27;t know anyone who is using any of the other family of shells. Bash&#x2F;zsh and to some extent fish really dominate the developer mindshare.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;hold-up-we-really-need-to-talk-about-posix&quot;&gt;Hold up, we really need to talk about POSIX&lt;&#x2F;h2&gt;
&lt;p&gt;We really need to take a minute and talk about POSIX before we continue. A lot of folks have leveled &quot;but it&#x27;s not POSIX&quot; as an argument against using Nushell, but I&#x27;d like to turn that around and ask the question:&lt;&#x2F;p&gt;
&lt;p&gt;&quot;What&#x27;s so good about POSIX?&quot;&lt;&#x2F;p&gt;
&lt;p&gt;Most folks when asked would likely point to it as a common ground that code can be ported to. In reply, I&#x27;d like to quote a few bits of the POSIX standard.&lt;&#x2F;p&gt;
&lt;p&gt;The following are &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;pubs.opengroup.org&#x2F;onlinepubs&#x2F;9699919799&#x2F;utilities&#x2F;V3_chap02.html&quot;&gt;reserved words in the POSIX standard for shell scripting&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;case&lt;&#x2F;li&gt;
&lt;li&gt;do&lt;&#x2F;li&gt;
&lt;li&gt;done&lt;&#x2F;li&gt;
&lt;li&gt;elif&lt;&#x2F;li&gt;
&lt;li&gt;else&lt;&#x2F;li&gt;
&lt;li&gt;esac&lt;&#x2F;li&gt;
&lt;li&gt;fi&lt;&#x2F;li&gt;
&lt;li&gt;for&lt;&#x2F;li&gt;
&lt;li&gt;if&lt;&#x2F;li&gt;
&lt;li&gt;in&lt;&#x2F;li&gt;
&lt;li&gt;then&lt;&#x2F;li&gt;
&lt;li&gt;until&lt;&#x2F;li&gt;
&lt;li&gt;while&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Yes, really. &lt;code&gt;fi&lt;&#x2F;code&gt; and &lt;code&gt;esac&lt;&#x2F;code&gt; are a joke that never found their end. No one would design a language that did that with a straight face these days.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s take a quick look at the number of flags common Unix commands ship with. These are on my macOS system, so ymmv.&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;command&lt;&#x2F;th&gt;&lt;th&gt;number of flags&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;ls&lt;&#x2F;td&gt;&lt;td&gt;45&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;man&lt;&#x2F;td&gt;&lt;td&gt;15&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;ps&lt;&#x2F;td&gt;&lt;td&gt;29&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;If you look through the flags of &lt;code&gt;ls&lt;&#x2F;code&gt; to see why it has so many, notice how many are configuring what &lt;code&gt;ls&lt;&#x2F;code&gt; is displaying. In a real sense, this is going against the underlying philosophy of unix pipelines. Rather than composing a pipeline to get the display you want, you&#x27;re learning a language of flags for each command to configure the display.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s talk about exit codes. Actually, wait, I &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.sophiajt.com&#x2F;exit-codes&#x2F;&quot;&gt;already did that&lt;&#x2F;a&gt;. As I point out in the post, the standard says:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;The value of status may be 0, EXIT_SUCCESS, EXIT_FAILURE, [CX] [Option Start] or any other value, though only the least significant 8 bits (that is, status &amp;amp; 0377) shall be available from wait() and waitpid(); the full value shall be available from waitid() and in the siginfo_t passed to a signal handler for SIGCHLD. [Option End]&quot;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Sure - we all still use 8-bit machines while flipping through a manual we printed trying to find the exit code description to understand why a command failed.&lt;&#x2F;p&gt;
&lt;p&gt;I hear you: &quot;but, look, it doesn&#x27;t matter how archaic this stuff is, if we all agree to use it things keep working.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;I dunno - these arguments just don&#x27;t hold up. We&#x27;d still be using C as our main systems language because it&#x27;s the most documented, most portable, etc. But, by and large, we don&#x27;t. We&#x27;re increasingly choosing other languages.&lt;&#x2F;p&gt;
&lt;p&gt;The truth is, in 2023 if someone asked us to design a system, we wouldn&#x27;t design POSIX. If, in 2023, someone asked us to design a shell language, we wouldn&#x27;t design bash&#x2F;zsh. This matters.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;show-us-the-money&quot;&gt;Show us the money&lt;&#x2F;h2&gt;
&lt;p&gt;I make some pretty bold statements in the above. There is a heritage of technology that got us to this point. While that heritage is important, it&#x27;s not without its drawbacks. Are there better ways of doing it?&lt;&#x2F;p&gt;
&lt;h3 id=&quot;why-structure-matters&quot;&gt;Why structure matters&lt;&#x2F;h3&gt;
&lt;p&gt;Before we get into talking about Nushell, let&#x27;s talk about why structured data matters.&lt;&#x2F;p&gt;
&lt;p&gt;In the Unix pipeline way of thinking, text passes between commands. This is very flexible, but has a major problem: both the outputting command and the inputting command have to agree what shape that text will take so the info can be passed. This locks &lt;em&gt;representation&lt;&#x2F;em&gt; to &lt;em&gt;presentation&lt;&#x2F;em&gt;, disallowing commands from evolving their output over time. As we showed earlier, it also encourages a proliferation of flags.&lt;&#x2F;p&gt;
&lt;p&gt;That&#x27;s annoying. Does separating the structure from its presentation help us?&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;nushell&quot;&gt;&amp;gt; ls | where size &amp;gt; 10kb
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I always start with this example when showing off Nushell, because not only is it immediately readable, we didn&#x27;t have to dig through any flags to figure out what we needed to pass to &lt;code&gt;ls&lt;&#x2F;code&gt; to get that. We also aren&#x27;t parsing anything from &lt;code&gt;ls&lt;&#x2F;code&gt;. Instead, the data is passed directly to &lt;code&gt;where&lt;&#x2F;code&gt;, which handles it directly.&lt;&#x2F;p&gt;
&lt;p&gt;Commands already know this structure, why not make use of it?&lt;&#x2F;p&gt;
&lt;p&gt;The same &lt;code&gt;where&lt;&#x2F;code&gt; command works on other things. For example, we can process the output of the &lt;code&gt;ps&lt;&#x2F;code&gt; command:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;nushell&quot;&gt;&amp;gt; ps | where cpu &amp;gt; 40
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Or open a &lt;code&gt;csv&lt;&#x2F;code&gt; file and processing its rows:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;nushell&quot;&gt;&amp;gt; open fields.csv | where area &amp;gt; 5
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And so on. It&#x27;s the same &lt;code&gt;where&lt;&#x2F;code&gt; regardless of where the data is coming from. It also gives us the freedom to present the data however we want.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why-nushell-matters&quot;&gt;Why Nushell matters&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;nushell-is-designed-to-be-a-language&quot;&gt;Nushell is designed to be a language&lt;&#x2F;h3&gt;
&lt;p&gt;I had the good fortune of being a part of some prominent programming language teams, including &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;devblogs.microsoft.com&#x2F;typescript&#x2F;announcing-typescript-1-0&#x2F;&quot;&gt;helping to create TypeScript&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blog.rust-lang.org&#x2F;2016&#x2F;08&#x2F;10&#x2F;Shape-of-errors-to-come.html&quot;&gt;helping create Rust&#x27;s error messages as part of the Rust team in Mozilla&lt;&#x2F;a&gt;. Designing languages to be easy to use, easy to read, easy to scale up, and easy to debug is something I care about and have worked on for many years.&lt;&#x2F;p&gt;
&lt;p&gt;To that end, Nushell is designed with an eye towards being readable at a glance.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s do a &lt;code&gt;for&lt;&#x2F;code&gt; loop in Nushell:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;nushell&quot;&gt;for i in 1..10 {
    print $i
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;(&lt;em&gt;aside: &quot;but why do variables have dollar signs?&quot;. Turns out the flexibility of shell programming allows paths to not use quotes, so it&#x27;s nice to tell a difference between &lt;code&gt;cd foo&lt;&#x2F;code&gt; and &lt;code&gt;cd $foo&lt;&#x2F;code&gt;&lt;&#x2F;em&gt;)&lt;&#x2F;p&gt;
&lt;p&gt;This eye towards usable design shows up in many ways. Working with data is improved by not only having structure, but also being able to pattern match against it. Here&#x27;s an example of pattern matching a list in Nushell:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;nushell&quot;&gt;match $list {
  [$one] =&amp;gt; { print &amp;quot;one element list&amp;quot; }
  [$one, $two] =&amp;gt; { print &amp;quot;two element list&amp;quot; }
  [$head, ..$tail] =&amp;gt; { print $&amp;quot;the tail of the list is ($tail)&amp;quot; }
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In a way, working in Nushell should feel at home both interactively as a shell and as a full scripting language. We&#x27;ve had folks write COVID reporting software in Nushell, research experiments, even &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;couchbaselabs&#x2F;couchbase-shell&quot;&gt;entire shells for well-known database services&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;nushell-is-typechecked&quot;&gt;Nushell is typechecked&lt;&#x2F;h3&gt;
&lt;p&gt;Since Nushell doesn&#x27;t treat all data as text, you can represent tables, records, numbers, booleans, etc directly in the language.&lt;&#x2F;p&gt;
&lt;p&gt;As a result of this, Nushell is fully typechecked. Common errors can be caught early and shown to you before the script even runs.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;nushell_typecheck.png&quot; alt=&quot;Image of Nushell giving an error when a string was passed where an int was expected&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Taking what we learned from TypeScript - the types also feed into another important tool.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;nushell-has-ide-support&quot;&gt;Nushell has IDE support&lt;&#x2F;h3&gt;
&lt;p&gt;The types, autocompletion, and early error reporting feed into an engine in Nushell that knows a lot more about your code. As a result, you can write scripts and then work with them using the IDE support Nushell provides. Seeing errors, jumping to definitions, getting documentation on hovers, etc are all part of the Nushell experience.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;nushell_ide_hover.png&quot; alt=&quot;Image VSCode hover for Nushell with full code documentation&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;nushell-has-nice-errors&quot;&gt;Nushell has nice errors&lt;&#x2F;h3&gt;
&lt;p&gt;In Nushell, we make extensive use of remembering where data comes from, as well as what caused an error. Simple errors, like division by zero, are shown clearly:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;nushell_div_zero.png&quot; alt=&quot;Image of Nushell pointing to a divide by zero error&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;A more complex error may need to show more to help track down where a mistake came from. Let&#x27;s say you&#x27;ve accidentally put a string in your list of numbers, and then tried to process it:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;nushell_error_source.png&quot; alt=&quot;Image of Nushell showing the source of data that&amp;#39;s caused an error&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;nushell-has-a-sql-like-style&quot;&gt;Nushell has a SQL-like style&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;nushell_sql_like.png&quot; alt=&quot;Image of Nushell looking like sql working over data&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;When you start using Nushell to compose pipelines, you&#x27;ll notice that it has a distinct SQL-like style. Data flows through each stage, and you build up what you want to do to it as you add more commands.&lt;&#x2F;p&gt;
&lt;p&gt;This gives Nushell a distinctive design that encourages experimentation and exploration.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;nushell-is-and-has-always-been-crossplatform&quot;&gt;Nushell is, and has always been, crossplatform&lt;&#x2F;h3&gt;
&lt;p&gt;An important decision we made from day 1 was to be crossplatform. You can run Nushell on Windows, Linux, and macOS (and BSD, and Android) and get the same experience. You can easily write scripts in a way that they can be run across different platforms. Everything that you learn transfers between OSes without friction.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;is-nushell-good-enough-to-overcome-the-inertia&quot;&gt;Is Nushell good enough to overcome the inertia?&lt;&#x2F;h2&gt;
&lt;p&gt;I distinctly remember going to a SIAM conference many years back and giving a talk on the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;chapel-lang.org&quot;&gt;Chapel programming language&lt;&#x2F;a&gt;. Even back then, it was a clever language. In a couple lines, you could write code that could distribute and process a matrix across a network of computers. Coming from a lineage of array languages, it ate up data parallel processing. The equivalent code in other languages looked verbose in comparison.&lt;&#x2F;p&gt;
&lt;p&gt;I went through my talk, hoping I&#x27;d done a decent job of conveying the main points, and at the end, someone in the audience stood up and said &quot;but I can do all this in C++&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;He proceeded to explain that if he could recreate many of the techniques we showed all as part of a C++ library that people could use. At this time, I wasn&#x27;t sure how to respond other than &quot;but you don&#x27;t have to, we already built this language&quot; but he couldn&#x27;t be swayed. If it wasn&#x27;t C++, he didn&#x27;t want it.&lt;&#x2F;p&gt;
&lt;p&gt;Fast forward a couple years, and I&#x27;m standing in front of a JavaScript audience giving a similar talk, this time promoting TypeScript. I remember the kind of politely confused looks on people&#x27;s faces as I showed off the features TypeScript offered. There was a similar sense of &quot;why do we need to leave JavaScript?&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;To answer whether Nushell can overcome this kind of inertia, I&#x27;ll pose two questions:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Is Nushell compelling enough for a single person to adopt it?&lt;&#x2F;li&gt;
&lt;li&gt;Would adopting Nushell broadly as a community move the needle?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Let&#x27;s tackle the first question. Time and again, as people try Nushell, they come back with quotes like &quot;this is the most excited I&#x27;ve been about tech in 15 years&quot;. It has a fanbase that loves it, and that fanbase is growing. It reminds me of the early days of Rust, just after hitting 1.0.&lt;&#x2F;p&gt;
&lt;p&gt;To the second question: would adopting Nushell broadly actually improve things noticeably? Without a doubt. I say this without any reservation. Thinking of our shells as structured, interactive processing engines opens up the doors to a much wider array of things you can do with them. The commands would be far simpler than their POSIX equivalents and would compose far better. They&#x27;d benefit from the full knowledge of the data being shared between them. Adaptors could be made to connect to all parts of the system, allowing you full, structured interaction with everything you have access to.&lt;&#x2F;p&gt;
&lt;p&gt;In essence, as the saying goes, we&#x27;d be building a skyscraper starting from the 15th floor instead of the 1st.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;it-s-time-to-be-honest-about-what-nushell-is&quot;&gt;It&#x27;s time to be honest about what Nushell is&lt;&#x2F;h2&gt;
&lt;p&gt;It&#x27;s time I come clean about what Nushell is. Nushell isn&#x27;t exactly a shell, at least not in the traditional Unix sense of the word. Nushell is trying to answer the question: &quot;what if we asked more of our shells?&quot;&lt;&#x2F;p&gt;
&lt;p&gt;Nushell is really an interactive, data-focused scripting language with shell capabilities. It merges these three things into one:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A fully-typed scripting language&lt;&#x2F;li&gt;
&lt;li&gt;An interactive shell&lt;&#x2F;li&gt;
&lt;li&gt;A data processing system (that can also handle large data loads via dataframes)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Rather than these being three separate ideas glued together, in practice it feels like Nushell is treating everything you interact with as data. This allows you to pull together different kinds of data, and know that the same commands will work over them.&lt;&#x2F;p&gt;
&lt;p&gt;You might look at that list and think you don&#x27;t need all that, but the way I might frame it is this: it&#x27;s nice to have it when you need it.&lt;&#x2F;p&gt;
&lt;p&gt;I don&#x27;t need to do heavy data processing everyday, but it&#x27;s nice to not have to shift what I&#x27;m doing at all when I need to do it. I don&#x27;t have to download new utilities or switch languages. It&#x27;s all right there. Need to write a script to load some files and handle some directory processing? Still right there. Need to throw together some web query that outputs the top download results for a github repo? You guessed it, all still right there.&lt;&#x2F;p&gt;
&lt;p&gt;This is just scratching the surface, really. Nushell has a plugin system that allows more capabilities to be added based on your needs. We already have plugins that add a variety of additional file formats, querying capabilities, and more.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;it-s-okay-to-have-nice-things&quot;&gt;It&#x27;s okay to have nice things&lt;&#x2F;h2&gt;
&lt;p&gt;Nushell was built with a simple idea: working in the shell, writing code, and processing data should be &lt;em&gt;fun&lt;&#x2F;em&gt;. To that end, we work hard to make Nushell feel nice.&lt;&#x2F;p&gt;
&lt;p&gt;You can write readable scripts that come with their own documentation, and then come back to them 6 months later and still understand what they&#x27;re doing.&lt;&#x2F;p&gt;
&lt;p&gt;You can sit in the shell and play with pipeline ideas until one grows into a scripting project and then effortlessly transition your experiment into a full script.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;that-s-it&quot;&gt;That&#x27;s it&lt;&#x2F;h2&gt;
&lt;p&gt;That&#x27;s my case. It&#x27;s okay to have fun. It&#x27;s okay to write attractive, well-documented code. It&#x27;s okay to leave the designs of the past behind when they no longer fit the present day.&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s okay to move on to better ways of doing things.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Happy pride! I&#x27;m trans!</title>
        <published>2023-06-26T00:00:00+00:00</published>
        <updated>2023-06-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/happy-pride-im-trans/"/>
        <id>https://www.sophiajt.com/happy-pride-im-trans/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/happy-pride-im-trans/">&lt;p&gt;Hi, I&#x27;m trans. Let&#x27;s talk about it!&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;&#x2F;strong&gt; In this blog post, I talk about the medical side of my particular kind of transgender experience. If that&#x27;s not your thing, feel free to skip.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-long-time-in-the-making&quot;&gt;A long time in the making&lt;&#x2F;h2&gt;
&lt;p&gt;The first time I looked up anything trans-related was in my early 20s. I didn&#x27;t know it at the time, but I was actually looking for a way to help address a set of symptoms I was having.&lt;&#x2F;p&gt;
&lt;p&gt;For most of my adult life, I experienced a cluster of issues: dissociation, derealization, depersonalization, and others. I thought it was normal to feel disconnected from your body, and for parts of your brain to feel disconnected from other parts of your brain.&lt;&#x2F;p&gt;
&lt;p&gt;What I didn&#x27;t understand, but have come to learn this year, is that I have &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;genderdysphoria.fyi&#x2F;en&#x2F;biochemical-dysphoria&quot;&gt;biochemical dysphoria&lt;&#x2F;a&gt;. In short, this means that the hormone that my body used to regulate, testosterone, was not the correct regulating hormone for me. Think running an engine on the wrong fuel: it kinda works but it&#x27;s really not good on the engine and you&#x27;ll have side effects. Switch to the correct one, and you&#x27;ll notice a big difference.&lt;&#x2F;p&gt;
&lt;p&gt;The fix, as things go, is relatively simple. Remove the hormone you&#x27;re starting from and replace it with the other hormone (using a process often called HRT). If you have the condition, you&#x27;ll likely start feeling noticeably better rather quickly. If you don&#x27;t, you&#x27;ll likely feel worse.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-first-few-weeks-of-hrt&quot;&gt;The first few weeks of HRT&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;em&gt;Before I talk about my experiences on HRT, I want to say that I&#x27;m just sharing my experiences rather than giving medical advice. Everyone is different, and there&#x27;s really no telling how anyone else would respond. I did this through a doctor, as I luckily had access to trans-friendly medical care. It&#x27;s my sincere wish that in the future &lt;strong&gt;everyone&lt;&#x2F;strong&gt; will have that kind of access.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The early impact of HRT for me was certainly eye-opening. Mental health symptoms I&#x27;d had for decades started to lift within the first 2 weeks. I no longer felt internally disconnected. Instead, internally I had more flow, comfort, and a feeling of openness.&lt;&#x2F;p&gt;
&lt;p&gt;I think my reaction could be summed up with &quot;what... in the world?&quot; in a very good way. I remember walking around my apartment mumbling to myself &quot;I hope this doesn&#x27;t stop, because this is great.&quot; Luckily, so far, it hasn&#x27;t.&lt;&#x2F;p&gt;
&lt;p&gt;Along with the drastically improved mental health I had two other changes: emotional changes and mood changes.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;emotional-changes&quot;&gt;Emotional changes&lt;&#x2F;h3&gt;
&lt;p&gt;The emotional side also began to change rather quickly. I think this could be described as someone handing me glasses for the first time. Whereas before emotions felt like they were piecemeal and difficult to understand, now emotions feel clear. I could cry, and smile, and feel each more deeply and more connected to my inner world.&lt;&#x2F;p&gt;
&lt;p&gt;I love it. I&#x27;m able to speak more of the language of the inner world, which is helping me not only understand myself, but also communicate better with other people.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;mood-changes&quot;&gt;Mood changes&lt;&#x2F;h3&gt;
&lt;p&gt;Since November last year, I&#x27;ve been daily logging my mood on my phone. I was hoping to find some patterns or some kind of good data.&lt;&#x2F;p&gt;
&lt;p&gt;Without really realising it, I managed to log months of data before starting HRT as well as the months following. With it, I got a pretty clear picture of how HRT affected my mood.&lt;&#x2F;p&gt;
&lt;p&gt;Before starting HRT, my average mood around around 6 out of 10. After starting HRT, within a couple weeks, it had risen to 8 out of 10.&lt;&#x2F;p&gt;
&lt;p&gt;It wasn&#x27;t just on the app. Friends who talked to me who hadn&#x27;t seen me in a while would remark &quot;whatever you&#x27;re doing, keep doing it.&quot;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-first-three-months&quot;&gt;The first three months&lt;&#x2F;h2&gt;
&lt;p&gt;While I won&#x27;t list all the changes, as honestly &lt;em&gt;something&lt;&#x2F;em&gt; should probably be private in this blog post, let me highlight a few more changes:&lt;&#x2F;p&gt;
&lt;h3 id=&quot;week-3&quot;&gt;Week 3&lt;&#x2F;h3&gt;
&lt;p&gt;At week 3, I had my first big emotional wave. I&#x27;ve never felt something like it before. Imagine being a small boat on a very large sea and the wave effortlessly lifts you up and down.&lt;&#x2F;p&gt;
&lt;p&gt;It took a bit of practice (and no doubt something I&#x27;ll continue to learn) to ride this wave. Along with this, though, I noticed that these swells brought with them a kind of sharp focus when noticing things that are wrong&#x2F;unjust&#x2F;etc. You can see and feel when something isn&#x27;t right, and it can be confusing when other people don&#x27;t seem to notice or don&#x27;t seem to feel it as intensely.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;week-10&quot;&gt;Week 10&lt;&#x2F;h3&gt;
&lt;p&gt;Around week 10 my skin started to change. It changed to have a softer texture which is quite pleasant.&lt;&#x2F;p&gt;
&lt;p&gt;Along with the above, my psoriasis started clearing up. Patches which had been there for years shrunk, and are continuing to shrink.&lt;&#x2F;p&gt;
&lt;p&gt;The skin changes also got me starting to look into different fabrics and clothing, as the coarse men&#x27;s clothing honestly doesn&#x27;t feel all that great on the skin as it gets more sensitive. It&#x27;s nice to put on something and feel soft and cozy.&lt;&#x2F;p&gt;
&lt;p&gt;And that brings us to today.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;today&quot;&gt;Today&lt;&#x2F;h3&gt;
&lt;p&gt;I&#x27;ve just gotten back from my doctor appointment for my 3 month check-in. Clean bill of health, so on we go (thankfully). My doctor was very pleased with how I was taking to the treatment, and clearly I am as well.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;questions-one-might-have&quot;&gt;Questions one might have&lt;&#x2F;h2&gt;
&lt;p&gt;Okay, so there are probably a few questions that could come to mind reading this, and no doubt a few others I haven&#x27;t thought of. Let&#x27;s see if we can address those.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;trans-what-exactly&quot;&gt;Trans... what, exactly?&lt;&#x2F;h3&gt;
&lt;p&gt;Being transgender means being a part of a rather large umbrella. Many folks know that there are trans women and trans men. For me, though, my trans-ness means to leave maleness and go off into the unknown.&lt;&#x2F;p&gt;
&lt;p&gt;I don&#x27;t really have a goal. Hmm, I take that back. My goal is to be healthy, and I try to put the effort in each day to make that happen. What that means may change over time, but I&#x27;m not rushing it.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;aren-t-there-body-changes-on-hrt&quot;&gt;Aren&#x27;t there body changes on HRT?&lt;&#x2F;h3&gt;
&lt;p&gt;Yes.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;and&quot;&gt;And?&lt;&#x2F;h3&gt;
&lt;p&gt;Oh oh you mean, what will I do when they happen? Again, taking it a day at a time. I don&#x27;t have all that figured out, and I&#x27;m okay with that.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;on-a-personal-note&quot;&gt;On a personal note&lt;&#x2F;h2&gt;
&lt;p&gt;It scares me how political trans-ness has become when, especially for my case, it&#x27;s medical. It&#x27;s something I&#x27;m working on between me and my doctor. I&#x27;m betting that&#x27;s true for lots of folks: they just want to live their lives.&lt;&#x2F;p&gt;
&lt;p&gt;It scares me that receiving medical treatment is difficult for a lot of people, especially seeing just how effective the medicine can be. The changes can be profound, and in some cases, also life-saving. To withhold that feels cruel.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m sharing my experience here to both be a record for myself, and also to be something other folks can read to learn about what it&#x27;s like to have biochemical dysphoria and to have it treated. I wish I could share the joy that I have now, the feeling of relief, for being able to address things I&#x27;ve struggled with for over the last 20 years. Do I wish I could have started sooner? Absolutely. Maybe this post will help other folks ask questions and get treatment sooner, too.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Why I left Rust</title>
        <published>2023-05-28T00:00:00+00:00</published>
        <updated>2023-05-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/why-i-left-rust/"/>
        <id>https://www.sophiajt.com/why-i-left-rust/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/why-i-left-rust/">&lt;p&gt;There&#x27;s a lot of speculation about why I left Rust yesterday, so I want to set the record straight in this post.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-happened&quot;&gt;What happened&lt;&#x2F;h2&gt;
&lt;p&gt;A short timeline of what happened from my perspective, as this is relevant for later:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;A request went out to the interim leadership group for potential keynote speakers for RustConf.&lt;&#x2F;li&gt;
&lt;li&gt;JeanHeyd Meneide was proposed by myself and Manish as a keynote. JeanHeyd is one of the two &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.open-std.org&#x2F;jtc1&#x2F;sc22&#x2F;wg14&#x2F;www&#x2F;contacts&quot;&gt;editors of the official C standard&lt;&#x2F;a&gt;, a C++ expert, and a good speaker. We felt like he&#x27;d be a great invited expert with an outsider perspective.&lt;&#x2F;li&gt;
&lt;li&gt;A few days later it was held to a vote. Consensus in the interim leadership group (what the official blog calls the &quot;leadership chat&quot;) are of those present in the group when the decision is made. In total five members voted, and all five votes supported JeanHeyd as the keynote speaker.&lt;&#x2F;li&gt;
&lt;li&gt;JeanHeyd was asked and accepted the keynote.&lt;&#x2F;li&gt;
&lt;li&gt;Before the schedule was posted, it was discussed in a team meeting that JeanHeyd had been selected as one of the keynote speakers.&lt;&#x2F;li&gt;
&lt;li&gt;A couple team members had strong opinions&#x2F;discomfort against JeanHeyd being selected as a keynote speaker, as best as I understand it, because of the content of JeanHeyd&#x27;s blog post on reflection in Rust.&lt;&#x2F;li&gt;
&lt;li&gt;This discomfort was brought to the interim leadership group as a problem that must be fixed immediately. There was no discussion of the ramifications of making a change at this point. There were complaints that this pushback was not sufficient to require change, but this feedback was ignored. The discussion focused on the discomfort of the team members and changing JeanHeyd away from being a keynote speaker as the only solution.&lt;&#x2F;li&gt;
&lt;li&gt;Two people in Rust leadership then, without taking a vote from the interim leadership group (remember, JeanHeyd was voted on and selected by Rust leadership), reached directly to RustConf leadership and asked to change the invitation. (note: this used to say one person, but I&#x27;ve now had multiple people independently confirm it was two people.)&lt;&#x2F;li&gt;
&lt;li&gt;RustConf leadership decided to wait a week before informing JeanHeyd, giving Rust leadership time to change its mind. The interim leadership group was not informed of this week delay.&lt;&#x2F;li&gt;
&lt;li&gt;After the week expired, JeanHeyd was informed of the decision to downgrade the talk. Understandably, he fully declined to speak at RustConf.&lt;&#x2F;li&gt;
&lt;li&gt;When I read JeanHeyd&#x27;s blog post and learned of the declining of the invitation, I immediately resigned from the Rust project.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;I&#x27;ll also note that the above is the best I am able to understand and piece together. A full investigation needs to happen to uncover how and why the above happened. I also reserve the right to edit the above if new information comes to light.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why-did-i-leave&quot;&gt;Why did I leave?&lt;&#x2F;h2&gt;
&lt;p&gt;To my mind, why I left is obvious. I just watched the Rust organization disgrace one of the experts in my field. As an organization, Rust and RustConf offered little resistence to Rust being wielded as a weapon against an individual because of some discomfort of a couple team members.&lt;&#x2F;p&gt;
&lt;p&gt;What rang in my mind is: &quot;a system is what a system does&quot;&lt;&#x2F;p&gt;
&lt;p&gt;Rust acted as a cruel, heartless entity that did not care about JeanHeyd and treated him as disposable. Easy to offer a place of respect and just as quick to snatch it away. That is what Rust &lt;em&gt;is&lt;&#x2F;em&gt; because that is what Rust &lt;em&gt;did&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I left because when I felt JeanHeyd&#x27;s pain and disappointment at being mistreated and betrayed, my heart broke. I wept because of the cruelty. But I also wept because I helped create the system that could do this to someone.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;but-it-was-just-a-downgrade&quot;&gt;But it was just a downgrade&lt;&#x2F;h2&gt;
&lt;p&gt;I shake my head at people that say things like this. Clearly, they are not used to treating people - let alone experts in the field - with respect. Downgrading a keynote that you explicitly invited the speaker to give (and prior to this they weren&#x27;t even going to speak at your conference) is extraordinarily disrespectful. I asked around to see if anyone had experienced this or even heard of it happening. No one had.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;decisions-are-made-with-context-never-in-a-vacuum&quot;&gt;Decisions are made with context, never in a vacuum&lt;&#x2F;h2&gt;
&lt;p&gt;I also felt the weight of the context of the decision. JeanHeyd isn&#x27;t just a recent grant recipient of the Rust Foundation. JeanHeyd has important history with the Rust project.&lt;&#x2F;p&gt;
&lt;p&gt;It was JeanHeyd who called Rust out for having no Black representation among Rust conference speakers. Rightly so, as both the Rust organization and the conferences had little to no Black representation.&lt;&#x2F;p&gt;
&lt;p&gt;When I saw an organization that not only could act so coldly to an expert in the field, but also to one who was a vocal critic of Rust&#x27;s lack of diversity, it was hard not to see the additional context.&lt;&#x2F;p&gt;
&lt;p&gt;Systems have memory and biases. If the people that make up the system don&#x27;t work to fight against these, they are perpetuated.&lt;&#x2F;p&gt;
&lt;p&gt;As my buddy Aman pointed out, the context that this would have also been the first keynote by a person of color at RustConf should not be lost here.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;aman.png&quot; alt=&quot;Amanjeev saying no one has thus far said anything about this aspect so i will. if my memory serves right, this would have been the first keynote ever by a person of color. the sheer disrespect of how this was done is worse than what you think.&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;it-s-time-for-accountability&quot;&gt;It&#x27;s time for accountability&lt;&#x2F;h2&gt;
&lt;p&gt;I read back over how I handled the situation as it unfolded, and I could have done much better. My go-to tool is diplomacy, trying to build bridges, getting information, and finding compromises. But, after reading over what happened and how I acted, it&#x27;s clear part of the problem is &lt;em&gt;too much&lt;&#x2F;em&gt; diplomacy in leadership. Too many people giving each other the benefit of the doubt. Too many people asking for answers and then being satisfied to let bad decisions slide.&lt;&#x2F;p&gt;
&lt;p&gt;So let me do my part to fix my failings:&lt;&#x2F;p&gt;
&lt;p&gt;What we need isn&#x27;t diplomacy, it&#x27;s &lt;em&gt;accountability&lt;&#x2F;em&gt;. We need people to take responsibility for what happened and to make amends. We need people to step back from leadership who abused it to perform cruel acts against an expert in the wider programming language community. We need an organization that does not act cruelly so that the project it creates and the organization of people behind it can rebuild the trust it has lost.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;questions-that-need-to-be-answered&quot;&gt;Questions that need to be answered&lt;&#x2F;h2&gt;
&lt;p&gt;Rust, as an organization, is guilty of cruelty. It needs to be held accountable. Here are the first questions that come to mind that need to be answered:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;How was it possible for a decision to be made without a leadership vote?&lt;&#x2F;li&gt;
&lt;li&gt;Why was downgrading the talk the only path explored?&lt;&#x2F;li&gt;
&lt;li&gt;Why did RustConf leadership go along with this decision and not protect the speaker? Why wasn&#x27;t Rust leadership notified of the time period in which to change the decision?&lt;&#x2F;li&gt;
&lt;li&gt;Who ultimately is responsible for turning some team discomfort into disgracing a public expert? How are we going to hold them accountable?&lt;&#x2F;li&gt;
&lt;li&gt;How do we put safeguards in place so that this doesn&#x27;t happen again?&lt;&#x2F;li&gt;
&lt;li&gt;How can Rust not only be held accountable now, but maintain long-term accountability into the future?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Making a keyboard layout</title>
        <published>2023-02-22T00:00:00+00:00</published>
        <updated>2023-02-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/making-a-keyboard-layout/"/>
        <id>https://www.sophiajt.com/making-a-keyboard-layout/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/making-a-keyboard-layout/">&lt;p&gt;It all started innocently enough. I had gotten interested in more efficient typing at first by learning about different keyboards and what they offered. I was intrigued. Except there was one small problem: fancy keyboards are expensive, especially to import into New Zealand.&lt;&#x2F;p&gt;
&lt;p&gt;So, I took a different route: alternate &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;paulguerin.medium.com&#x2F;the-search-for-the-worlds-best-keyboard-layout-98d61b33b8e1&quot;&gt;keyboard layouts&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;These promised to help you type better than the standard qwerty layout. I dove in. I tried colemak, workman, and some of their variants. It was clear with practice you could type better with less hand strain. A normal person at this point might have picked something and stuck with it. Well okay, most people wouldn&#x27;t have even got that far. But I digress.&lt;&#x2F;p&gt;
&lt;p&gt;I on the other hand thought &quot;you know what would be cool? Making a layout for myself!&quot;&lt;&#x2F;p&gt;
&lt;p&gt;And down the rabbit hole I went.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why-do-a-new-layout&quot;&gt;Why do a new layout?&lt;&#x2F;h2&gt;
&lt;p&gt;It started from a simple idea that came from playing guitar and later made its way to professional Tetris competition: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;kotaku.com&#x2F;nes-tetris-players-call-it-rolling-and-theyre-setting-1846767518&quot;&gt;rolling&lt;&#x2F;a&gt;. The motion you might have used as a kid when you were bored, drumming your fingers on the table. As the fingers fall one after another, you can create high speeds.&lt;&#x2F;p&gt;
&lt;p&gt;The trick seemed simple enough. Lay out the keyboard to try to get the maximum benefit from rolling without making the typing that doesn&#x27;t roll harder than before.&lt;&#x2F;p&gt;
&lt;p&gt;While it&#x27;s still too early to declare victory, I&#x27;ll tell you that the text you are reading now was written using the layout I describe below.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;creating-the-layout&quot;&gt;Creating the layout&lt;&#x2F;h2&gt;
&lt;p&gt;I created a few programs with a relatively simple goal. I want to be able to generate layouts that matched a set of constraints. Once I had one, I&#x27;d try it out, change the parameters. Rinse and repeat.&lt;&#x2F;p&gt;
&lt;p&gt;In the end, I had gone through hundreds of layouts.&lt;&#x2F;p&gt;
&lt;p&gt;I learned a few things.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;you-need-to-find-a-corpus-of-text-close-to-what-you-type&quot;&gt;You need to find a corpus of text close to what you type&lt;&#x2F;h3&gt;
&lt;p&gt;Look through the data to make sure it will fit your writing style and that common words are covered.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;be-careful-about-using-text-with-high-counts-of-an-uncommon-word&quot;&gt;Be careful about using text with high counts of an uncommon word&lt;&#x2F;h3&gt;
&lt;p&gt;When I first started solving for a good keyboard, I used the source for Nushell, a codebase I&#x27;ve spent a lot of time in. This was great in theory, but in practice the algorithm tried to fit words like &quot;value&quot; and &quot;span&quot;, pushing other words out of the way.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;your-hands-might-help-you-find-what-works-for-you&quot;&gt;Your hands might help you find what works for you&lt;&#x2F;h3&gt;
&lt;p&gt;I would try out an idea and often revise after seeing how that idea worked in practice. I tried many shapes to roll and over time simplified it down to a set that felt I could hit with high enough accuracy.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;it-is-easy-to-over-fit-your-data&quot;&gt;It is easy to over-fit your data&lt;&#x2F;h3&gt;
&lt;p&gt;Scoring the different moves ended up being a bit of an art. Setting scores high enough, but not too high, took many iterations of trial and error.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;show-us-the-layout-already&quot;&gt;Show us the layout already&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.sophiajt.com&#x2F;images&#x2F;keyboard_layout.png&quot; alt=&quot;Keyboard with pmfcqxluoy inasbkreh ;vgdzjw,.&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Inas keyboard layout&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s the Inas layout (named by the home keys on the left hand).&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s talk about how I scored typing movements, and then talk about some ways we might improve on it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;scoring&quot;&gt;Scoring&lt;&#x2F;h2&gt;
&lt;p&gt;I broke my corpus of text up into words, then found 1-, 2-, and 3-letter runs of letters. These runs would then make up the &quot;roll&quot; that would get higher points.&lt;&#x2F;p&gt;
&lt;p&gt;I used the following scoring:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Typing on the home row is preferred&lt;&#x2F;li&gt;
&lt;li&gt;Center row keys are to be avoided (I learned from guitar that the lift of the finger can be easier on it than lateral stretches)&lt;&#x2F;li&gt;
&lt;li&gt;Runs of two should be together where possible&lt;&#x2F;li&gt;
&lt;li&gt;Jumps between the top row and bottom row should be avoided&lt;&#x2F;li&gt;
&lt;li&gt;Runs of three can fall in a row or can be two in a row and then fall by one row (in the code I call this a j-roll)&lt;&#x2F;li&gt;
&lt;li&gt;Try to use the pinkies less (unless necessary for the above)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;If you look at the keyboard above you can see quite a few patterns that fall out from that:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Common three letter runs like &quot;ing&quot;, &quot;you&quot;, &quot;the&quot;, and &quot;can&quot; are easier to type.&lt;&#x2F;li&gt;
&lt;li&gt;Longer words that build on runs are also easier: &quot;there&quot;, &quot;this&quot;, &quot;think&quot;, &quot;thing&quot;, &quot;your&quot;, &quot;than&quot;, &quot;care&quot;, &quot;other&quot;, &quot;another&quot;, and so on. Mixing and matching runs while you type ends up being a fun puzzle.&lt;&#x2F;li&gt;
&lt;li&gt;Surprisingly, some common words like &quot;and&quot; don&#x27;t run. I think this comes from how important &quot;ing&quot; is in English. This takes precedence over the &quot;n&quot; key for rolls.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;but-is-it-good&quot;&gt;But is it good?&lt;&#x2F;h2&gt;
&lt;p&gt;I&#x27;ve been working with this keyboard layout from the perspective of potential speed. It&#x27;s still too soon to know how fast you can get with it.&lt;&#x2F;p&gt;
&lt;p&gt;There are also other considerations. Namely, does this help your hands? Layouts like qwerty over time can hurt your hands. Does Inas help at all with it? The jury is still out. One good iteration on what I have so far would be to score movements that are more ergonomic higher. Inas has some of that on a basic level by preferring smaller movements and preferring the home row. Are there more ergonomic patters to include? Undoubtedly.&lt;&#x2F;p&gt;
&lt;p&gt;If you give it a try, let me know how it goes for you.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;build-your-own&quot;&gt;Build your own&lt;&#x2F;h2&gt;
&lt;p&gt;If you want to improve what I have or build your own keyboard you can &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sophiajt&#x2F;create_keyboard_layouts&quot;&gt;try it out for yourself&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>YouTube addiction, one month sober</title>
        <published>2023-02-13T00:00:00+00:00</published>
        <updated>2023-02-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/youtube-addiction-one-month-sober/"/>
        <id>https://www.sophiajt.com/youtube-addiction-one-month-sober/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/youtube-addiction-one-month-sober/">&lt;p&gt;Today marks my first month &lt;a href=&quot;&#x2F;youtube-addiction&quot;&gt;clean from YouTube&lt;&#x2F;a&gt;. It was the right choice, but that&#x27;s not to say it was easy.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s talk about it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;quitting&quot;&gt;Quitting&lt;&#x2F;h2&gt;
&lt;p&gt;When I decided to do something about my addiction, I had a few choices:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Cut back the amount I was watching&lt;&#x2F;li&gt;
&lt;li&gt;Quit cold turkey&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;They both have their pluses and minuses, but by the time I figured out what was going I was &lt;em&gt;done&lt;&#x2F;em&gt; with being hooked on it. I was ashamed of getting caught up in it so badly. I chose going cold turkey.&lt;&#x2F;p&gt;
&lt;p&gt;Would I choose that path again? Good question, let&#x27;s explore it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;cold-turkey&quot;&gt;Cold turkey&lt;&#x2F;h2&gt;
&lt;p&gt;It was pretty soon after I decided to quit that I blocked YouTube on all my devices. For most things, that meant finding the &lt;code&gt;&#x2F;etc&#x2F;hosts&lt;&#x2F;code&gt; file or equivalent for the OS, and adding a line to set &lt;code&gt;youtube.com&lt;&#x2F;code&gt; to &lt;code&gt;127.0.0.1&lt;&#x2F;code&gt;. That effectively shuts you out of YouTube the site.&lt;&#x2F;p&gt;
&lt;p&gt;On my phone, I used &lt;code&gt;AppBlock&lt;&#x2F;code&gt; to block the website. I would have preferred to edit &lt;code&gt;&#x2F;etc&#x2F;hosts&lt;&#x2F;code&gt; like I did with my machines, but unfortunately that part of the filesystem is read-only, and can only be modified if you jail-break your phone. App it is.&lt;&#x2F;p&gt;
&lt;p&gt;Once I blocked it everywhere I could, I tested it a few times to be sure it was working. Satisfied, I settled in to see what would change.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;changes&quot;&gt;Changes&lt;&#x2F;h2&gt;
&lt;p&gt;A few things changed right away. Now that I wasn&#x27;t obliterating myself for 8-10 hours a day, I started noticing a lot of things. One was that on an average day prior to quitting YouTube, I consumed a &lt;em&gt;lot&lt;&#x2F;em&gt; of sugar. Multiple desserts, plus sugary snacks in between meals, that kind of thing.&lt;&#x2F;p&gt;
&lt;p&gt;Before, when I was watching hours of YouTube, I&#x27;m guessing I would get up and find something to snack on and sit back down. Now, I don&#x27;t have that kind of &quot;permanently distracted&quot; frame of mind, I notice that I eat fewer snacks and cut way back on the sugar.&lt;&#x2F;p&gt;
&lt;p&gt;I also had time to walk more - something I&#x27;ve always enjoyed. I started doing a 5km (3.1 mi) walk every morning. It takes me almost exactly an hour, and it&#x27;s a nice way to start the day.&lt;&#x2F;p&gt;
&lt;p&gt;But the real changes started happening with my mental health.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;mental-health&quot;&gt;Mental health&lt;&#x2F;h2&gt;
&lt;p&gt;One of the things that made me try to find out what was wrong with me was my declining mental health. Part of me wanted to become a shut-in and lose myself, and another part of me wanted to fight this. I felt worse as the weeks passed.&lt;&#x2F;p&gt;
&lt;p&gt;Once I stopped YouTube, I knew I needed a few things: I needed to understand &lt;em&gt;why&lt;&#x2F;em&gt; I got addicted in the first place, and I needed to work on healthier habits.&lt;&#x2F;p&gt;
&lt;p&gt;This is still very early on for me, but I wanted to mention a few things I did:&lt;&#x2F;p&gt;
&lt;p&gt;I talked to my doctor, who put me in for addiction counselling services. Here in New Zealand, you can get five free visits with an addiction counsellor as you begin your recovery.&lt;&#x2F;p&gt;
&lt;p&gt;I put in for the services, but I didn&#x27;t know how long it would take to get into the system, so I also looked around locally for a therapist who could also give some support. This was a private therapist, so there are costs associated with it.&lt;&#x2F;p&gt;
&lt;p&gt;The contrast between the two could not have been more stark. The therapist was very gentle and sympathetic. The counsellor... well, let&#x27;s say they have a specific task at hand.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why-are-you-addicted-and-what-can-you-do-better&quot;&gt;Why are you addicted and what can you do better?&lt;&#x2F;h2&gt;
&lt;p&gt;Addiction counselling, as best as I can figure, has a different goal that general therapy. They&#x27;re trying to hold up a mirror so you can see something very important for you to see: you are not taking care of yourself.&lt;&#x2F;p&gt;
&lt;p&gt;More than that - your brain, in your current state, is not your friend.&lt;&#x2F;p&gt;
&lt;p&gt;These are some hard truths to swallow.&lt;&#x2F;p&gt;
&lt;p&gt;You work on habits you can change: how to make small changes each day, how to think about rewards and how you&#x27;ve been making bad assessments of what rewards are for and what you should do with them.&lt;&#x2F;p&gt;
&lt;p&gt;Did I mention that&#x27;s all in the first half hour?&lt;&#x2F;p&gt;
&lt;p&gt;Then we started talking about the &quot;why&quot;, in the same way of holding up a mirror and talking through ways of working with this stuff. I won&#x27;t share the personal details here, but we covered a decent bit of ground. In the end, as best as I could understand, is that while you may have past experiences that caused your instincts to protect you, they&#x27;re just that. We all try to protect ourselves from pain and danger. This is a good thing, unless it goes too far and we lose the ability to take normal daily risks and live a healthy life.&lt;&#x2F;p&gt;
&lt;p&gt;In a sense, the goal of building new habits isn&#x27;t to only have new habits. It&#x27;s to start rewiring the brain to process risks, pain, and danger in a healthier way. There will always be risks, like crossing a street, and we re-learn how to work with them.&lt;&#x2F;p&gt;
&lt;p&gt;To some folks, that might sound like total common sense. If it does for you, that&#x27;s great. For me, it got surprisingly easy to create a safe illusion that turned into an unhealthy way to cope. I needed to see my way out of that.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;other-changes&quot;&gt;Other changes&lt;&#x2F;h2&gt;
&lt;p&gt;After talking with my doctor, I also started cooking more. I&#x27;m not a particular good cook (actually I&#x27;m pretty bad, though getting better).&lt;&#x2F;p&gt;
&lt;p&gt;The act of cooking and eating your own food, though, is therapeutic. You can see how healthy (or not) the food you make is. You know the ingredients that go into it. You can make enough for leftovers.&lt;&#x2F;p&gt;
&lt;p&gt;By the time I knew I needed to quit YouTube last month, I&#x27;d given up on cooking. I might make a pizza here or there, but almost all my lunches and dinners came from delivery food. Now, this is reversed. I&#x27;ll still get the occasional delivery, but almost all of what I eat these days I make.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;cravings&quot;&gt;Cravings&lt;&#x2F;h2&gt;
&lt;p&gt;You may wonder how the actual quitting part is going. The short answer is that I have good days and bad days.&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s surprisingly easy some days to fill a day with fun things to do, so that I don&#x27;t even notice it passing. Other days, I might do some work on the computer and then lay in the floor thinking about stuff I want to watch, scheming ways I could justifying watching &lt;em&gt;some&lt;&#x2F;em&gt; YouTube. That voice that says &quot;watch a few hours to scratch the itch&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;This, I know, would be a bad idea(tm).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;content-as-an-addiction&quot;&gt;Content as an addiction&lt;&#x2F;h2&gt;
&lt;p&gt;In talking with lots of folks, at this point I&#x27;m convinced we&#x27;ve got content wrong. At least, how it&#x27;s delivered to us.&lt;&#x2F;p&gt;
&lt;p&gt;You can take most of them and understand the business model as &quot;retention = profits&quot;. The more time you spend on the site, the longer your eyeballs are taking in the ads and related, the more money the site makes off of you.&lt;&#x2F;p&gt;
&lt;p&gt;The way sites like TikTok and YouTube give you a feed of content means you can consume it in an unbroken fashion. It reminds me of the people you see at slot machines in casinos, pulling the lever to see what will happen. Maybe you&#x27;ll get lucky and come across something awesome.&lt;&#x2F;p&gt;
&lt;p&gt;The content also keeps you in a kind of trance - a state where you don&#x27;t &lt;em&gt;have&lt;&#x2F;em&gt; to think if you don&#x27;t want to.&lt;&#x2F;p&gt;
&lt;p&gt;I feel like one of those people complaining about how televisions make us zombies.&lt;&#x2F;p&gt;
&lt;p&gt;I chatted with my addiction counsellor about about social media platforms, and I&#x27;m sure you&#x27;re not at all surprised that they&#x27;re also addictive.&lt;&#x2F;p&gt;
&lt;p&gt;I don&#x27;t want this post to be &lt;em&gt;just&lt;&#x2F;em&gt; about the dangers of these platforms. There&#x27;s more to it than I can really cover here, and those platforms can be used for good as well. The main thing, for me, is how they interact with our brains. Are we still able to live healthy lives? Form deep healthy relationships? Take daily risks of being our complete selves? Are our brains staying healthy?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reaching-out&quot;&gt;Reaching out&lt;&#x2F;h2&gt;
&lt;p&gt;Probably the most important thing, though, is to directly target what I needed most of all. Addiction is isolating. The particular addiction, YouTube, is a lot of wanting to connect to others in a very safe way. So, to combat this, the goal is to &quot;reach out&quot;. To connect to real people. To get my &#x27;cup&#x27; filled with real intimacy and connections with others.&lt;&#x2F;p&gt;
&lt;p&gt;What in the world that means is something I&#x27;m trying to figure out. I know that my cup was very, very empty. Despite having so many friends, fun online interactions, game nights, etc. Those things are great, but they don&#x27;t meet the need for real connection.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m signing up for meetups, volunteering, and going and chatting with random people where I can to get face-to-face interactions again.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;step-at-a-time&quot;&gt;Step at a time&lt;&#x2F;h2&gt;
&lt;p&gt;That&#x27;s it. That&#x27;s where I&#x27;m at. Figuring out what I can, making changes where I can, and learning as I go.&lt;&#x2F;p&gt;
&lt;p&gt;To all the folks who reached out with their stories of struggles and recovery: thank you. Sincerely, thank you. The suggestions and words of encouragement have helped. Thanks for that.&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s to the hope my cup, and yours, will be filled.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>YouTube Addiction</title>
        <published>2023-01-13T00:00:00+00:00</published>
        <updated>2023-01-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/youtube-addiction/"/>
        <id>https://www.sophiajt.com/youtube-addiction/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/youtube-addiction/">&lt;p&gt;Hi, I&#x27;m a YouTube addict.&lt;&#x2F;p&gt;
&lt;p&gt;I know what you&#x27;re thinking. That sounds like a joke. That you want a funny punchline to go with it. Me too.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;first-time-i-noticed&quot;&gt;First time I noticed&lt;&#x2F;h2&gt;
&lt;p&gt;Truth is, though, I&#x27;ve had a problem for a while. I first noticed it back in 2011. Back then, I could feel it growing. I would spend something like 3 hours at night on weekdays and maybe around 10 hours total on the weekends on YouTube. I was mostly watching &quot;let&#x27;s plays&quot;. Long, winding playthroughs of video games with a friendly voice. Each series might, in total, be something like 40+ hours of content. Of which, the most prolific Let&#x27;s Play-ers have dozens, if not hundreds, of series. From one creator, you&#x27;d find another, and another. Already, back in 2011 watching my little niche, it was more content than anyone one person would ever be able to watch in a lifetime.&lt;&#x2F;p&gt;
&lt;p&gt;I would nap watching a series, and wake up to that same familiar voice. Episode after episode, I watched myself go deeper into the rabbit hole.&lt;&#x2F;p&gt;
&lt;p&gt;At the time, I told my roommate that I thought I might have a problem. He thought the entire concept of being addicted to something like YouTube was laughable. How could someone be addicted to watching some videos on a website? Maybe some of you reading this are thinking the same.&lt;&#x2F;p&gt;
&lt;p&gt;Still, it felt like the right thing at the time to try to curb this growing habit. I bought a stack of books on things like meditation and self-help and read everything I could. It helped a little. Meditation helped me to see just how much stress I was taking on. At the time, my roommate and I were interning at Apple. The pressure was high to do well and get noticed.&lt;&#x2F;p&gt;
&lt;p&gt;I made a promise to myself as I got into self-help and meditation that I would stop using YouTube as a way to soothe this stress. That I could find other ways.&lt;&#x2F;p&gt;
&lt;p&gt;I remember when I slipped back into it. My favorite YouTube content creator - after not posting for over a year - had posted the start of a new series. By this point, I&#x27;d been off YouTube for almost a year. I was used to doing other things with my time. And yet, when they posted that video, and I got a notification, I didn&#x27;t say no. Since then, I don&#x27;t think I&#x27;ve ever taken more than a couple months break from it. When I slip back into it, it effortlessly returns to being part of my daily routine.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-do-you-mean-by-addicted&quot;&gt;What do you mean by addicted?&lt;&#x2F;h2&gt;
&lt;p&gt;Yesterday, I watched 572 minutes of YouTube. That&#x27;s just over 9.5 hours. The day before it was 444 minutes. Just shy of 7.5 hours. The day before that was 510 minutes. 8.5 hours.&lt;&#x2F;p&gt;
&lt;p&gt;Sometimes it&#x27;s background sound to whatever I&#x27;m doing. But if I&#x27;m honest, most of the time I&#x27;m just watching, going from video to video. Not doing anything else. At this point, I have so many interests I&#x27;ll watch content for. Climbing videos, computing history, endless amounts of video game footage, music videos, concert footage, interviews, wordless videos of food being prepared in the morning in Japanese restaurants. Anything that could catch my eye, I&#x27;d watch. It&#x27;s gotten to the point where I don&#x27;t really enjoy the video as much as the numb hypnotic state from consuming that much content.&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s safe. It&#x27;s always there.&lt;&#x2F;p&gt;
&lt;p&gt;But I noticed something recently. I&#x27;ve been struggling with my mental health during the summertime, a time I traditionally have fewer problems. I wasn&#x27;t recharging like I should. I was waking up tired, napping during the day, and generally not feeling at all prepared when the day started.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;d tried to dial back on my commitments to see if I could recover. Weeks later, and I&#x27;m still not recovering.&lt;&#x2F;p&gt;
&lt;p&gt;It didn&#x27;t really hit me until today, when talking to a close friend, that it might be the amount of YouTube I&#x27;m watching. That&#x27;s when I took my calculator and added it up.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-familiar-story&quot;&gt;A familiar story&lt;&#x2F;h2&gt;
&lt;p&gt;I&#x27;ve heard this before. I had an alcoholic roommate years ago describe in detail what it was like for them to be an alcoholic. Why they would reach for it. When they&#x27;d reach for it. How they&#x27;d plan their life around it. Get the work done and use it to celebrate.&lt;&#x2F;p&gt;
&lt;p&gt;I feel like my use of YouTube has basically mirrored their alcoholism at this point. If anything, I spend more time in stupor than they did with alcohol.&lt;&#x2F;p&gt;
&lt;p&gt;The truth is, I don&#x27;t know how long I&#x27;ve been this bad. I keep clearing my YouTube history. Ostensibly, it&#x27;s so I can get better recommendations. But the truth is probably that I&#x27;m also trying to hide how bad it&#x27;s gotten from myself.&lt;&#x2F;p&gt;
&lt;p&gt;My roommate, when they finally came out about their struggles, let us clean their bedroom. I just remember duffle bag after duffle bag of empty bottles. It took so long to clean out their room because there were so many. I couldn&#x27;t fathom how anyone could drink so much. It had to be hundreds of bottles.&lt;&#x2F;p&gt;
&lt;p&gt;I don&#x27;t know how long I&#x27;ve been averaging over 8 hours a day, but I&#x27;m afraid it&#x27;s been a long time.&lt;&#x2F;p&gt;
&lt;p&gt;I remember telling myself years ago that as long as I was getting my work done it didn&#x27;t really matter what I did.&lt;&#x2F;p&gt;
&lt;p&gt;I remember my roommate saying the same thing.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;quitting&quot;&gt;Quitting&lt;&#x2F;h2&gt;
&lt;p&gt;I always thought that it&#x27;s easy to quit something. You just don&#x27;t do it. So naive.&lt;&#x2F;p&gt;
&lt;p&gt;This isn&#x27;t going to be easy. There are so many temptations to pull me back in that it&#x27;ll be a challenge to try to put this behind me. I mean, I&#x27;m a YouTube content creator now approaching 10k subs - a respectable number for a small channel. So much educational content is on YouTube. So much of how I get my name out is via YouTube. So much of what I do is attached to YouTube for good and for bad.&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s really all of the above. It&#x27;s true it has all these nice aspects. But for folks like me, who take it to an extreme, it very politely chews its way into your life and makes it far too tempting to sink deeper and deeper.&lt;&#x2F;p&gt;
&lt;p&gt;I don&#x27;t want to lose the audience I&#x27;m building, but I also want to be healthy. I&#x27;m afraid for myself and where I&#x27;ll be five years from now. Will I be worse than I am now if I don&#x27;t take steps? Will I become more withdrawn, stop working altogether, and live on my savings until I run out?&lt;&#x2F;p&gt;
&lt;p&gt;I think about other things, too, like &quot;How will I fill my days if I stop&quot;? I honestly don&#x27;t know. It&#x27;s scary to think about having a hole and not being able to fill it with that comfortable &quot;zoning out&quot; feeling.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m sure some folks are thinking &quot;what if you just limit yourself to 30 minutes a day?&quot;&lt;&#x2F;p&gt;
&lt;p&gt;That&#x27;s just it. If I could do that, I would have.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;admitting-it&quot;&gt;Admitting it&lt;&#x2F;h2&gt;
&lt;p&gt;I don&#x27;t know if I want to do a 12-step program or whatever. I honestly haven&#x27;t really figured anything out at this point. But the first thing I wanted to do was come clean and talk about where I&#x27;m at. If you&#x27;re someone reading this with similar patterns, you&#x27;re not alone.&lt;&#x2F;p&gt;
&lt;p&gt;I also wanted to write this all down to make a record of where I am. Maybe I&#x27;ll come back and read this later. Maybe I&#x27;ll be able to say something like &quot;I remember being hooked on YouTube for over 12 years. I&#x27;m glad I cleaned up.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s hope. Maybe then I&#x27;ll think up a good punchline, too.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>The goal is to nourish</title>
        <published>2022-12-23T00:00:00+00:00</published>
        <updated>2022-12-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/the-goal-is-to-nourish/"/>
        <id>https://www.sophiajt.com/the-goal-is-to-nourish/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/the-goal-is-to-nourish/">&lt;p&gt;I just finished watching the movie called Stutz, a movie created by Jonah Hill about his psychiatrist. Through the movie, Stutz gives bite-sized practices drawn from Buddhism, psychiatry, and his own experiments. One of the themes is to accept that connection is the goal (connection with others, ourselves, and our body) and we connect using, among other things, vulnerability.&lt;&#x2F;p&gt;
&lt;p&gt;For years, I&#x27;ve thought about a conversation I had with a friend of mine. He had worked with David Schnarch, a well-known psychology that wrote books like Passionate Marriage. In my friends work with David, they worked towards an end goal where yes, we should recover from our pain and trauma, and that will be work we continue with, but that we also have a choice to put light back out into the world.&lt;&#x2F;p&gt;
&lt;p&gt;I knew as I talked to my friend about this, that this was unshakeably the goal. I knew that I could put my fears and trauma out into the world, but I also knew that without the light, it wouldn&#x27;t end up helping myself or others. Not in the sense of sugar-coating my experiences, but rather that there is a light within us that is part of who we are, and that we can share our experiences &lt;em&gt;and&lt;&#x2F;em&gt; share our light at the same time. We don&#x27;t have to hide our light for others to see our pain. We can show up as ourselves.&lt;&#x2F;p&gt;
&lt;p&gt;Showing up, being vulnerable, being willing to fall on my face has always been hard for me. I wanted nothing more than to the gifted kid that never made errors. I wanted people to look up to me. To see me as some kind of spiritual giant. Or great intellect. To do nearly super-human feats.&lt;&#x2F;p&gt;
&lt;p&gt;It wasn&#x27;t until I got older that I started to see those desires as part of wanting to hide. If I do super-human feats, perhaps people will be distracted from the fact that I&#x27;m still a very human human.&lt;&#x2F;p&gt;
&lt;p&gt;In recent years, I&#x27;ve started to slowly understand how intimacy and vulnerable don&#x27;t have to come with rejection. Sure, someone may respond poorly to what I&#x27;m sharing, which hurts my feelings and makes me want to hide. But I&#x27;m also there in the room as I&#x27;m sharing. I&#x27;m also able to be a light for myself in that moment. When you carry your own light, now others can have their experiences, too, and you can hold space for them.&lt;&#x2F;p&gt;
&lt;p&gt;Maybe it&#x27;s from playing too much Stardew Valley, but I just get this mental image of waking up every morning and watering the crops. It becomes so routine you almost don&#x27;t think about it.&lt;&#x2F;p&gt;
&lt;p&gt;It teaches a subtle lesson. That if you nourish other beings a little each day, you grow as a result. I don&#x27;t mean giving when you have nothing to give, draining the last bit of blood from your body. I mean just like you breathe oxygen, exercise, and try to eat well, giving a little to others is part of a healthy life.&lt;&#x2F;p&gt;
&lt;p&gt;This morning I struggled with derealisation. It&#x27;s an uncomfortable mental state where everything feels unreal. You may feel like you&#x27;re watching yourself or your surroundings, but rather than you being the focus, it feels like you&#x27;re watching a movie. I didn&#x27;t panic. I just told myself that in the coming hours that it may go away and that I should give myself time to check in a little later and see if it&#x27;s improved a little. By afternoon, it had lifted.&lt;&#x2F;p&gt;
&lt;p&gt;I don&#x27;t recount that as a kind of &quot;wow, I&#x27;m great&quot; moment. Instead, I share it because it&#x27;s interesting to contrast what it was like 10 years. Months of gray weather in Seattle was too much for me, and I would go through weeks of on and off dealing with feeling like I was in a movie. It drained me. I panicked, worried, and felt like I didn&#x27;t really have any grounding.&lt;&#x2F;p&gt;
&lt;p&gt;While I think part of being able to deal with it comes with practice, I also think there&#x27;s another important component. Feeling more connected, feeling like you can still live your life and use what you have to connect to other people (even in small ways) meant I didn&#x27;t have to solve the problem right then or risk losing any hope of love and connection in my life. The love and connection are there, whether or not I could see and feel them. And they&#x27;d be waiting for me. And that comes from the regular nourishing of those connections, both with myself and with others.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m not entirely sure how best to end this post. It&#x27;s not like there&#x27;s a magic formula that if you follow it you never hurt and never feel alone. I just wanted to share that having moments of appreciation with other people - even during difficult times - has been an important piece of the journey for me.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Autism is everywhere and in everything</title>
        <published>2022-07-13T00:00:00+00:00</published>
        <updated>2022-07-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/autism-is-everywhere-and-in-everything/"/>
        <id>https://www.sophiajt.com/autism-is-everywhere-and-in-everything/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/autism-is-everywhere-and-in-everything/">&lt;p&gt;I&#x27;ve been thinking recently about being on the Autistic spectrum.&lt;&#x2F;p&gt;
&lt;p&gt;But first, some trigger warnings: topics include some talk of sex and gender, emotional pain, burnout.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;i-thought-it-was-about-sexuality-or-gender-or&quot;&gt;I thought it was about sexuality, or gender, or...&lt;&#x2F;h2&gt;
&lt;p&gt;I&#x27;ve wanted to talk about this for a long time. Before coming out as non-binary, I was diagnosed in 2020 as being on the autistic spectrum. It hadn&#x27;t even crossed my mind until a close friend recommended I look into it.&lt;&#x2F;p&gt;
&lt;p&gt;As I sat reading my diagnosis I just kinda started to unzip the first outer coat of many coats I&#x27;d learned to wear for the first 40 years of my life. I listened to podcasts, read articles, listened to other folks, and just tried to understand anything. Even more fundamental than sexuality, or understanding gender, was this idea that I had be fighting extremely hard to look and appear normal to the world.&lt;&#x2F;p&gt;
&lt;p&gt;I was exhausted.&lt;&#x2F;p&gt;
&lt;p&gt;Exhausted of opening up to people only to have them leave when they couldn&#x27;t handle the intensity that comes naturally when I let my guard down. Instead of punishing myself, though, I had a key to understand something fundamental about myself. The way I viewed the world and how the world interacted with me as an experience was profoundly different than it was for most other people.&lt;&#x2F;p&gt;
&lt;p&gt;With each thought, I felt like I stripped off another outer coat and set it aside, until I could no longer understand how to communicate with people anymore. I still knew the tricks I&#x27;d learned. I still know how to &quot;mask&quot;, to use patterns I&#x27;d seen other people use to appear more normal. But what I wanted to know was &quot;what was I like when I didn&#x27;t do that?&quot;. In essence, who was I?&lt;&#x2F;p&gt;
&lt;p&gt;When I told my ex, who I&#x27;d recently separated from, that I had been diagnosed she laughed at me. Rather than getting angry, it confirmed for me what I&#x27;d already known - there&#x27;s just a deep-seated difference in the needs I have and the needs she had. In hindsight, it also confirmed another sad aspect of being on the spectrum: you can have a very large tolerance for people having bad expectations of you because you learn at an early age that you must accommodate others in order to survive. You have no basis for what a good boundary is. Perhaps just as bad, in my case I&#x27;ve found it exceedingly difficult to feel when the other person loves me, respects me, or otherwise. So I kept working harder in the hopes that at some point in the future something will feel right and things would click.&lt;&#x2F;p&gt;
&lt;p&gt;For months after my diagnosis, I worked backwards. I wanted to reach an earlier version of myself to see how long I&#x27;d been this way. You&#x27;ll probably be unsurprised to learn I&#x27;ve always been this way. I remembered countless events that now made so much more sense. Times of overstimulation, panic, being unable to understand why my parents were punishing me, feeling completely lost as to why the kids at the new school did things and why they singled me out.&lt;&#x2F;p&gt;
&lt;p&gt;In time, as I worked backward, I began to ask questions like &quot;how does sexuality relate to autism?&quot; and &quot;how does gender relate to autism?&quot;. Though the research here is fairly new, I came across terms like &quot;neuroqueer&quot; that talked about how autism can &quot;queer&quot; your own perception of your gender and sexuality.&lt;&#x2F;p&gt;
&lt;p&gt;Wait. What?&lt;&#x2F;p&gt;
&lt;p&gt;I tested it on myself. Was that what was happening? The more I let myself just experience my inner world and not require myself to use images and concepts that I learned from outside, the more I saw sexuality and gender as basically formless goo. A kind nothing concept that carried value for others, but didn&#x27;t seem to hold much importance to me.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;when-i-say-i-m-non-binary-i-mean&quot;&gt;When I say I&#x27;m non-binary, I mean...&lt;&#x2F;h2&gt;
&lt;p&gt;...gender doesn&#x27;t make sense to me as an internal experience. I wear the clothes I wear because I own them and they fit. I&#x27;m not thinking about what I&#x27;m wearing or how I&#x27;m presenting myself outside of the house unless my clothes are stained and dirty.&lt;&#x2F;p&gt;
&lt;p&gt;Gender, to me, feels like those clothes.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-it-is-like&quot;&gt;What it is like&lt;&#x2F;h2&gt;
&lt;p&gt;Sex is nice, but it has nothing on the bliss of a hyperfocus. Losing track of time, where hours are there merely to serve as a dimensional tube to channel more of your topic into you. People are lovely and should be a part of life, but it&#x27;s sad that many folks will never understand what it&#x27;s like.&lt;&#x2F;p&gt;
&lt;p&gt;But this coin is so easily two-sided. In the computer industry, many a company has noticed that as long as they keep people like me &quot;entertained with hard problems&quot; we&#x27;re happy. That is, until we burnout because no one reminded us to take care of ourselves.&lt;&#x2F;p&gt;
&lt;p&gt;What it&#x27;s like for me:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Imagine not knowing if your partner likes you or if they&#x27;re just tolerating you. Imagine this going on for years.&lt;&#x2F;li&gt;
&lt;li&gt;Imagine being in a tumble dry cycle of ups and downs and feeling like you come out of every social situation worse than you started.&lt;&#x2F;li&gt;
&lt;li&gt;Imagine letting yourself enjoy a topic you find fascinating and the joy feels nearly limitless as you dig deeper. Imagine this lasting for days, weeks, months, or even years.&lt;&#x2F;li&gt;
&lt;li&gt;Imagine being told you&#x27;re weird most of your life and finding the only way to feel &quot;not weird&quot; is to completely ignore yourself.&lt;&#x2F;li&gt;
&lt;li&gt;Imagine not having the ability to socially read the person in front of you until you&#x27;ve spent many hours with them, or they remind you of someone you knew 10 years ago and you hope that they&#x27;re similar enough they&#x27;ll react to the same things.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;If this sounds like you, perhaps you&#x27;re like me. If so, welcome to the club.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;autism-club&quot;&gt;Autism club&lt;&#x2F;h2&gt;
&lt;p&gt;In autism club, we embrace what we are and who we are. There are snacks, heavy blankets, endless libraries, friends to do projects with, calm lighting, soft sounds, and a universal welcome to any and all parts of you. You don&#x27;t have to mask, and we won&#x27;t ask you to. Autism club is welcome to all ages. It is our hope that young and old from all walks of life will join this club and bring who they are to it.&lt;&#x2F;p&gt;
&lt;p&gt;We make this club for ourselves.&lt;&#x2F;p&gt;
&lt;p&gt;Here you can feel your feelings in the way they come out, as intense as they are or even the mildest whisper. You don&#x27;t have to cut them off. You don&#x27;t have to ignore the urge to self-stimulate to help direct the energies you feel.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;carrying-the-club-with-you&quot;&gt;Carrying the club with you&lt;&#x2F;h2&gt;
&lt;p&gt;I&#x27;ve been trying to learn how to carry autism club with me, wherever I go. Not only so I can be welcoming to others, but I can also be welcoming to myself. The term self-care feels like it almost gets overused these days, but it&#x27;s still just as important. Checking in and understanding your needs -- even the ones you were taught to ignore -- opens the door to giving yourself space.&lt;&#x2F;p&gt;
&lt;p&gt;I, for one, need that space. And I hope as I grow older, perhaps I&#x27;ll also grow more capable of being a better support to myself and others. Perhaps I&#x27;ll also find the right people who can be that to me in return.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;and-then&quot;&gt;And then?&lt;&#x2F;h2&gt;
&lt;p&gt;As I write this, I don&#x27;t have the perfect thought to end on. Just this idea that everything is ever changing, and that&#x27;s us too. There isn&#x27;t an endpoint to this journey because what it means to think and feel and experience the world through the way we process information is so central. I carried it with me into the start of this post. And, as I finish, I&#x27;ll carry it with me from here.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>How we judge things</title>
        <published>2022-06-23T00:00:00+00:00</published>
        <updated>2022-06-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/how-we-judge-things/"/>
        <id>https://www.sophiajt.com/how-we-judge-things/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/how-we-judge-things/">&lt;p&gt;I&#x27;ve been thinking recently...&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-good-the-bad-and-the-average&quot;&gt;The good, the bad, and the average&lt;&#x2F;h2&gt;
&lt;p&gt;Do you ever wonder about how we judge things? By this I mean, let&#x27;s say we go to a restaurant with a friend. The meal is going well enough, then towards the middle of the meal we try our friend&#x27;s dish. Wham! It&#x27;s amazing!&lt;&#x2F;p&gt;
&lt;p&gt;How do we judge the restaurant? Do we say it&#x27;s just okay because that&#x27;s how we felt about our meal? Or do we say it&#x27;s amazing because of the bite we had of our friend&#x27;s meal?&lt;&#x2F;p&gt;
&lt;p&gt;Say we go watch a movie. The movie is pretty good, but there&#x27;s this 20 minute section in the last third that just feels like it goes forever. Was the movie good, since we enjoyed the majority of it? Or do we feel the movie was a big let-down because of the drag at its slowest point?&lt;&#x2F;p&gt;
&lt;p&gt;Do we judge something by its best moment, its worst moment, or by its average moment? There&#x27;s also the question to ask - do we judge something by our experience or by the experience of those around us? - but I&#x27;m more interested in our subjective experience for now.&lt;&#x2F;p&gt;
&lt;p&gt;Noticing how we do this for various forms of entertainment, we can also turn our eyes toward how we judge people. People we&#x27;ve just met. People we&#x27;re friends with. Relationships we&#x27;re in and how people act in those relationships. Do we judge people by their best moment? Worst moment? Or average moment?&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s not that these are set in stone. For example, in social media perhaps we follow people who we feel on average are entertaining. Maybe some tweets don&#x27;t makes us laugh, but enough do that we stick around. Let&#x27;s say something comes out of their past that casts a shadow over them. We may shift from judging their average moment to now judging them by their worst.&lt;&#x2F;p&gt;
&lt;p&gt;What I&#x27;ve wondered for myself is this - do I know what style of judgement I&#x27;m choosing? And, is that the appropriate kind of judgement for this situation?&lt;&#x2F;p&gt;
&lt;p&gt;Imagine you have a friend that&#x27;s generally fun, but sometimes is cruel. If you judge them by their best moments, you might get a sense of them &quot;having such potential&quot; because you see the high points. If you judge them by their average, perhaps you seem them as &quot;a fun person, with a few quirks&quot;. If, instead, you judge them by their low moments, you may think &quot;you know, they actually can be pretty mean&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;It seems like, in a way, all of these are true at once. It&#x27;s us, as the judge, who get to say how much weight we put on each type of judgement.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;redemption&quot;&gt;Redemption&lt;&#x2F;h2&gt;
&lt;p&gt;Stories give us another way to see how we view things as they tend to exaggerate some aspect of the human existence. One aspect of some stories is the &quot;redemption arc&quot;. Can we see this in the context of the judgement from earlier?&lt;&#x2F;p&gt;
&lt;p&gt;If we judge Darth Vader, we might get three different answers:&lt;&#x2F;p&gt;
&lt;p&gt;By their best moment: a hero!
By their average: a pretty bad person
By their worst: a monster&lt;&#x2F;p&gt;
&lt;p&gt;Stories like to tug on our emotions by playing against these different feelings, but what about how this translates to how we interact with people in the real world. Are we able to judge correctly if someone has redeemed themselves?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;person-or-situation&quot;&gt;Person or situation&lt;&#x2F;h2&gt;
&lt;p&gt;I was recently listening to a podcast, and the speaker mentioned a bit of advice they had gotten: if you are leading a team, do not be afraid to fire people. If working with them is taking energy, and that energy isn&#x27;t making the product or you stronger, cut them off.&lt;&#x2F;p&gt;
&lt;p&gt;It felt so cold, and yet, there&#x27;s something decisive about it. They&#x27;re looking at what is happening and judging not just the person but the situation as a whole. Are things going in the right direction? Even if someone is a star engineer on the team, if the situation shows that their average is that the whole team drags as a result of their actions, then perhaps that judgement is more important than their star contributions?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-personal-note&quot;&gt;A personal note&lt;&#x2F;h2&gt;
&lt;p&gt;I was raised to give people second chances. To be forgiving. That forgiveness was part of what you did. In hindsight, this seems to be asking us to focus only on the best moments, or perhaps to focus on the average at the expense of the bad. Instead, we should respect all of our judgements of both people and situations we find ourselves in. To weigh them all, so that we understand them, and then act based on all we see without letting ourselves be pre-disposed to any one style.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Scripting languages of the future</title>
        <published>2021-10-31T00:00:00+00:00</published>
        <updated>2021-10-31T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/scripting-languages-of-the-future/"/>
        <id>https://www.sophiajt.com/scripting-languages-of-the-future/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/scripting-languages-of-the-future/">&lt;p&gt;I&#x27;ve been thinking recently about what the future for scripting languages could look like. We&#x27;ve had a good run with Python, JavaScript, and Ruby for the last few decades. I wondered, what might the next few decades look like.&lt;&#x2F;p&gt;
&lt;p&gt;What is the scripting language of the future? How should it work? Here are some thoughts.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;scalability&quot;&gt;Scalability&lt;&#x2F;h2&gt;
&lt;p&gt;Working on &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;devblogs.microsoft.com&#x2F;typescript&#x2F;announcing-typescript-0-9&#x2F;&quot;&gt;TypeScript&lt;&#x2F;a&gt;, something that became a constant refrain for us was that &quot;TypeScript is JavaScript that scales&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;I might be a bit biased, but this &lt;em&gt;is&lt;&#x2F;em&gt; actually incredibly valuable. If your team invests time into writing an app in a scripting language, there shouldn&#x27;t be an impedance mismatch that grows as the app gets larger. For JavaScript, we&#x27;d watch teams grow their apps only to have to increase testing and onboarding training to prevent bugs from creeping in. And yet, they still crept in.&lt;&#x2F;p&gt;
&lt;p&gt;TypeScript gave tools a chances to catch these errors earlier, even in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;devblogs.microsoft.com&#x2F;bharry&#x2F;typescript-a-real-world-story-of-adoption-in-tfs&#x2F;&quot;&gt;well-tested codebases&lt;&#x2F;a&gt;. Back in 2012, this was something viewed with a healthy dose of skepticism, and today &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;insights.stackoverflow.com&#x2F;survey&#x2F;2021#most-popular-technologies-language-prof&quot;&gt;over third of professional developers use TypeScript&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;What TypeScript showed is that you could join together the idea of a flexible lightweight (and optional!) type system onto an existing programming language, and do so successfully.&lt;&#x2F;p&gt;
&lt;p&gt;The question then is - what if you created a programming language from the start to have this kind of support? No need for transpilers, while also having stronger engine integration and maybe even better runtime errors?&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s a tempting mix of possibilities and one well worth being a part of the scripting language of the future.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;tune-ability&quot;&gt;Tune-ability&lt;&#x2F;h2&gt;
&lt;p&gt;I&#x27;ve known multiple people who were hired to rewrite a piece of infrastructure originally written in a scripting language. Just like scripts need to be able to scale to larger sizes, scripts need to be tune-able. The choice to go dynamic shouldn&#x27;t be a hard stop on real performance tuning and maintenance.&lt;&#x2F;p&gt;
&lt;p&gt;The work on numpy, scipy, pandas and others for Python is one possible blueprint. Instead of having to leave your language of choice, powerful libraries build up around it to support the high performance needs of different disciplines.&lt;&#x2F;p&gt;
&lt;p&gt;There will likely be some resistance to this point, as there seems to be just an inevitable trade-off between performance and the flexibility that a scripting language provides. In all honesty, this feels like an older, and perhaps outdated, way of looking at this trade-off.&lt;&#x2F;p&gt;
&lt;p&gt;For years, JavaScript developers have looked to techniques like &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;wolfram-developers&#x2F;performance-through-elegant-javascript-15b98f0904de&quot;&gt;monomorphism&lt;&#x2F;a&gt; to tune the performance of JavaScript code. They&#x27;re structuring code in a way that&#x27;s more &quot;VM friendly&quot;. The VM has to do less work to understand the types and structures in the code, and as a result guesses correctly the first time when doing runtime code generation.&lt;&#x2F;p&gt;
&lt;p&gt;The ability to tune code can come from other sources, too. Type decorations is one tempting direction to mention, though so far no established languages (that I know of) have used the technique to general type hints to speed up code. Unless type hints are used across hot paths, and with a sound type system, the transformations risks actually slowing performance.&lt;&#x2F;p&gt;
&lt;p&gt;There is, however, a large exception. Dataframe systems like pandas structure operations across arrays of known types. While the setup code is all in Python, the code that actually runs is happily in systems-level tuned native libraries. In a way, Python is merely orchestrating these operations.&lt;&#x2F;p&gt;
&lt;p&gt;Future languages could take advantage of this pattern in other ways. The associated standard libraries of these scripting languages could encourage more orchestration and less manual processing in the language itself.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;easy-parallelism&quot;&gt;Easy parallelism&lt;&#x2F;h2&gt;
&lt;p&gt;On a related point to the one above: future languages need easy parallelism. By now, we&#x27;ve heard it a million times. The &quot;free lunch is over&quot;, tomorrow&#x27;s CPUs will have a zillion cores and will run at 1hz. Okay, maybe not quite that bad, but still the writing is very clearly on the wall and very much already happening. It&#x27;s not far-fetched to imagine that today&#x27;s 8-16 core machines over the next few decades grow to be dozens or even hundreds of cores. Any language that hopes to have a strong footing, even scripting languages, need to be able to handle this.&lt;&#x2F;p&gt;
&lt;p&gt;This isn&#x27;t without its own challenges. As has been quotes a few times recently, Matz - the creator of Ruby - famously said &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;betterprogramming.pub&#x2F;ruby-has-its-own-2020-new-years-resolution-77b801dfaacc&quot;&gt;&quot;I regret adding threads&quot;&lt;&#x2F;a&gt;. Having now used a lot of different kinds of parallelism systems in a lot of languages, I can easily see why. Traditional threading, and things like it, honestly feel like goto to me. Just like goto, it&#x27;s easy to write code that&#x27;s hard to read and, over time, hard to maintain.&lt;&#x2F;p&gt;
&lt;p&gt;Luckily, traditional threads aren&#x27;t the only game in town. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rayon-rs&#x2F;rayon&quot;&gt;Work-stealing task pools&lt;&#x2F;a&gt; like popular libraries in Rust use are very fast and can be built to work with other abstractions like parallel iteration and reduction operations.&lt;&#x2F;p&gt;
&lt;p&gt;Making abstractions like this part of the language gives more opportunity to use more of the machine across all scripts written in that language. All this without, we hope, running afoul of the design choices that make language creators mourn years later.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;ide-support&quot;&gt;IDE support&lt;&#x2F;h2&gt;
&lt;p&gt;This might sound completely alien to some folks, but the future for scripting languages includes strong IDE support. Gone are the days of most scripting being written in a simple text editor. Today, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;2020.stateofjs.com&#x2F;en-US&#x2F;other-tools&#x2F;#text_editors&quot;&gt;more than 86% of JavaScript is developed in an IDE&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Future languages are competing against established languages which have tooling and IDE support polished over many years. Any new language that wants to compete against that will have to swing for the fences.&lt;&#x2F;p&gt;
&lt;p&gt;At a minimum, support for the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;microsoft.github.io&#x2F;language-server-protocol&#x2F;&quot;&gt;language server protocol&lt;&#x2F;a&gt; these days in a must. Its broad support across editors gives languages much more leverage than ever before to get in front of developers.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;looking-ahead&quot;&gt;Looking ahead&lt;&#x2F;h2&gt;
&lt;p&gt;There&#x27;s definitely a large space to explore for scripting languages of the future. The points I list above are important, as are additional points that we&#x27;ll learn as we go. Perhaps we&#x27;ll be able to bring the performance that more modern JS engines enjoy to a broader range of languages through an effort similar to what LLVM did for lower-level languages.&lt;&#x2F;p&gt;
&lt;p&gt;I, for one, am looking forward to this future and what future languages it will bring.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Let&#x27;s talk about exit codes</title>
        <published>2021-10-16T00:00:00+00:00</published>
        <updated>2021-10-16T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/exit-codes/"/>
        <id>https://www.sophiajt.com/exit-codes/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/exit-codes/">&lt;p&gt;Before &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.nushell.sh&#x2F;&quot;&gt;starting a shell&lt;&#x2F;a&gt;, if you would have asked me what an exit code was, I would have quickly replied &quot;0 for success, non-zero for failure&quot; without batting an eye. That&#x27;s what it meant, right?&lt;&#x2F;p&gt;
&lt;p&gt;Today, someone filed an &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;nushell&#x2F;nushell&#x2F;issues&#x2F;4082&quot;&gt;issue on the Nushell repo&lt;&#x2F;a&gt;. In it, they ran &lt;code&gt;git log&lt;&#x2F;code&gt;, exited, and Nushell reported the command to have failed.&lt;&#x2F;p&gt;
&lt;p&gt;To know why it happens, we&#x27;ve got to do some digging. First, let&#x27;s take a look at the standards to understand what we should expect.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;what-the-standard-says&quot;&gt;What the standard says&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;bash&quot;&gt;Bash&lt;&#x2F;h2&gt;
&lt;p&gt;One of the first places you&#x27;ll learn about exit codes is the Bash manual. It says:&lt;&#x2F;p&gt;
&lt;p&gt;&quot;A successful command returns a 0, while an unsuccessful one returns a non-zero value that usually may be interpreted as an error code. Well-behaved UNIX commands, programs, and utilities return a 0 exit code upon successful completion, &lt;em&gt;though there are some exceptions&lt;&#x2F;em&gt;.&quot; (emph. mine)&lt;&#x2F;p&gt;
&lt;h2 id=&quot;posix&quot;&gt;POSIX&lt;&#x2F;h2&gt;
&lt;p&gt;The POSIX Open Group Base standard says:&lt;&#x2F;p&gt;
&lt;p&gt;&quot;The value of status may be 0, EXIT_SUCCESS, EXIT_FAILURE, [CX] [Option Start]  or any other value, though only the least significant 8 bits (that is, status &amp;amp; 0377) shall be available from wait() and waitpid(); the full value shall be available from waitid() and in the siginfo_t passed to a signal handler for SIGCHLD. [Option End]&quot;&lt;&#x2F;p&gt;
&lt;p&gt;On the same page it says: &quot;The functionality described on this reference page is aligned with the ISO C standard. Any conflict between the requirements described here and the ISO C standard is unintentional. This volume of POSIX.1-2017 defers to the ISO C standard.&quot;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;iso-c&quot;&gt;ISO C&lt;&#x2F;h2&gt;
&lt;p&gt;Okay, so what&#x27;s the ISO C standard say?&lt;&#x2F;p&gt;
&lt;p&gt;&quot;If the value of status is zero or EXIT_SUCCESS, an implementation-defined form of the status successful termination is returned. If the value of status is EXIT_FAILURE, an implementation-defined form of the status unsuccessful termination is returned. Otherwise the status returned is implementation-defined.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;&quot;an implementation-defined form of the status unsuccessful termination is returned&quot; feels unsatisfying, but at least we know that non-zero means unsuccessful, right?&lt;&#x2F;p&gt;
&lt;h1 id=&quot;the-bug&quot;&gt;The bug&lt;&#x2F;h1&gt;
&lt;p&gt;The original report was about &lt;code&gt;git log&lt;&#x2F;code&gt;. Let&#x27;s run the steps the user reports: run &lt;code&gt;git log&lt;&#x2F;code&gt;, quit with &lt;code&gt;q&lt;&#x2F;code&gt;, and then check the exit code. I&#x27;ll do this in bash, since that&#x27;s the shell everyone will have access to:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; git log
&amp;gt; echo $?
141
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Sure enough, a non-zero exit code.&lt;&#x2F;p&gt;
&lt;p&gt;Bash is reporting that &lt;code&gt;git log&lt;&#x2F;code&gt; exits with exit code 141. This clearly feels intentional. It&#x27;s not a 0 or 1, but a number specific to the other 254 possibilities.&lt;&#x2F;p&gt;
&lt;p&gt;Turns out that &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.ingeniousmalarkey.com&#x2F;2016&#x2F;07&#x2F;git-log-exit-code-141.html&quot;&gt;some folks dug into this 5+ years ago&lt;&#x2F;a&gt;. They write a bullet list with their findings:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Git pipes the logs into less&lt;&#x2F;li&gt;
&lt;li&gt;I quit the less process, which sends a SIGPIPE signal (13) to the underlying git process streaming the logs&lt;&#x2F;li&gt;
&lt;li&gt;git catches the interrupt and exits prematurely and per POSIX convention returns 128 + the SIGPIPE status ==&amp;gt; 141 to indicate that it was terminated by signal 13.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;when-failures-aren-t-failures&quot;&gt;When failures aren&#x27;t failures&lt;&#x2F;h1&gt;
&lt;p&gt;Why is the user being told about the SIGPIPE in this case? I&#x27;m sure there&#x27;s a perfectly reasonable set of events that take us to this point. Git is calling out to &lt;code&gt;less&lt;&#x2F;code&gt;, and &lt;code&gt;less&lt;&#x2F;code&gt; wants to report the user quitting it ends the pipe prematurely. And yet, it definitely feels to fall short of the &lt;em&gt;spirit of the specifications&lt;&#x2F;em&gt;. Non-zero errors &lt;em&gt;should&lt;&#x2F;em&gt; mean we&#x27;ve exited in an unexpected way. The steps above exit us in about the only reasonable way to exit interactively viewing the log.&lt;&#x2F;p&gt;
&lt;p&gt;As it turns out, &lt;code&gt;git log&lt;&#x2F;code&gt; isn&#x27;t alone. Here&#x27;s a discussion on &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;19120263&#x2F;why-exit-code-141-with-grep-q&quot;&gt;Stack Overflow about &lt;code&gt;grep -q&lt;&#x2F;code&gt; returning 141&lt;&#x2F;a&gt;. In it, the responses point out yet other commands, like &lt;code&gt;head&lt;&#x2F;code&gt;, also return 141 in their regular course of action.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;there-are-standards-and-there-are-standards&quot;&gt;There are standards, and there are standards&lt;&#x2F;h1&gt;
&lt;p&gt;Something folks tend to assume is that the POSIX standard covers a lot of how Unix-like systems work. While this is true at some level, there are cases like this one where we quickly shift to having to lean more on conventions than standards. As the Bash manual says &quot;though there are some exceptions&quot;. Using pipes and command composition leads to having to follow one part of the standard that in turn leads to really confusing situations for the user, like the situations listed above. A command like &lt;code&gt;head&lt;&#x2F;code&gt; or &lt;code&gt;less&lt;&#x2F;code&gt; doesn&#x27;t take all of its inputs. As it closes, it passes along that &quot;hey, technically the pipe I was reading from isn&#x27;t going to be able to write to its output because I&#x27;m closing&quot;. From the user&#x27;s perspective, though, exiting early is exactly what&#x27;s supposed to happen. It&#x27;s not actually an error.&lt;&#x2F;p&gt;
&lt;p&gt;It kinda makes you wonder - if we could do this over again, how would we do it differently?&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Retiring</title>
        <published>2021-03-03T00:00:00+00:00</published>
        <updated>2021-03-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/retiring/"/>
        <id>https://www.sophiajt.com/retiring/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/retiring/">&lt;p&gt;Yesterday was my last day at Microsoft. I&#x27;ve been fortunate to have worked in an industry that paid well over my 20+ year career and to have grown up with frugal parents who passed that on to me. Starting the 4th of March, I&#x27;ll be retiring to work on open source and teaching.&lt;&#x2F;p&gt;
&lt;p&gt;So what&#x27;s next? I have a few projects in mind:&lt;&#x2F;p&gt;
&lt;h2 id=&quot;get-nushell-to-1-0&quot;&gt;Get Nushell to 1.0&lt;&#x2F;h2&gt;
&lt;p&gt;We&#x27;re currently working on the plans for what it will take to get Nushell ready for 1.0. For the last year and a half, Nushell has been quite the passion project for me, and being at the place where we can talk about 1.0 and how to get there has me excited.&lt;&#x2F;p&gt;
&lt;p&gt;We&#x27;ll publish these plans once they&#x27;re ready so we can get your feedback, but suffice to say there&#x27;s lots of cool things we&#x27;d like to do.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;finish-the-rust-beginner-series&quot;&gt;Finish the Rust beginner series&lt;&#x2F;h2&gt;
&lt;p&gt;I&#x27;ve been enjoying working on the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=gesNaLkUJeA&amp;amp;list=PLP2yfE2-FXdQmXLvrQ5QN64enbF_KCYQW&quot;&gt;Rust beginner series&lt;&#x2F;a&gt;, where I work through the concepts you&#x27;ll need as a beginner in Rust. It&#x27;s more of an overview of the language and how language features fit together. I&#x27;m having fun with it, and hearing some good feedback, which is always nice.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;work-on-the-rust-intermediate-series&quot;&gt;Work on the Rust intermediate series&lt;&#x2F;h2&gt;
&lt;p&gt;I recently &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;sophiajt&#x2F;status&#x2F;1358592787852140550?s=20&quot;&gt;asked on Twitter&lt;&#x2F;a&gt; about intermediate Rust content, which inspired me to start an intermediate Rust series. You can find out more information &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.sophiajt.com&#x2F;intermedia-rust-series&#x2F;&quot;&gt;on this series in this blog post&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;keep-doing-systems-with-jt&quot;&gt;Keep doing Systems with JT&lt;&#x2F;h2&gt;
&lt;p&gt;I&#x27;ve been having a blast &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;user&#x2F;giard321&quot;&gt;making videos about various OSes&lt;&#x2F;a&gt;. What started as a &quot;it&#x27;d be fun to make some videos on these two hobby OSes&quot; has turned into a weekly video, and I&#x27;d like to keep this going.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;how-can-we-help&quot;&gt;How can we help?&lt;&#x2F;h1&gt;
&lt;p&gt;Probably the best thing is encouragement! Say hi on &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;sophiajt&quot;&gt;Twitter&lt;&#x2F;a&gt; or come by the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;user&#x2F;giard321&quot;&gt;YouTube channel&lt;&#x2F;a&gt; or &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.twitch.tv&#x2F;sophiajt&quot;&gt;Twitch stream&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;If you have the funds and don&#x27;t mind chipping in, I have &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.patreon.com&#x2F;sophiajt&quot;&gt;Patreon&lt;&#x2F;a&gt;, too. This will help me upgrade hardware, improve video editing, and more.&lt;&#x2F;p&gt;
&lt;p&gt;If you&#x27;d specifically like to help &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;nushell&#x2F;nushell&quot;&gt;Nushell&lt;&#x2F;a&gt; hit 1.0, I&#x27;d be happy to show you around. We&#x27;ve got a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;discord.gg&#x2F;NtAbbGn&quot;&gt;discord&lt;&#x2F;a&gt; where you can join us and chat about what&#x27;s happening and where to jump in. There are lots of places to help with code, docs, designs, and more. We&#x27;ll also soon be posting the proposal for getting to 1.0, which will include lots of areas that you could help with.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h1&gt;
&lt;p&gt;I&#x27;m both nervous and excited. Though I&#x27;ve planned as best I can and I live as simply as I can, it feels like taking a leap into the big blue unknown. But I&#x27;m all for following the heart and seeing what happens next.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Intermediate Rust series</title>
        <published>2021-02-12T00:00:00+00:00</published>
        <updated>2021-02-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/intermedia-rust-series/"/>
        <id>https://www.sophiajt.com/intermedia-rust-series/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/intermedia-rust-series/">&lt;p&gt;Hi all!&lt;&#x2F;p&gt;
&lt;p&gt;A few days ago I &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;sophiajt&#x2F;status&#x2F;1358592787852140550?s=20&quot;&gt;posted on Twitter&lt;&#x2F;a&gt; asking for topics that people wanted to see covered for intermediate Rust content. The response was awesome and it&#x27;s inspired me to make a series where I go through each topic and do my best to cover it as a video and&#x2F;or blog post.&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s the current list of topics. If you see something missing, you can drop an issue on &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sophiajt&#x2F;sophiajt.github.io&quot;&gt;this repo&lt;&#x2F;a&gt; or ping me &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;sophiajt&quot;&gt;on Twitter&lt;&#x2F;a&gt; and I&#x27;ll try to add it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rust-features&quot;&gt;Rust features&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Associated types&lt;&#x2F;li&gt;
&lt;li&gt;Working with lifetimes&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Pin&lt;&#x2F;code&gt; and &lt;code&gt;Pin&amp;lt;Box&amp;lt;Stream&amp;gt;&amp;gt;&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Macros, proc macros, custom attributes&lt;&#x2F;li&gt;
&lt;li&gt;Concurrency&lt;&#x2F;li&gt;
&lt;li&gt;Async&#x2F;await&lt;&#x2F;li&gt;
&lt;li&gt;Threads&#x2F;tasks&lt;&#x2F;li&gt;
&lt;li&gt;MPSC theory&lt;&#x2F;li&gt;
&lt;li&gt;Futures&lt;&#x2F;li&gt;
&lt;li&gt;Send&#x2F;Sync&lt;&#x2F;li&gt;
&lt;li&gt;Unsafe&lt;&#x2F;li&gt;
&lt;li&gt;FFI, shared mem across FFI, closures&#x2F;function pointers over FFI&lt;&#x2F;li&gt;
&lt;li&gt;FFI to C and C++&lt;&#x2F;li&gt;
&lt;li&gt;C interop, opaque structures, repl(c), working with null, alloc&#x2F;free, bitflag export to C&lt;&#x2F;li&gt;
&lt;li&gt;What tools to use for C++&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;std::sync&lt;&#x2F;code&gt; (Arc, Rc, RefCell, etc)&lt;&#x2F;li&gt;
&lt;li&gt;Raw pointers&lt;&#x2F;li&gt;
&lt;li&gt;Impl trait, dyn trait, and trait objects&lt;&#x2F;li&gt;
&lt;li&gt;Fn traits&lt;&#x2F;li&gt;
&lt;li&gt;Field sensitivity, field sensitivity + smart ptrs, field sensitivity and closures&lt;&#x2F;li&gt;
&lt;li&gt;Why do we cast from &lt;code&gt;Box&amp;lt;Struct&amp;gt;&lt;&#x2F;code&gt; to &lt;code&gt;Box&amp;lt;dyn Trait&amp;gt;&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;How to use &lt;code&gt;[patch]&lt;&#x2F;code&gt; in Cargo.toml&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;std::mem&lt;&#x2F;code&gt;, swap, replace, take&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;crates&quot;&gt;Crates&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Tonic&lt;&#x2F;li&gt;
&lt;li&gt;Tokio&lt;&#x2F;li&gt;
&lt;li&gt;Deeper dive into existing frameworks&#x2F;libraries&lt;&#x2F;li&gt;
&lt;li&gt;Channels&#x2F;async&#x2F;par_iter (concurrency vs parallelism)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;projects&quot;&gt;Projects&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Basic SQL database&lt;&#x2F;li&gt;
&lt;li&gt;Interpreters and parsers&lt;&#x2F;li&gt;
&lt;li&gt;Tokio + io_uring for CLI apps&lt;&#x2F;li&gt;
&lt;li&gt;Filesystem + FUSE&lt;&#x2F;li&gt;
&lt;li&gt;Seda or actor based project&lt;&#x2F;li&gt;
&lt;li&gt;Wasm + wasm bindgen&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;patterns-and-practices&quot;&gt;Patterns and practices&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Like http:&#x2F;&#x2F;railstutorial.org but for Rust&lt;&#x2F;li&gt;
&lt;li&gt;Functional composition&lt;&#x2F;li&gt;
&lt;li&gt;Async functional composition&lt;&#x2F;li&gt;
&lt;li&gt;Dependency injection (and alternatives)&lt;&#x2F;li&gt;
&lt;li&gt;Design patterns&lt;&#x2F;li&gt;
&lt;li&gt;Lessons from Rust in production&lt;&#x2F;li&gt;
&lt;li&gt;How to teach Rust to teams&lt;&#x2F;li&gt;
&lt;li&gt;Testing patterns and strategies&lt;&#x2F;li&gt;
&lt;li&gt;https:&#x2F;&#x2F;rust-lang.github.io&#x2F;api-guidelines&#x2F;checklist.html&lt;&#x2F;li&gt;
&lt;li&gt;Zero copy processing best practices&lt;&#x2F;li&gt;
&lt;li&gt;Error handling. One big error enum or something extensible? Anyhow?&lt;&#x2F;li&gt;
&lt;li&gt;Debugging Rust&lt;&#x2F;li&gt;
&lt;li&gt;Modelling classic data structures in Rust&lt;&#x2F;li&gt;
&lt;li&gt;Logging&lt;&#x2F;li&gt;
&lt;li&gt;Shared data structures in long-running apps&lt;&#x2F;li&gt;
&lt;li&gt;Profiling&lt;&#x2F;li&gt;
&lt;li&gt;Improving compile times&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;rust-background&quot;&gt;Rust background&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;How do nightly features stabilize?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;looking-ahead&quot;&gt;Looking ahead&lt;&#x2F;h1&gt;
&lt;p&gt;As you can see, there&#x27;s a &lt;em&gt;lot&lt;&#x2F;em&gt; of area to cover. My plan is to make steady progress on the list above, covering topic by topic until we cover as many of the topics as possible. People were also upvoting tweets with likes, so I may juggle this list around so that I&#x27;m sure to cover the hot topics sooner.&lt;&#x2F;p&gt;
&lt;p&gt;Excited to dig into this!&lt;&#x2F;p&gt;
&lt;p&gt;If you&#x27;d like to follow along to enjoy the content as it comes out, you can follow me &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;sophiajt&quot;&gt;on Twitter&lt;&#x2F;a&gt;, you can follow my &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;user&#x2F;giard321&quot;&gt;YouTube channel&lt;&#x2F;a&gt; where I post my technical content, and follow me on &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.twitch.tv&#x2F;sophiajt&quot;&gt;Twitch&lt;&#x2F;a&gt; for when I stream a topic.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Nushell 0.5.0</title>
        <published>2019-11-05T00:00:00+00:00</published>
        <updated>2019-11-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/nushell-0-5-0/"/>
        <id>https://www.sophiajt.com/nushell-0-5-0/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/nushell-0-5-0/">&lt;p&gt;Nushell, or Nu for short, is a new shell that takes a modern, structured approach to your commandline. It works seamlessly with the data from your filesystem, operating system, and a growing number of file formats to make it easy to build powerful commandline pipelines.&lt;&#x2F;p&gt;
&lt;p&gt;Today, we&#x27;re happy to announce the 0.5.0 release for Nu. We&#x27;ve got lots of new features, including some long-requested ones, in this release.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;where-to-get-it&quot;&gt;Where to get it&lt;&#x2F;h1&gt;
&lt;p&gt;Nu 0.5.0 is available as &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;nushell&#x2F;nushell&#x2F;releases&#x2F;tag&#x2F;0_5_0&quot;&gt;pre-built binaries&lt;&#x2F;a&gt; or from &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;crates.io&#x2F;crates&#x2F;nu&quot;&gt;crates.io&lt;&#x2F;a&gt;. If you have Rust installed you can install it using &lt;code&gt;cargo +beta install nu&lt;&#x2F;code&gt; (or if you want all the features &lt;code&gt;cargo +beta install nu --all-features&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;h1 id=&quot;nu-as-a-login-shell-sophiajt&quot;&gt;Nu as a login shell (sophiajt)&lt;&#x2F;h1&gt;
&lt;p&gt;One of the key features that landed in 0.5.0 is set of new capabilities that work together to allow you to use Nu as a login shell, completely independent of bash or other hosting shells. For this, we&#x27;ve built in support for querying and updating the environment variables and the path.&lt;&#x2F;p&gt;
&lt;p&gt;To get started, you&#x27;ll need to first copy the environment you&#x27;re using into the config. Luckily, we&#x27;ve also made some improvements there:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; config --set [path $nu:path]
&amp;gt; config --set [env $nu:env]
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Once these values are set, you&#x27;ll be able to use Nu as your login shell.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;new-variables&quot;&gt;New variables&lt;&#x2F;h2&gt;
&lt;p&gt;As you saw above, we&#x27;ve added a few new built-in variables. These will let you know what the current values that Nu can see are for your environment, path, and the config itself.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; echo $nu:env
&amp;gt; echo $nu:path
&amp;gt; echo $nu:config
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;adding-paths-to-your-path&quot;&gt;Adding paths to your PATH&lt;&#x2F;h2&gt;
&lt;p&gt;One of the first things you&#x27;ll notice is that the new $nu:path is structured. If you run the echo above, you might see something like this:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; echo $nu:path
━━━┯━━━━━━━━━━━━━━━━━━
 # │ &amp;lt;value&amp;gt;
───┼──────────────────
 0 │ &#x2F;usr&#x2F;local&#x2F;sbin
 1 │ &#x2F;usr&#x2F;local&#x2F;bin
 2 │ &#x2F;usr&#x2F;sbin
 3 │ &#x2F;usr&#x2F;bin
 4 │ &#x2F;sbin
 5 │ &#x2F;bin
 6 │ &#x2F;usr&#x2F;games
 7 │ &#x2F;usr&#x2F;local&#x2F;games
 8 │ &#x2F;snap&#x2F;bin
━━━┷━━━━━━━━━━━━━━━━━━
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We&#x27;ve added two new commands: &lt;code&gt;prepend&lt;&#x2F;code&gt; for adding items to the start of a table and &lt;code&gt;append&lt;&#x2F;code&gt; for adding items to the end of a table. With these commands, we can now query out the path, update it, and save it back.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; echo $nu:path | prepend &amp;quot;&#x2F;my&#x2F;new&#x2F;directory&amp;quot; | config --set_into path
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;adding-variables-to-your-environment&quot;&gt;Adding variables to your environment&lt;&#x2F;h2&gt;
&lt;p&gt;You can use a similar set of steps to add new variables, or change existing variables, in your environment.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; echo $nu:env | insert GREETING hello_world | config --set_into env
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;em&gt;Note: the previous &lt;code&gt;add&lt;&#x2F;code&gt; command of previous releases has been renamed &lt;code&gt;insert&lt;&#x2F;code&gt; to remove confusion with mathematical functions.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;on-going-improvements&quot;&gt;On-going improvements&lt;&#x2F;h1&gt;
&lt;p&gt;We&#x27;re continuing to improve the commands we currently ship as part of Nu. Here are a few you might find helpful:&lt;&#x2F;p&gt;
&lt;h2 id=&quot;substrings-flare576&quot;&gt;Substrings (Flare576)&lt;&#x2F;h2&gt;
&lt;p&gt;The &lt;code&gt;str&lt;&#x2F;code&gt; command now supports being able to retrieve a substring from the strings given, so you could return, for example, the first 5 characters and stop after that.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; ls | get name
━━━━┯━━━━━━━━━━━━━━━━━━━━
 #  │ &amp;lt;value&amp;gt;
────┼────────────────────
  0 │ target
  1 │ CODE_OF_CONDUCT.md
  2 │ .cargo
  3 │ src
  4 │ features.toml
  5 │ rustfmt.toml
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; ls | get name | str --substring &amp;quot;0,3&amp;quot;
━━━━┯━━━━━━━━━
 #  │ &amp;lt;value&amp;gt;
────┼─────────
  0 │ tar
  1 │ COD
  2 │ .ca
  3 │ src
  4 │ fea
  5 │ rus
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;recycling-jdvr&quot;&gt;Recycling (jdvr)&lt;&#x2F;h2&gt;
&lt;p&gt;Ever wish you could &lt;code&gt;rm&lt;&#x2F;code&gt; things, but not forever? You can now tell &lt;code&gt;rm&lt;&#x2F;code&gt; to send items to your platform&#x27;s recycle bin rather than deleting them forever. As with our other commands, this works across all the platforms that Nu supports.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; rm myfile.txt --trash
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;parameter-descriptions-sophiajt&quot;&gt;Parameter descriptions (sophiajt)&lt;&#x2F;h2&gt;
&lt;p&gt;We&#x27;re also continuing to improve the built-in help system. New in this release are descriptions for the flags and parameters that the command uses. For example, here&#x27;s a look at what the help for &lt;code&gt;rm&lt;&#x2F;code&gt; now looks like:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; help rm
Remove a file

Usage:
  &amp;gt; rm &amp;lt;path&amp;gt; {flags}

parameters:
  &amp;lt;path&amp;gt; the file path to remove

flags:
  --trash: use the platform&amp;#39;s recycle bin instead of permanently deleting
  --recursive: delete subdirectories recursively
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;new-commands&quot;&gt;New commands&lt;&#x2F;h1&gt;
&lt;p&gt;In addition to the new &lt;code&gt;append&lt;&#x2F;code&gt; and &lt;code&gt;prepend&lt;&#x2F;code&gt; we mentioned earlier, we&#x27;ve added a few new commands to Nu.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;average-notryanb&quot;&gt;Average (notryanb)&lt;&#x2F;h2&gt;
&lt;p&gt;Growing our set of mathematics functions for working with numbers, we now have an &lt;code&gt;average&lt;&#x2F;code&gt; command which will take the average of values given to it.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; ls | get size | average
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;read-sophiajt&quot;&gt;Read (sophiajt)&lt;&#x2F;h2&gt;
&lt;p&gt;We&#x27;ve also introduced a new command to load in strings as tables. This new &lt;code&gt;read&lt;&#x2F;code&gt; command will take a pattern that describes the columns, their names, and where they are in each row of the string.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; open .editorconfig
root = true

[*]
indent_style = space
indent_size = 4
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = false
end_of_line = lf
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; open .editorconfig | read &amp;quot;{variable} = {value}&amp;quot;
━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━━
 # │ variable                 │ value
───┼──────────────────────────┼───────
 0 │ root                     │ true
 1 │ indent_style             │ space
 2 │ indent_size              │ 4
 3 │ charset                  │ utf-8
 4 │ trim_trailing_whitespace │ true
 5 │ insert_final_newline     │ false
 6 │ end_of_line              │ lf
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;bugfixes-sophiajt-jesterornot-thegedge-andrasio-wycats-notryanb-detegr-t-hart&quot;&gt;Bugfixes (sophiajt, JesterOrNot, thegedge, andrasio, wycats, notryanb, Detegr, t-hart)&lt;&#x2F;h1&gt;
&lt;p&gt;As always, we&#x27;ve had lots of bugfixes. A &lt;em&gt;huge&lt;&#x2F;em&gt; &quot;thank you!&quot; to folks who reported issues, fixed issues, and just generally shared their experience with the shell. It&#x27;s much appreciated and helps to continue making Nu that much better.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;survey&quot;&gt;Survey&lt;&#x2F;h1&gt;
&lt;p&gt;If you haven&#x27;t already taken it, we&#x27;d love to hear your feedback in a quick (roughly 3 question) &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;t.co&#x2F;nujSjnI0dr?amp=1&quot;&gt;survey&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;looking-forward&quot;&gt;Looking forward&lt;&#x2F;h1&gt;
&lt;p&gt;There are a bunch of areas we&#x27;re currently working on to make Nu more stable and feature complete. Until this work is finished, please consider Nu to be somewhere in the &lt;em&gt;pre-alpha&lt;&#x2F;em&gt; to &lt;em&gt;alpha&lt;&#x2F;em&gt; quality level.&lt;&#x2F;p&gt;
&lt;p&gt;That said, we&#x27;re excited to merge this work and continue to take steps towards a more full-featured shell. Soon to be coming will be Nu working on stable Rust(!!), some improvements in the Nu internal engine which will make it possible to have better streaming and cleaner commands, and features like aliases.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Nushell 0.4.0</title>
        <published>2019-10-15T00:00:00+00:00</published>
        <updated>2019-10-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/nushell-0-4-0/"/>
        <id>https://www.sophiajt.com/nushell-0-4-0/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/nushell-0-4-0/">&lt;p&gt;Nushell, or Nu for short, is a new shell that takes a modern, structured approach to your commandline. It works seamlessly with the data from your filesystem, operating system, and a growing number of file formats to make it easy to build powerful commandline pipelines.&lt;&#x2F;p&gt;
&lt;p&gt;Today we&#x27;re happy to announce the 0.4.0 release of Nushell. The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;nushell&#x2F;nushell&#x2F;releases&#x2F;tag&#x2F;0.4.0&quot;&gt;0.4.0 release&lt;&#x2F;a&gt; marks a continually maturing shell that is now starting to show signs of stability. And, of course, a few fun features along the way.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;where-to-get-it&quot;&gt;Where to get it&lt;&#x2F;h1&gt;
&lt;p&gt;Nu 0.4.0 is available as &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;nushell&#x2F;nushell&#x2F;releases&#x2F;tag&#x2F;0.4.0&quot;&gt;pre-built binaries&lt;&#x2F;a&gt; or from &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;crates.io&#x2F;crates&#x2F;nu&quot;&gt;crates.io&lt;&#x2F;a&gt;. If you have Rust installed you can install it using &lt;code&gt;cargo +beta install nu&lt;&#x2F;code&gt; (or if you want all the features &lt;code&gt;cargo +beta install nu --all-features&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;h1 id=&quot;what-s-new&quot;&gt;What&#x27;s new&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;new-colors-wycats&quot;&gt;New Colors (wycats)&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.sophiajt.com&#x2F;images&#x2F;0_4_0_new_colors.png&quot; alt=&quot;The prompt with the latest colors&quot; &#x2F;&gt;
New colors!&lt;&#x2F;p&gt;
&lt;p&gt;With 0.4.0, we&#x27;re adding some new colors to show off different types of the command, where errors might be happening, and if the command is internal or external. The coloring is just the tip of the iceberg, as it were, and builds from a reworking of the parser to make it more accurate, more stable, and more feature-complete.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;streaming-table-sophiajt&quot;&gt;Streaming table (sophiajt)&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.sophiajt.com&#x2F;images&#x2F;0_4_0_streaming_table.gif&quot; alt=&quot;Animation of a long table streaming out&quot; &#x2F;&gt;
Streaming tables&lt;&#x2F;p&gt;
&lt;p&gt;Up to this point, we&#x27;ve taken a few shortcuts with how streams worked in Nushell. We knew that a table, in theory, was a stream of rows. In practice, though, this wasn&#x27;t the case as the code has lots of assumptions about how tables worked.&lt;&#x2F;p&gt;
&lt;p&gt;With the 0.4.0, we&#x27;re taking a big step in the direction of full support for streams. You&#x27;ll see that now data will start being printed as it becomes available, with tables printing pages of 50 rows at a time (by default). This allows you to get deep listings of files (eg using &lt;code&gt;ls **&lt;&#x2F;code&gt;), work with streams from external sources, and more.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;better-ctrl-c-support-sophiajt-landaire&quot;&gt;Better ctrl-c support (sophiajt, landaire)&lt;&#x2F;h2&gt;
&lt;p&gt;As part of having streams of tables, it&#x27;s always helpful to be able to say &quot;stop!&quot; when you need to. With 0.4.0, using ctrl-c to stop the output should be a lot more responsive and will take you back to the prompt.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;textview-gets-vi-keys-jonnywalker81&quot;&gt;Textview gets VI keys (JonnyWalker81)&lt;&#x2F;h2&gt;
&lt;p&gt;The built-in text viewer now lets you use vi keys for navigation thanks to JonnyWalker81&#x27;s work.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;onto-the-beta-compiler-est31&quot;&gt;Onto the Beta compiler (est31)&lt;&#x2F;h2&gt;
&lt;p&gt;For those of you wondering if and when Nu was going to be usable on stable Rust, you need but wait just a little longer. Contributer est31 has been hard at work at moving Nu onto stable Rust and has now successfully moved Nu off of nightly and onto beta. As beta matures and becomes the next release of Rust, we&#x27;ll be able to move Nu onto stable. This should help people who are working to distribute Nu on various distributions.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;brazilian-portuguese-book-marcelocg&quot;&gt;Brazilian Portuguese book (marcelocg)&lt;&#x2F;h2&gt;
&lt;p&gt;Contributor marcelocg surprised us with a translation of the Nu book into Brazillian Portuguese. Obrigado, Marcelo!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;new-commands&quot;&gt;New commands&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;from-ssv-t-hart&quot;&gt;from-ssv (t-hart)&lt;&#x2F;h3&gt;
&lt;p&gt;To follow along with our &lt;code&gt;from-csv&lt;&#x2F;code&gt; (comma-separated-values) and &lt;code&gt;from-tsv&lt;&#x2F;code&gt; (tab-separated-values), we now have a new way of handle importing content from commands that output their own tables: &lt;code&gt;from-ssv&lt;&#x2F;code&gt;. Like its siblings, it looks for values separated by a separator, using the spaces to show where the breaks between cells should be.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;match-rnxpyke&quot;&gt;match (rnxpyke)&lt;&#x2F;h3&gt;
&lt;p&gt;We&#x27;re continuing to evolve our support for matching string data. Recently, we began experimenting with a &lt;code&gt;match&lt;&#x2F;code&gt; command that can find matches in strings for you. We plan to continue experimenting and exploring what&#x27;s possible in this space in the future.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;lots-of-new-documentation-sdfnz-twe4ked-chhetripradeep-mfarberbrodsky-cristicismas-charles-schleich-coolshaurya-notryanb-pema99-gilesv-yahsinhuangtw-jesterornot-nalshihabi-marcelocg-sorrell-pizzafox-iggy14750-drsensor-mlbright-bradybromley-andrasio-piotrek-szczygiel&quot;&gt;Lots of new documentation (sdfnz, twe4ked, chhetripradeep, mfarberbrodsky, cristicismas, Charles-Schleich, coolshaurya, notryanb, pema99, gilesv, yahsinhuangtw, JesterOrNot, nalshihabi, marcelocg, sorrell, pizzafox, iggy14750, DrSensor, mlbright, BradyBromley, andrasio, piotrek-szczygiel)&lt;&#x2F;h2&gt;
&lt;p&gt;Happy hacktoberfest! Lots of people wanted to jump in and help document all of our commands, help fix docs that are already there, and generally give things a bit of polish. Much appreciated everyone who came by and contributed.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;tons-of-stability-fixes-thegedge-sophiajt-wycats-jonnywalker81-vsoch-pka&quot;&gt;Tons of stability fixes (thegedge, sophiajt, wycats, JonnyWalker81, vsoch, pka)&lt;&#x2F;h2&gt;
&lt;p&gt;As always, there were a bunch of stability and correctness both in Nu and in the CI that support Nu&#x27;s development&lt;&#x2F;p&gt;
&lt;h1 id=&quot;looking-ahead&quot;&gt;Looking ahead&lt;&#x2F;h1&gt;
&lt;p&gt;We&#x27;ll continuing filling out the features that will let folks use Nu as their everyday shell. Coming up are better support for the environment, path, and for command aliases.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Nushell 0.3.0</title>
        <published>2019-09-24T00:00:00+00:00</published>
        <updated>2019-09-24T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/nushell-0-3-0/"/>
        <id>https://www.sophiajt.com/nushell-0-3-0/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/nushell-0-3-0/">&lt;p&gt;Nushell, or Nu for short, is a new shell that takes a modern, structured approach to your commandline. It works seamlessly with the data from your filesystem, operating system, and a growing number of file formats to make it easy to build powerful commandline pipelines.&lt;&#x2F;p&gt;
&lt;p&gt;We&#x27;re happy to announce that today we&#x27;re releasing Nushell 0.3.0. Nu has seen numerous bugfixes, performance improvements, and features added since its initial public release (which was only a few weeks ago!)&lt;&#x2F;p&gt;
&lt;h1 id=&quot;where-to-get-it&quot;&gt;Where to get it&lt;&#x2F;h1&gt;
&lt;p&gt;Nu 0.3.0 is available as &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;nushell&#x2F;nushell&#x2F;releases&#x2F;tag&#x2F;0.3.0&quot;&gt;pre-built binaries&lt;&#x2F;a&gt; or from &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;crates.io&#x2F;crates&#x2F;nu&quot;&gt;crates.io&lt;&#x2F;a&gt;. If you have Rust installed you can install it using &lt;code&gt;cargo +nightly install nu&lt;&#x2F;code&gt; (or if you want all the features &lt;code&gt;cargo +nightly install nu --all-features&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;h1 id=&quot;what-s-new&quot;&gt;What&#x27;s new&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;new-table-design-porges-sophiajt&quot;&gt;New table design (Porges, sophiajt)&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.sophiajt.com&#x2F;images&#x2F;utf8_table.png&quot; alt=&quot;Table with utf8 box drawing&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;One of the most striking differences is that Nu now uses UTF-8 box drawing to draw its tables.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.sophiajt.com&#x2F;images&#x2F;utf8_light_table.png&quot; alt=&quot;Table with utf8 box drawing in light mode&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The table is also configurable. If you feel like the table is a bit too heavy, you can also configure it to work in light mode using this command:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; config --set [table_mode light]
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;new-file-formats-pmeredit-est31-andrasio-sophiajt&quot;&gt;New file formats (pmeredit, est31, andrasio, sophiajt)&lt;&#x2F;h2&gt;
&lt;p&gt;Nu now natively supports new file formats, including: bson, tsv, sqlite, and url-encoded strings.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;new-commands-incrop-ramonsnir-ijt-sophiajt-andrasio-jonnywalker81-chhetripradeep-pka&quot;&gt;New commands (incrop, ramonsnir, ijt, sophiajt, andrasio, JonnyWalker81, chhetripradeep, pka)&lt;&#x2F;h2&gt;
&lt;p&gt;Since the 0.2.0 release, Nu has gained a set of additional commands, including:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;help&lt;&#x2F;code&gt; - built-in help system&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;reverse&lt;&#x2F;code&gt; - reverse a table&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;last&lt;&#x2F;code&gt; - like the &lt;code&gt;first&lt;&#x2F;code&gt; command, but working from the bottom of the table, return n rows&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;embed&lt;&#x2F;code&gt; - create a new table using the current table as a start&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;fetch&lt;&#x2F;code&gt; - get the contents of a URL (this originally lived in &lt;code&gt;open&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;post&lt;&#x2F;code&gt; - post to a URL and get the results&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;pwd&lt;&#x2F;code&gt; - print the working directory&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;env&lt;&#x2F;code&gt; - give access to a number of important paths and environment settings&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;pivot&lt;&#x2F;code&gt; - pivot a table so that rows become columns and vice-versa&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;echo&lt;&#x2F;code&gt; - a built-in echo command&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;error-improvements-sophiajt&quot;&gt;Error improvements (sophiajt)&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.sophiajt.com&#x2F;images&#x2F;did_you_mean.png&quot; alt=&quot;Improve error messages&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We&#x27;ve made steady progress on improving error messages. Recently, we added &quot;did you mean?&quot; errors to help when you mistype the name of columns. Nu 0.3.0 also has gone through a few passes to generally polish the errors to include more information when an error occurs.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;shell-features-pka-wycats-twe4ked-andrasio-iamcodemaker&quot;&gt;Shell features (pka, wycats, twe4ked, andrasio, iamcodemaker)&lt;&#x2F;h2&gt;
&lt;p&gt;Nu now supports &lt;code&gt;~&lt;&#x2F;code&gt; to refer to your home directory as part of a path. You can also use &lt;code&gt;cd -&lt;&#x2F;code&gt; to return to a previous directory you were working in.&lt;&#x2F;p&gt;
&lt;p&gt;The shell itself also got a few updates. You can now enable &#x27;vi&#x27; mode, if you&#x27;d prefer vi-like bindings (by running &lt;code&gt;config --set [edit_mode vi]&lt;&#x2F;code&gt;). On non-Windows platforms, you can also use Ctrl-R to enable Sublime-style history searching (we&#x27;re hoping to enable Windows support for this soon).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;plugin-improvements-sophiajt-andrasio&quot;&gt;Plugin improvements (sophiajt, andrasio)&lt;&#x2F;h2&gt;
&lt;p&gt;Plugins have continued to mature, and it&#x27;s now possible to use plugins to extend Nu with support for new file formats.&lt;&#x2F;p&gt;
&lt;p&gt;We&#x27;ve also added documentation on how to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;nushell&#x2F;contributor-book&#x2F;blob&#x2F;master&#x2F;en&#x2F;plugins.md&quot;&gt;write Nu plugins in both Rust and Python&lt;&#x2F;a&gt;, with info on Ruby coming soon.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;docker-support-vsoch-drsensor&quot;&gt;Docker support (vsoch, DrSensor)&lt;&#x2F;h2&gt;
&lt;p&gt;If you&#x27;re interested in using Nu and Docker together, be sure to check out the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;nushell&#x2F;nushell&#x2F;blob&#x2F;master&#x2F;docs&#x2F;docker.md&quot;&gt;new Docker support&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;book-progress&quot;&gt;Book progress&lt;&#x2F;h2&gt;
&lt;p&gt;The &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;book.nushell.sh&quot;&gt;Nu book&lt;&#x2F;a&gt; is now available in &lt;em&gt;three&lt;&#x2F;em&gt; languages: English, Spanish, and Japanese.&lt;&#x2F;p&gt;
&lt;p&gt;We&#x27;ve also created a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;nushell&#x2F;contributor-book&#x2F;blob&#x2F;master&#x2F;en&#x2F;README.md&quot;&gt;Nu contributor book&lt;&#x2F;a&gt;, which will help developers who want to contribute to Nu learn about its philosophy, design, and how to create plugins.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;acknowledgements&quot;&gt;Acknowledgements&lt;&#x2F;h2&gt;
&lt;p&gt;est31, pmeredit, twe4ked, DrSensor, vsoch, pka, jankoprowski, Porges, max-sixty, ijt, djc, vthriller, taiki-e, oskarskog, iamcodemaker, JonnyWalker81, yaahc, tim77, svartalf, ramonsnir, orf, lesichkovm, ineol, incrop, eoinkelly, devnought, chhetripradeep, aidanharris, GuillaumeGomez, and BatmanAod for contributing to the Nu codebase. Also a &lt;em&gt;big&lt;&#x2F;em&gt; thanks to our issue reporters!&lt;&#x2F;p&gt;
&lt;p&gt;ymgyt - for the Japanese version of the Nu book!&lt;&#x2F;p&gt;
&lt;p&gt;mistydemeo, romanlevin, ralvessa, pka, lord, kkalyan, jankprowski, and boisgera for helping with the book.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;looking-ahead&quot;&gt;Looking ahead&lt;&#x2F;h2&gt;
&lt;p&gt;We&#x27;re hard at work on the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;nushell&#x2F;nushell&#x2F;issues&#x2F;261&quot;&gt;upcoming milestone release&lt;&#x2F;a&gt;. If you&#x27;d like to help, feel free to jump in! We have an active &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;discord.gg&#x2F;NtAbbGn&quot;&gt;discord&lt;&#x2F;a&gt; you can join for both users and contributors.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Introducing nushell</title>
        <published>2019-08-23T00:00:00+00:00</published>
        <updated>2019-08-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/introducing-nushell/"/>
        <id>https://www.sophiajt.com/introducing-nushell/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/introducing-nushell/">&lt;p&gt;Today, we&#x27;re introducing a new shell, written in Rust. It draws inspiration from the classic Unix philosophy of pipelines, the structured data approach of PowerShell, functional programming, systems programming, and more.&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s called Nushell, or just Nu for short. We have a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;book.nushell.sh&#x2F;en&quot;&gt;book&lt;&#x2F;a&gt; (¡también se habla &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;book.nushell.sh&#x2F;es&quot;&gt;Español&lt;&#x2F;a&gt;!). We have a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;nushell&#x2F;nushell&quot;&gt;repo&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;This release was made by Sophia Turner (me), Yehuda Katz, and Andrés Robalino, with contributions from Odin Dutton.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.sophiajt.com&#x2F;images&#x2F;nushell-autocomplete4.gif&quot; alt=&quot;Nu in action&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;but-why&quot;&gt;But why?&lt;&#x2F;h1&gt;
&lt;p&gt;Many of us have gotten used to bash (or zsh&#x2F;fish&#x2F;etc), and don&#x27;t understand why you would need another kind of shell. That was me, too, a few months ago before I started working on this. My friend Yehuda had discovered PowerShell and was going on and on about how amazing it was to do more with the shell, but until he actually gave me a demo, I didn&#x27;t really believe him.&lt;&#x2F;p&gt;
&lt;p&gt;Then he talked me into joining him on an idea he had. What if we could take the ideas of a structured shell and make it more functional (as opposed to object-oriented)? What if, like PowerShell, it worked on Windows, Linux, and macOS? What if it had great error messages? I fell in love with the project ideas, made a few new friends, and many nights and weekends later I&#x27;d like to show you what we&#x27;ve made.&lt;&#x2F;p&gt;
&lt;p&gt;In this post, I&#x27;ll talk about how a few simple ideas drive how Nu works, what Nu can do with them, and where we hope to go in the future.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;simple-ideas&quot;&gt;Simple ideas&lt;&#x2F;h1&gt;
&lt;p&gt;To Nu, everything is data. When you type &lt;code&gt;ls&lt;&#x2F;code&gt;, you&#x27;re given a table of information about the directory you&#x27;re listing:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.sophiajt.com&#x2F;images&#x2F;nu_ls.png&quot; alt=&quot;ls command&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Rather than having to remember different flags to &lt;code&gt;ls&lt;&#x2F;code&gt;, we can just work with the data it gives back. We can find the files greater than a certain size:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.sophiajt.com&#x2F;images&#x2F;nu_ls_filter.png&quot; alt=&quot;ls with filtering&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Or we could choose to sort it by a column, or only show directories, or more. That by itself is fun but perhaps not compelling enough.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.sophiajt.com&#x2F;images&#x2F;nu_ps_filter.png&quot; alt=&quot;ps with filtering&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Where this simple concept - that everything in Nu is data - starts to shine when we try other commands and realize that we&#x27;re using the same commands to filter, to sort, etc. Rather than having the need to remember all the parameters to all the commands, we can just use the same verbs to act over our data, regardless of where the data came from. Nu pushes this idea even further.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.sophiajt.com&#x2F;images&#x2F;open_cargo.png&quot; alt=&quot;opening toml file&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Nu also understands structured text files like JSON, TOML, YAML, and more. Opening these files gives us the same tables we saw with &lt;code&gt;ls&lt;&#x2F;code&gt; and &lt;code&gt;ps&lt;&#x2F;code&gt;. Again, this lets us use the same commands to filter our data, explore it, and use it.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;working-with-the-outside-world&quot;&gt;Working with the outside world&lt;&#x2F;h1&gt;
&lt;p&gt;The above approach could be fun, but if we&#x27;re not careful, it could become a walled garden. What happens outside of the commands Nu comes with?&lt;&#x2F;p&gt;
&lt;p&gt;First, let&#x27;s take a look at working with a file that Nu doesn&#x27;t understand.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; open people.psv
Octavia | Butler | Writer
Bob | Ross | Painter
Antonio | Vivaldi | Composer
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To work with this in Nu, we need to do two steps: figure out where the rows are, and then figure out what the columns are. The rows are pretty easy, we just have one record per row:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; open people.psv | lines
---+------------------------------
 # | value
---+------------------------------
 0 | Octavia | Butler | Writer
 1 | Bob | Ross | Painter
 2 | Antonio | Vivaldi | Composer
---+------------------------------
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Next, we can create our columns by splitting each row at the pipe (&lt;code&gt;|&lt;&#x2F;code&gt;) symbol:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; open people.psv | lines | split-column &amp;quot;|&amp;quot;
---+----------+-----------+-----------
 # | Column1  | Column2   | Column3
---+----------+-----------+-----------
 0 | Octavia  |  Butler   |  Writer
 1 | Bob      |  Ross     |  Painter
 2 | Antonio  |  Vivaldi  |  Composer
---+----------+-----------+-----------
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;That&#x27;s already good enough that we can work with the data. We can go a step further and name the columns if we want:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; open people.psv | lines | split-column &amp;quot; | &amp;quot; firstname lastname job
---+-----------+----------+----------
 # | firstname | lastname | job
---+-----------+----------+----------
 0 | Octavia   | Butler   | Writer
 1 | Bob       | Ross     | Painter
 2 | Antonio   | Vivaldi  | Composer
---+-----------+----------+----------
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;But what about working with commands outside of Nu? Let&#x27;s first call the native version of &lt;code&gt;ls&lt;&#x2F;code&gt; instead of the Nu version:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; ^ls
assets	     Cargo.lock  docs	images	 Makefile.toml	README.md     rustfmt2.toml  src     tests
Cargo2.toml  Cargo.toml  extra	LICENSE  open		readonly.txt  rustfmt.toml   target
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We&#x27;ll use the same commands we used on data to bring it into Nu:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;^ls | split-row &amp;quot; &amp;quot; file
----+---------------
 #  | value
----+---------------
 0  | assets
 1  | Cargo2.toml
 2  | Cargo.lock
 3  | Cargo.toml
 4  | docs
 5  | extra
 6  | images
 7  | LICENSE
 8  | Makefile.toml
 9  | open
 10 | README.md
 11 | readonly.txt
 12 | rustfmt2.toml
 13 | rustfmt.toml
 14 | src
 15 | target
 16 | tests
----+---------------
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Or maybe we want to work with the native &lt;code&gt;ls -la&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;^ls -la | lines | split-column &amp;quot; &amp;quot;
----+------------+---------+----------+----------+---------+---------+---------+---------+---------------
 #  | Column1    | Column2 | Column3  | Column4  | Column5 | Column6 | Column7 | Column8 | Column9
----+------------+---------+----------+----------+---------+---------+---------+---------+---------------
 0  | total      | 296     |          |          |         |         |         |         |
 1  | drwxr-xr-x | 13      | sophia | sophia | 4096    | Aug     | 24      | 03:24   | .
 2  | drwxr-xr-x | 21      | sophia | sophia | 4096    | Aug     | 22      | 17:00   | ..
 3  | drwxr-xr-x | 2       | sophia | sophia | 4096    | Aug     | 3       | 05:39   | assets
 4  | drwxr-xr-x | 2       | sophia | sophia | 4096    | Aug     | 21      | 19:29   | .azure
 5  | drwxr-xr-x | 2       | sophia | sophia | 4096    | Jun     | 23      | 05:09   | .cargo
 6  | -rw-r--r-- | 1       | sophia | sophia | 2963    | Aug     | 22      | 20:17   | Cargo2.toml
 7  | -rw-r--r-- | 1       | sophia | sophia | 201255  | Aug     | 24      | 03:24   | Cargo.lock
 8  | -rw-r--r-- | 1       | sophia | sophia | 3127    | Aug     | 24      | 03:24   | Cargo.toml
 9  | drwxr-xr-x | 2       | sophia | sophia | 4096    | Jun     | 17      | 15:32   | docs
 10 | -rw-r--r-- | 1       | sophia | sophia | 148     | Jun     | 17      | 15:32   | .editorconfig
 11 | drwxr-xr-x | 4       | sophia | sophia | 4096    | Aug     | 22      | 19:29   | extra
 12 | drwxr-xr-x | 8       | sophia | sophia | 4096    | Aug     | 24      | 03:24   | .git
 13 | -rw-r--r-- | 1       | sophia | sophia | 58      | Aug     | 10      | 11:08   | .gitignore
 14 | drwxr-xr-x | 2       | sophia | sophia | 4096    | Aug     | 24      | 03:24   | images
 15 | -rw-r--r-- | 1       | sophia | sophia | 1085    | Jun     | 17      | 15:32   | LICENSE
 16 | -rw-r--r-- | 1       | sophia | sophia | 614     | Jun     | 17      | 15:32   | Makefile.toml
 17 | -rw-r--r-- | 1       | sophia | sophia | 0       | Aug     | 23      | 04:58   | open
 18 | -rw-r--r-- | 1       | sophia | sophia | 11375   | Aug     | 24      | 03:24   | README.md
 19 | -r--r--r-- | 1       | sophia | sophia | 0       | Jul     | 4       | 03:51   | readonly.txt
 20 | -rw-r--r-- | 1       | sophia | sophia | 37      | Aug     | 23      | 04:54   | rustfmt2.toml
 21 | -rw-r--r-- | 1       | sophia | sophia | 16      | Aug     | 1       | 19:45   | rustfmt.toml
 22 | drwxr-xr-x | 10      | sophia | sophia | 4096    | Aug     | 24      | 03:24   | src
 23 | drwxr-xr-x | 4       | sophia | sophia | 4096    | Aug     | 22      | 19:22   | target
 24 | drwxr-xr-x | 4       | sophia | sophia | 4096    | Aug     | 22      | 04:15   | tests
 25 | drwxrwxr-x | 2       | sophia | sophia | 4096    | Jul     | 19      | 15:18   | .vscode
----+------------+---------+----------+----------+---------+---------+---------+---------+---------------
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;After a bit of experimenting, we might come up with a command like this:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; ^ls -la | lines | skip 1 | split-column &amp;quot; &amp;quot; perms files group user size month day time name
----+------------+-------+----------+----------+--------+-------+-----+-------+---------------
 #  | perms      | files | group    | user     | size   | month | day | time  | name
----+------------+-------+----------+----------+--------+-------+-----+-------+---------------
 0  | drwxr-xr-x | 13    | sophia | sophia | 4096   | Aug   | 24  | 03:24 | .
 1  | drwxr-xr-x | 21    | sophia | sophia | 4096   | Aug   | 22  | 17:00 | ..
 2  | drwxr-xr-x | 2     | sophia | sophia | 4096   | Aug   | 3   | 05:39 | assets
 3  | drwxr-xr-x | 2     | sophia | sophia | 4096   | Aug   | 21  | 19:29 | .azure
 4  | drwxr-xr-x | 2     | sophia | sophia | 4096   | Jun   | 23  | 05:09 | .cargo
 5  | -rw-r--r-- | 1     | sophia | sophia | 2963   | Aug   | 22  | 20:17 | Cargo2.toml
 6  | -rw-r--r-- | 1     | sophia | sophia | 201255 | Aug   | 24  | 03:24 | Cargo.lock
 7  | -rw-r--r-- | 1     | sophia | sophia | 3127   | Aug   | 24  | 03:24 | Cargo.toml
 8  | drwxr-xr-x | 2     | sophia | sophia | 4096   | Jun   | 17  | 15:32 | docs
 9  | -rw-r--r-- | 1     | sophia | sophia | 148    | Jun   | 17  | 15:32 | .editorconfig
 10 | drwxr-xr-x | 4     | sophia | sophia | 4096   | Aug   | 22  | 19:29 | extra
 11 | drwxr-xr-x | 8     | sophia | sophia | 4096   | Aug   | 24  | 03:24 | .git
 12 | -rw-r--r-- | 1     | sophia | sophia | 58     | Aug   | 10  | 11:08 | .gitignore
 13 | drwxr-xr-x | 2     | sophia | sophia | 4096   | Aug   | 24  | 03:24 | images
 14 | -rw-r--r-- | 1     | sophia | sophia | 1085   | Jun   | 17  | 15:32 | LICENSE
 15 | -rw-r--r-- | 1     | sophia | sophia | 614    | Jun   | 17  | 15:32 | Makefile.toml
 16 | -rw-r--r-- | 1     | sophia | sophia | 0      | Aug   | 23  | 04:58 | open
 17 | -rw-r--r-- | 1     | sophia | sophia | 11375  | Aug   | 24  | 03:24 | README.md
 18 | -r--r--r-- | 1     | sophia | sophia | 0      | Jul   | 4   | 03:51 | readonly.txt
 19 | -rw-r--r-- | 1     | sophia | sophia | 37     | Aug   | 23  | 04:54 | rustfmt2.toml
 20 | -rw-r--r-- | 1     | sophia | sophia | 16     | Aug   | 1   | 19:45 | rustfmt.toml
 21 | drwxr-xr-x | 10    | sophia | sophia | 4096   | Aug   | 24  | 03:24 | src
 22 | drwxr-xr-x | 4     | sophia | sophia | 4096   | Aug   | 22  | 19:22 | target
 23 | drwxr-xr-x | 4     | sophia | sophia | 4096   | Aug   | 22  | 04:15 | tests
 24 | drwxrwxr-x | 2     | sophia | sophia | 4096   | Jul   | 19  | 15:18 | .vscode
----+------------+-------+----------+----------+--------+-------+-----+-------+---------------
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Because Nu let&#x27;s you manipulate your data until it&#x27;s how you want it, there&#x27;s a feeling of playing with your data. You get used to using the verbs, and then you can use them on anything. When you&#x27;re ready, you can write it back to disk.&lt;&#x2F;p&gt;
&lt;p&gt;Oh, before I forget - I wanted to quickly show how to get data from Nu back out into the outside world. Here&#x27;s an example of calling &lt;code&gt;echo&lt;&#x2F;code&gt; on each filename in a directory:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; ls | get name | echo $it
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You can see that we can mix-and-match commands that are inside of Nu with those that are outside, and data will still flow between them as expected. But Nu is more than just a pipeline.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;more-than-a-pipeline&quot;&gt;More than a pipeline&lt;&#x2F;h1&gt;
&lt;p&gt;As we built Nu, we realized we could experiment with other parts of how a shell works. The first of these experiments lead us to an observation: if everything is data in Nu, we should be able to view this data.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.sophiajt.com&#x2F;images&#x2F;view_source.png&quot; alt=&quot;viewing source file&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We&#x27;ve seen the tables. Nu also supports opening and looking at text and binary data. If we open a source file, we can scroll around in a syntax-highlighted file. If we open an xml, we can look at its data. We can even open a binary file and look at what&#x27;s inside (hint: there&#x27;s even a fun easter egg if you open certain kinds binary files, especially if you&#x27;ve installed Nu with the optional &lt;code&gt;rawkey&lt;&#x2F;code&gt; feature).&lt;&#x2F;p&gt;
&lt;p&gt;Being able to view data is helpful, and this kind of polish extends to other aspects, like error messages:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.sophiajt.com&#x2F;images&#x2F;nu_error2.png&quot; alt=&quot;simple error&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Nu takes heavy inspiration from the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blog.rust-lang.org&#x2F;2016&#x2F;08&#x2F;10&#x2F;Shape-of-errors-to-come.html&quot;&gt;error messages in Rust&lt;&#x2F;a&gt;. As much as possible, draw your eyes to the problem.&lt;&#x2F;p&gt;
&lt;p&gt;Combined with the pipeline, some pretty interesting errors are possible:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.sophiajt.com&#x2F;images&#x2F;nu_error_metadata.png&quot; alt=&quot;error with metadata&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;You might wonder how does that even work. Nu has a metadata system (still early!) that you can read about in the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;book.nushell.sh&#x2F;en&#x2F;metadata&quot;&gt;Metadata chapter&lt;&#x2F;a&gt; of the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;book.nushell.sh&quot;&gt;Nu book&lt;&#x2F;a&gt;. Let&#x27;s just take a quick peek at it:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; open Cargo.toml
------------+--------------+------------------+----------+----------
 bin        | dependencies | dev-dependencies | lib      | package
------------+--------------+------------------+----------+----------
 [11 items] | [object]     | [object]         | [object] | [object]
------------+--------------+------------------+----------+----------
&amp;gt; open Cargo.toml | tags
----------+------------------------------------------
 span     | origin
----------+------------------------------------------
 [object] | &#x2F;home&#x2F;sophia&#x2F;Source&#x2F;nushell&#x2F;Cargo.toml
----------+------------------------------------------
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Data that flows through the pipeline gets a set of additional metadata tagged to it. We can use this later to figure out how to display the contents, show a better error message, and more.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;shells-plural&quot;&gt;Shells, plural&lt;&#x2F;h1&gt;
&lt;p&gt;Let&#x27;s say you&#x27;re in a directory, but you&#x27;d really like to flip back and forth between it and one or two others. You could open up multiple tabs, multiple terminals, if you&#x27;re on a Unix system you could use &quot;screen&quot;, and probably even more than that. What if the shells were just built in?&lt;&#x2F;p&gt;
&lt;p&gt;In Nu, we can &lt;code&gt;enter&lt;&#x2F;code&gt; a directory, which adds it to a ring of shells we can bounce between:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; enter ..&#x2F;rhai&#x2F;
&#x2F;home&#x2F;sophia&#x2F;Source&#x2F;rhai(master)&amp;gt; shells
---+---+------------+-------------------------------
 # |   | name       | path
---+---+------------+-------------------------------
 0 |   | filesystem | &#x2F;home&#x2F;sophia&#x2F;Source&#x2F;nushell
 1 | X | filesystem | &#x2F;home&#x2F;sophia&#x2F;Source&#x2F;rhai
---+---+------------+-------------------------------
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Using &lt;code&gt;n&lt;&#x2F;code&gt; and &lt;code&gt;p&lt;&#x2F;code&gt; we can jump back and forth between the shells. &lt;code&gt;exit&lt;&#x2F;code&gt; gets us out of a shell.&lt;&#x2F;p&gt;
&lt;p&gt;You might noticed that &lt;code&gt;name&lt;&#x2F;code&gt; column in the &lt;code&gt;shells&lt;&#x2F;code&gt; table. Why&#x27;s that there? Oh no... oh yes.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; enter Cargo.toml
&#x2F;&amp;gt; shells
---+---+--------------------------------------------+-------------------------------
 # |   | name                                       | path
---+---+--------------------------------------------+-------------------------------
 0 |   | filesystem                                 | &#x2F;home&#x2F;sophia&#x2F;Source&#x2F;nushell
 1 |   | filesystem                                 | &#x2F;home&#x2F;sophia&#x2F;Source&#x2F;rhai
 2 | X | {&#x2F;home&#x2F;sophia&#x2F;Source&#x2F;nushell&#x2F;Cargo.toml} | &#x2F;
---+---+--------------------------------------------+-------------------------------
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;That&#x27;s right, we&#x27;re in the file. Can we &lt;code&gt;cd&lt;&#x2F;code&gt;? Oh yes, we can:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&#x2F;&amp;gt; ls
------------+--------------+------------------+----------+----------
 bin        | dependencies | dev-dependencies | lib      | package
------------+--------------+------------------+----------+----------
 [11 items] | [object]     | [object]         | [object] | [object]
------------+--------------+------------------+----------+----------
&#x2F;&amp;gt; cd bin
&#x2F;bin&amp;gt; ls
----+----------------------+---------------------------
 #  | name                 | path
----+----------------------+---------------------------
 0  | nu_plugin_inc        | src&#x2F;plugins&#x2F;inc.rs
 1  | nu_plugin_sum        | src&#x2F;plugins&#x2F;sum.rs
 2  | nu_plugin_add        | src&#x2F;plugins&#x2F;add.rs
 3  | nu_plugin_edit       | src&#x2F;plugins&#x2F;edit.rs
 4  | nu_plugin_str        | src&#x2F;plugins&#x2F;str.rs
 5  | nu_plugin_skip       | src&#x2F;plugins&#x2F;skip.rs
 6  | nu_plugin_sys        | src&#x2F;plugins&#x2F;sys.rs
 7  | nu_plugin_tree       | src&#x2F;plugins&#x2F;tree.rs
 8  | nu_plugin_binaryview | src&#x2F;plugins&#x2F;binaryview.rs
 9  | nu_plugin_textview   | src&#x2F;plugins&#x2F;textview.rs
 10 | nu                   | src&#x2F;main.rs
----+----------------------+---------------------------
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;plugins&quot;&gt;Plugins&lt;&#x2F;h1&gt;
&lt;p&gt;Nu can&#x27;t come with everything you might want to do with it, so we&#x27;re releasing Nu with the ability to extend it with plugins. There&#x27;s more information in the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;book.nushell.sh&#x2F;en&#x2F;plugins&quot;&gt;plugins chapters&lt;&#x2F;a&gt;. Nu will look for these plugins in your path, and load them up on startup.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;all-because-of-rust&quot;&gt;All because of Rust&lt;&#x2F;h1&gt;
&lt;p&gt;Nu would not have been possible without Rust. Internally, it uses async&#x2F;await, async streams, and liberal use of &quot;serde&quot; to manage serializing and deserializing into the common data format and to communicate with plugins.&lt;&#x2F;p&gt;
&lt;p&gt;We also heavily leveraged &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;crates.io&quot;&gt;crates.io&lt;&#x2F;a&gt;. The ability to load numerous file formats, display messages, draw tables, and more all came from the hundreds (thousands?) of generous developers who wrote the crates we use in Nu. A &lt;strong&gt;huge&lt;&#x2F;strong&gt; thank you to everyone who contributed to Nu without ever knowing it.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;what-s-next&quot;&gt;What&#x27;s next?&lt;&#x2F;h1&gt;
&lt;p&gt;Nu is just getting started. In this release, we have a foundation to build on. Next, we&#x27;ll work towards stability, the abilty to use Nu as your main shell, the ability to write functions and scripts in Nu, and much more.&lt;&#x2F;p&gt;
&lt;p&gt;If you want to give it a spin, the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;book.nushell.sh&#x2F;en&#x2F;installation&quot;&gt;installation instructions&lt;&#x2F;a&gt; will help you get started. If you want to chat come by our &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;discord.gg&#x2F;NtAbbGn&quot;&gt;discord&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;nushell&#x2F;nushell&quot;&gt;github&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Creating crossplatform Rust terminal apps</title>
        <published>2019-04-27T00:00:00+00:00</published>
        <updated>2019-04-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/porting-the-pikachu/"/>
        <id>https://www.sophiajt.com/porting-the-pikachu/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/porting-the-pikachu/">&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;pikachu.jpg&quot; alt=&quot;Pikachu animation in Windows&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Look Mom, Pikachu running in Windows CMD!&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve been wanting to play around with the cool &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;rust&#x2F;comments&#x2F;bf5uzr&#x2F;update_on_my_3d_ascii_art_generator_termiontobj&#x2F;&quot;&gt;spinning Pikachu demo&lt;&#x2F;a&gt; everyone was talking about. Sadly, it used termion to do its magic, which meant that unfortunately it wouldn&#x27;t work for me.&lt;&#x2F;p&gt;
&lt;p&gt;Termion has been a boon for Rust, with lots of folks using it to create terminal applications. Unfortunately, as a Windows user, I know there&#x27;s a good chance that if the crate depends on termion that&#x27;s the end of the line for me, as termion apps just don&#x27;t work in Windows. Surely, I thought, there must be a better way, but I never managed to find one.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;enter-crossterm&quot;&gt;Enter crossterm&lt;&#x2F;h1&gt;
&lt;p&gt;Yesterday, I discovered a crate I have wanted for at least a year: that holy grail of something like termion that also worked crossplatform. The crate is called &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;TimonPost&#x2F;crossterm&quot;&gt;crossterm&lt;&#x2F;a&gt;, and it is exactly that. Rather than being an exact copy of termion, I&#x27;d call Crossterm a termion-like crate. The API surface feels very similar between the two crates, but it&#x27;s not identical. That said, often, the translation is 1:1 (or close to it).&lt;&#x2F;p&gt;
&lt;p&gt;In this post, I&#x27;ll detail what I had to do to port to crossterm. You can take a look at my &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sophiajt&#x2F;rust-sloth&#x2F;tree&#x2F;crossterm-port&quot;&gt;repo&lt;&#x2F;a&gt; and give it a spin.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;moving-to-crossterm&quot;&gt;Moving to crossterm&lt;&#x2F;h2&gt;
&lt;p&gt;Like termion, crossterm is a single crate to depend on that pulls in what you need for interacting with the terminal:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;-termion = &amp;quot;1&amp;quot;
+crossterm = &amp;quot;0.9.3&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Next, is setting up the terminal:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;-    let mut stdout = AlternateScreen::from(stdout().into_raw_mode().unwrap()); &#x2F;&#x2F; Raw output is clean output
-    let mut stdin = async_stdin().bytes(); &#x2F;&#x2F; Async in so input isn&amp;#39;t blocking
+
+    let crossterm = Crossterm::new();
+    #[allow(unused)]
+    let screen = RawScreen::into_raw_mode();
+    let input = crossterm.input();
+    let mut stdin = input.read_async();
+    let cursor = cursor();
+
+    cursor.hide()?;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;There are a few more steps here, and I took a slightly different approach than termion. In the original, the author uses an AlternateScreen, a way to easily switch back to the previous terminal with the application exits. The crossterm package supports this, though there were is an &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;TimonPost&#x2F;crossterm&#x2F;issues&#x2F;128&quot;&gt;issue&lt;&#x2F;a&gt; that&#x27;s being worked on. Using an AlternateScreen is optional, so I just left it off.&lt;&#x2F;p&gt;
&lt;p&gt;The next step was to set up raw mode. Raw mode lets us get user input directly without the normal terminal buffering. The order of operations in crossterm above is important.&lt;&#x2F;p&gt;
&lt;p&gt;Lastly, I hide the cursor so it doesn&#x27;t mess up the animation.&lt;&#x2F;p&gt;
&lt;p&gt;The event loop is similar, though a little more verbose in my version:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;-        let b = stdin.next();
-        if let Some(Ok(b&amp;#39;q&amp;#39;)) = b {
-            break;
+        if let Some(b) = stdin.next() {
+            match b {
+                InputEvent::Keyboard(event) =&amp;gt; match event {
+                    KeyEvent::Char(&amp;#39;q&amp;#39;) =&amp;gt; break,
+                    _ =&amp;gt; {}
+                },
+                _ =&amp;gt; {}
+            }
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The event systems between termion and crossterm, while similar, are different enough that I preferred to do two-step match to make sure I understood it. Events for both key and mouse come in through the event stream, which is a nice benefit.&lt;&#x2F;p&gt;
&lt;p&gt;Drawing colors to the screen is also very similar between termion and crossterm:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;-    format!(&amp;quot;{}{}{}{}&amp;quot;, color::Fg(color::Rgb(bg.0, bg.1, bg.2)),
-                        color::Bg(color::Rgb(25,25,25)),
-                      src,
-                      color::Fg(color::Reset))
+                    print!(
+                        &amp;quot;{}{}{}&amp;quot;,
+                        Colored::Fg(Color::Rgb {
+                            r: (pixel.1).0,
+                            g: (pixel.1).1,
+                            b: (pixel.1).2
+                        }),^M
+                        Colored::Bg(Color::Rgb {
+                            r: 25,
+                            g: 25,
+                            b: 25
+                        }),
+                        pixel.0
+                    )
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The change from &lt;code&gt;color::Fg&lt;&#x2F;code&gt; to &lt;code&gt;Colored::Fg&lt;&#x2F;code&gt; is straightforward enough I did most of these changes with search&#x2F;replace.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;gotchas&quot;&gt;Gotchas&lt;&#x2F;h1&gt;
&lt;p&gt;The translation is not without its own set of hiccups. The main one of which you get a hint at here:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;-    pub frame_buffer: Vec&amp;lt;String&amp;gt;,
+    pub frame_buffer: Vec&amp;lt;(char, (u8, u8, u8))&amp;gt;,
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Originally, the whole framebuffer was turned into a vector of strings. On most Unix platforms, these would include the ANSI commands to change the color or move the cursor. It&#x27;s a powerful tool, and being text-based, you can prebuffer the whole frame via string manipulation.&lt;&#x2F;p&gt;
&lt;p&gt;Unfortunately, assuming everything is string-based doesn&#x27;t work in Windows. When crossterm outputs using println!, it&#x27;s calling into the Windows Console API between each piece of the println. This allows the same code to work, assuming it doesn&#x27;t buffer the string.&lt;&#x2F;p&gt;
&lt;p&gt;To work around this, I stopped buffering the string and instead stored the pixel value in the buffer. When it was time, I drew the whole frame using print! statements.&lt;&#x2F;p&gt;
&lt;p&gt;When I first did this, it was noticeably slower than the termion version(roughly 5-10 fps). This is because calling into the Console API that often (once per character) is going to pull down performance. Luckily, I could work around this by just checking if we were already using the color I wanted to render. If we were, I didn&#x27;t set the color again.&lt;&#x2F;p&gt;
&lt;p&gt;Performance between the termion version and the crossterm version now look the same to me, which I call good enough :)&lt;&#x2F;p&gt;
&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h1&gt;
&lt;p&gt;We have a way to move more of our terminal apps to being crossplatform, so that they work out-of-the-box on Windows as well as Unix-based systems. It was fun to write the port, and I did the port in a couple hours without ever having used crossterm before.&lt;&#x2F;p&gt;
&lt;p&gt;Also, big thanks to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ecumene-software&quot;&gt;Mitchell Hynes&lt;&#x2F;a&gt; for writing the original!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>The Fallow Year, my Rust2019 post</title>
        <published>2018-12-08T00:00:00+00:00</published>
        <updated>2018-12-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/the-fallow-year/"/>
        <id>https://www.sophiajt.com/the-fallow-year/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/the-fallow-year/">&lt;p&gt;&lt;strong&gt;Definition:&lt;&#x2F;strong&gt; &lt;em&gt;fallow: (of agricultural land) Ploughed but left unseeded for more than one planting season.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Rust is an amazing project. It&#x27;s unlike anything I&#x27;ve ever seen. Not only are we seeing an ever-growing number of big name users of Rust, we also continue to see leaps in productivity and functionality. Yesterday, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blog.rust-lang.org&#x2F;2018&#x2F;12&#x2F;06&#x2F;Rust-1.31-and-rust-2018.html&quot;&gt;the Rust 2018 edition shipped&lt;&#x2F;a&gt;. The culmination of three years of work, it shows off what the community is capable of: new features, backwards compatibility, new ergonomics without sacrificing performance, and the list goes on and on.&lt;&#x2F;p&gt;
&lt;p&gt;Which is why it might comes as a little bit of a surprise that I suggest we let the field rest for the year. More specifically, that we should let one field rest while we plant another.&lt;&#x2F;p&gt;
&lt;p&gt;Rather than focusing on new designs, I suggest we turn our attention outside of RFCs to other areas of Rust.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;examples&quot;&gt;Examples&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;strong&gt;The compiler&lt;&#x2F;strong&gt;: The compiler team has been understaffed while also being heavily taxed by the effort of keeping up with new designs. I think they&#x27;ve done a stellar job with the resources they have, but they need help -- and lots of it. RFCs have gone unimplemented simply because not enough people are contributing. Compile times need work. The compiler team is generally too busy to implement core functionality that it hoped to get done this year, like compiler-drive IDE completions.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s clear through the backlog of the growing list of accepted RFCs. Let&#x27;s take the time to do the deep refactoring that we haven&#x27;t had time to do because we were stretched too thin. Let&#x27;s give ourselves space to experiment with new ways of doing things. Let&#x27;s get the compiler ready to serve both build and IDE scenarios.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;RLS and related tools&lt;&#x2F;strong&gt;: We&#x27;ve had big success with projects like rustfmt, and it would be great to mirror that success in the Rust Language Server, or RLS, which powers Rust&#x27;s IDE support. Unfortunately, the current RLS has to rely on many hacks to work with what is available from the compiler. By freeing up the compiler team, we also give space to the dev tools team to collaborate and finish the RLS, removing the need for hacks that cause incomplete functionality and unpredictabilty.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;The community&lt;&#x2F;strong&gt;: That&#x27;s right, the community needs a pause too. Everyone loves new features, but we need a bit of time to let all the new ones sink in before we start designing more. What design patterns will arise in practice? What are the best ways to work with async code at scale? On and on. Getting all this experience will let us see more clearly where to design next.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Documentation, videos, and other materials:&lt;&#x2F;strong&gt; Along with the growing knowledge the community is getting by more using the current Rust more deeply, we can also translate this knowledge into more documentation. The need is strong for mid-level Rust developer documentation. What are the Rust design patterns? How does one get the most benefit from Rust quickly? How does one translate C++ knowedge to Rust? And so on.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Libraries:&lt;&#x2F;strong&gt; We can use the knowledge we have to create new and better libraries. Existing libraries could continue to mature and adopt Rust 2018 idioms. Areas like GUI development need some clear direction and focus.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Outreach:&lt;&#x2F;strong&gt; We&#x27;ve worked on some outreach to companies who might be interested in Rust, but there&#x27;s more we can do here. New whitepapers, new documentation about how to use Rust in specific sub-fields, like finance, data mining, machine learning, etc.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;the-list&quot;&gt;The list&lt;&#x2F;h1&gt;
&lt;p&gt;As it turns out, these aren&#x27;t my ideas. They&#x27;re yours.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blog.rust-lang.org&#x2F;2018&#x2F;11&#x2F;27&#x2F;Rust-survey-2018.html&quot;&gt;This year&#x27;s Rust survey&lt;&#x2F;a&gt; results highlighted these areas of improvement (sorted by number of comments):&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;the need for better library support&lt;&#x2F;li&gt;
&lt;li&gt;a more improved IDE experience&lt;&#x2F;li&gt;
&lt;li&gt;the need for broader adoption of Rust generally&lt;&#x2F;li&gt;
&lt;li&gt;a richer ecosystem of tools and support&lt;&#x2F;li&gt;
&lt;li&gt;an improved learning curve&lt;&#x2F;li&gt;
&lt;li&gt;the need for important language features and crates to be stable and supported&lt;&#x2F;li&gt;
&lt;li&gt;support for async programming&lt;&#x2F;li&gt;
&lt;li&gt;support for GUI development&lt;&#x2F;li&gt;
&lt;li&gt;better documentation&lt;&#x2F;li&gt;
&lt;li&gt;improved compile times&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;You&#x27;ll notice that only one of these, &quot;support for async programming&quot;, implies adding new functionality to Rust itself. Rather than asking for new features, users wanted better documentation, tools, library support, IDE support, learning materials, and overall stability.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;the-idea&quot;&gt;The idea&lt;&#x2F;h1&gt;
&lt;p&gt;Let&#x27;s finish what we started. As much as is possible and practical this year, let&#x27;s set aside new designs and ship what we&#x27;ve already designed. Let&#x27;s tackle challenges we haven&#x27;t had time to give our full attention.&lt;&#x2F;p&gt;
&lt;p&gt;In short, let&#x27;s grow Rust where it needs it most.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>A Snapshot of Rust&#x27;s Popularity in July 2018</title>
        <published>2018-07-28T00:00:00+00:00</published>
        <updated>2018-07-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/snapshot-of-rust-popularity/"/>
        <id>https://www.sophiajt.com/snapshot-of-rust-popularity/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/snapshot-of-rust-popularity/">&lt;p&gt;Talking about a language&#x27;s popularity is traditionally a tricky topic. How do you measure popularity? How do you compare one language to another when they&#x27;re focused on different styles and different audiences? So, rather than having one or two charts, I&#x27;m going to look at a number of &quot;slices&quot; into Rust&#x27;s growth to see it front different angles.&lt;&#x2F;p&gt;
&lt;p&gt;There are also &lt;em&gt;many&lt;&#x2F;em&gt; ways we could measure popularity. For example, looking at the growth of StackOverflow, internal forums, Twitter traffic, Google Trends, or the various language popularity reports. Each of these measures has its own strengths and trade-offs.&lt;&#x2F;p&gt;
&lt;p&gt;For our purposes in this post, we&#x27;re going to focus on a set of data points that should help show growth of &lt;em&gt;usage&lt;&#x2F;em&gt; rather than growth of &lt;em&gt;buzz&lt;&#x2F;em&gt; (that is, the amount people talking are about Rust). If people are using a language to do real work, that&#x27;s the best indicator of a language&#x27;s success.&lt;&#x2F;p&gt;
&lt;p&gt;The first of place we&#x27;ll look for Rust usage is in open source, and with that, let&#x27;s look at GitHub.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;growth-on-github&quot;&gt;Growth on GitHub&lt;&#x2F;h1&gt;
&lt;p&gt;GitHub offers a few ways to measure how well a particular language is growing. GitHub itself uses the number of pull requests in a given language, which it uses in the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;octoverse.github.com&quot;&gt;GitHub Octoverse&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;If we were to run this query for 2018 so far, the top fifteen languages (by number of PRs) would be:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;JavaScript: 1736476&lt;&#x2F;li&gt;
&lt;li&gt;Python: 804790&lt;&#x2F;li&gt;
&lt;li&gt;Java: 703649&lt;&#x2F;li&gt;
&lt;li&gt;Ruby: 560430&lt;&#x2F;li&gt;
&lt;li&gt;PHP: 359040&lt;&#x2F;li&gt;
&lt;li&gt;C++: 319324&lt;&#x2F;li&gt;
&lt;li&gt;TypeScript: 311229&lt;&#x2F;li&gt;
&lt;li&gt;Go: 258131&lt;&#x2F;li&gt;
&lt;li&gt;C#: 246513&lt;&#x2F;li&gt;
&lt;li&gt;CSS: 236795&lt;&#x2F;li&gt;
&lt;li&gt;Shell: 168301&lt;&#x2F;li&gt;
&lt;li&gt;C: 160889&lt;&#x2F;li&gt;
&lt;li&gt;Swift: 67664&lt;&#x2F;li&gt;
&lt;li&gt;Scala: 67188&lt;&#x2F;li&gt;
&lt;li&gt;Rust: 52936&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Rust comes in at 15th place as part of the group of Swift&#x2F;Scala&#x2F;Rust. This is pretty good company to be in. All of the languages on this list are known for doing heavy lifting in real applications, rather than being hobby or boutique languages.&lt;&#x2F;p&gt;
&lt;p&gt;Being 15th is also significant because, if the Octoverse were held today, Rust would make their top languages list for the first time.&lt;&#x2F;p&gt;
&lt;p&gt;Moving on, one gotcha of focusing on PRs is that it lets a relatively small number of highly successful projects skew the results. The popularity of the projects drives high numbers of PRs, and as a result the language looks far better. To compensate for this, let&#x27;s also look at &quot;active projects&quot;. For our purposes, let&#x27;s define &quot;active projects&quot; as the number of projects that a) are larger than a &quot;hello world&quot;, b) have at least 1 star, and c) have been worked on in the last 30 days:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;JavaScript: 56437&lt;&#x2F;li&gt;
&lt;li&gt;Python: 37554&lt;&#x2F;li&gt;
&lt;li&gt;Java: 27912&lt;&#x2F;li&gt;
&lt;li&gt;C++: 16787&lt;&#x2F;li&gt;
&lt;li&gt;PHP: 16451&lt;&#x2F;li&gt;
&lt;li&gt;Shell: 12245&lt;&#x2F;li&gt;
&lt;li&gt;C#: 11503&lt;&#x2F;li&gt;
&lt;li&gt;C: 10662&lt;&#x2F;li&gt;
&lt;li&gt;Go: 8816&lt;&#x2F;li&gt;
&lt;li&gt;CSS: 8781&lt;&#x2F;li&gt;
&lt;li&gt;TypeScript: 8447&lt;&#x2F;li&gt;
&lt;li&gt;Ruby: 7518&lt;&#x2F;li&gt;
&lt;li&gt;Swift: 3828&lt;&#x2F;li&gt;
&lt;li&gt;Objective-C: 3054&lt;&#x2F;li&gt;
&lt;li&gt;Rust: 2604&lt;&#x2F;li&gt;
&lt;li&gt;Kotlin: 2343&lt;&#x2F;li&gt;
&lt;li&gt;Scala: 2072&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Another respectable showing for Rust. Again, we see it as part of the languages for doing serious work.&lt;&#x2F;p&gt;
&lt;p&gt;The GitHub numbers tell one story, but do we see the same story if we look in other places? With this kind of popularity, we&#x27;d expect to see visible use of Rust in industry.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;rust-s-commercial-users&quot;&gt;Rust&#x27;s Commercial Users&lt;&#x2F;h1&gt;
&lt;p&gt;Rust has seen a surprising amount of growth in commercial usage over the past year alone. Here&#x27;s a partial list of names people may know:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Amazon&lt;&#x2F;strong&gt; - Building &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;amzn&#x2F;askalono&quot;&gt;tools in Rust&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Atlassian&lt;&#x2F;strong&gt; (makers of Jira) - Using &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;rust-www&#x2F;pull&#x2F;922&quot;&gt;Rust in the backend&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Dropbox&lt;&#x2F;strong&gt; - Using Rust in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;air.mozilla.org&#x2F;rust-meetup-may-2017&#x2F;&quot;&gt;both the frontend and backend&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Facebook&lt;&#x2F;strong&gt; - Tools for &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;Sunjay03&#x2F;status&#x2F;1019782490800603136&quot;&gt;source control&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Google&lt;&#x2F;strong&gt; - As part of the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;fuchsia-mirror?utf8=%E2%9C%93&amp;amp;q=&amp;amp;type=&amp;amp;language=rust&quot;&gt;Fuchsia project&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Microsoft&lt;&#x2F;strong&gt; - Using Rust in part of their &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;maxgortman&#x2F;status&#x2F;1012011425353461760&quot;&gt;new Azure IoT work&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;npm&lt;&#x2F;strong&gt; - Using Rust in some of the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;rust-www&#x2F;pull&#x2F;634&quot;&gt;npm core services&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Red Hat&lt;&#x2F;strong&gt; - Creating a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;stratis-storage&quot;&gt;new storage system&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Reddit&lt;&#x2F;strong&gt; - Using Rust in its &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;rust&#x2F;comments&#x2F;7utj4t&#x2F;reddit_is_hiring_a_senior_rust_engineer&#x2F;&quot;&gt;comment processing&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Twitter&lt;&#x2F;strong&gt; - As part of the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;stuhood&#x2F;status&#x2F;978410393944047617?s=19&quot;&gt;build team support for Twitter&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;You can see even more on the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rust-lang.org&#x2F;en-US&#x2F;friends.html&quot;&gt;Friends of Rust&lt;&#x2F;a&gt; that include other familiar names like Baidu, Wire, Mozilla, Samsung, Cloudflare, Chef, Canonical, and more.&lt;&#x2F;p&gt;
&lt;p&gt;Across the industry, software companies are beginning to adopt Rust at some level in their organization. As expected, these may be tentative at first, focusing on Rust for build tools, for backend processing, or targeting a specific platform like IoT. Early adopters like Dropbox and Canonical have now grown beyond initial investments to using Rust in an increasing amount of their codebase.&lt;&#x2F;p&gt;
&lt;p&gt;All told, it&#x27;s still early days for Rust. Large companies take time to try new technology before they adopt it more broadly. We&#x27;re seeing Rust in that part of the adoption curve, and it&#x27;s doing well here. Languages -- like Go and TypeScript -- that saw explosive growth in recent years also saw similar patterns at this part of their lifecycle.&lt;&#x2F;p&gt;
&lt;p&gt;Because of Rust&#x27;s closeness with C++, we should also look at industries that are traditionally strongly populated by C++ developers. One such industry is game development.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;zooming-into-games&quot;&gt;Zooming into Games&lt;&#x2F;h1&gt;
&lt;p&gt;Despite the game industry&#x27;s use of established development technologies, Rust is beginning to make in-roads with game developers. Here&#x27;s a list of usage of Rust in some familiar names among game developers:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Chucklefish Games&lt;&#x2F;strong&gt; - Using Rust in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rust-lang.org&#x2F;pdfs&#x2F;Rust-Chucklefish-Whitepaper.pdf&quot;&gt;multiple upcoming games&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Electronic Arts&lt;&#x2F;strong&gt; - Using Rust in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;ZigguratVertigo&#x2F;status&#x2F;1021562281056980993&quot;&gt;SEED&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Frostbite Engine&lt;&#x2F;strong&gt; - Using Rust in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;Ca1ne&#x2F;status&#x2F;983612241235804160&quot;&gt;backend processing&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Ready at Dawn Studios&lt;&#x2F;strong&gt; - &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;AndreaPessino&#x2F;status&#x2F;1021532074153394176&quot;&gt;All new development&lt;&#x2F;a&gt; will be in Rust.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Unity&lt;&#x2F;strong&gt; - Using Rust in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;bltroutwine&#x2F;status&#x2F;1002234680949719040&quot;&gt;data engineering&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;We&#x27;re also seeing &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;SergiusIW&#x2F;status&#x2F;1021236971786694656&quot;&gt;other indie developers&lt;&#x2F;a&gt; beginning to use it for their titles.&lt;&#x2F;p&gt;
&lt;p&gt;Just as we saw in the &quot;big name&quot; usage, we see a similar pattern with game developers. Initial usage is targeted, perhaps at backend or data-focused projects. After this, there&#x27;s a path to developing core technology, and even whole games, in Rust.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;jobs&quot;&gt;Jobs&lt;&#x2F;h1&gt;
&lt;p&gt;When we ran the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blog.rust-lang.org&#x2F;2017&#x2F;09&#x2F;05&#x2F;Rust-2017-Survey-Results.html&quot;&gt;2017 Rust survey&lt;&#x2F;a&gt;, one of the big themes that came up for people not using Rust was around their companies not using it. The jobs just weren&#x27;t there.&lt;&#x2F;p&gt;
&lt;p&gt;In 2018, with a growing numbers of companies and studios using Rust, has this situation improved?&lt;&#x2F;p&gt;
&lt;p&gt;In short, yes, though there&#x27;s still a lot of room to grow. A quick look at LinkedIn&#x27;s job list shows a number of Rust opportunities from the likes of Amazon as well as a number of companies involved in blockchain, security, science&#x2F;healthcare, and more. Still, when compared to the volume of job offerings for languages like Go or TypeScript, there&#x27;s still a gap in terms of availability.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s move on from Rust&#x27;s use in companies to look at the growth of the community that supports Rust.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;community-and-governance&quot;&gt;Community and Governance&lt;&#x2F;h1&gt;
&lt;p&gt;In times past, a language could survive on being used solely for commercial development. These days, however, a language&#x27;s community forms its foundation. It offers a way to ramp up new users, support new projects, and set the tone for the project going forward.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;rust_meetups.png&quot; alt=&quot;Map showing Rust being used in over 130 meetups around the world&quot; &#x2F;&gt;
&lt;em&gt;Rust meetups now total over 130 around the world&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The in-person piece of the Rust community, the Rust meetups, have seen 30% growth in the last nine months and now total over 130 around the world. We&#x27;ve likewise seen steady growth in the number of conferences that users can attend for more training and networking.&lt;&#x2F;p&gt;
&lt;p&gt;We&#x27;ve also seen some impressive growth in indicators of the online community as well since the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.sophiajt.com&#x2F;2017&#x2F;10&#x2F;fun-facts-about-rust-growth.html&quot;&gt;last time I reported on them&lt;&#x2F;a&gt;. For example, the Rust reddit recently passed 40k users (up from the 29k of nine months ago), the GitHub repo is nearly at 30k stars (up from 24k), and the official Rust twitter has over 31k followers (up from 24k).&lt;&#x2F;p&gt;
&lt;p&gt;This enthusiasm has also translated into the teams that govern Rust itself. Combined, the governing teams have doubled in size in the last 9 months to over &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rust-lang.org&#x2F;en-US&#x2F;team.html&quot;&gt;100 positions across the various teams&lt;&#x2F;a&gt;. The scope has also grown in tandem, with new teams that cover infrastructure, developer experiences, and dependency management.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h1&gt;
&lt;p&gt;These are just some data points about Rust&#x27;s use in industry and in the software development community. It&#x27;s difficult to get a complete picture, and even more difficult to predict what will come next. That said, it does seem to shine a promising ray of light on where Rust is today.&lt;&#x2F;p&gt;
&lt;p&gt;Where will Rust go tomorrow? That is anyone&#x27;s guess. I, for one, will certainly be watching and cheering it along.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Starting the next thing</title>
        <published>2018-07-24T00:00:00+00:00</published>
        <updated>2018-07-24T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/starting-the-next-thing/"/>
        <id>https://www.sophiajt.com/starting-the-next-thing/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/starting-the-next-thing/">&lt;p&gt;It&#x27;s that time again! July 31st will be my last day at Mozilla.&lt;&#x2F;p&gt;
&lt;p&gt;Even though I was only at Mozilla for just under two and a half years, I had the good fortune to work on some pretty awesome projects.&lt;&#x2F;p&gt;
&lt;p&gt;I joined the Rust team and worked with Niko Matsakis and Aaron Turon on where Rust could grow, building on my experience coming from TypeScript. We learned a &lt;em&gt;ton&lt;&#x2F;em&gt; from each other, and I&#x27;m really grateful for all those conversations and the close friendship that resulted. I also got to roll up my sleeves and write some code. The first project was to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blog.rust-lang.org&#x2F;2016&#x2F;08&#x2F;10&#x2F;Shape-of-errors-to-come.html&quot;&gt;redesign the Rust error messages&lt;&#x2F;a&gt; with Niko. The next was to create the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;internals.rust-lang.org&#x2F;t&#x2F;introducing-rust-language-server-source-release&#x2F;4209&quot;&gt;Rust Language Server&lt;&#x2F;a&gt; with Nick Cameron. Both have grown a life of their own, and it&#x27;s been awesome to see!&lt;&#x2F;p&gt;
&lt;p&gt;I was also lucky to help Jack Moffitt out with the Servo project. Under his guidance, it produced loads of good code and good ideas. These made their way into &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;hacks.mozilla.org&#x2F;2017&#x2F;08&#x2F;inside-a-super-fast-css-engine-quantum-css-aka-stylo&#x2F;&quot;&gt;Firefox&lt;&#x2F;a&gt; and into the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blog.mozilla.org&#x2F;blog&#x2F;2018&#x2F;04&#x2F;03&#x2F;mozilla-brings-firefox-augmented-virtual-reality&#x2F;&quot;&gt;Firefox Reality&lt;&#x2F;a&gt; work. Learning from Jack and connecting with the Firefox org (and some of the awesome Firefox managers) was a treat.&lt;&#x2F;p&gt;
&lt;p&gt;Finally, my last seven months have been helping create and run the Developer Technology team at Mozilla, a melding of the Rust and WebAssembly efforts under one umbrella. This allowed even closer collaboration between the two projects and has already resulted in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;rustwasm.github.io&#x2F;&quot;&gt;lots of cool new technology, tools, and coding practices&lt;&#x2F;a&gt;. I&#x27;m excited to watch what they&#x27;ll be able to come up with next.&lt;&#x2F;p&gt;
&lt;p&gt;And speaking of &quot;next&quot;, what&#x27;s next for me?  I&#x27;m moving on to create a new company.  I don&#x27;t have a ton of details to share, yet, but I hope to do so in the coming months as the ideas and technology start to come together.  &quot;Will it use Rust?&quot; I can already hear many of you asking.  Most assuredly.  If there&#x27;s a better solution for efficient, write-once-and-don&#x27;t-worry-about-it software development, I&#x27;ve yet to find it.&lt;&#x2F;p&gt;
&lt;p&gt;Thank you, Mozilla!  Both for the experience and for the friends I&#x27;ve made along the way.&lt;&#x2F;p&gt;
&lt;p&gt;PS: I plan to continue podcasting - it&#x27;s fun :)&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>How fast can we compile Rust hello world?</title>
        <published>2018-05-03T00:00:00+00:00</published>
        <updated>2018-05-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/how-fast-can-we-compile-rust-hello-world/"/>
        <id>https://www.sophiajt.com/how-fast-can-we-compile-rust-hello-world/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/how-fast-can-we-compile-rust-hello-world/">&lt;p&gt;Seeing &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blog.mozilla.org&#x2F;nnethercote&#x2F;2018&#x2F;04&#x2F;30&#x2F;how-to-speed-up-the-rust-compiler-in-2018&#x2F;&quot;&gt;Nick Nethercote&#x27;s blog post about speeding up the compiler&lt;&#x2F;a&gt;, I started wondering just how fast could a Rust compiler be? How fast could we compile a simple example? How fast can we compile a Rust hello world?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;starting-out&quot;&gt;Starting out&lt;&#x2F;h2&gt;
&lt;p&gt;When you do a &lt;code&gt;cargo new hello_rust --bin&lt;&#x2F;code&gt;, you get a simple Rust hello world:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;fn main() {
    println!(&amp;quot;Hello, world!&amp;quot;);
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Awesome. Let&#x27;s see how long this takes to build:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;term&quot;&gt;&amp;gt; time cargo build
   Compiling hello_rust v0.1.0 (file:&#x2F;&#x2F;&#x2F;home&#x2F;sophia&#x2F;Source&#x2F;hello_rust)
    Finished dev [unoptimized + debuginfo] target(s) in 0.52 secs

real     0m0.548s
user     0m0.468s
sys      0m0.080s
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Half a second on my XPS 13 9360, with a i7-7500U @ 2.70GHz with 16 gigs of RAM. That seems, a bit long for a hello world. Maybe cargo is doing extra work?&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;term&quot;&gt;&amp;gt; time rustc src&#x2F;main.rs

real     0m0.378s
user     0m0.289s
sys      0m0.083s
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;That&#x27;s definitely better. We&#x27;re just over 1&#x2F;3rd of a second.&lt;&#x2F;p&gt;
&lt;p&gt;What should we expect? If only there were another language we could compile a hello world for that&#x27;s comparable...&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;term&quot;&gt;&amp;gt; cat hello_c.c
#include &amp;lt;stdio.h&amp;gt;

int main() {
    puts(&amp;quot;Hello, from C!&amp;quot;);
    return 0;
}
&amp;gt; time clang hello_c.c

real     0m0.082s
user     0m0.021s
sys      0m0.041s
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Woooaah! Wait a second. You&#x27;re telling me that compiling C hello world is over 4.5x faster. That&#x27;s... that&#x27;s something. Maybe the compiler is doing a bit too much work for this small example? I mean, we don&#x27;t need much from the standard library, just the println macro.&lt;&#x2F;p&gt;
&lt;p&gt;You know, a reasonable person would probably stop here and walk away. Chalk it up to &quot;Rust is more complicated&quot; or &quot;maybe if I knew the right commandline options&quot;&lt;&#x2F;p&gt;
&lt;p&gt;No, that&#x27;s not us. Not today. Today, we&#x27;re going to write our own Rust translator. We&#x27;re going to see just how fast we can compile Rust to a working hello world.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;first-stop-let-s-build-a-rust-c-translator&quot;&gt;First stop: let&#x27;s build a Rust-&amp;gt;C translator.&lt;&#x2F;h2&gt;
&lt;p&gt;Here&#x27;s my thinking: if we write our own translator, we can translate the Rust to C ourselves, and then compile the C. That way, we should end up with a compile time close to the C.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;term&quot;&gt;&amp;gt; cargo new rabbithole --bin
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Writing a full compiler is complex work, but we&#x27;re going for speed here. And speed means cutting corners. To that end, we&#x27;re implementing &lt;em&gt;just enough&lt;&#x2F;em&gt; of a compiler to translate our Rust to C, then we&#x27;re calling that good enough.&lt;&#x2F;p&gt;
&lt;p&gt;First step, we need a parser. Luckily, there already is a crate that can parse Rust code for us.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;[dependencies]
syn = {version = &amp;quot;0.13&amp;quot;, features = [&amp;quot;full&amp;quot;, &amp;quot;extra-traits&amp;quot;] }
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;extern crate syn;

use std::env;
use std::fs::File;
use std::io::Read;

fn main() {
    let mut args = env::args();
    args.next();

    match args.next() {
        Some(fname) =&amp;gt; {
            let mut src = String::new();
            let mut file = File::open(&amp;amp;fname).expect(&amp;quot;Unable to open file&amp;quot;);
            file.read_to_string(&amp;amp;mut src).expect(&amp;quot;Unable to read file&amp;quot;);

            let syntax = syn::parse_file(&amp;amp;src).expect(&amp;quot;Unable to parse file&amp;quot;);
            println!(&amp;quot;{:#?}&amp;quot;, syntax);
        }
        _ =&amp;gt; {
            println!(&amp;quot;Please supply the file to compile&amp;quot;);
        }
    }
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code data-lang=&quot;term&quot;&gt;&amp;gt; cargo run -- hello.rs
File {
    shebang: None,
    attrs: [],
    items: [
        Fn(
            ItemFn {
                attrs: [],
                vis: Inherited,
                constness: None,
                unsafety: None,
                abi: None,
                ident: Ident {
                    term: Term {
                        sym: main
                    }
                },
                decl: FnDecl {
                    fn_token: Fn,
                    generics: Generics {
                        lt_token: None,
                        params: [],
                        gt_token: None,
                        where_clause: None
                    },
                    paren_token: Paren,
                    inputs: [],
                    variadic: None,
                    output: Default
                },
                block: Block {
                    brace_token: Brace,
                    stmts: [
                        Item(
                            Macro(
                                ItemMacro {
                                    attrs: [],
                                    ident: None,
                                    mac: Macro {
                                        path: Path {
                                            leading_colon: None,
                                            segments: [
                                                PathSegment {
                                                    ident: Ident {
                                                        term: Term {
                                                            sym: println
                                                        }
                                                    },
                                                    arguments: None
                                                }
                                            ]
                                        },
                                        bang_token: Bang,
                                        delimiter: Paren(
                                            Paren
                                        ),
                                        tts: TokenStream [
                                            Literal {
                                                lit: &amp;quot;Hello, world!&amp;quot;
                                            }
                                        ]
                                    },
                                    semi_token: Some(
                                        Semi
                                    )
                                }
                            )
                        )
                    ]
                }
            }
        )
    ]
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This might look a bit intimidating, so let&#x27;s break it down. The top-most thing is a File.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;File&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Each File continues zero or more Items. An Item are things like declarations. Function declarations, for example, are one kind of Item.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;File
&lt;ul&gt;
&lt;li&gt;Item&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Since this file has one function, it has one item, an ItemFn. This holds all the information about our main function. You can see in here that we have the function&#x27;s declaration (sometimes called the function prototype, if you come from C). This tells us how many parameters it takes, what its return type is, etc. Luckily for us, this is all empty because main has nothing interesting here. This lets us focus on the body of the function, here called &#x27;block&#x27;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;File
&lt;ul&gt;
&lt;li&gt;Item (ItemFn)
&lt;ul&gt;
&lt;li&gt;Block&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Blocks contain statements and expressions. This is really the meat of what actually &lt;em&gt;does&lt;&#x2F;em&gt; things, and which is where we&#x27;ll actually spend our time writing the compiler. Let&#x27;s take a closer look:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;block: Block {
    brace_token: Brace,
    stmts: [
        Item(
            Macro(
                ItemMacro {
                    attrs: [],
                    ident: None,
                    mac: Macro {
                        path: Path {
                            leading_colon: None,
                            segments: [
                                PathSegment {
                                    ident: Ident {
                                        term: Term {
                                            sym: println
                                        }
                                    },
                                    arguments: None
                                }
                            ]
                        },
                        bang_token: Bang,
                        delimiter: Paren(
                            Paren
                        ),
                        tts: TokenStream [
                            Literal {
                                lit: &amp;quot;Hello, world!&amp;quot;
                            }
                        ]
                    },
                    semi_token: Some(
                        Semi
                    )
                }
            )
        )
    ]
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;On closer inspection we see this block has only one statement. A something-something macro something or other. Oh right, println is a macro! Let&#x27;s focus on just the macro invocation itself:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;mac: Macro {
    path: Path {
        leading_colon: None,
        segments: [
            PathSegment {
                ident: Ident {
                    term: Term {
                        sym: println
                    }
                },
                arguments: None
            }
        ]
    },
    bang_token: Bang,
    delimiter: Paren(
        Paren
    ),
    tts: TokenStream [
        Literal {
            lit: &amp;quot;Hello, world!&amp;quot;
        }
    ]
},
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now this is a little more like it. It&#x27;s still a little cumbersome, but we can see the parts we need. There&#x27;s a &lt;code&gt;sym&lt;&#x2F;code&gt; thing that says what the macro is. Later on, we can see the string that we&#x27;re printing is a literal string. We can ignore the rest.&lt;&#x2F;p&gt;
&lt;p&gt;That&#x27;s it. Make sure it&#x27;s invoking println, and then we&#x27;ll look for the string that&#x27;s being printed.&lt;&#x2F;p&gt;
&lt;p&gt;To make things a little easier on ourselves, let&#x27;s make a quick-and-dirty intermediate representation. This will only have one command so far, but it&#x27;ll be an easy way to de-couple the function that does the parsing from the one that does the code generation.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;enum Command {
    PrintLn(String)
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;With that, we&#x27;re ready to make our parser that can take in the &lt;code&gt;syn::File&lt;&#x2F;code&gt; and output our Command. There are a few ways we can do this, but to keep things pretty simple, I&#x27;m going to make a separate &lt;code&gt;parse&lt;&#x2F;code&gt; function for each layer we talked about earlier: File, Item, and Block. You can think of this as us unpacking the useful information from what &lt;code&gt;syn&lt;&#x2F;code&gt; gives us into much simpler data structures.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;extern crate syn;

use std::env;
use std::fs;
use std::io::Read;

#[derive(Debug)]
struct File {
    functions: Vec&amp;lt;Function&amp;gt;,
}

#[derive(Debug)]
struct Function {
    body: Vec&amp;lt;Command&amp;gt;,
}

#[derive(Debug)]
enum Command {
    PrintLn(String),
}

fn parse_body(body: &amp;amp;syn::Block) -&amp;gt; Result&amp;lt;Vec&amp;lt;Command&amp;gt;, String&amp;gt; {
    let mut stmts = vec![];
    for stmt in &amp;amp;body.stmts {
        match stmt {
            syn::Stmt::Item(syn::Item::Macro(ref im)) =&amp;gt; {
                let macro_name = im.mac.path.segments[0].ident.as_ref();
                if macro_name == &amp;quot;println&amp;quot; {
                    match im.mac.tts.clone().into_iter().next() {
                        Some(ref arg) =&amp;gt; {
                            stmts.push(Command::PrintLn(arg.to_string()));
                        }
                        None =&amp;gt; return Err(&amp;quot;Expected argument in function&amp;quot;.into()),
                    }
                } else {
                    return Err(format!(&amp;quot;Unknown macro: {}&amp;quot;, macro_name));
                }
            }
            _ =&amp;gt; return Err(&amp;quot;Unexpected statement in function&amp;quot;.into()),
        }
    }
    Ok(stmts)
}

fn parse_fn(item: &amp;amp;syn::ItemFn) -&amp;gt; Result&amp;lt;Function, String&amp;gt; {
    Ok(Function {
        body: parse_body(&amp;amp;item.block)?,
    })
}

fn parse_file(file: &amp;amp;syn::File) -&amp;gt; Result&amp;lt;File, String&amp;gt; {
    let mut functions = vec![];
    for item in &amp;amp;file.items {
        match item {
            syn::Item::Fn(ref item_fn) =&amp;gt; {
                functions.push(parse_fn(item_fn)?);
            }
            _ =&amp;gt; return Err(&amp;quot;Unexpected item in file&amp;quot;.into()),
        }
    }
    Ok(File { functions })
}

fn main() {
    let mut args = env::args();
    args.next();

    match args.next() {
        Some(fname) =&amp;gt; {
            let mut src = String::new();
            let mut file = fs::File::open(&amp;amp;fname).expect(&amp;quot;Unable to open file&amp;quot;);
            file.read_to_string(&amp;amp;mut src).expect(&amp;quot;Unable to read file&amp;quot;);

            let syntax = syn::parse_file(&amp;amp;src).expect(&amp;quot;Unable to parse file&amp;quot;);
            let result = parse_file(&amp;amp;syntax);

            println!(&amp;quot;{:#?}&amp;quot;, result);
        }
        _ =&amp;gt; {
            println!(&amp;quot;Please supply the file to compile&amp;quot;);
        }
    }
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Which results in:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;term&quot;&gt;Ok(
    File {
        functions: [
            Function {
                body: [
                    PrintLn(
                        &amp;quot;\&amp;quot;Hello, world!\&amp;quot;&amp;quot;
                    )
                ]
            }
        ]
    }
)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;That&#x27;s much nicer! It took a little work reading the &lt;code&gt;syn&lt;&#x2F;code&gt; documentation, but once we got the hang of it, we can now work with real Rust source code and turn it into something we can use.&lt;&#x2F;p&gt;
&lt;p&gt;Oh, before we go, let&#x27;s clean one thing up. You might have noticed that extra set of quotes in the macro argument. No problem, we&#x27;ll just turn:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;stmts.push(Command::PrintLn(arg.to_string()));
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Into:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;stmts.push(Command::PrintLn(arg.to_string().replace(&amp;quot;\&amp;quot;&amp;quot;, &amp;quot;&amp;quot;)));
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Which gives us:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;term&quot;&gt;Ok(
    File {
        functions: [
            Function {
                body: [
                    PrintLn(
                        &amp;quot;Hello, world!&amp;quot;
                    )
                ]
            }
        ]
    }
)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Beautiful. Now that we have it in this form, we have a much simpler form that we can hand to the other half of the translator. In this half, we&#x27;ll be outputting the C code and compiling it.&lt;&#x2F;p&gt;
&lt;p&gt;Since we only care about one function in one file, let&#x27;s just make a quick-and-dirty function to generate the C:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;fn compile_to_c(file: &amp;amp;File) -&amp;gt; String {
    let mut c_output = String::new();

    c_output += &amp;quot;#include &amp;lt;stdio.h&amp;gt;\n&amp;quot;;
    c_output += &amp;quot;int main() {\n&amp;quot;;

    for stmt in &amp;amp;file.functions[0].body {
        match stmt {
            Command::PrintLn(ref msg) =&amp;gt; {
                c_output += &amp;amp;format!(&amp;quot;puts(\&amp;quot;{}\&amp;quot;);\n&amp;quot;, msg);
            }
        }
    }

    c_output += &amp;quot;}\n&amp;quot;;
    c_output
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;That&#x27;s it. Let&#x27;s call it.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;println!(&amp;quot;{}&amp;quot;, compile_to_c(&amp;amp;result.unwrap()));
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Running it again, we get:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;term&quot;&gt;#include &amp;lt;stdio.h&amp;gt;
int main() {
puts(&amp;quot;Hello, world!&amp;quot;);
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Woah! That looks like C to me. Dare we try to compile it?&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;term&quot;&gt;&amp;gt; cargo run -- ..&#x2F;hello_rust&#x2F;src&#x2F;main.rs  &amp;gt; testme.c
&amp;gt; clang testme.c
&amp;gt; .&#x2F;a.out
Hello, world!
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It... works! We just made a compiler!&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;term&quot;&gt;&amp;gt; time .&#x2F;target&#x2F;release&#x2F;rabbithole ..&#x2F;hello_rust&#x2F;src&#x2F;main.rs &amp;gt; testme.c

real    0m0.014s
user    0m0.010s
sys    0m0.004s
&amp;gt; time clang testme.c -o testme
real    0m0.100s
user    0m0.043s
sys    0m0.041s
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Nice, by cutting lots of corners and making our own translator, we got the compile times down from 0.378s to 0.114s, less than 1&#x2F;3rd of where we were.&lt;&#x2F;p&gt;
&lt;p&gt;Should we stop there? Surely we can go further down the rabbit hole. Oh right, C is not the lowest we can go&lt;&#x2F;p&gt;
&lt;h2 id=&quot;deeper-down-the-rabbit-hole&quot;&gt;Deeper down the rabbit hole&lt;&#x2F;h2&gt;
&lt;p&gt;Let&#x27;s cook up some assembly. First, let&#x27;s test how fast we can assemble a hello world in assembly.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;term&quot;&gt;&amp;gt; cat hello_asm.s
 .text
 .global main
main:
 mov $hw_str, %rdi
 call puts
 mov $0, %rax
 ret

 .data
hw_str:
 .asciz &amp;quot;hello asm&amp;quot;
&amp;gt; time as hello_asm.s -o hello_asm.o
real    0m0.019s
user    0m0.008s
sys    0m0.011s
&amp;gt; time ld -o hello -dynamic-linker &#x2F;lib64&#x2F;ld-linux-x86-64.so.2 &#x2F;usr&#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;crt1.o &#x2F;usr&#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;crti.o -lc hello_asm.o &#x2F;usr&#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;crtn.o

real    0m0.044s
user    0m0.036s
sys    0m0.008s
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Wow, the assembly output cuts the compile almost in half! If you haven&#x27;t seen x64 assembly before, that might look a little strange. Instead of working with C code with functions, we&#x27;ve dropped down much closer to the machine itself. The above represents the lowest we can go in Linux. Let&#x27;s unpack what&#x27;s happening:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;asm&quot;&gt; .text
 .global main
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Our assembly file starts with two things. One, a section that we&#x27;ll be talking about the code itself (.text) and then the one symbol we&#x27;ll be making visible (main). This will be the main function that the linker will use later.&lt;&#x2F;p&gt;
&lt;p&gt;Next, main begins:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;asm&quot;&gt;main:
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;What follows are series of assembly commands. The hardware keeps numbers and addresses in registers, similar to how you might store them in variables.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;asm&quot;&gt;mov $hw_str, %rdi
call puts
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;With that in mind, this doesn&#x27;t seem quite so bad. The first line is going to set up our register that we&#x27;ll use as the argument to the puts function (here, in Linux, %rdi). After the argument is ready, we call puts.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;asm&quot;&gt; mov $0, %rax
 ret
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;After that, we return 0, just like we did in C. Here, in 64-bit assembly, we&#x27;re returning the return value in %rax.&lt;&#x2F;p&gt;
&lt;p&gt;That&#x27;s it. Oh wait, one more thing. So this was the code section, we still haven&#x27;t told it what the string is to print (which we called $hw_str earlier).&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;asm&quot;&gt; .data
hw_str:
 .asciz &amp;quot;hello asm&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;That&#x27;s not bad. We have a data section that contains our strings. We have one string, called &lt;code&gt;hw_str&lt;&#x2F;code&gt;, and we give it a null-terminated string to print.&lt;&#x2F;p&gt;
&lt;p&gt;You may have been wondering about our linker line, too:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;term&quot;&gt;&amp;gt; time ld -o hello -dynamic-linker &#x2F;lib64&#x2F;ld-linux-x86-64.so.2 &#x2F;usr&#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;crt1.o &#x2F;usr&#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;crti.o -lc hello_asm.o &#x2F;usr&#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;crtn.o
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This bit of magic is actually the kind of tasks that your C compiler does for you behind the scenes. In Linux, for a program to run, it needs to be able to access things like the Linux program loader, the C standard library, and the Linux subsystems. The above takes the barebones object file we made with the assembler and gives it all it needs to be a complete Linux executable.&lt;&#x2F;p&gt;
&lt;p&gt;Before we write our assembly-outputting function, let&#x27;s take a quick pause and talk about Windows. We&#x27;ve been giving a lot of examples for Linux, but you can do the same kinds of things in Windows. Make sure you have a 64-bit &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.nasm.us&#x2F;&quot;&gt;nasm&lt;&#x2F;a&gt; installed.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;term&quot;&gt;C:\Users\Sophia\source\fast_hello&amp;gt;type nasm_hello.asm
    global main
    extern puts

    section .text
main:
    push rbp
    mov rbp, rsp
    mov rcx, message
    call puts
    mov rax, 0
    pop rbp
    ret
message:
    db &amp;#39;Hello, Rust!&amp;#39;, 0
C:\Users\Sophia\source\fast_hello&amp;gt;nasm -f win64 nasm_hello.asm -g -o nasm_hello.obj

C:\Users\Sophia\source\fast_hello&amp;gt;link -out:b.exe -defaultlib:libcmt &amp;quot;-libpath:C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\lib\\amd64&amp;quot; &amp;quot;-libpath:C:\\Program Files (x86)\\Windows Kits\\10\\Lib\\10.0.15063.0\\ucrt\\x64&amp;quot; &amp;quot;-libpath:C:\\Program Files (x86)\\Windows Kits\\10\\Lib\\10.0.15063.0\\um\\x64&amp;quot; -nologo nasm_hello.obj
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You can see that the assembly looks different, though it&#x27;s similar. We do a little more setup, but the core of the work is the same. We set up where the string is, we send it to the &lt;code&gt;puts&lt;&#x2F;code&gt; function, and we return 0 via the &lt;code&gt;rax&lt;&#x2F;code&gt; register. Likewise, after we have an object file from the assembler, we have to do a similar dance with the linker in order to have a fully working Windows executable.&lt;&#x2F;p&gt;
&lt;p&gt;With that, we can see all the techniques we&#x27;re using in Linux can work in Windows, too.&lt;&#x2F;p&gt;
&lt;p&gt;Okay, let&#x27;s finish this up and see where we are. Just like we wrote a C output function, we&#x27;re going to write an assembly output function. This function will create two strings: one for the code and one for the data, and then stitch them together.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;fn compile_to_asm(file: &amp;amp;File) -&amp;gt; String {
    let mut asm_code_output = String::new();
    let mut asm_data_output = String::new();

    asm_data_output += &amp;quot;.data\n&amp;quot;;

    asm_code_output += &amp;quot;.text\n&amp;quot;;
    asm_code_output += &amp;quot;.global main\n&amp;quot;;
    asm_code_output += &amp;quot;main:\n&amp;quot;;

    let mut temp_num = 0;
    for stmt in &amp;amp;file.functions[0].body {
        match stmt {
            Command::PrintLn(ref msg) =&amp;gt; {
                asm_code_output += &amp;amp;format!(&amp;quot;mov $str_{}, %edi\n&amp;quot;, temp_num);
                asm_code_output += &amp;quot;call puts\n&amp;quot;;

                asm_data_output += &amp;amp;format!(&amp;quot;str_{}:\n&amp;quot;, temp_num);
                asm_data_output += &amp;amp;format!(&amp;quot; .asciz \&amp;quot;{}\&amp;quot;&amp;quot;, msg);
                temp_num += 1;
            }
        }
    }

    asm_code_output + &amp;amp;asm_data_output
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre&gt;&lt;code data-lang=&quot;term&quot;&gt;&amp;gt; time .&#x2F;target&#x2F;release&#x2F;rabbithole ..&#x2F;hello_rust&#x2F;src&#x2F;main.rs &amp;gt; hello_asm.s

real    0m0.015s
user    0m0.010s
sys    0m0.005s
&amp;gt; time as hello_asm.s -o hello_asm.o
real    0m0.022s
user    0m0.009s
sys    0m0.012s
&amp;gt; time ld -o hello -dynamic-linker &#x2F;lib64&#x2F;ld-linux-x86-64.so.2 &#x2F;usr&#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;crt1.o &#x2F;usr&#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;crti.o -lc hello_asm.o &#x2F;usr&#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;crtn.o

real    0m0.043s
user    0m0.029s
sys    0m0.011s
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;From 0.114s to 0.08s. We dropped another 30% off the compile time!&lt;&#x2F;p&gt;
&lt;p&gt;To recap, we started at 0.548s with Cargo, then 0.378s with rustc, 0.114 going via C, and 0.08 going via assembly. Roughly a 6.8x speedup. Can we squeeze anything else out?&lt;&#x2F;p&gt;
&lt;p&gt;You might be wondering about keeping more things in memory and getting a bit more caching. It&#x27;s a good hunch, let&#x27;s try it!&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;term&quot;&gt;&amp;gt; time (.&#x2F;target&#x2F;release&#x2F;rabbithole ..&#x2F;hello_rust&#x2F;src&#x2F;main.rs &amp;gt; hello_asm.s &amp;amp;&amp;amp; as hello_asm.s -o hello_asm.o &amp;amp;&amp;amp; ld -o hello -dynamic-linker &#x2F;lib64&#x2F;ld-linux-x86-64.so.2 &#x2F;usr&#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;crt1.o &#x2F;usr&#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;crti.o -lc hello_asm.o &#x2F;usr&#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;crtn.o)

real    0m0.048s
user    0m0.028s
sys    0m0.021s
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;That&#x27;s another 40% off the compile time. We&#x27;ve now gone from 0.548s to 0.048s, a whole 11x faster. There&#x27;s even more we can do. For example, we can squeeze out more by writing our own parser, outputting the .o ourselves, and more. But we&#x27;ll leave that as an exercise for the reader.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;I hope you had as much fun reading this post as I had in writing it. There are amazing benefits to all the features that cargo and rustc provide, and the Rust ecosystem builds on those benefits. At the same time, it&#x27;s fun to play around with compiler technology and see that when we get down to it, it&#x27;s just another Rust program that we can tune to our heart&#x27;s content.&lt;&#x2F;p&gt;
&lt;p&gt;You can see the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sophiajt&#x2F;rabbithole&quot;&gt;rabbithole source&lt;&#x2F;a&gt; if you want to play with it yourself.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Talking about how we talk about Rust in 2018</title>
        <published>2018-01-10T00:00:00+00:00</published>
        <updated>2018-01-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/how-we-talk-about-rust-in-2018/"/>
        <id>https://www.sophiajt.com/how-we-talk-about-rust-in-2018/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/how-we-talk-about-rust-in-2018/">&lt;p&gt;&lt;em&gt;This is an entry in the #rust2018 blogging efforts to talk about Rust in 2018&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;When you come to Rust, you&#x27;re bound to hear a lot of phrases.  &quot;Wrestling with the compiler&quot;. &quot;Rust evangelism task force&quot;. &quot;Non-lexical lifetimes&quot;. &quot;Systems programming&quot;.  Some seem strange. Others are a bit scary.  Some are just a common set you quickly need to learn to before you can even read the Rust news.&lt;&#x2F;p&gt;
&lt;p&gt;In this post, I want to talk about how we talk about Rust in 2018.  I think there are some ways we can change what we&#x27;re saying and how we&#x27;re saying it. These changes will help Rust be more approachable for beginners and an even nicer place in general.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;wrestling-with-the-compiler&quot;&gt;&quot;Wrestling with the compiler&quot;&lt;&#x2F;h1&gt;
&lt;p&gt;I think we&#x27;ve all been there. Especially when we&#x27;re starting with Rust, or trying to do something new with it we haven&#x27;t done before, we feel like the compiler is fighting us every step of the way.&lt;&#x2F;p&gt;
&lt;p&gt;Sure, it&#x27;s frustrating. On a bad day, we might even say &quot;forget it&quot;. I wonder, though, is there a better way to talk about it? If you&#x27;re a Rust user, do you trust the compiler?  Are the error messages helping to clarify your thinking?  Is it, as some people like to say, a pair programming partner for you?&lt;&#x2F;p&gt;
&lt;p&gt;I suggest in 2018, we kick the idea of wrestling with the Rust compiler to the curb and focus on how it helps us rather than the idea of it beating us down.  Niko mentioned &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;smallcultfollowing.com&#x2F;babysteps&#x2F;blog&#x2F;2018&#x2F;01&#x2F;09&#x2F;rust2018&#x2F;&quot;&gt;error messages&lt;&#x2F;a&gt; here to help with that, and I think we should push hard there.  While we can change how we talk about the compiler, we can also change how the compiler talks to us as well.&lt;&#x2F;p&gt;
&lt;p&gt;By the end of 2018, no more wrestling.  It&#x27;s a tool to help us, and we should work hard both in how we talk and how it works to ensure this is true.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;rust-evangelism-task-force&quot;&gt;&quot;Rust evangelism task force&quot;&lt;&#x2F;h1&gt;
&lt;p&gt;We&#x27;ve seen the jokes about Rust having its own task force that swoops in and says things like &quot;you should rewrite it in Rust&quot;.  Sometimes the swoop happens just as a new security exploit is released.  Sometimes it comes out of nowhere.&lt;&#x2F;p&gt;
&lt;p&gt;Or maybe you&#x27;ve seen this: someone on a thread, maybe on reddit, posts that &lt;em&gt;maybe&lt;&#x2F;em&gt; Rust isn&#x27;t doing so well in a benchmark or in a particular scenario.  Minutes later there are half a dozen comments dissecting what happened.&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s intimidating.  And really, it&#x27;s not helpful to Rust.&lt;&#x2F;p&gt;
&lt;p&gt;As a community, it&#x27;s great that we have so much enthusiasm.  I just want to be sure we&#x27;re channeling that enthusiasm in a way that keeps Rust growing.  There are ways we can be courteous by not piling on or jumping in with uninvited suggestions.  That might seem like little things, but at scale I think they&#x27;ll make a big difference.&lt;&#x2F;p&gt;
&lt;p&gt;Some of you may be familiar with burntsushi&#x27;s ripgrep tool.  The author of a similar tool, ack, had a &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;blog.petdance.com&#x2F;2018&#x2F;01&#x2F;02&#x2F;the-best-open-source-project-for-someone-might-not-be-yours-and-thats-ok&#x2F;&quot;&gt;great quote&lt;&#x2F;a&gt; about the other day that applies to more than just search tools:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;If someone uses ripgrep instead of ack, it doesn’t hurt me.  It’s the difference between an abundance vs. scarcity view of the world.  I choose abundance.&quot;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;We can adopt the same way of thinking.  If someone wants to use Go or C instead of Rust, that&#x27;s great!  Perhaps that&#x27;s a better fit for what they&#x27;re working on.  Maybe they&#x27;ll try Rust again in the future.  We should make it easy to come and go.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;systems-programming&quot;&gt;&quot;Systems programming&quot;&lt;&#x2F;h1&gt;
&lt;p&gt;There are a lot of terms that we use when talking about Rust that I think are simply confusing.  Have you ever had this conversation?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Person 1:&lt;&#x2F;strong&gt; Have you heard of the Rust programming language?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Person 2:&lt;&#x2F;strong&gt; I&#x27;m not sure, what is it?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Person 1:&lt;&#x2F;strong&gt; It&#x27;s a systems programming language.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Person 2:&lt;&#x2F;strong&gt; What&#x27;s a systems programming language?&lt;&#x2F;p&gt;
&lt;p&gt;Rather than answering the question, we just made it seem even more complicated.  Confusingly, even among people who have used Rust for a while there isn&#x27;t even total consensus on what is meant by a systems programming language.  Doubly confusingly, Rust isn&#x27;t even &lt;em&gt;just&lt;&#x2F;em&gt; a systems programming language anymore.  With the ability to create web applications and tie into other languages, it starts to feel more than just systems-level development.&lt;&#x2F;p&gt;
&lt;p&gt;You can use Rust to build pretty much anything from a low-level operating system component to a JSX-like web app.  In the future, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;marshall_law&#x2F;status&#x2F;944031810941603840&quot;&gt;we&#x27;ll be in space&lt;&#x2F;a&gt;.  Systems is both too confusing and too limiting for what Rust will be used to do.&lt;&#x2F;p&gt;
&lt;p&gt;Maybe there&#x27;s a better term that we can use, or a small phrase that captures the right feel?&lt;&#x2F;p&gt;
&lt;h1 id=&quot;non-lexical-lifetimes-and-more&quot;&gt;&quot;Non-lexical lifetimes&quot; and more&lt;&#x2F;h1&gt;
&lt;p&gt;Lots of the Rust community is pretty facile when it comes to computer science.  Some of us have dabbled in Haskell.  Others are old-hands at C++.  We&#x27;ve seen programming from different angles and have a lot of vocabulary to use to describe Rust.&lt;&#x2F;p&gt;
&lt;p&gt;This started out as pretty effective short-hand.  &quot;This is like typeclasses in Haskell&quot; we might say.  &quot;Lifetimes are lexically-scoped&quot;.  &quot;You need to use a lifetime variable, they&#x27;re just like generics...&quot; Etc.  We can use it to communicate, but the end result can be a bit of a mouthful.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m not going to suggest we remove these terms from our vocabulary entirely, but I want us to think about how we can improve what we write publically.  People we don&#x27;t know will come by IRC, read our blog posts, and see our forum threads.  They&#x27;ll be coming from a variety of backgrounds, many of which will be different from our own.&lt;&#x2F;p&gt;
&lt;p&gt;If where we&#x27;re talking is public with a wide audience, let&#x27;s keep that in mind as we communicate.  Keep the door open for more people to join.&lt;&#x2F;p&gt;
&lt;p&gt;Rust, at its heart, isn&#x27;t intimidating.  It&#x27;s a technology that a wide range of programmers can use to target a wide range of applications.  We don&#x27;t need to make it sound or feel more complicated, and those extra few minutes to reword a sentence here or there can help.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Improving how we improve Rust in 2018</title>
        <published>2018-01-07T00:00:00+00:00</published>
        <updated>2018-01-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/rust2018-and-data/"/>
        <id>https://www.sophiajt.com/rust2018-and-data/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/rust2018-and-data/">&lt;p&gt;Here&#x27;s my #rust2018 post to add to the batch.&lt;&#x2F;p&gt;
&lt;p&gt;The past few years, I&#x27;ve been lucky to be part of the Rust community survey process.  In 2016, this data helped show the need to improve usability.  We had good foundations, but they were too hard to get at.  In 2017, we saw a renewed need to reach out to companies, to improve documentation, and a continued importance of pushing to making Rust more usable.&lt;&#x2F;p&gt;
&lt;p&gt;These surveys were a key part of seeing big issues, but it got me thinking.  Are there better ways to get and use data?  Can we see Rust more clearly -- for what we do well and where we need to improve -- in the future?&lt;&#x2F;p&gt;
&lt;p&gt;When you do performance tuning, you benchmark and run perf profilers to get at the root of the problem.  What if we did the equivalent for Rust as a whole?&lt;&#x2F;p&gt;
&lt;p&gt;We already measure through the surveys.  The problem is, we can only really measure once or twice a year.  This results in waiting long periods of time to see if we successfully addressed an issue.  The delay may mean we don&#x27;t catch new issues in time or we may fix a problem only to find out we didn&#x27;t address the underlying cause.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;getting-better-data-sooner&quot;&gt;Getting better data, sooner&lt;&#x2F;h1&gt;
&lt;p&gt;What if we had a way to have better data sooner?  There are a few ways we could do this.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;smaller-surveys&quot;&gt;Smaller surveys&lt;&#x2F;h2&gt;
&lt;p&gt;The first thing we could do is put out smaller surveys and use them as a quick check-in.  They might target specific features in a &quot;did this change solve your issue?&quot; way.  We do a bit of this in the RFC process already.  People who know about a particular RFC can jump in and comment on whether or not it the approach works for them.&lt;&#x2F;p&gt;
&lt;p&gt;While we want to continue using RFCs for this feedback, we could extend what we do here.  For example, a blog post could talk about a group of RFCs working together to address one core problem. We could have a quick survey as part of the post to gather feedback on whether the combination of changes does what we hoped.&lt;&#x2F;p&gt;
&lt;p&gt;This is still pretty manual, though, and is focused developers actively reading RFCs and blogs and volunteering their time, which may be limited.  Are there ways we can get more people involved across a wider range of changes?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;usability-studies&quot;&gt;Usability studies&lt;&#x2F;h2&gt;
&lt;p&gt;There&#x27;s another avenue we could explore: usability studies.  Work on software development in the past has shown there&#x27;s naturally a distance between what people &lt;em&gt;think&lt;&#x2F;em&gt; they spend the most time on and what they actually &lt;em&gt;do&lt;&#x2F;em&gt; spend the most time on.  Self-reporting often misses these insights.&lt;&#x2F;p&gt;
&lt;p&gt;When you actually watch someone working, issues with usability become more obvious.&lt;&#x2F;p&gt;
&lt;p&gt;With the rise of coding streams, we already have some usability data already.  Perhaps there is a way to leverage the same tools so that we can perform studies remotely.  The end result of these could more directly answer how workflows improve, and give us a clearer insight into both the Rust learning process and how more experienced Rust users use Rust in their work.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;opt-in-statistics&quot;&gt;Opt-in statistics&lt;&#x2F;h2&gt;
&lt;p&gt;What if Rust developers could opt-in to some statistics gathered from the tools themselves?  This would let Rust developers help the Rust project as part of their everyday work.&lt;&#x2F;p&gt;
&lt;p&gt;So it&#x27;s clear, let me state I&#x27;m a strong privacy advocate.  I have no desire to read people&#x27;s private source code, to try to &quot;guess&quot; what they&#x27;re doing, or anything remotely like that.  Instead, here are some ideas we could be looking at that are helpful while not being invasive:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;What error messages are people hitting?  How often?&lt;&#x2F;li&gt;
&lt;li&gt;Roughly how much time is spent working in Rust?&lt;&#x2F;li&gt;
&lt;li&gt;How long are build times compared to the lines of code?  How much is incremental compilation helping?&lt;&#x2F;li&gt;
&lt;li&gt;Roughly how much are particular language features being used?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I believe there&#x27;s a way to we can gather data like this in a way that is both opt-in and preserves the privacy of the developer.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;transparency&quot;&gt;Transparency&lt;&#x2F;h2&gt;
&lt;p&gt;An important aspect of &quot;better data, sooner&quot; is transparency.&lt;&#x2F;p&gt;
&lt;p&gt;If we&#x27;re careful, we can and should make the data we gather public.  It gives contributors a window into the Rust world in more depth than we&#x27;ve previously had.&lt;&#x2F;p&gt;
&lt;p&gt;Imagine a live &quot;board&quot; where you could go and see Rust being used in real time, seeing what errors are occuring the most or if the latest fixes to nightly improved build times in the wild.  This data could help not only people putting code in the compiler, but also folks writing RFCs, documentation, and more.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;measure-twice-cut-once&quot;&gt;Measure twice, cut once&lt;&#x2F;h1&gt;
&lt;p&gt;When I was growing up, my dad would do various woodworking projects around the house.  When I&#x27;d help, he would remind me to &quot;measure twice, cut once&quot;.  You didn&#x27;t want to waste the effort it took to cut the wood if you couldn&#x27;t use the result.&lt;&#x2F;p&gt;
&lt;p&gt;We can take a similar attitude for Rust in 2018.  There are a lot of things we &lt;em&gt;could&lt;&#x2F;em&gt; do.  Lots of initiatives.  Lots of projects.  Can we come up with ways to measure twice before we invest the time?  I think we can, and Rust will be better for it.&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s to a happy, successful Rust in 2018!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Fun facts about Rust&#x27;s growing popularity</title>
        <published>2017-10-30T00:00:00+00:00</published>
        <updated>2017-10-30T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/fun-facts-about-rust-growth/"/>
        <id>https://www.sophiajt.com/fun-facts-about-rust-growth/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/fun-facts-about-rust-growth/">&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;There are now &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rust-lang.org&#x2F;en-US&#x2F;friends.html&quot;&gt;100 friends of Rust&lt;&#x2F;a&gt; (Be sure to hover to learn about how each company uses Rust)&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;There are now 3 Rust podcasts: &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.newrustacean.com&#x2F;&quot;&gt;New Rustacean&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;rusty-spike.blubrry.net&#x2F;&quot;&gt;Rusty Spike&lt;&#x2F;a&gt;, and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;request-for-explanation.github.io&#x2F;podcast&#x2F;&quot;&gt;Request for Explanation&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;First year had one conference, the second year had three, and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blog.rust-lang.org&#x2F;2017&#x2F;07&#x2F;18&#x2F;conf-lineup.html&quot;&gt;this year had four&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;crates.io is not even 3 years old, but already the number of crates has &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.modulecounts.com&#x2F;&quot;&gt;passed CRAN(R) and Hackage(Haskell)&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The Rust reddit is now over &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;rust&#x2F;&quot;&gt;29,000 Rustaceans strong&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;the #rust irc channel has grown to over 1300 people&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The Rust gitter channel is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gitter.im&#x2F;rust-lang&#x2F;rust&quot;&gt;over 1800 people&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;our first Rust survey had 3,086 responses. Our second had 5,368 responses, over 2,000 more than the first year.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Rust is a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;octoverse.github.com&#x2F;&quot;&gt;top 10 most discussed&lt;&#x2F;a&gt; project on GitHub.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Rust is a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;octoverse.github.com&#x2F;&quot;&gt;top 10 most reviewed&lt;&#x2F;a&gt; project on GitHub.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Rust is used on &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;air.mozilla.org&#x2F;rust-meetup-may-2017&#x2F;&quot;&gt;hundreds of millions of desktops&lt;&#x2F;a&gt; via Dropbox.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The &quot;impl period&quot; now has &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;internals.rust-lang.org&#x2F;t&#x2F;the-impl-period-newsletter-2&#x2F;6034&quot;&gt;at least 37 different teams&lt;&#x2F;a&gt; helping implement new designs.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The popular @code, ranked 5th in this years Stack Overflow survey, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Microsoft&#x2F;vscode&#x2F;pull&#x2F;22722&quot;&gt;powers its code search with ripgrep&lt;&#x2F;a&gt;, a search tool written in Rust.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Atlassian uses Rust in a service for analyzing petabytes of source code.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The new O&#x27;Reilly Rust book was the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;safaribot&#x2F;status&#x2F;919255962120318976&quot;&gt;most popular on Safari&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;There are &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.meetup.com&#x2F;topics&#x2F;rust&#x2F;&quot;&gt;over 100 meetups&lt;&#x2F;a&gt; around the world discussing Rust.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;npm rewrote performance-critical bottlenecks in the registry service architecture with Rust.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Popular indie game developer Chucklefish recently &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;rust&#x2F;comments&#x2F;78bowa&#x2F;hey_this_is_kyren_from_chucklefish_we_make_and&#x2F;&quot;&gt;announced their new game will be written in Rust&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The number of full-time Rust developers continues to grow. Over half are &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blog.rust-lang.org&#x2F;2017&#x2F;09&#x2F;05&#x2F;Rust-2017-Survey-Results.html&quot;&gt;working on large Rust codebases&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Rust was the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;insights.stackoverflow.com&#x2F;survey&#x2F;2017#most-loved-dreaded-and-wanted&quot;&gt;most loved technology two years in a row&lt;&#x2F;a&gt; in the Stack Overflow survey.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;@rustlang has &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;rustlang&quot;&gt;over 24k twitter followers&lt;&#x2F;a&gt; 🎉🎉&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;367 applicants applied for the 12 spots in the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blog.rust-lang.org&#x2F;2017&#x2F;06&#x2F;27&#x2F;Increasing-Rusts-Reach.html&quot;&gt;Rust Reach initiative&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;There are at least 5 Rust books in production, with releases over the next 18 monts.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Red Hat added support for Rust in their &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;developers.redhat.com&#x2F;blog&#x2F;2017&#x2F;10&#x2F;04&#x2F;red-hat-adds-go-clangllvm-rust-compiler-toolsets-updates-gcc&#x2F;&quot;&gt;recent updates&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;IntelliJ &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;intellij-rust.github.io&#x2F;2017&#x2F;07&#x2F;31&#x2F;changelog-47.html&quot;&gt;officially supports Rust&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Rust&#x27;s reddit channel hit 100,000 uniques and 1,000,000 views in July&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Amazon is hiring for &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.jobs&#x2F;en&#x2F;jobs&#x2F;559813&#x2F;sr-software-development-engineer&quot;&gt;developers with Rust experience&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Google engineers are experimenting with &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;chromium.googlesource.com&#x2F;chromiumos&#x2F;platform&#x2F;crosvm&#x2F;&quot;&gt;Rust for low-level system modules&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The official &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;channel&#x2F;UCaYhcUwRBNscFNUKTjgPFiA&#x2F;videos&quot;&gt;Rust YouTube channel&lt;&#x2F;a&gt; has over 90 videos on Rust.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Android Rust development grew &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blog.rust-lang.org&#x2F;2017&#x2F;09&#x2F;05&#x2F;Rust-2017-Survey-Results.html&quot;&gt;10x in 2017 (to 9.9% of devs)&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;iOS Rust development grew &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blog.rust-lang.org&#x2F;2017&#x2F;09&#x2F;05&#x2F;Rust-2017-Survey-Results.html&quot;&gt;10x in 2017 (to 5.3% of devs)&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Rust has seen slow, steady growth in commercial usage. Now over &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blog.rust-lang.org&#x2F;2017&#x2F;09&#x2F;05&#x2F;Rust-2017-Survey-Results.html&quot;&gt;20% of Rust devs use it at work&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blog.rust-lang.org&#x2F;2017&#x2F;09&#x2F;05&#x2F;Rust-2017-Survey-Results.html&quot;&gt;More than 75% of respondents&lt;&#x2F;a&gt; said they feel comfortable in the Rust community, which includes even non-users of Rust.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blog.rust-lang.org&#x2F;2017&#x2F;09&#x2F;05&#x2F;Rust-2017-Survey-Results.html&quot;&gt;Rust attracts about 18%&lt;&#x2F;a&gt;, or roughly 1&#x2F;5th, of its userbase in new users every month.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The number of Rust devs with more than a year of experience grew to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blog.rust-lang.org&#x2F;2017&#x2F;09&#x2F;05&#x2F;Rust-2017-Survey-Results.html&quot;&gt;42% in the last year&lt;&#x2F;a&gt;. That&#x27;s a lot of experience!&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;More than 2% of all Rust devs work on Rust codebases totalling &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blog.rust-lang.org&#x2F;2017&#x2F;09&#x2F;05&#x2F;Rust-2017-Survey-Results.html&quot;&gt;more than 100k lines of code&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;A growing number of Rust devs use Windows, which now makes up over &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blog.rust-lang.org&#x2F;2017&#x2F;09&#x2F;05&#x2F;Rust-2017-Survey-Results.html&quot;&gt;30% of all Rust users&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;This year we saw a huge increase, at &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blog.rust-lang.org&#x2F;2017&#x2F;09&#x2F;05&#x2F;Rust-2017-Survey-Results.html&quot;&gt;16% of responses&lt;&#x2F;a&gt;, in the amount and style of documentation requested to cover more learning styles&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;This year we also saw a shift in non-user reasons to be &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blog.rust-lang.org&#x2F;2017&#x2F;09&#x2F;05&#x2F;Rust-2017-Survey-Results.html&quot;&gt;companies don&#x27;t use it&lt;&#x2F;a&gt;. More folks now would learn it if it can pay the bills.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Speaking of module counts, at 16&#x2F;day Rust is the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.modulecounts.com&#x2F;&quot;&gt;7th fastest growing package repo&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;internals.rust-lang.org&#x2F;&quot;&gt;Rust internal forum&lt;&#x2F;a&gt; is a hotbed of activity, with popular posts regularly getting over 10k views.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;A growing number of GNOME developers are using Rust, with ports underway for &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;mail.gnome.org&#x2F;archives&#x2F;desktop-devel-list&#x2F;2017-January&#x2F;msg00001.html&quot;&gt;some important libraries&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Rust and GNOME teams have had one hackfest with another next month&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Though early days, we&#x27;re seeing more Rust support in the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;coaxion.net&#x2F;blog&#x2F;2017&#x2F;10&#x2F;rendering-html5-video-in-servo-with-gstreamer&#x2F;&quot;&gt;gstreamer media playback framework&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Canonical uses Rust in everything from server monitoring to middleware.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Lots of System 76 &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;system76&quot;&gt;tools and systems code&lt;&#x2F;a&gt; are written in Rust.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Principal Intel engineers are &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;agnathan&#x2F;status&#x2F;895461817899663360&quot;&gt;encouraging people to learn Rust&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Facebook wrote a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;facebookexperimental&#x2F;mononoke&quot;&gt;mercurial server in Rust&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Facebook is also a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rust-belt-rust.com&#x2F;sponsors.html&quot;&gt;sponsor for Rust Belt Rust&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;thanks.rust-lang.org&#x2F;&quot;&gt;Over 2000 people&lt;&#x2F;a&gt; have contributed to Rust.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The github repo has also gotten over 24k stars, making it one of the most popular programming language repos.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Not to be missed, even the Rust book repo had &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;book&quot;&gt;over 180 contributors&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Rust &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;hacks.mozilla.org&#x2F;2016&#x2F;07&#x2F;shipping-rust-in-firefox&#x2F;&quot;&gt;first shipped in Firefox 48&lt;&#x2F;a&gt;, almost a year and a half ago.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Rust is now used in five different modules in Firefox, with the next release having a new style system written in Rust.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;RustBridge&quot;&gt;Rust Bridge&lt;&#x2F;a&gt; continues to be a good outreach to underrepresented developers, now having its 7th(?) event at this week&#x27;s Rust Belt Rust&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Rust is supported by &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rust-lang.org&#x2F;en-US&#x2F;team.html&quot;&gt;11 regular subteams and 3 shepherd teams&lt;&#x2F;a&gt; that help mentor and lead discussion&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Staff engineer at Tumblr mentions that &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;pearapps&#x2F;status&#x2F;902485357178048512&quot;&gt;Tumblr is using Rust&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Rust is just behind Scala in active github projects (this month: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;api.github.com&#x2F;search&#x2F;repositories?q=stars:%3E0+forks:%3E0+size:%3E10+language:rust+pushed:2017-10-01..2017-10-31&quot;&gt;1263&lt;&#x2F;a&gt; vs &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;api.github.com&#x2F;search&#x2F;repositories?q=stars:%3E0+forks:%3E0+size:%3E10+language:scala+pushed:2017-10-01..2017-10-31&quot;&gt;1376&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;If you haven&#x27;t seen them yet, the Mozilla Hacks videos are some of Rust&#x27;s most popular (with &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=8EPsnf_ZYU0&quot;&gt;one over 50k views&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Also in the survey, 16.8% of Rust devs are doing embedded work.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.twitter.com&#x2F;japaricious&quot;&gt;Jorge Aparacio&lt;&#x2F;a&gt; has been a long-time supporter for embedded and is writing a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;japaric&#x2F;discovery&quot;&gt;book for embedded Rust development&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Rust got mentioned in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;chasinglogic&#x2F;status&#x2F;850115493923086336&quot;&gt;a Batgirl comic&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The new Chucklefish game is not the first in Rust. An even earlier game was &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.twitter.com&#x2F;bringershar&quot;&gt;Shar&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Between Rust&#x27;s first and second year, 56 RFCs were merged.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;In the last ~3 months, 36 RFCs were merged.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Rust has had over 45 releases. Many since 1.0 have been well-received in programming news circles.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Another published Rust game is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;m12y.com&#x2F;a-snakes-tale&#x2F;&quot;&gt;a Snake&#x27;s Tale&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Speaking of popular posts, one Rust project, alacritty, received &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=13338592&quot;&gt;over 1000 points on Hacker News&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;crates.io has had over 240,000,000 downloads&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;standard Rust tools are voted&#x2F;promoted by the community. RLS, rustfmt, clippy, and rustup each have over 1000 stars on GitHub.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;for a bit of history, here&#x27;s &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blog.rust-lang.org&#x2F;2015&#x2F;04&#x2F;10&#x2F;Fearless-Concurrency.html&quot;&gt;a post that helped start it all&lt;&#x2F;a&gt;. To this day, still a regularly referenced post.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Ever wonder about the en-US at the end of https:&#x2F;&#x2F;www.rust-lang.org&#x2F;en-US&#x2F; ? The Rust homepage is in 13 different languages!&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Language interop is an important piece of Rust&#x27;s growth. We have C++ interop with &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang-nursery&#x2F;rust-bindgen&quot;&gt;bindgen&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;There&#x27;s also node.js interop with &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.twitter.com&#x2F;RustNeon&quot;&gt;Neon&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;There&#x27;s good Ruby&#x2F;Rust interop with &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;tildeio&#x2F;helix&quot;&gt;Helix&lt;&#x2F;a&gt; and others&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Python and Rust also have &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;bheisler.github.io&#x2F;post&#x2F;calling-rust-in-python&#x2F;&quot;&gt;on-going interop work&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;In addition to interop, Rust has been an &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;apple&#x2F;swift-evolution&#x2F;blob&#x2F;master&#x2F;releases&#x2F;swift-4_0.md&quot;&gt;influence on Swift&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Rust&#x27;s focus on memory safety without performance loss has helped other languages as well, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=iDFhvCkCLb4&amp;amp;list=PL3jwVPmk_PRxo23yyoc0Ip_cP3-rCm7eB&amp;amp;index=1&quot;&gt;including D&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Rust has also been inspired by other languages, including a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blog.rust-lang.org&#x2F;2016&#x2F;08&#x2F;10&#x2F;Shape-of-errors-to-come.html&quot;&gt;revamp of errors&lt;&#x2F;a&gt; inspired by Elm.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Rust has also grown from a wide range of influences, including discussions with &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;channel9.msdn.com&#x2F;Events&#x2F;Lang-NEXT&#x2F;Lang-NEXT-2014&#x2F;Panel-Systems-Programming-Languages-in-2014-and-Beyond&quot;&gt;top language designers&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Rust&#x27;s 1st job was on creating browser tech. In making Servo, Rust focused on both safety and speed, w&#x2F;o one excluding the other.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Rust focuses on productivity also, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blog.rust-lang.org&#x2F;2017&#x2F;03&#x2F;02&#x2F;lang-ergonomics.html&quot;&gt;leaning on ergonomics&lt;&#x2F;a&gt; for getting more done with fewer language rough edges.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;IEEE lists Rust as the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;spectrum.ieee.org&#x2F;static&#x2F;interactive-the-top-programming-languages-2017&quot;&gt;22nd most popular programming language&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;This year, according to Redmonk, Rust &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;redmonk.com&#x2F;sogrady&#x2F;2017&#x2F;03&#x2F;17&#x2F;language-rankings-1-17&#x2F;&quot;&gt;jumped from 47th to 26th most popular programming language&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Likewise, Google trends shows Rust with (albeit a little noisy) &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;trends.google.com&#x2F;trends&#x2F;explore?date=today%205-y&amp;amp;q=%2Fm%2F0dsbpg6&quot;&gt;comfortable growth over the last 5 years&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Rust is global, with heavy growth in the United States and Europe. These are the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;sophiajt&#x2F;status&#x2F;924107142595878912&quot;&gt;meetup locations worldwide&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Google trends also shows strong activity recently in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;trends.google.com&#x2F;trends&#x2F;explore?date=today%203-m&amp;amp;q=%2Fm%2F0dsbpg6&quot;&gt;parts of Asia&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Just noticed the Rust reddit has had 16 posts in the last 24 hours. Not bad!&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Rust just isn&#x27;t a lang, but a community as well, with a focus on helpfulness. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;@geekytwoshoes11&#x2F;once-a-rustacean-always-a-rustacean-fed0a877472f&quot;&gt;Growing this&lt;&#x2F;a&gt; is also important.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;In addition to community, Rust-focused contractors like &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;integer32.com&#x2F;&quot;&gt;Integer 32&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;asquera&quot;&gt;Asquera&lt;&#x2F;a&gt; have sprung up.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Speaking of, there are a number of trainers available for Rust. The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-community&#x2F;team&quot;&gt;Rust community team&lt;&#x2F;a&gt; can help connect you.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;If you can make it out to one of the conferences, there are &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;rustconf.com&#x2F;training.html&quot;&gt;great hands-on labs&lt;&#x2F;a&gt; there as well.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;We&#x27;ve seen through multiple surveys that people stick around once they get used to Rust. It&#x27;s a joy to watch.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;I forgot to mention, there&#x27;s also an &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;rust-slack.herokuapp.com&#x2F;&quot;&gt;unofficial Rust slack&lt;&#x2F;a&gt; channel.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;As well as an &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;discord.me&#x2F;rust-lang&quot;&gt;unofficial discord server&lt;&#x2F;a&gt; for Rust discussions.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Rust is used commercially in a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;internals.rust-lang.org&#x2F;t&#x2F;2016-rust-commercial-user-survey-results&#x2F;4317&quot;&gt;wide range of areas&lt;&#x2F;a&gt;, incl. embedded systems, a&#x2F;v transcoding, servers, and more.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;internals.rust-lang.org&#x2F;t&#x2F;announcing-the-impl-period-sep-18-dec-17&#x2F;5676&quot;&gt;&quot;impl period&quot;&lt;&#x2F;a&gt; is a reaction to Rust&#x27;s growth. Discussions were at such a high volume that focus was needed.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The Rust team at Mozilla is spread across three continents, with most hosting meetups&#x2F;talks.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Speaking of meetups, if you ever have a chance to go, check out the SF Rust meetup. Lots of great talks&#x2F;ideas (also free pizza!)&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;A core piece of Rust&#x27;s growth is a sense of courtesy. This comes from the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rust-lang.org&#x2F;en-US&#x2F;conduct.html&quot;&gt;code of conduct&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Rust is growing into new areas. Recently, there&#x27;s been a focus on WASM support, with new tools like &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;lord.io&#x2F;blog&#x2F;2017&#x2F;wargo&#x2F;&quot;&gt;wargo&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Anecdotally, I can say that I see new faces on Rust twitter regularly. More people are getting excited and sharing their adventures.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;A big feature for commercial adoption just landed in cargo: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;boats.gitlab.io&#x2F;blog&#x2F;post&#x2F;2017-10-28-alternative-registries&#x2F;&quot;&gt;alternative registries&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The Rust community has its own poet that writes limericks on the news, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;llogiq&#x2F;status&#x2F;924256412125007872&quot;&gt;including yours truly&lt;&#x2F;a&gt;. 😅&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Another fun survey fact: despite more users and releases every 6 weeks, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blog.rust-lang.org&#x2F;2017&#x2F;09&#x2F;05&#x2F;Rust-2017-Survey-Results.html&quot;&gt;only ~7% of users had upgrade breakage&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.twitter.com&#x2F;linclark&quot;&gt;Lin Clark&lt;&#x2F;a&gt;, who makes awesome code cartoons, wrote a popular one on the upcoming &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;hacks.mozilla.org&#x2F;2017&#x2F;08&#x2F;inside-a-super-fast-css-engine-quantum-css-aka-stylo&#x2F;&quot;&gt;Firefox style system rewrite&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Also, speaking of, there was a followup article on WebRender, another upcoming &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;hacks.mozilla.org&#x2F;2017&#x2F;10&#x2F;the-whole-web-at-maximum-fps-how-webrender-gets-rid-of-jank&#x2F;&quot;&gt;update to Firefox rendering&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;While some may see Rust as largely Mozilla-driven, the Rust core team is actually made of folks from four different companies.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;On a personal note, I&#x27;ve been pleasantly surprised that each Rusty Spike episode has gotten &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;sophiajt&#x2F;status&#x2F;924337748047048704&quot;&gt;over 500 listens&lt;&#x2F;a&gt;, even though it&#x27;s new.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;This is the place-holder for a lot of stuff we can&#x27;t talk about being done by companies you might know. Wish we could talk about it!&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Outreach to companies is exclusively grass roots by engineers in those companies promoting Rust and asking people to present.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Rust is growing in importance in infosec. Projects like Tor have already begun &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.bleepingcomputer.com&#x2F;news&#x2F;software&#x2F;tor-browser-will-feature-more-rust-code&#x2F;&quot;&gt;moving code to Rust&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-unofficial&#x2F;awesome-rust&quot;&gt;Awesome Rust&lt;&#x2F;a&gt; is well worth a shout-out. If you ever wonder about what&#x27;s good in the Rust world, check it out.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>RLS now available on nightly</title>
        <published>2017-04-18T00:00:00+00:00</published>
        <updated>2017-04-18T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/rls-now-in-nightly/"/>
        <id>https://www.sophiajt.com/rls-now-in-nightly/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/rls-now-in-nightly/">&lt;p&gt;We&#x27;ve got some good news for Rust IDE support.&lt;&#x2F;p&gt;
&lt;p&gt;We recently hit a milestone for the Rust Language Server, a tool that combines the power of the compiler with a fast autocompletion engine.  Up to this point, if you wanted to use it you had to build it from scratch.  The process was tedious, time-consuming, and error-prone.&lt;&#x2F;p&gt;
&lt;p&gt;We&#x27;re happy to report you can now install RLS from &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;rustup.rs&#x2F;&quot;&gt;rustup&lt;&#x2F;a&gt;.  Landing as a component in rustup means a few important things.&lt;&#x2F;p&gt;
&lt;p&gt;First, this will make it &lt;strong&gt;easier to get up and running&lt;&#x2F;strong&gt; with the RLS. You no longer have to build the RLS to use it. Getting it up and running now just takes the time to run a few rustup commands:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;rustup default nightly
rustup update nightly
rustup component add rls
rustup component add rust-analysis
rustup component add rust-src
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You can find more helpful tips in the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang-nursery&#x2F;rls&#x2F;blob&#x2F;master&#x2F;README.md&quot;&gt;readme&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Second, this also makes it &lt;strong&gt;easier for IDE&#x2F;editor plugins to automatically install the RLS&lt;&#x2F;strong&gt; and use its capabilities.  This opens up the possibility for an even smoother user experience that is driven directly by the IDE plugin.  We&#x27;re looking forward to exploring this further.&lt;&#x2F;p&gt;
&lt;p&gt;Lastly, it is now &lt;strong&gt;easier to stay up-to-date&lt;&#x2F;strong&gt; with the RLS as it improves.  Once you install the component, it will update alongside your compiler.  All you&#x27;ll need to do is run the &lt;code&gt;rustup update nightly&lt;&#x2F;code&gt; command, and the RLS and its dependencies will update with it.&lt;&#x2F;p&gt;
&lt;p&gt;We&#x27;ve also been hard at work fixing bugs and improving the experience of using the RLS so that it&#x27;s more stable and accurate than before.  For larger projects, you may also notice that the RLS is a bit faster as well.&lt;&#x2F;p&gt;
&lt;p&gt;We&#x27;re excited to get this out to more people and hear your &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang-nursery&#x2F;rls&#x2F;issues&quot;&gt;feedback&lt;&#x2F;a&gt;.  There&#x27;s still plenty of work to do, and if you&#x27;d like to jump in and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang-nursery&#x2F;rls&#x2F;blob&#x2F;master&#x2F;contributing.md&quot;&gt;help&lt;&#x2F;a&gt;, we&#x27;d love to have you.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Using Rust in Windows</title>
        <published>2017-03-28T00:00:00+00:00</published>
        <updated>2017-03-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/rust-in-windows/"/>
        <id>https://www.sophiajt.com/rust-in-windows/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/rust-in-windows/">&lt;p&gt;As a Rust user, I was discouraged by not having all the good tips for using Rust in Windows in one place. This is an attempt to just that.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;getting-started&quot;&gt;Getting started&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;step-1-install-visual-studio-community-edition&quot;&gt;Step 1: Install Visual Studio Community edition&lt;&#x2F;h2&gt;
&lt;p&gt;My recommendation for working with Rust in Windows is to first get &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.visualstudio.com&#x2F;downloads&#x2F;&quot;&gt;Visual Studio 2017 Community&lt;&#x2F;a&gt; installed. &lt;em&gt;Edit:&lt;&#x2F;em&gt; Make sure you check the boxes to install &lt;strong&gt;C++ support&lt;&#x2F;strong&gt; when you instal Visual Studio, this provides the linker. The Rust compiler will use the linker that VS provides to translate our Rust code all the way to being an application. Having VS installed pays off in more ways than one, as we&#x27;ll see later.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;step-2-install-rustup&quot;&gt;Step 2: Install rustup&lt;&#x2F;h2&gt;
&lt;p&gt;The Rust toolchain (including the compiler and the &lt;code&gt;cargo&lt;&#x2F;code&gt; build tool) are managed by a tool called &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;rustup.rs&#x2F;&quot;&gt;rustup&lt;&#x2F;a&gt;. This is the easiest way get going with Rust. It also has a few advantages, like allowing you to more easily switch the style of compiler (stable&#x2F;beta&#x2F;nightly) as well as building for other targets, like embedded systems.&lt;&#x2F;p&gt;
&lt;p&gt;Once Visual Studio is installed, rustup will detect it and let us install the compiler that works with the VS toolchain. Rustup on the initial install will let you pick the compiler, and you can select working with nightly or release. What you choose is up to you. Nightly gives you access to new features but hasn&#x27;t been tested as thoroughly as the stable release compiler.&lt;&#x2F;p&gt;
&lt;p&gt;Whether you choose Nightly or Stable, you&#x27;ll have commands available to you at the terminal. You won&#x27;t need a separate shell to get to them. The commands &#x27;rustc&#x27; and &#x27;cargo&#x27; are the Rust compiler and Rust package manager respectively.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;step-3-make-sure-everything-is-working&quot;&gt;Step 3: Make sure everything is working&lt;&#x2F;h2&gt;
&lt;p&gt;In a source directory, you can test if Rust has been installed correctly by creating a simple project, compiling it, and running it.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;cargo new hello_world --bin
cd hello_world
cargo run (or &amp;quot;cargo build&amp;quot; followed by &amp;quot;cargo run&amp;quot;)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You can find out lots of helpful general &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;book&#x2F;getting-started.html&quot;&gt;getting started tips&lt;&#x2F;a&gt; in the Rust documentation.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;writing-rust-code-in-windows&quot;&gt;Writing Rust Code in Windows&lt;&#x2F;h1&gt;
&lt;p&gt;Currently, IDE support for Rust is still in its infancy. If you don&#x27;t need fully intellisense-style IDE experience, pretty much all editors now have basic Rust support. Pick your favorite one, install their Rust plugin or syntax highlighter, and you&#x27;re good to go. Many of these plugins come with support for a project called &#x27;racer&#x27;, which provides an autocompletion. Visual Studio users may be interested in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;marketplace.visualstudio.com&#x2F;items?itemName=vosen.VisualRust&quot;&gt;Visual Rust&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;For the more daring, there&#x27;s a project called the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang-nursery&#x2F;rls&quot;&gt;Rust Language Server&lt;&#x2F;a&gt;, which is based on the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Microsoft&#x2F;language-server-protocol&#x2F;blob&#x2F;master&#x2F;protocol.md&quot;&gt;Language Server Protocol&lt;&#x2F;a&gt; developed for VS Code and now part of a growing number of editors and IDEs.&lt;&#x2F;p&gt;
&lt;p&gt;You can find steps for how to set up the RLS and use it with VS Code on its &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang-nursery&#x2F;rls&#x2F;blob&#x2F;master&#x2F;README.md&quot;&gt;readme&lt;&#x2F;a&gt;. That said, the RLS is still pre-beta quality as of the writing of this post, so please exercise caution if you go this route.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;debugging-with-visual-studio&quot;&gt;Debugging with Visual Studio&lt;&#x2F;h1&gt;
&lt;p&gt;Earlier we installed Visual Studio. It seems a waste to have this nice VS install sitting around and not getting more benefit from it it. Let&#x27;s use it for debugging.&lt;&#x2F;p&gt;
&lt;p&gt;Before we do some debugging, there are two steps we&#x27;ll want to do beforehand:&lt;&#x2F;p&gt;
&lt;h2 id=&quot;step-1-install-rust-src&quot;&gt;Step 1: Install rust-src&lt;&#x2F;h2&gt;
&lt;p&gt;When we&#x27;re debugging, VS will sometimes complain because it can&#x27;t find the source code to the standard libs. We can remove this announce by installing the rust-src, and helping VS find the source it&#x27;s looking for (this is also a helpful step for &lt;code&gt;racer&lt;&#x2F;code&gt; support)&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;rustup component add rust-src
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This will let you find the source to the standard libs when you&#x27;re debugging. After the command is run, it will be put in your .multirust directory. For me that directory is:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;C:\Users\Sophia Turner\.multirust\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\src
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;When Visual Studio asks you for a file from the standard library source, this should give you a good place to start looking for it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;step-2-add-natvis-for-rust&quot;&gt;Step 2: Add natvis for Rust&lt;&#x2F;h2&gt;
&lt;p&gt;Rust has its own common structs, like String and Vec, that Visual Studio won&#x27;t understand by default currently. To be able to view these data structures, we use native visualisation or .natvis files. Rustup will helpfully make them available for us, we just have to copy them into our personal directory. For me, the .natvis files are in:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;C:\Users\Sophia Turner\.multirust\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\src\etc\natvis
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;NOTE: you may need to install the &lt;code&gt;nightly&lt;&#x2F;code&gt; toolchain to have this directory. You don&#x27;t need to use the nightly compiler as your main compiler, though, to take advantage of them.&lt;&#x2F;p&gt;
&lt;p&gt;I copy these files into:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;C:\Users\Sophia Turner\Documents\Visual Studio 2017\Visualizers
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If you don&#x27;t have a &lt;code&gt;Visualizers&lt;&#x2F;code&gt; directory, go ahead and create it and then copy the files into it. Once you start up VS, it should pick them up and give you a little better view of your Rust data.&lt;&#x2F;p&gt;
&lt;p&gt;With that, debugging a Rust app works very similar to debugging other apps. There are a few steps you need to do:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Compile your projects with debug info. The easiest way is to build using &lt;code&gt;cargo build&lt;&#x2F;code&gt; and NOT &lt;code&gt;cargo build --release&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Run your application&lt;&#x2F;li&gt;
&lt;li&gt;Attach the VS debugger using the &#x27;Attach...&#x27; feature. You should be able to find your application in the list. Once you attach, you can hit pause, set breakpoints, and step as normal.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;debugging-with-vscode-and-msvc&quot;&gt;Debugging with VSCode and MSVC&lt;&#x2F;h1&gt;
&lt;p&gt;You can also setup vscode as your development and debugging platform. There are some good tips on how to do this in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.brycevandyk.com&#x2F;debug-rust-on-windows-with-visual-studio-code-and-the-msvc-debugger&#x2F;&quot;&gt;this blog post&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h1&gt;
&lt;p&gt;There is still plenty of room for improvement, but already there&#x27;s enough here that we can write, build, and debug Rust applications without too much fuss. The Rust teams are working to continue to improve the experience of developing in Windows on Rust, but it&#x27;s encouraging to see the progress and where it could go in the future.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Rust Language Server Alpha 2 Release</title>
        <published>2017-03-02T00:00:00+00:00</published>
        <updated>2017-03-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/rls-alpha-2/"/>
        <id>https://www.sophiajt.com/rls-alpha-2/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/rls-alpha-2/">&lt;p&gt;Today, we&#x27;re happy to announce the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang-nursery&#x2F;rls&quot;&gt;second alpha&lt;&#x2F;a&gt; for the Rust Language Server, a project build to bring high-quality Rust IDE support to any IDE or editor.  This release brings new features, better stability, and an easier installation than the first alpha.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;support-for-new-project-types&quot;&gt;Support for new project types&lt;&#x2F;h2&gt;
&lt;p&gt;When a project first starts, it tends to begin life as a library or as an application.  As projects grow, sometimes they take on aspects of both, being both a library and an application that can be executed.&lt;&#x2F;p&gt;
&lt;p&gt;With alpha 2, we add support for this hybrid project type. Why, you might ask?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;working_on_cargo.png&quot; alt=&quot;Image of Editing Cargo Source&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Editing Cargo&#x27;s source code&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;With this change we can now work on Cargo in RLS.  We&#x27;re continuing to improve the experience and take on even larger codebases, but it&#x27;s promising to see the RLS already able to work with real-world projects, like Cargo.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;support-for-custom-derive&quot;&gt;Support for custom derive&lt;&#x2F;h2&gt;
&lt;p&gt;Rust projects that need serialisation often reach for the popular &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;serde-rs&#x2F;serde&quot;&gt;serde&lt;&#x2F;a&gt; crate to do the work.  With alpha 2, we now support the new serde annotations that are based on the new custom derive capabilities, which is sometimes called &quot;macros 1.1&quot;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;support-for-test-code&quot;&gt;Support for test code&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;working_on_tokio.png&quot; alt=&quot;Image of tokio test code&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Editing a test in Tokio&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;With alpha 2, you&#x27;ll also be able to get intellisense for the &lt;code&gt;#[test]&lt;&#x2F;code&gt; functions code in your project, allowing you to seamlessly switch between application and test code without having to change anything in your IDE or project.  We&#x27;d like to extend this coverage more in the future.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;better-stability&quot;&gt;Better stability&lt;&#x2F;h2&gt;
&lt;p&gt;We&#x27;ve fixed dozens of issues in the RLS and related crates.  As a result, the experience is much more solid.  We continue to make stability a focus as we push towards the beta release, but we&#x27;re already pleased with the progress since the first alpha.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;easier-installation&quot;&gt;Easier installation&lt;&#x2F;h2&gt;
&lt;p&gt;When you look at the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang-nursery&#x2F;rls&#x2F;blob&#x2F;master&#x2F;README.md&quot;&gt;setup instructions&lt;&#x2F;a&gt; for the RLS now, you&#x27;ll see we&#x27;ve got it down to four steps.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;working_with_std_docs.png&quot; alt=&quot;Image of hover with std docs&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Standard library documentation on hover&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We&#x27;ve also simplified getting access to the standard library documentation.  In one step, you can get now all the types and documentation for the standard library to your RLS install, allowing you to get the same IDE experience with the standard library that you do with your own code.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;part-of-the-rust-language-nursery&quot;&gt;Part of the Rust language nursery&lt;&#x2F;h2&gt;
&lt;p&gt;The RLS, as it&#x27;s matured, has proven that it&#x27;s ready to take a step closer to being an official Rust project.  Recently, the Rust tools team voted to bring the RLS in the Rust language &#x27;nursery&#x27;, a set of blessed projects that are working towards becoming an officially supported part of the Rust toolchain.  We&#x27;re excited to take this step and are committed to continuing to improve it towards the eventual 1.0 release.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;looking-forward&quot;&gt;Looking forward&lt;&#x2F;h1&gt;
&lt;p&gt;We&#x27;re hopeful this will let more people set up the RLS and get the best experience.  In the future, we hope to transition the RLS over to the rustup tool, which should allow you to add RLS support with one easy command.  This release is a stepping stone to that vision.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Announcing Rust Language Server Alpha Release</title>
        <published>2017-01-18T00:00:00+00:00</published>
        <updated>2017-01-18T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/rls-alpha-release/"/>
        <id>https://www.sophiajt.com/rls-alpha-release/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/rls-alpha-release/">&lt;p&gt;Today, we&#x27;re announcing the first alpha release of the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sophiajt&#x2F;rls&quot;&gt;Rust Language Server (aka RLS)&lt;&#x2F;a&gt;. With this alpha release, this is the first time we&#x27;re encouraging early adopters to try on real projects and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sophiajt&#x2F;rls&#x2F;issues&quot;&gt;send us feedback&lt;&#x2F;a&gt;. The RLS has now reached a level of maturity where it should be able to run against most Cargo-based Rust projects.&lt;&#x2F;p&gt;
&lt;p&gt;But what exactly is the Rust Language Server?&lt;&#x2F;p&gt;
&lt;h1 id=&quot;in-a-nutshell&quot;&gt;In a nutshell&lt;&#x2F;h1&gt;
&lt;p&gt;The Rust Language Server is a way of providing editors and IDEs with a range of functionality. Rather than leaving each editor plugin to have to parse and understand the types in your program and provide you with capabilities like refactoring, the RLS centralizes all this logic and provides it to the editor via a standard &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Microsoft&#x2F;language-server-protocol&quot;&gt;language server protocol&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;In this alpha release, this allows editors and IDEs to share the following capabilities:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;auto-completion&lt;&#x2F;strong&gt; - allowing you to complete symbols and press &#x27;.&#x27; for member lists&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;goto definition&lt;&#x2F;strong&gt; - jump to the definition of a given symbol&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;goto symbol&lt;&#x2F;strong&gt; - jump to the definition of a symbol you know the name of&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;find all references&lt;&#x2F;strong&gt; - show all the locations a given symbol is referenced&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;rename&#x2F;refactor&lt;&#x2F;strong&gt; - rename all instances of a given symbol to a new name&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;types on hover&lt;&#x2F;strong&gt; - get the type of a symbol&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;show errors&lt;&#x2F;strong&gt; - as the user types, get live analysis showing errors as they happen&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The alpha release of the RLS has been run successfully on Linux, Mac, and Windows.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;how-to-get-started&quot;&gt;How to get started&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;strong&gt;Step 0&lt;&#x2F;strong&gt;: Make sure you have a recent &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rust-lang.org&#x2F;en-US&#x2F;other-installers.html&quot;&gt;nightly rustc&#x2F;cargo&lt;&#x2F;a&gt;, &lt;strong&gt;git&lt;&#x2F;strong&gt;, &lt;strong&gt;python&lt;&#x2F;strong&gt;, &lt;strong&gt;node&lt;&#x2F;strong&gt;, and &lt;strong&gt;cmake&lt;&#x2F;strong&gt; installed&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Step 1&lt;&#x2F;strong&gt;: Check out the RLS:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;git clone https:&#x2F;&#x2F;github.com&#x2F;sophiajt&#x2F;rls
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;Step 2&lt;&#x2F;strong&gt;: Set up your editor (here we show &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sophiajt&#x2F;rls_vscode&quot;&gt;VS Code plugin&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;git clone https:&#x2F;&#x2F;github.com&#x2F;sophiajt&#x2F;rls_vscode.git
cd rls_vscode
npm install
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;Step 3&lt;&#x2F;strong&gt;: Set the RLS_ROOT environment variable to point to where you checked out the RLS:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;export RLS_ROOT=&#x2F;Source&#x2F;rls
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;At this point, you can open the project in VS Code, and when you run the project, it will open a new instance of VS Code with the RLS plugin enabled. The plugin will build RLS for you.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;&#x2F;strong&gt; the initial analysis of a project can take quite a long time, as metadata is built for all the project dependencies.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note 2:&lt;&#x2F;strong&gt; analysis currently ignores test code, so you won&#x27;t get IDE support for it. We have a fix for this in the works.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;how-does-it-work&quot;&gt;How does it work&lt;&#x2F;h1&gt;
&lt;p&gt;The current version of the RLS is built from a combination of two tools: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;phildawes&#x2F;racer&quot;&gt;racer&lt;&#x2F;a&gt; and the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;rust&#x2F;&quot;&gt;Rust compiler&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Racer allows us to get quick-and-dirty completions, allow you to get completion results in sub-second times. The trade-off this makes is that the results are not as accurate.&lt;&#x2F;p&gt;
&lt;p&gt;For tasks that require higher accuracy, like safe refactoring or code navigation, the RLS uses the Rust compiler directly. Because this type of analysis, while more accurate, takes longer to complete, the RLS will tell the editor when the analysis has successfully completed.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;help-it-doesn-t-work&quot;&gt;Help, it doesn&#x27;t work!&lt;&#x2F;h1&gt;
&lt;p&gt;The RLS is closely tied to particular versions of rustc. If you&#x27;re a rustup user, the DLLs it needs are managed by rustup. In this case, you&#x27;ll get an error like this if you run the rls by hand:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;jturner-23759:rls jturner$ ~&#x2F;.cargo&#x2F;bin&#x2F;rls
dyld: Library not loaded: @rpath&#x2F;librustc_driver-6eb85298.dylib
  Referenced from: &#x2F;Users&#x2F;jturner&#x2F;.cargo&#x2F;bin&#x2F;rls
  Reason: image not found
Abort trap: 6
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If you see an error like this, you can run the rls by instead running the command &lt;code&gt;cargo run&lt;&#x2F;code&gt; in the rls directory. In the future, as we improve the rls integration with the main Rust tools, this will no longer be an issue.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;what-s-next&quot;&gt;What&#x27;s next&lt;&#x2F;h1&gt;
&lt;p&gt;The RLS is still early in its life and needs to go through a stabilization period before it&#x27;s ready for 1.0. This alpha release marks the first release in this series.&lt;&#x2F;p&gt;
&lt;p&gt;The next release will be a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sophiajt&#x2F;rls&#x2F;milestone&#x2F;3&quot;&gt;second alpha&lt;&#x2F;a&gt; that includes another set of bugfixes and polish. This will be followed by a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sophiajt&#x2F;rls&#x2F;milestone&#x2F;4&quot;&gt;beta&lt;&#x2F;a&gt;. The beta will be the first that will be distributed as a binary and will be much closer to final 1.0 experience in terms of ease-of-install and ease-of-use.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;i-want-to-help&quot;&gt;I want to help&lt;&#x2F;h1&gt;
&lt;p&gt;Great! There are a few ways you can jump in.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Test the RLS&lt;&#x2F;strong&gt; - use the RLS on your projects and tell us how it feels. This will help us shake it out and make sure it&#x27;s ready for production.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Contribute to RLS:&lt;&#x2F;strong&gt; - we&#x27;d like to add more refactorings, more Rust-centric code navigation (eg find all impls for a type), and possibly more advanced features like lifetime visualization and macro debugging.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Contribute an editor plugin&lt;&#x2F;strong&gt; - there are already at least &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;langserver.org&#x2F;&quot;&gt;six plugins&lt;&#x2F;a&gt; that follow the Language Server Protocol that the RLS uses, each in its own state of completion. If you have experience with one of those editors, or if you have a favorite editor you don&#x27;t see on the list, you can help us by improving support. While the RLS will continue to grow and mature, it&#x27;s really the plugin where the &quot;rubber meets the road&quot;. It&#x27;s the plugin that helps the developer get the most out of what the RLS provides.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Hack on the compiler&lt;&#x2F;strong&gt; - ultimately, we want to drive everything in the RLS straight from the compiler. This means being able to have sub-second response times for interactive completions as well. The Rust compiler team has already started &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;rust&#x2F;pull&#x2F;37400&quot;&gt;a series of refactoring&lt;&#x2F;a&gt; to make the transition to an interactive mode possible. If you have a background in compilers, IDEs, or static analysis tools and would like to help with this work, you can contact the compiler team at #rustc on irc.mozilla.org or through the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;rust&#x2F;&quot;&gt;Rust compiler project on GitHub&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Programming Language and Compilers Reading List</title>
        <published>2016-10-08T00:00:00+00:00</published>
        <updated>2016-10-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/programming-language-and-compilers-reading-list/"/>
        <id>https://www.sophiajt.com/programming-language-and-compilers-reading-list/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/programming-language-and-compilers-reading-list/">&lt;p&gt;This week, the talented &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;_jbfitz&quot;&gt;Julien Fitzpatrick&lt;&#x2F;a&gt; (btw, you should check out their &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=Ce6ppwgF4SA&quot;&gt;RustConf talk&lt;&#x2F;a&gt; if you haven&#x27;t already) asked what a good list would be for people who are interested in programming languages and compilers. I took it as a good excuse to write a blog post with some of my recommendations. I&#x27;m going to attempt to put together a list that doesn&#x27;t require a lot of background information, but as these things go, sometimes you&#x27;ll have to re-read portions of books to get their benefit. Also, this isn&#x27;t going to be an exhaustive list. I have never read through an exhaustive reading list before. Instead, this is definitely biased towards writing real code, getting things working, and learning by doing. Without further ado, let&#x27;s get started!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;getting-started&quot;&gt;Getting started&lt;&#x2F;h2&gt;
&lt;p&gt;To kick things off, the first thing to do is to remove any fears we have about thinking that compilers are big complicated things that are only possible by the most heroic of efforts. Yes, some compilers can be quite complex, but that&#x27;s true of many kinds of industrial software. At its core, though, the compiler just does a few relatively simple things. So let&#x27;s demystify those things.&lt;&#x2F;p&gt;
&lt;p&gt;First off, let&#x27;s make a small compiler. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;thejameskyle&quot;&gt;@thejameskyle&lt;&#x2F;a&gt; has written a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;thejameskyle&#x2F;the-super-tiny-compiler&#x2F;blob&#x2F;master&#x2F;the-super-tiny-compiler.js&quot;&gt;cool tutorial&lt;&#x2F;a&gt; that helps take you through the steps of creating a simple compiler. Rather than chewing your way through dusty tome after dusty tome before you write your first line of code, my suggestion would be to always have a code editor open at each step of the way. Play with the ideas as you learn them.&lt;&#x2F;p&gt;
&lt;p&gt;Alright, next, after we&#x27;ve played around with our little compiler and made a few changes and see how our changes affect the output, it&#x27;s time to start building up our knowledge. Fundamentally, how a programming language works can be described in abstractions that build on other abstractions. If we peel these abstractions away, we&#x27;re left with a pretty simple foundation.&lt;&#x2F;p&gt;
&lt;p&gt;One of the compiler books I liked that help build up these abstractions from a simple base is &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;wphomes.soic.indiana.edu&#x2F;jsiek&#x2F;&quot;&gt;Jeremy Siek&lt;&#x2F;a&gt;&#x27;s &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;ecee.colorado.edu&#x2F;ecen4553&#x2F;fall12&#x2F;notes.pdf&quot;&gt;compiler course&lt;&#x2F;a&gt;. The notes are laid out by chapter, and each chapter introduces a new concept that you&#x27;ll add to the compiler. I enjoyed the hands-on approach, since you can think about how each feature affects each part of the compiler. It definitely gave me a &quot;oh my god, I can&#x27;t believe this works!&quot; moments. You may also want to adjust to fit your particular style. For example, if something like the assembly piece feels awkward, you could instead output code to a language you&#x27;re more familiar with, and work through the other steps of the compiler.&lt;&#x2F;p&gt;
&lt;p&gt;On the programming language side, probably one of the better survey books I&#x27;ve seen is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.com&#x2F;Programming-Language-Pragmatics-Fourth-Michael&#x2F;dp&#x2F;0124104096&quot;&gt;Programming Language Pragmatics&lt;&#x2F;a&gt;. I&#x27;d probably pair it with something like &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.com&#x2F;Masterminds-Programming-Conversations-Creators-Languages&#x2F;dp&#x2F;0596515170&quot;&gt;Masterminds of Programming&lt;&#x2F;a&gt; or &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.com&#x2F;Coders-Work-Reflections-Craft-Programming&#x2F;dp&#x2F;1430219483&quot;&gt;Coders at Work&lt;&#x2F;a&gt;. These two books are interviews with programming language creators. Creating programming languages is definitely equal parts art and engineering, and bouncing between the creators talking about the art and seeing how the engineering works in practice might help see parts of the picture a bit clearer.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;working-some-problems&quot;&gt;Working some problems&lt;&#x2F;h2&gt;
&lt;p&gt;I used to hate doing homework. I mean, who didn&#x27;t? But getting a little older, I realize just how useful doing some of the problems in the book can be. That&#x27;s the time where you actually are solving little puzzles. And, if you&#x27;re lucky, it&#x27;s also a great chance to have one of those &quot;a ha!&quot; moments that unlock the next set of secrets.&lt;&#x2F;p&gt;
&lt;p&gt;If you&#x27;re like I was at the time, you&#x27;ve heard of &quot;functional programming&quot; about a million times but weren&#x27;t sure why anyone should care all that much. It wasn&#x27;t really until I was working through &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.com&#x2F;Introduction-Functional-Programming-International-Computing&#x2F;dp&#x2F;0134841891&quot;&gt;Introduction to Functional Programming by Bird&#x2F;Wadler&lt;&#x2F;a&gt; that things started to click. The problems in this book are great. They&#x27;re juicy enough that you might have to work at them a little, but you come away with a much better sense of the concepts in each chapter.&lt;&#x2F;p&gt;
&lt;p&gt;Another book I enjoyed the problems in is the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.com&#x2F;Compilers-Principles-Techniques-Tools-2nd&#x2F;dp&#x2F;B009TGD06W&quot;&gt;Dragon book&lt;&#x2F;a&gt;. The problem with the Dragon book, though, is that it definitely feels like a stuffy college textbook. That said, it&#x27;s worth a skim. My favorite part about it are the problems in the earlier chapters. Working through those gave me a bit more confidence I understood the concepts.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;getting-more-modern&quot;&gt;Getting more modern&lt;&#x2F;h2&gt;
&lt;p&gt;Perhaps another problem with the well-known dragon book is that the dragon is a bit long in the tooth these days. Modern techniques have moved on a bit from where they were a few decades ago.&lt;&#x2F;p&gt;
&lt;p&gt;One thing to check out to see a bit more of how modern compilers work is the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.aosabook.org&#x2F;en&#x2F;llvm.html&quot;&gt;LLVM chapter&lt;&#x2F;a&gt; of Architecture of Open Source Applications (which may also be a fun read for someone interested in how things work generally).&lt;&#x2F;p&gt;
&lt;p&gt;I don&#x27;t know of a good book on this topic, but there&#x27;s a good video that goes into some of the ways that &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;channel9.msdn.com&#x2F;Blogs&#x2F;Seth-Juarez&#x2F;Anders-Hejlsberg-on-Modern-Compiler-Construction&quot;&gt;modern compilers work differently&lt;&#x2F;a&gt; than those in the dragon book.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;for-the-brave&quot;&gt;For the brave&lt;&#x2F;h1&gt;
&lt;p&gt;When you&#x27;ve worked your way to this point and are feeling pretty confident, it&#x27;s time to scale to the dizzying heights. To get there, you&#x27;ll inevitably come across &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.com&#x2F;Types-Programming-Languages-MIT-Press&#x2F;dp&#x2F;B00AJXZ5JE&quot;&gt;Types and Programming Languages&lt;&#x2F;a&gt; (which you might hear pronounced &quot;tapple&quot;). I&#x27;m not going to mince words, this book is brutal. It took months and months of working on it to crack it. I managed to finally get my head around it by methodically using a hands-on approach. I went &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sophiajt&#x2F;Pierce-and-Types&quot;&gt;chapter by chapter&lt;&#x2F;a&gt; and implemented each new language concept the author introduced. It took a little while, but it managed to turn the greek symbols into something a bit more concrete.&lt;&#x2F;p&gt;
&lt;p&gt;At this point you have quite the toolbox. You&#x27;ve written a few small compilers, you&#x27;ve seen how language features work and how they interact with each other, you can read academic papers (if need be), and maybe you&#x27;ve even made a programming language of your own. Now you can branch out to almost anywhere.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Helping with the Rust Errors</title>
        <published>2016-08-03T00:00:00+00:00</published>
        <updated>2016-08-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/helping-out-with-rust-errors/"/>
        <id>https://www.sophiajt.com/helping-out-with-rust-errors/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/helping-out-with-rust-errors/">&lt;p&gt;I recently did some work with Niko Matsakis on a new compiler error format. You can try them out
by setting &lt;code&gt;RUST_NEW_ERROR_FORMAT=true&lt;&#x2F;code&gt;. While I put together a
blog post talking about the design for the main blog, I also wanted to open it up for people to come
help us move to the new errors. I&#x27;ve split up this post based on background for testers, doc
writers, first-time compiler hackers, and experienced compiler hackers.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;i-m-good-at-testing&quot;&gt;I&#x27;m good at testing!&lt;&#x2F;h1&gt;
&lt;p&gt;Perfect! We&#x27;ve love your help to come up with tests that show where an error message is confusing or
just plain wrong. If you&#x27;d like a little help getting started, there are a bunch of unit tests for
the compiler that all fail intentionally. You can find these in the rust-lang repo under the
&lt;code&gt;src&#x2F;test&#x2F;compile_fail&lt;&#x2F;code&gt; directory. You&#x27;ll notice we&#x27;ve already started a
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;rust&#x2F;issues&#x2F;35233&quot;&gt;list of errors&lt;&#x2F;a&gt;, but that list is incomplete. We&#x27;d
like to make sure every error code that needs to be updated makes it onto that list so that others
can help update them.&lt;&#x2F;p&gt;
&lt;p&gt;There are a &lt;em&gt;bunch&lt;&#x2F;em&gt; of good examples in the &lt;code&gt;compile_fail&lt;&#x2F;code&gt; directory that explore various error
codes. If you look around there
you can also search for error messages and see if there is already a test. Running this test will
help you see if the error has been updated to the new format.&lt;&#x2F;p&gt;
&lt;p&gt;If you can find a test case that needs to be updated, file an issue like one of those listed in the
&quot;list of errors&quot; link and cc @sophiajt. I can help get the error updated to the new format
and tag the error so that others can find it.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;i-love-writing-docs&quot;&gt;I love writing docs!&lt;&#x2F;h1&gt;
&lt;p&gt;Good, we need that too. There are a couple places where doc writers can help out, especially if
if you already know a little Rust.&lt;&#x2F;p&gt;
&lt;p&gt;The first place is helping us write clearer error messages. Even now, and especailly as we move to
the new format, some errors are confusing and sometimes wrong. By helping write clearer error
wording, and by experimenting with new ways to describe the error that is occuring, you can help us
further improve the errors for the next developer.&lt;&#x2F;p&gt;
&lt;p&gt;If you look at the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;rust&#x2F;issues&#x2F;35233&quot;&gt;list of errors&lt;&#x2F;a&gt; we have so far
you can see what we&#x27;re going for. The likely need here is that errors need new labels. The general
style of the new errors:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The error message text. This describes the general problem.&lt;&#x2F;li&gt;
&lt;li&gt;The primary error label (the &#x27;^^^&#x27; underline). This describes the &#x27;what&#x27; of the error.
It tries to summarize what went wrong in an fairly brief, yet approachable way.&lt;&#x2F;li&gt;
&lt;li&gt;The secondary error label (the &#x27;+++&#x27; underline). This describes the &#x27;why&#x27; of the error. By reading
these the user can see the order of operations that lead to the error.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;You can also explore the &lt;code&gt;src&#x2F;test&#x2F;compile-fail&lt;&#x2F;code&gt; of the compiler source code for a lot of unit
tests that fail intentionally. By looking through these, you can help find errors that aren&#x27;t
update or that use confusing notes and labels.&lt;&#x2F;p&gt;
&lt;p&gt;Worth mentioning too, if you&#x27;re a writer, also keep a lookout for Stage 2 (which hopefully will be
ready in the coming weeks). We&#x27;ll need help in the future writing helpful extended messages that
describe errors. A great place to jump into help out here and learn about other places doc writers
can help is #rust-docs on irc.mozilla.org.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;i-know-rust-but-i-ve-never-hacked-the-compiler&quot;&gt;I know Rust but I&#x27;ve never hacked the compiler!&lt;&#x2F;h1&gt;
&lt;p&gt;Excellent, a first-time compiler hacker. Let&#x27;s walk through updating an error
message to the new format. You can look through the
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;rust&#x2F;issues&#x2F;35233&quot;&gt;list of errors&lt;&#x2F;a&gt; to see which ones need updating.&lt;&#x2F;p&gt;
&lt;p&gt;Once you&#x27;ve downloaded the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;rust&quot;&gt;Rust compiler source&lt;&#x2F;a&gt;, run the
command:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;&amp;gt; python src&#x2F;bootstrap&#x2F;bootstrap.py --step libstd --stage 1&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This will build &quot;Stage 1&quot; of the compiler. After the first compile, this saves us a &lt;em&gt;bunch&lt;&#x2F;em&gt; of time
as we test our ideas as it is the minimal compiler rather than a full install.&lt;&#x2F;p&gt;
&lt;p&gt;Once built, we can run this by hand using (here, I&#x27;m on OS X):&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;RUST_NEW_ERROR_FORMAT=true .&#x2F;build&#x2F;x86_64-apple-darwin&#x2F;stage1&#x2F;bin&#x2F;rustc &amp;lt;rust file&amp;gt;&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s take a look at an error that needs to be updated. You can find a lot of error tests in the
&lt;code&gt;src&#x2F;test&#x2F;compile-fail&lt;&#x2F;code&gt; directory in the compiler source. For this example, I&#x27;ll use
&lt;code&gt;src&#x2F;test&#x2F;compile-fail&#x2F;borrowck&#x2F;borrowck-match-binding-is-assignment.rs&lt;&#x2F;code&gt;. You can also see which
error this is looking for the EXXXX number, which is the error number. This one is E0384.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;term&quot;&gt;error[E0384]: re-assignment of immutable variable `x`
  --&amp;gt; src&#x2F;test&#x2F;compile-fail&#x2F;borrowck&#x2F;borrowck-match-binding-is-assignment.rs:50:13
   |
50 |             x += 1;
   |             ^^^^^^
   |
note: prior assignment occurs here
  --&amp;gt; src&#x2F;test&#x2F;compile-fail&#x2F;borrowck&#x2F;borrowck-match-binding-is-assignment.rs:49:10
   |
49 |         [x,_,_] =&amp;gt; {
   |          ^
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We can see that&#x27;s still using some of the old logic because the underlines don&#x27;t have a label. You
can also tell because there&#x27;s an attached note is simple enough to be that label. Let&#x27;s change
the note to be a label.&lt;&#x2F;p&gt;
&lt;p&gt;To fix this, we first need to find it in the compiler source. Search tools to the rescue. I tend to
use the error number (and sometimes part of the error message text)&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;term&quot;&gt;jturner-23759:rust jturner$ grep -r E0384 src
src&#x2F;librustc_borrowck&#x2F;borrowck&#x2F;mod.rs:            self.tcx.sess, span, E0384,
src&#x2F;librustc_borrowck&#x2F;diagnostics.rs:E0384: r##&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We now have the line that creates the error and another that lists it for us. We only need to change
the first of these.&lt;&#x2F;p&gt;
&lt;p&gt;Looking at the code, sure enough, this is using the older style:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;Rust&quot;&gt;struct_span_err!(
    self.tcx.sess, span, E0384,
    &amp;quot;re-assignment of immutable variable `{}`&amp;quot;,
    self.loan_path_to_string(lp))
    .span_note(assign.span, &amp;quot;prior assignment occurs here&amp;quot;)
    .emit();
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This is a pretty easy fix. We just move from &lt;code&gt;.span_note&lt;&#x2F;code&gt; to &lt;code&gt;.span_label&lt;&#x2F;code&gt; and create a simple
label, like this:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;Rust&quot;&gt;struct_span_err!(
    self.tcx.sess, span, E0384,
    &amp;quot;re-assignment of immutable variable `{}`&amp;quot;,
    self.loan_path_to_string(lp))
    .span_label(assign.span, &amp;amp;format!(&amp;quot;prior assignment occurs here&amp;quot;))
    .emit();
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Once we build and run the new compiler against the error message, we get something where the label
is now part of the main snippet.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;term&quot;&gt;error[E0384]: re-assignment of immutable variable `x`
  --&amp;gt; src&#x2F;test&#x2F;compile-fail&#x2F;borrowck&#x2F;borrowck-match-binding-is-assignment.rs:50:13
   |
49 |         [x,_,_] =&amp;gt; {
   |          - prior assignment occurs here
50 |             x += 1;
   |             ^^^^^^
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;That looks a little better, but we&#x27;re not done. You&#x27;ll notice that we don&#x27;t have a label on our
primary span (the ^^^^ part). In the new format, we like to have a label here because it&#x27;s one of
the first places your eye will look when you see an error message.&lt;&#x2F;p&gt;
&lt;p&gt;The second is that the label &quot;prior assignment occurs here&quot;. That feels a little awkward. Since the
label is now part of our code snippet, we can use a better wording. Let&#x27;s update the error to look
like this:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;term&quot;&gt;error[E0384]: re-assignment of immutable variable `x`
  --&amp;gt; src&#x2F;test&#x2F;compile-fail&#x2F;borrowck&#x2F;borrowck-match-binding-is-assignment.rs:50:13
   |
49 |         [x,_,_] =&amp;gt; {
   |          - first assignment to `x`
50 |             x += 1;
   |             ^^^^^^ re-assignment of immutable variable
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;With a little bit of wording changes and the new primary label, that&#x27;s not bad. Of course, as you
get comfortable working with these errors you may find even better wording that&#x27;s more clear. Next,
let&#x27;s update the code to output this style:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;Rust&quot;&gt;struct_span_err!(
    self.tcx.sess, span, E0384,
    &amp;quot;re-assignment of immutable variable `{}`&amp;quot;,
    self.loan_path_to_string(lp))
    .span_label(assign.span, &amp;amp;format!(&amp;quot;first assignment to `{}`&amp;quot;,
                                      self.loan_path_to_string(lp)))
    .span_label(span, &amp;amp;format!(&amp;quot;re-assignment of immutable variable&amp;quot;))
    .emit();
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You&#x27;ll notice that I reused the same &lt;code&gt;span&lt;&#x2F;code&gt; that the main error message uses in my new
&lt;code&gt;.span_label&lt;&#x2F;code&gt;. When I do this, I&#x27;m telling the DiagnosticBuilder that this span_label is talking
about the primary span and is the root of what is causing the error. Other labels are secondary
spans because they&#x27;re more informational.&lt;&#x2F;p&gt;
&lt;p&gt;And with that, we&#x27;re done! Well, almost. We can&#x27;t forget to update the unit tests.&lt;&#x2F;p&gt;
&lt;p&gt;To quickly check the unit tests that will fail because of our changes, we can run:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;python src&#x2F;bootstrap&#x2F;bootstrap.py --step check-cfail --stage 1&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Compile-fail unit tests are set up with their own annotations that say what labels to expect and
where. As we update errors, we&#x27;ll need to also update the corresponding test the new expected
labels.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;term&quot;&gt;failures:
    [compile-fail] compile-fail&#x2F;asm-out-assign-imm.rs
    [compile-fail] compile-fail&#x2F;assign-imm-local-twice.rs
    [compile-fail] compile-fail&#x2F;borrowck&#x2F;borrowck-insert-during-each.rs
    [compile-fail] compile-fail&#x2F;liveness-assign-imm-local-in-loop.rs
    [compile-fail] compile-fail&#x2F;liveness-assign-imm-local-in-op-eq.rs
    [compile-fail] compile-fail&#x2F;liveness-assign-imm-local-with-init.rs

test result: FAILED. 2381 passed; 6 failed; 15 ignored; 0 measured
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Sure enough, we need to update some of the unit tests. Let&#x27;s run these individually. To do this, we
can use:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;python src&#x2F;bootstrap&#x2F;bootstrap.py --step check-cfail &amp;lt;test name&amp;gt; --stage 1&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;like so:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;python src&#x2F;bootstrap&#x2F;bootstrap.py --step check-cfail asm-out-assign-imm --stage 1&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;A fair amount of text comes out, but what we&#x27;re interested in is:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;term&quot;&gt;error: &#x2F;Users&#x2F;jturner&#x2F;Source&#x2F;rust&#x2F;src&#x2F;test&#x2F;compile-fail&#x2F;asm-out-assign-imm.rs:21: unexpected &amp;quot;note&amp;quot;: &amp;#39;first assignment to `x`&amp;#39;

error: &#x2F;Users&#x2F;jturner&#x2F;Source&#x2F;rust&#x2F;src&#x2F;test&#x2F;compile-fail&#x2F;asm-out-assign-imm.rs:24: unexpected &amp;quot;note&amp;quot;: &amp;#39;re-assignment of immutable variable&amp;#39;

error: &#x2F;Users&#x2F;jturner&#x2F;Source&#x2F;rust&#x2F;src&#x2F;test&#x2F;compile-fail&#x2F;asm-out-assign-imm.rs:21: expected note not found: prior assignment occurs here
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;These lines tell us what&#x27;s breaking our test case. In this example we see there are notes being
printed that it doesn&#x27;t expect and one expected note not found. This makes sense, since we changed
the wording in the error. Let&#x27;s go ahead and fix this.&lt;&#x2F;p&gt;
&lt;p&gt;We can change:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;Rust&quot;&gt;    x = 1; &#x2F;&#x2F;~ NOTE prior assignment occurs here
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;Rust&quot;&gt;    x = 1; &#x2F;&#x2F;~ NOTE first assignment
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;&#x2F;&#x2F;~&lt;&#x2F;code&gt; tells the test runner what the expected message is. Here, the message is a NOTE, which
corresponds to the label we changed.&lt;&#x2F;p&gt;
&lt;p&gt;One more to go. We also added a new label on the primary span. We can insert a new note where
this goes:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;Rust&quot;&gt;    unsafe {
        asm!(&amp;quot;mov $1, $0&amp;quot; : &amp;quot;=r&amp;quot;(x) : &amp;quot;r&amp;quot;(5));
        &#x2F;&#x2F;~^ ERROR re-assignment of immutable variable `x`
        &#x2F;&#x2F;~| NOTE re-assignment of immutable
        &#x2F;&#x2F;~| NOTE in this expansion of asm!
    }
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;em&gt;Notice: we use the &lt;code&gt;&#x2F;&#x2F;~&lt;&#x2F;code&gt; when the note is by itself, or &lt;code&gt;&#x2F;&#x2F;~^&lt;&#x2F;code&gt; and &lt;code&gt;&#x2F;&#x2F;~|&lt;&#x2F;code&gt; when we&#x27;re looking
for multiple notes.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;With that, the test now passes:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;term&quot;&gt;running 1 test
test [compile-fail] compile-fail&#x2F;asm-out-assign-imm.rs ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;From there we work our way through the errors. Having these error tests failing gives us a chance
to be sure that our fix is good. Here, when we fix
&lt;code&gt;compile-fail&#x2F;liveness-assign-imm-local-in-loop.rs&lt;&#x2F;code&gt; we see that in a loop the two spans we&#x27;re using
might be the same span if the error happens in a loop. Let&#x27;s fix that:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;Rust&quot;&gt;let mut err = struct_span_err!(
        self.tcx.sess, span, E0384,
        &amp;quot;re-assignment of immutable variable `{}`&amp;quot;,
        self.loan_path_to_string(lp));
err.span_label(span, &amp;amp;format!(&amp;quot;re-assignment of immutable variable&amp;quot;));
if span != assign.span {
    err.span_label(assign.span, &amp;amp;format!(&amp;quot;first assignment to `{}`&amp;quot;,
                                         self.loan_path_to_string(lp)));
}
err.emit();
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;While we&#x27;re at it, let&#x27;s run a quick tidy to make sure our code conforms to the compiler coding
standard:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;python src&#x2F;bootstrap&#x2F;bootstrap.py --stage 1 --step check-tidy&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Perfect. Ship it!&lt;&#x2F;p&gt;
&lt;p&gt;After we&#x27;ve finished with updating the error and the corresponding unit tests, we can create a PR.
When you file the PR, put the message &quot;r? @sophiajt&quot; at the bottom of your commit
message. This will add me to do the code review.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;extra-credit&quot;&gt;Extra credit&lt;&#x2F;h1&gt;
&lt;p&gt;A keen eye will notice that the file we&#x27;ve been working on did not show up in our failed tests.
&quot;Why is that?&quot; you might ask. Unit tests that look at the compiler messages work in a few different
ways. Some look at how a test looks (eg, tests in the src&#x2F;test&#x2F;ui directory). Others make sure the
content is there, like the unit tests we just fixed. Because there is a lot of content to look for
there are two kinds of &quot;look for content&quot; error test cases. The first kind will only look at the
main message. You can see that this is the case because these test cases have no indicators to look
for NOTE or HELP, only ERROR and WARN.&lt;&#x2F;p&gt;
&lt;p&gt;Watch what happens if we add a single NOTE to our original test case:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;term&quot;&gt;error: &#x2F;Users&#x2F;jturner&#x2F;Source&#x2F;rust&#x2F;src&#x2F;test&#x2F;compile-fail&#x2F;borrowck&#x2F;borrowck-match-binding-is-assignment.rs:25: unexpected &amp;quot;note&amp;quot;: &amp;#39;first assignment to `x`&amp;#39;

error: &#x2F;Users&#x2F;jturner&#x2F;Source&#x2F;rust&#x2F;src&#x2F;test&#x2F;compile-fail&#x2F;borrowck&#x2F;borrowck-match-binding-is-assignment.rs:32: unexpected &amp;quot;note&amp;quot;: &amp;#39;first assignment to `x`&amp;#39;

error: &#x2F;Users&#x2F;jturner&#x2F;Source&#x2F;rust&#x2F;src&#x2F;test&#x2F;compile-fail&#x2F;borrowck&#x2F;borrowck-match-binding-is-assignment.rs:33: unexpected &amp;quot;note&amp;quot;: &amp;#39;re-assignment of immutable variable&amp;#39;

error: &#x2F;Users&#x2F;jturner&#x2F;Source&#x2F;rust&#x2F;src&#x2F;test&#x2F;compile-fail&#x2F;borrowck&#x2F;borrowck-match-binding-is-assignment.rs:38: unexpected &amp;quot;note&amp;quot;: &amp;#39;first assignment to `x`&amp;#39;

error: &#x2F;Users&#x2F;jturner&#x2F;Source&#x2F;rust&#x2F;src&#x2F;test&#x2F;compile-fail&#x2F;borrowck&#x2F;borrowck-match-binding-is-assignment.rs:39: unexpected &amp;quot;note&amp;quot;: &amp;#39;re-assignment of immutable variable&amp;#39;

error: &#x2F;Users&#x2F;jturner&#x2F;Source&#x2F;rust&#x2F;src&#x2F;test&#x2F;compile-fail&#x2F;borrowck&#x2F;borrowck-match-binding-is-assignment.rs:44: unexpected &amp;quot;note&amp;quot;: &amp;#39;first assignment to `x`&amp;#39;

error: &#x2F;Users&#x2F;jturner&#x2F;Source&#x2F;rust&#x2F;src&#x2F;test&#x2F;compile-fail&#x2F;borrowck&#x2F;borrowck-match-binding-is-assignment.rs:45: unexpected &amp;quot;note&amp;quot;: &amp;#39;re-assignment of immutable variable&amp;#39;

error: &#x2F;Users&#x2F;jturner&#x2F;Source&#x2F;rust&#x2F;src&#x2F;test&#x2F;compile-fail&#x2F;borrowck&#x2F;borrowck-match-binding-is-assignment.rs:50: unexpected &amp;quot;note&amp;quot;: &amp;#39;first assignment to `x`&amp;#39;

error: &#x2F;Users&#x2F;jturner&#x2F;Source&#x2F;rust&#x2F;src&#x2F;test&#x2F;compile-fail&#x2F;borrowck&#x2F;borrowck-match-binding-is-assignment.rs:51: unexpected &amp;quot;note&amp;quot;: &amp;#39;re-assignment of immutable variable&amp;#39;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;That&#x27;s more like it! Now, we can continue fixing this unit test like we did the others.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;tips&quot;&gt;Tips&lt;&#x2F;h2&gt;
&lt;p&gt;As you convert errors you may need to change &lt;code&gt;span_err&lt;&#x2F;code&gt; (or &lt;code&gt;span_err!&lt;&#x2F;code&gt;)
to &lt;code&gt;struct_span_err&lt;&#x2F;code&gt; (or &lt;code&gt;struct_span_err!&lt;&#x2F;code&gt;), add new .span_labels, or tweak the wording for the
error message to feel right.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;i-m-an-experienced-rust-compiler-hacker&quot;&gt;I&#x27;m an experienced Rust compiler hacker!&lt;&#x2F;h1&gt;
&lt;p&gt;Perfect! There are a few hairy things we need to figure out, still, and they may require the keen
eye of a compiler hacker. In the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;rust&#x2F;issues&#x2F;35233&quot;&gt;list of errors&lt;&#x2F;a&gt;
there is a second list of issues for experienced compiler hackers. Additionally, there are areas
that need a bit more work to make them feel like the new messages.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;region-errors&quot;&gt;Region errors&lt;&#x2F;h2&gt;
&lt;p&gt;Regions errors currently provide a decent amount of information, but unfortunately to understand it
you currently need a pretty decent understanding of Rust already. Ideally, these messages would get
a similar treatment to the borrowck errors mentioned above.&lt;&#x2F;p&gt;
&lt;p&gt;Something like:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;term&quot;&gt;error[E0495]: cannot infer an appropriate lifetime for lifetime parameter &amp;#39;r in function call due to conflicting requirements
  --&amp;gt; src&#x2F;test&#x2F;compile-fail&#x2F;regions-infer-call-3.rs:18:24
   |
18 |     let z = with(|y| { select(x, y) });
   |                        ^^^^^^^^^^^^
   |
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the block at 18:21...
  --&amp;gt; src&#x2F;test&#x2F;compile-fail&#x2F;regions-infer-call-3.rs:18:22
   |
18 |     let z = with(|y| { select(x, y) });
   |                      ^^^^^^^^^^^^^^^^
note: ...so that reference does not outlive borrowed content
  --&amp;gt; src&#x2F;test&#x2F;compile-fail&#x2F;regions-infer-call-3.rs:18:34
   |
18 |     let z = with(|y| { select(x, y) });
   |                                  ^
note: but, the lifetime must be valid for the call at 18:12...
  --&amp;gt; src&#x2F;test&#x2F;compile-fail&#x2F;regions-infer-call-3.rs:18:13
   |
18 |     let z = with(|y| { select(x, y) });
   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...so type `&amp;amp;isize` of expression is valid during the expression
  --&amp;gt; src&#x2F;test&#x2F;compile-fail&#x2F;regions-infer-call-3.rs:18:13
   |
18 |     let z = with(|y| { select(x, y) });
   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You can see that we say things like &quot;for the call at 18:12&quot; or &quot;on the block at 18:21&quot;. The span
information is available but we&#x27;re not really using it well. Instead of saying this, we may want to
calculate the actual span that relates to &quot;the call at 18:12&quot; or the end point of &quot;the block at
18:21&quot;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;macro-errors&quot;&gt;Macro errors&lt;&#x2F;h2&gt;
&lt;p&gt;I&#x27;ve started a thread on
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;internals.rust-lang.org&#x2F;t&#x2F;improving-macro-errors&#x2F;3809&quot;&gt;improving macro errors&lt;&#x2F;a&gt; on the Rust
internals list. The hope is to look at a better overall design for macro errors that fits better
with the new error style.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;thanks&quot;&gt;Thanks!&lt;&#x2F;h1&gt;
&lt;p&gt;Thanks for wanting to jump in and help! You can find me on irc.mozilla.org as sophiajt and on
github.com as sophiajt. If you have any questions, please ask. You can also get lots of good
help in #rust-internals and #rustc on irc.mozilla.org.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Rhai 0.2 release</title>
        <published>2016-03-26T00:00:00+00:00</published>
        <updated>2016-03-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/rhai-02/"/>
        <id>https://www.sophiajt.com/rhai-02/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/rhai-02/">&lt;p&gt;I&#x27;ve just updated &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sophiajt&#x2F;rhai&quot;&gt;Rhai&lt;&#x2F;a&gt; to 0.2. This release focuses on improving the interaction between Rhai and Rust. The result is a cleaner, easier-to-use API. This new API does mean some API breakages, so you&#x27;ll need to update your code to work with 0.2.&lt;&#x2F;p&gt;
&lt;p&gt;With this release, Rhai also now has arrays as a built-in type.&lt;&#x2F;p&gt;
&lt;p&gt;You can upgrade&#x2F;install Rhai from &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;crates.io&#x2F;crates&#x2F;rhai&quot;&gt;cargo&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;api-improvements&quot;&gt;API improvements&lt;&#x2F;h1&gt;
&lt;p&gt;Rhai 0.2 has a lot of small improvements that give it a much more natural feel in Rust. The main three areas are function registration, getters&#x2F;setter helpers, and simpler eval.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;function-registration&quot;&gt;Function registration&lt;&#x2F;h2&gt;
&lt;p&gt;Function registration now works through method calls on the engine, and we can infer the expected function type. The end result is generally much cleaner.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;[Before]&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;&amp;amp;(add as fn(x: i32, y: i32)-&amp;gt;i32).register(&amp;amp;mut engine, &amp;quot;add&amp;quot;);
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;[Now]&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;engine.register_fn(&amp;quot;add&amp;quot;, add);
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;getter-setter-helpers&quot;&gt;Getter&#x2F;setter helpers&lt;&#x2F;h2&gt;
&lt;p&gt;To help cut down on repetition, Rhai 0.2 has a few helpers for working with getters and setters.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;[Before]&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;&amp;amp;(TestStruct::get_x as fn(&amp;amp;mut TestStruct)-&amp;gt;i32).register(&amp;amp;mut engine, &amp;quot;get$x&amp;quot;);
&amp;amp;(TestStruct::set_x as fn(&amp;amp;mut TestStruct, i32)-&amp;gt;()).register(&amp;amp;mut engine, &amp;quot;set$x&amp;quot;);
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;[Now]&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;engine.register_get_set(&amp;quot;x&amp;quot;, TestStruct::get_x, TestStruct::set_x);
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;simpler-eval&quot;&gt;Simpler eval&lt;&#x2F;h2&gt;
&lt;p&gt;Eval will now take the expected return type as a type parameter, letting you cut out a few steps. We&#x27;ve also moved to using &amp;amp;str rather than String for eval inputs.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;[Before]&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;if let Ok(result) = engine.eval(&amp;quot;40 + 2&amp;quot;.to_string()).unwrap().downcast::&amp;lt;i32&amp;gt;() {}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;[Now]&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;if let Ok(result) = engine.eval::&amp;lt;i32&amp;gt;(&amp;quot;40 + 2&amp;quot;) {}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;new-feature-arrays&quot;&gt;New feature: arrays&lt;&#x2F;h1&gt;
&lt;p&gt;In addition to the API improvements, Rhai now has a built-in array type.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;var y = [1, 2, 3];
y[1] = 5;

print(y[1]);
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;thanks&quot;&gt;Thanks!&lt;&#x2F;h1&gt;
&lt;p&gt;Thanks for the feedback on Rhai&#x27;s first release. Also, big thanks to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;nikomatsakis&quot;&gt;@nikomatsakis&lt;&#x2F;a&gt;, who gave me a few key pointers on how improve the API.&lt;&#x2F;p&gt;
&lt;p&gt;Looking forward to hearing from you.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Embedded scripting in Rust</title>
        <published>2016-03-14T00:00:00+00:00</published>
        <updated>2016-03-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/embedded-scripting-in-rust/"/>
        <id>https://www.sophiajt.com/embedded-scripting-in-rust/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/embedded-scripting-in-rust/">&lt;p&gt;For the last few weeks, I&#x27;ve been working on an embedded scripting language for Rust, based loosely on &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.chaiscript.com&quot;&gt;ChaiScript&lt;&#x2F;a&gt; called &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sophiajt&#x2F;rhai&quot;&gt;Rhai&lt;&#x2F;a&gt;. What&#x27;s an embedded scripting language? While the definition might depend on who you ask, for this post embedded scripting has a few distinct features:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A language that derives all functionality from bindings to the hosting environment&lt;&#x2F;li&gt;
&lt;li&gt;As a result, it allows complete control over the API exposed to the script, letting you lock down the script to your application&#x27;s needs&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;In short, it&#x27;s like the little brother of a full scripting language. It&#x27;s smaller, thinner, but still useful for a variety of apps.&lt;&#x2F;p&gt;
&lt;p&gt;Because I&#x27;m using Rust as the host language, I also put a few other constraints on the project to make it work with a wider range of use cases.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;No use of &#x27;unsafe&#x27; - this lets us script where security is a concern&lt;&#x2F;li&gt;
&lt;li&gt;No additional dependencies - keeps our design small&lt;&#x2F;li&gt;
&lt;li&gt;Easy-to-use - even being safe and lightweight, it still needs to be easy to get started&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;introducing-rhai&quot;&gt;Introducing: Rhai&lt;&#x2F;h1&gt;
&lt;p&gt;Let&#x27;s take a look at what Rhai looks like, then we&#x27;ll break down how it works.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;hello-world&quot;&gt;Hello world&lt;&#x2F;h2&gt;
&lt;p&gt;As I mentioned earlier, one of the goals with Rhai was to have minimal setup to get going. This example is a full &quot;hello world&quot; of scripting that evaluates some script and gives us the result:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;extern crate rhai;
use rhai::Engine;

fn main() {
    let mut engine = Engine::new();

    if let Ok(result) = engine.eval(&amp;quot;40 + 2&amp;quot;.to_string())
        .unwrap().downcast::&amp;lt;i32&amp;gt;() {

        println!(&amp;quot;Answer: {}&amp;quot;, *result);  &#x2F;&#x2F; prints 42
    }
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Looking a little closer. We pull in the Rhai crate and get the scripting engine into view:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;extern crate rhai;
use rhai::Engine;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Next, we create an instance of the engine:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;let mut engine = Engine::new();
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Finally, we call into the engine. Perhaps the most interesting part here is the roundtrip. The &#x27;eval&#x27; method takes a &lt;code&gt;String&lt;&#x2F;code&gt;, and returns a &lt;code&gt;Result&amp;lt;Box&amp;lt;Any&amp;gt;, EvalAltResult&amp;gt;&lt;&#x2F;code&gt;. Because we&#x27;re in a scripting context, everything we&#x27;re working with is dynamically typed, so as values get passed around, we make liberal use of &lt;code&gt;Box&amp;lt;Any&amp;gt;&lt;&#x2F;code&gt;. Here, the expression &quot;40 + 2&quot; is going to evaluated to give us a Box&#x27;ed number. Of course, we can also have errors occur during script execution, so we need to return a Result.&lt;&#x2F;p&gt;
&lt;p&gt;To go from a Result to the actual numeric value, we have to take a few steps to peel away the layers. I cheat and use &#x27;unwrap&#x27; to get through the Result, then the downcast takes us from a &lt;code&gt;Box&amp;lt;Any&amp;gt;&lt;&#x2F;code&gt; to a &lt;code&gt;Box&amp;lt;i32&amp;gt;&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;engine.eval(&amp;quot;40 + 2&amp;quot;.to_string()).unwrap().downcast::&amp;lt;i32&amp;gt;()
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;That&#x27;s it. We&#x27;ve done a full round trip of creating script and then making sense of its output. The language, at this point, has only basic functionality because we haven&#x27;t registered anything the script can use. So let&#x27;s fix that.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;registering-your-functions&quot;&gt;Registering your functions&lt;&#x2F;h2&gt;
&lt;p&gt;To make your functions visible to the script, you&#x27;ll need to register them with the script engine. Let&#x27;s do the same example, but this time we&#x27;ll create an add function in our native code and call it from script:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;extern crate rhai;
use rhai::{Engine, FnRegister};

fn add(x: i32, y: i32) -&amp;gt; i32 {
    x + y
}

fn main() {
    let mut engine = Engine::new();

    &amp;amp;(add as fn(x: i32, y: i32)-&amp;gt;i32).register(&amp;amp;mut engine, &amp;quot;add&amp;quot;);

    if let Ok(result) = engine.eval(&amp;quot;add(40, 2)&amp;quot;.to_string())
        .unwrap().downcast::&amp;lt;i32&amp;gt;() {

        println!(&amp;quot;Answer: {}&amp;quot;, *result);  &#x2F;&#x2F; prints 42
    }
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The big change in this example is this line:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;&amp;amp;(add as fn(x: i32, y: i32)-&amp;gt;i32).register(&amp;amp;mut engine, &amp;quot;add&amp;quot;);
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This uses the function registration capability taken from the FnRegister trait that we&#x27;ve added to our imports. It&#x27;s a trait implemenented on functions which gives them a register method. We call the method and pass into it both our engine and the name we want the function to be called in script. With that, we&#x27;re good to go and can call the function.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s do two more examples so we can see how some of the other details play out.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;function-overloading&quot;&gt;Function overloading&lt;&#x2F;h2&gt;
&lt;p&gt;Rhai also has supported for function overloading. This gives you a way to work with generic functions (like the example below) or to register multiple functions to the same name. During call resolution, the engine will call these functions and will fall through to the case that matches the types at runtime.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;use std::fmt::Display;

extern crate rhai;
use rhai::{Engine, FnRegister};

fn showit&amp;lt;T: Display&amp;gt;(x: &amp;amp;mut T) -&amp;gt; () {
    println!(&amp;quot;{}&amp;quot;, x)
}

fn main() {
    let mut engine = Engine::new();

    &amp;amp;(showit as fn(x: &amp;amp;mut i32)-&amp;gt;()).register(&amp;amp;mut engine, &amp;quot;print&amp;quot;);
    &amp;amp;(showit as fn(x: &amp;amp;mut bool)-&amp;gt;()).register(&amp;amp;mut engine, &amp;quot;print&amp;quot;);
    &amp;amp;(showit as fn(x: &amp;amp;mut String)-&amp;gt;()).register(&amp;amp;mut engine, &amp;quot;print&amp;quot;);
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;working-with-custom-types&quot;&gt;Working with custom types&lt;&#x2F;h2&gt;
&lt;p&gt;Finally, in addition to working with your functions, Rhai also supports working with custom types. In this example, we introduce a few more features. First, you can register functions that take a &lt;code&gt;&amp;amp;mut&lt;&#x2F;code&gt; as their first argument. This allows them to be used as methods in the script. Next, we register a special getter function. This lets us read (or write, if we register a setter also) the member directly in script.&lt;&#x2F;p&gt;
&lt;p&gt;You&#x27;ll notice too that we make sure our object is clone-able. As we&#x27;ll talk about in the next section, this ends up being a requirement when working with values in the script engine. We make sure to register our custom type with the engine to make cloning possible from inside the engine.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;extern crate rhai;
use rhai::{Engine, FnRegister};

#[derive(Clone)]
struct TestStruct {
    x: i32
}

impl TestStruct {
    fn update(&amp;amp;mut self) {
        self.x += 1000;
    }

    fn get_x(&amp;amp;mut self) -&amp;gt; i32 { self.x }

    fn new() -&amp;gt; TestStruct {
        TestStruct { x: 1 }
    }
}

fn main() {
    let mut engine = Engine::new();

    engine.register_type::&amp;lt;TestStruct&amp;gt;();

    &amp;amp;(TestStruct::new as fn()-&amp;gt;TestStruct).register(&amp;amp;mut engine, &amp;quot;new_ts&amp;quot;);

    &amp;amp;(TestStruct::update as fn(&amp;amp;mut TestStruct)-&amp;gt;())
        .register(&amp;amp;mut engine, &amp;quot;update&amp;quot;);
    &amp;amp;(TestStruct::get_x as fn(&amp;amp;mut TestStruct)-&amp;gt;i32)
        .register(&amp;amp;mut engine, &amp;quot;get$x&amp;quot;);

    if let Ok(result) =
        engine.eval(&amp;quot;var myts = new_ts(); myts.update(); myts.x&amp;quot;.to_string())
            .unwrap().downcast::&amp;lt;i32&amp;gt;() {

        println!(&amp;quot;result: {}&amp;quot;, *result); &#x2F;&#x2F; prints 1001
    }
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;how-it-works&quot;&gt;How it works&lt;&#x2F;h1&gt;
&lt;p&gt;Let&#x27;s take a look at how the scripting engine works. There may be even better ways to do some of these steps, so I&#x27;m eager to hear your feedback.&lt;&#x2F;p&gt;
&lt;p&gt;Without further ado, let&#x27;s jump in.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;function-resolution&quot;&gt;Function resolution&lt;&#x2F;h2&gt;
&lt;p&gt;The heart of the system is the function resolver. In Rhai, all function calls, even all operators like plus and minus, end up going through the resolver. Yet, it&#x27;s a relatively simple piece of code.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;First, find all functions which match the name. Let&#x27;s say &#x27;foo&#x27;&lt;&#x2F;li&gt;
&lt;li&gt;For each &#x27;foo&#x27; function, try to call the function with the argument(s) given&lt;&#x2F;li&gt;
&lt;li&gt;If it succeeds, return the resulting value&lt;&#x2F;li&gt;
&lt;li&gt;If it fails, continue trying the rest of the functions registered to &#x27;foo&#x27;&lt;&#x2F;li&gt;
&lt;li&gt;If none succeed, error&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Going through all the functions which match a name gives us the ability to do overloaded functions. It also lets us do operators, which themselves are commonly overloaded.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;function-registration&quot;&gt;Function registration&lt;&#x2F;h2&gt;
&lt;p&gt;The next piece to working with functions in the engine is registering them. There are two kinds of functions that are registered: inner functions, or those created inside the script itself, and external functions, or those created in the native code.&lt;&#x2F;p&gt;
&lt;p&gt;Inner functions are relatively simple. They work by creating a new scope, adding the function arguments to this new scope, and then executing the function body.&lt;&#x2F;p&gt;
&lt;p&gt;External functions, if you will, are where the magic happens. Here, we handle the boundary between the scripting world and the native world.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s look at how to register a function with one pass-by-value argument &lt;code&gt;fn(T)-&amp;gt;U&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;impl&amp;lt;T: Any+Clone, U: Any+Clone&amp;gt; FnRegister for fn(T)-&amp;gt;U {
    fn register(self, engine: &amp;amp;mut Engine, name: &amp;amp;str) {
        let wrapped : Box&amp;lt;Fn(&amp;amp;mut Box&amp;lt;Any&amp;gt;)-&amp;gt;Result&amp;lt;Box&amp;lt;Any&amp;gt;, EvalAltResult&amp;gt;&amp;gt; =
            Box::new(
                move |arg: &amp;amp;mut Box&amp;lt;Any&amp;gt;| {
                    let inside = (*arg).downcast_mut() as Option&amp;lt;&amp;amp;mut T&amp;gt;;
                    match inside {
                        Some(b) =&amp;gt; Ok(Box::new(self(b.clone())) as Box&amp;lt;Any&amp;gt;),
                        None =&amp;gt; Err(EvalAltResult::ErrorFunctionArgMismatch)
                    }
                }
            );

        let ent = engine.fns.entry(name.to_string()).or_insert(Vec::new());
        (*ent).push(FnType::ExternalFn1(wrapped));
    }
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;There&#x27;s a lot going on, so let&#x27;s break it down:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;impl&amp;lt;T: Any+Clone, U: Any+Clone&amp;gt; FnRegister for fn(T)-&amp;gt;U
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;As I mentioned earlier, all the types used in the scripting engine need to be clone-able. We enforce that here as well because we&#x27;ll use the clone feature in the call. We are implementing the FnRegister trait on all functions that match this constraint.&lt;&#x2F;p&gt;
&lt;p&gt;Next, we are going to create a wrapper function which will call the function given:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;let wrapped : Box&amp;lt;Fn(&amp;amp;mut Box&amp;lt;Any&amp;gt;)-&amp;gt;Result&amp;lt;Box&amp;lt;Any&amp;gt;, EvalAltResult&amp;gt;&amp;gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;All functions of arity one have this internal wrapper function, regardless of if they are pass by value or reference. This lets us work through a vector of functions easily during function resolution, without having to have too much information out the specific type of the function.&lt;&#x2F;p&gt;
&lt;p&gt;Next, we have the wrapper function itself:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;Box::new(
    move |arg: &amp;amp;mut Box&amp;lt;Any&amp;gt;| {
        let inside = (*arg).downcast_mut() as Option&amp;lt;&amp;amp;mut T&amp;gt;;
        match inside {
            Some(b) =&amp;gt; Ok(Box::new(self(b.clone())) as Box&amp;lt;Any&amp;gt;),
            None =&amp;gt; Err(EvalAltResult::ErrorFunctionArgMismatch)
        }
    }
);
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The wrapper is a closure that moves its environment. In this case, it&#x27;s moving the function we&#x27;re wrapping. Once it has ownership, we can safely return the wrapper and complete registration.&lt;&#x2F;p&gt;
&lt;p&gt;Inside the closure, we handle working with the argument. Because we know the type of the function during registration, we use this knowledge to downcast the argument and give it the proper type. If this succeeds, we know we have the correct function and can call it. If it fails, we know this isn&#x27;t a match and later can try the next function in the overloads.&lt;&#x2F;p&gt;
&lt;p&gt;To call the function, since we&#x27;re pass by value, we need to take the extra cloning step to get to a value rather than a reference. This lets us respect the ownership model, albeit at the cost of the clone.&lt;&#x2F;p&gt;
&lt;p&gt;That&#x27;s the heart of how the resolution system works. Resolution works through each possible match, and registration gives us a wrapper function that can try each function against the types known at compile time.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-rest-of-the-story&quot;&gt;The rest of the story&lt;&#x2F;h2&gt;
&lt;p&gt;Many of the remaining features built on these two main components. As mentioned earlier, when you register special get and set functions for fields, the engine will use them when you work with the fields in script.&lt;&#x2F;p&gt;
&lt;p&gt;The engine will register a set of basic arithmetic and comparison operators to get started with. These also use the same function resolution mechanism.&lt;&#x2F;p&gt;
&lt;p&gt;For variables, the engine works by passing a scope stack around. For lookup, in order to follow the ownership rules (and maintain pass-by-value semantics), we clone variable values when they&#x27;re used in an expression. During assignment, we use a mutable reference to their value in the scope stack so that it can be updated with the right-hand side of the assignment.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;what-s-next&quot;&gt;What&#x27;s next?&lt;&#x2F;h1&gt;
&lt;p&gt;Rhai is still very young and has a bit of growing to do before it&#x27;s ready for primetime. Parsing and error reporting are barebones and don&#x27;t have the kind of error recovery you&#x27;d expect from more industrial-strength scripting. There are also a number of convenience features that would be relatively easy to add, like vectors, iterators, for..in.., and so on.&lt;&#x2F;p&gt;
&lt;p&gt;If you&#x27;d like to help out, jump over to the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sophiajt&#x2F;rhai&quot;&gt;GitHub site&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Going down the rabbit hole with Rust traits</title>
        <published>2016-02-09T00:00:00+00:00</published>
        <updated>2016-02-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/down-the-rabbit-hole-with-traits/"/>
        <id>https://www.sophiajt.com/down-the-rabbit-hole-with-traits/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/down-the-rabbit-hole-with-traits/">&lt;p&gt;One of the first things you might notice about Rust, if you come to it from other OOP-style languages, is that Rust separates methods from the data they work on.  You create your &lt;code&gt;struct&lt;&#x2F;code&gt;, then you &lt;code&gt;impl&lt;&#x2F;code&gt; a few methods on it later.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;struct Rect {
    height: i32,
    width: i32
}

impl Rect {
    fn area(&amp;amp;self) -&amp;gt; i32 { self.height * self.width }
}

fn main() {
    let r = Rect { height: 10, width: 5 };
    println!(&amp;quot;area: {}&amp;quot;, r.area());
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Which, to me, seemed slightly awkward at first.  But, as I dug in a little futher, I started asking questions like &quot;Can I do that to existing types?  Even basic types like the String type?&quot;  Indeed you can.  In this post we&#x27;ll see some of what&#x27;s possible.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Warning: we&#x27;re going down a rabbit hole under the influence of the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Avenue_Q&quot;&gt;Bad Idea Bears&lt;&#x2F;a&gt;.  I hope you have your snorkel. :)&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;warming-up&quot;&gt;Warming up&lt;&#x2F;h1&gt;
&lt;p&gt;We&#x27;ve talked a little about the basics already.  In Rust, &lt;code&gt;impl&lt;&#x2F;code&gt; gives us a way to &quot;add&quot; methods onto types.  But, when we try to do the same thing to &lt;code&gt;String&lt;&#x2F;code&gt;, we hit a snag:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;impl String {
    fn my_len(&amp;amp;self) -&amp;gt; usize { self.len() }
}

fn main() {
    let name = &amp;quot;foo&amp;quot;.to_string();

    println!(&amp;quot;my length: {}&amp;quot;, name.my_len());
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;When we try to compile this, the compiler gives us back an error:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;mylen.rs:1:1: 3:2 error: cannot define inherent `impl` for a type outside of the crate where the type is defined; define and implement a trait or new type instead [E0116]
mylen.rs:1 impl String {
mylen.rs:2     fn my_len(&amp;amp;self) -&amp;gt; usize { self.len() }
mylen.rs:3 }
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So we can&#x27;t &lt;code&gt;impl&lt;&#x2F;code&gt; for a type outside of... oh wait.  We can do it, so long as we give it a trait to work with.&lt;&#x2F;p&gt;
&lt;p&gt;Try #2:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;trait MyLen {
    fn my_len(&amp;amp;self) -&amp;gt; usize;
}

impl MyLen for String {
    fn my_len(&amp;amp;self) -&amp;gt; usize { self.len() }
}

fn main() {
    let name = &amp;quot;foo&amp;quot;.to_string();

    println!(&amp;quot;my length: {}&amp;quot;, name.my_len());
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Woah, that worked!  With that, we peek into the rabbit hole.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;traits-and-extending-strings&quot;&gt;Traits and extending strings&lt;&#x2F;h1&gt;
&lt;p&gt;To kick off our explorations, let&#x27;s give ourselves an example to use.  Let&#x27;s say we want to read in the contents of some file, and we get the filename for that file from the commandline.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;use std::io::Error;

fn read_all(fname: String) -&amp;gt; Result&amp;lt;String, Error&amp;gt; {
    use std::fs::File;
    use std::io::prelude::*;

    let mut contents = String::new();
    let mut f = try!(File::open(fname));
    try!(f.read_to_string(&amp;amp;mut contents));
    Ok(contents)
}

fn main() {
    use std::env::args; 

    if let Some(fname) = args().nth(1) {
        if let Ok(contents) = read_all(fname) {
            println!(&amp;quot;{}&amp;quot;, contents);
        }
    }
} 
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Wouldn&#x27;t it be nice to not mix and match helper functions and methods?  Wouldn&#x27;t it read a little nicer to have&lt;code&gt;fname.read_all()&lt;&#x2F;code&gt;?&lt;&#x2F;p&gt;
&lt;p&gt;Using the same pattern we used before, this is pretty easy to do.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;use std::io::Error;

trait FileReader {
    fn read_all(&amp;amp;self) -&amp;gt; Result&amp;lt;String, Error&amp;gt;;
}

impl FileReader for str {
    fn read_all(&amp;amp;self) -&amp;gt; Result&amp;lt;String, Error&amp;gt; {
        use std::fs::File;
        use std::io::prelude::*;

        let mut contents = String::new();
        let mut f = try!(File::open(self));
        try!(f.read_to_string(&amp;amp;mut contents));
        Ok(contents)
    }
}

fn main() {
    use std::env::args; 

    if let Some(fname) = args().nth(1) {
        if let Ok(contents) = fname.read_all() {
            println!(&amp;quot;{}&amp;quot;, contents);
        }
    }
}    
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;That&#x27;s not bad!  Go get my nth argument, check if we&#x27;re good, then read the contents.&lt;&#x2F;p&gt;
&lt;p&gt;If we could stop ourselves there, we&#x27;d be mostly okay.  Our example is still pretty readable, though we might get a few dirty looks from the senior devs in the lunch line.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;traits-and-extending-option&quot;&gt;Traits and extending Option&lt;&#x2F;h1&gt;
&lt;p&gt;The Bad Idea Bears call us deeper!  Can we play a little &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Code_golf&quot;&gt;code &quot;golf&quot;&lt;&#x2F;a&gt; and squeeze out using &lt;code&gt;Option&lt;&#x2F;code&gt; in our main?  Sure!  All we need to do is create another &lt;code&gt;impl&lt;&#x2F;code&gt; for our &lt;code&gt;FileReader&lt;&#x2F;code&gt; trait, this time for &lt;code&gt;Option&lt;&#x2F;code&gt; (specifically those that contain Strings):&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;use std::io::Error;

trait FileReader {
    fn read_all(&amp;amp;self) -&amp;gt; Result&amp;lt;String, Error&amp;gt;;
}

impl FileReader for str {
    fn read_all(&amp;amp;self) -&amp;gt; Result&amp;lt;String, Error&amp;gt; {
        use std::fs::File;
        use std::io::prelude::*;

        let mut contents = String::new();
        let mut f = try!(File::open(self));
        try!(f.read_to_string(&amp;amp;mut contents));
        Ok(contents)
    }
}

impl FileReader for Option&amp;lt;String&amp;gt; {
    fn read_all(&amp;amp;self) -&amp;gt; Result&amp;lt;String, Error&amp;gt; {
        use std::io::ErrorKind;
        match *self {
            Option::None =&amp;gt; Err(Error::new(ErrorKind::NotFound, 
                &amp;quot;No such file or directory&amp;quot;)),
            Option::Some(ref s) =&amp;gt; s.read_all()
        }
    }
}

fn main() {
    use std::env::args; 
    
    if let Ok(contents) = args().nth(1).read_all() {
        println!(&amp;quot;{}&amp;quot;, contents);
    }
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Yay!  Our main is smaller, and we&#x27;ve still managed to maintain at least a &lt;em&gt;little&lt;&#x2F;em&gt; of our decency.  I mean, we could have used &lt;code&gt;unwrap&lt;&#x2F;code&gt;, and thrown care to the wind!  Instead, we&#x27;re still doing error-checking on our contents. Albeit, our error-checking is kinda smooshed into one place.&lt;&#x2F;p&gt;
&lt;p&gt;What&#x27;s that, Bad Idea Bear?  We should go further?  Okay!&lt;&#x2F;p&gt;
&lt;h1 id=&quot;traits-and-extending-iterators&quot;&gt;Traits and extending iterators&lt;&#x2F;h1&gt;
&lt;p&gt;We&#x27;re doing a &lt;code&gt;read_all()&lt;&#x2F;code&gt; on the Option, but what if we go right to the arguments themselves?&lt;&#x2F;p&gt;
&lt;p&gt;If we poke around in the docs, we find out that args() returns its own type, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;std&#x2F;env&#x2F;struct.Args.html&quot;&gt;Args&lt;&#x2F;a&gt;. As we read on we see that Args is just an &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;std&#x2F;iter&#x2F;trait.Iterator.html&quot;&gt;Iterator&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;That gives us a couple choices.  We can implement a new trait on Args:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;trait FileReaderIter {
    fn read_nth(&amp;amp;mut self, pos: usize) -&amp;gt; Result&amp;lt;String, Error&amp;gt;;
}

impl FileReaderIter for Args {
    fn read_nth(&amp;amp;mut self, pos: usize) -&amp;gt; Result&amp;lt;String, Error&amp;gt; {
        self.nth(pos).read_all()
    }    
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Or, we can work with Iterator:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;trait FileReaderIter : Iterator&amp;lt;Item=String&amp;gt; + Sized {
    fn read_nth(&amp;amp;mut self, pos: usize) -&amp;gt; Result&amp;lt;String, Error&amp;gt; {
        self.nth(pos).read_all()
    }
}

impl FileReaderIter for Args {}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Let&#x27;s actually stop here for a minute and look at this one.  We can&#x27;t extend Iterator itself.  This is a Good Thing(tm), because if we could, we would end up having to extend countless implementors of Iterator.  Instead, we need to create a new trait that extends from Iterator.&lt;&#x2F;p&gt;
&lt;p&gt;Next, we need to say what &lt;em&gt;kind&lt;&#x2F;em&gt; of iterator we can work on.  We know ahead of time that this works on specifically iterators over Strings.  We use the &lt;code&gt;&amp;lt;Item=String&amp;gt;&lt;&#x2F;code&gt; to lock that knowledge in place for the compiler.  This is called an &lt;em&gt;associated type&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;With the new trait and associated type, we&#x27;re almost done.  Lastly, we&#x27;re doing something a little different this time around.  We have a default implementation inside of the trait instead of just having a prototype.  A default implementation saves you the trouble of having to repeat yourself with each type that implements the trait, if the function is general and trivial.&lt;&#x2F;p&gt;
&lt;p&gt;The gotcha is that if you use a default implementation that uses &lt;code&gt;self&lt;&#x2F;code&gt;, the compiler needs to know how big &lt;code&gt;self&lt;&#x2F;code&gt; will be because it will pass it by-value.  Hence, anything that implements &lt;code&gt;FileReaderIter&lt;&#x2F;code&gt; must have a known size so the compiler knows how many bytes to copy in when &lt;code&gt;self&lt;&#x2F;code&gt; is passed to the method.  To ensure this, we add another trait to inherit from, &lt;code&gt;Sized&lt;&#x2F;code&gt;.  With that, we can say that Args trivially implements this trait.&lt;&#x2F;p&gt;
&lt;p&gt;Phew, okay, that&#x27;s it.  What have we gotten for our effort?&lt;&#x2F;p&gt;
&lt;p&gt;Both approaches give us this simple main:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;fn main() {
    use std::env::args;

    if let Ok(contents) = args().read_nth(1) {
        println!(&amp;quot;{}&amp;quot;, contents);    
    }
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;At this point we&#x27;re far enough down in the rabbit hole that there&#x27;s only a pinpoint of light from the entrance.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s work our way back out, shall we?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;(ps: if you want to follow Bad Idea Bear further, this little nugget is hidden in the Rust docs: both Result and Option implement iterator traits and can be &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;play.rust-lang.org&#x2F;?gist=3a890c9c2617c4f1d4f1&amp;amp;version=stable&quot;&gt;used as iterators&lt;&#x2F;a&gt;)&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;climbing-back-out-of-the-rabbit-hole&quot;&gt;Climbing back out of the rabbit hole&lt;&#x2F;h1&gt;
&lt;p&gt;Cleverness and readability often trade off with each other.  As we tried to get more clever and squeeze our main down, the end result became more code we had to maintain.  We also increased the amount of &#x27;magic&#x27; we used, whether it was treating multiple failure styles&#x2F;cases as one case or the amount of additional capabilities we were giving types like String and Option.&lt;&#x2F;p&gt;
&lt;p&gt;Rust&#x27;s trait system is powerful and clever.  It lets you express the algorithms that are core to your project in a way that can even extend the basic Rust API.  Indeed, that&#x27;s one reason why the Rust language and core libraries are intentionally kept pretty small and tidy: so you can make these kind of additions (using eg. modules from &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;crates.io&#x2F;&quot;&gt;creates.io&lt;&#x2F;a&gt;) and the standard library doesn&#x27;t get in your way.&lt;&#x2F;p&gt;
&lt;p&gt;But, as they say, with great power comes great opportunities to follow Bad Idea Bears down rabbit holes.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Rust quickie - matching Strings</title>
        <published>2016-02-08T00:00:00+00:00</published>
        <updated>2016-02-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/rust-quickie-matching-strings/"/>
        <id>https://www.sophiajt.com/rust-quickie-matching-strings/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/rust-quickie-matching-strings/">&lt;p&gt;In case you find yourself trying to match a &lt;code&gt;String&lt;&#x2F;code&gt; (perhaps as part of an &lt;code&gt;Option&lt;&#x2F;code&gt; or &lt;code&gt;Result&lt;&#x2F;code&gt;), here&#x27;s a little trick.&lt;&#x2F;p&gt;
&lt;p&gt;As a concrete example, let&#x27;s say you&#x27;re working with commandline args and want to do different things if it&#x27;s there and equal to a special value (like &quot;-&quot;), if it&#x27;s any other filename, or if it&#x27;s not there.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;match args().nth(1) {
    Some(&amp;quot;-&amp;quot;)     =&amp;gt; println!(&amp;quot;Input is stdin&amp;quot;),
    Some(ref x)   =&amp;gt; println!(&amp;quot;Open file: {}&amp;quot;, x),
    None          =&amp;gt; println!(&amp;quot;Open default file &#x2F;foo&#x2F;bar&amp;quot;)
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;When you try to compile this, you get:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;error: mismatched types:
 expected `collections::string::String`,
    found `&amp;amp;&amp;#39;static str`
(expected struct `collections::string::String`,
    found &amp;amp;-ptr) [E0308]
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Bummer! At least on the surface, it looks like we don&#x27;t have an easy way to use a string constant like &quot;-&quot; in our pattern match when what we&#x27;re matching against a String.&lt;&#x2F;p&gt;
&lt;p&gt;Luckily, Rust pattern matching has a way to help us.  We can approximate the above by using &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;book&#x2F;patterns.html#guards&quot;&gt;match guards&lt;&#x2F;a&gt;.  Match guards allow us to put an additional &lt;code&gt;if&lt;&#x2F;code&gt; expression on the pattern.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;match args().nth(1) {
    Some(ref x) if x == &amp;quot;-&amp;quot; =&amp;gt; println!(&amp;quot;Input is stdin&amp;quot;),
    Some(ref x) =&amp;gt; println!(&amp;quot;Open file: {}&amp;quot;, x),
    None        =&amp;gt; println!(&amp;quot;Open default file &#x2F;foo&#x2F;bar&amp;quot;)
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Match guards give you an extra bit of &quot;juice&quot; to express your logic.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Feature Bias, or Rethinking the Blub Paradox</title>
        <published>2016-01-23T00:00:00+00:00</published>
        <updated>2016-01-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/rethinking-the-blub-paradox/"/>
        <id>https://www.sophiajt.com/rethinking-the-blub-paradox/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/rethinking-the-blub-paradox/">&lt;p&gt;I got a lot of great feedback on my previous post &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.sophiajt.com&#x2F;2016&#x2F;01&#x2F;rust-and-blub-paradox.html&quot;&gt;&quot;Rust and the Blub Paradox&quot;&lt;&#x2F;a&gt;, which inspired me to write a follow-up.&lt;&#x2F;p&gt;
&lt;p&gt;In its original formulation, the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.paulgraham.com&#x2F;avg.html&quot;&gt;Blub Paradox&lt;&#x2F;a&gt; is something of a tool for people to feel smug about their favorite language. I heard a lot of feedback that it feels condescending. I hadn&#x27;t realized that in my mind the Blub Paradox had morphed from its original form into something different.&lt;&#x2F;p&gt;
&lt;p&gt;In this post, I&#x27;d like to break down the Blub Paradox into to what I see as its fundamental observation: that we, as programmers, can have a form of unconscious bias. I&#x27;ll call this &lt;em&gt;Feature Bias&lt;&#x2F;em&gt; so that we don&#x27;t confuse it with Paul&#x27;s original idea.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;there-are-no-universally-better-languages&quot;&gt;There are no universally better languages&lt;&#x2F;h1&gt;
&lt;p&gt;There is no way to universally sort programming languages on a continuum that is monotonically increasing in awesomeness. It&#x27;s impossible. Not only are languages too complex to have any kind of universal ranking, they are tools and as tools the value is left to the tool user. It&#x27;s like asking &quot;is pencil better than a paint brush?&quot; It all depends on what you&#x27;re doing and what you&#x27;re more comfortable with.&lt;&#x2F;p&gt;
&lt;p&gt;The types of languages that Paul criticizes in Beating the Averages aren&#x27;t universally worse than his favorite languages. Taking one example, everyone loves to put Java down, but have you ever watched Notch (the creator of Minecraft) &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.twitch.tv&#x2F;notch&#x2F;b&#x2F;302823358&quot;&gt;code in it&lt;&#x2F;a&gt;? He seems perfectly content to create with his tool of choice, and he&#x27;s certainly capable of doing so.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;feature-bias-happens-locally-per-feature&quot;&gt;Feature Bias happens locally per feature&lt;&#x2F;h1&gt;
&lt;p&gt;Rather than trying to sort languages universally, a useful version of the Blub Paradox is a local phenomenon. It happens on a feature by feature level.&lt;&#x2F;p&gt;
&lt;p&gt;If a programmer accustomed to working with a feature sees a language that lacks the feature, they can also see the use cases where programmers in that other language might benefit from its use.&lt;&#x2F;p&gt;
&lt;p&gt;If a programmer who doesn&#x27;t use a feature looks at a language with this feature, until they&#x27;ve spent time to understand it, they may see the feature as unnecessary.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;feature-bias-happens-to-most-programmers-even-the-best&quot;&gt;Feature Bias happens to most programmers, even the best&lt;&#x2F;h1&gt;
&lt;p&gt;As a language PM at Microsoft sitting on a few programming language committees, I saw Feature Bias happen to people from junior developers to famous language designers with decades of industry experience. The first time a developer sees a new feature, regardless of skill level, there&#x27;s a chance they may experience the bias.&lt;&#x2F;p&gt;
&lt;p&gt;True story: the C# feature LINQ had to &#x27;bake&#x27; for at least a year with the design committee before enough members saw its value for it to become part of the language. All the while the champions behind it were trying to educate and get other committee members to give it a chance.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;features-don-t-have-universal-value&quot;&gt;Features don&#x27;t have universal value&lt;&#x2F;h1&gt;
&lt;p&gt;Once the developer puts in the time to understand the feature, they &lt;em&gt;still&lt;&#x2F;em&gt; may not like it. That&#x27;s not the paradox&#x2F;bias anymore. They&#x27;ve put the time in to understand the trade-offs, and they don&#x27;t feel the trade-offs are worth it. That&#x27;s a totally acceptable response.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;the-root-of-the-bias&quot;&gt;The root of the bias&lt;&#x2F;h1&gt;
&lt;p&gt;To summarize, just like other unconscious biases, this bias is pointing out something that&#x27;s common for people to experience and they may not realize they&#x27;re experiencing it.&lt;&#x2F;p&gt;
&lt;p&gt;A lot of programmers I know, including myself on a good day, use an understanding of the bias as a way to train ourselves to take time with each feature and work through the knee-jerk &quot;oh this is crap!&quot; reaction. I definitely still fall victim to it. Just as with other biases, you have to keep working at it.&lt;&#x2F;p&gt;
&lt;p&gt;In seeing the responses from people, it&#x27;s unfortunate that the original Blub Paradox has been used as a club to beat people with. It makes it that much harder to see where it can be helpful. In my experience, it can shine a light on an area that helps us become better programmers and teachers.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Rust and the Blub Paradox</title>
        <published>2016-01-22T00:00:00+00:00</published>
        <updated>2016-01-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/rust-and-blub-paradox/"/>
        <id>https://www.sophiajt.com/rust-and-blub-paradox/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/rust-and-blub-paradox/">&lt;p&gt;A few weeks ago, I read an &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.quora.com&#x2F;Which-language-has-the-brightest-future-in-replacement-of-C-between-D-Go-and-Rust-And-Why&quot;&gt;analysis of Rust, D, and Go&lt;&#x2F;a&gt; by Andrei Alexandrescu. Andrei, a &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.amazon.com&#x2F;Modern-Design-Generic-Programming-Patterns&#x2F;dp&#x2F;0201704315&quot;&gt;respected member of the C++ community&lt;&#x2F;a&gt; and a core developer of the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;dlang.org&#x2F;&quot;&gt;D programming language&lt;&#x2F;a&gt;, took a stab at Rust at the end of his writeup with what seems like a pretty astute observation:&lt;&#x2F;p&gt;
&lt;p&gt;&quot;Reading any amount of Rust code evokes the joke &quot;friends don&#x27;t let friends skip leg day&quot; and the comic imagery of men with hulky torsos resting on skinny legs. Rust puts safe, precise memory management front and center of everything. Unfortunately, that&#x27;s seldom the problem domain, which means a large fraction of the thinking and coding are dedicated to essentially a clerical job&quot;&lt;&#x2F;p&gt;
&lt;p&gt;Having met Andrei and seen a few of his talks, I know that he likes to poke fun. Still, let&#x27;s take the bait. Is his observation funny because it&#x27;s a funny image or is it funny because there&#x27;s an underlying truth to what he&#x27;s saying?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;EDIT:&lt;&#x2F;strong&gt; thanks to all the responses to this post, I&#x27;ve written a follow-up on &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.sophiajt.com&#x2F;2016&#x2F;01&#x2F;rethinking-the-blub-paradox.html&quot;&gt;where the Blub Paradox is wrong and where it&#x27;s helpful&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;EDIT #2:&lt;&#x2F;strong&gt; Wow, some people also seem to be taking this article as an attack on Andrei. Not at all! Like I said, I&#x27;ve chatted with him in person and he&#x27;s very much the type that likes to say funny things, whether about himself or the wide array of programming languages. I just took one of his quotes about Rust as a starting point and had fun with it and looked at what might be weird about Rust coming from other languages.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;blub-paradox&quot;&gt;Blub paradox&lt;&#x2F;h1&gt;
&lt;p&gt;Whenever I think about how useful certain language features are, I almost always come back to Paul Graham&#x27;s essay &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.paulgraham.com&#x2F;avg.html&quot;&gt;&quot;Beating the Averages&quot;&lt;&#x2F;a&gt;. In it, he observes an interesting phenomenon among programmers he calls &quot;the Blub Paradox&quot;. To recap for those who haven&#x27;t heard of it, the paradox goes something like this: let&#x27;s say there&#x27;s a programmer using a language called Blub. Blub falls somewhere in the middle of the programming language pack in terms of capability. It&#x27;s not the lowest, most minimal language nor is it the most powerful.&lt;&#x2F;p&gt;
&lt;p&gt;When the Blub programmer looks &quot;down&quot; the spectrum of languages, they can easily see that those languages are less expressive than their preferred Blub language. Unfortunately, when they look &quot;up&quot; the spectrum of languages, they can&#x27;t tell they&#x27;re looking up. As Paul puts it:&lt;&#x2F;p&gt;
&lt;p&gt;&quot;What he sees are merely weird languages. He probably considers them about equivalent in power to Blub, but with all this other hairy stuff thrown in as well. Blub is good enough for him, because he thinks in Blub.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;When I read that years ago, I remember thinking &quot;wow, that&#x27;s pretty astute.&quot; Little did I know that years later it would become firmly ingrained as part of how I thought about teaching programming as a programming language PM.&lt;&#x2F;p&gt;
&lt;p&gt;As a programming language PM at Microsoft, I worked on &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.typescriptlang.org&quot;&gt;TypeScript&lt;&#x2F;a&gt;, a typed version of JavaScript. Without fail, if I was speaking to an audience of predominantly JavaScript developers, I would get many frowns as I tried to enumerate the advantages of adding a bit of type-checking to JavaScript. Even if it was optional. Even if I showed half a dozen powerful advantages. As Paul notes, it just looked &quot;weird&quot;. To a JavaScript developer, TypeScript would often just seem like a language that was equally expressive with &quot;hairy&quot; stuff thrown in.&lt;&#x2F;p&gt;
&lt;p&gt;As I talked to more language PMs, and I met more and more people at conferences, I learned that Paul&#x27;s observation was not only accurate, it was also surprisingly universal. Most programmers will struggle when looking at a new language they don&#x27;t use. Often, they&#x27;ll have allergic reactions to features that are foreign. It takes time to work with the features enough to understand why they aren&#x27;t just unnecessary ornamenation gumming up the works.&lt;&#x2F;p&gt;
&lt;p&gt;In short, the Blub Paradox is something that as programmers we actively need to assume we&#x27;re falling into and then work to get ourselves out of.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s do just that. Let&#x27;s look at a few stand-out Rust features and assume these features are weird and unnecessary. From there, we&#x27;ll see if we can work to un-Blub ourselves.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;weird-feature-1-rust-style-polymorphism&quot;&gt;Weird feature #1: Rust-style polymorphism&lt;&#x2F;h1&gt;
&lt;p&gt;Let&#x27;s make a Rust program that uses a bit of polymorphism to print out two different structs. I&#x27;ll show you the code first, then break it down.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;use std::fmt;

struct Foo {
    x: i32
}

impl fmt::Display for Foo {
    fn fmt(&amp;amp;self, f: &amp;amp;mut fmt::Formatter) -&amp;gt; fmt::Result {
        write!(f, &amp;quot;(x: {})&amp;quot;, self.x)
    }
}

struct Bar {
    x: i32,
    y: i32
}

impl fmt::Display for Bar {
    fn fmt(&amp;amp;self, f: &amp;amp;mut fmt::Formatter) -&amp;gt; fmt::Result {
        write!(f, &amp;quot;(x: {}, y: {})&amp;quot;, self.x, self.y)
    }
}

fn print_me&amp;lt;T: fmt::Display&amp;gt;(obj : T) {
    println!(&amp;quot;Value: {}&amp;quot;, obj)
}

fn main() {
    let foo = Foo {x: 7};
    let bar = Bar {x: 5, y: 10};
    print_me(foo);
    print_me(bar);
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;What an eye-full! There&#x27;s polymorphism there, but it doesn&#x27;t look anything like OO. It&#x27;s generic, and not only generic, but it has constraints. And what&#x27;s this &lt;code&gt;impl&lt;&#x2F;code&gt; stuff?&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s break it into parts. I&#x27;m creating two structs to hold our values. I go a step further and make sure they implement something called &lt;code&gt;fmt::Display&lt;&#x2F;code&gt;. In C++, you might overload the &amp;lt;&amp;lt; operator for ostream. The end result is similar in Rust. After I have this in place, I can call print functions and pass these structs directly.&lt;&#x2F;p&gt;
&lt;p&gt;With that, we&#x27;re half way through the example.&lt;&#x2F;p&gt;
&lt;p&gt;Next, we have our &lt;code&gt;print_me&lt;&#x2F;code&gt; function. This function is generic, and will accept anything so long as what is passed in can do &lt;code&gt;fmt::Display&lt;&#x2F;code&gt;. Luckily, we&#x27;ve already said how both structs can do just that.&lt;&#x2F;p&gt;
&lt;p&gt;The rest is straight-forward. We create a few structs and pass them to &lt;code&gt;print_me&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Phew... that seemed like a bit of work. And really, that&#x27;s how polymorphism starts in Rust. It&#x27;s all with generics.&lt;&#x2F;p&gt;
&lt;p&gt;Now, let&#x27;s switch to C++ for a minute. Someone using C++, especially a beginner, might not go the generic route at first and might instead opt to use OO-style polymorphism:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;cpp&quot;&gt;#include &amp;lt;iostream&amp;gt;

class Foo {
    public:
        int x;
        virtual void print();
};

class Bar: public Foo {
    public:
        int y;
        virtual void print();
};

void Foo::print() {
    std::cout &amp;lt;&amp;lt; &amp;quot;x: &amp;quot; &amp;lt;&amp;lt; this-&amp;gt;x &amp;lt;&amp;lt; &amp;#39;\n&amp;#39;;
}

void Bar::print() {
    std::cout &amp;lt;&amp;lt; &amp;quot;x: &amp;quot; &amp;lt;&amp;lt; this-&amp;gt;x &amp;lt;&amp;lt; &amp;quot; y: &amp;quot; &amp;lt;&amp;lt; this-&amp;gt;y &amp;lt;&amp;lt; &amp;#39;\n&amp;#39;;
}

void print(Foo foo) {
    foo.print();
}

void print2(Foo &amp;amp;foo) {
    foo.print();
}

void print3(Foo *foo) {
    foo-&amp;gt;print();
}

int main() {
    Bar bar;
    bar.x = 5;
    bar.y = 10;

    print(bar);
    print2(bar);
    print3(&amp;amp;bar);
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Pretty easy, right? Okay, here&#x27;s a quick quiz for you. What does the C++ code print?&lt;&#x2F;p&gt;
&lt;p&gt;If you guessed wrong, don&#x27;t worry. You&#x27;re in good company.&lt;&#x2F;p&gt;
&lt;p&gt;If you guessed right, congrats! Now, think a minute about how much do you have to understand about C++ to know the answer. From what I see, you need to understand the stack, how objects are copied, when they are copied, pointers, references, v-tables, and virtual dispatch. Just to do a few simple lines of OO.&lt;&#x2F;p&gt;
&lt;p&gt;When I first started learning C++, I had a pretty steep hill to climb. Luckily, &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;blog2.emptycrate.com&#x2F;&quot;&gt;my cousin&lt;&#x2F;a&gt; is an expert C++ programmer and took me under-wing to show me the ropes. Still, I made tons of beginner mistakes like the one above. Why? In part, the hill is steep because of the cognitive load of learning C++.&lt;&#x2F;p&gt;
&lt;p&gt;Some of that cognitive load is inherent in programming a computer at a system&#x27;s level. You need to understand the stack. You need to understand how pointers work. What C++ adds is another layer of complexity around knowing when a value isn&#x27;t fully copied and when virtual dispatch is and isn&#x27;t used -- all without any warning to the user if they do something that is &quot;probably a bad idea(tm)&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;This isn&#x27;t to knock on C++. Much of Rust is based on keeping the C++ philosophy of low-level efficient abstractions intact. In fact, you can even write code that&#x27;s &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gist.github.com&#x2F;sophiajt&#x2F;a182347b763398d8ea4f&quot;&gt;very similar to the Rust example&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;What Rust &lt;em&gt;does&lt;&#x2F;em&gt; do in this case is to separate inheritance from polymorphism and push you towards genericity from the start. In doing so, it gets you thinking generically from day #1. It might seem weird to separate inheritance from polymorphism if you&#x27;re used to them being used together.&lt;&#x2F;p&gt;
&lt;p&gt;That separation gives us one of our first Blub moments: what&#x27;s the advantage of separating inheritance and polymorphism? In fact, does Rust even have inheritance?&lt;&#x2F;p&gt;
&lt;p&gt;Believe it or not, at least as of Rust 1.5, Rust does not allow inheritance of structs. Instead, we can grow the functionality of structs from outside them using a feature called &#x27;traits&#x27;. Traits allow you a way to add methods, require methods, and retrofit datastructures for existing systems. They&#x27;re also allowed to inherit, so one trait can extend another.&lt;&#x2F;p&gt;
&lt;p&gt;If you poke around in the Rust, you&#x27;ll also notice something else. We don&#x27;t have the same issues we had with C++. There&#x27;s no worrying about what gets lost when the function is called or how virtual dispatch works. In Rust, we&#x27;re uniform regardless of the type. Because of this, a whole class of beginner errors vanish.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;weird-feature-2-what-no-exceptions&quot;&gt;Weird feature #2: what, no exceptions?&lt;&#x2F;h1&gt;
&lt;p&gt;While we&#x27;re on the subject of things Rust doesn&#x27;t have, its next weird feature is that it lacks exceptions. Isn&#x27;t that like going backwards? How do we talk about errors that only occur sometimes? How do we bubble out errors so we can handle them in one place?&lt;&#x2F;p&gt;
&lt;p&gt;Next you&#x27;ll be saying I have to learn monads.&lt;&#x2F;p&gt;
&lt;p&gt;Actually... no, just kidding, you don&#x27;t need to learn monads. Rust&#x27;s exception-less programming is a lot more straight-forward. Here&#x27;s an example of what this looks like in practice. First, examples of what the functions look like:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;impl SystemTime {
  &#x2F;&#x2F;&#x2F; Returns the system time corresponding to &amp;quot;now&amp;quot;.
  pub fn now() -&amp;gt; SystemTime;

  &#x2F;&#x2F;&#x2F; Returns an `Err` if `earlier` is later
  pub fn duration_from_earlier(&amp;amp;self, earlier: SystemTime) -&amp;gt; Result&amp;lt;Duration, SystemTimeError&amp;gt;;
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Notice the &lt;code&gt;now&lt;&#x2F;code&gt; function returns a SystemTime and doesn&#x27;t have any error cases, while &lt;code&gt;duration_from_earlier&lt;&#x2F;code&gt; does have a Result that can be either a Duration or the error SystemTimeError. At a glance, you know a function&#x27;s success and possible failure cases.&lt;&#x2F;p&gt;
&lt;p&gt;But all those failure cases are bound to stack up. Who wants to see them all over the code? Sure, it&#x27;s good to do error checking, but the point of exceptions is to be able to handle them not only locally but also to let them bubble up and handle them in one place.&lt;&#x2F;p&gt;
&lt;p&gt;Rust lets you do that, too.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;fn load_header(file: &amp;amp;mut File) -&amp;gt; Result&amp;lt;Header, io::Error&amp;gt; {
  Ok(Header { header_block: try!(file.read_u32()) })
}

fn load_metadata(file: &amp;amp;mut File) -&amp;gt; Result&amp;lt;Metadata, io::Error&amp;gt; {
  Ok(Metadata { metadata_block: try!(file.read_u32()) })
}

fn load_audio(file: &amp;amp;mut File) -&amp;gt; Result&amp;lt;Audio, io::Error&amp;gt; {
  let header = try!(load_header(file));
  let metadata = try!(load_metadata(file));
  Ok(Audio { header: header, metadata: metadata })
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;While it may not look like it at first, the above example uses the &quot;bubbling&quot; style of exceptions. The trick is in a Rust macro called &lt;code&gt;try!&lt;&#x2F;code&gt;. What it does is pretty simple. It will call a function for you. If that call returns with a success value, it will hand that to you. If it instead returns an error, &lt;code&gt;try!&lt;&#x2F;code&gt; will return from the containing function with that error.&lt;&#x2F;p&gt;
&lt;p&gt;The end result means that if if &lt;code&gt;load_header&lt;&#x2F;code&gt; ever has a problem when calling &lt;code&gt;file.read_u32()&lt;&#x2F;code&gt;, that Error will be returned instead. If it is, the same thing happens in &lt;code&gt;load_audio&lt;&#x2F;code&gt;, meaning that it, too, will return the same Error. And so on, until the calling function finally handles the error case.&lt;&#x2F;p&gt;
&lt;p&gt;I wrote a &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.sophiajt.com&#x2F;2015&#x2F;11&#x2F;learning-to-try-things-in-rust.html&quot;&gt;post about &lt;code&gt;try!&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;, if you&#x27;d like to learn more.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;weird-feature-3-the-borrow-checker&quot;&gt;Weird feature #3: the borrow-checker&lt;&#x2F;h1&gt;
&lt;p&gt;You know, it&#x27;s funny. Many people mention the borrow-checker as the first thing about Rust. Often, they even rank it as &lt;em&gt;the&lt;&#x2F;em&gt; thing that sets Rust apart. To Andrei, this is the &quot;hulky torso&quot; part of Rust. To me, though, the borrow-checker is just another pass in the compiler. Just like type-checking, it helps catch a level of bugs before they happen at runtime. That&#x27;s it. It might seem hefty at first, but I&#x27;d argue that&#x27;s just because it&#x27;s different and learning to work with it grows a new muscle as a programmer, not unlike working with a new type system.&lt;&#x2F;p&gt;
&lt;p&gt;What kinds of bugs does the borrow-checker catch, you ask?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;use-after-free&quot;&gt;Use-after-free&lt;&#x2F;h2&gt;
&lt;p&gt;Ah yes, the classic problem of freeing memory and then trying to use it later. Quite often, this is what makes programs crash with the dreaded &quot;null pointer exception&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;There are a good handful of C++ best practices to help avoid this (using RAII, preferring references or smart pointers over raw pointers, documenting the ownership in your API docs, etc), which is likely what Andrei referred to as &quot;large fraction of the thinking and coding are dedicated to essentially a clerical job&quot;. A team of highly trained C++ programmers would see avoiding use-after-free as largely clerical because that&#x27;s about what it amounts to -- so long as you obey all the best practices, never cheat, and you always only grow the team with more experts.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;invalid-iterator&quot;&gt;Invalid iterator&lt;&#x2F;h2&gt;
&lt;p&gt;Ever modify a container you&#x27;re iterating over in C++ and then have a random crash later on? I have. If you managed to add or remove an item to the container that was enough to force memory reallocation, your iterator has become invalid.&lt;&#x2F;p&gt;
&lt;p&gt;I don&#x27;t often make this error, but I still do from time to time.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;data-races&quot;&gt;Data races&lt;&#x2F;h2&gt;
&lt;p&gt;In Rust, data is either shared or mutable. If it&#x27;s mutable, it can&#x27;t be shared, so you don&#x27;t risk mutating from two threads in a race. If it&#x27;s shared, you can&#x27;t mutate, so you can read to your heart&#x27;s content from multiple threads.&lt;&#x2F;p&gt;
&lt;p&gt;If you&#x27;re coming from C++, or any other language with a set of good parallel libraries, this is going to feel overly strict to say the least. Luckily, this isn&#x27;t the whole story, but instead the general basis that gives you a simple set of rules to build more abstractions on. The rest of the story is still young and forming. There are a growing number of &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;areweconcurrentyet.com&#x2F;&quot;&gt;libraries focused on concurrency&lt;&#x2F;a&gt; that you can follow if you&#x27;re interested to learn more.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;tracking-ownership&quot;&gt;Tracking ownership&lt;&#x2F;h2&gt;
&lt;p&gt;This may seem a bit redundant, but it&#x27;s actually something that C++ struggles with. I alluded earlier to &quot;documenting the ownership in your API docs&quot;. The problem is that this information is in a comment rather than the code itself.&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s a scenario: you&#x27;re in C++ and you need to call a library that you didn&#x27;t write. Let&#x27;s say it&#x27;s a C-based library and takes a raw pointer. Will it delete what you passed in? Will it take ownership of it and put it into one of its data structures? Maybe you&#x27;re calling into a scripting engine like Ruby. Then who owns it?&lt;&#x2F;p&gt;
&lt;p&gt;Rather than reading through docs, Rust lets you verify that your assumptions match reality when it tracks how you are using the API with the borrow-checker.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;and-more&quot;&gt;And more&lt;&#x2F;h2&gt;
&lt;p&gt;Borrow checking helps other classes of errors. For example, it helps improve local reasoning when you&#x27;re writing a function because you can safely assume that any mutable values coming in are disjoint and won&#x27;t interact with each other when you change them.&lt;&#x2F;p&gt;
&lt;p&gt;This incidentally also opens the door for additional optimizations because the compiler can ensure that values can never be both aliased and mutable, something that is difficult to do in C-based languages with alias analysis.&lt;&#x2F;p&gt;
&lt;p&gt;There&#x27;s more good info about the borrow checker and classes of errors it prevents in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;rustlang&#x2F;status&#x2F;689823725219377152&quot;&gt;&quot;You can&#x27;t spell trust without Rust&quot;&lt;&#x2F;a&gt; if you&#x27;re interested.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;weird-feature-4-rules-are-meant-to-be-broken&quot;&gt;Weird feature #4: rules are meant to be broken&lt;&#x2F;h1&gt;
&lt;p&gt;I&#x27;d argue that one of Rust&#x27;s strongest suits is that it&#x27;s pragmatic. Most of Rust&#x27;s stringent checks can be circumvented using features like &lt;code&gt;unsafe&lt;&#x2F;code&gt;, &lt;code&gt;mem::transmute&lt;&#x2F;code&gt;, and more. That&#x27;s right, don&#x27;t like the borrow-checker for your use case? No problem, turn it off.&lt;&#x2F;p&gt;
&lt;p&gt;Rust is made to be able to express anything you can do in a C-like systems language. The advantage of Rust is that it&#x27;s much easier to start with safe defaults that can be pushed out of the way when needed. It&#x27;s much more difficult to build safety on top of unsafe language features.&lt;&#x2F;p&gt;
&lt;p&gt;While Rust lets you pick and choose, it biases towards not letting you shoot your foot off.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;did-rust-miss-leg-day&quot;&gt;Did Rust miss leg day?&lt;&#x2F;h1&gt;
&lt;p&gt;Speaking of feet, did Rust miss leg day after all? Is it lopsided? Has it been focused on the wrong things?&lt;&#x2F;p&gt;
&lt;p&gt;Rust is getting stronger, and luckily it has enough safeguards in place to know how to go into the squat without pulling its back. This part can&#x27;t be understated. The philosophy behind Rust is one of having good fundamentals. As long as the good fundamentals are there, the language can grow on that foundation.&lt;&#x2F;p&gt;
&lt;p&gt;But you don&#x27;t have to take my word on it. Like any fix for the Blub Paradox, it comes down to programmers picking up Rust and seeing if the kinds of capabilities Rust gives them allows them to express themselves efficiently and in a way that avoids classes of bugs that distract from the problem at hand.&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s natural to think that some features are ornamental when you&#x27;re first coming to them. Time and exposure are the real test.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Special thanks to Yehuda Katz and Jason Turner for reviewing this post and sending me their feedback&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Travel log (Maui)</title>
        <published>2015-12-15T00:00:00+00:00</published>
        <updated>2015-12-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/travel-log-maui/"/>
        <id>https://www.sophiajt.com/travel-log-maui/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/travel-log-maui/">&lt;p&gt;When I left Seattle, I jokingly told my friend &quot;the first country I&#x27;m travelling to is Hawaii&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;&quot;But it is isn&#x27;t a different country,&quot; she replied.&lt;&#x2F;p&gt;
&lt;p&gt;It is.  Oh it is.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;Maui_1.jpg&quot; alt=&quot;Image of Maui from Kula Lodge&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Looking at Maui from the Kula Lodge&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Having travelled around the United States, I can&#x27;t say there are many places even similar to Hawaii.  Or, more precisely, Maui, the island I spent most of my time on this past week.&lt;&#x2F;p&gt;
&lt;p&gt;To start with many of the views look absolutely, totally fake.  Yes, the above picture was my view at lunch one day.  Only after staying in Maui for a week did I start to get used to the fact that driving around the interior of Maui, at any moment you could turn the corner and see another breath-taking view.&lt;&#x2F;p&gt;
&lt;p&gt;I don&#x27;t know if I could get used to it &lt;em&gt;really&lt;&#x2F;em&gt;.  Half my shots of the beach or looking out over the mountain look like they&#x27;re from a postcard.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;Maui_2.jpg&quot; alt=&quot;Image of Kamaole Beach III&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Kamaole Beach III&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Sure, I guess someone might over time get used to the amazing mixture of volcanic rock, perfect beaches, and mountain views rounded out with gorgeous weather.  Add to that easy access to a wide variety of fresh produce and fish, and you have yourself a quite literal slice of paradise.  It became quickly obvious why Hawaii has its reputation.  It is, quite simply, nothing short of amazing.&lt;&#x2F;p&gt;
&lt;p&gt;To give it an even more foreign feel, I was greeted by a number of foods and plants I&#x27;d never heard of before.  Fruit that tastes like cinnamon (complete with a gritty texture), starfruit, and even the plentyful macadamia nuts used in new ways (like in the crust on Mahi Mahi, for example).&lt;&#x2F;p&gt;
&lt;p&gt;Speaking of macadamia nuts...&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;Maui_5.jpg&quot; alt=&quot;Image of Spam-flavored Macademia nuts&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Like I said, a variety of foods.  The plants, too, came in all shapes and sizes.  One of the most striking is the Rainbow Eucalyptus.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;Maui_3.jpg&quot; alt=&quot;Image of Rainbow Eucalyptus&quot; &#x2F;&gt;
&lt;em&gt;Rainbow Eucalyptus at Garden of Eden&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The above picture is from the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;mauigardenofeden.com&#x2F;&quot;&gt;Garden of Eden&lt;&#x2F;a&gt; on the Road to Hana.  Both the Garden and the Road to Hana are well worth exploring.  The Road is a windy affair that takes you around through some of the various micro-climates as you traverse the island.  My friend and I explored it one day, stopping at the Garden of Eden, a nature reserve that contained many cool varieties of plants, including the Rainbow Eucalyptus above.  In addition, many varieties of bamboo, bananas, flowers of various sorts, and starfruit flourish.&lt;&#x2F;p&gt;
&lt;p&gt;But you don&#x27;t really have to go very far in any direction to get the island experience.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;Maui_4.jpg&quot; alt=&quot;Image of Maui Beach&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Maui, as one may expect being a holiday spot for many, is a great reminder to take things a little slower.  Stop and look at the flowers, enjoy the views, soak in the sun, and rest up for whatever adventure might come along tomorrow.  There&#x27;s also a general friendly, caring spirit that people generally strive for called the Aloha Spirit, sharing its name with the famous greeting.  As a sense of goodwill, it carries through the island&#x27;s inhabitants and even into &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.uhcc.hawaii.edu&#x2F;aloha&#x2F;alohaSpirit.php&quot;&gt;governance&lt;&#x2F;a&gt;.  Just as important as soaking in the sun is to soak in some of the Aloha while you&#x27;re there and take it with you.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;Maui_6.jpg&quot; alt=&quot;Image of rocks spelling Aloha&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m looking forward to returning to Hawaii and seeing what else it has to offer.  Like many places, it feels like I just scratched the surface.  What I found was a warm, welcoming place, both in temperature and in vibe.  Highly recommended checking it out.  It&#x27;s well-worth the flight.  Just don&#x27;t rush too much, or you&#x27;ll miss some of the best parts.&lt;&#x2F;p&gt;
&lt;p&gt;Mahalo for reading!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>HandmadeCon 2015</title>
        <published>2015-12-05T00:00:00+00:00</published>
        <updated>2015-12-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/handmadecon-2015/"/>
        <id>https://www.sophiajt.com/handmadecon-2015/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/handmadecon-2015/">&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;handmade1.jpg&quot; alt=&quot;Image of HandmadeCon 2015 Banner&quot; &#x2F;&gt;
&lt;em&gt;HandmadeCon 2015, where even the welcome banner is handmade&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Today, I attended &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;mollyrocket.com&#x2F;news_0002.html&quot;&gt;HandmadeCon 2015&lt;&#x2F;a&gt;. HandmadeCon is the first convention for the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;handmadehero.org&#x2F;&quot;&gt;Handmade Hero&lt;&#x2F;a&gt; project by Casey Muratori, a game industry gun-for-hire who most recently worked on &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;the-witness.net&#x2F;news&#x2F;&quot;&gt;The Witness&lt;&#x2F;a&gt;, the follow-up game for Sophia Blow, the creator of &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;braid-game.com&#x2F;&quot;&gt;Braid&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;key-takeaways&quot;&gt;Key takeaways&lt;&#x2F;h1&gt;
&lt;p&gt;There was a &lt;em&gt;ton&lt;&#x2F;em&gt; of material in the interviews. Enough so that I suspect if two people wrote down their takeaways, they might have wildly different lists. Still, here are the takeaways I had:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Quick iteration is king. Working towards faster turnaround time is going to deeply impact overall quality.&lt;&#x2F;li&gt;
&lt;li&gt;Lock-in fundamental game choices as early as possible. Examples: game controls for platforming, game speed for open-world. These impact how you design levels, and any change may cause you to have to redo levels, puzzles, assets, etc.&lt;&#x2F;li&gt;
&lt;li&gt;To work in the game industry you need to show both self-motivated passion and curiosity. The rest can be learned.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;format&quot;&gt;Format&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;handmade2.jpg&quot; alt=&quot;Image of Casey and Sophia talking&quot; &#x2F;&gt;
&lt;em&gt;Casey (right) interviewing Sophia Blow&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Casey has hand-picked a list of game developers with deep technical experience for the conference. With each developer, he interviewed them about their strengths and would tease out the key points from the discussion, often drilling in to learn more. I hadn&#x27;t heard of some of the people he&#x27;d picked, but I quickly realized he&#x27;d hand-selected each for their specific expertise in gaming, whether controls, code layout, networking, design, or ingenuity.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;tommy-refenes&quot;&gt;Tommy Refenes&lt;&#x2F;h2&gt;
&lt;h2 id=&quot;super-meat-boy&quot;&gt;&lt;em&gt;Super Meat Boy&lt;&#x2F;em&gt;&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;key-quote-s&quot;&gt;Key quote(s)&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&quot;Best way to get the best work out of people is to give people a way to give you the best work&quot;&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;assets-pipeline&quot;&gt;Assets pipeline&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Original asset pipeline used JSFL to output texture files with indexing from the Adobe Flash tools&lt;&#x2F;li&gt;
&lt;li&gt;Now he just works with the SWF directly. He (&lt;em&gt;gasp&lt;&#x2F;em&gt;) read the SWF manuals.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;movement&quot;&gt;Movement&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Spent three months perfecting controls using a square that jumped around the screen&lt;&#x2F;li&gt;
&lt;li&gt;Movement was built on a set of hand-coded equations whose parameters were tweaked until everything felt right. He offhandedly called these &quot;garbage numbers&#x2F;equations&quot;&lt;&#x2F;li&gt;
&lt;li&gt;Rather than being real-world, everything was based on how it played
&lt;ul&gt;
&lt;li&gt;Eg) 200ms of grace time where meat boy sticks to the wall, allowing you to press the other way and then hit the jump button, or vice versa, to initiate a wall jump&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;After the initial controls tuning, they were locked in and did not change for the rest of the development&lt;&#x2F;li&gt;
&lt;li&gt;This allowed level design to build on the controls&lt;&#x2F;li&gt;
&lt;li&gt;Explored things like analog, but ended up going digital. Reasons: never want a &quot;half jump&quot; or a slow acceleration&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;testing&quot;&gt;Testing&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Fans are the best testers&lt;&#x2F;li&gt;
&lt;li&gt;PC is crazy complex, and you&#x27;re bound to bake in some hardware configuration assumptions&lt;&#x2F;li&gt;
&lt;li&gt;He&#x27;s working on crowd-sourced alpha&#x2F;beta testing platform that he can ship builds out to specific testers&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;mike-acton&quot;&gt;Mike Acton&lt;&#x2F;h2&gt;
&lt;h2 id=&quot;insomniac-creators-of-ratchet-and-clank&quot;&gt;&lt;em&gt;Insomniac [creators of Ratchet and Clank]&lt;&#x2F;em&gt;&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;key-quote-s-1&quot;&gt;Key quote(s)&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&quot;Adding stuff to the problem does not make the problem simpler&quot;&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;&quot;Everytime I hear &#x27;I can just optimize at the end&#x27; I want to slap someone&quot;&lt;&#x2F;em&gt; Probably a chain of failures lead to this.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;&quot;Capture and visualize&quot;&lt;&#x2F;em&gt; your data. Actually look at the data. eg) build tools to look at the spacial queries that developers are running.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;reaction-to-tommy&quot;&gt;Reaction to Tommy&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Mike started off with a few reactions to Tommy&#x27;s interview.&lt;&#x2F;li&gt;
&lt;li&gt;Tommy&#x27;s input style isn&#x27;t garbage, it &lt;em&gt;is&lt;&#x2F;em&gt; real and it fits the input of his movements and output of &quot;Tommy smiles&quot;&lt;&#x2F;li&gt;
&lt;li&gt;Doing things that are &quot;real world&quot; may actually just be the wrong answer and move you the wrong direction&lt;&#x2F;li&gt;
&lt;li&gt;He whole-heartedly agreed about locking down controls so you can lock down how levels are made&lt;&#x2F;li&gt;
&lt;li&gt;On a related note: ovement speed, esp in an open-world game, greatly affect how the engine works because of streaming off disk, etc&lt;&#x2F;li&gt;
&lt;li&gt;Read the CPU manuals&lt;&#x2F;li&gt;
&lt;li&gt;BTW, docs are seriously important. Doc your own internal formats, too. This is your key input.&lt;&#x2F;li&gt;
&lt;li&gt;Also, focus on your own problem and your own game. Too many indie devs mimicking other frameworks&#x2F;tools.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;hiring-a-game-developer&quot;&gt;Hiring a game developer&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Main corollary for game developer success: curiosity&lt;&#x2F;li&gt;
&lt;li&gt;Demonstrate what you&#x27;ve done with your own willpower&lt;&#x2F;li&gt;
&lt;li&gt;Learn how to practice, and take practice seriously. Anything else is an excuse. Your career is one of the most important things in your life, up there with family.&lt;&#x2F;li&gt;
&lt;li&gt;Practice with the goal of getting better&#x2F;faster and solving the problem. Throw it away rather than keeping it. If it&#x27;s practice, it&#x27;s not a project. You&#x27;re honing a skill rather than building a thing.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;pat-wyatt&quot;&gt;Pat Wyatt&lt;&#x2F;h2&gt;
&lt;h2 id=&quot;guild-wars-diablo-starcraft-and-more&quot;&gt;&lt;em&gt;Guild Wars, Diablo, StarCraft and more&lt;&#x2F;em&gt;&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;key-quote-s-2&quot;&gt;Key quote(s)&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&quot;Make your iteration speed as fast as you can, because this will determine the quality of your game&quot;&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;early-network-stacks&quot;&gt;Early network stacks&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Synchronized network models where client and server both had game state and were kept in lock-step&lt;&#x2F;li&gt;
&lt;li&gt;Warcraft: RTS are not so twitchy, don&#x27;t need to see effect simultaneously&lt;&#x2F;li&gt;
&lt;li&gt;Eg) 4 network moves per second, and a move is when you&#x27;ve heard from everyone&lt;&#x2F;li&gt;
&lt;li&gt;Starcraft similar to Warcraft&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;diablo-on-battle-net&quot;&gt;Diablo on Battle.Net&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Move from singleplayer to real-time multiplayer&lt;&#x2F;li&gt;
&lt;li&gt;First idea: Synchronized at first, to help prevent cheating&lt;&#x2F;li&gt;
&lt;li&gt;Ideally, network model should be separate from UI data, since one is updated by network, and one by the client, and they may be updated at different times&lt;&#x2F;li&gt;
&lt;li&gt;Problem with synchonized client&#x2F;server: if you don&#x27;t do it perfectly, you diverge and it&#x27;s hard to debug&lt;&#x2F;li&gt;
&lt;li&gt;Diablo written too quickly to do a synchronized version&lt;&#x2F;li&gt;
&lt;li&gt;Solution: &quot;Asynchronous loosely-coupled game&quot;&lt;&#x2F;li&gt;
&lt;li&gt;Each level has a &#x27;master&#x27;, and the master is the consensus driver for world state for that level&lt;&#x2F;li&gt;
&lt;li&gt;Replayable log of state that can be given to a new master if the first one drops out&lt;&#x2F;li&gt;
&lt;li&gt;Game host declares who is master for a given level based on who first entered that level&lt;&#x2F;li&gt;
&lt;li&gt;State change happens in two steps: &quot;I am attempting to pick up the sword&quot; then master plays through all attempts and break ties&lt;&#x2F;li&gt;
&lt;li&gt;DON&#x27;T DO A GAME LIKE THIS. People will cheat.
&lt;ul&gt;
&lt;li&gt;Griefers will take advantage&lt;&#x2F;li&gt;
&lt;li&gt;Ask yourself: &quot;How will people hack this?&quot; &quot;How will people abuse others?&quot;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;guild-wars&quot;&gt;Guild Wars&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;All client&#x2F;server, all TCP&lt;&#x2F;li&gt;
&lt;li&gt;Network functionality split across many servers&lt;&#x2F;li&gt;
&lt;li&gt;File server: handles versions and creates deltas based on what client has available, compresses, and sends update to client for assets in the manifest&lt;&#x2F;li&gt;
&lt;li&gt;Asset ids automatically assigned by perforce full path&lt;&#x2F;li&gt;
&lt;li&gt;File servers were put near users because this helps throughput. Related: tcp window and waiting for ack for each packet&lt;&#x2F;li&gt;
&lt;li&gt;Lobby server: authentication and presence. Arena, instance, etc all controlled through lobby server because you don&#x27;t have a persistent connection. Helps with p2p messages, guild msgs etc, encryption&lt;&#x2F;li&gt;
&lt;li&gt;Matchmaking server: will match up servers with capacity with needs of user&lt;&#x2F;li&gt;
&lt;li&gt;Using tons of servers allows you scale up and distribute across machines&lt;&#x2F;li&gt;
&lt;li&gt;Network code is shared across all servers. Every server is actually a generic modular server. It just hotloads the specific module. eg) lobby server just loads the lobby module&lt;&#x2F;li&gt;
&lt;li&gt;Need RPC protocol that supports versioning. These days, things like &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;developers.google.com&#x2F;protocol-buffers&#x2F;?hl=en&quot;&gt;protocol buffers&lt;&#x2F;a&gt; would work fine.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;udp-vs-tcp&quot;&gt;UDP vs TCP&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Mobile - UDP works great, since you&#x27;re already going to be losing packets&lt;&#x2F;li&gt;
&lt;li&gt;MMO - TCP is great because you don&#x27;t want to lose packets&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;network-game-states&quot;&gt;Network game states&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Failure is always legal. Eg) can&#x27;t load model file, you don&#x27;t crash. Instead you get a white box&lt;&#x2F;li&gt;
&lt;li&gt;Server is authoritative and may pull players back to acceptable state. Also, every client sees their version of the server truth, like the arrow that &quot;bends in space&quot; because target moved&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;best-practices&quot;&gt;Best practices&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Always simulate network jitter and latency, minimum 200ms, so you are always creating robust networking code&lt;&#x2F;li&gt;
&lt;li&gt;You will always be hacked
&lt;ul&gt;
&lt;li&gt;Deeply understand your interaction model&lt;&#x2F;li&gt;
&lt;li&gt;Rate limiting helps prevent abuse&lt;&#x2F;li&gt;
&lt;li&gt;Hiding IP addresses so they can&#x27;t be targetted for attacks like DDOS&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;hiring-a-game-developer-1&quot;&gt;Hiring a game developer&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Demonstrate passion&lt;&#x2F;li&gt;
&lt;li&gt;Read &quot;cracking the coding interview&quot;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;sophia-blow&quot;&gt;Sophia Blow&lt;&#x2F;h2&gt;
&lt;h2 id=&quot;braid-the-witness&quot;&gt;&lt;em&gt;Braid, The Witness&lt;&#x2F;em&gt;&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Iteration is king. More you optimize the less you can modify.&lt;&#x2F;li&gt;
&lt;li&gt;Programming for fungibility to allow for faster iteration.&lt;&#x2F;li&gt;
&lt;li&gt;Program for a decoupled system, as much as possible. This includes game mechanics, types of puzzles, etc&lt;&#x2F;li&gt;
&lt;li&gt;Doing programming as a game designer, you can more closely point the best way forward in the game design as you know exactly what&#x27;s possible&lt;&#x2F;li&gt;
&lt;li&gt;Programming as a designer also helps you explore more of the design space than you might otherwise have. Eg) in Braid the enemies unaffected by your time travel.&lt;&#x2F;li&gt;
&lt;li&gt;Good design can often be a search space with a seed value and things that seem like time wasted, but that&#x27;s part of the journey.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;ron-gilbert&quot;&gt;Ron Gilbert&lt;&#x2F;h2&gt;
&lt;h2 id=&quot;secret-of-monkey-island-creator-of-scumm&quot;&gt;&lt;em&gt;Secret of Monkey Island, creator of SCUMM&lt;&#x2F;em&gt;&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;For Maniac Mansion, C64 was hooked to a Unix&#x2F;Vax machine with hotloading to C64. This is how they could swap out and do fast iterations&lt;&#x2F;li&gt;
&lt;li&gt;To learn how to do an interpreter, he banked out BASIC ROM to RAM and then manipulated it. Cool hack.&lt;&#x2F;li&gt;
&lt;li&gt;For pathfinding, used dijkstra&#x27;s algorithm with rectangle shapes. This evolved over time.&lt;&#x2F;li&gt;
&lt;li&gt;Later games used seamlessly stiched-together soundtracks that changed as the player progressed.&lt;&#x2F;li&gt;
&lt;li&gt;Cutscenes, which came from Lucasfilm games, were originally hand-scripted. They had to &quot;cheat&quot; a little so the player couldn&#x27;t interrupt the cutscene with their own movement. Eg) Making the character the player was following appear far enough ahead of the player so that the player couldn&#x27;t run in front and interrupt animation&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Travel log (Blacksburg)</title>
        <published>2015-12-03T00:00:00+00:00</published>
        <updated>2015-12-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/travel-log-blacksburg/"/>
        <id>https://www.sophiajt.com/travel-log-blacksburg/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/travel-log-blacksburg/">&lt;p&gt;This is the first of posts detailing my current trip, which will take me around southwest Virginia, Seattle, Hawaii, Australia, New Zealand, Hong Kong, and Japan.&lt;&#x2F;p&gt;
&lt;p&gt;My first stop was Blacksburg, home of Virginia Tech.  I lived in Blacksburg from 1996 - 2009, so it was both familiar and a little alien, as it hasn&#x27;t stood still since I&#x27;ve been gone.  Still, a great time to reconnect with friends that I haven&#x27;t seen in years.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;virginia-tech&quot;&gt;Virginia Tech&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;library_bridge.jpg&quot; alt=&quot;Image of Virginia Tech&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Torgersen Hall at Virginia Tech&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It was nice to take a stroll around campus and see all the familiar buildings.  Even new building felt familiar with the use of Hokie Stone, a distinctive limestone taken from the local quarries.&lt;&#x2F;p&gt;
&lt;p&gt;The students were just coming back from Thanksgiving break, so when I first got here there were very few people around, giving it a ghost town feeling.  Not in a bad way, though.  I found it peaceful and quiet.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;war_memorial.jpg&quot; alt=&quot;Image of War Memorial Chapel&quot; &#x2F;&gt;
&lt;em&gt;War Memorial Chapel&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;When you&#x27;re walking around the Tech campus, you can&#x27;t help but notice the Burruss Hall building.  It&#x27;s a giant building that is both familiar and imposing.  If you&#x27;ve seen any brochures about Virginia Tech, it&#x27;s likely you&#x27;ve already seen it.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;burruss_close.jpg&quot; alt=&quot;Image of Burruss Hall close-up&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Staring up at Burruss Hall&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If you step back from Burruss Hall and look down, you&#x27;ll notice a ring of stones.  This is the memorial for those killed in the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Virginia_Tech_shooting&quot;&gt;shootings on April 16, 2007&lt;&#x2F;a&gt;.  Each stone has a name of someone who was killed that day.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;stones.jpg&quot; alt=&quot;Image of stone in the Virginia Tech shooting memorial&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Rather than feeling overtly sad, the memorial feels more like a place to recognize and pay respect to the lost while at the same time giving the living space to move on and go about their lives.  Still, the losses are felt, and the lost remembered.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;memorial_note.jpg&quot; alt=&quot;Image of note for shooting victim&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;blacksburg&quot;&gt;Blacksburg&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;looking_at_blacksburg.jpg&quot; alt=&quot;Image of Blacksburg&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Look out at Blackburg from the Virginia Tech library&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Virginia Tech is surrounded by the town of Blacksburg.  It&#x27;s a fairly small affair, nestled into the hills of Virginia.  Downtown Blacksburg is only a few streets wide, with a few dozen restaurants and shops packed together before the streets stretch into the neighboring residential areas.&lt;&#x2F;p&gt;
&lt;p&gt;Because of its relatively small size, the student population inevitably develops a fondness for certain restaurants.  Some of these became institutions that would go on to serve each new batch of students.  One such institution is the Bollo&#x27;s cafe and bakery.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;bollos.jpg&quot; alt=&quot;Image of Bollo&amp;#39;s coffeeshop with dog&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Bollo&#x27;s, a Blacksburg institution (with photogenic dog)&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It was good to see that it&#x27;s still around.  As an undergrad student at Virginia Tech, I spent many a night here laughing with friends, going on dates, playing games, and drinking the strongest coffee I&#x27;d ever had.  Sorry Seattle, you weren&#x27;t my first latte.&lt;&#x2F;p&gt;
&lt;p&gt;Speaking of Seattle, which is currently being swallowed by the efficient apartment complex, Blacksburg still has lots of great houses in prime locations.  The house I&#x27;m staying in is rich with character, created sometime in the early 1900s.  Its heating has been modernized, but it still has the history intact.  In the basement is a shower for the field workers to wash off.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;shower.jpg&quot; alt=&quot;Image of old timey shower in the basement&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It was great to see my Blacksburg friends again.  It felt like taking a slow bath in the familiar before rising to walk off to the unknown.  A perfect way to start the trip.  I can&#x27;t wait to see what adventures lie ahead.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Building a simple JIT in Rust</title>
        <published>2015-12-01T00:00:00+00:00</published>
        <updated>2015-12-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/building-a-simple-jit-in-rust/"/>
        <id>https://www.sophiajt.com/building-a-simple-jit-in-rust/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/building-a-simple-jit-in-rust/">&lt;p&gt;The other day I threw together a simple Just-In-Time compiler (or JIT, for short), and I thought it&#x27;d be fun to show the steps I did. With this, it should be possible to create a page of executable memory, write some machine code into it, and then treat it like a function call from Rust.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s get started! You can grab my &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sophiajt&#x2F;rustyjit&quot;&gt;JIT project&lt;&#x2F;a&gt;, if you want to follow along. I&#x27;ve only tested this in OS X, but it should adaptable for other platforms.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Updated 12&#x2F;2&#x2F;2015:&lt;&#x2F;strong&gt; Thanks to some reader comments, I&#x27;ve updated the code below to not use malloc and instead use posix_memalign directly as the allocation step, which avoids leaking memory.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;creating-executable-memory&quot;&gt;Creating executable memory&lt;&#x2F;h1&gt;
&lt;p&gt;For our JIT, we&#x27;ll need to first allocate the memory that will hold our JIT&#x27;ted code. The most important thing here is to create a block of memory that&#x27;s executable so that we can later jump into it, run code, and then return back out.&lt;&#x2F;p&gt;
&lt;p&gt;To do this, we need a few functions from the standard C library, which we can access through the &lt;code&gt;libc&lt;&#x2F;code&gt; external module.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;&#x2F;&#x2F; added to Cargo.toml
[dependencies]
libc = &amp;quot;0.2.2&amp;quot;

&#x2F;&#x2F; main.rs
extern crate libc;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Once we&#x27;ve pulled in libc, we need to allocated memory. Not just any memory, we need to allocate &lt;em&gt;aligned&lt;&#x2F;em&gt; memory. Some operating systems, like OS X, require that executable code memory starts at a particular alignment. For example, that the address is exactly a multiple of 0x1000.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;const PAGE_SIZE: usize = 4096;
&#x2F;&#x2F; ...
unsafe {
  let mut page : *mut libc::c_void = mem::uninitialized();
  libc::posix_memalign(&amp;amp;mut page, PAGE_SIZE, size);
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Once allocated, we now have memory we can safely jump to. Well, almost. Before we can run code in our newly-allocated memory, we need to enable executing code in this area of memory.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;unsafe {
  libc::mprotect(page, size, libc::PROT_EXEC | libc::PROT_READ | libc::PROT_WRITE);
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now we&#x27;re ready. We have something we can write into and then jump into. Since running JIT code is basically &quot;no man&#x27;s land&quot; without any safeguards, it&#x27;s easy to get yourself in trouble. One step that I add is to also fill the memory block with the &lt;code&gt;RET&lt;&#x2F;code&gt; instruction, which will let us return from our function even if we happen to accidentally run other memory in the block.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;extern {
    fn memset(s: *mut libc::c_void, c: libc::uint32_t, n: libc::size_t) -&amp;gt; *mut libc::c_void;
}
&#x2F;&#x2F; ...
unsafe {
  memset(page, 0xc3, size);  &#x2F;&#x2F; prepopulate with &amp;#39;RET&amp;#39; calls (0xc3)
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We&#x27;ve allocated our JIT memory, aligned it, set it as executable, and then filled it with the &lt;code&gt;RET&lt;&#x2F;code&gt; instruction. We&#x27;re ready to write some code into it.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Note:&lt;&#x2F;em&gt; You&#x27;ll notice we don&#x27;t explicitly call &lt;code&gt;libc::free()&lt;&#x2F;code&gt; after we allocate. For simplicity, we treat the JIT&#x27;ed functions we create as long-lived, but a full-blown JIT would likely use better memory hygiene.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;getting-ready-to-write-our-first-program&quot;&gt;Getting ready to write our first program&lt;&#x2F;h1&gt;
&lt;p&gt;To write our first JIT program, let&#x27;s first make a way to more easily work with our memory. In its current state, it&#x27;s a raw C void* pointer, but this is a bit unweildy as we don&#x27;t have a lot of support to work with that in Rust. To make something that feels more natural, we&#x27;ll create a new struct type that will hold our pointer and allow us to create indexing functions for easier access. This will let us access the memory like &lt;code&gt;m[0] = 0x10&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s create the struct we&#x27;ll use:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;use std::mem;

struct JitMemory {
    contents : *mut u8
}

fn alloc() -&amp;gt; JitMemory {
  let contents: mut* u8;
  unsafe {
    &#x2F;&#x2F;note: allocate &amp;#39;page&amp;#39; as before

    &#x2F;&#x2F;then, transmute
    contents = mem::transmute(page);
  }

  JitMemory { contents: contents }
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We&#x27;ve got the JitMemory struct which will hold the memory we&#x27;ve allocated, and we use the &lt;code&gt;mem::transmute&lt;&#x2F;code&gt; call to convert our raw void pointer to a raw u8 pointer, which will be easier to work with in our next step.&lt;&#x2F;p&gt;
&lt;p&gt;Now that we have the struct, let&#x27;s create some indexing functions.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;use std::ops::{Index, IndexMut};

impl Index&amp;lt;usize&amp;gt; for JitMemory {
    type Output = u8;

    fn index(&amp;amp;self, _index: usize) -&amp;gt; &amp;amp;u8 {
        unsafe {&amp;amp;*self.contents.offset(_index as isize) }
    }
}

impl IndexMut&amp;lt;usize&amp;gt; for JitMemory {
    fn index_mut(&amp;amp;mut self, _index: usize) -&amp;gt; &amp;amp;mut u8 {
        unsafe {&amp;amp;mut *self.contents.offset(_index as isize) }
    }
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;With these in place, we can now more easily write instructions into memory. Before we do, let&#x27;s put everything we&#x27;d done so far into a constructor for our struct:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;impl JitMemory {
  fn new(num_pages: usize) -&amp;gt; JitMemory {
    let contents : *mut u8;
    unsafe {
      let size = num_pages * PAGE_SIZE;
      let mut _contents : *mut libc::c_void = mem::uninitialized(); &#x2F;&#x2F; avoid uninitalized warning
      libc::posix_memalign(&amp;amp;mut _contents, PAGE_SIZE, size);
      libc::mprotect(_contents, size, libc::PROT_EXEC | libc::PROT_READ | libc::PROT_WRITE);

      memset(_contents, 0xc3, size);  &#x2F;&#x2F; for now, prepopulate with &amp;#39;RET&amp;#39;

      contents = mem::transmute(_contents);
    }

    JitMemory { contents: contents }
  }
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;writing-our-first-jit-program&quot;&gt;Writing our first JIT program&lt;&#x2F;h1&gt;
&lt;p&gt;With our new constructor and indexing functions in place, we can write our first JIT program. The simplest &quot;hello world&quot; that I use when doing JIT is a function that takes no parameters and returns a simple value.&lt;&#x2F;p&gt;
&lt;p&gt;We can do this with two assembly instructions:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;MOV RAX, 0x3  ; move our return value (0x3) into RAX,
              ; the register in x64 used for return values
RET           ; return from the function call
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Great, now we just need to write this program into our JIT memory. But wait, we don&#x27;t have an assembler :)&lt;&#x2F;p&gt;
&lt;p&gt;Not to fear, there are plenty of assemblers to get us started. There are even &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;defuse.ca&#x2F;online-x86-assembler.htm&quot;&gt;online assemblers&lt;&#x2F;a&gt; you can use. Let&#x27;s plug the first line &lt;code&gt;MOV RAX, 0x3&lt;&#x2F;code&gt; into our online assembler.&lt;&#x2F;p&gt;
&lt;p&gt;The top line of the result is the raw hex. This is what we want. These are the actual bits we&#x27;ll be writing into memory for our function: 48C7C003000000&lt;&#x2F;p&gt;
&lt;p&gt;With these bytes, and the RET instruction we already filled our memory with, we now have our full function. We can use our indexing functions to write this out:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;let mut jit : JitMemory = JitMemory::new(1);  &#x2F;&#x2F; allocate a page of memory

jit[0] = 0x48;  &#x2F;&#x2F; mov RAX, 0x3
jit[1] = 0xc7;
jit[2] = 0xc0;
jit[3] = 0x03;
jit[4] = 0x00;
jit[5] = 0x00;
jit[6] = 0x00;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;turning-our-memory-into-a-function&quot;&gt;Turning our memory into a function&lt;&#x2F;h1&gt;
&lt;p&gt;We have an executable block of memory with the code for our function filled in. The last step is to turn this into a Rust function we can call. We do this by doing another mem::transmute:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;fn run_jit() -&amp;gt; (fn() -&amp;gt; i64) {
  let mut jit : JitMemory = JitMemory::new(1);

  jit[0] = 0x48;  &#x2F;&#x2F; mov RAX, 0x3
  jit[1] = 0xc7;
  jit[2] = 0xc0;
  jit[3] = 0x03;
  jit[4] = 0x00;
  jit[5] = 0x00;
  jit[6] = 0x00;

  unsafe { mem::transmute(jit.contents) }
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And with that, after a few handfuls of unsafe calls and transmutes, we have our function. The only thing left is to call it:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;fn main() {
  let fun = run_jit();
  println!(&amp;quot;{}&amp;quot;, fun());
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;debugging&quot;&gt;Debugging&lt;&#x2F;h1&gt;
&lt;p&gt;When working with a JIT, it&#x27;s inevitable at some point something will go wrong, and we&#x27;ll need to dive into the debugger. Luckily, Rust works with LLDB out of the box.&lt;&#x2F;p&gt;
&lt;p&gt;Here are some helpful LLDB commands to get you started:&lt;&#x2F;p&gt;
&lt;p&gt;Start the JIT in LLDB:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;lldb target&#x2F;debug&#x2F;rustyjit&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Set a breakpoint for the line that contains the call into our JIT code:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;&amp;gt; br set -line 64&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Run to our breakpoint:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;&amp;gt; run&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Now that we&#x27;re about to run our JIT code, there are a few things we can do.&lt;&#x2F;p&gt;
&lt;p&gt;The first one is to verify the address of our code:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;&amp;gt; p fun&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Unfortunately, that&#x27;s not the most helpful thing in the world. What we often want is look at the memory behind the function:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;&amp;gt; mem read fun&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This gives us back something like this:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;0x100804000: 48 c7 c0 03 00 00 00 c3 c3 c3 c3 c3 c3 c3 c3 c3  H??....?????????
0x100804010: c3 c3 c3 c3 c3 c3 c3 c3 c3 c3 c3 c3 c3 c3 c3 c3  ????????????????
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;That&#x27;s better. Now we can see if the bytes we expect to be there are in fact there. If we wanted, we could update memory using &lt;code&gt;mem write&lt;&#x2F;code&gt; if something was out of place.&lt;&#x2F;p&gt;
&lt;p&gt;We can also use the built in disassembler to read back out what the asm instructions are for our function:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;&amp;gt; dis -A x64 -s fun&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Finally, we can continue with the program:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;&amp;gt; cont&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;lots-ahead&quot;&gt;Lots ahead&lt;&#x2F;h1&gt;
&lt;p&gt;Now that we have a tiny JIT and a way to debug it, the sky is the limit. Turning source code into machine code is the heart of any compiler, and with these few additional steps that compiler could be made to output code that we can run directly.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Porting a C# NES emulator to Rust</title>
        <published>2015-11-20T00:00:00+00:00</published>
        <updated>2015-11-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/porting-csharp-nes-emu-to-rust/"/>
        <id>https://www.sophiajt.com/porting-csharp-nes-emu-to-rust/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/porting-csharp-nes-emu-to-rust/">&lt;p&gt;Many years ago, I created a &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;jturner.tapetrade.net&#x2F;sharpnes&#x2F;index.html&quot;&gt;simple NES emulator in C#&lt;&#x2F;a&gt; using SDL and Mono. For fun, I wanted to see what it would be like to port that emulator to Rust. A couple weeks later, after poking on it on and off between packing for a move, I was able to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sophiajt&#x2F;rustynes&quot;&gt;get it working&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;http:&#x2F;&#x2F;www.sophiajt.com&#x2F;images&#x2F;smb1.png&quot; alt=&quot;Image of Super Mario Bros 1 on emulator&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;what-i-did&quot;&gt;What I did&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;loading-a-binary-file&quot;&gt;Loading a binary file&lt;&#x2F;h2&gt;
&lt;p&gt;Loading the types of files commonly used in emulators requires us to work with binary files. To do so, we need a way of loading the raw data both as just plain bytes and also as numbers. Rust, by default, comes with a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;std&#x2F;fs&#x2F;struct.File.html&quot;&gt;fairly slim API&lt;&#x2F;a&gt; for dealing with binary data. No matter, Rust is also very flexible and allows you to build on additional parts to the API to suit your needs.&lt;&#x2F;p&gt;
&lt;p&gt;I started there, and built out a few functions that would let me read in the numbers from the file both using big-endian and little-endian.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;pub trait BitReader {
    fn read_u32_be(&amp;amp;mut self) -&amp;gt; Result&amp;lt;u32, io::Error&amp;gt;;
    fn read_u32_le(&amp;amp;mut self) -&amp;gt; Result&amp;lt;u32, io::Error&amp;gt;;
}
impl BitReader for File {
    fn read_u32_be(&amp;amp;mut self) -&amp;gt; Result&amp;lt;u32, io::Error&amp;gt; {
        let mut buffer = [0; 4];

        try!(self.read(&amp;amp;mut buffer));

        Ok(buffer[3] as u32 + ((buffer[2] as u32) &amp;lt;&amp;lt; 8) +
            ((buffer[1] as u32) &amp;lt;&amp;lt; 16) + ((buffer[0] as u32) &amp;lt;&amp;lt; 24))
    }
    fn read_u32_le(&amp;amp;mut self) -&amp;gt; Result&amp;lt;u32, io::Error&amp;gt; {
        let mut buffer = [0; 4];

        try!(self.read(&amp;amp;mut buffer));

        Ok(buffer[0] as u32 + ((buffer[1] as u32) &amp;lt;&amp;lt; 8) +
            ((buffer[2] as u32) &amp;lt;&amp;lt; 16) + ((buffer[3] as u32) &amp;lt;&amp;lt; 24))
    }
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Once I had the trait, I could import it where I wanted to use these extra read capabilities on File.&lt;&#x2F;p&gt;
&lt;p&gt;With these extra methods in place, I could plow through the binary file loading with a mix of the File read functionality and the BitReader trait.&lt;&#x2F;p&gt;
&lt;p&gt;I did notice I used the odd concoction &lt;code&gt;buffer.iter().cloned().collect()&lt;&#x2F;code&gt; to convert from an array to a Vec of the same contained type:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;for _ in 0..(num_prg_pages*4) {
    let mut buffer = [0; 4096];
    try!(f.read(&amp;amp;mut buffer));
    prg_rom.push(buffer.iter().cloned().collect());
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;There may be a more Rust-native way of doing it. Personally, I think it&#x27;d be nice to be able to read directly into a Vec, so you could elide that step.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;side-by-side-porting&quot;&gt;Side-by-side porting&lt;&#x2F;h2&gt;
&lt;p&gt;One of the first things I did after I had file loading in place was to start porting over the CPU emulation. Because I wanted the code to be fairy clean, I opted to not do a literal port. Instead, I opened two separate editor windows: one for the original C# source, and one for the new Rust source. Tedious, but I hoped that a port focused on what would fit better with Rust would be less error-prone.&lt;&#x2F;p&gt;
&lt;p&gt;There&#x27;s another reason not to do copy&#x2F;pasting of code when porting: too many little things needed to be changed to the Rust style. For example, Rust-friendly names often differ from the C# equivalent (eg the ReadChrRom method would need to be read_chr_rom to match Rust naming conventions). Like-wise, little things that help readability in Rust, like the &quot;no parens around if guards&quot; means that copy&#x2F;pasted code would need to be touched up. All told, a minor frustration, but it gave ample time to make the code look a bit cleaner in the transfer so likely a net win.&lt;&#x2F;p&gt;
&lt;p&gt;Feeling more comfortable with Rust&#x27;s use of expressions, I could write code in a more dense way. For example, here is some code from the ROR or Rotate Right opcode in C#:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;csharp&quot;&gt;if ((valueholder &amp;amp; 0x1) == 0x1)
	bitholder = 1;
else
	bitholder = 0;

valueholder = (byte)(valueholder &amp;gt;&amp;gt; 1);

if (carry_flag == 1)
	valueholder = (byte)(valueholder | 0x80);

carry_flag = bitholder;

if ((valueholder &amp;amp; 0xff) == 0x0)
	zero_flag = 1;
else
	zero_flag = 0;

if ((valueholder &amp;amp; 0x80) == 0x80)
	sign_flag = 1;
else
	sign_flag = 0;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;and here&#x27;s what it became in Rust:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;let bit = (value &amp;amp; 0x1) == 0x1;
value = (value &amp;gt;&amp;gt; 1) &amp;amp; 0x7f;
value += if self.carry {0x80} else {0};
self.carry = bit;
self.zero = value == 0;
self.sign = (value &amp;amp; 0x80) == 0x80;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Some of these changes could have been done in the original C#, but I didn&#x27;t notice them at the time. Still, I think the result Rust is still pretty readable, even though it&#x27;s more compact.&lt;&#x2F;p&gt;
&lt;p&gt;While we&#x27;re talking about bit rotation, one of the annoyances I experienced working on bit manipulation code is that Rust is more vigilant about overflow checking. In hindsight, this is actually a good thing, but coming from languages like C# and JavaScript that are less vigilant, it was a bit of a headache to adjust to. I ended up doing some of my own bit masks so I didn&#x27;t have to worry about it, but I noticed that they&#x27;ve added a number of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;brson&#x2F;rust&#x2F;blob&#x2F;relnotes&#x2F;RELEASES.md#libraries&quot;&gt;&quot;wrapping&quot; operations in Rust 1.4&lt;&#x2F;a&gt; that allow you to work around the overflow checks.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;hitting-the-first-ownership-error&quot;&gt;Hitting the first ownership error&lt;&#x2F;h2&gt;
&lt;p&gt;A few days into the port, I hit my first ownership error. Here&#x27;s a quick rundown of the NES, so you can see why that might be so:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;CPU: The CPU :)&lt;&#x2F;li&gt;
&lt;li&gt;PPU: The NES&#x27;s graphics unit&lt;&#x2F;li&gt;
&lt;li&gt;MMU: Not technically not called the MMU, but let&#x27;s call it an MMU for our purposes&lt;&#x2F;li&gt;
&lt;li&gt;Cart: The program to run&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Now that we have the parts, here&#x27;s how they talk to each other:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;CPU asks the MMU for an instruction, and the CPU may also write back to memory&lt;&#x2F;li&gt;
&lt;li&gt;PPU reads memory from the Cart, and can also transfer memory from MMU to graphics memory&lt;&#x2F;li&gt;
&lt;li&gt;MMU needs to read information from the Cart and can also read and write from the PPU&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;All the subsystems, in essence, need to be able to talk to each other at some level. Which is exactly how I set up the C# project. Singleton objects with references to each other. When I ported over to TypeScript a few years ago, similar idea.&lt;&#x2F;p&gt;
&lt;p&gt;But in Rust, ownership needs to be clear. If you call a method, you can&#x27;t also pass something you own to that method, like so:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;foo.x.y(foo.x.z)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The net result is that I went back to the drawing board and thought long and hard about what was &lt;em&gt;actually&lt;&#x2F;em&gt; necessary for each component. After a couple of refactorings, I think I landed on a solution that&#x27;s both cleaner and clearer. Every object has one owner, and I don&#x27;t do any ref cells or ref counting.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;deriving-debug&quot;&gt;Deriving debug&lt;&#x2F;h2&gt;
&lt;p&gt;There are a few tricks that I loved in Haskell that I wished other languages would pick up. One of them is the ability to automatically be able to print out objects for you.&lt;&#x2F;p&gt;
&lt;p&gt;In Rust, you can do this using the &#x27;derive&#x27; command:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;#[derive(Debug)]
struct Foo {
  x: u32
}
&#x2F;&#x2F;...

let foo = Foo { x: 10 }
println!(&amp;quot;{:?}&amp;quot;, foo);
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;By deriving Debug, you have the ability to output a debug format of that structure, which is output using {:?}.&lt;&#x2F;p&gt;
&lt;p&gt;This is very handy to help bootstrap a project, when you quickly want to look at the contents of what is working so far. After a while, I found I ended up removing these helpers and putting in my own, customized implementations.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sdl&quot;&gt;SDL&lt;&#x2F;h2&gt;
&lt;p&gt;Using SDL was dead simple. I used the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;AngryLawyer&#x2F;rust-sdl2&quot;&gt;SDL2 Rust bindings&lt;&#x2F;a&gt;. After a few tries to follow the directions to install SDL2 carefully, I had it working in both Windows and OS X. After it&#x27;s installed, the bindings &quot;just work&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;d never used SDL2 before, but after looking through the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;AngryLawyer&#x2F;rust-sdl2&#x2F;tree&#x2F;master&#x2F;examples&quot;&gt;examples directory&lt;&#x2F;a&gt;, especially the texture sample, I was good to go.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;what-i-didn-t-do&quot;&gt;What I didn&#x27;t do&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;chase-crashing-bugs&quot;&gt;Chase crashing bugs&lt;&#x2F;h2&gt;
&lt;p&gt;After wrestling a few ownership errors, I largely spent my time on correctness. I ended up having a few hard-to-find issues where I flipped the boolean logic on a check or discovering I forgot to implement a piece of the machine that was required. After many hours pouring over the code side by side, or looking at the output log, I finally managed to get the outputs similar.&lt;&#x2F;p&gt;
&lt;p&gt;Just as in the C# and JavaScript versions of the emulator, I didn&#x27;t worry about any crashes. A few times I had an arithmetic overflow or error accessing a vector out of bounds, but those were easy to fix.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;optimize&quot;&gt;Optimize&lt;&#x2F;h2&gt;
&lt;p&gt;After I got the emulator working, I let it rip. The result was something unplayably fast. Not bad for a first try.&lt;&#x2F;p&gt;
&lt;p&gt;In hindsight, this isn&#x27;t too surprising. The CPU gets to work directly with the MMU. Ditto with the MMU and the PPU. The systems can call functions in each other without any abstraction, VM, or GC. By default, the core structs sit on the stack.&lt;&#x2F;p&gt;
&lt;p&gt;Using Rust had nudged me into doing what would have made sense for a decent C-based approach, without the risks. Of course, it&#x27;s not like Rust prevents you from adding in a hefty abstraction layer, but the defaults seem to push you in the right direction.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;unit-test&quot;&gt;Unit test&lt;&#x2F;h2&gt;
&lt;p&gt;For this to feel like a real Rust project, though, it needs some tests. I asked &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;pcwalton&quot;&gt;Patrick Walton&lt;&#x2F;a&gt;, the author of probably the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;pcwalton&#x2F;sprocketnes&quot;&gt;first NES emulator for Rust&lt;&#x2F;a&gt;, about testing emulators with Rust unit tests, but he didn&#x27;t use them for his project either.&lt;&#x2F;p&gt;
&lt;p&gt;Still, I suspect there&#x27;s a way of creating fairly testable, and still performant, parts of the emulator. For example, opcodes could each have their own unit test if there was a way, possibly with traits, to decouple them from working so closely with the MMU.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;add-audio-support&quot;&gt;Add audio support&lt;&#x2F;h2&gt;
&lt;p&gt;In Patrick&#x27;s &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;air.mozilla.org&#x2F;sprocketnes-practical-systems-programming-in-rust&#x2F;&quot;&gt;video about his emulator&lt;&#x2F;a&gt;, he mentions that he took it on to show that Rust can do real-time processing. For an emulator, that means that the audio is emulated properly and sounds correct. I haven&#x27;t added any audio support, but it would be a fun project at some point.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;precisely-emulate-the-machine&quot;&gt;Precisely emulate the machine&lt;&#x2F;h2&gt;
&lt;p&gt;The never-ending rabbit hole for any emulation project is to see just how precisely you can emulate the hardware. There&#x27;s plenty of work here.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;what-i-ve-learned&quot;&gt;What I&#x27;ve learned&lt;&#x2F;h1&gt;
&lt;p&gt;I&#x27;m getting a little more comfortable with Rust. Thinking through an ownership refactoring can still take a while, but it&#x27;s starting to feel like the hurdle you take on so that you can worry less about safety and performance. I still have a ways to go before it becomes second nature.&lt;&#x2F;p&gt;
&lt;p&gt;Cargo shines again, and the SDL bindings were easy to put in place and worked as expected. No complaints there.&lt;&#x2F;p&gt;
&lt;p&gt;Feels like I&#x27;m still scratching the surface. There are likely some slick spots to use traits and macros to cut down on the redundancy and coupling, repectively. But I&#x27;m happy with the progress.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Steam Machines enter the market</title>
        <published>2015-11-11T00:00:00+00:00</published>
        <updated>2015-11-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/steam-machines/"/>
        <id>https://www.sophiajt.com/steam-machines/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/steam-machines/">&lt;p&gt;This week marks the release of the first official &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;store.steampowered.com&#x2F;hardware&quot;&gt;Steam Machines&lt;&#x2F;a&gt;. For the last five months, I&#x27;ve been a proud owner of the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.alienware.com&#x2F;landings&#x2F;alpha&#x2F;&quot;&gt;Alienware Alpha&lt;&#x2F;a&gt;, one of the three Steam Machine types now available. Knowing what could be possible, I&#x27;ve been curiously awaiting the official launch.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;the-plan&quot;&gt;The plan&lt;&#x2F;h1&gt;
&lt;p&gt;Valve&#x27;s motivation for creating the Steam Machine seems pretty straight forward: move to the TV and compete more directly with game consoles. Currently, that space is shared by the big three: Sony, Microsoft, and Nintendo. Why not make that the big four instead, with Valve in the mix?&lt;&#x2F;p&gt;
&lt;p&gt;To get there, Valve has started with three initial devices.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;http:&#x2F;&#x2F;cdn.akamai.steamstatic.com&#x2F;steam&#x2F;apps&#x2F;353370&#x2F;header.jpg?t=1447180995&quot; alt=&quot;Image of Steam Controller&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The Steam Controller is a gamepad with two round touchpads and a set of traditional gamepad buttons. It can be configured to work as a normal gamepad for games with gamepad support. Alternatively, the touchpads can be used just as touchpads to play games that work with a mouse instead of gamepad.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;http:&#x2F;&#x2F;cdn.akamai.steamstatic.com&#x2F;steam&#x2F;apps&#x2F;353380&#x2F;header.jpg?t=1447183971&quot; alt=&quot;Image of Steam Link&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The Steam Link is something of a gaming bridge between the PC and your TV, allowing you to stream games from your PC over to your TV. At around $50, it&#x27;s pretty inexpensive.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;http:&#x2F;&#x2F;cdn.akamai.steamstatic.com&#x2F;steam&#x2F;apps&#x2F;353390&#x2F;header.jpg?t=1447197276&quot; alt=&quot;Image of Steam Machine&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Alienware Steam Machine&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Lastly, the Steam Machine. The Steam Machine itself isn&#x27;t actually a thing. Rather, it&#x27;s a PC specification that hardware vendors can build to. Out of the gate, three hardware vendors have already produced a Steam Machine: Alienware (pictured above), Zotac, and Syber. Steam Machines also come with a new operating system called &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;store.steampowered.com&#x2F;steamos&#x2F;&quot;&gt;SteamOS&lt;&#x2F;a&gt;, a form of Linux that&#x27;s been optimized for gaming.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;the-right-plan&quot;&gt;The right plan?&lt;&#x2F;h1&gt;
&lt;p&gt;Now that we know the plan, is that plan the right plan? Specifically, does the Steam Machine have a home?&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s clear to me that a device like the Steam Machine has value in the market. It&#x27;s smaller than a gaming console, more flexible, and just as powerful. I&#x27;ve spent countless hours gaming, reading news, watching movies, and even programming on mine. I&#x27;ve even stopped using my Playstation 4, opting instead to do all my gaming on the Alpha.&lt;&#x2F;p&gt;
&lt;p&gt;But as I look at the Steam Machine release this week, I have some concerns.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;concern-1-no-flagship-steam-machine&quot;&gt;Concern 1: No flagship Steam Machine&lt;&#x2F;h2&gt;
&lt;p&gt;The console market is notorious for razor-thin margins on release hardware. Traditionally, consoles are often sold as &lt;em&gt;loss leaders&lt;&#x2F;em&gt; in their early years. Meaning, they are &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.forbes.com&#x2F;sites&#x2F;timworstall&#x2F;2013&#x2F;09&#x2F;06&#x2F;microsoft-upends-the-economics-of-games-machines-with-xbox-one&#x2F;&quot;&gt;sold below the manufacturing costs&lt;&#x2F;a&gt;. The thought here is the licensing profits from the games bought by initial adopters will help offset the loss. Once the console becomes embedded in the market, manufacturing improves, and over many, many small iterations, the console itself becomes cheap enough to make a profit.&lt;&#x2F;p&gt;
&lt;p&gt;Consoles are always, with rare exception, first-party. This means that the company who built the software stack that the games run on is also the company who owns and sells the hardware. Nintendo, Microsoft, Sony, and even previous game vendors like Atari and Sega, all made first-party consoles.&lt;&#x2F;p&gt;
&lt;p&gt;Rather than being first-party, Valve has opted for an approach that&#x27;s closer to non-console markets like phones: third-party hardware. Early software plays like Microsoft with MS-DOS and Windows, and more recent ones like Google&#x27;s Android platform are some examples here. The gist is that the standard platform works against a standard hardware spec. It doesn&#x27;t really matter who the vendor of the hardware is, so long as it matches the spec.&lt;&#x2F;p&gt;
&lt;p&gt;That might look good on paper for Valve. Since they&#x27;re new into the hardware game, why not let the vendors who know what they&#x27;re doing do it?&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s still a risky play, and, I&#x27;d argue, one that&#x27;s potentially riskier than partnering with one vendor to create a Steam-branded first-party machine. Some reasons why:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Third-party vendors can&#x27;t afford to sell loss leader machines.&lt;&#x2F;strong&gt; This means the machines will necessarily be lower-powered than they could be. This narrows the performance per $ gap between this batch of Steam Machines and established consoles like Playstation 4 and Xbox One. Which, in turn, hits customers in the wallet. While the Steam Machines are cool pieces of technology, they are also spendy pieces of technology. For example, the Zotac machine is $900 at the time of writing. At that price, I could buy &lt;strong&gt;3 WiiUs&lt;&#x2F;strong&gt; -or- &lt;strong&gt;an Xbox One &lt;em&gt;and&lt;&#x2F;em&gt; a Playstation 4&lt;&#x2F;strong&gt;, with money left over for games.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Third-party purchase experience is going to be whatever that vendor makes available.&lt;&#x2F;strong&gt; For example, this morning when looking at the new Alienware machine I got website errors on the Dell.com site. Of course, some of this will get better over time, but it&#x27;s difficult to see how both a higher price tag and a worse purchasing experience is going to help the Steam Machine brand.&lt;&#x2F;p&gt;
&lt;p&gt;As an aside, you might think that being third-party would help you create the Steam Machine of your dreams, but as of the time of this writing, you can&#x27;t even configure an Alienware machine to use SSD. For a gaming machine. No SSD. What? If you&#x27;re like me, that&#x27;s the first thing you&#x27;ll want to upgrade. I asked the Alienware rep over Twitter about it and got:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;http:&#x2F;&#x2F;www.sophiajt.com&#x2F;images&#x2F;alienware.png&quot; alt=&quot;Image of Alienware blaming lack of consumer choice on SKU complexity&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Again, likely something that will be fixed in time, but not the best initial experience and one that will turn-off some gamers from the Steam Machine idea.&lt;&#x2F;p&gt;
&lt;p&gt;Lastly, &lt;strong&gt;Valve&#x27;s Steam brand is already better than the third-party vendor brands&lt;&#x2F;strong&gt;. Steam is &lt;strong&gt;the&lt;&#x2F;strong&gt; major name in PC gaming today. Period. Who is Zotac or Syber? I honestly have never heard of them. Why play second fiddle to brands that aren&#x27;t as strong as your own?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;concern-2-steamos&quot;&gt;Concern 2: SteamOS&lt;&#x2F;h2&gt;
&lt;p&gt;The motivations here also seem straightforward: Valve gets to create a platform that a) they control and can tweak to their hearts content, b) supports a standard set of APIs that other vendors can leverage and is possibly less of a moving target than the competing APIs, and c) is free.&lt;&#x2F;p&gt;
&lt;p&gt;With c), Valve helps ensure that vendors can cut costs and deliver less-expensive Steam Machines. But the whole play here is very confusing.&lt;&#x2F;p&gt;
&lt;p&gt;Remember that a Steam Machine is a whole PC. Unlike a game console like Playstation 4, these guys can be a full Windows 10 machine if you install Windows on them. And Windows &lt;em&gt;already&lt;&#x2F;em&gt; runs Steam. So, in fact, a Steam Machine with SteamOS is actually a less powerful experience than taking SteamOS off and putting Windows in its place.&lt;&#x2F;p&gt;
&lt;p&gt;As for the advantages, again it seems like Valve is trying to take a page from the Android playbook.&lt;&#x2F;p&gt;
&lt;p&gt;Unfortunately, the current market is decidedly different than the market Android found itself in. With the release of the iPhone, and its rise in the smartphone market, you had a gap created with a lot of phone vendors wanting an iPhone-like experience without an easy way to get it. By creating a comparable work-alike, many vendors could sign up and build out the Android ecosystem. Is SteamOS entering a market of hardware vendors looking to enter the game console market? Having only one major PC brand, Dell, signing on to ship hardware with SteamOS is an indicator this may not be the case.&lt;&#x2F;p&gt;
&lt;p&gt;Likewise, are game developers scrambling to get onto SteamOS? Guessing by the size of the game lists, SteamOS has about a fifth the number of titles available for Steam on Windows. That, by itself, is actually pretty impressive. But, consoles really live and die on the titles themselves. Let&#x27;s do a quick rundown of my favorite kind of game, RPGs:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Witcher III: &lt;strong&gt;no&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Final Fantasy XIV - A Realm Reborn: &lt;strong&gt;no&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Dark Souls II: &lt;strong&gt;no&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;In fact, I struggled to find triple-A RPGs from the last few years that run on SteamOS. What&#x27;s telling is that all three are available on Windows as well on consoles, where they use gamepad support. In theory, this should be a solid group of games to show off your powerful new platform.&lt;&#x2F;p&gt;
&lt;p&gt;In fact, Fallout 4, which was also released this week, &lt;strong&gt;does not have SteamOS support&lt;&#x2F;strong&gt;. Likely to be one of the biggest games of the year, and it won&#x27;t run on Valve&#x27;s newly-shipping machines.&lt;&#x2F;p&gt;
&lt;p&gt;I suspect that the tech-savvy buyers will do exactly what I did when I got my machine: take out the hard drive, put in an SSD, and install Windows.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;concern-3-partnerships-or-lack-thereof&quot;&gt;Concern 3: Partnerships, or lack thereof&lt;&#x2F;h2&gt;
&lt;p&gt;Concerns 1 &amp;amp; 2 above could be summarized as &quot;Steam Machine lacks partnerships&quot;. The more high profile hardware companies competing to create the best Steam Machine, the better the end result. The more high profile game companies making games for the Steam Machine, the more SteamOS feels like an established platform like Playstation 4 and Xbox One.&lt;&#x2F;p&gt;
&lt;p&gt;Partnerships are a catch-22. It&#x27;s difficult to get them without first showing that your platform is a big enough draw to support the investment it takes to port a game or build a machine. Without the partnerships, the platform never grows to that size.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;road-ahead&quot;&gt;Road ahead&lt;&#x2F;h1&gt;
&lt;p&gt;It&#x27;s too early to say whether or not Valve will be successful. This release of the Steam Machine is muddied by a confusing story and a lack of partnerships, but there is still time to improve the experience. When Steam first came out, it had few games and many thought it was a weak idea. It, of course, grew to the giant it is today.&lt;&#x2F;p&gt;
&lt;p&gt;Like building a game distribution mechanism like Steam, a game console is also a long play. It takes years and lots of cash to build up a brand in the console market. Microsoft famously rumored to have spent &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;venturebeat.com&#x2F;2011&#x2F;11&#x2F;15&#x2F;the-making-of-the-xbox-part-2&#x2F;&quot;&gt;north of a billion dollars to establish the first Xbox&lt;&#x2F;a&gt;. From outward appearances, Valve is trying to compete with the console on a fraction of that budget.&lt;&#x2F;p&gt;
&lt;p&gt;Will Valve and its partners have the patience to build their own niche? Time will tell.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Learning to &#x27;try!&#x27; things in Rust</title>
        <published>2015-11-04T00:00:00+00:00</published>
        <updated>2015-11-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/learning-to-try-things-in-rust/"/>
        <id>https://www.sophiajt.com/learning-to-try-things-in-rust/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/learning-to-try-things-in-rust/">&lt;p&gt;I started learning Rust in earnest a few weeks ago.  Coming from C++, a fair share of the idioms felt right at home.  There was clear memory management and an eye towards lightweight abstractions.&lt;&#x2F;p&gt;
&lt;p&gt;But when I started looking around for how to do exceptions, I was surprised to find that Rust had none.  In its place were types like this:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;fn foo_maker() -&amp;gt; Result&amp;lt;Foo, io::Error&amp;gt; { ...}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I recognized this style, having come from playing with languages like Haskell, but despite doing some functional programming before I wasn&#x27;t entirely sure how to approach it.  At first blush, the Result value seems pretty straightforward, it either returns something of Foo or an io::Error.  We know which one it returns by pattern matching out the value:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;let result = foo_maker();
match result {
  Ok(foo) -&amp;gt; foo,
  Err(err) -&amp;gt; println!(&amp;quot;Error: {:?}&amp;quot;, err) &#x2F;&#x2F; Ooops, we hit an error, tell the user
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Great, you might think, that&#x27;s cute.  Well, at least at first.  Real code tends to have a few reads in a row:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;let num_chans = read_u16_le(&amp;amp;mut f);
let samples_per_sec = read_u32_le(&amp;amp;mut f);
let avg_bytes_per_sec = read_u32_le(&amp;amp;mut f);
let block_align = read_u16_le(&amp;amp;mut f);
let bits_per_sample = read_u16_le(&amp;amp;mut f);
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Since we&#x27;re reading from a file, any of these reads could hit an error.  Perhaps the hard drive dies, or we prematurely hit the end of the file.  Because of that, each function returns a Result that we later have to pattern match to get the value out.  This means we have to pattern match every result.  Yuck.&lt;&#x2F;p&gt;
&lt;p&gt;If you poke around on the internets, you&#x27;ll find a sneaky way around this using &lt;code&gt;.unwrap()&lt;&#x2F;code&gt;.  The &lt;code&gt;.unwrap()&lt;&#x2F;code&gt; call does just what it name implies: it unwraps the Result and gives us the value, assuming the result is Ok.  What if it errored with an Err? Well, then the application panics.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;let num_chans = read_u16_le(&amp;amp;mut f).unwrap();
let samples_per_sec = read_u32_le(&amp;amp;mut f).unwrap();
let avg_bytes_per_sec = read_u32_le(&amp;amp;mut f).unwrap();
let block_align = read_u16_le(&amp;amp;mut f).unwrap();
let bits_per_sample = read_u16_le(&amp;amp;mut f).unwrap();
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If you felt a cold shiver run down your spine looking at that, good on you :).  Now, let&#x27;s talk about how we actually fix this code.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;do-or-do-not-there-is-a-try&quot;&gt;Do or do not. There is a try!&lt;&#x2F;h1&gt;
&lt;p&gt;Looking a bit further in Rust examples, I learned about another way to call functions using the &lt;code&gt;try!&lt;&#x2F;code&gt; macro.  Maybe, I thought, &lt;code&gt;try!&lt;&#x2F;code&gt; would save us.  So I tried it out:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;use std::io;
use std::fs::File;

fn main() {
    let mut f = try!(File::open(&amp;quot;foo.txt&amp;quot;));
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;...and &lt;strong&gt;BOOM&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;std macros&amp;gt;:5:8: 6:42 error: mismatched types:
 expected `()`,
    found `core::result::Result&amp;lt;_, _&amp;gt;`
(expected (),
    found enum `core::result::Result`) [E0308]
&amp;lt;std macros&amp;gt;:5 return $ crate:: result:: Result:: Err (
&amp;lt;std macros&amp;gt;:6 $ crate:: convert:: From:: from ( err ) ) } } )
read_a_file.rs:5:17: 5:44 note: in this expansion of try! (defined in &amp;lt;std macros&amp;gt;)
&amp;lt;std macros&amp;gt;:5:8: 6:42 help: run `rustc --explain E0308` to see a detailed explanation
error: aborting due to previous error
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Okay, seriously?  I feel like I jumped in the Haskell pool after drinking a C++ template error cocktail.  What &lt;em&gt;is&lt;&#x2F;em&gt; that?&lt;&#x2F;p&gt;
&lt;p&gt;Luckily after asking around, I was finally able to piece together what was going wrong.  The hint lies in these lines:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt; expected `()`,
    found `core::result::Result&amp;lt;_, _&amp;gt;`
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Ah, some type mismatch is happening.  Our main function doesn&#x27;t return anything, which is the &lt;code&gt;()&lt;&#x2F;code&gt; in the &#x27;expected&#x27; above, but &lt;code&gt;try!&lt;&#x2F;code&gt; only works inside functions that return a &lt;code&gt;Result&lt;&#x2F;code&gt;.  This might be the first time in my life I&#x27;ve ever seen a function in a C-style language that was callable only inside functions of a particular type.&lt;&#x2F;p&gt;
&lt;p&gt;Shouldn&#x27;t be too hard to fix, just put it in a function that returns Result, right?&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;use std::io;
use std::fs::File;

fn read_file() -&amp;gt; Result&amp;lt;(), io::Error&amp;gt; {
    let mut f = try!(File::open(&amp;quot;foo.txt&amp;quot;));
    Ok(())
}
fn main() {
    read_file();
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Yup, that did it.  Then I promptly closed my editor and walked away.  I mean, this thing just felt &lt;em&gt;alien&lt;&#x2F;em&gt;.  Unnatural.  Gross.&lt;&#x2F;p&gt;
&lt;p&gt;What I didn&#x27;t realize was that a few weeks later I&#x27;d grok the genius in this approach.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;genius-1-unlike-try-catch-try-is-precise&quot;&gt;Genius #1 - Unlike try&#x2F;catch, try! is precise&lt;&#x2F;h2&gt;
&lt;p&gt;Let&#x27;s look at a real-life example from a project I&#x27;m working on:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;fn load_data(fname: &amp;amp;String) -&amp;gt; Result&amp;lt;Data, io::Error&amp;gt; {
  let mut f = try!(File::open(fname));
  let num_pages = try!(f.read_u8()) * 4;
 
  let mut pages : Vec&amp;lt;Vec&amp;lt;u8&amp;gt;&amp;gt; = Vec::new();
  for _ in 0..num_pages {
      let mut buffer = [0; 4096];
      try!(f.read(&amp;amp;mut buffer));
      
      pages.push(buffer.iter().cloned().collect());
  }
  &#x2F;&#x2F; ...
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It may take your eyes a minute to adjust to the new syntax, but knowing what we know, we can look at the code above and know exactly which functions might give us errors.  The &lt;code&gt;try!()&lt;&#x2F;code&gt; call even works on calls that are part of an expression, like &lt;code&gt;try!(f.read_u8()) * 4&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Compare this to traditional try&#x2F;catch blocks and how they tend to get put around whole sections of code when in reality only parts of the code blocks may throw exceptions.  The end result is code that&#x27;s very clear and doesn&#x27;t muddy exceptional code and value-based code together.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;genius-2-feels-like-exceptions&quot;&gt;Genius #2 - Feels like exceptions&lt;&#x2F;h2&gt;
&lt;p&gt;With this little bit of syntax, we get something that is value-based, but still feels like exceptions.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s say your task is to write code that will load a variety of audio file formats.  In each audio format loader, you have various subsections that get loaded (eg, a header, a metadata chunk, a chunk of audio data, etc).  It&#x27;d be great if you could create specialized functions for each.  If there are any errors, you just want to bubble that back out to the original caller loading the file.  The resulting code may look something like:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;fn load_header(file: &amp;amp;mut File) -&amp;gt; Result&amp;lt;Header, io::Error&amp;gt; {
  Ok(Header { header_block: try!(file.read_u32()) })
}

fn load_metadata(file: &amp;amp;mut File) -&amp;gt; Result&amp;lt;Metadata, io::Error&amp;gt; {
  Ok(Metadata { metadata_block: try!(file.read_u32()) })
}

fn load_audio(file: &amp;amp;mut File) -&amp;gt; Result&amp;lt;Audio, io::Error&amp;gt; {
  let header = try!(load_header(file));
  let metadata = try!(load_metadata(file));
  Ok(Audio { header: header, metadata: metadata })
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We can refactor our file loading into helper functions, and we continue to use the same familiar &lt;code&gt;try!&lt;&#x2F;code&gt; pattern.  How does this work?  The trick is that all the Results agree that &lt;code&gt;io::Error&lt;&#x2F;code&gt; is the error case.  If one of my helper functions hits a bad read and has to return an error, that error naturally bubbles all the way out without calling any additional code.&lt;&#x2F;p&gt;
&lt;p&gt;The end result is that we have precise syntax that is transparent about errors at every layer, stays pretty lightweight, and gives us the familiar &quot;bubble out&quot; feel of languages with exceptions.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;trade-offs&quot;&gt;Trade-offs&lt;&#x2F;h1&gt;
&lt;p&gt;Of course, there are trade-offs.  We end up repeating &lt;code&gt;try!()&lt;&#x2F;code&gt; in places we might have just wrapped in one big try&#x2F;catch block.  For example, the fix to our earlier use case might look like this:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;let num_chans = try!(read_u16_le(&amp;amp;mut f));
let samples_per_sec = try!(read_u32_le(&amp;amp;mut f));
let avg_bytes_per_sec = try!(read_u32_le(&amp;amp;mut f));
let block_align = try!(read_u16_le(&amp;amp;mut f));
let bits_per_sample = try!(read_u16_le(&amp;amp;mut f));
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Personally, I&#x27;m happy making the trade-off for the added precision.&lt;&#x2F;p&gt;
&lt;p&gt;We also saw another trade-off earlier.  If you use &lt;code&gt;try!()&lt;&#x2F;code&gt; in a function that doesn&#x27;t return a Result, you get an incomprehensible error message.  But once you know what&#x27;s going on, you can use it with confidence.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Telling the truth in code, function signatures and transparency</title>
        <published>2015-10-28T00:00:00+00:00</published>
        <updated>2015-10-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/telling-truth-in-code-function/"/>
        <id>https://www.sophiajt.com/telling-truth-in-code-function/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/telling-truth-in-code-function/">&lt;p&gt;When people talk about reasons to use a type system, there are always a couple usual suspects: error checking, documentation, and if you&#x27;re an IDE person like me, tooling&#x2F;editor tricks that use type information, like auto-complete.&lt;&#x2F;p&gt;
&lt;p&gt;But there&#x27;s another aspect to the types of function signatures that&#x27;s related to documentation but is perhaps stands on its own: transparency.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;what-is-transparency&quot;&gt;What is transparency?&lt;&#x2F;h1&gt;
&lt;p&gt;For this post, transparency helps us answer a few questions:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;What does this function require?&lt;&#x2F;li&gt;
&lt;li&gt;What does this function return?&lt;&#x2F;li&gt;
&lt;li&gt;What is this function going to do with what I give it?
&lt;ul&gt;
&lt;li&gt;Can it modify it?&lt;&#x2F;li&gt;
&lt;li&gt;Can it delete it?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Can this function fail?  If so, how?&lt;&#x2F;li&gt;
&lt;li&gt;Does this function do anything besides use its value?
&lt;ul&gt;
&lt;li&gt;ie) does this function &quot;change the world&quot; in some way?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;why-is-transparency-important&quot;&gt;Why is transparency important?&lt;&#x2F;h1&gt;
&lt;p&gt;A way most of us can relate to transparency is in the relationships you have in your life.  When you&#x27;re not transparent with another person -- keeping all of your thoughts to yourself, never saying when you&#x27;re angry, etc -- how does the other person ever know how to react to you?&lt;&#x2F;p&gt;
&lt;p&gt;Transparency in code works similarly.  When a function is transparent, you know what you need to do when the function is called, and you know how to react when the function is called.  Let&#x27;s look at a few examples.  In each example, we&#x27;re going to talk about a function that takes in an employee name and writes that name to a file.
Examples&lt;&#x2F;p&gt;
&lt;h2 id=&quot;python&quot;&gt;Python&lt;&#x2F;h2&gt;
&lt;pre&gt;&lt;code data-lang=&quot;python&quot;&gt;def writeToFile(name):
    # write out to the file
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We&#x27;ll start with the simplest form of transparency: minimal transparency.  Looking at what we have it&#x27;s tempting to say we don&#x27;t know anything at all, but that&#x27;s not quite true.  We do know the function name and that it takes a single parameter.&lt;&#x2F;p&gt;
&lt;p&gt;Things we don&#x27;t know:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;What kind of thing does it take?&lt;&#x2F;li&gt;
&lt;li&gt;Can it modify the thing we give it?&lt;&#x2F;li&gt;
&lt;li&gt;Can it delete what we give it?&lt;&#x2F;li&gt;
&lt;li&gt;Does it return anything?&lt;&#x2F;li&gt;
&lt;li&gt;Does it throw any exceptions?&lt;&#x2F;li&gt;
&lt;li&gt;Does it have any permanent effect on our system
&lt;ul&gt;
&lt;li&gt;eg) send files over the network, add to a database, launch the missiles?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Without this knowledge, we resort to aggressively testing, commenting, and using naming and coding conventions to get the idea across.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;c&quot;&gt;C&lt;&#x2F;h2&gt;
&lt;pre&gt;&lt;code data-lang=&quot;c&quot;&gt;int writeToFile(char *name) { 
    &#x2F;* write out to the file *&#x2F;
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Moving into C, we start to see a bit more information popping out.  We know that it takes in a &lt;code&gt;char*&lt;&#x2F;code&gt; for the name.  Since this also isn&#x27;t &lt;code&gt;const&lt;&#x2F;code&gt;, we know that it&#x27;s allowed to change the contents of the string we pass in.  We also know it returns an &lt;code&gt;int&lt;&#x2F;code&gt;, likely for error codes.&lt;&#x2F;p&gt;
&lt;p&gt;We are starting to see into what the function can do, but there&#x27;s still quite a bit we don&#x27;t know:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Can this function change our system?&lt;&#x2F;li&gt;
&lt;li&gt;Can the &lt;code&gt;name&lt;&#x2F;code&gt; value be deleted?&lt;&#x2F;li&gt;
&lt;li&gt;Can the function raise a signal (a C-flavored way of exceptions&#x2F;events)?&lt;&#x2F;li&gt;
&lt;li&gt;And what about those error codes?
&lt;ul&gt;
&lt;li&gt;How do we know the &lt;code&gt;int&lt;&#x2F;code&gt; is for error codes, and not returning the length of data written?&lt;&#x2F;li&gt;
&lt;li&gt;If it is for error codes, how do we know which ones it supports?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;We&#x27;ve improved some, but we still lean heavily on conventions, code comments, and testing to ensure that this function behaves correctly.  As an aside: one interesting point of C is that it doesn&#x27;t have exceptions, like many languages, so you&#x27;re almost encouraged to have a more value-based programming style, though it lacks many common features that help fill out the value-based story (pattern matching, algebraic data types, etc).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rust&quot;&gt;Rust&lt;&#x2F;h2&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;fn writeToFile (name: &amp;amp;str) -&amp;gt; Result&amp;lt;()&amp;gt; {
  &#x2F;&#x2F; write out to the file
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Above is a simple Rust version.  If you&#x27;ve never seen Rust before, let&#x27;s quickly break down it says:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;fn&lt;&#x2F;code&gt; keyword creates our function&lt;&#x2F;li&gt;
&lt;li&gt;Next, we give the function a name: writeToFile&lt;&#x2F;li&gt;
&lt;li&gt;Our function gets one argument called &#x27;name&#x27; which has the type &lt;code&gt;&amp;amp;str&lt;&#x2F;code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;&amp;amp;str&lt;&#x2F;code&gt; is a type in two parts:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;str&lt;&#x2F;code&gt; is the simple string type&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;&amp;amp;&lt;&#x2F;code&gt; meaning that this value is being borrowed and is owned by someone else (aka you&#x27;re not allowed to delete it)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Finally, we return something of type &lt;code&gt;Result&amp;lt;()&amp;gt;&lt;&#x2F;code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Result&amp;lt;()&amp;gt;&lt;&#x2F;code&gt; is the Rust way of saying I can return either:
&lt;ul&gt;
&lt;li&gt;a) successfully, without a value (the () above)&lt;&#x2F;li&gt;
&lt;li&gt;b) an error&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The Rust example tells a bit more of the story than the C version.  In Rust, everything is immutable by default, so we know from looking at the signature that what we pass in can&#x27;t be changed.  It also won&#x27;t be deleted, because what is passed is &#x27;borrowed&#x27; rather than us giving ownership over to this function.  Rust is similar to C in that we don&#x27;t have exceptions and instead use return values to denote success or failure (read more in Rust Error Handling).  Rust encodes the success or failure in the return value, requiring the caller to code defensively around possible errors.  This has the effect of encouraging code to be more robust by handling both success and failure where they can occur.&lt;&#x2F;p&gt;
&lt;p&gt;An improvement over where we were in C, but we still have a lingering question: does this function have any permanent effect on the system?  To be able to answer that question, we go one example deeper down the rabbit hole.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;haskell&quot;&gt;Haskell&lt;&#x2F;h2&gt;
&lt;pre&gt;&lt;code data-lang=&quot;haskell&quot;&gt;writeToFile :: String -&amp;gt; IO ()
writeToFile name = do 
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Since this might be unfamiliar let&#x27;s take a second to breakdown what we&#x27;re seeing:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;We start by declaring the type (which isn&#x27;t terribly dissimilar from a forward declaration in C)&lt;&#x2F;li&gt;
&lt;li&gt;The type has two parts:
&lt;ul&gt;
&lt;li&gt;We take one argument that has a type &lt;code&gt;String&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;We return an &lt;code&gt;IO ()&lt;&#x2F;code&gt; [see below]&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;After the type, we write out the actual implementation of the function&lt;&#x2F;li&gt;
&lt;li&gt;Just as in Rust, Haskell is immutable by default.  When we say we pass in a String, we&#x27;re also implying that this string can&#x27;t be changed or deleted.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Also similar to Rust, in Haskell there are no exceptions, so you must handle all possible values when you call the function.  By saying &lt;code&gt;IO ()&lt;&#x2F;code&gt;, this might at first seem similar to the &lt;code&gt;Result&amp;lt;()&amp;gt;&lt;&#x2F;code&gt;.  In some sense, it is, in that IO carries along any possible errors.&lt;&#x2F;p&gt;
&lt;p&gt;It also goes a bit further.  In essence, it says: &quot;I&#x27;m going to go change the world, and when I come back you need to carry that truth on.&quot;  In Haskell, if you call a function that performs I&#x2F;O like our writeToFile function, you must also carry on that fact in your own return type.  You have to be fully transparent all the way through the call stack of who is changing the world, even indirectly.  This lets you clearly document who is modifying the world and who isn&#x27;t.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;dark-side-of-transparency&quot;&gt;Dark side of transparency&lt;&#x2F;h1&gt;
&lt;p&gt;But, it can&#x27;t be all roses, right?  Let&#x27;s look at what I see as the dark side of transparency: encapsulation (or its lack thereof).&lt;&#x2F;p&gt;
&lt;p&gt;As good software engineers, we know an important piece of building a system is having good encapsulation.  Any module or object worth its weight exposes only necessary functionality to the world and hides the rest.  This encourages loose coupling, so that components don&#x27;t depend on each others&#x27; implementation details.&lt;&#x2F;p&gt;
&lt;p&gt;In a way, transparency in the type runs counter to information hiding in that it encourages more coupling in the code.  Some of this is natural.  For example, in the C code, we have to remember what the return values are.  If we add a new one, we may have to change the code handling the call as well.  Likewise, in Python, if we change the types of parameters we allow, we may have to go update the callers.&lt;&#x2F;p&gt;
&lt;p&gt;On the other hand, knowing that a function may fail may be sufficient.  In the Rust case, code that handles the call may need to be updated if you change how the function fails, even if it only cares about if it fails.&lt;&#x2F;p&gt;
&lt;p&gt;Likewise, in Haskell you may want to drop some probe into your system to catch the result of a function while you&#x27;re debugging.  Such changes can have a ripple effect in your codebase as this probe may change a series of function calls to reflect that I&#x2F;O has been performed.  (Not withstanding workarounds with fun names like &lt;code&gt;unsafePerformIO&lt;&#x2F;code&gt;)&lt;&#x2F;p&gt;
&lt;h1 id=&quot;all-a-balance&quot;&gt;All a balance&lt;&#x2F;h1&gt;
&lt;p&gt;Types are there to help.  Leaning on them not enough means encoding more information in your tests and code comments.  Leaning on them too much may mean tightly coupling parts of your system.  What the right balance is may change from project to project, or developer to developer.&lt;&#x2F;p&gt;
&lt;p&gt;Just as in our relationships with other people, it makes sense to not tell everyone we meet everything about us.  It&#x27;s a balance.  Finding the right amount of transparency that encourages flexible, resilient systems is an art.&lt;&#x2F;p&gt;
&lt;p&gt;In the last few weeks, in playing with Rust more I&#x27;ve grown to appreciate its pragmatic set of trade-offs.  Yes, you don&#x27;t get to know if the system was changed, but if something can impact the rest of the program, you&#x27;re encouraged to handle it.  Not that there aren&#x27;t workarounds or ways to easily opt-out, but just as in life, it&#x27;s all a balance.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Lessons from the first 12 Euler problems in Rust</title>
        <published>2015-10-09T00:00:00+00:00</published>
        <updated>2015-10-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/lessons-from-first-12-euler-problems-in/"/>
        <id>https://www.sophiajt.com/lessons-from-first-12-euler-problems-in/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/lessons-from-first-12-euler-problems-in/">&lt;p&gt;&lt;strong&gt;!! Spoiler Alert !!&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;I&#x27;m going to be talking about solutions to select problems from the first 12 Euler problems. If you haven&#x27;t solved these for yourself yet, I highly recommend taking the time to solve them on your own first.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;background&quot;&gt;Background&lt;&#x2F;h1&gt;
&lt;p&gt;Before I went to Microsoft for a &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.typescriptlang.org&#x2F;&quot;&gt;stint in JavaScript&lt;&#x2F;a&gt;, I did my fair share of systems programming in C++. I&#x27;ve built compilers, head-tracking software, signal processing software, and emulators and even did some of my first programming language projects in it and &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;chaiscript.com&#x2F;&quot;&gt;for it&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;So when word got out four years ago about a new systems language called &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rust-lang.org&#x2F;&quot;&gt;Rust&lt;&#x2F;a&gt;, I was intrigued. I mean, it was &lt;em&gt;new&lt;&#x2F;em&gt; and it was called &lt;em&gt;rust&lt;&#x2F;em&gt;. Obviously there was some cheekiness involved :)&lt;&#x2F;p&gt;
&lt;p&gt;While I&#x27;ve dabbled with it before, this week was the first time I really gave it some dedicated time to learn it. &lt;strong&gt;TL;DR:&lt;&#x2F;strong&gt; hey, this is kinda neat!&lt;&#x2F;p&gt;
&lt;p&gt;In this post I talk through solving some of the Euler problems in Rust, both de-rusting my programming skills and learning what this Rust thing was all about.&lt;&#x2F;p&gt;
&lt;p&gt;If you&#x27;re interested, you can grab the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sophiajt&#x2F;rustnewbie&quot;&gt;source code to my solutions&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;problem-1&quot;&gt;Problem 1&lt;&#x2F;h1&gt;
&lt;p&gt;&quot;sum of all multiples of 3 or 5 below 1000&quot;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;fn main() {
    let mut answer = 0;

    for x in 0..1000 {
        if x % 3 == 0 {
            answer += x;
        }
        else if x % 5 == 0 {
            answer += x;
        }
    }

    println!(&amp;quot;{}&amp;quot;, answer);
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;My solution to problem 1 is pretty straightforward, but you can already start to see some of the characteristic earmarks of Rust. On &lt;strong&gt;line 2&lt;&#x2F;strong&gt;, there&#x27;s a let keyword which creates a variable. After that is the mut keyword for saying that the variable we&#x27;re creating is mutable, as variables are immutable by default.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Line 4&lt;&#x2F;strong&gt; shows off using an iterator. Rust&#x27;s iterators are lazy, meaning they generate values only as needed. This gives them some cool properties, which we&#x27;ll see later, but it has the property of being relatively cheap to iterate over them, since we don&#x27;t generate a full range before iteration starts.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Line 5&lt;&#x2F;strong&gt; reminds us that we&#x27;re not in C. The if doesn&#x27;t require parens around its condition. Indeed, if you put them there, the compiler warns you that you don&#x27;t need them.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Line 13&lt;&#x2F;strong&gt; shows how to print out a value. Note the &#x27;!&#x27; after println. If you&#x27;re like me, you&#x27;re bound to leave this off once or twice and get an incomprehensible error message. Similar to C and many other languages, you pass println! a format string. Here, we just use &quot;{}&quot;. The {} part means to use a default output of the argument we pass in, which in our case just writes out the number.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;problem-2&quot;&gt;Problem 2&lt;&#x2F;h1&gt;
&lt;p&gt;&quot;sum of even fibonacci below 4,000,000&quot;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;struct Fibonacci {
    curr: u64,
    next: u64,
}

&#x2F;&#x2F; Implement &amp;#39;Iterator&amp;#39; for &amp;#39;Fibonacci&amp;#39;
impl Iterator for Fibonacci {
    type Item = u64;
    &#x2F;&#x2F; The &amp;#39;Iterator&amp;#39; trait only requires the &amp;#39;next&amp;#39; method to be defined. The
    &#x2F;&#x2F; return type is &amp;#39;Option&amp;lt;T&amp;gt;&amp;#39;, &amp;#39;None&amp;#39; is returned when the &amp;#39;Iterator&amp;#39; is
    &#x2F;&#x2F; over, otherwise the next value is returned wrapped in &amp;#39;Some&amp;#39;
    fn next(&amp;amp;mut self) -&amp;gt; Option&amp;lt;u64&amp;gt; {
        let new_next = self.curr + self.next;

        self.curr = self.next;
        self.next = new_next;

        &#x2F;&#x2F; &amp;#39;Some&amp;#39; is always returned, this is an infinite value generator
        Some(self.curr)
    }
}

&#x2F;&#x2F; Returns a fibonacci sequence generator
fn fibonacci() -&amp;gt; Fibonacci {
    Fibonacci { curr: 1, next: 1 }
}

fn main() {
    let mut sum:u64 = 0;
    for i in fibonacci().take_while(|&amp;amp;x| x &amp;lt; 4000000).filter(|&amp;amp;x| x % 2 == 0) {
        sum += i;
    }
    println!(&amp;quot;sum: {}&amp;quot;, sum);
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Lest you think that I somehow jumped from beginner level to advanced in a few minutes, rest assured that I used the tried and true method of the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;rustbyexample.com&#x2F;trait&#x2F;iter.html&quot;&gt;copy&#x2F;paste&lt;&#x2F;a&gt;. In trying to find out how to make an iterator so I could iterate over a fibonacci sequence, I found the source to do just that. Ah, the internet.&lt;&#x2F;p&gt;
&lt;p&gt;There&#x27;s a fair bit going on here, so let&#x27;s break it down by line.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Lines 1-4:&lt;&#x2F;strong&gt; Create a simple struct to hold the current value to be returned as well as the next value. Fibonacci needs at least these two values to continue to calculate each iteration.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Line 7:&lt;&#x2F;strong&gt; Now Rust is showing off the fancy. What is going on here? In Rust, a type, like our Fibonacci struct from lines 1-4, can implement a trait. What&#x27;s a trait? Think of it as a small contract with the compiler. If you can show how your type satisfies all the requirements of the contract, then wherever that trait is required, the compiler knows how to use your type. In this example, we want to use our type in the &lt;code&gt;for..in&lt;&#x2F;code&gt; language feature. In some languages, this wouldn&#x27;t be possible. In Rust, if we can satisfy the Iterator trait, the compiler has enough information to allow that type to be used in the &lt;code&gt;for..in&lt;&#x2F;code&gt; feature.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Line 8:&lt;&#x2F;strong&gt; Ah the problem with copy&#x2F;paste. As I started writing this blog post, I had no idea what that line was doing. Docs to the rescue. It turns out that this line is saying what the &#x27;associated type&#x27; is. With some traits, there&#x27;s going to be both a) the type that is implementing the trait (here: our Fibonacci struct) and b) an additional type that needs to be known to get the rest of the story. For us, since we&#x27;re creating an iterator over the fibonacci sequence, we need to let Rust know what the type of each &quot;turn of the crank&quot; on the iterator will output. Each fibonacci number will be a 64-bit unsigned integer, so we use the Rust short-hand type &lt;code&gt;u64&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Lines 12-20:&lt;&#x2F;strong&gt; Here&#x27;s where we describe how to turn the crank for each step of our iterator. We calculate what the next turn will output and then return the current value. This allows us to keep one in reserve ready to be used to calculate the next value, and so on. You can see on line 19 that instead of just returning a &lt;code&gt;u64&lt;&#x2F;code&gt; directly, we instead say that it&#x27;s optionally a &lt;code&gt;u64&lt;&#x2F;code&gt;. While in our case we iterate forever, using &lt;code&gt;Option&lt;&#x2F;code&gt; here gives us a way to shut off the valve and finish the iterator if we ever wanted to.&lt;&#x2F;p&gt;
&lt;p&gt;Notice, too, on &lt;strong&gt;line 19&lt;&#x2F;strong&gt; the value is said last and the return statement is elided. This is just shorthand for returning a value from the function.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Lines 24-26:&lt;&#x2F;strong&gt; Create a simple function to give us our starting value to begin our fibonacci sequence. You can see a couple Rust-isms here, too. As before, a value by itself is an implied return value. It also shows how to create an instance of the struct without a constructor.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Line 30:&lt;&#x2F;strong&gt; We&#x27;re finally in the main! I&#x27;ve forgotten what problem we were solving by now. Ah right, &quot;find the sum of even fibonacci numbers less than 4,000,000&quot;. Let&#x27;s look at the solution. Since there&#x27;s a lot going on in this fluent-style approach, let&#x27;s break it up into steps:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;fibonacci()&lt;&#x2F;code&gt; - we call our function and get out the default value to start iterating with. Since we already told Rust how to use values of this type as iterators, it gets all the capabilities that iterators have.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;.take_while(|&amp;amp;x| x &amp;lt; 4000000)&lt;&#x2F;code&gt; - that didn&#x27;t take long, we&#x27;re already jumping in and using the functionality of the iterator to check each turn of the crank, and if we exceed 4,000,000 stop.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;|&amp;amp;x| x &amp;lt; 4000000&lt;&#x2F;code&gt; is a simple function that takes in a reference to each element we bind to x, and then we check the value we&#x27;re handed in the body of our function. If you&#x27;re coming from C++, this reference style might look a little strange. Aren&#x27;t you risking someone updating the value? Turns out Rust&#x27;s references are &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;doc.rust-lang.org&#x2F;book&#x2F;references-and-borrowing.html#borrowing&quot;&gt;immutable by default&lt;&#x2F;a&gt;. The reference here also shows us the performance characteristics of &lt;code&gt;.take_while&lt;&#x2F;code&gt;. By this I mean, when we look at the &lt;code&gt;.take_while&lt;&#x2F;code&gt; call, we see it will only pass references, so know ahead of time if we&#x27;re iterating over big structures, we&#x27;re not paying the price of copying each one with each step of the iterator.&lt;&#x2F;p&gt;
&lt;p&gt;Speaking of performance, it may look like .take_while is going to be exceedingly expensive. Is it consuming all of our fibonacci sequence until we have all the items we need to get to 4,000,000? Luckily, it isn&#x27;t. Instead, &lt;code&gt;.take_while&lt;&#x2F;code&gt; itself returns an iterator that you can continue your fluent calls on. I think of it like a series of machines in a factory:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;-&amp;gt; [  ] -&amp;gt; [  ] -&amp;gt; [  ] -&amp;gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If I start the conveyor up and I pull from the right hand, I&#x27;m moving whatever was on the far left all the way through the system. In our case, we&#x27;re starting up the fibonacci iterator and getting that machine running. It spits out a single fibonacci-shaped number for us. This number chugs along and enters the next machine, which is our machine that checks if it&#x27;s too big. If it&#x27;s not, the conveyor chugs along and out drops a single fibonacci-shaped number of the acceptable size.&lt;&#x2F;p&gt;
&lt;p&gt;As these machines work in lock-step, we&#x27;re getting just what we need when we need it rather than trying to run ahead and doing a bunch of work in advance. This allows you compose a lot of steps together and still stay efficient.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;.filter(|&amp;amp;x| x % 2 == 0)&lt;&#x2F;code&gt; - Just like &lt;code&gt;.take_while&lt;&#x2F;code&gt; above, this one checks each number as it passes through. This time, it only lets the number through if it&#x27;s divisible by 2, and hence even.&lt;&#x2F;p&gt;
&lt;p&gt;Now we have all the steps in place, each time we turn the crank of the whole iterator, only fibonacci numbers that are less than 4,000,000 and even will pop out.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Line 31:&lt;&#x2F;strong&gt; We&#x27;ve already done all the hard work. Now we just have to sum those numbers together.&lt;&#x2F;p&gt;
&lt;p&gt;With that, we&#x27;re done. While it was quite a mouthful, we can see the compositional nature of Rust, a bit of the type system, and how iterators work in more detail.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;problem-3&quot;&gt;Problem 3&lt;&#x2F;h1&gt;
&lt;p&gt;&quot;highest prime factor of 600851475143&quot;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;fn is_prime(num:u64) -&amp;gt; bool {
    for i in 2..(num &#x2F; 2 + 1) {
        if num % i == 0 {
            return false;
        }
    }
    return true;
}

struct Prime {
    curr: u64,
}

impl Iterator for Prime {
    type Item = u64;
    fn next(&amp;amp;mut self) -&amp;gt; Option&amp;lt;u64&amp;gt; {
        let mut new_next = self.curr + 1;
        while !is_prime(new_next) {
            new_next += 1;
        }

        self.curr = new_next;

        Some(self.curr)
    }
}


&#x2F;&#x2F; Returns the primes
fn primes() -&amp;gt; Prime {
    Prime { curr: 1 }
}

fn main() {
    let mut num:u64 = 600851475143;
    let mut highest_prime_factor = 0;

    for i in primes() {
        if num % i == 0 {
            highest_prime_factor = i;
        }
        while (num % i == 0) &amp;amp;&amp;amp; (num &amp;gt;= 2) {
            num &#x2F;= i;
        }
        if num == 1 {
            break;
        }
    }
    println!(&amp;quot;num: {}&amp;quot;, highest_prime_factor);
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Very similar to Problem #2 above, I create an implementation of Iterator, so I can use it later. This time, rather than creating a stream of fibonacci values, I create a stream of prime numbers.&lt;&#x2F;p&gt;
&lt;p&gt;Just like we had a struct for Fibonacci in Problem #2, I create one here for Prime numbers. Since we don&#x27;t need the previous one to calculate the next one, I only keep the current value around and then start with that number + 1 when trying to find the next prime.&lt;&#x2F;p&gt;
&lt;p&gt;Once we have our iterator, we take each prime, and then try to divide out all its multiples from our give number. What&#x27;s left should be our highest prime factor. Easy peasy.&lt;&#x2F;p&gt;
&lt;p&gt;PS: I know it&#x27;s probably already too late, but I should have warned you to avert your eyes from my inefficient prime number skills :)&lt;&#x2F;p&gt;
&lt;h1 id=&quot;problem-4&quot;&gt;Problem 4&lt;&#x2F;h1&gt;
&lt;p&gt;&quot;largest palindrome product of two 3-digit numbers&quot;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;fn is_palindrome(num: u64) -&amp;gt; bool {
    let s = num.to_string();
    for (i1, i2) in s.chars().zip(s.chars().rev()) {
        if i1 != i2 {
            return false;
        }
    }
    return true;
}

fn main() {
    let mut largest = 0;
    for i in 100..999 {
        for j in 100..999 {
            if is_palindrome(i * j) &amp;amp;&amp;amp; ((i * j) &amp;gt; largest) {
                largest = i * j;
                println!(&amp;quot;Largest: {}, {} x {}&amp;quot;, largest, i, j);
            }
        }
    }
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Problem #4 also uses some iterators to find the palindrome product (&lt;strong&gt;line 13&lt;&#x2F;strong&gt; and &lt;strong&gt;line 14&lt;&#x2F;strong&gt;). If it finds a palindrome product, and that new product is larger than what it saw before, it replaces it with the new one.&lt;&#x2F;p&gt;
&lt;p&gt;There&#x27;s one fun trick in this solution on &lt;strong&gt;line 3&lt;&#x2F;strong&gt;. We need to check if the number is a palindrome. While you can do this &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;199184&#x2F;how-do-i-check-if-a-number-is-a-palindrome&quot;&gt;numerically&lt;&#x2F;a&gt;, I couldn&#x27;t help but use some more iterators. This time, after converting the number to a string, we create an iterator over the characters in the string (using &lt;code&gt;.chars()&lt;&#x2F;code&gt;). We want to see if the number is a palindrome, so one way to test this is that if we reverse the string and if still get the same value, we know we&#x27;ve got one.&lt;&#x2F;p&gt;
&lt;p&gt;That&#x27;s exactly what we do. Here, I use &lt;code&gt;.zip(s.chars().rev())&lt;&#x2F;code&gt; to combine the iterator that goes forward over the characters with one that goes in reverse. The &lt;code&gt;.zip()&lt;&#x2F;code&gt; call brings both iterators together and iterates over both iterators for us, returning a pair (or tuple) of values. Think of it running both machines side by side, and with each turn of the crank one value pops out of each and zip returns both values tied together with a bow.&lt;&#x2F;p&gt;
&lt;p&gt;Now that we have a single pair, we immediately use it. At the beginning of line 3, you can see the for &lt;code&gt;(i1, i2)&lt;&#x2F;code&gt; in part of the line. Just as before &lt;code&gt;for..in&lt;&#x2F;code&gt; will run over the iterator. We know that the iterator is going to be outputting pairs of values. We could have just grabbed the pair as a single value and used it later, but here I go one step further by taking the pair the iterator gives me and pulling it apart so I can use it. This pulling apart, called destructuring, is a handy way of working with structured data when you&#x27;re interested in its constituent parts rather than the structure itself. In this case, this lets me more easily compare the left side to the right side, so I destructure the pair into two values: &lt;code&gt;i1&lt;&#x2F;code&gt; and &lt;code&gt;i2&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;problems-5-through-7&quot;&gt;Problems 5 through 7&lt;&#x2F;h1&gt;
&lt;p&gt;Problems &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sophiajt&#x2F;rustnewbie&#x2F;blob&#x2F;master&#x2F;euler&#x2F;src&#x2F;ex5.rs&quot;&gt;#5&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sophiajt&#x2F;rustnewbie&#x2F;blob&#x2F;master&#x2F;euler&#x2F;src&#x2F;ex6.rs&quot;&gt;#6&lt;&#x2F;a&gt;, and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sophiajt&#x2F;rustnewbie&#x2F;blob&#x2F;master&#x2F;euler&#x2F;src&#x2F;ex7.rs&quot;&gt;#7&lt;&#x2F;a&gt; are all straightforward and don&#x27;t show off anything new in the language. Let&#x27;s jump ahead to the next interesting one.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;problem-8&quot;&gt;Problem 8&lt;&#x2F;h1&gt;
&lt;p&gt;&quot;largest product of 13 adjacent digits&quot;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;fn main() {
    let input =
        &amp;quot;73167176531330624919225119674426574742355349194934\
        96983520312774506326239578318016984801869478851843\
        85861560789112949495459501737958331952853208805511\
        12540698747158523863050715693290963295227443043557\
        66896648950445244523161731856403098711121722383113\
        62229893423380308135336276614282806444486645238749\
        30358907296290491560440772390713810515859307960866\
        70172427121883998797908792274921901699720888093776\
        65727333001053367881220235421809751254540594752243\
        52584907711670556013604839586446706324415722155397\
        53697817977846174064955149290862569321978468622482\
        83972241375657056057490261407972968652414535100474\
        82166370484403199890008895243450658541227588666881\
        16427171479924442928230863465674813919123162824586\
        17866458359124566529476545682848912883142607690042\
        24219022671055626321111109370544217506941658960408\
        07198403850962455444362981230987879927244284909188\
        84580156166097919133875499200524063689912560717606\
        05886116467109405077541002256983155200055935729725\
        71636269561882670428252483600823257530420752963450&amp;quot;;

    let mut largest = 0;
    let input_bytes = input.as_bytes();
    let mut largest_string: &amp;amp;[u8] = &amp;amp;input_bytes[0..1];

    let span_width = 13;

    for i in 0..(input_bytes.len() - span_width + 1) {
        let mut sum = 1u64;
        for j in 0..(span_width) {
            sum *= (input_bytes[i + j] - 48) as u64;
        }
        if sum &amp;gt; largest {
            largest = sum;
            largest_string = &amp;amp;input_bytes[i..(i+span_width)];
        }
    }

    println!(&amp;quot;Largest: {} is {:?}&amp;quot;, largest, std::str::from_utf8(largest_string));
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In Problem #8, we see an example of working with strings, this time using a new feature called a &#x27;slice&#x27;. We start with the block from &lt;strong&gt;line 3&lt;&#x2F;strong&gt; to &lt;strong&gt;line 22&lt;&#x2F;strong&gt; that gives us this giant input string. Notice that I use the backslash &#x27;&#x27; to continue the line to the next line. Rust is smart enough to let us indent without introducing new whitespace into the string.&lt;&#x2F;p&gt;
&lt;p&gt;Now that we have our string, on &lt;strong&gt;line 25&lt;&#x2F;strong&gt; we turn it into a array of bytes we can search through. Notice we didn&#x27;t use &lt;code&gt;.chars()&lt;&#x2F;code&gt; this time. Recall that &lt;code&gt;.chars()&lt;&#x2F;code&gt; gave us an iterator. Rather than iterating over one value at a time here, we want the flexibility to look across spans in our string. To do that, we use &lt;code&gt;.as_bytes()&lt;&#x2F;code&gt; to get an array (technically, a byte slice).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Line 26&lt;&#x2F;strong&gt; introduces the slice we&#x27;ll use. A slice is a window into values in memory. Since we want to look at a span of values, we create a holder for this slice. We&#x27;ll later set it to spans of our 13 adjacent digits. PS: you&#x27;ll notice I set it to a dummy default value, which I later throw away. This is to get around the compiler warning about uninitialized values.&lt;&#x2F;p&gt;
&lt;p&gt;The rest of the search follows fairly naturally. We do an iterator over the indices in our input, stopping short of the length of the span. We use that index to calculate the product at that span (&lt;strong&gt;line 32&lt;&#x2F;strong&gt; to &lt;strong&gt;line 34&lt;&#x2F;strong&gt;). Once we find a match, we save it off, using a slice to save off the winning span (&lt;strong&gt;line 37&lt;&#x2F;strong&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;Finally, we use another format string &lt;code&gt;{:?}&lt;&#x2F;code&gt;, which can print out our winning span for us using the debug formatter. The &lt;code&gt;{:?}&lt;&#x2F;code&gt; format is a handy builtin which can handle a wider range of types with a default formatter.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;problem-9&quot;&gt;Problem 9&lt;&#x2F;h1&gt;
&lt;p&gt;Problem &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sophiajt&#x2F;rustnewbie&#x2F;blob&#x2F;master&#x2F;euler&#x2F;src&#x2F;ex9.rs&quot;&gt;#9&lt;&#x2F;a&gt; is another solution that&#x27;s simple and doesn&#x27;t show off any new features. Moving on.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;problem-10&quot;&gt;Problem 10&lt;&#x2F;h1&gt;
&lt;p&gt;&quot;sum of all primes below 2 million&quot;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;fn main() {
    let mut sum = 0;
    const SIZE: usize = 2000000;
    let mut slots: [bool; SIZE] = [true; SIZE];
    slots[0] = false;
    slots[1] = false;

    &#x2F;&#x2F; We calculate the primes using a simple stride and marking off multiples
    for stride in 2..(SIZE&#x2F;2) {
        let mut pos = stride;
        while pos &amp;lt; (SIZE - stride) {
            pos += stride;
            slots[pos] = false;
        }
    }

    for (idx, pr) in slots.into_iter().enumerate() {
        if *pr { sum += idx; }
    }

    println!(&amp;quot;Sum: {}&amp;quot;, sum);
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Reading the problem description, you might have guessed that I would use the iterator solution from earlier. The astute reader probably already noticed that doing so would be. very. slow. Especially, as we look at primes above a million, where each step is itself taking hundreds of thousands, if not millions, of calculations. While I could let it run and heat up my apartment, it&#x27;s better to do a more direct approach.&lt;&#x2F;p&gt;
&lt;p&gt;We trade space for time.&lt;&#x2F;p&gt;
&lt;p&gt;On &lt;strong&gt;line 4&lt;&#x2F;strong&gt;, I create my first fixed size array that will hold whether or not the number in that position is prime. Once we have the variable, it&#x27;s initialized using another cool shorthand: &lt;code&gt;[true; SIZE]&lt;&#x2F;code&gt;. This creates an array of boolean true values of the size given on the right of the &#x27;;&#x27;, here the SIZE constant I defined. For example, you can create a 500-element array of zeros using &lt;code&gt;[0; 500]&lt;&#x2F;code&gt;. Neat.&lt;&#x2F;p&gt;
&lt;p&gt;Once we have our slots, we loop over them using any possible multiple and check that off the list by setting that position to false. Once we&#x27;re done, we have an array that tells us where the primes are.&lt;&#x2F;p&gt;
&lt;p&gt;The only trick remaining is how to get the numbers back out again. To do this, we use the iterator on &lt;strong&gt;line 17&lt;&#x2F;strong&gt;. Similar to our fluent iterators before, this time we turn our array of slots into an iterator, and then call &lt;code&gt;.enumerate()&lt;&#x2F;code&gt;. The &lt;code&gt;.enumerate()&lt;&#x2F;code&gt; call is a special kind of zip that gives us the index at that point in the iteration paired with the actual value. Just as before, we destructure the index and the boolean that indicates if it&#x27;s a prime number separately.&lt;&#x2F;p&gt;
&lt;p&gt;On &lt;strong&gt;line 18&lt;&#x2F;strong&gt;, we check if the number is prime, and if so we add it to our sum. You&#x27;ll notice the &lt;code&gt;*pr&lt;&#x2F;code&gt; call here. Just as in C, this lets me dereference and get at the value at that location in memory. I could have instead written for &lt;code&gt;(idx, &amp;amp;pr)&lt;&#x2F;code&gt; in and just gotten to the value that way, using destructuring instead of dereferencing. With that change, the line would have been &lt;code&gt;if pr { ... }&lt;&#x2F;code&gt;, and I could get at the value &lt;code&gt;pr&lt;&#x2F;code&gt; without needing to dereference.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;problem-11&quot;&gt;Problem 11&lt;&#x2F;h1&gt;
&lt;p&gt;&quot;find the largest product in a grid&quot;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;let input = &amp;quot;\
    08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08 \
    49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00 \
    81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65 \
    52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91 \
    22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80 \
    24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50 \
    32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70 \
    67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21 \
    24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72 \
    21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95 \
    78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92 \
    16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57 \
    86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58 \
    19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40 \
    04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66 \
    88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69 \
    04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36 \
    20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16 \
    20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54 \
    01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48&amp;quot;;

let input_split = input.split_whitespace();
let input_as_num: Vec&amp;lt;i32&amp;gt; = input_split.map(|x|
    match i32::from_str_radix(x, 10) {
        Ok(v) =&amp;gt; v,
        Err(u) =&amp;gt; { println!(&amp;quot;Garbage in input: {}&amp;quot;, u); 0 }
    }
).collect();
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I&#x27;m only showing the interesting part of the solution since it&#x27;s a bit long, but you can read the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sophiajt&#x2F;rustnewbie&#x2F;blob&#x2F;master&#x2F;euler&#x2F;src&#x2F;ex11.rs&quot;&gt;whole solution&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Here we do a bit more string manipulation using some new methods. The &lt;code&gt;.split_whitespace()&lt;&#x2F;code&gt; method on &lt;strong&gt;line 23&lt;&#x2F;strong&gt; lets us turn our input string into an iterator of strings, splitting at any whitespace.&lt;&#x2F;p&gt;
&lt;p&gt;Once we have this iterator, &lt;strong&gt;line 24&lt;&#x2F;strong&gt; takes this iterator and maps a function over it. This function attempts to convert each substring to a signed 32-bit integer &lt;code&gt;i32&lt;&#x2F;code&gt; using the &lt;code&gt;.from_str_radix(x, 10)&lt;&#x2F;code&gt; call. This call returns a &lt;code&gt;Result&lt;&#x2F;code&gt;, a way of handling either a success or failure condition of an action that might fail. As is the case with converting from strings to numbers, if you happen to pass in something that can&#x27;t be converted to a number, there needs to be a way to signal back out that the conversion failed. Some languages do this through exceptions, which break out of normal execution and give you an error you can handle. Rust uses a simpler, more functional approach and treats errors as just any other value. With this method, the type system encourages us to be vigilant and always have code available to handle errors.&lt;&#x2F;p&gt;
&lt;p&gt;To see which of success&#x2F;failure is returned, we use the match keyword. Just as in other languages with pattern matching, the match keyword lets us ask which of the possible values is in the Result: &lt;code&gt;Ok&lt;&#x2F;code&gt; or &lt;code&gt;Err&lt;&#x2F;code&gt;. Pattern matching lets us destructure and find the success value or error message.&lt;&#x2F;p&gt;
&lt;p&gt;Finally, on &lt;strong&gt;line 29&lt;&#x2F;strong&gt;, we use the &lt;code&gt;.collect()&lt;&#x2F;code&gt; method to run through the iterator and create a vector of &lt;code&gt;i32&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;problem-12&quot;&gt;Problem 12&lt;&#x2F;h1&gt;
&lt;p&gt;&quot;triangle number with over 500 divisors&quot;&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;fn main() {
    let mut num = 0u64;

    &#x2F;&#x2F; Cache the primes we&amp;#39;ll be using
    let first_primes: Vec&amp;lt;u64&amp;gt; = primes().take(1000).collect();

    for i in 1..1000000u64 {
        num += i;

        let mut num_div = 1u64;

        let mut num_tmp = num;
        for &amp;amp;x in &amp;amp;first_primes {
            let prime = x;
            if (num % prime) == 0 {
                let mut exponent = 1;

                while (num_tmp % prime) == 0 {
                    exponent += 1;
                    num_tmp &#x2F;= prime;
                }
                num_div *= exponent;
            }
            if num_tmp == 1 { break; }
        }

        if num_div &amp;gt; 500 {
            println!(&amp;quot;num: {}&amp;quot;, num);
            return;
        }
    }
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Again we&#x27;ll trim down to the interesting parts, since we&#x27;ve seen the prime iterator before, but you can read the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sophiajt&#x2F;rustnewbie&#x2F;blob&#x2F;master&#x2F;euler&#x2F;src&#x2F;ex12.rs&quot;&gt;full file&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;This looks pretty familiar. On &lt;strong&gt;line 5&lt;&#x2F;strong&gt;, we run our primes iterator, take enough to use later, and turn that into a &lt;code&gt;Vec&amp;lt;u64&amp;gt;&lt;&#x2F;code&gt; we can use a bunch of times.&lt;&#x2F;p&gt;
&lt;p&gt;The other interesting line is &lt;strong&gt;line 13&lt;&#x2F;strong&gt;. If you&#x27;ve played with vectors in Rust before, you know that you can iterate over them, like this:&lt;&#x2F;p&gt;
&lt;p&gt;{% highlight rust %}
fn main() {
let x: Vec&lt;u32&gt; = (1..10).collect();&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;for i in x {
    println!(&amp;quot;{}&amp;quot;, i);
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;}
{% endhighlight %}&lt;&#x2F;p&gt;
&lt;p&gt;But if we try to do this in our Euler problem, we get a new error:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;error: use of moved value: `first_primes`
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;What is a &lt;em&gt;moved value&lt;&#x2F;em&gt;?&lt;&#x2F;p&gt;
&lt;p&gt;It turns out that a moved value is part of Rust&#x27;s ownership system. Just like the first time a programmer sees a pointer in C or a monad in Haskell, ownership in Rust is one of those things that&#x27;s so uniquely Rust that it takes getting used to. Once you begin to understand it, you&#x27;ll be able to see how the type system is trying to help you describe your intentions a bit more clearly.&lt;&#x2F;p&gt;
&lt;p&gt;If you&#x27;re scratching your head, here&#x27;s an example: imagine malloc&#x27;ing an array in C and then passing that malloc&#x27;ed array into a function. Who is responsible for cleaning up that memory, the function you called or the function that created the array? In C, you don&#x27;t know by looking at the code, you only know as the writer of the code what your intention was. Maybe the function is called &#x27;cleanup&#x27; at which case, yes, you do want it to free that memory. Or maybe the function is called &#x27;inspect&#x27; and you decidedly &lt;em&gt;don&#x27;t&lt;&#x2F;em&gt; want it to free the memory. This is why Rust makes this very explicit. By looking at the code, you can follow who is responsible for what. The set of checks that do this make up Rust&#x27;s ownership system.&lt;&#x2F;p&gt;
&lt;p&gt;There are a lot of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;book&#x2F;references-and-borrowing.html&quot;&gt;resources&lt;&#x2F;a&gt; to understand ownership,which do a good job of explaining ownership in detail. For us, ownership is like trying to answer questions like &quot;who is responsible for this thing?&quot; and &quot;when does this thing get removed?&quot; Ownership can be passed from variable to variable, and its strictly checked by the compiler.&lt;&#x2F;p&gt;
&lt;p&gt;When you first encounter the above error, if you haven&#x27;t already read about ownership, you might be in for a few hours of reading to get caught up. But we have some hints here that we can get started with to help figure out what&#x27;s happening.&lt;&#x2F;p&gt;
&lt;p&gt;In our small example, we could iterate over a vector and all was well. When did things start to go wrong in the Euler problem?&lt;&#x2F;p&gt;
&lt;p&gt;On &lt;strong&gt;line 13&lt;&#x2F;strong&gt;, we want to loop over a vector, and when we look out to &lt;strong&gt;line 7&lt;&#x2F;strong&gt;, we see this is actually an inner loop being used by an outer loop. That means that if the inner loop takes control of our vector, the next time around the outer loop we&#x27;ve lost the ownership.&lt;&#x2F;p&gt;
&lt;p&gt;We don&#x27;t want the inner loop to take ownership and then lose the ability to use the vector again in the next iteration of the loop, so we have to &#x27;borrow&#x27; ownership. As the name implies, by borrowing, we&#x27;re only taking temporary ownership for a time, and we have to follow all the rules stated when we borrow. With that in mind, let&#x27;s look at &lt;strong&gt;line 13&lt;&#x2F;strong&gt; again:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;for &amp;amp;x in &amp;amp;first_primes
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We borrow &lt;code&gt;first_primes&lt;&#x2F;code&gt; instead of taking permanent ownership using the &lt;code&gt;&amp;amp;&lt;&#x2F;code&gt; operator. This operator says &quot;I would like to borrow first_primes, and I can not edit the contents&quot;. The compiler will then be able to check that we&#x27;re using what we&#x27;ve borrowed correctly. You might be curious borrowing and also being able to mutate. To do that, we could&#x27;ve used the &lt;code&gt;&amp;amp;mut&lt;&#x2F;code&gt; operator assuming the original vector was mutable.&lt;&#x2F;p&gt;
&lt;p&gt;Finally, we use the same destructure trick we did earlier to get at the values of &lt;code&gt;x&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;PS:&lt;&#x2F;strong&gt; In this example, since all we were doing was iterating, we could have used the &lt;code&gt;.iter()&lt;&#x2F;code&gt; rather than borrowing, though that won&#x27;t always be the case in other examples that need more direct interaction with the vector.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;cargo&quot;&gt;Cargo&lt;&#x2F;h1&gt;
&lt;p&gt;After I got enough of these problems together that I got tired of building them by hand, I moved over to using Cargo. Cargo is Rust&#x27;s build&#x2F;package tool that is quite handy.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;[package]

name = &amp;quot;eulerinrust&amp;quot;
version = &amp;quot;0.1.0&amp;quot;

[[bin]]
name = &amp;quot;ex1&amp;quot;
path = &amp;quot;src&#x2F;ex1.rs&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;em&gt;An example of Cargo.toml&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Cargo lets you describe dependencies that your project needs, which it fetches from crates.io. You can also control whether you&#x27;re doing a release or debug build, and quite a bit more. I&#x27;ll no doubt start directly with Cargo for any future Rust projects.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h1&gt;
&lt;p&gt;These are just tiny examples created while playing around in a fairly simple set of problems, and yet there&#x27;s actually quite a lot of Rust&#x27;s richness shining through. Rust has a powerful iterator story that feels composable and clear. Rust&#x27;s error checking is keeping us vigilant about handling error cases, matching types, and remembering who is responsible for values in the system. Overall, it feels like a very well thought-out language that holds together well.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Off to new adventures</title>
        <published>2015-10-05T00:00:00+00:00</published>
        <updated>2015-10-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/off-to-new-adventures/"/>
        <id>https://www.sophiajt.com/off-to-new-adventures/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/off-to-new-adventures/">&lt;p&gt;A few weeks ago I posted about moving teams inside of Microsoft.  As sometimes happens when you make a change, you realize that you actually need to make a bigger change.  A few weeks into the new team, and I could tell that it was time for me to move onto new adventures.&lt;&#x2F;p&gt;
&lt;p&gt;Microsoft has been a great place for me to &quot;grow up&quot; as a program manager.  When I started as an intern, I was mentored by some of the most capable PMs I&#x27;ve ever met.  They took a keen interest in me, and I benefited greatly from their years of experience and patience.&lt;&#x2F;p&gt;
&lt;p&gt;From a little bird of a PM, I grew to being able to lead the great TypeScript team.  I got to meet countless numbers of people and make some good friends along the way.  It was a wild adventure to be on the team, and I&#x27;m excited to see what they come up with next.&lt;&#x2F;p&gt;
&lt;p&gt;But as little birds grow, there comes a time to leave the nest and to take more risks. There are many adventures to be had, and to have them, you have to ride out the storms in search of the blue skies.&lt;&#x2F;p&gt;
&lt;p&gt;My first step will be to take some time to travel the world and see friends I haven&#x27;t seen in years.  My goal: recharge, explore, and take stock.  After that, who knows.&lt;&#x2F;p&gt;
&lt;p&gt;Part of the adventure is not seeing the way ahead and going anyway.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Programming languages are a failure</title>
        <published>2013-02-17T00:00:00+00:00</published>
        <updated>2013-02-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/programming-languages-are-a-failure/"/>
        <id>https://www.sophiajt.com/programming-languages-are-a-failure/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/programming-languages-are-a-failure/">&lt;p&gt;After spending years working in programming languages, helping out with some big-name projects and trying to generally make programmers&#x27; lives easier, I&#x27;ve decided something.&lt;&#x2F;p&gt;
&lt;p&gt;Programming languages are a failure.&lt;&#x2F;p&gt;
&lt;p&gt;Okay okay, before you write this off as a troll for attention, hear me out for a minute longer.&lt;&#x2F;p&gt;
&lt;p&gt;Calling a programming language a &#x27;language&#x27; is false advertising.  Think of what comes to mind when I say &#x27;language&#x27;.  A language, as in human-to-human language, has some pretty interesting properties:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;It can be used to express intent&lt;&#x2F;li&gt;
&lt;li&gt;It can transmit information even if one (or even both) of the speakers are non-native&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The act of programming is inherently not like speaking.  Imagine having a conversation with someone in the same way you program.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Say what you want the other person to understand&lt;&#x2F;li&gt;
&lt;li&gt;Say it again, this time with slightly different wording&lt;&#x2F;li&gt;
&lt;li&gt;Say it again, with yet more slightly different wording&lt;&#x2F;li&gt;
&lt;li&gt;(Rinse, repeat.  Time passes...)&lt;&#x2F;li&gt;
&lt;li&gt;Test the other person on what you&#x27;ve said to be very sure they understood&lt;&#x2F;li&gt;
&lt;li&gt;Move on to the next thing you want the other person to understand&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Of course, the reason we have to do this in programming is because we want what we say to be precise, so the computer exactly what to do, right?  Human language is filled with all that icky imprecision, which is why we use a programming language.  The special kind of language that precisely describes what we mean to the computer, so long as we&#x27;re patient enough to explain ourselves just so.&lt;&#x2F;p&gt;
&lt;p&gt;What we&#x27;ve actually created is something akin to legalese for programming rather than legal documents, a sort of programese.  It&#x27;s a one-way conversation with the computer in a style that removes as much room as possible for misinterpretation.  The dirty secret is that programming languages, like many legal documents, never really finish going through refinement, even after years and years of refinement.&lt;&#x2F;p&gt;
&lt;p&gt;Why not embrace the ambiguity?  Better yet, why not make programming a two-way communication that more closely resembles people talking?&lt;&#x2F;p&gt;
&lt;p&gt;Instead of this:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; The bird sits on the pole.
Error: I don&amp;#39;t understand &amp;#39;bird&amp;#39;.  I don&amp;#39;t understand &amp;#39;pole&amp;#39;. 
&amp;gt; The bird, an animal, sits on the telephone pole.
Error: The animal &amp;#39;bird&amp;#39; can not &amp;quot;sit&amp;quot;. 
&amp;gt; The bird, an animal, stands on the telephone pole.
Okay.
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Why not have this:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; The bird sits on the pole.
Question: By &amp;quot;sits&amp;quot; do you mean &amp;quot;stands&amp;quot;? 
&amp;gt; Yes
Understood.
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Let the programming system ask you when it truly doesn&#x27;t understand.  The difference is, where it can infer an understanding based on context and background knowledge, it does.&lt;&#x2F;p&gt;
&lt;p&gt;This opens up further possibilities.  What the programming system could be doing for you behind the scenes is fill out what it understands, changing the text much like Telescopic Text.  This would replace &quot;The bird sits on the pole&quot; after you type it in to be a telescopic text  you could click on &lt;code&gt;&quot;[The bird] [sits on] [the pole]&quot;&lt;&#x2F;code&gt;.  If you clicked on &lt;code&gt;[The bird]&lt;&#x2F;code&gt;, the text would telescope in one level, giving you: &lt;code&gt;&quot;[The bird, an animal][sits on][the pole]&quot;&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Imagine how much easier&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Promising new programming languages</title>
        <published>2011-09-22T00:00:00+00:00</published>
        <updated>2011-09-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/promising-new-programming-languages/"/>
        <id>https://www.sophiajt.com/promising-new-programming-languages/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/promising-new-programming-languages/">&lt;p&gt;It seems like these days there are lots of programming languages springing up.  A combination of the web, parallel programming, and just outright curiosity seems to be fueling creativity towards new mixtures of classic features and experimental new ones.&lt;&#x2F;p&gt;
&lt;p&gt;Here are a few new(-ish) projects I&#x27;m keeping my eye on:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.rust-lang.org&#x2F;&quot;&gt;Rust&lt;&#x2F;a&gt; (Mozilla Research) - Concurrent language that only allows sharing of mutable state if it&#x27;s handed off between threads.  Uses typestates to enforce this ownership.  Expected to be used in Project Servo, Mozilla&#x27;s experimental parallel browser engine.  Recent talk slides look promising.  Still experimental (haven&#x27;t reached 0.1 yet).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;kotlinlang.org&#x2F;&quot;&gt;Kotlin&lt;&#x2F;a&gt; (JetBrains) - Impressively clean&#x2F;lightweight syntax language for the JVM in the spirit of a Scala light.  Perhaps may be to Scala what Firefox was to Netscape, but it&#x27;s not yet release so it&#x27;s hard to say for sure.  Still, their presentation at the JVM Language Summit is worth a watch.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ooc-lang.org&#x2F;&quot;&gt;ooc&lt;&#x2F;a&gt; - You have to like the infectious audacity of this project.  Hobbyist putting together a language, then proceeding to write one compiler for it in itself and then another.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;dart.dev&#x2F;&quot;&gt;Dart&lt;&#x2F;a&gt; (Google) - Mentioning it here because I&#x27;m curious, but the hype has already overshadowed it. We&#x27;re still weeks away from knowing anything about it.  Still, Gilad Bracha is like a &quot;curiously strong mint&quot;, so we at least know it won&#x27;t be flavorless.&lt;&#x2F;p&gt;
&lt;p&gt;These are just the ones on my radar.  There are certainly others (Ceylon, Gosu, Mirah - and those are just the ones on the JVM), but they haven&#x27;t quite made it to my twitter follow list.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Will parallelism go implicit?</title>
        <published>2011-03-08T00:00:00+00:00</published>
        <updated>2011-03-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/will-parallelism-go-implicit/"/>
        <id>https://www.sophiajt.com/will-parallelism-go-implicit/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/will-parallelism-go-implicit/">&lt;p&gt;I&#x27;ve been spending quite a bit of time recently with &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.com&#x2F;Implicit-Parallel-Programming-Rishiyur-Nikhil&#x2F;dp&#x2F;1558606440&quot;&gt;Implicit Parallel Programming in pH&lt;&#x2F;a&gt;, which luckily the school library had a copy of.  It&#x27;s quite a good textbook to introduce programmers to functional programming, perhaps even one of the better ones (next to the original &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.amazon.com&#x2F;Introduction-Functional-Programming-International-Computing&#x2F;dp&#x2F;0134841891&quot;&gt;Introduction to Functional Programming&lt;&#x2F;a&gt; by Bird, Wadler that I mentioned in an earlier blog post).  What turned me on to it, though, wasn&#x27;t the treatment of functional programming - it was its far more audacious titular goal.&lt;&#x2F;p&gt;
&lt;p&gt;Which leads to the obvious question. &lt;em&gt;What is implicit parallelism?&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If you bring up the term around PL geeks, you might get a few questioning looks and some comments that hint at automatic loop parallelization.  Even more confusingly, this second kind of parallelism is sometimes referred to as automatic parallelism.  It refers to taking sequential codes and reasoning about where parallelism could occur without changing any results.  Implicit parallelism is a more holistic approach - what if the only sequentiality in your program comes from the data dependencies?  Then the rest, it stands to reason, can be done in parallel.&lt;&#x2F;p&gt;
&lt;p&gt;I mentioned this as an audacious effort.  The first and foremost reason, to my engineering mind, is &lt;em&gt;how in the world will you make this efficient?&lt;&#x2F;em&gt;  I can just imagine the compiler identifying tens, perhaps even hundreds, of tiny tasks that can be done in parallel at any one timeslice.   How do we schedule these tasks in such a way we don&#x27;t pay a high overhead for synchronization and task switching?&lt;&#x2F;p&gt;
&lt;p&gt;I haven&#x27;t dug into the implementations of the languages yet to see how they address this issue, but as I was brainstorming this morning it hit me.  Implicit parallelism isn&#x27;t so different from implicit (or automatic) memory management.  When garbage collectors first came out, they weren&#x27;t the lean mean things they are today.  That&#x27;s part of the advantage of having decades to polish an approach, and now fewer and fewer applications programmers use languages that don&#x27;t have gc support.  It saves more headaches than it causes, and that&#x27;s generally a winning combination.&lt;&#x2F;p&gt;
&lt;p&gt;Not always, of course.  The HPC community has regularly shunned gc in their languages, where high performance codes are hand-tuned Fortran or C with manual memory management.  Still, I would argue that HPC is boutique, a cottage industry focused on maximal efficiency.&lt;&#x2F;p&gt;
&lt;p&gt;Most everyday programmers don&#x27;t need these levels of efficiency, and I imagine, will instead opt for automatic support for parallelism.  This saves them the headache of separately tuning for the same application to run comfortably on either 16 or 128 cores.  From the consumer&#x27;s point of view, this is also a win.  Buying that new 256 core machine actually will make these apps run faster.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Some final thoughts&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Perhaps it&#x27;s time to focus on introducing more forms of automatic and implicit parallelism into our programming languages and runtime systems.  Our early attempts, taking from the experiments of the past could kick it off, and once industrial interest has turned to it, I&#x27;d expect steady progress in efficiency (just like we&#x27;ve seen in gc).&lt;&#x2F;p&gt;
&lt;p&gt;Is there some practical limit to the amount of parallelism in code?  There&#x27;s a tension between &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Amdahl%27s_law&quot;&gt;Amdahl&#x27;s law&lt;&#x2F;a&gt;, that maximum speedup through parallelism is limited by the amount of sequential code, and &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Gustafson%27s_Law&quot;&gt;Gustafson&#x27;s law&lt;&#x2F;a&gt;, which says that the increased computing power lets us tackle larger problems.  To continue to gain we may have to change how we approach problems, or even reframe the problems themselves.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Thoughts on actor-based languages</title>
        <published>2010-09-07T00:00:00+00:00</published>
        <updated>2010-09-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/thoughts-on-actor-based-languages/"/>
        <id>https://www.sophiajt.com/thoughts-on-actor-based-languages/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/thoughts-on-actor-based-languages/">&lt;p&gt;(or &quot;Minnow, a post-mortem&quot;)&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve been fortunate to work on both &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sophiajt&#x2F;minnow-language&#x2F;tree&#x2F;alpha3&quot;&gt;Minnow&lt;&#x2F;a&gt;(a shared-nothing actor-based language) and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;chapel-lang.org&#x2F;&quot;&gt;Chapel&lt;&#x2F;a&gt;(concurrent global-view language). I wanted to give a few thoughts comparing the two approaches.&lt;&#x2F;p&gt;
&lt;p&gt;First, when we talk about concurrency or parallelism, without going into the pedantic definitions of each, we should answer the question &quot;why not stay serial?&quot; There are a lot of reasons to do so, if we can. Serial code is going to be easier to write, easier to debug, and easier to reason about. Generally, going parallel is just going to complicate our lives.&lt;&#x2F;p&gt;
&lt;p&gt;I see two main reasons why going parallel would be required:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Reliability&lt;&#x2F;strong&gt; - Does the system have to tolerate failures of its parts?&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Performance&lt;&#x2F;strong&gt; - Is serial too slow for your application?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;In &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.erlang.org&#x2F;&quot;&gt;Erlang&lt;&#x2F;a&gt;, reliability is king. Its shared-nothing actor-model style allows actors to fail and be restarted, which allows for more advanced features like hot code swapping.&lt;&#x2F;p&gt;
&lt;p&gt;For areas where performance is king, C and Fortran still reign. In high-performance scientific computing, it&#x27;s common to remove abstractions and program as &quot;close to the metal&quot; as possible. Though this doesn&#x27;t preclude reliability, that reliability must either be done by the programmer or by the underlying architecture. It is, as you can imagine, very fast.&lt;&#x2F;p&gt;
&lt;p&gt;When I created Minnow, I set out to create an actor-based language that could perform as fast as C but potentially gain the benefit of reliability from the actor abstraction. Focusing solely on single node, shared-memory machine, I was able to optimize:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Message sends, down to a few atomic operations&lt;&#x2F;li&gt;
&lt;li&gt;Number of actors possible, using light-weight threads and continuations&lt;&#x2F;li&gt;
&lt;li&gt;Run-time overhead, even in the presence of fairness counters for cooperative multi-tasking, by minimizing extraneous work in loops and function calls&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;In short, Minnow was quite fast.&lt;&#x2F;p&gt;
&lt;p&gt;Was it fast enough? As it turns out, the answer is &lt;em&gt;no&lt;&#x2F;em&gt;. Though Minnow avoiding copying where possible, it did not allow the user to see a large matrix and operate on pieces of it. Doing so would go against the notion of shared-nothing, we might even say that shared-nothing runs counter to the goal of performance. Algorithms where we could bifurcate data into chunks, for example, wouldn&#x27;t suffer, but in general we can no longer use contiguous memory in a natural way.&lt;&#x2F;p&gt;
&lt;p&gt;The modern batch of concurrent languages (Chapel, X10, Co-Array Fortran, and others) return to looking at memory in a contiguous way. In fact, using &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Partitioned_global_address_space&quot;&gt;partitioned global address space&lt;&#x2F;a&gt; (or PGAS), the notion of contiguous memory is extended to encompass the memories of all the nodes in a cluster.&lt;&#x2F;p&gt;
&lt;p&gt;The question of where reliability should live, and if we should push it into the language and sacrifice performance, appears to be solved issue in the high-performance community. It remains to be seen if the larger programmer community will embrace this approach.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Digging into scheme&#x2F;racket</title>
        <published>2010-09-05T00:00:00+00:00</published>
        <updated>2010-09-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.sophiajt.com/digging-into-scheme-racket/"/>
        <id>https://www.sophiajt.com/digging-into-scheme-racket/</id>
        
        <content type="html" xml:base="https://www.sophiajt.com/digging-into-scheme-racket/">&lt;p&gt;I spent some of last night and this morning digging into Racket, the modern version of the venerable Scheme language. Every time I return to a Lisp variant, I find the parentheses less annoying that I did the last time. With proper indenting and some syntax highlighting, is there all that much difference?&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;scheme&quot;&gt;(define factorial
  (lambda (n)
    (if (= n 0) 1
        (* n (factorial (- n 1))))))
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Arguably the trailing parentheses are an eye chard.&lt;&#x2F;p&gt;
&lt;p&gt;With the download of Racket you also get DrRacket, which is an updated version of DrScheme, a learning tool aimed at programmers of different experience levels (and to my understanding different ages as well)&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve just begun to experiment with DrRacket to see what it can do. To get familiar with the Scheme style, I&#x27;ve been working through Teach Yourself &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.ccs.neu.edu&#x2F;home&#x2F;dorai&#x2F;t-y-scheme&#x2F;t-y-scheme-Z-H-1.html&quot;&gt;Scheme in Fixnum Days&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
</feed>
