<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Alex Poulos</title>
    <description>The latest articles on DEV Community by Alex Poulos (@mapoulos).</description>
    <link>https://dev.to/mapoulos</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F551752%2F068aa672-ef66-4f5f-b810-4490e4bd9950.jpeg</url>
      <title>DEV Community: Alex Poulos</title>
      <link>https://dev.to/mapoulos</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mapoulos"/>
    <language>en</language>
    <item>
      <title>Going from Senior to Staff</title>
      <dc:creator>Alex Poulos</dc:creator>
      <pubDate>Fri, 24 Oct 2025 16:06:07 +0000</pubDate>
      <link>https://dev.to/mapoulos/going-from-senior-to-staff-2d0f</link>
      <guid>https://dev.to/mapoulos/going-from-senior-to-staff-2d0f</guid>
      <description>&lt;p&gt;I recently gave a talk at Staff Plus in New York on "Unbecoming the Bottleneck: Growing Others as an IC".  Afterwards, someone wrote to me with the following question, and I've written up a response as a blog post:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Question: I’ve been stuck at senior for several years. With several other seniors on the team and a relatively new tech lead hired into the team, it’s hard to get visibility, especially when many rooms are gated by title.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here are few thoughts!&lt;/p&gt;

&lt;p&gt;Technical mastery is crucial, but only part of the equation. And yet, you still want to become the person that people come to with thorny technical questions, or the person of last resort during a tricky incident. Ideally, you are coming up with approaches to ship features or improve your systems that others haven’t thought of, and are appreciably better on some metric (like time to implement, cloud cost, query latency, etc). If there is another person or two on the team occupying that role, you may need to counter position yourself by staking out expertise on something that’s not important yet, but may be in the future (perhaps a new homegrown tool that your organization is rolling out, or how to integrate well with some wider company initiative). You want to be shipping high-quality, high impact work with relatively few surprises in production. If there is a long tenured trusted engineer on the team, you might go to them and ask “What’s something that’s been bugging you but you haven’t gotten around to dealing with? Can I help?”.&lt;/p&gt;

&lt;p&gt;Early in my time at Spotify, for instance, I spent a month or so optimizing a bunch of SQL queries in services that had been paging us because of increased latency. Sometimes this was as simple as adding the right index, but occasionally I had to rewrite a query so that it would actually hit an index. But in each case, I made sure to document the improvement and share it with the team. This was a relatively small accomplishment in the grand scheme of my tenure, but it established me early as someone who could make order-of-magnitude improvements on small pieces of the system. Other engineers were happy to not be getting paged as much, and our leadership felt less existential angst that certain core services were just going to fall over under increased load. &lt;/p&gt;

&lt;p&gt;Assuming you've gained a reputation for technical mastery (which to be clear is a hard thing to do!), you also need to excel in the "soft skills" of communication, project management, and relationship building. The most important relationships are probably with your leadership chain. Ethan Evans’ magic loop is a great formula here. Basically, you’re trying to address or help address whatever top-line worries your leadership has. Is there a project going off the rails? Maybe you can step in to provide some guidance to get it back on track. Is there a nagging production issue that another org has escalated? Maybe you can quickly get to the bottom of the issue. You'll want to look for opportunities to write RFCs or other technical design docs, work on projects where you're leading a key piece of the work (ideally directing the implementation work of others too). You'll also want to be building good relationships with other teammates and engineers from other teams.&lt;/p&gt;

&lt;p&gt;But let's finally address the environment. All of this is much easier when you're in a setting where there's plenty of high-impact work to go around. Ideally you want to be in a situation where there's an abundance of high-impact work, but a shortage of people skilled enough to lead key streams of work. If you're not in that kind of environment, you'll realistically have to either out perform others to get access to key projects, or wait until those "above you" make space (either by leaving or getting promoted). Sometimes you may need to leave the team or the company, but I'd generally recommend resisting that impulse at first, so long as you're still learning at a decent rate and have a decent work environment. If you're choosing a new team, looking for a team with a lot of high-impact, difficult technical work is a key thing to look for. In the short-term, an absence of strong technical leadership on a team could make it appealing (a great chance for you to demonstrate leadership!), but in the long-run you'll want to put yourself in frequent situations where you're &lt;em&gt;not&lt;/em&gt; the most tenured or experienced person in the room. Ultimately you'll learn the most if you're around other engineers who are better than you, so soak up those opportunities when granted. In the long-run, it's probably better, even if in the short-run it does make advancement trickier. &lt;/p&gt;

