<?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: semuserable</title>
    <description>The latest articles on DEV Community by semuserable (@semuserable).</description>
    <link>https://dev.to/semuserable</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%2F140856%2F0133a9a0-8d35-4170-9a10-cdb7f159d8ec.png</url>
      <title>DEV Community: semuserable</title>
      <link>https://dev.to/semuserable</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/semuserable"/>
    <language>en</language>
    <item>
      <title>dotnet cross-platform interop with C via Environment.ProcessId system call</title>
      <dc:creator>semuserable</dc:creator>
      <pubDate>Fri, 28 Mar 2025 08:19:12 +0000</pubDate>
      <link>https://dev.to/semuserable/dotnet-cross-platform-interop-with-c-via-environmentprocessid-system-call-46bi</link>
      <guid>https://dev.to/semuserable/dotnet-cross-platform-interop-with-c-via-environmentprocessid-system-call-46bi</guid>
      <description>&lt;p&gt;The goal of this article is to understand how high-level &lt;code&gt;dotnet&lt;/code&gt; code interoperates with low-level &lt;code&gt;C&lt;/code&gt; code in a cross-platform manner when making &lt;a href="https://en.wikipedia.org/wiki/System_call" rel="noopener noreferrer"&gt;system call&lt;/a&gt; via &lt;a href="https://learn.microsoft.com/en-us/dotnet/api/system.environment.processid?view=net-9.0" rel="noopener noreferrer"&gt;Environment.ProcessId&lt;/a&gt; in &lt;code&gt;dotnet&lt;/code&gt;.  &lt;/p&gt;

&lt;p&gt;We'll delve into the differences between running it on &lt;code&gt;windows&lt;/code&gt; and &lt;code&gt;unix-like&lt;/code&gt; (&lt;code&gt;macOS&lt;/code&gt;, &lt;code&gt;Linux&lt;/code&gt;) operating systems in a cross-platform manner. We'll also write some &lt;code&gt;C&lt;/code&gt; code to check and prove that we really understand what's going on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Before the start
&lt;/h2&gt;

&lt;p&gt;I assume my reader is a person who is well-versed with general programming concepts and have a curiosity towards inner working of &lt;code&gt;dotnet&lt;/code&gt; platform. &lt;/p&gt;

&lt;p&gt;Just to note, I'm not an expert in system programming topic, so I may be wrong or misinterpret something. But for this article, I wanted to play around with &lt;code&gt;C&lt;/code&gt; and prove the concepts that I want to understand. Basically, the whole point of this article is to document my findings.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pre-requisites
&lt;/h3&gt;

&lt;p&gt;If you want to follow along, this is the suggested list of tools that should be installed&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://dotnet.microsoft.com/en-us/" rel="noopener noreferrer"&gt;dotnet&lt;/a&gt; (&lt;a href="https://dotnet.microsoft.com/en-us/download/dotnet/9.0" rel="noopener noreferrer"&gt;.NET 9&lt;/a&gt; is used for this article) and &lt;code&gt;C#&lt;/code&gt; &lt;a href="https://en.wikipedia.org/wiki/Decompiler" rel="noopener noreferrer"&gt;decompiler&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;a copy of &lt;a href="https://github.com/dotnet/runtime" rel="noopener noreferrer"&gt;dotnet runtime&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://en.wikipedia.org/wiki/Integrated_development_environment" rel="noopener noreferrer"&gt;IDE&lt;/a&gt; of choice - &lt;a href="https://code.visualstudio.com/" rel="noopener noreferrer"&gt;Visual Studio Code&lt;/a&gt;, &lt;a href="https://visualstudio.microsoft.com/" rel="noopener noreferrer"&gt;Visual Studio&lt;/a&gt;, &lt;a href="https://www.jetbrains.com/rider/" rel="noopener noreferrer"&gt;Rider&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;any operating system (OS) you're most comfortable with - &lt;a href="https://en.wikipedia.org/wiki/MacOS" rel="noopener noreferrer"&gt;macOS&lt;/a&gt;, &lt;a href="https://en.wikipedia.org/wiki/Linux" rel="noopener noreferrer"&gt;Linux&lt;/a&gt;, &lt;a href="https://en.wikipedia.org/wiki/Microsoft_Windows" rel="noopener noreferrer"&gt;Windows&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.docker.com/" rel="noopener noreferrer"&gt;docker&lt;/a&gt; and/or any virtualization technology - &lt;a href="https://www.parallels.com/" rel="noopener noreferrer"&gt;Parallels&lt;/a&gt;, &lt;a href="https://mac.getutm.app/" rel="noopener noreferrer"&gt;UTM&lt;/a&gt;, &lt;a href="https://www.virtualbox.org/" rel="noopener noreferrer"&gt;virtualbox&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All provided examples were done on &lt;code&gt;macOS M1&lt;/code&gt; (&lt;a href="https://en.wikipedia.org/wiki/AArch64" rel="noopener noreferrer"&gt;aarch64&lt;/a&gt; architecture), &lt;code&gt;docker&lt;/code&gt; and &lt;code&gt;Rider&lt;/code&gt; was used as an &lt;code&gt;IDE&lt;/code&gt; and &lt;code&gt;decompiler&lt;/code&gt; for &lt;code&gt;C#&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  System call
&lt;/h2&gt;

&lt;p&gt;Before delving into the code, let's provide a definition to a &lt;code&gt;system call&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/System_call" rel="noopener noreferrer"&gt;System call&lt;/a&gt; is a mechanism that allows user-level applications to request services from the operating system's kernel, such as accessing hardware, managing files, creating and terminating processes, and facilitating communication between processes.&lt;/p&gt;

&lt;p&gt;As an example, if your code creates a file (via &lt;a href="https://learn.microsoft.com/en-us/dotnet/api/system.io.file.create?view=net-8.0" rel="noopener noreferrer"&gt;File.Create&lt;/a&gt; high-level API) you're basically making a &lt;code&gt;system call&lt;/code&gt; to the underlying operating system. If you make an HTTP request, you do a &lt;code&gt;system call&lt;/code&gt;, and so on.&lt;/p&gt;

&lt;h2&gt;
  
  
  The path of &lt;a href="https://learn.microsoft.com/en-us/dotnet/api/system.environment.processid?view=net-9.0" rel="noopener noreferrer"&gt;Environment.ProcessId&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;We'll start exploring the simplest possible &lt;code&gt;system call&lt;/code&gt; - &lt;a href="https://learn.microsoft.com/en-us/dotnet/api/system.environment.processid?view=net-9.0" rel="noopener noreferrer"&gt;Environment.ProcessId&lt;/a&gt; (get the unique identifier for the current process).&lt;/p&gt;

&lt;p&gt;Let's introduce various deepness levels:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;client-level&lt;/code&gt; developer-level calls, the decompilation starts here, this code is expected to be written by a developer and called in &lt;code&gt;Production&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;high-level&lt;/code&gt; decompiled &lt;code&gt;C#&lt;/code&gt; code, implementation details can start to differ, this is not expected to be written directly by a developer&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;low-level&lt;/code&gt; direct or indirect calls to &lt;code&gt;C\C++&lt;/code&gt; code, operating system specific implementation details, the lowest level we're aiming for&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each level will be accompanied by a diagram for visual understanding of calls. For various operating systems, an appropriate decompiled code will be presented too.&lt;/p&gt;

&lt;p&gt;Let's get started!&lt;/p&gt;

&lt;h3&gt;
  
  
  Client-level
&lt;/h3&gt;

&lt;p&gt;This is the code that you should write if you want to get a process id&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;processId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Environment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ProcessId&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;processId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// output: 1 (this is an example value)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's start outlining this call via a diagram&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F91a4nj68lx1hlr26eril.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F91a4nj68lx1hlr26eril.png" alt="client-level diagram showing Environment.ProcessId call" width="314" height="140"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  High-level
&lt;/h3&gt;

&lt;p&gt;Now we need to decompile &lt;code&gt;Environment.ProcessId&lt;/code&gt; which resides in &lt;code&gt;System.Runtime.dll&lt;/code&gt;. We'll be decompiling for two major flavours of operating systems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;unix-like&lt;/code&gt; - various &lt;code&gt;Unix&lt;/code&gt; and &lt;code&gt;Unix-like&lt;/code&gt; operating systems: &lt;code&gt;macOS&lt;/code&gt;, &lt;code&gt;gnu/Linux&lt;/code&gt; (&lt;code&gt;Debian&lt;/code&gt;, &lt;code&gt;Ubuntu&lt;/code&gt;, etc.), &lt;code&gt;musl/Linux&lt;/code&gt; (&lt;code&gt;Alpine&lt;/code&gt;), &lt;code&gt;iOS&lt;/code&gt;, &lt;code&gt;Android&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;windows&lt;/code&gt; - &lt;code&gt;Windows&lt;/code&gt; only&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;info&lt;/strong&gt; "Decompilation"&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;unix-like&lt;/code&gt; flavour is decompiled on &lt;code&gt;macOS M1&lt;/code&gt; via &lt;code&gt;Rider&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;windows&lt;/code&gt; flavour is decompiled on &lt;code&gt;Windows 11&lt;/code&gt; on &lt;code&gt;Parallels&lt;/code&gt; via &lt;code&gt;Rider&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;Decompiled code&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;unix-like&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;partial&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Environment&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;ProcessId&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;get&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;processId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s_processId&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;processId&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="n"&gt;s_processId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;processId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;GetProcessId&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
          &lt;span class="c1"&gt;// Assume that process Id zero is invalid for user processes. It holds for all mainstream operating systems.&lt;/span&gt;
          &lt;span class="n"&gt;Debug&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;processId&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;processId&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&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;ul&gt;
&lt;li&gt;
&lt;code&gt;windows&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;partial&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Environment&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;ProcessId&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;get&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;processId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Environment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;s_processId&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;processId&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;Environment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;s_processId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;processId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Environment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetProcessId&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;processId&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&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;blockquote&gt;
&lt;p&gt;&lt;strong&gt;note&lt;/strong&gt; "Implementation details"&lt;/p&gt;

&lt;p&gt;These are the implementation details, important point here is that it can change between &lt;code&gt;dotnet&lt;/code&gt; versions. Don't expect it to be be always the same.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We can already notice differences between &lt;code&gt;unix-like&lt;/code&gt; and &lt;code&gt;windows&lt;/code&gt; operating systems. Although it looks quite similar, in reality these are two completely different calls. Notice that &lt;code&gt;Environment&lt;/code&gt; class is declared as &lt;code&gt;static partial&lt;/code&gt; meaning that during &lt;code&gt;dotnet&lt;/code&gt; runtime build process we can use (substitute) platform-specific implementations.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F6b3nrujul3srqua5tb5b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F6b3nrujul3srqua5tb5b.png" alt="high-level decompilation diagram" width="710" height="388"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Low-level
&lt;/h3&gt;

&lt;p&gt;In order to really see this difference we need to go one level deeper. Let's decompile &lt;code&gt;GetProcessId()&lt;/code&gt; for &lt;code&gt;unix-like&lt;/code&gt; and &lt;code&gt;Environment.GetProcessId()&lt;/code&gt; for &lt;code&gt;windows&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;unix-like&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Environment.Unix.cs&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;partial&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Environment&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;MethodImplAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MethodImplOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NoInlining&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt; &lt;span class="c1"&gt;// Avoid inlining PInvoke frame into the hot path&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;GetProcessId&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Interop&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetPid&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Interop.GetPid.cs&lt;/span&gt;
&lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;partial&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Interop&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;partial&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Sys&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;LibraryImport&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Libraries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SystemNative&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;EntryPoint&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"SystemNative_GetPid"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
        &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;partial&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;GetPid&lt;/span&gt;&lt;span class="p"&gt;();&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;ul&gt;
&lt;li&gt;
&lt;code&gt;windows&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Environment.cs&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;partial&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Environment&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;MethodImpl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MethodImplOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NoInlining&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;GetProcessId&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Interop&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Kernel32&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetCurrentProcessId&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Interop.cs&lt;/span&gt;
&lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Interop&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Kernel32&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;LibraryImport&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"kernel32.dll"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;DllImport&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"kernel32.dll"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="kt"&gt;uint&lt;/span&gt; &lt;span class="nf"&gt;GetCurrentProcessId&lt;/span&gt;&lt;span class="p"&gt;();&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;blockquote&gt;
&lt;p&gt;&lt;strong&gt;note&lt;/strong&gt; "Combined results"&lt;/p&gt;

&lt;p&gt;These are combined results from several levels of decompilation.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here we've been introduced to &lt;code&gt;Interop&lt;/code&gt; class which is a bridge between managed and unmanaged (native) worlds.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F51fn62dka2sy6h9zfhcb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F51fn62dka2sy6h9zfhcb.png" alt="high-level further decompilation diagram" width="784" height="528"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From now on, we'll investigate each operating system flavour separately starting with &lt;code&gt;windows&lt;/code&gt; and then moving on to &lt;code&gt;unix-like&lt;/code&gt;, which will be covered in more depth.&lt;/p&gt;

&lt;h4&gt;
  
  
  windows
&lt;/h4&gt;

