<?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>Forem: Anas Ismail Khan</title>
    <description>The latest articles on Forem by Anas Ismail Khan (@anasik).</description>
    <link>https://forem.com/anasik</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%2F61116%2Fb6c5e9f0-628c-4cc3-976d-3538350df89e.jpeg</url>
      <title>Forem: Anas Ismail Khan</title>
      <link>https://forem.com/anasik</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/anasik"/>
    <language>en</language>
    <item>
      <title>Why did Anders Hejlsberg choose Go for Typescript instead of C# or Rust?</title>
      <dc:creator>Anas Ismail Khan</dc:creator>
      <pubDate>Sun, 16 Mar 2025 00:00:00 +0000</pubDate>
      <link>https://forem.com/anasik/why-did-anders-hejlsberg-choose-go-for-typescript-instead-of-c-or-rust-1jeh</link>
      <guid>https://forem.com/anasik/why-did-anders-hejlsberg-choose-go-for-typescript-instead-of-c-or-rust-1jeh</guid>
      <description>&lt;p&gt;Ever since Anders Hejlsberg made the announcement for Project Corsa, aka Strada, aka typescript-go, there’s been a lot of unrest surrounding their decision to use Go.&lt;/p&gt;

&lt;p&gt;On one hand, we have the Rust fans demanding to know why Rust wasn’t chosen for this, considering the popularity of Rust as the de facto modern low-level language.&lt;/p&gt;

&lt;p&gt;The dev lead of Typescript, Ryan Cavanaugh himself, took to Reddit to address the first question&lt;sup id="fnref:1"&gt;1&lt;/sup&gt;. He said, and I quote:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“In the end we had two options - do a complete from-scrach rewrite in Rust, which could take years and yield an incompatible version of TypeScript that no one could actually use, or just do a port in Go and get something usable in a year or so and have something that’s extremely compatible in terms of semantics and extremely competitive in terms of performance.”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;On the other hand we have the C# community asking the real questions: Why did the lead architect of C# sit by such a decision? This one, was answered by Anders Hejlsberg himself in an interview with Michigan TypeScript&lt;sup id="fnref:2"&gt;2&lt;/sup&gt;:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“C# was considered but Go is definitely the lowest-level language we can get to and still have automatic garbage-collection […] C# is byte-code first and while it has some AOT, it’s not available on all platforms and it doesn’t have decades of hardening and wasn’t engineered that way to begin with. Go has a little more expressiveness when it comes to data-structures and inline structs. Our JS codebase is written in a highly functional style with very few classes which is also a characteristic of Go […] we would have had to switch to an OOP paradigm to switch to C# […] ultimately that was the path of least resistance.”&lt;/em&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Link to Ryan’s reddit comment: &lt;a href="https://lnkd.in/dqHx6gj3" rel="noopener noreferrer"&gt;https://lnkd.in/dqHx6gj3&lt;/a&gt; ↩&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link to Anders’ interview: &lt;a href="https://lnkd.in/dUJiwEzv" rel="noopener noreferrer"&gt;https://lnkd.in/dUJiwEzv&lt;/a&gt; ↩&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>andershejlsberg</category>
      <category>ryancavanaugh</category>
      <category>typescript</category>
    </item>
    <item>
      <title>My second contribution to ASP.NET Core OData</title>
      <dc:creator>Anas Ismail Khan</dc:creator>
      <pubDate>Sat, 22 Feb 2025 17:42:10 +0000</pubDate>
      <link>https://forem.com/anasik/my-second-contribution-to-aspnet-core-odata-47c0</link>
      <guid>https://forem.com/anasik/my-second-contribution-to-aspnet-core-odata-47c0</guid>
      <description>&lt;p&gt;A month ago, I wrote about my first contribution to an open-source, Microsoft-maintained, project, from June 2024, that got merged by November 2024. What I didn't mention at that time was that &lt;em&gt;that&lt;/em&gt; wasn't my only contribution to that project. Shortly after that pull request got merged, I opened a second one. Once again, I created an issue, to report a bug, and a pull request, to solve the bug, back to back. However, this time I made them in the correct order. &lt;/p&gt;