&lt;p&gt;And one last word on "rooms gated by title." It's enormously frustrating to be gated from a room because you don't have the title. Sometimes this does inhibit impact. But what I've discovered since gaining the title is that though the title does confer access to more rooms, many of these rooms are not places where high-impact work happens. And if you're doing high-impact work relevant to one of those rooms, you'll often find yourself invited as a guest. I guess the key takeaway is that in general, "access to the right room" is probably &lt;em&gt;not&lt;/em&gt; the key blocker on your growth, as exasperating as the exclusion feels.&lt;/p&gt;

</description>
      <category>leadership</category>
    </item>
    <item>
      <title>Rust: First Thoughts</title>
      <dc:creator>Alex Poulos</dc:creator>
      <pubDate>Wed, 28 Jul 2021 19:05:57 +0000</pubDate>
      <link>https://dev.to/mapoulos/rust-first-thoughts-7l0</link>
      <guid>https://dev.to/mapoulos/rust-first-thoughts-7l0</guid>
      <description>&lt;p&gt;My third child, Maximus, was born this Spring, and thanks to a generous parental leave policy I’ve had the summer off to spend with family and friends, and to poke at various tech projects and those with friends (Thanks &lt;a href="https://washpost.engineering/" rel="noopener noreferrer"&gt;WaPo&lt;/a&gt;! Recently one of these projects presented the opportunity to learn some Rust.&lt;/p&gt;

&lt;p&gt;I come to Rust having spent most of my career writing Java or (Java/Type)script. Many moons ago in high school and university I did C and C++ but have happily forgotten most of that. I’ve also recently built some small projects in Go, which is the most interesting and common comparand for Rust (a nice comparison can be found &lt;a href="https://bitfieldconsulting.com/golang/rust-vs-go" rel="noopener noreferrer"&gt;here&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Rust happened to be extremely well suited for the task I had: speeding up some CPU bound geospatial JavaScript code. Porting this to Rust took execution time from about &lt;strong&gt;5 minutes&lt;/strong&gt; on my 4 year old Macbook Pro to &lt;strong&gt;30s&lt;/strong&gt; without any algorithmic improvements. Dropping in some parallelism knocked it down once again to about &lt;strong&gt;10s&lt;/strong&gt;. A 30x speed improvement is not to be ignored!&lt;/p&gt;

&lt;h2&gt;
  
  
  The Good
&lt;/h2&gt;

&lt;p&gt;Rust has a modern dev tooling may seem par for the course for a modern language. Dependency management, a code formatter, and unit testing are all built into the standard tooling. Rust here has borrowed a number of important features from languages and ecosystems like JavaScript and Go. What’s remarkable is that Rust gives you this first class tooling in a language that compiles down to native code. Given that Rust’s primary competitors are C and C++, this is a huge asset. Dependency management in anything non-trivial in C or C++ is monstrous. Getting C-like performance without the arcane dependency management is an enormous boon.&lt;/p&gt;

&lt;p&gt;Rust’s indebtedness to functional languages like Haskell and OCaml make it quite simple to write code in a functional style. Immutability is a first class concern, and we get a full set of generic functions for operating on collections (&lt;code&gt;map&lt;/code&gt;, &lt;code&gt;filter&lt;/code&gt;,&lt;code&gt;fold&lt;/code&gt; a.k.a. Rust’s &lt;code&gt;reduce&lt;/code&gt;). This means the day to day experience of writing Rust is not unlike writing functionally inflected Typescript (my high-level language of choice at the moment). I write lots &lt;code&gt;map&lt;/code&gt; and &lt;code&gt;fold&lt;/code&gt; transformations, and the language provides robust support for fallible and nullable operations through the &lt;code&gt;Result&lt;/code&gt; and &lt;code&gt;Option&lt;/code&gt; enums. For instance, say I want to iterate over a list of objects and create a HashMap. In Typescript, that would probably look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Block&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;blocks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Block&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="cm"&gt;/* ... */&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;blockMap&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;blocks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;block&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;block&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;block&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In Rust, you can do the same:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Block&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;blocks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Vec&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Block&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// push some blocks...&lt;/span&gt;

&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;blockMap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Block&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;blocks&lt;/span&gt;&lt;span class="nf"&gt;.fold&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; 
    &lt;span class="n"&gt;acc&lt;/span&gt;&lt;span class="nf"&gt;.push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="py"&gt;.id&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rust’s generic return implementation of the &lt;code&gt;collect&lt;/code&gt; function even allow you to do this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// map to a tuple, then collect into a HashMap&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;blockMap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Block&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;blocks&lt;/span&gt;&lt;span class="nf"&gt;.map&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; 
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="py"&gt;.id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.collect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Go makes it much harder to write this kind of code, particularly in an immutable fashion. The same code in Go would look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;blockMap&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="n"&gt;Block&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;block&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;blocks&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;blockMap&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="py"&gt;.id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;block&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is nice and concise, but you have to create the map and then mutate it. In Rust, by contrast, data is presumed immutable unless you mark it as &lt;code&gt;mut&lt;/code&gt;. Writing code in Go that minimizes mutation is ugly and not idiomatic (for example, see this &lt;a href="https://blog.logrocket.com/functional-programming-in-go/" rel="noopener noreferrer"&gt;post&lt;/a&gt;). And Go’s lack of generics means &lt;code&gt;map&lt;/code&gt;, &lt;code&gt;filter&lt;/code&gt;, and &lt;code&gt;reduce&lt;/code&gt; or &lt;code&gt;fold&lt;/code&gt; are not really a thing in Go. In practice this means writing a lot more for loops manually and building up slices or maps. &lt;/p&gt;

&lt;p&gt;With Rust, thread-safe code become much easier to write, which follows from Rust’s core principle of ownership (In short, you can only have one mutable reference to any given piece of data). Simple map and reduce operations can be parallelized with great ease by dropping in &lt;a href="https://github.com/rayon-rs/rayon" rel="noopener noreferrer"&gt;Rayon&lt;/a&gt;. For other use cases you can wrap your code in an &lt;code&gt;Arc&lt;/code&gt; (Atomic reference counter) and proceed a bit more manually. It’s still possible to shoot your self in the foot, but Rust protects you from many mistakes at compile time. I was able to parallelize some geospatial operations and graph traversal in a period of hours thanks to Rust’s robust tools for concurrency and parallelism.&lt;/p&gt;

&lt;p&gt;Go also has robust concurrency primitives built around go functions and channels. Go enforces less at compile time, however. For instance, the default map in Go is not thread safe. But the Go compiler will happily let you mutate a map within in go function. You’ll just likely hit a panic at runtime (at least according to this &lt;a href="https://quii.gitbook.io/learn-go-with-tests/go-fundamentals/concurrency" rel="noopener noreferrer"&gt;book&lt;/a&gt; you need channels to update a map in parallel).&lt;/p&gt;

&lt;p&gt;Of course most application level code is IO bound. Neither Go nor Rust make things as easy as &lt;code&gt;Promise.all&lt;/code&gt; in JavaScript. But hopefully this will get easier as stable async and await continue to trickle out through the Rust ecosystem.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Hard
&lt;/h2&gt;

&lt;p&gt;Rust has a reputation for being hard to learn, and to an extent this is true. Learning to deal with the borrow checker is hard. Rust’s borrow checker is the part of the compiler that enforces memory safety. In short, you can’t have multiple mutable references to the same data. Lots of things you do without thinking in a language with a garbage collector become harder (passing a list to a function for instance: do I need reference to a vector? Or a reference to a vector of references? does anything need to be mutated? Ahh!). You end up with a lot of statements like this from the compiler:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flt38zlj9wjx532jg2bwq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flt38zlj9wjx532jg2bwq.png" alt="Screen Shot 2021-07-28 at 2.11.49 PM"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The upshot of all this is great: memory and thread safety largely enforced by the compiler without a garbage collector. That Rust delivers that is, quite frankly, amazing. But it does force the programmer to think about memory and references and makes certain data modeling patterns nigh impossible (double linked lists or anything really with circular references). The compiler enforces good habits but the virtue is hard at first, especially when you’re used to being proficient quickly in a new language. &lt;/p&gt;

&lt;p&gt;Go is useful as a comparand here: Go’s minimal syntax and set of distinctives are quite easy for an experienced developer to pick up. You can go from no Go to building a functional app in a few weeks if you’ve already learned a few languages before. There will be relatively few surprises or headaches. You won’t be a master, but you’ll be productive quickly. Rust’s learning curve is steeper.&lt;/p&gt;

&lt;p&gt;On the other hand, we shouldn’t overstate Rust’s weirdness. If you’re mostly writing application level code, rather than libraries, writing Rust feels a lot like writing functionally inflected Typescript. Their &lt;a href="https://newrustacean.com/show_notes/bonus/translating_between_languages/index.html" rel="noopener noreferrer"&gt;type systems &lt;/a&gt;diverge, but the everyday experience is much closer than one might expect, especially when considering that Rust compiles down to low level machine code. Rust is vastly more pleasant to work in than C.&lt;/p&gt;

&lt;p&gt;My other big initial headache with Rust was learning the Rust idioms for conversion between types. Rust has a generics system built on traits that is extremely powerful, and the idiomatic way to convert between types is to use the From and TryFrom traits. Here’s an example of converting between two types of geometry:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;geojson_str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;r#"
{
    "type": "Feature",
    "properties": {
        "name": "Firestone Grill"
    },
    "geometry": {
        "type": "Point",
        "coordinates": [-120.66029,35.2812]
    }
}
"#&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;geojson&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;geojson_str&lt;/span&gt;&lt;span class="py"&gt;.parse&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;GeoJson&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;geometry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;geo&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Geometry&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;geojson&lt;/span&gt;
    &lt;span class="py"&gt;.geometry&lt;/span&gt;
    &lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;.try_into&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;geos_geometry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;geos&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Geometry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;geometry&lt;/span&gt;&lt;span class="nf"&gt;.try_into&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// use Rust's geos bindings to do something interesting...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The hard part of this is discoverability. I’m a big fan of “autocomplete as documentation.” It’s really nice  like to be able to type &lt;code&gt;geometry.&lt;/code&gt; and see what I can convert a type into. But generic methods like this lead to a lot of trial and error until you learn how to make sense of the code docs. It’s even worse when you’re dealing with enums, since then you have to sort out whether the enum or the different enumerated items are valid to convert. The Rust community is well aware of the problem here: I think the main solution is for projects to have full code samples illustrating conversions, not simple a reference to the traits.&lt;/p&gt;

&lt;p&gt;A minor annoyance around readability. I rather like Go’s idiom of “keep the happy path on the left.” Rust’s enumerations make this much harder to do. With idiomatic Rust you end up having to read a lot like Lisp, from the inside out. The &lt;code&gt;?&lt;/code&gt; operator in Rust 2018 makes this easier, but you have to produce custom error types to use in a function or method that can error in more than one way.&lt;/p&gt;

&lt;p&gt;A final point to note is the ecosystem. Rust’s ecosystem isn’t as mature as Go’s or (of course) JavaScript’s. You’re much less likely to have mature api clients for that service you need (even AWS’s are still in beta). On the other hand, there are mature libraries for doing web apps and some areas where Rust is definitely better than Go: geospatial processing being a crucial one for me, web assembly being another. Rust’s popularity is only increasing and the broader developer community has largely settled on Rust as a replacement to C and C++. The creator of Node is writing its spiritual successor, Deno, in Rust, for instance, and recently said on a podcast that he’d never start another C project).&lt;/p&gt;

&lt;p&gt;The need for more libraries is also an opportunity for an aspiring open source dev: there’s tons of interesting work to do and my experience has been that the Rust community is extremely friendly and welcoming. Pick a project you like and ask how you can help!&lt;/p&gt;

&lt;h3&gt;
  
  
  Links
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Why Rust is hard: &lt;a href="https://vorner.github.io/difficult.html" rel="noopener noreferrer"&gt;https://vorner.github.io/difficult.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Geospatial Libraries in Rust: &lt;a href="https://georust.org/" rel="noopener noreferrer"&gt;https://georust.org/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>rust</category>
      <category>geospatial</category>
      <category>go</category>
    </item>
    <item>
      <title>Speeding up the creation of infrastructure code</title>
      <dc:creator>Alex Poulos</dc:creator>
      <pubDate>Tue, 05 Jan 2021 21:14:48 +0000</pubDate>
      <link>https://dev.to/mapoulos/speeding-up-the-creation-of-infrastructure-code-39f4</link>
      <guid>https://dev.to/mapoulos/speeding-up-the-creation-of-infrastructure-code-39f4</guid>
      <description>&lt;p&gt;Building cloud applications is hard. The number of services available from public cloud providers is astonishing, and these offerings can dramatically increase your team’s velocity. And yet, integrating these services into a product is &lt;em&gt;hard&lt;/em&gt;: documentation is not always as clear or well-organized as you’d like, and all the more when a particular product feature might need to direct requests to 5 or 6 different AWS services, each of which requires piles of JSON to configure correctly. Here's an approach I've used successfully across several different applications recently:&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Create whatever you need in the AWS Web Console
&lt;/h2&gt;

&lt;p&gt;Amazon’s web console holds your hand. This is a good thing, but should be used with care. The goal is not to do it once, then forget about it, but to do it the easy way, and the capture this in code. &lt;/p&gt;

&lt;p&gt;You probably know from perusing the docs what AWS services you're going to need: so fire up the console and start clicking away! For instance, you might make that S3 bucket with a dozen different life-cycle rules, or that ECR repo with a score of tag expiration settings. Depending on what you're doing, this might require coordinating resources across different AWS services (e.g. making an SQS queue, and a lambda).&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Use the AWS CLI tools to dump the configuration of the stuff you’ve made
&lt;/h2&gt;

&lt;p&gt;Trying to manually figure out how to map from AWS's Web Console to CloudFormation or API Client code takes forever. Fortunately, the AWS-CLI provides a much better way. You can use this to dump the JSON of all the entities you created in step 1. Maybe you're working with CloudFront. You can do this to list your distributions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws cloudfront list-distributions &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; distributions.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The exact command varies, of course, depending on the service. &lt;code&gt;aws &amp;lt;servicename&amp;gt; help&lt;/code&gt; will generally lead you to the right command. Generally you want one that starts with &lt;code&gt;list&lt;/code&gt; or &lt;code&gt;describe&lt;/code&gt; (e.g.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws ec2 describe-instances
aws dynamodb describe-table &lt;span class="nt"&gt;--table-name&lt;/span&gt; &amp;lt;TABLE_NAME&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Remember that the aws-cli tools are fundamentally just convenience wrappers to REST APIs, which is why they often aren’t terrible user friendly. REST APIs and traditional *nix tools have different structures and conventions (For instance, a *nix command would usually have required params expressed as positional arguments rather than named ones).&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Craft this into either into CloudFormation or client SDK code
&lt;/h2&gt;

&lt;p&gt;Now that you have a JSON representations of the entities you need, you can write these up as code, either as CloudFormation/CDK/Terraform templates, or with the AWS client SDKs. In my particular case, I wanted to create these resources in response to a REST API call, so I wrote up the creation logic in TypeScript using the AWS -v3 JavaScript SDK. These are awesome to use for a lot of reasons. I was able to copy and paste much of the JSON from step and just tweak the params that were different for each entity. And since it was TypeScript, I was told at compile time if a parameter was named incorrectly. It made juggling hundreds of lines of JSON configuration much less error-prone and frustrating.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion: The AWS CLI is your friend
&lt;/h2&gt;

&lt;p&gt;I’ve used this strategy to put together ECS blue/green deploy code and to set up some complicated video workflows with AWS's Elemental service suite. Juggling mountains of JSON is &lt;strong&gt;not&lt;/strong&gt; fun. Creating what you need in the web console, by contrast, and then exporting via the CLI will speed up your develop of infrastructure-facing code, especially if you can’t find good examples to follow. Good luck!&lt;/p&gt;

</description>
      <category>cloudnative</category>
      <category>typescript</category>
      <category>cloudskills</category>
    </item>
  </channel>
</rss>