&lt;p&gt;Firstly, we'll look into &lt;code&gt;windows&lt;/code&gt; chain of calls.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;LibraryImport&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"kernel32.dll"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;DllImport&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"kernel32.dll"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="kt"&gt;uint&lt;/span&gt; &lt;span class="nf"&gt;GetCurrentProcessId&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All &lt;code&gt;C&lt;/code&gt; interop calls are facilitated via &lt;a href="https://learn.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.dllimportattribute?view=net-9.0" rel="noopener noreferrer"&gt;DllImport&lt;/a&gt; (old approach) and/or &lt;a href="https://learn.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.libraryimportattribute?view=net-8.0" rel="noopener noreferrer"&gt;LibraryImport&lt;/a&gt; (new approach). &lt;code&gt;DllImport&lt;/code&gt; (or &lt;code&gt;LibraryImport&lt;/code&gt;) is the real bridge that connects managed and unmanaged worlds in &lt;code&gt;dotnet&lt;/code&gt;. This is part of &lt;code&gt;dotnet&lt;/code&gt; &lt;a href="https://learn.microsoft.com/en-us/dotnet/standard/native-interop/pinvoke" rel="noopener noreferrer"&gt;Platform Invoke (P/Invoke)&lt;/a&gt; technology.&lt;/p&gt;

&lt;p&gt;This code is telling the following: import &lt;code&gt;kernel32.dll&lt;/code&gt; dynamic library (only exists on &lt;code&gt;Windows&lt;/code&gt;) allowing access to native &lt;a href="https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getcurrentprocessid" rel="noopener noreferrer"&gt;GetCurrentProcessId&lt;/a&gt; function. Using the above declaration the function name must fully match the native counterpart, otherwise it won't work.&lt;/p&gt;

&lt;p&gt;This is it for &lt;code&gt;windows&lt;/code&gt;. It's just a direct call to &lt;code&gt;GetCurrentProcessId&lt;/code&gt; from &lt;code&gt;kernel32.dll&lt;/code&gt;, that's it. But for &lt;code&gt;unix-like&lt;/code&gt; it's not that simple.&lt;/p&gt;

&lt;h4&gt;
  
  
  unix-like
&lt;/h4&gt;

&lt;p&gt;Now it's turn to delve into &lt;code&gt;unix-like&lt;/code&gt; chain of calls.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;LibraryImport&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Libraries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SystemNative&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;EntryPoint&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"SystemNative_GetPid"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;partial&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;GetPid&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Shim via &lt;code&gt;Libraries.SystemNative&lt;/code&gt;
&lt;/h5&gt;

&lt;p&gt;This is where the things start to diverge quite a bit. Firstly, instead of &lt;code&gt;kernel32.dll&lt;/code&gt; a lib called &lt;code&gt;Libraries.SystemNative&lt;/code&gt;&lt;br&gt;
is being loaded instead. Secondly, &lt;a href="https://learn.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.libraryimportattribute.entrypoint?view=net-9.0#system-runtime-interopservices-libraryimportattribute-entrypoint" rel="noopener noreferrer"&gt;LibaryImport.EntryPoint&lt;/a&gt; property says that there is a function called &lt;code&gt;SystemNative_GetPid&lt;/code&gt; that needs to be used in order to get process id.&lt;/p&gt;

&lt;p&gt;Let's go step by step. Looking into &lt;a href="https://github.com/dotnet/runtime" rel="noopener noreferrer"&gt;dotnet runtime&lt;/a&gt; we can find that &lt;a href="https://github.com/dotnet/runtime/blob/478cfe2f79dd6b33d678685f87b6c37e1a460191/src/libraries/Common/src/Interop/Unix/Interop.Libraries.cs" rel="noopener noreferrer"&gt;Libraries.SystemNative&lt;/a&gt; acts as a &lt;code&gt;shim&lt;/code&gt; (adapter) to a dynamic library called &lt;code&gt;libSystem.Native&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;partial&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Interop&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;partial&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Libraries&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;libc&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"libc"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// Shims&lt;/span&gt;
        &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;SystemNative&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"libSystem.Native"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;NetSecurityNative&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"libSystem.Net.Security.Native"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;CryptoNative&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"libSystem.Security.Cryptography.Native.OpenSsl"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;CompressionNative&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"libSystem.IO.Compression.Native"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;GlobalizationNative&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"libSystem.Globalization.Native"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;IOPortsNative&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"libSystem.IO.Ports.Native"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;HostPolicy&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"libhostpolicy"&lt;/span&gt;&lt;span class="p"&gt;;&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;blockquote&gt;
&lt;p&gt;&lt;strong&gt;info&lt;/strong&gt; "&lt;code&gt;shim&lt;/code&gt; explained"&lt;/p&gt;

&lt;p&gt;In the context of &lt;code&gt;dotnet&lt;/code&gt; and system libraries, a &lt;code&gt;shim&lt;/code&gt; is a small compatibility layer that acts as an intermediary between your application and the actual system APIs. It does the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;hides platform-specific details and provides a unified API&lt;/li&gt;
&lt;li&gt;allows &lt;code&gt;dotnet&lt;/code&gt; code to run on multiple operating systems 
without changing how it calls system functions&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h5&gt;
  
  
  libSystem.Native on various unix-like operating systems
&lt;/h5&gt;

&lt;p&gt;So, it seems that for &lt;code&gt;unix-like&lt;/code&gt; operating systems there is an additional library called &lt;code&gt;libSystem.Native&lt;/code&gt; that's supplied by &lt;code&gt;dotnet runtime&lt;/code&gt;. Let's inline it's name and check the call again.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;LibraryImport&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"libSystem.Native"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;EntryPoint&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"SystemNative_GetPid"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;partial&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;GetPid&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In order for this to work &lt;code&gt;libSystem.Native&lt;/code&gt; dynamic library must be physically present on &lt;code&gt;unix-like&lt;/code&gt; operating system.&lt;/p&gt;

&lt;p&gt;Let's find it!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;info&lt;/strong&gt; "dynamic libraries on various operating systems"&lt;/p&gt;

&lt;p&gt;Various operating systems use different dynamic library extensions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;macOS&lt;/code&gt; - &lt;code&gt;.dylib&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Linux&lt;/code&gt; - &lt;code&gt;.so&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Windows&lt;/code&gt; - &lt;code&gt;.dll&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;macOS&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;run
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;find /usr/local/share/dotnet &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s2"&gt;"libSystem.Native.*"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;output
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/usr/local/share/dotnet/shared/Microsoft.NETCore.App/9.0.2/libSystem.Native.dylib
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Linux&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;run via &lt;code&gt;docker&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run --rm mcr.microsoft.com/dotnet/runtime:9.0 find / -name "libSystem.Native.*"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;output
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/usr/share/dotnet/shared/Microsoft.NETCore.App/9.0.2/libSystem.Native.so
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Windows&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;there is no &lt;code&gt;libSystem.Native.dll&lt;/code&gt; on &lt;code&gt;Windows&lt;/code&gt; as this &lt;code&gt;shim&lt;/code&gt; is used for &lt;code&gt;unix-like&lt;/code&gt; only&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, depending on the operating system &lt;code&gt;dotnet&lt;/code&gt; supplies a specific &lt;code&gt;libSystem.Native&lt;/code&gt; version of the library: &lt;code&gt;.dylib&lt;/code&gt; for &lt;code&gt;macOS&lt;/code&gt;, &lt;code&gt;.so&lt;/code&gt; for &lt;code&gt;Linux&lt;/code&gt;.&lt;/p&gt;

&lt;h5&gt;
  
  
  SystemNative_GetPid and System.Native
&lt;/h5&gt;

&lt;p&gt;We've found where &lt;code&gt;libSystem.Native&lt;/code&gt; resides, it's provided by &lt;code&gt;dotnet runtime&lt;/code&gt;, now it's time to understand what &lt;code&gt;SystemNative_GetPid&lt;/code&gt; call is.&lt;/p&gt;

&lt;p&gt;The real implementation of &lt;code&gt;SystemNative_GetPid&lt;/code&gt; can be found in &lt;code&gt;pal_process.c&lt;/code&gt; (with accompanying header file) which is inside &lt;a href="https://github.com/dotnet/runtime/blob/v9.0.2/src/native/libs/System.Native" rel="noopener noreferrer"&gt;System.Native&lt;/a&gt; folder.&lt;/p&gt;

&lt;p&gt;But before we continue, let's get acquainted with &lt;code&gt;PAL&lt;/code&gt; concept first. In &lt;code&gt;dotnet runtime&lt;/code&gt;, &lt;code&gt;PAL&lt;/code&gt; stands for &lt;code&gt;Platform Abstraction Layer&lt;/code&gt;. It's a component that enables &lt;code&gt;dotnet&lt;/code&gt; to run on multiple operating systems and hardware platforms. It provides a consistent interface between &lt;code&gt;dotnet runtime&lt;/code&gt; and the underlying operating system, abstracting away platform-specific details. This allows the majority of &lt;code&gt;dotnet runtime&lt;/code&gt; code to be platform-agnostic.&lt;/p&gt;

&lt;p&gt;Now onto &lt;code&gt;C&lt;/code&gt; code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="c1"&gt;// System.Native/pal_process.h, declaration&lt;/span&gt;
&lt;span class="n"&gt;PALEXPORT&lt;/span&gt; &lt;span class="kt"&gt;int32_t&lt;/span&gt; &lt;span class="nf"&gt;SystemNative_GetPid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 

&lt;span class="c1"&gt;// System.Native/pal_process.c, implementation&lt;/span&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;unistd.h&amp;gt;&lt;/span&gt;&lt;span class="c1"&gt; // 'getpid' resides here&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;span class="kt"&gt;int32_t&lt;/span&gt; &lt;span class="nf"&gt;SystemNative_GetPid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;getpid&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// System.Native/entrypoints.c, exporting to be available in C# interop&lt;/span&gt;
&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Entry&lt;/span&gt; &lt;span class="n"&gt;s_sysNative&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="n"&gt;DllImportEntry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SystemNative_GetPid&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;blockquote&gt;
&lt;p&gt;source code: &lt;a href="https://github.com/dotnet/runtime/blob/v9.0.2/src/native/libs/System.Native/pal_process.h" rel="noopener noreferrer"&gt;pal_process.h&lt;/a&gt;, &lt;a href="https://github.com/dotnet/runtime/blob/v9.0.2/src/native/libs/System.Native/pal_process.c" rel="noopener noreferrer"&gt;pal_process.c&lt;/a&gt;, &lt;a href="https://github.com/dotnet/runtime/blob/v9.0.2/src/native/libs/System.Native/entrypoints.c" rel="noopener noreferrer"&gt;entrypoints.c&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The crux of provided snippet is the real implementation that works on all &lt;code&gt;unix-like&lt;/code&gt; operating systems. Let's finalize the flow of calls by adding &lt;code&gt;low-level&lt;/code&gt; chain of calls into the diagram.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fe3xur3szl6ptvvb4t83v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fe3xur3szl6ptvvb4t83v.png" alt="finalized flow diagram" width="784" height="956"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  Conclusion? Not yet
&lt;/h5&gt;

&lt;p&gt;&lt;code&gt;getpid()&lt;/code&gt; is the function that's being called on &lt;code&gt;unix-like&lt;/code&gt; operating systems. &lt;/p&gt;

&lt;p&gt;We've basically covered all flows for &lt;code&gt;Environment.ProcessId&lt;/code&gt; call and the article could finish here. But my curiosity was still thirsty and I needed to know exactly what &lt;code&gt;getpid&lt;/code&gt; function does, how it works on different &lt;code&gt;unix-like&lt;/code&gt; systems and where it resides.&lt;/p&gt;

&lt;p&gt;If you're like me, then continue reading.&lt;/p&gt;

&lt;h5&gt;
  
  
  C Standard Library (libc) and POSIX
&lt;/h5&gt;

&lt;p&gt;Here is &lt;code&gt;getpid()&lt;/code&gt; function and it gets current process id. But wait a sec, how does it do that? If &lt;code&gt;getpid()&lt;/code&gt; is being called from &lt;code&gt;libSystem.Native&lt;/code&gt; then where is the lib where the actual &lt;code&gt;getpid()&lt;/code&gt; resides? Also, how it handles various &lt;code&gt;unix-like&lt;/code&gt; operating systems?&lt;/p&gt;

&lt;p&gt;I'm glad you've asked! This is the topic we'll start exploring now. But first, we need to understand what &lt;code&gt;C Standard Library (libc)&lt;/code&gt; and &lt;code&gt;POSIX&lt;/code&gt; are.&lt;/p&gt;

&lt;h6&gt;
  
  
  libc
&lt;/h6&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/C_standard_library" rel="noopener noreferrer"&gt;C Standard Library (libc)&lt;/a&gt; is the &lt;a href="https://en.wikipedia.org/wiki/Standard_library" rel="noopener noreferrer"&gt;standard library&lt;/a&gt; for the &lt;code&gt;C&lt;/code&gt; programming language, also called &lt;code&gt;libc&lt;/code&gt; (this term will be used from now on). &lt;code&gt;libc&lt;/code&gt; provides various macros, type definitions and functions for tasks such as string manipulation, mathematical computation, input/output processing, memory management, and so on. &lt;/p&gt;