&lt;p&gt;The same project from the last article required me to enable ETags on the OData API that I was working on. An ETag is an HTTP header that's used for cache-invalidation and concurrency control. It's basically like a hash representing the state of the resource/data at said endpoint. The client may use it as a cache key and the server can use it for concurrency control when multiple requests attempt to update the resource at the same time. ETag values are based on a special field/column on the resource record that changes every time the record is updated. &lt;/p&gt;

&lt;p&gt;Lets talk for a moment about how ETags help with concurrency control. There's a concept called &lt;em&gt;Optimistic Concurrency Control&lt;/em&gt;. It's a non-locking mechanism that gets its name from the optimism of assuming that conflicts are very unlikely to occur. I like to think that it gets its name from the assumption that the user would be responsible enough to include the &lt;code&gt;if-match&lt;/code&gt; header in the update request. This header, which holds the last known ETag value known by the client, is compared with the current value on the resource to detect conflicts. &lt;/p&gt;

&lt;p&gt;Caching works in a similar manner. Client passes the ETag in a header called &lt;code&gt;if-none-match&lt;/code&gt; in a GET request. If the value matches, the server sends back a &lt;code&gt;304 Not Modified&lt;/code&gt; status. Otherwise it sends back the whole record. This reduces bandwidth usage and speeds up the response time. &lt;/p&gt;

&lt;p&gt;In C#, a popular convention, but by no means a rule, for these concurrency check fields is to use a &lt;code&gt;byte[]&lt;/code&gt; field called &lt;code&gt;RowVersion&lt;/code&gt; annotated with a &lt;code&gt;[Timestamp]&lt;/code&gt; or &lt;code&gt;[ConcurrencyCheck]&lt;/code&gt; attribute. The &lt;code&gt;Microsoft.AspNetCore.OData&lt;/code&gt; package has a lot of abstraction built in to simplify the generation and validation of ETags. If your model has concurrency fields set up correctly, it automatically picks them up and handles conversions. It even goes one step further and adds a field called &lt;code&gt;@odata.etag&lt;/code&gt; to the JSON response, rather than just putting it in the headers. &lt;em&gt;And even more importantly&lt;/em&gt;, it gives you a these two prebuilt methods for computing and comparing ETags:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;queryOptions.IfMatch.ApplyTo(IQueryable query)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;queryOptions.IfNoneMatch.ApplyTo(IQueryable query)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;ApplyTo&lt;/code&gt; method, which exists on the &lt;code&gt;ETag&lt;/code&gt; class, has a &lt;code&gt;foreach&lt;/code&gt; loop that iterates over all the concurrency properties and compares them one by one with the values on the actual record. As you might have already guessed, for each field, it was performing a simple equality comparison. Well and good, until you introduce array fields like 90% of the users like to. Meaning, the &lt;code&gt;IfMatch&lt;/code&gt; and &lt;code&gt;IfNoneMatch&lt;/code&gt; headers were definitely not having the intended effect for what was undoubtedly the most popular use-case.&lt;/p&gt;

&lt;p&gt;Initially, I thought it was just me and that I had configured something incorrectly. To make sure, I decided to take a look at the existing E2E tests for the ETag class. Surprisingly, not a single field in the model for the test was of the type &lt;code&gt;byte[]&lt;/code&gt;. I proceeded to add one and sure enough, the test failed immediately. I went back to the &lt;code&gt;ETag.ApplyTo&lt;/code&gt; method and added a check inside the loop for array types. I added some code to handle the array condition and guess what? The tests passed.&lt;/p&gt;

&lt;p&gt;I opened an &lt;a href="https://github.com/OData/AspNetCoreOData/issues/1332" rel="noopener noreferrer"&gt;issue&lt;/a&gt; and a &lt;a href="https://github.com/OData/AspNetCoreOData/pull/1334" rel="noopener noreferrer"&gt;pull request&lt;/a&gt; immediately. I added detailed instructions for reproducing the bug using the existing E2E ETag Test code. This happened at the very end of October. Since the team was busy creating releases for the already merged bugs, it took them as late as January to actually respond. They asked for more tests and I explained how I brilliantly modified an existing one. I thought they'd have a problem with me modifying an existing test since I myself didn't feel all that great about it but all I had really done was add a new field to the test and make sure that all the existing test cases were ignoring that field except for the one test case that actually needed it. &lt;/p&gt;

&lt;p&gt;Luckily, a few days from that, they approved my changes and then another few days after that, they merged it. They are yet to make a release that includes this fix; &lt;del&gt;because including this fix, there's hardly been any changes to that branch&lt;/del&gt; however, I'm hoping it's just around the corner because we are forced to use a fork in our project, instead of the NuGet package, solely because of this bug.&lt;/p&gt;




&lt;h2&gt;
  
  
  Got a problem that needs solving?
&lt;/h2&gt;

&lt;p&gt;➡️ &lt;strong&gt;Debugging is my superpower. Let me know if you have a bug that needs to be squashed at: &lt;a href="mailto:contact@anasismail.com"&gt;contact@anasismail.com&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This post first appeared on the my blog at &lt;a href="https://anasismail.com/oops-i-did-it-again" rel="noopener noreferrer"&gt;https://anasismail.com/oops-i-did-it-again&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>microsoft</category>
      <category>csharp</category>
      <category>aspnetcoreodata</category>
    </item>
    <item>
      <title>How I coded for Microsoft without getting hired</title>
      <dc:creator>Anas Ismail Khan</dc:creator>
      <pubDate>Sat, 01 Feb 2025 17:03:23 +0000</pubDate>
      <link>https://forem.com/anasik/how-i-coded-for-microsoft-without-getting-hired-351p</link>
      <guid>https://forem.com/anasik/how-i-coded-for-microsoft-without-getting-hired-351p</guid>
      <description>&lt;p&gt;I've been a fan of open-source longer than I have been an adult. The moment I first switched to Linux in 2012, I knew it would remain my daily driver until I could afford to buy a Mac. As I, both voluntarily and involuntarily, continued to ditch my usual programs in favor of free and open-source alternatives, the deeper I dove into the world of open-source and the stronger became my desire to contribute to it.&lt;/p&gt;

&lt;p&gt;I didn't have to wait long because between the Septembers of 2014 and 2015, I led the development of Emu-OS — An ubuntu-based distro for retro-gaming. This was a short-lived but two-pronged high because by then, building an operating system had also already been my dream for a couple of years. Sadly, just when Emu-OS started gaining popularity, my team abandoned me and I was too young to know how to continue on my own. Since then, I’ve come a long way, both as a developer and a professional, but Emu-OS remained my sole open-source contribution until just a few months ago. &lt;/p&gt;

&lt;p&gt;Last May, I started architecting a project in C# which revolved around OData — a standard maintained primarily by Microsoft for building RESTful APIs with powerful querying capabilities. In fact, &lt;em&gt;I particularly chose to build it in C# because of that.&lt;/em&gt; It was the right decision because while there's fairly official OData libraries for both Java and Javascript, they are ridiculously lacking when compared to &lt;code&gt;Microsoft.AspNetCore.OData&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It was practically our first day taking that library for a test-drive when a fellow coder showed me a bug. Remember when I said earlier that OData has &lt;em&gt;powerful querying capabilities&lt;/em&gt;?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;randomapi.com/Products?$select=ProductID,ProductName,Price,Category&amp;amp;$filter=Price gt 20 and Category eq 'Electronics'&amp;amp;$orderby=Price desc&amp;amp;$top=10&amp;amp;$skip=5&amp;amp;$expand=Supplier&amp;amp;$count=true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above query would fetch the ID, Name, Price and Category of the top 10 Electronic Products whose price exceeds $20, sorted from highest to lowest price. Notice the part that says &lt;code&gt;$expand=Supplier&lt;/code&gt;? That's a join with the Suppliers table. Powerful stuff right? &lt;/p&gt;