&lt;p&gt;From &lt;code&gt;C&lt;/code&gt; language perspective &lt;code&gt;libc&lt;/code&gt; defines a set of header files which can be used in programs: &lt;a href="https://en.wikipedia.org/wiki/C_file_input/output" rel="noopener noreferrer"&gt;stdio.h&lt;/a&gt;, &lt;a href="https://en.wikipedia.org/wiki/C_mathematical_functions#Overview_of_functions" rel="noopener noreferrer"&gt;math.h&lt;/a&gt;, etc. (full list can be found &lt;a href="https://en.wikipedia.org/wiki/C_standard_library#Header_files" rel="noopener noreferrer"&gt;here&lt;/a&gt;). &lt;code&gt;libc&lt;/code&gt; is available on all &lt;code&gt;C-compliant&lt;/code&gt; platforms, it works on &lt;code&gt;Windows&lt;/code&gt;, &lt;code&gt;macOS&lt;/code&gt;, &lt;code&gt;Linux&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Example time! &lt;/p&gt;

&lt;p&gt;Let's write a simple &lt;code&gt;C&lt;/code&gt; program which will be using &lt;code&gt;libc&lt;/code&gt; function calls and which will work on all major operating systems.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="c1"&gt; // '&amp;lt;stdio.h&amp;gt;' header resides in 'libc' library&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;math.h&amp;gt;&lt;/span&gt;&lt;span class="c1"&gt;  // '&amp;lt;math.h&amp;gt;' header resides in 'libc' library&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"This is 'libc' call!&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 'printf' function is from '&amp;lt;stdio.h&amp;gt;' header which resides in 'libc' library&lt;/span&gt;
  &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"exp(1) = %f&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;exp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;  &lt;span class="c1"&gt;// 'exp' function is from '&amp;lt;stdio.h&amp;gt;' header which resides in 'libc' library&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&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;It's time to compile and run it!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;info&lt;/strong&gt; "compiling &lt;code&gt;C&lt;/code&gt; in a cross-platform manner"&lt;/p&gt;