&lt;p&gt;Now let's talk about the bug. My teammate noticed that if you try to &lt;code&gt;$select&lt;/code&gt; a field that was housing a &lt;code&gt;Collection&amp;lt;String&amp;gt;&lt;/code&gt;, it would crash. I recreated the bug and immediately noticed that the problem was specific to SQL databases. If you had a mock database in-memory, or if you were to convert the &lt;code&gt;IQueryable&lt;/code&gt; to a &lt;code&gt;List&lt;/code&gt; it would work fine. I also noticed that while on SQL Server it was happening only with string collections, on SQLite it was happening with numeric types too. This made perfect sense since Primitive Collections were not even supported before EF Core 8, however it was also clear that this wasn't defined behavior. &lt;/p&gt;

&lt;p&gt;I decided to clone the repo for &lt;code&gt;Microsoft.AspNetCore.OData&lt;/code&gt;, use a package reference in my project and debug through its lines. As early as the first run, I was able to isolate the problematic part of the code because a quick glance at the variables in the debugger showed me exactly the kind of LINQ that was part of the error message. Long story short, here's what was happening:&lt;br&gt;
While collections were handled separately there was absolutely no discrimination in terms of base types. The same code was powering collections of navigations, complex and primitives. For each element of the collection it was performing a nested select like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;collection.Select(field =&amp;gt; field.Select(d=&amp;gt; d))&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;While this makes perfect sense for navigations and complex types, for primitives it meant absolutely nothing and theoretically couldn't even be executed. &lt;del&gt;What's weird to me is that on SQL Server, integers could handle this when strings couldn't despite the fact that on a spectrum of scalar to collection, strings lean towards the collection side.&lt;/del&gt; I grabbed a list of all the primitive types as defined in the release notes for EF Core 8 and added a condition where if the underlying type in the collection was any of those, it should proceed without the nested select. Worked like a charm. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/OData/AspNetCoreOData/pull/1282" rel="noopener noreferrer"&gt;I opened my PR on July 16th 2024.&lt;/a&gt; When it failed to catch attention, &lt;a href="https://github.com/OData/AspNetCoreOData/issues/1286" rel="noopener noreferrer"&gt;I created an issue for the bug two days later&lt;/a&gt;. That did the trick. Throughout August, I worked with the maintainers to make sure the code was up-to-standards, and that all tests were passing and everything was well-documented and more importantly, correctly documented. While I got approved a couple of times in September, it wasn't until the latter half of October that the nitpicking stopped. In November, I reached out to them and requested that they merge it because my project depended on it and they heeded my request. 10 days later, &lt;a href="https://github.com/OData/AspNetCoreOData/releases/tag/8.2.6" rel="noopener noreferrer"&gt;the first release with my commits&lt;/a&gt; came out. &lt;/p&gt;

&lt;p&gt;Those of you who have made it this far, I want to thank you for taking the time to read this. As I finished typing the last paragraph, I realized that it reads like an excited child wrote it. But that's exactly how I feel. I've been a developer for the past 13 years, worked with people from various countries, written code in every major language, and made a lot of money, but very few experiences have felt as rewarding as this.&lt;/p&gt;




&lt;h2&gt;
  
  
  Got a problem that needs solving?
&lt;/h2&gt;

&lt;p&gt;➡️ &lt;strong&gt;Debugging is my superpower. Let me know if you have a bug that needs to be squashed at: &lt;a href="mailto:contact@anasismail.com"&gt;contact@anasismail.com&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This post first appeared on the my blog at &lt;a href="https://anasismail.com/how-to-work-for-microsoft-without-getting-hired" rel="noopener noreferrer"&gt;https://anasismail.com/how-to-work-for-microsoft-without-getting-hired&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>microsoft</category>
      <category>odata</category>
      <category>aspnetcore</category>
      <category>csharp</category>
    </item>
  </channel>
</rss>