&lt;p&gt;I want to compile &lt;code&gt;C&lt;/code&gt; program for various operating systems from one machine, that's why on &lt;code&gt;macOS M1&lt;/code&gt; I use &lt;a href="https://andrewkelley.me/post/zig-cc-powerful-drop-in-replacement-gcc-clang.html" rel="noopener noreferrer"&gt;zig drop-in replacement compiler&lt;/a&gt; (can be used on &lt;code&gt;Linux&lt;/code&gt;, &lt;code&gt;Windows&lt;/code&gt; too) for cross-platform compilation. &lt;br&gt;
There are also &lt;a href="https://clang.llvm.org/" rel="noopener noreferrer"&gt;clang&lt;/a&gt;, &lt;a href="https://gcc.gnu.org/" rel="noopener noreferrer"&gt;gcc&lt;/a&gt; (usually pre-installed on &lt;code&gt;macOS&lt;/code&gt; and &lt;code&gt;Linux&lt;/code&gt;). For &lt;code&gt;Windows&lt;/code&gt; there are &lt;br&gt;
&lt;a href="https://visualstudio.microsoft.com/vs/features/cplusplus/" rel="noopener noreferrer"&gt;Visual Studio installer&lt;/a&gt; or &lt;a href="https://www.mingw-w64.org/" rel="noopener noreferrer"&gt;mingw&lt;/a&gt; (which installs &lt;a href="https://gcc.gnu.org/" rel="noopener noreferrer"&gt;gcc&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Another important thing to remember is that I compile for &lt;code&gt;aarch64&lt;/code&gt; architecture for &lt;code&gt;M1&lt;/code&gt; series of processors, if you use &lt;code&gt;Intel&lt;/code&gt; or &lt;code&gt;AMD&lt;/code&gt; you'd need to&lt;br&gt;
compile for &lt;code&gt;x64/x84&lt;/code&gt; architecture.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;macOS (native)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;compile
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;zig cc -o libc_example_macos libc_example.c
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;run
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./libc_example_macos
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;output
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;This is &lt;span class="s1"&gt;'libc'&lt;/span&gt; call!
exp&lt;span class="o"&gt;(&lt;/span&gt;1&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 2.718282
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;gnu/Linux (cross-compile)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;compile
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;zig cc &lt;span class="nt"&gt;-o&lt;/span&gt; libc_example_linux_gnu libc_example.c &lt;span class="nt"&gt;-target&lt;/span&gt; aarch64-linux-gnu
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;run via &lt;code&gt;docker&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PWD&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;:/app &lt;span class="nt"&gt;-w&lt;/span&gt; /app debian:latest sh &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"./libc_example_linux_gnu"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;output
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;This is &lt;span class="s1"&gt;'libc'&lt;/span&gt; call!
exp&lt;span class="o"&gt;(&lt;/span&gt;1&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 2.718282
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;musl/Linux (cross-compile)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;compile
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;zig cc &lt;span class="nt"&gt;-o&lt;/span&gt; libc_example_linux_musl libc_example.c &lt;span class="nt"&gt;-target&lt;/span&gt; aarch64-linux-musl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;run via &lt;code&gt;docker&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PWD&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;:/app &lt;span class="nt"&gt;-w&lt;/span&gt; /app alpine:latest sh &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"./libc_example_linux_musl"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;output
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;This is &lt;span class="s1"&gt;'libc'&lt;/span&gt; call!
exp&lt;span class="o"&gt;(&lt;/span&gt;1&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 2.718282
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Windows (cross-compile)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;compile
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;zig cc &lt;span class="nt"&gt;-o&lt;/span&gt; libc_example_windows.exe libc_example.c &lt;span class="nt"&gt;-target&lt;/span&gt; aarch64-windows
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;run via &lt;code&gt;virtual machine&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;libc_example_windows.exe
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;output
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;This is &lt;span class="s1"&gt;'libc'&lt;/span&gt; call!
exp&lt;span class="o"&gt;(&lt;/span&gt;1&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 2.718282
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;info&lt;/strong&gt; "Linux flavours: gnu and musl"&lt;/p&gt;

&lt;p&gt;There are various &lt;code&gt;Linux&lt;/code&gt; flavours. Broadly speaking there are two main ones: &lt;a href="https://www.gnu.org/home.en.html" rel="noopener noreferrer"&gt;gnu&lt;/a&gt; (Debian, Ubuntu, etc) and &lt;a href="https://musl.libc.org/" rel="noopener noreferrer"&gt;musl&lt;/a&gt; (Alpine, etc).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Awesome! &lt;code&gt;libc_example.c&lt;/code&gt; program works everywhere!&lt;/p&gt;

&lt;p&gt;But where is &lt;code&gt;libc&lt;/code&gt; actually lives? We're ready to answer that: each operating system implements its own version of &lt;code&gt;libc&lt;/code&gt;. &lt;code&gt;libc&lt;/code&gt; can be treated as an &lt;code&gt;interface&lt;/code&gt; and each operating system implements its own version. Let's visualize that.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;info&lt;/strong&gt; "How to read a table"&lt;/p&gt;

&lt;p&gt;Below is a reference table comparing how the &lt;code&gt;libc&lt;/code&gt; is &amp;gt;implemented across major operating systems. Each row describes the &amp;gt;following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Operating system&lt;/code&gt; self-explanatory&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;C standard library (libc)&lt;/code&gt; the name by which &lt;code&gt;libc&lt;/code&gt; is commonly known on each platform&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Dynamic library name&lt;/code&gt; the actual dynamic library file that contains the implementation&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Function name&lt;/code&gt; an example function name that remains consistent across platforms despite the different underlying implementations&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operating system&lt;/th&gt;
&lt;th&gt;macOS&lt;/th&gt;
&lt;th&gt;Linux&lt;/th&gt;
&lt;th&gt;Windows&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;C standard library (libc)&lt;/td&gt;
&lt;td&gt;BSD&lt;/td&gt;
&lt;td&gt;gnu or musl&lt;/td&gt;
&lt;td&gt;MSVRT/UCRT&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dynamic library name&lt;/td&gt;
&lt;td&gt;libSystem.dylib&lt;/td&gt;
&lt;td&gt;libc.so.6 or libc.so&lt;/td&gt;
&lt;td&gt;msvcrt.dll&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Function name&lt;/td&gt;
&lt;td&gt;printf&lt;/td&gt;
&lt;td&gt;printf&lt;/td&gt;
&lt;td&gt;printf&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Each operating system links its own version of &lt;code&gt;libc&lt;/code&gt; (via &lt;a href="https://www.youtube.com/watch?v=UdMRcJwvWIY" rel="noopener noreferrer"&gt;dynamic or static linking&lt;/a&gt;) during &lt;code&gt;C&lt;/code&gt; compilation phase. It means that all functions from &lt;code&gt;libc&lt;/code&gt; are always available and can be used from any &lt;code&gt;C&lt;/code&gt; program without any additional setup. Important thing to note is that it can actually be several physical files (dynamic libraries) that implement &lt;code&gt;libc&lt;/code&gt; and dynamic library name can also differ (we'll see it in the context of &lt;code&gt;macOS&lt;/code&gt; later, as it's an operating system level implementation detail).&lt;/p&gt;

&lt;p&gt;Phew!&lt;/p&gt;

&lt;p&gt;We covered &lt;code&gt;libc&lt;/code&gt;, but we still haven't figured out where &lt;code&gt;getpid&lt;/code&gt; lives and how it's connected to &lt;code&gt;libc&lt;/code&gt;, the next section will provide more details on that.&lt;/p&gt;

&lt;h6&gt;
  
  
  POSIX
&lt;/h6&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/POSIX" rel="noopener noreferrer"&gt;POSIX&lt;/a&gt; is a family of standards for maintaining compatibility between operating systems. It defines a common set of APIs and&lt;br&gt;
behaviors for &lt;code&gt;unix-like&lt;/code&gt; operating systems. Before &lt;code&gt;POSIX&lt;/code&gt;, &lt;code&gt;Unix&lt;/code&gt; systems were highly fragmented — each vendor had different APIs, &lt;br&gt;
making cross-platform development difficult. &lt;code&gt;POSIX&lt;/code&gt; was introduced to standardize system calls and libraries. On &lt;code&gt;unix-like&lt;/code&gt; systems &lt;code&gt;POSIX API&lt;/code&gt; is part of &lt;code&gt;libc&lt;/code&gt; &lt;br&gt;
(aka superset of &lt;code&gt;libc&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;And you know what? &lt;code&gt;getpid()&lt;/code&gt; is &lt;a href="https://en.wikipedia.org/wiki/C_POSIX_library" rel="noopener noreferrer"&gt;POSIX API&lt;/a&gt; call! Here's &lt;a href="https://linux.die.net/man/2/getpid" rel="noopener noreferrer"&gt;getpid for Linux&lt;/a&gt; and &lt;br&gt;
&lt;a href="https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getpid.2.html" rel="noopener noreferrer"&gt;getpid for macOS&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Important distinction between &lt;code&gt;unix-like&lt;/code&gt; and &lt;code&gt;windows&lt;/code&gt; is that &lt;code&gt;POSIX API&lt;/code&gt; is not supported on &lt;code&gt;Windows&lt;/code&gt;. &lt;code&gt;Windows&lt;/code&gt; uses &lt;a href="https://en.wikipedia.org/wiki/Windows_API" rel="noopener noreferrer"&gt;WinAPI&lt;/a&gt; instead and &lt;code&gt;GetCurrentProcessId&lt;/code&gt; from &lt;code&gt;kernel32.dll&lt;/code&gt; is &lt;code&gt;WinAPI&lt;/code&gt; call. That's why we have two completely different flows from &lt;code&gt;dotnet&lt;/code&gt; &lt;code&gt;PAL&lt;/code&gt; perspective.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;info&lt;/strong&gt; "POSIX support for &lt;code&gt;Windows&lt;/code&gt;"&lt;/p&gt;

&lt;p&gt;Altough, built-in &lt;code&gt;libc&lt;/code&gt; on &lt;code&gt;Windows&lt;/code&gt; doesn't support &lt;code&gt;POSIX API&lt;/code&gt; and &lt;code&gt;dotnet&lt;/code&gt; uses &lt;code&gt;WinAPI&lt;/code&gt; instead, &lt;code&gt;POSIX&lt;/code&gt; support can be added externally via &lt;a href="https://cygwin.com/" rel="noopener noreferrer"&gt;cygwin&lt;/a&gt;, &lt;a href="https://learn.microsoft.com/en-us/windows/wsl/" rel="noopener noreferrer"&gt;WSL&lt;/a&gt; or &lt;a href="https://www.mingw-w64.org/" rel="noopener noreferrer"&gt;MinGW&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Remember that &lt;code&gt;dotnet&lt;/code&gt; as a platform has been on &lt;code&gt;Windows&lt;/code&gt; for tens of years already (via &lt;a href="https://en.wikipedia.org/wiki/.NET_Framework" rel="noopener noreferrer"&gt;.NET Framework&lt;/a&gt; which is outdated) and a final cross-platform support was added only starting from &lt;code&gt;.NET Core&lt;/code&gt;. There is also &lt;a href="https://www.mono-project.com/docs/advanced/runtime/" rel="noopener noreferrer"&gt;Mono runtime&lt;/a&gt; but let's leave it for now as it's not related for the current article. Overall, here's the [history of dotnet (&lt;a href="https://en.wikipedia.org/wiki/.NET" rel="noopener noreferrer"&gt;https://en.wikipedia.org/wiki/.NET&lt;/a&gt;) if you need more details.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Are you confused yet? &lt;/p&gt;

&lt;p&gt;I guess some examples are needed here! So, let's call &lt;code&gt;POSIX API&lt;/code&gt; for &lt;code&gt;unix-like&lt;/code&gt; and &lt;code&gt;WinAPI&lt;/code&gt; for &lt;code&gt;windows&lt;/code&gt; to get process id in &lt;code&gt;C&lt;/code&gt; language.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;unix-like&lt;/strong&gt; (file name: &lt;code&gt;get_pid_unix_like.c&lt;/code&gt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="c1"&gt;   // '&amp;lt;stdio.h&amp;gt;' header resides in 'libc' library&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;unistd.h&amp;gt;&lt;/span&gt;&lt;span class="c1"&gt;  // '&amp;lt;unistd.h&amp;gt;' header resides in 'libc' library and it's 'POSIX API'&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;pid_t&lt;/span&gt; &lt;span class="n"&gt;pid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;getpid&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;  &lt;span class="c1"&gt;// 'getpid' function is from '&amp;lt;unistd.h&amp;gt;' header which resides in 'libc' library and it's 'POSIX API'&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Current Process ID: %i&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&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;&lt;strong&gt;windows&lt;/strong&gt; (file name: &lt;code&gt;get_pid_windows.c&lt;/code&gt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="c1"&gt;    // '&amp;lt;stdio.h&amp;gt;' header resides in 'libc' library&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;windows.h&amp;gt;&lt;/span&gt;&lt;span class="c1"&gt;  // '&amp;lt;windows.h&amp;gt;' header resides in 'WinAPI' library&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;DWORD&lt;/span&gt; &lt;span class="n"&gt;pid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GetCurrentProcessId&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// 'GetCurrentProcessId' function is from '&amp;lt;windows.h&amp;gt;' header which resides in 'WinAPI' library&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Current Process ID: %lu&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&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;Now it's time to compile and run.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;info&lt;/strong&gt; "Linux: glibc vs musl"&lt;/p&gt;

&lt;p&gt;For &lt;code&gt;gnu/Linux&lt;/code&gt; the actual implementation of &lt;code&gt;libc&lt;/code&gt; and &lt;code&gt;POSIX API&lt;/code&gt; is called &lt;code&gt;glibc&lt;/code&gt; while for &lt;code&gt;musl&lt;/code&gt; it's called... &lt;code&gt;musl&lt;/code&gt;. By the way, &lt;code&gt;musl&lt;/code&gt; is mostly POSIX-compliant, not fully. But for the sake of current discussion it doesn't matter, as &lt;code&gt;getpid&lt;/code&gt; will work on any &lt;code&gt;Linux&lt;/code&gt; flavour.&lt;/p&gt;

&lt;p&gt;For the next example, I specifically excluded &lt;code&gt;musl/Linux&lt;/code&gt; as for &lt;code&gt;musl&lt;/code&gt; compilation &lt;code&gt;static linking&lt;/code&gt; is used instead of &lt;code&gt;dynamic linking&lt;/code&gt;. During &lt;code&gt;static linking&lt;/code&gt;, the call to &lt;code&gt;getpid&lt;/code&gt; will be directly included into the resulting program so we won't be able to see the actual dynamic library file whereabouts.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;macOS&lt;/strong&gt; (native &lt;code&gt;get_pid_unix_like.c&lt;/code&gt;)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;compile
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;zig cc -o get_pid_macos get_pid_unix_like.c
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;run
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./get_pid_macos
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;output
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Current Process ID: 67194
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;gnu/Linux&lt;/strong&gt; (cross-compile &lt;code&gt;get_pid_unix_like.c&lt;/code&gt;)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;compile
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;zig cc &lt;span class="nt"&gt;-o&lt;/span&gt; get_pid_linux_gnu get_pid_unix_like.c &lt;span class="nt"&gt;-target&lt;/span&gt; aarch64-linux-gnu
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;run via &lt;code&gt;docker&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PWD&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;:/app &lt;span class="nt"&gt;-w&lt;/span&gt; /app debian:latest sh &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"./get_pid_linux_gnu"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;output
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Current Process ID: 7
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;musl/Linux&lt;/strong&gt; (cross-compile &lt;code&gt;get_pid_unix_like.c&lt;/code&gt;)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;compile
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;zig cc &lt;span class="nt"&gt;-o&lt;/span&gt; get_pid_linux_musl get_pid_unix_like.c &lt;span class="nt"&gt;-target&lt;/span&gt; aarch64-linux-musl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;run via &lt;code&gt;docker&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PWD&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;:/app &lt;span class="nt"&gt;-w&lt;/span&gt; /app alpine:latest sh &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"./get_pid_linux_musl"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;output
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Current Process ID: 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Windows&lt;/strong&gt; (cross-compile &lt;code&gt;get_pid_windows.c&lt;/code&gt;)"&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;compile
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;zig cc &lt;span class="nt"&gt;-o&lt;/span&gt; get_pid_windows.exe get_pid_windows.c &lt;span class="nt"&gt;-target&lt;/span&gt; aarch64-windows
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;run via &lt;code&gt;virtual machine&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;get_pid_windows.exe
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;output
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Current Process ID: 17256
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Based on the provided examples, when &lt;code&gt;get_pid_unix_like.c&lt;/code&gt; is compiled it will work only on &lt;code&gt;unix-like&lt;/code&gt; systems and &lt;code&gt;get_pid_windows.c&lt;/code&gt; will work only on &lt;code&gt;windows&lt;/code&gt; respectively. As we've seen previously, for &lt;code&gt;windows&lt;/code&gt;, &lt;code&gt;dotnet&lt;/code&gt; calls into &lt;code&gt;GetCurrentProcessId()&lt;/code&gt; function directly, without any explicit &lt;code&gt;C&lt;/code&gt; code ...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;LibraryImport&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"kernel32.dll"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;DllImport&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"kernel32.dll"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="kt"&gt;uint&lt;/span&gt; &lt;span class="nf"&gt;GetCurrentProcessId&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;... while for &lt;code&gt;unix-like&lt;/code&gt; it calls directly into &lt;code&gt;C&lt;/code&gt; via &lt;code&gt;getpid&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;unistd.h&amp;gt;&lt;/span&gt;&lt;span class="c1"&gt; // 'getpid' resides here&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;span class="kt"&gt;int32_t&lt;/span&gt; &lt;span class="nf"&gt;SystemNative_GetPid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;getpid&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;Now, where does &lt;code&gt;getpid&lt;/code&gt; actually live? &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"I want to physically know the library this function lives in!" (c) me&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h5&gt;
  
  
  &lt;code&gt;getpid&lt;/code&gt; whereabouts
&lt;/h5&gt;

&lt;p&gt;We need to understand what operating system we're targeting.  We'll focus only on two "flavours" of them: &lt;code&gt;macOS&lt;/code&gt; and &lt;code&gt;gnu/Linux&lt;/code&gt; (&lt;code&gt;Debian&lt;/code&gt;, &lt;code&gt;Ubuntu&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;As we already compiled &lt;code&gt;get_pid_macos&lt;/code&gt; and &lt;code&gt;get_pid_linux_gnu&lt;/code&gt; from previous step, we can check which dynamic libraries were linked during the compilation phase.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;macOS&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;run &lt;code&gt;otool&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;otool -L ./get_pid_macos
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;output
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./get-process-id-macos:
    /usr/lib/libSystem.B.dylib &lt;span class="o"&gt;(&lt;/span&gt;compatibility version 1.0.0, current version 1351.0.0&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;gnu/Linux&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;run &lt;code&gt;ldd&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PWD&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;:/app &lt;span class="nt"&gt;-w&lt;/span&gt; /app debian:latest sh &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"ldd ./get_pid_linux_gnu"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;output
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    linux-vdso.so.1 &lt;span class="o"&gt;(&lt;/span&gt;0x0000ffffaa71a000&lt;span class="o"&gt;)&lt;/span&gt;
    libc.so.6 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; /lib/aarch64-linux-gnu/libc.so.6 &lt;span class="o"&gt;(&lt;/span&gt;0x0000ffffaa520000&lt;span class="o"&gt;)&lt;/span&gt;
    /lib/ld-linux-aarch64.so.1 &lt;span class="o"&gt;(&lt;/span&gt;0x0000ffffaa6dd000&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Based on provided outputs we can conclude the following: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;on &lt;code&gt;macOS&lt;/code&gt; - &lt;code&gt;getpid&lt;/code&gt; function resides in &lt;code&gt;libSystem.B.dylib&lt;/code&gt; dynamic library&lt;/li&gt;
&lt;li&gt;on &lt;code&gt;gnu/Linux&lt;/code&gt; (&lt;code&gt;Debian&lt;/code&gt;) - &lt;code&gt;getpid&lt;/code&gt; function resides in &lt;code&gt;/lib/aarch64-linux-gnu/libc.so.6&lt;/code&gt; dynamic library&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When program is compiled, the system standard libraries (&lt;code&gt;glibc/POSIX&lt;/code&gt;, &lt;code&gt;WinAPI&lt;/code&gt;) are linked automatically so all of their functionality is available by default.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;As a reminder from where we started&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;processId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Environment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ProcessId&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;processId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// output: 1 (this is an example value)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Environment.ProcessId&lt;/code&gt; call does the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;for &lt;code&gt;unix-like&lt;/code&gt; operating systems (including &lt;code&gt;macOS&lt;/code&gt; and various &lt;code&gt;Linux&lt;/code&gt; flavours: &lt;code&gt;gnu&lt;/code&gt;, &lt;code&gt;musl&lt;/code&gt;), calls &lt;code&gt;getpid&lt;/code&gt; function (which is &lt;code&gt;POSIX&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;for &lt;code&gt;Windows&lt;/code&gt;, calls &lt;code&gt;GetCurrentProcessId&lt;/code&gt; function (which is &lt;code&gt;WinAPI&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;each &lt;code&gt;unix-like&lt;/code&gt; operating system implements its own version of &lt;code&gt;C Standard Library (libc)&lt;/code&gt; and has its own flavour of &lt;code&gt;libc&lt;/code&gt; - &lt;code&gt;glibc&lt;/code&gt; (&lt;code&gt;Debian&lt;/code&gt;, &lt;code&gt;Ubuntu&lt;/code&gt;, etc), &lt;code&gt;musl&lt;/code&gt; (&lt;code&gt;Alpine&lt;/code&gt;, etc)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;libc&lt;/code&gt; and &lt;code&gt;WinAPI&lt;/code&gt; libraries are linked automatically during program compilation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We've only covered one simple &lt;code&gt;system call&lt;/code&gt;, but it gave us a proper view into the inner details of how low-level interoperability with &lt;code&gt;C&lt;/code&gt; is being done in &lt;code&gt;dotnet &lt;br&gt;
runtime&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;There are a lot of other system calls such as: working with files (IO), making HTTP requests, etc. All of them follow a similar pattern.&lt;/p&gt;

&lt;p&gt;We also need to remember that all of that are implementation details and the actual chain of calls may change in future versions of &lt;code&gt;dotnet&lt;/code&gt;.&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>c</category>
      <category>crossplatform</category>
      <category>programming</category>
    </item>
    <item>
      <title>Flavours of rounding</title>
      <dc:creator>semuserable</dc:creator>
      <pubDate>Tue, 24 Aug 2021 00:00:00 +0000</pubDate>
      <link>https://dev.to/semuserable/flavours-of-rounding-42e0</link>
      <guid>https://dev.to/semuserable/flavours-of-rounding-42e0</guid>
      <description>&lt;p&gt;How often do you round various numbers in your day-to-day job? Do you know what type of rounding do you actually use?&lt;/p&gt;

&lt;p&gt;Let's compare several programming languages and their &lt;strong&gt;default&lt;/strong&gt; (meaning without additional parameters if the rounding function allows it) rounding techniques.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I'll use several notions of rounding: &lt;a href="https://en.wikipedia.org/wiki/Rounding#Round_half_to_even" rel="noopener noreferrer"&gt;banker's rounding&lt;/a&gt;, &lt;a href="https://en.wikipedia.org/wiki/Rounding#Round_half_away_from_zero" rel="noopener noreferrer"&gt;away from zero&lt;/a&gt; and &lt;a href="https://en.wikipedia.org/wiki/Rounding#Round_half_up" rel="noopener noreferrer"&gt;round half up&lt;/a&gt;. More info about different techniques can be found on &lt;a href="https://en.wikipedia.org/wiki/Rounding" rel="noopener noreferrer"&gt;Wikipedia&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  .NET
&lt;/h2&gt;

&lt;p&gt;In dotnet (Framework, Core, 5+) &lt;a href="https://en.wikipedia.org/wiki/Rounding#Round_half_to_even" rel="noopener noreferrer"&gt;banker's rounding&lt;/a&gt; is used by default.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 0&lt;/span&gt;
&lt;span class="n"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1.5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 2&lt;/span&gt;
&lt;span class="n"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2.5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 2&lt;/span&gt;
&lt;span class="n"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;3.5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 4&lt;/span&gt;

&lt;span class="n"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Round&lt;/span&gt;&lt;span class="p"&gt;(-&lt;/span&gt;&lt;span class="m"&gt;23.5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// -24&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you need &lt;a href="https://en.wikipedia.org/wiki/Rounding#Round_half_away_from_zero" rel="noopener noreferrer"&gt;away from zero&lt;/a&gt;, use the following&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MidpointRounding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AwayFromZero&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 1&lt;/span&gt;
&lt;span class="n"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MidpointRounding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AwayFromZero&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 2&lt;/span&gt;
&lt;span class="n"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MidpointRounding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AwayFromZero&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 3&lt;/span&gt;
&lt;span class="n"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;3.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MidpointRounding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AwayFromZero&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 4&lt;/span&gt;

&lt;span class="n"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Round&lt;/span&gt;&lt;span class="p"&gt;(-&lt;/span&gt;&lt;span class="m"&gt;23.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MidpointRounding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AwayFromZero&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// -24&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you need &lt;a href="https://en.wikipedia.org/wiki/Rounding#Round_half_up" rel="noopener noreferrer"&gt;round half up&lt;/a&gt;, use the following&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MidpointRounding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToPositiveInfinity&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 1&lt;/span&gt;
&lt;span class="n"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MidpointRounding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToPositiveInfinity&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 2&lt;/span&gt;
&lt;span class="n"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MidpointRounding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToPositiveInfinity&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 3&lt;/span&gt;
&lt;span class="n"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;3.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MidpointRounding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToPositiveInfinity&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 4&lt;/span&gt;

&lt;span class="n"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Round&lt;/span&gt;&lt;span class="p"&gt;(-&lt;/span&gt;&lt;span class="m"&gt;23.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MidpointRounding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToPositiveInfinity&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// -23&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  JavaScript
&lt;/h2&gt;

&lt;p&gt;In JavaScript &lt;a href="https://en.wikipedia.org/wiki/Rounding#Round_half_up" rel="noopener noreferrer"&gt;round half up&lt;/a&gt; is used be default.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 1&lt;/span&gt;
&lt;span class="n"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1.5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 2&lt;/span&gt;
&lt;span class="n"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2.5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 3&lt;/span&gt;
&lt;span class="n"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;3.5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 4&lt;/span&gt;

&lt;span class="n"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(-&lt;/span&gt;&lt;span class="m"&gt;23.5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// -23&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Python (2.7, 3+)
&lt;/h2&gt;

&lt;p&gt;In Python 2.7 &lt;a href="https://en.wikipedia.org/wiki/Rounding#Round_half_away_from_zero" rel="noopener noreferrer"&gt;away from zero&lt;/a&gt; is used by default.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 1
&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 2
&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;2.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 3
&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;3.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 4
&lt;/span&gt;
&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;23.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# -24
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But in Python 3+ &lt;a href="https://en.wikipedia.org/wiki/Rounding#Round_half_to_even" rel="noopener noreferrer"&gt;banker's rounding&lt;/a&gt; is used by default.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 0
&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 2
&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;2.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 2
&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;3.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 4
&lt;/span&gt;
&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;23.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# -24
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;This was quite surprising, to be honest.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Java
&lt;/h2&gt;

&lt;p&gt;In Java (JDK 1.8.0, 9, 10, 11) &lt;a href="https://en.wikipedia.org/wiki/Rounding#Round_half_up" rel="noopener noreferrer"&gt;round half up&lt;/a&gt; is used by default.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Math&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;round&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 1&lt;/span&gt;
&lt;span class="nc"&gt;Math&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;round&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1.5&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 2&lt;/span&gt;
&lt;span class="nc"&gt;Math&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;round&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;2.5&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 3&lt;/span&gt;
&lt;span class="nc"&gt;Math&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;round&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;3.5&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 4&lt;/span&gt;

&lt;span class="nc"&gt;Math&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;round&lt;/span&gt;&lt;span class="o"&gt;(-&lt;/span&gt;&lt;span class="mf"&gt;23.5&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// -23&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Go
&lt;/h2&gt;

&lt;p&gt;In Go &lt;a href="https://en.wikipedia.org/wiki/Rounding#Round_half_away_from_zero" rel="noopener noreferrer"&gt;away from zero&lt;/a&gt;  is used by default.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;math&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// 1&lt;/span&gt;
&lt;span class="n"&gt;math&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// 2&lt;/span&gt;
&lt;span class="n"&gt;math&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// 3&lt;/span&gt;
&lt;span class="n"&gt;math&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;3.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// 4&lt;/span&gt;

&lt;span class="n"&gt;math&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="m"&gt;23.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// -24&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But if you want &lt;a href="https://en.wikipedia.org/wiki/Rounding#Round_half_to_even" rel="noopener noreferrer"&gt;banker's rounding&lt;/a&gt; there is a default function for this too.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;math&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RoundToEven&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// 0&lt;/span&gt;
&lt;span class="n"&gt;math&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RoundToEven&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// 2&lt;/span&gt;
&lt;span class="n"&gt;math&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RoundToEven&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// 2&lt;/span&gt;
&lt;span class="n"&gt;math&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RoundToEven&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;3.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// 4&lt;/span&gt;

&lt;span class="n"&gt;math&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RoundToEven&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="m"&gt;23.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// -24&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  PHP
&lt;/h2&gt;

&lt;p&gt;In PHP &lt;a href="https://en.wikipedia.org/wiki/Rounding#Round_half_away_from_zero" rel="noopener noreferrer"&gt;away from zero&lt;/a&gt; is used by default.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nb"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;# 1&lt;/span&gt;
&lt;span class="nb"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1.5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;# 2&lt;/span&gt;
&lt;span class="nb"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;2.5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;# 3&lt;/span&gt;
&lt;span class="nb"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;3.5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;# 4&lt;/span&gt;

&lt;span class="nb"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;23.5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;# -24&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>dotnet</category>
      <category>javascript</category>
      <category>python</category>
      <category>java</category>
    </item>
    <item>
      <title>Postgres pg_stat_statement setup via docker</title>
      <dc:creator>semuserable</dc:creator>
      <pubDate>Tue, 29 Jun 2021 17:44:03 +0000</pubDate>
      <link>https://dev.to/semuserable/postgres-pgstatstatement-setup-via-docker-3pkn</link>
      <guid>https://dev.to/semuserable/postgres-pgstatstatement-setup-via-docker-3pkn</guid>
      <description>&lt;p&gt;Sometimes we want to track and analyze &lt;code&gt;SQL&lt;/code&gt; in &lt;code&gt;postgres&lt;/code&gt;. It may be that you use some fancy &lt;code&gt;ORM&lt;/code&gt; and all &lt;code&gt;SQL&lt;/code&gt; is abstracted away, but then you begin to notice some performance drops and you're starting to suspect that the &lt;code&gt;SQL&lt;/code&gt; you expected to be run "very efficiently", in fact performs poorly.&lt;/p&gt;

&lt;p&gt;That's how I've got acquainted with &lt;a href="https://www.postgresql.org/docs/9.4/pgstatstatements.html" rel="noopener noreferrer"&gt;pg_stat_statements&lt;/a&gt; tool. I suggest to read about it on the official site.&lt;/p&gt;

&lt;p&gt;Here, we'll setup it for local development via &lt;code&gt;docker&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.docker.com/" rel="noopener noreferrer"&gt;Docker&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Configuration
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;run &lt;code&gt;postgres&lt;/code&gt; in &lt;code&gt;docker&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;--name&lt;/span&gt; test-postgres &lt;span class="nt"&gt;-p&lt;/span&gt; 5432:5432 &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;secretpass &lt;span class="nt"&gt;-d&lt;/span&gt; postgres
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Make sure the port &lt;code&gt;5432&lt;/code&gt; is not occupied by any process, otherwise the &lt;code&gt;postgres&lt;/code&gt; won't be started (although container will be created).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;go into container command prompt via interactive mode
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; test-postgres /bin/bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;edit &lt;code&gt;postgresql.conf&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In order to enable &lt;code&gt;pg_stat_statements&lt;/code&gt; functionality we need to edit some settings in &lt;code&gt;postgres&lt;/code&gt; config file. Execute the following commands one by one (or via &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt;).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"shared_preload_libraries = 'pg_stat_statements'"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$PGDATA&lt;/span&gt;/postgresql.conf
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"pg_stat_statements.max = 10000"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$PGDATA&lt;/span&gt;/postgresql.conf
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"pg_stat_statements.track = all"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$PGDATA&lt;/span&gt;/postgresql.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Check if config is updated by running &lt;code&gt;cat $PGDATA/postgresql.conf&lt;/code&gt;. New lines will be at the end.&lt;/p&gt;

&lt;p&gt;Check &lt;a href="https://www.postgresql.org/docs/9.4/pgstatstatements.html#AEN130206" rel="noopener noreferrer"&gt;F.29.3. Configuration Parameters&lt;/a&gt; for &lt;code&gt;pg_stat_statements.max&lt;/code&gt; and &lt;code&gt;pg_stat_statements.track&lt;/code&gt; properties.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;connect to &lt;code&gt;postgres&lt;/code&gt; shell via &lt;code&gt;psql&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;psql &lt;span class="nt"&gt;-U&lt;/span&gt; postgres postgres
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Where &lt;code&gt;-U postgres&lt;/code&gt; (default user) is username and &lt;code&gt;postgres&lt;/code&gt; is a database name.&lt;/p&gt;

&lt;p&gt;Connection can be also established via any database tool like &lt;a href="https://dbeaver.io/" rel="noopener noreferrer"&gt;dbeaver&lt;/a&gt; (free), &lt;a href="https://www.jetbrains.com/datagrip/" rel="noopener noreferrer"&gt;DataGrip&lt;/a&gt; (paid), etc.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;create an extension via &lt;code&gt;SQL&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="n"&gt;EXTENSION&lt;/span&gt; &lt;span class="n"&gt;pg_stat_statements&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We've finished with the configuration and ready to start using the tool. We need to restart a container for changes to take an effect.&lt;/p&gt;

&lt;p&gt;Run &lt;code&gt;exit&lt;/code&gt; to leave &lt;code&gt;postgres&lt;/code&gt; shell, then &lt;code&gt;exit&lt;/code&gt; to leave container shell. Then start &lt;code&gt;postgres&lt;/code&gt; again - &lt;code&gt;docker start test-progres&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Playground
&lt;/h2&gt;

&lt;p&gt;Connect to the database. We'll be using &lt;code&gt;psql&lt;/code&gt; from within a &lt;code&gt;docker&lt;/code&gt; container.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;go into container bash again
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; test-postgres /bin/bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;then &lt;code&gt;psql&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;psql &lt;span class="nt"&gt;-U&lt;/span&gt; postgres postgres
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;run some &lt;code&gt;SQL&lt;/code&gt; several times.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;pg_stat_statements&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will see something like this.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;userid&lt;/th&gt;
&lt;th&gt;dbid&lt;/th&gt;
&lt;th&gt;query&lt;/th&gt;
&lt;th&gt;calls&lt;/th&gt;
&lt;th&gt;total_time&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;13408&lt;/td&gt;
&lt;td&gt;SELECT * FROM pg_stat_statements&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;0.1371&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;This is an excerpt, another columns don't really matter right now.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The most interesting columns are &lt;code&gt;query&lt;/code&gt;, &lt;code&gt;calls&lt;/code&gt;, &lt;code&gt;total_time&lt;/code&gt; (in milliseconds).&lt;/p&gt;

&lt;p&gt;Let's create &lt;code&gt;moviesdb&lt;/code&gt; database first and then call the previous &lt;code&gt;SQL&lt;/code&gt; again.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;DATABASE&lt;/span&gt; &lt;span class="n"&gt;moviesdb&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Query &lt;code&gt;pg_stat_statements&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;pg_stat_statements&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;userid&lt;/th&gt;
&lt;th&gt;dbid&lt;/th&gt;
&lt;th&gt;query&lt;/th&gt;
&lt;th&gt;calls&lt;/th&gt;
&lt;th&gt;total_time&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;13408&lt;/td&gt;
&lt;td&gt;SELECT * FROM pg_stat_statements&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;0.412&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;13408&lt;/td&gt;
&lt;td&gt;CREATE DATABASE moviesdb&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;334.0824&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;We just touched a tip of an iceberg. There are numerous ways to query the table and get various insights. Try it out for yourself!&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>sql</category>
    </item>
    <item>
      <title>Starting with Fable (F#)</title>
      <dc:creator>semuserable</dc:creator>
      <pubDate>Sat, 01 Feb 2020 19:06:47 +0000</pubDate>
      <link>https://dev.to/semuserable/starting-with-fable-f-kbi</link>
      <guid>https://dev.to/semuserable/starting-with-fable-f-kbi</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;TLDR: &lt;a href="https://github.com/semuserable/fable-basic-interop" rel="noopener noreferrer"&gt;https://github.com/semuserable/fable-basic-interop&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;
Starting with Fable (F#)

&lt;ul&gt;
&lt;li&gt;Preface&lt;/li&gt;
&lt;li&gt;Tools&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

Bootstrapping

&lt;ul&gt;
&lt;li&gt;Project structure&lt;/li&gt;
&lt;li&gt;JavaScript side&lt;/li&gt;
&lt;li&gt;Fable side&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

Basic interop

&lt;ul&gt;
&lt;li&gt;window.alert()&lt;/li&gt;
&lt;li&gt;Math.random()&lt;/li&gt;
&lt;li&gt;DOM&lt;/li&gt;
&lt;li&gt;p5.js&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Additional resources&lt;/li&gt;

&lt;/ul&gt;

&lt;h1&gt;
  
  
  Starting with Fable (F#)
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Preface
&lt;/h2&gt;

&lt;p&gt;I like &lt;code&gt;F#&lt;/code&gt; and somewhat dislike vanilla &lt;code&gt;JavaScript&lt;/code&gt;. When I found out that you can write front-end  using &lt;code&gt;F#&lt;/code&gt;, I was perplexed. That's how I met &lt;a href="https://fable.io/" rel="noopener noreferrer"&gt;Fable&lt;/a&gt; - a compiler which translates &lt;code&gt;F#&lt;/code&gt; into &lt;code&gt;JavaScript&lt;/code&gt; via &lt;a href="https://babeljs.io/" rel="noopener noreferrer"&gt;Babel&lt;/a&gt;. There are already a &lt;a href="https://github.com/jashkenas/coffeescript/wiki/List-of-languages-that-compile-to-JS" rel="noopener noreferrer"&gt;plethora&lt;/a&gt; of different languages which can be converted into &lt;code&gt;JavaScript&lt;/code&gt;. So, why choosing &lt;code&gt;F#&lt;/code&gt; specifically?&lt;/p&gt;

&lt;p&gt;This is not a tutorial about &lt;code&gt;F#&lt;/code&gt;, so I want to suggest checking out the awesome &lt;a href="https://fsharpforfunandprofit.com/" rel="noopener noreferrer"&gt;fsharpforfunandprofit&lt;/a&gt; and you can decide for youself. But for me personally, &lt;code&gt;F#&lt;/code&gt; is a very powerful, pragmatic, functional language which allows to write succinct, statically typed (bullet-proof!) code without any semantic noise.&lt;/p&gt;

&lt;p&gt;I want to write front-end with statically-typed language. Today, &lt;code&gt;TypeScript&lt;/code&gt; is standard de-facto if you want to write 'JavaScript-with-types'. But still, you must understand what exactly &lt;code&gt;TypeScript&lt;/code&gt; brings to the table. You must be prepared mentally. If you're too accustomed to type-less (dynamic) code, migration to &lt;code&gt;TypeScript&lt;/code&gt; will be painful. You must embrace the types and learn how to use them otherwise you will be writing the same old &lt;code&gt;JavaScript&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For me, &lt;code&gt;Fable&lt;/code&gt; was a rough start. It's a fresh technology and as &lt;code&gt;F#&lt;/code&gt; is not that widespread in the wild (in comparison to &lt;code&gt;JavaScript&lt;/code&gt;, &lt;code&gt;TypeScript&lt;/code&gt;), information about &lt;code&gt;Fable&lt;/code&gt; is scarce. The official example projects are not easy to comprehend when you just want to start simple. They usually involve some tinkering around.&lt;/p&gt;

&lt;p&gt;So, I decided to create an easy to follow tutorial about how you can start using &lt;code&gt;Fable&lt;/code&gt; today. I want to spread the word about &lt;code&gt;F#&lt;/code&gt; and &lt;code&gt;Fable&lt;/code&gt; specifically, so more people can try using it.&lt;/p&gt;

&lt;p&gt;I hope you'll like it. Enjoy!&lt;/p&gt;

&lt;h2&gt;
  
  
  Tools
&lt;/h2&gt;

&lt;p&gt;Before the start, make sure you have everything installed.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://nodejs.org/en/" rel="noopener noreferrer"&gt;nodejs&lt;/a&gt; with &lt;a href="https://www.npmjs.com/" rel="noopener noreferrer"&gt;npm&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dotnet.microsoft.com/download" rel="noopener noreferrer"&gt;dotnet core SDK&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;IDE&lt;/code&gt; -
personally I use &lt;a href="https://www.jetbrains.com/rider/" rel="noopener noreferrer"&gt;JetBrains Rider&lt;/a&gt;, but you can choose &lt;a href="https://code.visualstudio.com/" rel="noopener noreferrer"&gt;Visual Studio Code&lt;/a&gt; with &lt;a href="http://ionide.io/" rel="noopener noreferrer"&gt;ionide plugin&lt;/a&gt; or &lt;a href="https://visualstudio.microsoft.com/" rel="noopener noreferrer"&gt;Visual Studio&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Bootstrapping
&lt;/h1&gt;

&lt;p&gt;Let's start by understanding the basic folder structure of a simple &lt;code&gt;Fable&lt;/code&gt; app. I prefer to start simple and build upon that.&lt;/p&gt;

&lt;p&gt;In order to bootstrap a project you could use an &lt;a href="https://fable.io/docs/2-steps/choose-a-template.html" rel="noopener noreferrer"&gt;official&lt;/a&gt; guide, but personally I'm not using that approach much. You will be redirected to &lt;code&gt;fable2-sample&lt;/code&gt; &lt;a href="https://github.com/fable-compiler/fable2-samples" rel="noopener noreferrer"&gt;repository&lt;/a&gt;, but it's not that convenient to navigate inside (as for my taste). There are a bunch of projects with different setup and it's hard to find a really 'empty' project. Even 'minimal' one is not that 'minimal' and contains &lt;code&gt;Fable.React&lt;/code&gt;, &lt;code&gt;Fable.Elmish.React&lt;/code&gt; dependencies. For a person who just want to start, it could be overwhelming.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I still highly recomment to check &lt;code&gt;fable2-sample&lt;/code&gt; as it contains a plethora of different approaches which you can use in &lt;code&gt;Fable&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Latest &lt;code&gt;Fable&lt;/code&gt; version is &lt;code&gt;3&lt;/code&gt;, so you can think that &lt;code&gt;fable2-sample&lt;/code&gt; contains outdated projects, which is not true. All projects are on the latest version.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In &lt;code&gt;dotnet&lt;/code&gt; world we use &lt;code&gt;dotnet new&lt;/code&gt; commands to start new projects. I would like to do the same with &lt;code&gt;Fable&lt;/code&gt;, but there are no official templates. That's why I created &lt;a href="https://github.com/semuserable/Semuserable.Fable.Templates" rel="noopener noreferrer"&gt;templates&lt;/a&gt; project where you just type &lt;code&gt;dotnet new fable-empty&lt;/code&gt; and an empty project without redundant dependencies is created.&lt;/p&gt;

&lt;p&gt;It's time to create a new empty project.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;install templates
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dotnet new -i Semuserable.Fable.Templates::*
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;create a folder and move into it&lt;/li&gt;
&lt;li&gt;run
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dotnet new fable-empty
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;If you want to uninstall templates, run &lt;code&gt;dotnet new -u Semuserable.Fable.Templates&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A minimal &lt;code&gt;Fable&lt;/code&gt; project is created.&lt;/p&gt;

&lt;p&gt;Let's ensure that everything is working &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;execute &lt;code&gt;npm install&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;execute &lt;code&gt;npm start&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;open up &lt;code&gt;http://localhost:8080&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;press &lt;code&gt;F12&lt;/code&gt; and open &lt;code&gt;Console&lt;/code&gt; tab&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here we can see &lt;code&gt;Hello from Fable!&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Project structure
&lt;/h2&gt;

&lt;p&gt;Each Fable project can be split into 2 sides&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;JavaScript&lt;/code&gt; side - &lt;code&gt;webpack&lt;/code&gt;, &lt;code&gt;npm&lt;/code&gt;, static content (&lt;code&gt;.html&lt;/code&gt;, &lt;code&gt;.css&lt;/code&gt; etc)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Fable&lt;/code&gt; side - &lt;code&gt;F#&lt;/code&gt; project
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- public
    | index.html 
- src
    | App.fs
    | App.fsproj
| package.json
| package-lock.json
| webpack.config.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;public&lt;/code&gt; - static content&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;src&lt;/code&gt; - &lt;code&gt;F#&lt;/code&gt; project (&lt;code&gt;Fable&lt;/code&gt;) itself&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;package.json&lt;/code&gt;, &lt;code&gt;package-lock.json&lt;/code&gt; - &lt;code&gt;npm&lt;/code&gt; dependencies&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;webpack.config.js&lt;/code&gt; - webpack configuration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this tutorial I'll use &lt;code&gt;Fable.Core&lt;/code&gt; library without any additional dependencies.&lt;/p&gt;

&lt;h2&gt;
  
  
  JavaScript side
&lt;/h2&gt;

&lt;p&gt;In order for &lt;code&gt;Fable&lt;/code&gt; to interop with &lt;code&gt;JavaScript&lt;/code&gt; eco-system, we must ensure that all needed libraries are installed with &lt;code&gt;npm&lt;/code&gt;. For such a simple example, we won't use many dependencies, just the core ones in order to start the dev server and run &lt;code&gt;Fable&lt;/code&gt; compiler.&lt;/p&gt;

&lt;p&gt;Let's quickly review two important files - &lt;code&gt;package.json&lt;/code&gt; and &lt;code&gt;webpack-config.js&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;open up &lt;code&gt;package.json&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"App"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"private"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"webpack-dev-server"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"dependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@babel/core"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^7.7.7"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"fable-compiler"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^2.4.12"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"fable-loader"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^2.1.8"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"webpack"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^4.41.5"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"webpack-cli"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^3.3.10"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"webpack-dev-server"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^3.10.1"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we see minimal dependencies that are needed to start a server. There are &lt;code&gt;Fable&lt;/code&gt; specific ones: &lt;code&gt;fable-compiler&lt;/code&gt; and &lt;code&gt;fable-loader&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;open up &lt;code&gt;webpack.config.js&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Note this only includes basic configuration for development mode.&lt;/span&gt;
&lt;span class="c1"&gt;// For a more comprehensive configuration check:&lt;/span&gt;
&lt;span class="c1"&gt;// https://github.com/fable-compiler/webpack-config-template&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;path&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;contentFolder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./public&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;development&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./src/App.fsproj&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;__dirname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;contentFolder&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="na"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bundle.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;devServer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;contentBase&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;contentFolder&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;8080&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;module&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
            &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="sr"&gt;fs&lt;/span&gt;&lt;span class="se"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;x|proj&lt;/span&gt;&lt;span class="se"&gt;)?&lt;/span&gt;&lt;span class="sr"&gt;$/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;use&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fable-loader&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;}]&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;Very basic &lt;code&gt;webpack&lt;/code&gt; config. All we need to know right now is that content will be served from &lt;code&gt;./public&lt;/code&gt; folder (must have &lt;code&gt;index.html&lt;/code&gt; created there), server will be listening to port &lt;code&gt;8080&lt;/code&gt; and the &lt;code&gt;bundle.js&lt;/code&gt; (an app) will be generated in &lt;code&gt;./public&lt;/code&gt; folder.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fable side
&lt;/h2&gt;

&lt;p&gt;Here we have a very basic &lt;code&gt;.fsproj&lt;/code&gt; project setup. &lt;code&gt;App.fsproj&lt;/code&gt; is a &lt;a href="https://docs.microsoft.com/en-us/dotnet/standard/net-standard" rel="noopener noreferrer"&gt;netstandard&lt;/a&gt; application and &lt;code&gt;App.fs&lt;/code&gt; contains the actual &lt;code&gt;Fable&lt;/code&gt; app.&lt;/p&gt;

&lt;p&gt;Load &lt;code&gt;src/App.fsproj&lt;/code&gt; project into IDE of your choice and open up &lt;code&gt;App.fs&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight fsharp"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nc"&gt;App&lt;/span&gt;

&lt;span class="c1"&gt;// import Fable core types&lt;/span&gt;
&lt;span class="k"&gt;open&lt;/span&gt; &lt;span class="nn"&gt;Fable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Core&lt;/span&gt; 

&lt;span class="c1"&gt;// JavaScrpt interop call&lt;/span&gt;
&lt;span class="nn"&gt;JS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt; &lt;span class="s2"&gt;"Hello from Fable!"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By default, we just wrote some info into &lt;code&gt;JavaScript&lt;/code&gt; console. Input some new stuff into &lt;code&gt;log&lt;/code&gt; and refresh the page - &lt;a href="http://localhost:8080" rel="noopener noreferrer"&gt;http://localhost:8080&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;That's some very basic interop provided by &lt;code&gt;Fable.Core&lt;/code&gt; library.&lt;/p&gt;

&lt;h1&gt;
  
  
  Basic interop
&lt;/h1&gt;

&lt;p&gt;In order to utilize the full power of &lt;code&gt;Fable&lt;/code&gt; and &lt;code&gt;F#&lt;/code&gt; we need to write some interop code to glue &lt;code&gt;F#&lt;/code&gt; and &lt;code&gt;JavaScript&lt;/code&gt; together. Our minimum job is to understand how to map &lt;code&gt;JavaScript&lt;/code&gt; types to &lt;code&gt;F#&lt;/code&gt; ones. We also can use some helpers in the form of &lt;code&gt;TypeScript&lt;/code&gt; &lt;a href="https://github.com/DefinitelyTyped/DefinitelyTyped" rel="noopener noreferrer"&gt;type definition files&lt;/a&gt;, more on that later.&lt;/p&gt;

&lt;p&gt;There is an official &lt;a href="https://fable.io/docs/communicate/js-from-fable.html" rel="noopener noreferrer"&gt;Fable interop documentation&lt;/a&gt; which you can try on your own. Armed with the interop knowledge we can start implementing it by ourselves.&lt;/p&gt;

&lt;p&gt;In this tutorial we'll implement &lt;code&gt;window.alert()&lt;/code&gt; (which is absent from &lt;code&gt;Fable.Core&lt;/code&gt;), &lt;code&gt;Math.random()&lt;/code&gt; (which exists in &lt;code&gt;Fable.Core&lt;/code&gt;, but we'll implement it nonetheless and I'll show additionally how you can find what is implemented by default and what's not), a little bit of &lt;code&gt;DOM&lt;/code&gt; API and &lt;code&gt;p5.js&lt;/code&gt; lib.&lt;/p&gt;

&lt;h2&gt;
  
  
  window.alert()
&lt;/h2&gt;

&lt;p&gt;Let's start with &lt;code&gt;window.alert()&lt;/code&gt;. Firstly, we need to understand what we try to implement here. Is this a &lt;code&gt;JavaScript&lt;/code&gt; library, a &lt;code&gt;React&lt;/code&gt; component (heavily used in real &lt;code&gt;Fable&lt;/code&gt; apps, but we won't touch it here) or maybe something &lt;code&gt;global&lt;/code&gt;? &lt;/p&gt;

&lt;p&gt;&lt;code&gt;window&lt;/code&gt; is a global object in &lt;code&gt;JavaScript&lt;/code&gt;. Next thing, what is &lt;code&gt;alert()&lt;/code&gt; call actually do? Does it accept parameters? These questions are usually answered by &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/alert" rel="noopener noreferrer"&gt;comprehensive documentation&lt;/a&gt;. Let's open it and see how it can help. From docs, we see that &lt;code&gt;alert&lt;/code&gt; function accepts one optional parameter of type &lt;code&gt;string&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0nmqt68x2f0dm6vxcz2q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0nmqt68x2f0dm6vxcz2q.png" alt="window.alert()" width="748" height="344"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we have all necessary info for &lt;code&gt;F#&lt;/code&gt; implementation. Let's try! &lt;/p&gt;

&lt;p&gt;Open up &lt;code&gt;App.fs&lt;/code&gt; and write&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight fsharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// interface&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="nc"&gt;Window&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
    &lt;span class="c1"&gt;// function description&lt;/span&gt;
    &lt;span class="k"&gt;abstract&lt;/span&gt; &lt;span class="n"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;unit&lt;/span&gt;

&lt;span class="c1"&gt;// wiring-up JavaScript and F# with [&amp;lt;Global&amp;gt;] and jsNative&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="p"&gt;[&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Global&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;]&lt;/span&gt; &lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Window&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;jsNative&lt;/span&gt;

&lt;span class="c1"&gt;// client calls&lt;/span&gt;
&lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;alert&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Global Fable window.alert"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;alert&lt;/span&gt; &lt;span class="s2"&gt;"Global Fable window.alert without parentheses"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here I used an &lt;code&gt;F# interface&lt;/code&gt; approach which described a mapping between &lt;code&gt;JavaScript&lt;/code&gt; and &lt;code&gt;F#&lt;/code&gt; via some &lt;code&gt;interface&lt;/code&gt; magic.&lt;/p&gt;

&lt;p&gt;If you still has a process running after previous &lt;code&gt;npm start&lt;/code&gt; just save and reload the page. You should see two sequential alert popups!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxly953p7e99ahwe49xeh.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxly953p7e99ahwe49xeh.gif" alt="Alt Text" width="445" height="126"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's try another approach.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight fsharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Special attribute for mapping, $0 == message parameter&lt;/span&gt;
&lt;span class="p"&gt;[&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"window.alert($0)"&lt;/span&gt;&lt;span class="o"&gt;)&amp;gt;]&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;alert&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="o"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;unit&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;jsNative&lt;/span&gt;

&lt;span class="n"&gt;alert&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Emit from Fable window.alert"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;alert&lt;/span&gt; &lt;span class="s2"&gt;"Emit from Fable window.alert without parentheses"&lt;/span&gt;
&lt;span class="s2"&gt;"Emit from Fable window.alert with F# style"&lt;/span&gt; &lt;span class="p"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;alert&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can choose whatever approach you want, it mostly depends on your style or libraries which you try to incorporate.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Have you noticed a subtle difference between the two calls? The former call has an optional parameter while the latter one is required.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Math.random()
&lt;/h2&gt;

&lt;p&gt;Next one is &lt;code&gt;Math.random()&lt;/code&gt;. Using the knowledge we already gained, we know that &lt;code&gt;math&lt;/code&gt; is also a global object in &lt;code&gt;JavaScript&lt;/code&gt;. If you are unsure you can always check &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random#Syntax" rel="noopener noreferrer"&gt;the official docs&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight fsharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// interface&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="nc"&gt;Math&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
    &lt;span class="k"&gt;abstract&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;unit&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="p"&gt;[&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Global&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;]&lt;/span&gt; &lt;span class="nc"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Math&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;jsNative&lt;/span&gt;

&lt;span class="c1"&gt;// client call&lt;/span&gt;
&lt;span class="nn"&gt;JS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="bp"&gt;()&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pretty easy, but I want to point out one important thing. Have you noticed that we wrote &lt;code&gt;Math&lt;/code&gt; and not &lt;code&gt;math&lt;/code&gt; where &lt;code&gt;jsNative&lt;/code&gt; is used? Thats's because by importing it like that you must be sure that &lt;code&gt;F#&lt;/code&gt; name is exactly the same as a &lt;code&gt;JavaScript&lt;/code&gt; one. &lt;code&gt;JavaScript&lt;/code&gt; API is &lt;code&gt;Math.random()&lt;/code&gt;, not &lt;code&gt;math.random()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Another one&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight fsharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Math.random()"&lt;/span&gt;&lt;span class="o"&gt;)&amp;gt;]&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="bp"&gt;()&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;jsNative&lt;/span&gt;

&lt;span class="nn"&gt;JS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="bp"&gt;()&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Math.random()&lt;/code&gt; is implemented in &lt;a href="https://github.com/fable-compiler/Fable/blob/972505785486fe003ab70764544c2cf498e32fcd/src/Fable.Core/Fable.Core.JS.fs#L84" rel="noopener noreferrer"&gt;Fable.Core&lt;/a&gt;, you don't need to recreate it again. You can find what's implemented or not by taking a look at official &lt;code&gt;Fable&lt;/code&gt; packages.&lt;/p&gt;

&lt;p&gt;Reload the page and check the console (&lt;code&gt;F12&lt;/code&gt; -&amp;gt; &lt;code&gt;Console&lt;/code&gt;)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fn9y8r15iqj16qx6b11vh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fn9y8r15iqj16qx6b11vh.png" alt="Alt Text" width="800" height="25"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  DOM
&lt;/h2&gt;

&lt;p&gt;Now, we'll work with &lt;code&gt;DOM&lt;/code&gt;! We'll create a &lt;code&gt;div&lt;/code&gt; element with a text inside and attach it to some &lt;code&gt;div&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here's what we'll implement&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="c1"&gt;// https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement#JavaScript&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;newDiv&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;div&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;newContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createTextNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hi from F# Fable!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
&lt;span class="nx"&gt;newDiv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newContent&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;currentDiv&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;app&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;insertBefore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newDiv&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;currentDiv&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alright, we need to understand where we want a new &lt;code&gt;div&lt;/code&gt; to be attached. Do you remember &lt;code&gt;index.html&lt;/code&gt; file? It's time to open it - &lt;code&gt;project_folder/public/index.html&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Open &lt;code&gt;index.html&lt;/code&gt; and add &lt;code&gt;&amp;lt;div id="app"&amp;gt;&amp;lt;/div&amp;gt;&lt;/code&gt; above &lt;code&gt;script&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"app"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"bundle.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We'll be adding new stuff before &lt;code&gt;app&lt;/code&gt; div.&lt;/p&gt;

&lt;p&gt;Where should we start with this one? Again, documentation. We need to understand what functions we're going to use.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement#Syntax" rel="noopener noreferrer"&gt;document.createElement()&lt;/a&gt; - returns &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Element" rel="noopener noreferrer"&gt;Element&lt;/a&gt; which is &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Node" rel="noopener noreferrer"&gt;Node&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Document/createTextNode#Syntax" rel="noopener noreferrer"&gt;document.createTextNode()&lt;/a&gt; - returns &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Text" rel="noopener noreferrer"&gt;Text&lt;/a&gt; which is &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Node" rel="noopener noreferrer"&gt;Node&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Node/appendChild" rel="noopener noreferrer"&gt;Node.appendChild()&lt;/a&gt; - returns &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Node" rel="noopener noreferrer"&gt;Node&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById#Syntax" rel="noopener noreferrer"&gt;document.getElementById()&lt;/a&gt; - returns &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Element" rel="noopener noreferrer"&gt;Element&lt;/a&gt; which is &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Node" rel="noopener noreferrer"&gt;Node&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Node/insertBefore#Syntax" rel="noopener noreferrer"&gt;Node.insertBefore()&lt;/a&gt; - returns &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Node" rel="noopener noreferrer"&gt;Node&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By using info from the docs, create the following &lt;code&gt;F#&lt;/code&gt; structure&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight fsharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// interfaces&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="nc"&gt;Node&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
    &lt;span class="k"&gt;abstract&lt;/span&gt; &lt;span class="n"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;child&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Node&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Node&lt;/span&gt;
    &lt;span class="k"&gt;abstract&lt;/span&gt; &lt;span class="n"&gt;insertBefore&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Node&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt;&lt;span class="n"&gt;child&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Node&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Node&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="nc"&gt;Document&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
    &lt;span class="k"&gt;abstract&lt;/span&gt; &lt;span class="n"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;tagName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Node&lt;/span&gt;
    &lt;span class="k"&gt;abstract&lt;/span&gt; &lt;span class="n"&gt;createTextNode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Node&lt;/span&gt;
    &lt;span class="k"&gt;abstract&lt;/span&gt; &lt;span class="n"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;elementId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Node&lt;/span&gt;
    &lt;span class="k"&gt;abstract&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Node&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;set&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="p"&gt;[&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Global&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;]&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Document&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;jsNative&lt;/span&gt;

&lt;span class="c1"&gt;// client code&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;newDiv&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"div"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="s2"&gt;"Good news everyone! Generated dynamically by Fable!"&lt;/span&gt;
&lt;span class="p"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;createTextNode&lt;/span&gt;
&lt;span class="p"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;newDiv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;appendChild&lt;/span&gt;
&lt;span class="p"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ignore&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;currentDiv&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"app"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;insertBefore&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;newDiv&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;currentDiv&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ignore&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Notice that I implemented &lt;code&gt;document.createElement&lt;/code&gt; without an &lt;code&gt;options&lt;/code&gt; parameter which is optional in docs. That's totally fine.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;close the &lt;code&gt;npm&lt;/code&gt; process by pressing &lt;code&gt;Ctrl-Z&lt;/code&gt;. &lt;code&gt;index.html&lt;/code&gt; in &lt;code&gt;public&lt;/code&gt; folder is NOT auto-reloading.&lt;/li&gt;
&lt;li&gt;run &lt;code&gt;npm start&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Open up &lt;code&gt;http://localhost:8080/&lt;/code&gt; in a browser and behold!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fmgomjna1znw6nts3fz78.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fmgomjna1znw6nts3fz78.png" alt="Alt Text" width="800" height="155"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you want to work with &lt;code&gt;DOM&lt;/code&gt; you don't need to recreate all the bindings from scratch, there is an official library! It's called &lt;a href="https://github.com/fable-compiler/fable-browser/tree/master/src/Dom" rel="noopener noreferrer"&gt;Fable.Browser.Dom&lt;/a&gt;. Also, there are all other sorts of default stuff implemented in this &lt;a href="https://github.com/fable-compiler/fable-browser" rel="noopener noreferrer"&gt;official repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now you know how to work with &lt;code&gt;DOM&lt;/code&gt; via &lt;code&gt;Fable&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  p5.js
&lt;/h2&gt;

&lt;p&gt;It's time to implement some part of the 3rd party library. I chose &lt;a href="https://p5js.org/" rel="noopener noreferrer"&gt;p5js&lt;/a&gt; as it's a library to draw graphics and animation!&lt;/p&gt;

&lt;p&gt;Stop the current &lt;code&gt;npm&lt;/code&gt; process (&lt;code&gt;Ctrl+Z&lt;/code&gt;), move to the root of the project and run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install p5 --save
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;p5.js&lt;/code&gt; is installed locally and ready to be used. It's time to write some bindings!&lt;/p&gt;

&lt;p&gt;There are several approaches which we can take here. We can open &lt;code&gt;node_modules/p5/lib/p5.js&lt;/code&gt; and try to decipher functions and types, but I personally don't recommend to do it (only if you have no other choice) if you have access to the source code. Because what's stored in &lt;code&gt;node_modules&lt;/code&gt; could be packed/abridged/minified version of the library.&lt;/p&gt;

&lt;p&gt;First approach is to check the source code of the project. Like &lt;a href="https://github.com/processing/p5.js/blob/master/src/core/main.js#L35-L36" rel="noopener noreferrer"&gt;p5 constructor&lt;/a&gt; and &lt;a href="https://github.com/processing/p5.js/blob/master/src/core/rendering.js#L51" rel="noopener noreferrer"&gt;createCanvas&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Next approach would be to check &lt;code&gt;TypeScript&lt;/code&gt; type definition files by &lt;a href="https://github.com/DefinitelyTyped/DefinitelyTyped" rel="noopener noreferrer"&gt;DefinitellyTyped&lt;/a&gt;. I highly recommend to check it for other libraries too. Taking &lt;code&gt;p5.js&lt;/code&gt; as an example we have &lt;a href="https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/p5/index.d.ts#L88" rel="noopener noreferrer"&gt;p5 constructor type definition&lt;/a&gt; and &lt;a href="https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/p5/src/core/rendering.d.ts#L27" rel="noopener noreferrer"&gt;createCanvas type definition&lt;/a&gt;. The cool thing about this apporach, is that we already have types which we can convert directly (not always but still) to &lt;code&gt;F#&lt;/code&gt; types, but we should do it manually.&lt;/p&gt;

&lt;p&gt;Final approach would be to use &lt;a href="https://fable.io/ts2fable/" rel="noopener noreferrer"&gt;ts2fable&lt;/a&gt; tool to convert &lt;code&gt;TypeScript&lt;/code&gt; definition files into &lt;code&gt;F#&lt;/code&gt; itself! It's like the second approach but automatic. You just supply &lt;code&gt;*.ts&lt;/code&gt; file and it outputs &lt;code&gt;F#&lt;/code&gt; types! How cool is that? But be aware, this output is not always what you want to include in your final bindings. You need to check if its what you really need. There are some differences between &lt;code&gt;TypeScript&lt;/code&gt; and &lt;code&gt;F#&lt;/code&gt; type systems, which must be checked manually.&lt;/p&gt;

&lt;p&gt;Armed with all this knowledge we can finally write some &lt;code&gt;p5.js&lt;/code&gt; bindings with &lt;code&gt;Fable&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight fsharp"&gt;&lt;code&gt;&lt;span class="k"&gt;open&lt;/span&gt; &lt;span class="nn"&gt;Fable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Core&lt;/span&gt;

&lt;span class="c1"&gt;// p5.js interface&lt;/span&gt;
&lt;span class="p"&gt;[&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;StringEnum&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;]&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="nc"&gt;Renderer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
    &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;[&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;CompiledName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"p2d"&lt;/span&gt;&lt;span class="o"&gt;)&amp;gt;]&lt;/span&gt; &lt;span class="nc"&gt;P2D&lt;/span&gt;
    &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;[&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;CompiledName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"webgl"&lt;/span&gt;&lt;span class="o"&gt;)&amp;gt;]&lt;/span&gt; &lt;span class="nc"&gt;WebGL&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="p"&gt;[&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"p5/lib/p5.js"&lt;/span&gt;&lt;span class="o"&gt;)&amp;gt;]&lt;/span&gt; &lt;span class="n"&gt;p5&lt;/span&gt;&lt;span class="o"&gt;(?&lt;/span&gt;&lt;span class="n"&gt;sketch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;p5&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;unit&lt;/span&gt;&lt;span class="p"&gt;,&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="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;    
    &lt;span class="k"&gt;member&lt;/span&gt; &lt;span class="o"&gt;__.&lt;/span&gt;&lt;span class="n"&gt;setup&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;unit&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;unit&lt;/span&gt;&lt;span class="o"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;unit&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;jsNative&lt;/span&gt;
    &lt;span class="k"&gt;member&lt;/span&gt; &lt;span class="o"&gt;__.&lt;/span&gt;&lt;span class="n"&gt;draw&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;unit&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;unit&lt;/span&gt;&lt;span class="o"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;unit&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;jsNative&lt;/span&gt;
    &lt;span class="k"&gt;member&lt;/span&gt; &lt;span class="o"&gt;__.&lt;/span&gt;&lt;span class="n"&gt;createCanvas&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt;&lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Renderer&lt;/span&gt;&lt;span class="o"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;unit&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;jsNative&lt;/span&gt;
    &lt;span class="k"&gt;member&lt;/span&gt; &lt;span class="o"&gt;__.&lt;/span&gt;&lt;span class="n"&gt;background&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;unit&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;jsNative&lt;/span&gt;
    &lt;span class="k"&gt;member&lt;/span&gt; &lt;span class="o"&gt;__.&lt;/span&gt;&lt;span class="n"&gt;millis&lt;/span&gt;&lt;span class="bp"&gt;()&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;jsNative&lt;/span&gt;
    &lt;span class="k"&gt;member&lt;/span&gt; &lt;span class="o"&gt;__.&lt;/span&gt;&lt;span class="n"&gt;rotateX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;angle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt;&lt;span class="o"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;unit&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;jsNative&lt;/span&gt;
    &lt;span class="k"&gt;member&lt;/span&gt; &lt;span class="o"&gt;__.&lt;/span&gt;&lt;span class="n"&gt;box&lt;/span&gt;&lt;span class="bp"&gt;()&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;unit&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;jsNative&lt;/span&gt;

&lt;span class="c1"&gt;// client code&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;sketch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;p5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setup&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="bp"&gt;()&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;createCanvas&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="o"&gt;.,&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="o"&gt;.,&lt;/span&gt; &lt;span class="nc"&gt;WebGL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;draw&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="bp"&gt;()&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;background&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rotateX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;millis&lt;/span&gt;&lt;span class="bp"&gt;()&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="o"&gt;.)&lt;/span&gt;
        &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;box&lt;/span&gt;&lt;span class="bp"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;// draw    &lt;/span&gt;
&lt;span class="n"&gt;p5&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sketch&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ignore&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lo and behold!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Feppumtse4jm7sj0hxf6n.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Feppumtse4jm7sj0hxf6n.gif" alt="Alt Text" width="583" height="502"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's it for this tutorial. The final project can be found &lt;a href="https://github.com/semuserable/fable-basic-interop" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thanks for reading, I hope it was helpful!&lt;/p&gt;

&lt;h1&gt;
  
  
  Additional resources
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://fable.io/" rel="noopener noreferrer"&gt;fable.io&lt;/a&gt; - official site&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://fable.io/repl/" rel="noopener noreferrer"&gt;Fable REPL&lt;/a&gt; - ready to use projects with REPL style&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://fable.io/community/" rel="noopener noreferrer"&gt;Fable community&lt;/a&gt; - libs, projects, templates&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/kunjee17/awesome-fable" rel="noopener noreferrer"&gt;awesome Fable&lt;/a&gt; - curated list of useful &lt;code&gt;Fable&lt;/code&gt; goodness, inspired by &lt;a href="https://github.com/sindresorhus/awesome" rel="noopener noreferrer"&gt;awesome&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>dotnet</category>
      <category>fsharp</category>
      <category>fable</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Simplest TypeScript project using Visual Studio Code</title>
      <dc:creator>semuserable</dc:creator>
      <pubDate>Sun, 03 Mar 2019 12:19:27 +0000</pubDate>
      <link>https://dev.to/semuserable/simplest-typescript-project-using-visual-studio-code-1lgl</link>
      <guid>https://dev.to/semuserable/simplest-typescript-project-using-visual-studio-code-1lgl</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Disclaimer: originally posted on &lt;code&gt;medium&lt;/code&gt;, but revised and updated for &lt;code&gt;dev.to&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This tutorial is aimed for newcomers to &lt;code&gt;TypeScript&lt;/code&gt; and &lt;code&gt;Visual Studio Code&lt;/code&gt;. You won’t find here deep programming concepts or challenges as I tried to come up with the simplest possible solution. Originally it was written just for myself, but then I decided to share it. Also, it’s for Windows platform, but if you use another OS it’s not difficult to make a switch.&lt;/p&gt;

&lt;h1&gt;
  
  
  Preface
&lt;/h1&gt;

&lt;p&gt;I won’t go into much detail about what &lt;code&gt;TypeScript&lt;/code&gt; is as all the relevant info can easily be found on wiki, but rather how to start using it from within Visual Studio Code.&lt;/p&gt;

&lt;h1&gt;
  
  
  Setup
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;get &lt;a href="https://code.visualstudio.com/" rel="noopener noreferrer"&gt;Visual Studio Code&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;get &lt;a href="https://nodejs.org/en/" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt;. It comes with &lt;code&gt;npm&lt;/code&gt; package manager&lt;/li&gt;
&lt;li&gt;open command prompt and run the following command to install the latest stable version of &lt;code&gt;TypeScript&lt;/code&gt; globally
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install -g typescript
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;check globally installed packages
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm list -g --depth=0 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Configuration
&lt;/h1&gt;

&lt;p&gt;Create an empty folder and open it in &lt;code&gt;Visual Studio Code&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;First thing we need to do is to create &lt;code&gt;tsconfig.json&lt;/code&gt; file. In order to do so we'll execute this command in terminal (&lt;code&gt;Ctrl+`&lt;/code&gt; to open terminal)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tsc --init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;create source code (ex. &lt;code&gt;main.ts&lt;/code&gt;)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Person&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nf"&gt;say&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;mike&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Mike&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="na"&gt;say&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`My name is &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; and I'm &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; years old!`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;sayIt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;person&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;say&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;sayIt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mike&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;now we want to setup a convenient build process in order to run the project with a couple of buttons. Press &lt;code&gt;Ctrl+Shift+P&lt;/code&gt; and start typing &lt;strong&gt;Configure Default Build Task&lt;/strong&gt;, press &lt;code&gt;Enter&lt;/code&gt; to select it then &lt;strong&gt;tsc: build - tsconfig.json&lt;/strong&gt;. This will create a file named &lt;code&gt;tasks.json&lt;/code&gt; in &lt;code&gt;.vscodefolder&lt;/code&gt; (click &lt;code&gt;Refresh Explorer&lt;/code&gt; on a project tab to see the changes). Now we have all needed commands and arguments for our build.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is our project structure after all the steps.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fzumpwn4zf25gmo1mbeea.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fzumpwn4zf25gmo1mbeea.png" alt="Project structure" width="327" height="158"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Run
&lt;/h1&gt;

&lt;p&gt;It’s time to finally run the build task. Press &lt;code&gt;Ctrl+Shift+B&lt;/code&gt; and if all went well a new file will be created (&lt;code&gt;main.js&lt;/code&gt;). In order to see the output we need to feed it into &lt;code&gt;node&lt;/code&gt; command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;node main.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s see it in action!&lt;br&gt;
&lt;a href="https://media2.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%2Fvl9656xirha4f9sz4r4l.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fvl9656xirha4f9sz4r4l.gif" alt="Node run" width="581" height="203"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Alrighty! We had fun with command line and eager to try something new. Let’s create a minimal &lt;code&gt;html&lt;/code&gt; and change some DOM properties of the page through &lt;code&gt;TypeScript&lt;/code&gt;.&lt;/p&gt;
&lt;h1&gt;
  
  
  Working with DOM
&lt;/h1&gt;

&lt;p&gt;Create a new file named index.html. It’s so minimalist that I’m even embarassed a little bit.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;    
    &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Fun with TypeScript&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"rock_id"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Let's rock&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"main.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s change &lt;code&gt;main.ts&lt;/code&gt; file and modify &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt; element inner text using &lt;code&gt;TypeScript&lt;/code&gt;. The main part here is &lt;code&gt;&amp;lt;script src=”main.js”&amp;gt;&lt;/code&gt; element. &lt;code&gt;main.js&lt;/code&gt; is a transplied code from &lt;code&gt;TypeScript&lt;/code&gt; and will run naturally.&lt;/p&gt;

&lt;p&gt;WARNING!!! Another minimalist example!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rock_id&lt;/span&gt;&lt;span class="dl"&gt;"&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="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Changed by TypeScript!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Final project structure after all the changes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F7caq8hmaq2vjqr9dqdy6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F7caq8hmaq2vjqr9dqdy6.png" alt="Final project structure" width="180" height="181"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Press &lt;code&gt;Ctrl+Shift+B&lt;/code&gt; and check &lt;code&gt;main.js&lt;/code&gt; file (just for curiosity). Next, open &lt;code&gt;index.html&lt;/code&gt; and observe the result. Wow! So easy!&lt;/p&gt;

&lt;dl&gt;
  
  &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fj3knwq2gfsmwv5huqtjs.png" alt="Index html" width="200" height="109"&gt;index.html page
  

&lt;/dl&gt;

&lt;p&gt;Awesome, but there is something strange in this example. What is &lt;code&gt;!&lt;/code&gt; symbol doing here? It’s called the &lt;a href="https://github.com/Microsoft/TypeScript/wiki/What%27s-new-in-TypeScript#user-content-non-null-assertion-operator" rel="noopener noreferrer"&gt;non-null assertion operator&lt;/a&gt;. Compiler forces us to check for &lt;code&gt;null/undefined&lt;/code&gt; values if &lt;code&gt;tsconfig.json&lt;/code&gt; is configured with  &lt;code&gt;strict&lt;/code&gt; flag. If we try to omit it the compiler will yell at you.&lt;/p&gt;

&lt;dl&gt;
  
  &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fal0hu1zlairzwi6re1na.png" alt="Compiler error" width="760" height="67"&gt;Compiler error with -strict flag
  

&lt;/dl&gt;

&lt;p&gt;We must explicitly check for &lt;code&gt;null/undefined&lt;/code&gt; in order to safely use the return value from &lt;code&gt;.getElementById&lt;/code&gt;. But in this example it’s redundant because I’m 100% sure that it won’t return any &lt;code&gt;null/undefined&lt;/code&gt;. So I just use &lt;code&gt;!&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That’s it! Thanks for reading!&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>web</category>
      <category>tutorial</category>
      <category>node</category>
    </item>
  </channel>
</rss>
