<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Chamal Mallawaarachchi</title>
    <description>The latest articles on Forem by Chamal Mallawaarachchi (@chamal1120).</description>
    <link>https://forem.com/chamal1120</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%2F1282790%2Fec4630b7-8ae9-4735-8933-9a3adff05d6a.jpg</url>
      <title>Forem: Chamal Mallawaarachchi</title>
      <link>https://forem.com/chamal1120</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/chamal1120"/>
    <language>en</language>
    <item>
      <title>Pyrefly: A new rust based Language Server for Python from Meta</title>
      <dc:creator>Chamal Mallawaarachchi</dc:creator>
      <pubDate>Thu, 20 Nov 2025 07:04:05 +0000</pubDate>
      <link>https://forem.com/chamal1120/pyrefly-a-new-rust-based-language-server-for-python-from-meta-11il</link>
      <guid>https://forem.com/chamal1120/pyrefly-a-new-rust-based-language-server-for-python-from-meta-11il</guid>
      <description>&lt;p&gt;Today, Meta has announced the first public beta of their new in-development open source Language Server for Python called Pyrefly.&lt;/p&gt;

&lt;p&gt;According to Meta this was started as an in-house tool for their instagram developers as they were experiencing severe performance issues when navigating their codebases with exisiting Python tooling.&lt;/p&gt;

&lt;p&gt;While there are other fast language servers like Ruff which doesn't perform static type checking, Pyrefly is aiming to be both faster and feature complete type cheker and a Language Server.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Features in the type checker:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Type Inference: Pyrefly infers types in most locations, apart from function parameters. It can infer types of variables and return types.&lt;/li&gt;
&lt;li&gt;Flow Types: Pyrefly can understand your program's control flow to refine static types.&lt;/li&gt;
&lt;li&gt;Incrementality: Pyrefly aims for large-scale incrementality at the module level, with optimized checking and parallelism.&lt;/li&gt;
&lt;/ul&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%2Fzgunjgre729wf9v98fyq.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%2Fzgunjgre729wf9v98fyq.png" alt="pyrefly-type-checking" width="800" height="509"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Other than these, Pyrefly supports all the other features of Language Server Protocol (LSP) and generally the first thing you'll feel is the lightning fast autocomplete even in the dense codebases.&lt;/p&gt;

&lt;p&gt;NOTE: As of the Beta release in November 2025, Pyrefly is over 70% conformant with the Python Typing Specification. So it might not be a good choice for your complex production codebase yet but I would recommend it for small personal projects. Meta also mentioned that many improvements are needed for third party libraries like Django.&lt;/p&gt;

&lt;h2&gt;
  
  
  A perormance comparison meta showcased
&lt;/h2&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%2Fx5u85z38zj6jqalr3zhr.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%2Fx5u85z38zj6jqalr3zhr.png" alt="pyrefly-benchmark-by-meta" width="800" height="175"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Wanna give it a try?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  From browser
&lt;/h3&gt;

&lt;p&gt;Meta has created a sandbox that you can jump in from the browser and test Pyrefly.&lt;/p&gt;

&lt;p&gt;Pyrefly Sandbox - &lt;a href="https://pyrefly.org/sandbox" rel="noopener noreferrer"&gt;https://pyrefly.org/sandbox&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  By installing
&lt;/h3&gt;

&lt;p&gt;Pyrefly is available in PyPI and can be installable from your favourite python package manager.&lt;/p&gt;

&lt;p&gt;Below commands show you how can get started using some famous python package and runtime managers.&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="c"&gt;# using pip&lt;/span&gt;
pip &lt;span class="nb"&gt;install &lt;/span&gt;pyrefly
pyrefly init
pyrefly check &lt;span class="nt"&gt;--summarize-errors&lt;/span&gt;

&lt;span class="c"&gt;# using conda&lt;/span&gt;
conda &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; conda-forge pyrefly
pyrefly init
pyrefly check &lt;span class="nt"&gt;--summarize-errors&lt;/span&gt;

&lt;span class="c"&gt;# using uv&lt;/span&gt;
uvx pyrefly init
uvx pyrefly check &lt;span class="nt"&gt;--summarize-errors&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  IDE extensions?
&lt;/h2&gt;

&lt;p&gt;Yes, Meta already provides IDE extensions for Pyrefly for all major  IDEs.&lt;/p&gt;

&lt;p&gt;For VSCode, you can easily get it from their marketplace.&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%2Fltiqct3zuc7qmcsvrapb.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%2Fltiqct3zuc7qmcsvrapb.png" alt="pyrefly-vscode-extension" width="800" height="120"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For other code-oss based IDEs like Codium, the extension is available in openvsx.&lt;/p&gt;

&lt;p&gt;Openvsx link - &lt;a href="https://open-vsx.org/extension/meta/pyrefly" rel="noopener noreferrer"&gt;https://open-vsx.org/extension/meta/pyrefly&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What about GOAT text editors?
&lt;/h2&gt;

&lt;p&gt;Pyrefly is easily installable for Vim/Neovim, Emacs and Helix. &lt;/p&gt;

&lt;p&gt;Refer this section - &lt;a href="https://pyrefly.org/en/docs/IDE/#other-editors" rel="noopener noreferrer"&gt;https://pyrefly.org/en/docs/IDE/#other-editors&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  More information and references
&lt;/h2&gt;

&lt;p&gt;Pyrefly repository - &lt;a href="https://github.com/facebook/pyrefly" rel="noopener noreferrer"&gt;https://github.com/facebook/pyrefly&lt;/a&gt;&lt;br&gt;
Pyrefly Documentation - &lt;a href="https://pyrefly.org/en/docs" rel="noopener noreferrer"&gt;https://pyrefly.org/en/docs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thank you for reading upto here ❤️.&lt;/p&gt;

</description>
      <category>python</category>
      <category>ai</category>
      <category>productivity</category>
      <category>rust</category>
    </item>
    <item>
      <title>How to use unsupported macbooks for modern software development</title>
      <dc:creator>Chamal Mallawaarachchi</dc:creator>
      <pubDate>Sat, 15 Nov 2025 17:46:55 +0000</pubDate>
      <link>https://forem.com/chamal1120/how-to-use-unsupported-macbooks-for-modern-software-development-4nol</link>
      <guid>https://forem.com/chamal1120/how-to-use-unsupported-macbooks-for-modern-software-development-4nol</guid>
      <description>&lt;p&gt;If you clicked on this, chances are either you own an old unsupported macbook or willing to buy one to kickstart your development journey.&lt;/p&gt;

&lt;p&gt;Hey, that's a great decision in my opinion. If you don't have enough money to jump to a new MacBook, do not go for cheap Windows laptops. Instead consider an old MacBook.&lt;/p&gt;

&lt;h3&gt;
  
  
  But why?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Coz they have great displays. You will be starring at text for the rest of the journey so why not go for a better display?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Great keyboards (except the 2016-2017 models)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Great webcams, speakers and battery backup.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;MacOS is optimized for MacBooks and probability of you getting into OS related bugs are very low compared to a Windows machine.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Looks sleek, well built, good hinge mechanisms, auto brightness for both keyboard and display and many more quality of life things that most cheap Windows laptops skips.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You can even install Windows alongside MacOS if there's something that isn't working for you in MacOS (Only on Intel MacBooks).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  A note before going any further
&lt;/h3&gt;

&lt;p&gt;Please do not buy unsupported macbooks for iOS or any apple application development. While you will be able to develop, you won't be able to publish those to appstore.&lt;/p&gt;

&lt;h3&gt;
  
  
  Here are some models that I recommend
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;2013-2015 models (super cheap)&lt;/li&gt;
&lt;li&gt;2018-2019 models (if you can spend a little more)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Alright, Still in?
&lt;/h3&gt;

&lt;p&gt;Cool, then from here on I'm gonna tell you exactly what you need to do once you get that old mac to set it up to get the best juice out of it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Get a package manager up and running
&lt;/h3&gt;

&lt;p&gt;For those who don't know, a package manager is a terminal based tool (most of the time) that makes managing software easier than installing with any other way. Most Unix like OSes comes with a one but MacOS doesn't for some reason. But we can install one. Homebrew is the most famous option but it only supports upto 3 latest MacOS versions and if yours aren't in that, every app you install with that will build from source. It's a nightmare. Don't install homebrew if you're even on the supported OS list as it will get unsupported soon and after that you can't go any OS beyond that.&lt;/p&gt;

&lt;p&gt;Instead go for &lt;strong&gt;MacPorts package manager&lt;/strong&gt;. It supports versions as old as El Capitan (Even a 2012 model can go beyond that version).&lt;/p&gt;

&lt;p&gt;As long as you're on a model later than 2013, you'll have no problem installing modern software development kits like Java 21, Node.js latest, C/C++ 17, Flutter 3.x.x, Python 3.x.x, Dotnet 9 and etc.&lt;/p&gt;

&lt;p&gt;Macports -&amp;gt; &lt;a href="https://www.macports.org" rel="noopener noreferrer"&gt;https://www.macports.org&lt;/a&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%2Fuploads%2Farticles%2F63t4hzzc80en1fka5n5q.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%2F63t4hzzc80en1fka5n5q.png" alt="macports-macos" width="800" height="498"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Keep the OS lightweight
&lt;/h3&gt;

&lt;p&gt;While this things is pretty expected to know by anyone but added this anyways in case some might think that they would be able to run whole bunch of heavy applications. Only keep neccessary applications and do not add anything if that thing is provided by OS itself.&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%2F016y6g3awoc59hf6w10g.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%2F016y6g3awoc59hf6w10g.png" alt="lightweight-macos-1" width="800" height="569"&gt;&lt;/a&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%2Fuploads%2Farticles%2F2rlhztrl82x4djkwsyey.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%2F2rlhztrl82x4djkwsyey.png" alt="lightweight-macos-2" width="800" height="143"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Some things you get from MacOS by default,&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A simple screen recorder and screenshot tool&lt;/li&gt;
&lt;li&gt;Voice recorder&lt;/li&gt;
&lt;li&gt;A color picker (Useful for webd dev and designing)&lt;/li&gt;
&lt;li&gt;A camera app&lt;/li&gt;
&lt;li&gt;Notes taking app&lt;/li&gt;
&lt;li&gt;Music and video players&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;There's many more that MacOS has built in so definitely Google what you need to see if it already in the OS before going for a third party application.&lt;/p&gt;

&lt;h3&gt;
  
  
  Switch to CLI apps as much as possible
&lt;/h3&gt;

&lt;p&gt;This is the most impactful trick and this also helps you to become a better software developer as well. Always stick to CLI apps as much as possible. There will be a steep learning curve but it's gonna reward you along the way. Belive me.&lt;/p&gt;

&lt;p&gt;Some examples,&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Use Git CLI instead of any GIT GUIs&lt;/li&gt;
&lt;li&gt;Use terminal for files, and folder navigation.&lt;/li&gt;
&lt;li&gt;Use things like grep, sed or awk for searching files&lt;/li&gt;
&lt;li&gt;Use a terminal multiplexer to split the terminal instead of openning multiple terminal windows.&lt;/li&gt;
&lt;li&gt;Skip code editors like VSCode or any of it's forks. They run on electron which takes a lot of CPU and RAM just to even keep it running without doing anything. Switch to efficient editors that provides native binaries. I'd recommend Emacs if you need a Graphical User Interface or VIM/Neovim if terminal is comfortable.&lt;/li&gt;
&lt;/ol&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%2F8j9xextxzcdrvi0lgct6.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%2F8j9xextxzcdrvi0lgct6.png" alt="macos-cli-experience" width="800" height="496"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Do not customize your terminal too much
&lt;/h3&gt;

&lt;p&gt;I have seen that customizing the terminal too much also affects older macs to get slow even inside the terminal.&lt;/p&gt;

&lt;p&gt;Notable performance culprits I have noticed,&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Do not use Starship to customize your prompt. Use powerlevel10k. They are similar in customization but starship takes a lot of CPU power which makes your terminal emulator laggy.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Use an efficient terminal emulator that supports true color
&lt;/h3&gt;

&lt;p&gt;There's many. Choose something that fit's your liking. I recommend Alacritty or Kitty.&lt;/p&gt;

&lt;p&gt;Alacritty -&amp;gt; &lt;a href="https://alacritty.org" rel="noopener noreferrer"&gt;https://alacritty.org&lt;/a&gt;&lt;br&gt;
Kitty -&amp;gt; &lt;a href="https://sw.kovidgoyal.net/kitty" rel="noopener noreferrer"&gt;https://sw.kovidgoyal.net/kitty&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Use Turbo Boost Switcher
&lt;/h3&gt;

&lt;p&gt;A third party free software that use can use to turn off turbo boost when doing normal work. (I only enable turbo boost when compiling fairly large software)&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%2F24y4dnmee2rwvkdfkkww.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%2F24y4dnmee2rwvkdfkkww.png" alt="turbo-boost-switcher-macos" width="636" height="932"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Turbo Boost Switcher -&amp;gt; &lt;a href="https://tbswitcher.rugarciap.com" rel="noopener noreferrer"&gt;https://tbswitcher.rugarciap.com&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Finally, Some etc tips!
&lt;/h3&gt;

&lt;p&gt;If this MacBook is your first computer, it's better you understand how Unix works a little bit as well because it will help you to setup the computer, fix bugs and save from many other pifalls many new MacOS users face as developers.&lt;/p&gt;

&lt;p&gt;Some things that I think you might needed,&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;[XDG Base Directory Specification]&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;(&lt;a href="https://specifications.freedesktop.org/basedir/latest/" rel="noopener noreferrer"&gt;https://specifications.freedesktop.org/basedir/latest/&lt;/a&gt;)&lt;br&gt;
While MacOS itself doesn't respect this, many applications that will use as a developer in MacOS will respect this spec. So give it a read so you won't be hammering ChatGPT or google search asking "where the heck is my config for X app or Y app" and end up with delusional answers utltimately breaking other apps.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;[How manage environment variables]&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;(&lt;a href="https://support.apple.com/en-is/guide/terminal/apd382cc5fa-4f58-4449-b20a-41c53c006f8f/2.12/mac/11.0" rel="noopener noreferrer"&gt;https://support.apple.com/en-is/guide/terminal/apd382cc5fa-4f58-4449-b20a-41c53c006f8f/2.12/mac/11.0&lt;/a&gt;)&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;[File System Hierachy Standard]&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;(&lt;a href="https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard" rel="noopener noreferrer"&gt;https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard&lt;/a&gt;)&lt;br&gt;
You won't find all of the directories in this standard in MacOS as apple has done some modifications to this like &lt;code&gt;/Library&lt;/code&gt; for an example. Nevertheless, you might find this useful. Just read it, try doing &lt;code&gt;ls&lt;/code&gt; for each of those directories so you can know what you have, which you'll be able to use when you need them.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;When you first try to see if git is available or a compiler is available, you'll be prompted to install xcode-commandline-tools which will install many other programs behind your back. (i.e. Python3, Git, Clang(MacOS C-compiler), curl, grep, rsync and few others). Why I'm telling this is that, while it is good that they get installed automatically but they're not the most upto date versions. So I recommend you to install upto date tools using a package manager like macports set it has the default using the environment variables.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Many kids start with web dev. So you might getinto trouble with npm failed to install packages when you try to install them globally.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;New users eat their hair trying to fix this. The most simplest and easiest solution that I can suggest is creating a directory for npm global packages in the /home directory and assign it to npm using environment variables.&lt;/p&gt;

&lt;p&gt;Let me leave it here in case you want to fix it quickly&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="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt; &lt;span class="c"&gt;# make sure you're in home directory&lt;/span&gt;
/Users/&amp;lt;your-username&amp;gt;

&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; .npm-global &lt;span class="c"&gt;# create a directory&lt;/span&gt;

&lt;span class="nv"&gt;$ &lt;/span&gt;npm config &lt;span class="nb"&gt;set &lt;/span&gt;prefix &lt;span class="s1"&gt;'~/.npm-global'&lt;/span&gt; &lt;span class="c"&gt;# Set the prefix config variable&lt;/span&gt;

&lt;span class="nv"&gt;$ &lt;/span&gt;vim .zshrc &lt;span class="c"&gt;# open .zshrc file with a text-editor (i use vim here)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Paste the below line to it. Save and exit.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export PATH="$HOME/.npm-global/bin:$PATH"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;source&lt;/span&gt; ~/.zshrc &lt;span class="c"&gt;# reload zshell config&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now your npm global package installs will work!&lt;/p&gt;

&lt;h3&gt;
  
  
  That's it!
&lt;/h3&gt;

&lt;p&gt;If you can bear with those things, I think you'll have a great overall experience.&lt;/p&gt;

&lt;p&gt;Thank you for reading upto here ❤️.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>ai</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Meet Asgardeo: Your last stop for IaaS</title>
      <dc:creator>Chamal Mallawaarachchi</dc:creator>
      <pubDate>Fri, 14 Nov 2025 18:06:36 +0000</pubDate>
      <link>https://forem.com/chamal1120/the-iaas-that-saves-money-wtih-no-compromises-4pg6</link>
      <guid>https://forem.com/chamal1120/the-iaas-that-saves-money-wtih-no-compromises-4pg6</guid>
      <description>&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Are you using multiple services for manging authentication for your business/personal projects that accumilates several payment plans?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Are you frustrated on complex configurations for branding and workflow management?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;And still get stuck when it comes to extensiblity?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What if I say there's a product that checks all these under one bill.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enter Asgardeo
&lt;/h2&gt;

&lt;p&gt;Asgardeo is an &lt;a href="https://www.computer.org/publications/tech-news/trends/identity-as-a-service" rel="noopener noreferrer"&gt;IaaS&lt;/a&gt; (Identity as a Service) provided by &lt;a href="https://wso2.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;WSO2&lt;/strong&gt;&lt;/a&gt; for the modern AI blended era. It is a hosted and first party supported version of their own open source Identity Server.&lt;/p&gt;

&lt;p&gt;Yeah you heard it right. It is open source if you want and have time to set it up yourself on your own infrastructure.&lt;/p&gt;

&lt;h2&gt;
  
  
  So what's special about Asgardeo?
&lt;/h2&gt;

&lt;p&gt;It can deliver the same functionalities you orchestrated using bunch of services at your favourite cloud infrastructure provider as a single product.&lt;/p&gt;

&lt;p&gt;Some of the highlighting features includes,&lt;/p&gt;

&lt;h3&gt;
  
  
  1. A visual editor to customize your auth flow and how it looks.
&lt;/h3&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%2F5uieia5onxaf8mpcidx2.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%2F5uieia5onxaf8mpcidx2.png" alt="asgardeo-visual-login-form-editor"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Multiple ways for user onboarding including self-sign-up invitation and social account linking.
&lt;/h3&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%2Fgptmnp89mh4vqikqcyrg.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%2Fgptmnp89mh4vqikqcyrg.png" alt="asgardeo-single-user-creation"&gt;&lt;/a&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%2Fuploads%2Farticles%2Fe07d399comk9mek9fizz.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%2Fe07d399comk9mek9fizz.png" alt="asgardeo-multiple-user-onboarding"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Define your branding and login flow with AI.
&lt;/h3&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%2Fp1qxlr45s034todw8whr.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%2Fp1qxlr45s034todw8whr.png" alt="asgardeo-ai-based-branding"&gt;&lt;/a&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%2Fuploads%2Farticles%2Ftr6nqzr5lqb627d1cb83.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%2Ftr6nqzr5lqb627d1cb83.png" alt="asgardeo-ai-based-login-flow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Plethora of authentication methods including passwordless login.
&lt;/h3&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%2Fmf6vscl0v89b13uewx26.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%2Fmf6vscl0v89b13uewx26.png" alt="asgardeo-authentication-methods"&gt;&lt;/a&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%2Fuploads%2Farticles%2Ft2rn6qqy03cwo2f7kayg.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%2Ft2rn6qqy03cwo2f7kayg.png" alt="asgardeo-social-login-catalog"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Bulit-in logging and monitoring.
&lt;/h3&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%2Fhs0cgf4y29oueqd79eqk.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%2Fhs0cgf4y29oueqd79eqk.png" alt="asgardeo-logs-screen"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  6. supports webhooks to bring notifications to wherever you want.
&lt;/h3&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%2Ffc90dtcsl6oblnyl6rxf.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%2Ffc90dtcsl6oblnyl6rxf.png" alt="asgardeo-webhooks"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  7. SDKs for all widely used frameworks and technologies with joyful developer experience.
&lt;/h3&gt;

&lt;p&gt;--&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Checkout this video where I integrate Asgardeo authentication to Next.Js under 10 mins:


  &lt;iframe src="https://www.youtube.com/embed/M-jDQy9631A"&gt;
  &lt;/iframe&gt;


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

&lt;h2&gt;
  
  
  This is just the surface
&lt;/h2&gt;

&lt;p&gt;I am just touching the surface of this product and it has many powerful features that might feel like a godsend for your specific workflows. So definetely give this product a go. It has a free tier that doesn't require any payment method so you can go for a spin without wasting a cent.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sign up for Asgardeo -&amp;gt; &lt;a href="https://asgardeo.io" rel="noopener noreferrer"&gt;https://asgardeo.io&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Learn more about Asgardeo -&amp;gt; &lt;a href="https://wso2.com/asgardeo/docs" rel="noopener noreferrer"&gt;https://wso2.com/asgardeo/docs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Identity Server Source Code -&amp;gt; &lt;a href="https://github.com/wso2/product-is" rel="noopener noreferrer"&gt;https://github.com/wso2/product-is&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for reading up to here ❤️. Give this a share if you think helpful.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ai</category>
      <category>identity</category>
      <category>cloudnative</category>
    </item>
    <item>
      <title>How to use curl</title>
      <dc:creator>Chamal Mallawaarachchi</dc:creator>
      <pubDate>Sat, 03 May 2025 15:47:52 +0000</pubDate>
      <link>https://forem.com/chamal1120/how-to-use-curl-5gha</link>
      <guid>https://forem.com/chamal1120/how-to-use-curl-5gha</guid>
      <description>&lt;h2&gt;
  
  
  What is &lt;strong&gt;curl&lt;/strong&gt;?
&lt;/h2&gt;

&lt;p&gt;curl (connect URL) is a command line tool and a library for transferring data with URLs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why you should learn &lt;strong&gt;curl&lt;/strong&gt;?
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Test any REST/ GraphQL/ API&lt;/li&gt;
&lt;li&gt;Test anything else related to http/https requests and responses.&lt;/li&gt;
&lt;li&gt;Test xml/ json RPC protocols&lt;/li&gt;
&lt;li&gt;Upload/ download files&lt;/li&gt;
&lt;li&gt;Perform Monitoring and deployments with the help of scripts&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you're an engineer of just a pc enthusiast who works with urls, you should learn curl coz it's gonna make your life easier.&lt;/p&gt;

&lt;h2&gt;
  
  
  Useful &lt;strong&gt;curl&lt;/strong&gt; Flags:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-X &amp;lt;method&amp;gt;&lt;/code&gt;: Specifies the HTTP method (e.g., GET, POST, PUT, DELETE).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-H "&amp;lt;header&amp;gt;"&lt;/code&gt;: Adds a header to the request.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-d "&amp;lt;data&amp;gt;"&lt;/code&gt;: Sends data with a POST request (useful for sending JSON).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-I&lt;/code&gt;: Fetches only the HTTP headers.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-O&lt;/code&gt;: Saves the response to a file.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-L&lt;/code&gt;: Follows redirects.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-u &amp;lt;username&amp;gt;:&amp;lt;password&amp;gt;&lt;/code&gt;: For basic authentication.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-F "&amp;lt;form-field=@file&amp;gt;"&lt;/code&gt;: Used to upload files.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-v&lt;/code&gt;: Enables verbose output to see request/response details.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-H "Authorization: Bearer &amp;lt;token&amp;gt;"&lt;/code&gt;: Adds a Bearer token for authentication.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Examples of Using curl
&lt;/h2&gt;



&lt;h4&gt;
  
  
  REST API Example
&lt;/h4&gt;

&lt;p&gt;To make a GET request to a REST API endpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; GET https://api.example.com/users
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To send data with a POST request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://api.example.com/login &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"username": "user", "password": "pass"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  GraphQL API Example
&lt;/h4&gt;

&lt;p&gt;To send a query to a GraphQL API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://api.example.com/graphql &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"query": "{ users { id name } }"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To use variables in the query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://api.example.com/graphql &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"query": "query($id: ID!) { user(id: $id) { name } }", "variables": {"id": "123"}}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  JSON-RPC Example
&lt;/h4&gt;

&lt;p&gt;To call a method in a JSON-RPC API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://example.com/api &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
  "jsonrpc": "2.0",
  "method": "getUser",
  "params": {"id": 1},
  "id": 1
}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  File Upload Example
&lt;/h4&gt;

&lt;p&gt;To upload a file using &lt;code&gt;curl&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;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://example.com/upload &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-F&lt;/span&gt; &lt;span class="s2"&gt;"file=@path/to/file.jpg"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  File Download Example
&lt;/h4&gt;

&lt;p&gt;To download a file and save it locally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-O&lt;/span&gt; https://example.com/file.zip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Testing API with Authentication
&lt;/h4&gt;

&lt;p&gt;For a REST API with Bearer token authentication:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; GET https://api.example.com/protected-resource &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer &amp;lt;your-token&amp;gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Testing API with Basic Authentication
&lt;/h4&gt;

&lt;p&gt;For a REST API with Basic authentication:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-u&lt;/span&gt; &lt;span class="s2"&gt;"username:password"&lt;/span&gt; https://api.example.com/protected-resource
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Follow Redirects
&lt;/h4&gt;

&lt;p&gt;To make a request and follow any redirects:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-L&lt;/span&gt; https://example.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Get Only HTTP Headers
&lt;/h4&gt;

&lt;p&gt;To retrieve only the HTTP headers of a response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-I&lt;/span&gt; https://example.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
This should be all in one block, ready for you to use. Let me know if you need any more adjustments!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Curl is more than you think
&lt;/h2&gt;

&lt;p&gt;Believe me when I say this, I cannot cover all of the &lt;code&gt;curl&lt;/code&gt;'s functionalities from one article. &lt;/p&gt;

&lt;p&gt;If I did, it would be book. Infact, there is one if you're curious.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Go ahead and read if you want to know -&amp;gt; &lt;a href="https://everything.curl.dev" rel="noopener noreferrer"&gt;Everything about curl&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>linux</category>
      <category>api</category>
      <category>networking</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Cron Jobs for absolute beginners</title>
      <dc:creator>Chamal Mallawaarachchi</dc:creator>
      <pubDate>Fri, 02 May 2025 08:30:05 +0000</pubDate>
      <link>https://forem.com/chamal1120/cron-jobs-for-absolute-beginners-1dj3</link>
      <guid>https://forem.com/chamal1120/cron-jobs-for-absolute-beginners-1dj3</guid>
      <description>&lt;h3&gt;
  
  
  What the heck is Cron?
&lt;/h3&gt;

&lt;p&gt;Cron was originally existed as a preinstalled utility in old Unix systems. It was created to run scheduled jobs or in other words to execute something in a predefined time in future.&lt;/p&gt;

&lt;p&gt;Since GNU/Linux also created as a Unix like system, this functionality has been offered using multiple open source applications.&lt;/p&gt;

&lt;p&gt;Cron runs jobs repetitively, if you want to just run a command once there's another Unix utility called &lt;code&gt;at&lt;/code&gt; which will not be explained here.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fun fact!
&lt;/h3&gt;

&lt;p&gt;The name Cron originated from the Greek word &lt;code&gt;Chronos&lt;/code&gt; which means &lt;code&gt;Time&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Don't get confused!!
&lt;/h3&gt;

&lt;p&gt;There are multiple implementations of Cron for Linux. Some of the most used ones are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cronie&lt;/strong&gt; - Default Cron implementation on RHEL (Red Hat Enterprise Linux)  and RHEL based distros.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Dcron&lt;/strong&gt; - A lightweight implementation for distro's like Alpine and embedded systems.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;fcron&lt;/strong&gt; - One with support for non 24/7 systems.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Vixie-cron&lt;/strong&gt; - One of the earliest implementations.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Despite these multiple applications, they all invokes using the same commands/flags and use the same file formats and share the same basic structure while some of them having additional features.&lt;/p&gt;

&lt;p&gt;SO, SIMPLY YOU DON'T NEED TO WORRY AS LONG AS YOU HAVE ONE OF THE ABOVE INSTALLED.&lt;/p&gt;

&lt;h3&gt;
  
  
  Don't jump ahead and Install yet!
&lt;/h3&gt;

&lt;p&gt;Most of the GNU/Linux distro's comes with a cron application pre-installed. If it isn't, chances are it is available through their official package repositories.&lt;/p&gt;

&lt;p&gt;Ubuntu, Ubuntu based, RHEL and RHEL based distro's are usually come with cron pre-installed.&lt;/p&gt;

&lt;p&gt;For a system like Arch or Alpine linux, you need to install one from their package repositories and in that case choose one that is available and fit's for your needs.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can check if a cron application is available using the following command:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl status cron
&lt;span class="c"&gt;# this will only work on distro's with Systemd init system&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Most modern GNU/Linux distro's use systemd but if yours not, refer distro's documentation for the init system and how to check the services status.&lt;/p&gt;

&lt;h4&gt;
  
  
  Service is not running!
&lt;/h4&gt;

&lt;p&gt;Dont't worry just start it:&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;sudo &lt;/span&gt;systemctl start cron
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  For distro's with no cron (examples are for arch and RHEL based)
&lt;/h4&gt;

&lt;p&gt;Don't worry, just,&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install it using your default package manager:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;pacman &lt;span class="nt"&gt;-S&lt;/span&gt; cronie &lt;span class="c"&gt;# for arch based&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;yum &lt;span class="nb"&gt;install &lt;/span&gt;cronie &lt;span class="c"&gt;# RHEL based&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Enable the service:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;cronie.service &lt;span class="c"&gt;# for arch and RHEL based&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Start the service:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl start cronie.service &lt;span class="c"&gt;# for arch and RHEL based&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  How to use
&lt;/h3&gt;

&lt;p&gt;There are two basic terms you need be familiar first:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cron Job&lt;/strong&gt; - is single job (a command or  a set of commands) that is scheduled to run for a particular time in future.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Crontab&lt;/strong&gt; - is a file containing one or more Cron Jobs (Crontab is a short term for Cron tables).&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Now, let's see how to create a cron job!
&lt;/h4&gt;

&lt;p&gt;First, understand the format for writing a cron job:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;* * * * * command_to_run
│ │ │ │ │
│ │ │ │ └─ Day of the week (0–7) → 0 or 7 = Sunday
│ │ │ └──── Month (1–12)
│ │ └─────── Day of the month (1–31)
│ └────────── Hour (0–23)
└──────────── Minute (0–59)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The first 5 fields are use to denote the time to the script.&lt;/li&gt;
&lt;li&gt;In an all asterisk case, the command will run infinitely for every minute.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Example 1
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;5 &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"hi from cron job"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will run the echo command on the 5th minute of every hour infinitely.&lt;/p&gt;

&lt;h4&gt;
  
  
  Example 2
&lt;/h4&gt;

&lt;p&gt;Let's narrow it down further,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;5 1 2 &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"hi from cron job"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This job will run on the 5th minute of 1st hour of 2nd of every month infinitely.&lt;/p&gt;

&lt;h4&gt;
  
  
  Example 3
&lt;/h4&gt;

&lt;p&gt;Let's narrow further,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;5 1 2 7 &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"hi from cron job"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This job will run at 1.05 AM on 2nd of July in every year inifintely.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I hope you got the format now. You can run any command, any script, any program using a cron job in a Unix like systems.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  How to actually set this up
&lt;/h4&gt;

&lt;p&gt;With the format sinked in, now let's actually create a cron job.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Configure your default editor:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;EDITOR &lt;span class="o"&gt;=&lt;/span&gt; nvim &lt;span class="c"&gt;# I use neovim, you can put anything you want.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;EDITOR &lt;span class="o"&gt;=&lt;/span&gt; nano &lt;span class="c"&gt;# if you have no idea, use this one.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Execute the following command and crontab will be opened in your default editor:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;crontab &lt;span class="nt"&gt;-e&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;NOTE: If unconfigured, it will open &lt;code&gt;vi&lt;/code&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Now write one or more cron jobs inside the opened file.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;5 &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; yay &lt;span class="nt"&gt;-S&lt;/span&gt; neofetch &lt;span class="c"&gt;# I'm installing a package&lt;/span&gt;
&lt;span class="c"&gt;# Put a command that you can verify later&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;NOTE: If you look for the location of the crontab file, you might see that it is in a temp directory. That's because once you save the file, it will move it your users default crontab.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;3.Verify the status of the command manually. In my case I can see if the package has been installed.&lt;/p&gt;

&lt;h4&gt;
  
  
  So there's no logs?
&lt;/h4&gt;

&lt;p&gt;Cron does print logs to system log file,  but it only contains cron start, stop times and errors encountered by cron. You won't be able to capture all the details you need.&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;grep &lt;/span&gt;CRON /var/log/syslog &lt;span class="c"&gt;# You can grep CRON logs from sys log like this&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  But here's a solution that I use to get a more verbose log!
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;logs &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;touch &lt;/span&gt;cronlogs.log &lt;span class="c"&gt;# I create a logifle in my home directory&lt;/span&gt;
5 &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; yay &lt;span class="nt"&gt;-S&lt;/span&gt; neofetch &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; /home/&amp;lt;username&amp;gt;/logs/cronlogs.log 2&amp;gt;&amp;amp;1
&lt;span class="c"&gt;# Then append the stdout and stderr of the run command to that logfile.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  One more thing about Crontabs
&lt;/h4&gt;

&lt;p&gt;There are some crontabs that comes built in with cron. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;User Crontab
This is the crontab we just used above to run our cronjob. When we execute &lt;code&gt;crontab -e&lt;/code&gt; and write our cron job and save, it will automatically be moved to the current logged user's crontab.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Those Cron Jobs will only run for that user.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Sytem Crontab
If you're the root user or have root access, you can write to the system Crontab as well. These will allow you to specify for which user, a perticular job should run.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You open it using your preffered editor:&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;sudo &lt;/span&gt;nvim /etc/crontab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The format is the same with the addition of the username:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;minute hour day month weekday **user** command
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;NOTE: One Cron Job only can have one user&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Don't leave without reading this
&lt;/h3&gt;

&lt;p&gt;Cron used to be the defacto for scheduling tasks for DevOps, but it does have many problems. Some notable ones are,&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;No proper error handling to retry on failuires.&lt;/li&gt;
&lt;li&gt;Seperate verbose logs needs manual setup.&lt;/li&gt;
&lt;li&gt;No job dependancy support.&lt;/li&gt;
&lt;li&gt;Cannot handle missed jobs. (Though some implementaions can)&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Systemd Timers are the future
&lt;/h3&gt;

&lt;p&gt;This is the modern take on Cron Jobs without it's drawbacks and now widely used as a replacement to it.&lt;/p&gt;

&lt;p&gt;it is a bit complex to setup but in turn provides more control over the jobs and have a better intergration with the system.&lt;/p&gt;

&lt;p&gt;I will explain how to use Systemd Timers to take full advantage of it in a future article.&lt;/p&gt;

</description>
      <category>ubuntu</category>
      <category>linux</category>
      <category>devops</category>
      <category>powerautomate</category>
    </item>
    <item>
      <title>Setup Haskell for Neovim on Linux</title>
      <dc:creator>Chamal Mallawaarachchi</dc:creator>
      <pubDate>Tue, 29 Apr 2025 13:49:39 +0000</pubDate>
      <link>https://forem.com/chamal1120/-setup-haskell-for-neovim-on-linux-514o</link>
      <guid>https://forem.com/chamal1120/-setup-haskell-for-neovim-on-linux-514o</guid>
      <description>&lt;p&gt;This is a distro agnostic simple guide on how to setup haskell on modern linux using &lt;strong&gt;GHCup&lt;/strong&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  Requirements
&lt;/h3&gt;

&lt;p&gt;Make sure you're equipped with all the neccesary packages to run GHCup properly. I'm not gonna list all of them here (if you're a dev already, chances are you're). &lt;br&gt;&lt;br&gt;
So just go here and check -&amp;gt; &lt;a href="https://www.haskell.org/ghcup/install/#system-requirements" rel="noopener noreferrer"&gt;https://www.haskell.org/ghcup/install/#system-requirements&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  For an example,
&lt;/h4&gt;

&lt;p&gt;if you're on Arch Linux, you just need the &lt;strong&gt;linux-devel&lt;/strong&gt; and &lt;strong&gt;curl&lt;/strong&gt; packages and rest will be automatically downloaded installed by the GHCup installer.&lt;/p&gt;
&lt;h3&gt;
  
  
  Setting up
&lt;/h3&gt;
&lt;h4&gt;
  
  
  1. Paste the following command and run:
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;--proto&lt;/span&gt; &lt;span class="s1"&gt;'=https'&lt;/span&gt; &lt;span class="nt"&gt;--tlsv1&lt;/span&gt;.2 &lt;span class="nt"&gt;-sSf&lt;/span&gt; https://get-ghcup.haskell.org | sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This script will download and install the following binaries:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ghcup&lt;/strong&gt; - The Haskell toolchain installer&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ghc&lt;/strong&gt;   - The Glasgow Haskell Compiler&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;cabal&lt;/strong&gt; - The Cabal build tool for managing Haskell software&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;stack&lt;/strong&gt; - A cross-platform program for developing Haskell projects (similar to cabal)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;hls&lt;/strong&gt;   - (optional) A language server for developers to integrate with their editor/IDE&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note that &lt;code&gt;HLS (Haskell Language Server)&lt;/code&gt; is optional here. Make sure you install that when the installer prompts you if you want to use code actions, suggestions, goto definitions, and etc in Neovim (There are other LSPs but I highly recommend this for a beginner).&lt;/p&gt;
&lt;h4&gt;
  
  
  2. When installer prompts asking to write environment variables to your shell configuation, let it do that.
&lt;/h4&gt;

&lt;p&gt;It will add something simillar to following your shell configuration.&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="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"/home/&amp;lt;your-username&amp;gt;/.ghcup/env"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="s2"&gt;"/home/&amp;lt;your-username&amp;gt;/.ghcup/env"&lt;/span&gt; &lt;span class="c"&gt;# ghcup-env&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  3. After the installer finishes up, reload your shell configuation, close and reopen your terminal.
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;source&lt;/span&gt; .zshrc &lt;span class="c"&gt;# for zsh&lt;/span&gt;
&lt;span class="nb"&gt;source&lt;/span&gt; .bashrc &lt;span class="c"&gt;# for bash&lt;/span&gt;
&lt;span class="nb"&gt;source&lt;/span&gt; ~/.config/fish/config.fish &lt;span class="c"&gt;# for Fish&lt;/span&gt;

&lt;span class="c"&gt;# If you're using a different shell refer it's manual&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  4. Make sure everyting is correctly installed:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ghc --version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Should print &lt;code&gt;The Glorious Glasgow Haskell Compilation System, version 9.6.7&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ which haskell-language-server-wrapper
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Should print &lt;code&gt;/home/&amp;lt;your-username&amp;gt;/.ghcup/bin/haskell-language-server-wrapper&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  5. You can manage what has installed or install new tools using the below command:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ghcup tui
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Make sure ticks are like in the below image in the ghcup tui:
&lt;/h4&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%2Fs2bjm11j3pfh1f1at9mq.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%2Fs2bjm11j3pfh1f1at9mq.png" alt="ghcp tui" width="800" height="457"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Double tick means installed and set as default. If &lt;code&gt;hsl&lt;/code&gt; is not set, set it with &lt;code&gt;s&lt;/code&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Configuring neovim
&lt;/h3&gt;
&lt;h4&gt;
  
  
  1. If you're new to Neovim ( which I highly doubt) start with something like &lt;a href="https://github.com/nvim-lua/kickstart.nvim" rel="noopener noreferrer"&gt;kickstarter&lt;/a&gt; neovim config by TJ.
&lt;/h4&gt;

&lt;p&gt;Following steps assume that you have a lazy.nvim and nvim-lspconfig plugins installed and configured to the way you like.&lt;/p&gt;
&lt;h4&gt;
  
  
  2. Setup treesitter for syntax highlighting:
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lua"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"nvim-treesitter/nvim-treesitter"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;lazy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
  &lt;span class="n"&gt;build&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;":TSUpdate"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="c1"&gt;-- treesitter configs&lt;/span&gt;
    &lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"nvim-treesitter.configs"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;config&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;({&lt;/span&gt;
      &lt;span class="n"&gt;auto_install&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;-- Auto install treesitter parsers when a new file type detects&lt;/span&gt;
      &lt;span class="n"&gt;highlight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;enable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="n"&gt;indent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;enable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="k"&gt;end&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;h4&gt;
  
  
  3. There are multiple ways to start lsp servers using nvim.lspconfig. I will show the one I use here (which extentable later for other langs easily):
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lua"&gt;&lt;code&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"neovim/nvim-lspconfig"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;opts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;servers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;hls&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="c1"&gt;-- Pass Haskell Language Server to the opts table&lt;/span&gt;
      &lt;span class="c1"&gt;-- your other language servers can be listed here&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;-- config function using opts.servers&lt;/span&gt;

    &lt;span class="c1"&gt;-- Loop over the servers in opts.servers and enable each&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;pairs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;servers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="n"&gt;lspconfig&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;server&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;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&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;h4&gt;
  
  
  4. Check if the Tree-sitter parsers and LSPs are attaching to the buffer.
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Open up a new haskell file:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nvim hello.hs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Give some time for nvim treesitter to download the haskell parser &lt;br&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Check Treesitter:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Type the below command in your neovim cmdline in command mode and it will show avaiable active parsers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;:TsModulInfo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Type following command in the neovim command mode to verify if the LSP is attached to your buffer.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;:LspInfo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another good way to verify is to type some Haskell syntax. If your editor shows like below, you're good to go:&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%2F19zu5d93v3ac52baq96c.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%2F19zu5d93v3ac52baq96c.png" alt="haskell-in-action-in-neovim" width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  That's it!
&lt;/h4&gt;

&lt;h4&gt;
  
  
  Enjoy your functional programming :)
&lt;/h4&gt;

</description>
      <category>haskell</category>
      <category>functionalreactiveprogramming</category>
      <category>linux</category>
      <category>neovim</category>
    </item>
    <item>
      <title>Get to Know MCP</title>
      <dc:creator>Chamal Mallawaarachchi</dc:creator>
      <pubDate>Wed, 16 Apr 2025 10:26:23 +0000</pubDate>
      <link>https://forem.com/chamal1120/get-to-know-mcp-2724</link>
      <guid>https://forem.com/chamal1120/get-to-know-mcp-2724</guid>
      <description>&lt;p&gt;The Model Context Protocol (MCP) is released by Anthrophic is becoming the de facto for combining AI models to everything that it cannot directly access.&lt;/p&gt;

&lt;p&gt;So let me break it to you with the most simplest ways based on my understandings.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the problem?
&lt;/h2&gt;

&lt;p&gt;As you may already know, an AI model struggles when they need to access any information or tools out of their pre-trained datasets. So developers have to write custom code for each API, tool or data source to give them that fine grained access. This made AI bridging to any custom tool or data source a bitter task to any dev.&lt;/p&gt;

&lt;h2&gt;
  
  
  Anthrophic's solution
&lt;/h2&gt;

&lt;p&gt;Anthropic stepped in and introduced  MCP aka the Model Context Protocol. It's a tool, resource and model agnostic protocol to establish connections between AI Models and any other tool or resource.&lt;/p&gt;

&lt;p&gt;They introduced this as an open standard which uses JSON-RPC 2.0 which is already used by many standard protocols like Language Server Protocol (LSP) and Etherium network.&lt;/p&gt;

&lt;h2&gt;
  
  
  The most simplest explanation
&lt;/h2&gt;

&lt;p&gt;Think of it as a REST API for an AI to call and access information and tools it needs. Though they use completely different invoke and expose methods.&lt;/p&gt;

&lt;h2&gt;
  
  
  Abstracted architecture of an MCP
&lt;/h2&gt;

&lt;p&gt;&lt;br&gt;&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%2Fxbasplo5r8ffipj6winc.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%2Fxbasplo5r8ffipj6winc.png" alt="Model Context Protocol abstracted architecture" width="800" height="100"&gt;&lt;/a&gt;&lt;br&gt;
&lt;br&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  An Example
&lt;/h2&gt;

&lt;p&gt;Imagine you have your favorite spreadsheet application that you use regularly. You'd love to be able to tell an AI chatbot things like "create a budget spreadsheet" or "calculate the average of my quarterly sales" and have it actually do these tasks in your spreadsheet application.&lt;/p&gt;

&lt;p&gt;Here's how you could make this happen:&lt;br&gt;
Let's assume that this spreadsheet application has an API to control it's actions like insert data into cells, insert formulae and etc.&lt;br&gt;
Next, you can write a simple script using a programming language that sends commands to it's API.&lt;/p&gt;

&lt;p&gt;Now we need to connect our script to the AI, so it can send commands for the API for us. Instead of us writing a formula and sending, AI can read the spreadsheet, create a formula and write it to the spreadsheet.&lt;/p&gt;

&lt;p&gt;This is where MCP comes in!. We just need wrap our scripts into a the MCP supported function. That is called an MCP server.&lt;/p&gt;

&lt;p&gt;That has become fairly easy now due to the already available libraries for many programming languages.&lt;/p&gt;

&lt;p&gt;This is how you write an MCP server using official python SDK:&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="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mcp.server.fastmcp&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FastMCP&lt;/span&gt;

&lt;span class="c1"&gt;# Create an MCP server
&lt;/span&gt;&lt;span class="n"&gt;mcp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FastMCP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;my-spreadsheet-mcp-server&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="c1"&gt;# Add a tool
&lt;/span&gt;&lt;span class="nd"&gt;@mcp.tool&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;writeToSpreadSheet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userString&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
    Your logic or the script that 
    access the spreatsheet API
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;you can return what happened back to AI&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;


&lt;span class="c1"&gt;# Add a resource
&lt;/span&gt;&lt;span class="nd"&gt;@mcp.resource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;://{name}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;accessSpreadSheets&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
    Your logic or the script that 
    access the spreatsheet API
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;you can return what happened back to AI&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;here tools decorator tells the AI model that function access tool (like the spreadsheet program) and resource tells that it access a data source (like an actual spreadsheet file directly).&lt;/p&gt;

&lt;p&gt;After writing your mcp server. You can load it to an MCP client ( like claude desktop) to let an LLM access your MCP and do what you asks using the new capabilities of your MCP server.&lt;/p&gt;

&lt;p&gt;Using this method, you can give access to any data source, database, REST/RPC APIs or any other software to your choice of AI model.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wait, don't go and write another MCP server now!!
&lt;/h2&gt;

&lt;p&gt;There might be already an MCP server for your task that someone has written, so give it a try first.&lt;/p&gt;

&lt;p&gt;Here's list of MCP servers people have written as of now,&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/punkpeye/awesome-mcp-servers" rel="noopener noreferrer"&gt;https://github.com/punkpeye/awesome-mcp-servers&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;MCP official introduction by Anthropic - &lt;a href="https://www.anthropic.com/news/model-context-protocol" rel="noopener noreferrer"&gt;https://www.anthropic.com/news/model-context-protocol&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Python SDK for MCP -&lt;a href=""&gt;https://github.com/modelcontextprotocol/python-sdk&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;JSON-RPC 2.0 spec - &lt;a href="https://www.jsonrpc.org/specification" rel="noopener noreferrer"&gt;https://www.jsonrpc.org/specification&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>rag</category>
      <category>llm</category>
    </item>
    <item>
      <title>Flutter Development for Low end PCs</title>
      <dc:creator>Chamal Mallawaarachchi</dc:creator>
      <pubDate>Sun, 12 Jan 2025 12:18:04 +0000</pubDate>
      <link>https://forem.com/chamal1120/flutter-development-for-low-end-pcs-5gcd</link>
      <guid>https://forem.com/chamal1120/flutter-development-for-low-end-pcs-5gcd</guid>
      <description>&lt;p&gt;This is a dead simple and minimal dev workflow setup for flutter development.&lt;/p&gt;

&lt;h2&gt;
  
  
  Aight first up, let's see the memory footprint
&lt;/h2&gt;

&lt;p&gt;These screenshots are taken from my Hyprland setup which is a very minimal Desktop Setup.&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%2F929lkbjx3fkj25ss3n3z.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%2F929lkbjx3fkj25ss3n3z.png" alt="FLutter-with-low-end-pc" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can see that neovim is taking only 41mb of RAM while scrcpy is taking 181mb of RAM. These two apps replaces the VsCode and Android emulator which results in like 90% memory freeing.&lt;/p&gt;

&lt;p&gt;With Hyprland, my complete setup when running the emulator and code editor is still under 4GB of RAM.&lt;/p&gt;

&lt;p&gt;And with everything configured, this is how the setup looks;&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%2F89a5wfya8hpkqp587pik.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%2F89a5wfya8hpkqp587pik.png" alt="Neovim and flutter with scrcpy" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Ingredients:
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;A package manager - to install stuff easily&lt;/li&gt;
&lt;li&gt;Neovim - for code editing&lt;/li&gt;
&lt;li&gt;Android studio - for managing the android sdk&lt;/li&gt;
&lt;li&gt;Flutter sdk - duh.!&lt;/li&gt;
&lt;li&gt;Scrcpy - android screen mirroring tool&lt;/li&gt;
&lt;li&gt;Your android phone - for the emulation (assuming it is above android version 5)&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Steps:
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Setup package manager.&lt;/p&gt;

&lt;p&gt;Linux:&lt;br&gt;
&lt;em&gt;you already have a package manager built in!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;macOS:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# skip the first command if you already have  homebrew installed.&lt;/span&gt;
/bin/bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;-fssl&lt;/span&gt; https://raw.githubusercontent.com/homebrew/install/head/install.sh&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Windows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Follow this guide to setup chocolatey if you haven't: &lt;a href="https://chocolatey.org/install" rel="noopener noreferrer"&gt;https://chocolatey.org/install&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Install neovim (skip if deciding to use VsCode).&lt;/p&gt;

&lt;p&gt;Install neovim and configure it work with flutter. if you aren't familier with vim motions, you can swap this step with vscode but it will increase the memory footprint when running everything. But it will still be better than running the emulator with VsCode.&lt;/p&gt;

&lt;p&gt;Linux:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;pacman &lt;span class="nt"&gt;-s&lt;/span&gt; neovim &lt;span class="c"&gt;# if you're on arch linux, for other distros, google it up&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;macOS:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;neovim
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Windows:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;choco &lt;span class="nb"&gt;install &lt;/span&gt;neovim
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Install android studio.&lt;/p&gt;

&lt;p&gt;Linux:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yay &lt;span class="nt"&gt;-s&lt;/span&gt; android-studio &lt;span class="c"&gt;# if you're on arch linux, for other distros, google it up&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;macOS:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--cask&lt;/span&gt; android-studio
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Windows:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;choco &lt;span class="nb"&gt;install &lt;/span&gt;androidstudio
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Install flutter sdk.&lt;/p&gt;

&lt;p&gt;Linux:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yay &lt;span class="nt"&gt;-s&lt;/span&gt; flutter-bin &lt;span class="c"&gt;# This is arch linux syntax&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;macOS:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--cask&lt;/span&gt; flutter
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Windows:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;choco &lt;span class="nb"&gt;install &lt;/span&gt;flutter
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Flutter Setup (skip if you're VsCode and Install dart and flutter extensions instead):&lt;br&gt;
Follow this guide to setup flutter tools with neovim (yeah it is lengthy but it's worth for the profit) - &lt;a href="https://www.etiennetheodore.com/building-flutter-application-with-neovim/" rel="noopener noreferrer"&gt;https://www.etiennetheodore.com/building-flutter-application-with-neovim/&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Install scrcpy.&lt;/p&gt;

&lt;p&gt;Linux:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yay &lt;span class="nt"&gt;-s&lt;/span&gt; scrcpy &lt;span class="c"&gt;# This is arch linux syntax&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;macOS:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;scrcpy
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Windows:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;choco &lt;span class="nb"&gt;install &lt;/span&gt;scrcpy
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Enable usb debugging in your android device.&lt;/p&gt;

&lt;p&gt;a. Tap build number 7 times and enable developer. options&lt;br&gt;
b. Go to it and enable usb debugging.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Authorize your phone with adb.&lt;/p&gt;

&lt;p&gt;a. Connect your phone via a usb cable to your pc/mac.&lt;br&gt;
b. Type &lt;code&gt;adb devices&lt;/code&gt;.&lt;br&gt;
c. A prompt will come in your phone to authorize the device.&lt;br&gt;
d. After that just plug out and re-plug your device to computer.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Now create a new flutter project or open and existing one with neovim.&lt;/p&gt;

&lt;p&gt;a. &lt;code&gt;cd&lt;/code&gt; into your flutter project folder and type &lt;code&gt;nvim .&lt;/code&gt;.&lt;br&gt;
b. Then press &lt;code&gt;:&lt;/code&gt; symbol and type &lt;code&gt;flutterRun&lt;/code&gt; in neovim. this is a command provided by flutter-tools neovim plugin. you can learn all the commands it offers through their GitHub repo.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Mirror the screen using scrcpy.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;scrcpy &lt;span class="nt"&gt;--turn-screen-off&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;that's it!&lt;br&gt;
You now have a very fast flutter emulator just beside your code editor. this can also setup to connect wirelessly. more on that in a future article.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Thank You for reading. Share if you think this is useful.&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>mobile</category>
      <category>scrcpy</category>
      <category>android</category>
    </item>
    <item>
      <title>Hassle free flutter Development in Hyprland with Neovim</title>
      <dc:creator>Chamal Mallawaarachchi</dc:creator>
      <pubDate>Thu, 09 Jan 2025 20:59:54 +0000</pubDate>
      <link>https://forem.com/chamal1120/hassle-free-flutter-development-in-hyprland-with-neovim-e1f</link>
      <guid>https://forem.com/chamal1120/hassle-free-flutter-development-in-hyprland-with-neovim-e1f</guid>
      <description>&lt;p&gt;I am writing this article to help anyone surfing through the internet for a proper guide to setup a smooth flutter dev work low for their Hyprland setups.&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Install flutter through your package manager. If you're on Arch linux you can try following command.
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yay &lt;span class="nt"&gt;-S&lt;/span&gt; flutter-bin &lt;span class="c"&gt;# This will install dart and flutter from AUR&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  2. Install android-studio using your package manager. Again if on Arch, use below command.
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yay &lt;span class="nt"&gt;-S&lt;/span&gt; android-studio &lt;span class="c"&gt;# This will install android studio from AUR&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  3. Install flutter-tools neovim plugin to setup the LSP.
&lt;/h4&gt;

&lt;blockquote&gt;
&lt;p&gt;I assume you already know how to setup neovim plugins. Also this plugin will setup dart-ls automatically so don't install it through your lspconfig. flutter tools will give all of the functionalities Vs-code flutter extensions plus some additional stuff.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can follow the repo's README to set this up accroding to your neovim setup.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;flutter-tools - &lt;a href="https://github.com/nvim-flutter/flutter-tools.nvim" rel="noopener noreferrer"&gt;https://github.com/nvim-flutter/flutter-tools.nvim&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  4. Now open android studio and create an emulator of your choice.
&lt;/h4&gt;

&lt;p&gt;I recommend something above android 12 (S) as others will be x86 by default. Flutter will soon drop support for x86-based emulators or devices.&lt;/p&gt;

&lt;h4&gt;
  
  
  5. Once that done, next usual step is to run the emulator,
&lt;/h4&gt;

&lt;p&gt;But android studio's emulator does not support native &lt;em&gt;wayland&lt;/em&gt; as of now according to my findings.&lt;/p&gt;

&lt;h4&gt;
  
  
  MY WORKAROUND TO GET IT RUNNING:
&lt;/h4&gt;

&lt;p&gt;You can use following command to force the current session of the emulator to run through Xwayland.&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;env &lt;/span&gt;&lt;span class="nv"&gt;QT_QPA_PLATFORM&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;xcb flutter emulators &lt;span class="nt"&gt;--launch&lt;/span&gt; &amp;lt;your-emulator-name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;If you're using fractional scaling or any scaling in Hyprland, the emulator will launch in a blurred window. To fix that add the following code to your hyprland.conf&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;xwayland {
  force_zero_scaling = true
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6. That's it!
&lt;/h3&gt;

&lt;p&gt;You should be able to connect to the emulator using &lt;code&gt;:FlutterRun&lt;/code&gt; inside neovim. Other commands to control and access the flutter utilities can be found in the flutter-tools GitHub repo's README.&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%2Fw40pmkow1m0g9eje8241.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%2Fw40pmkow1m0g9eje8241.png" alt="Flutter tools in Action" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you want a quick neovim setup or an entire hyprland setup with everything configured, you can use my neovim config in my dotfiles.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;My dotfiles - &lt;a href="https://github.com/Chamal1120/dotfiles-linux-hyprland" rel="noopener noreferrer"&gt;https://github.com/Chamal1120/dotfiles-linux-hyprland&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Thank You chief for reading up to here
&lt;/h4&gt;

&lt;p&gt;Feel free to ask me if anything is doubtful or let me know if there are better ways to do what I am doing right now. Comments are always welcome.&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>hyprland</category>
      <category>neovim</category>
      <category>wayland</category>
    </item>
    <item>
      <title># How to write good commit messages</title>
      <dc:creator>Chamal Mallawaarachchi</dc:creator>
      <pubDate>Fri, 13 Dec 2024 15:05:48 +0000</pubDate>
      <link>https://forem.com/chamal1120/-how-to-write-good-commit-messages-57ac</link>
      <guid>https://forem.com/chamal1120/-how-to-write-good-commit-messages-57ac</guid>
      <description>&lt;p&gt;If you are here, chances are you have already used git and probably thinking "Am I writing my commit messages in a good standard?". &lt;/p&gt;

&lt;p&gt;If yes, then you must read this before you go and do your next big project.&lt;/p&gt;

&lt;h2&gt;
  
  
  So what is a good commit message?
&lt;/h2&gt;

&lt;p&gt;Well, there's actually multiple standards when it comes to git commit messages. But they all should,&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Be written in &lt;a href="https://en.wikipedia.org/wiki/Imperative_mood" rel="noopener noreferrer"&gt;imperative&lt;/a&gt; mood if it is a simple commit (means a one liner).&lt;/li&gt;
&lt;li&gt;Have a title in &lt;a href="https://en.wikipedia.org/wiki/Imperative_mood" rel="noopener noreferrer"&gt;imperative&lt;/a&gt; mood if it is a detailed commit.&lt;/li&gt;
&lt;li&gt;Write logically, each addressing a single concern.&lt;/li&gt;
&lt;li&gt;Reference issues or tasks explicitly (if there is any).&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Let's look at an example
&lt;/h2&gt;

&lt;p&gt;Simple Commit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;Fix typo in README
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Detailed Commit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;Add caching mechanism to improve performance

Implemented a caching layer to reduce redundant database calls,
which improves page load times by approximately 30%.

Fixes #42.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is written following the &lt;code&gt;Git flow style commits&lt;/code&gt; standard.&lt;/p&gt;

&lt;h2&gt;
  
  
  So what are the other standards then?
&lt;/h2&gt;

&lt;p&gt;Since there's many, I won't be writing all of them here. Below standards will be the ones you'll most probably should be using and encounter as a software developer. Some further references will be linked at the end of the article for curious people.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. GitHub Flow-Style Commits:
&lt;/h3&gt;

&lt;p&gt;Popular for open-source projects in GitHub. Often references related issues or pull requests (e.g., "Closes #123").&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;Add pagination to the blog list view

Pagination improves performance for blogs with a large number 
of posts. Closes #42.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Conventional commits:
&lt;/h3&gt;

&lt;p&gt;Probably the most widely used standard. Have a type at the beginning followed by a semi-colon and then a scope, description, body and a footer.&lt;/p&gt;

&lt;h4&gt;
  
  
  The commonly used types are,
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;feat: A new feature.&lt;/li&gt;
&lt;li&gt;fix: A bug fix.&lt;/li&gt;
&lt;li&gt;docs: Documentation updates.&lt;/li&gt;
&lt;li&gt;style: Code style changes (e.g., formatting, no logic changes).&lt;/li&gt;
&lt;li&gt;refactor: Code restructuring without changing behavior.&lt;/li&gt;
&lt;li&gt;perf: Performance improvements.&lt;/li&gt;
&lt;li&gt;test: Adding or updating tests.&lt;/li&gt;
&lt;li&gt;build: Changes to build tools or dependencies.&lt;/li&gt;
&lt;li&gt;ci: Continuous integration updates.&lt;/li&gt;
&lt;li&gt;chore: Miscellaneous tasks (e.g., updating dependencies).&lt;/li&gt;
&lt;li&gt;revert: Reverts a previous commit.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Scope (Optional):
&lt;/h4&gt;

&lt;p&gt;The part of the codebase affected (e.g., auth, api, ui).&lt;/p&gt;

&lt;h4&gt;
  
  
  Description:
&lt;/h4&gt;

&lt;p&gt;A short summary of the change in the imperative mood.&lt;/p&gt;

&lt;h4&gt;
  
  
  Body - for detailed commits(optional):
&lt;/h4&gt;

&lt;p&gt;Detailed explanation of the change.&lt;/p&gt;

&lt;h4&gt;
  
  
  Footer - for detailed commits(optional):
&lt;/h4&gt;

&lt;p&gt;Breaking changes (BREAKING CHANGE: ...) or issue references (Fixes #123).&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Tim Pope's Guidelines:
&lt;/h3&gt;

&lt;p&gt;Tim Pope, a Git expert, suggests:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Limit subject line to 50 characters.&lt;/li&gt;
&lt;li&gt;Capitalize the first word of the subject.&lt;/li&gt;
&lt;li&gt;Do not end the subject with a period.&lt;/li&gt;
&lt;li&gt;Use the imperative mood.&lt;/li&gt;
&lt;li&gt;Separate the body with a blank line.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;Refactor user authentication module

Simplified the code by removing redundant checks and aligning
with the latest OAuth2 library changes.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Angular Commit Guidelines:
&lt;/h3&gt;

&lt;p&gt;The foundation for Conventional Commits.&lt;br&gt;
Adds a specific format with types, scopes, and more.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;feat(user): add user profile page

This page includes basic details about the user and their recent
activity. Also adds lazy loading for the profile module.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Semantic Commit Messages:
&lt;/h3&gt;

&lt;p&gt;Focuses on using keywords to make commits machine-readable.&lt;br&gt;
Often integrated with tools like semantic-release.&lt;br&gt;
Similar to Conventional Commits but may include specific metadata.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;feature(login): implement Google OAuth login
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6. Subject-Prefix Standards:
&lt;/h3&gt;

&lt;p&gt;Uses a prefix to indicate the change type.&lt;br&gt;
Less formal than Conventional Commits.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;[Bugfix] Resolve incorrect total calculation
[Enhancement] Improve search performance
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  For further references
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Conventional Commits - &lt;a href="https://www.conventionalcommits.org/en/v1.0.0/" rel="noopener noreferrer"&gt;https://www.conventionalcommits.org/en/v1.0.0/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Tim Pope's blog post on commit messages - &lt;a href="https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html" rel="noopener noreferrer"&gt;https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Senamtic Versioning - &lt;a href="https://semver.org/" rel="noopener noreferrer"&gt;https://semver.org/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Angular git commit guideline - &lt;a href="https://github.com/angular/angular/blob/main/CONTRIBUTING.md#commit" rel="noopener noreferrer"&gt;https://github.com/angular/angular/blob/main/CONTRIBUTING.md#commit&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Thank You
&lt;/h2&gt;

&lt;p&gt;Load of thanks for reading up to here. comments are welcome. Point out if I have missed any details or stated anything erroneously. Let's learn together and grow to become better developers.&lt;/p&gt;

</description>
      <category>git</category>
      <category>github</category>
      <category>commit</category>
      <category>devops</category>
    </item>
    <item>
      <title>zoxide - A faster alternative to boring cd command</title>
      <dc:creator>Chamal Mallawaarachchi</dc:creator>
      <pubDate>Sun, 19 May 2024 04:08:55 +0000</pubDate>
      <link>https://forem.com/chamal1120/zoxide-a-faster-alternative-to-boring-cd-command-1ae3</link>
      <guid>https://forem.com/chamal1120/zoxide-a-faster-alternative-to-boring-cd-command-1ae3</guid>
      <description>&lt;h3&gt;
  
  
  Why zoxide is a better replacement??
&lt;/h3&gt;

&lt;p&gt;Best way to start explaining is to show how we normally navigate using the good old cd command.&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%2Fm1wy5leuhbuo7to2omwa.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%2Fm1wy5leuhbuo7to2omwa.png" alt="Usual cd command usage" width="800" height="523"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now you might think that &lt;em&gt;"hey, can't we just use up arrow key or an autocomplete plugin?"&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Well, those might perform very well when working with simple folder structures, but imagine having to press up arrow key thousands of times to get to your previously used directory that wanted to navigate to.&lt;/p&gt;

&lt;p&gt;And also in the case of auto-complete plugin, it will also leave a very unreadable number of lines in the terminal that might confuse you when you referring back the previous lines of your terminal for reviewing something.&lt;/p&gt;

&lt;p&gt;That's where zoxide excels!&lt;/p&gt;

&lt;p&gt;Both of those problems can be easily be eliminated just by installing zoxide to your terminal.&lt;/p&gt;

&lt;p&gt;Now let's see how we do the same operation using Zoxide.&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%2Fdu8dh20ek00z5nrptjql.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%2Fdu8dh20ek00z5nrptjql.png" alt="zoxide navigate command usage" width="800" height="584"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pretty easy right?&lt;/p&gt;

&lt;p&gt;Well if you have multiple folders with the same name in different directories there are two ways you can use zoxide to get to the exact one you want.&lt;/p&gt;

&lt;p&gt;Method 1 - If you are on a compatible shell version of bash,zsh or fish you will be automatically prompted with the available directories for that folder name as follows.&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%2Fpx40knt1xb26l7s7pd8a.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%2Fpx40knt1xb26l7s7pd8a.png" alt="Multiple directories on zoxide method 1" width="800" height="213"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Method 2 - If for some reason you don't get the above feature, you can use another famous tool called fzf (aka fuzzy finder). With the power of fzf you can use the below command to show all the directories saved with that particular folder name. You can even take a peak at the content inside that folder.&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%2Fiexafmtjzb6rqo1yt10o.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%2Fiexafmtjzb6rqo1yt10o.png" alt="Multiple directories on zoxide method 2" width="800" height="586"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Not only that there are many other ways you can customize the commands. You'll find a very detailed instruction set in their official repo which I have linked at the end of this article.&lt;/p&gt;

&lt;p&gt;Actually zoxide isn't the first program that provided these facilities. There were earlier programs which are still up-to-date named &lt;strong&gt;z&lt;/strong&gt;, &lt;strong&gt;autojump&lt;/strong&gt; and &lt;strong&gt;fasd&lt;/strong&gt;. While autojump and fasd are way more advanced than zoxide, they also have a more steep learning curve.&lt;/p&gt;

&lt;p&gt;In terms of simplicity and lightweightness, zoxide is the best option out of all. On top of that, zoxide is built on Rust which makes it blazing fast.&lt;/p&gt;

&lt;p&gt;Believe me you won't even notice that you're using a third party tool.&lt;/p&gt;

&lt;h3&gt;
  
  
  Okay now we'll see how to install this into your favorite terminal.
&lt;/h3&gt;

&lt;p&gt;zoxide will work with any Linux terminal including Windows and MacOS. Infact it is available through almost any package manager you have heard, used or seen.&lt;/p&gt;

&lt;h4&gt;
  
  
  For Linux/MacOS
&lt;/h4&gt;

&lt;p&gt;Although the official documentation of zoxide recommends using package installers or managers, I would highly suggest you to use &lt;strong&gt;curl&lt;/strong&gt; to get the install script and install.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-sS&lt;/span&gt; https://raw.githubusercontent.com/ajeetdsouza/zoxide/main/install.sh | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  For Windows
&lt;/h4&gt;

&lt;p&gt;zoxide works really well with Powershell in Windows.&lt;/p&gt;

&lt;p&gt;Use winget package manager to install zoxide.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;winget &lt;span class="nb"&gt;install &lt;/span&gt;ajeetdsouza.zoxide
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Post install steps (only for Linux/MacOS)
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Open your configuration file related your terminal using a code editor.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Assuming you are on zsh and using nano as the code editor&lt;/span&gt;
nano .zshrc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Add the following line to the end of the file to initialize zoxide with your terminal.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;eval "$(zoxide init zsh)"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;(skip this step if it is already in the file)&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Now add following line to add the zoxide install directory to the PATH which helps you to use the z command in every directory of your terminal.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;export PATH="/Users/chamalrandika/.local/bin:$PATH"&lt;/code&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Source the configuration file to invoke the changes.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;source&lt;/span&gt; .zshrc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Install fzf (if multiple directory handling didn't work with the default z syntax)
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;clone the official repo to get the install script.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone &lt;span class="nt"&gt;--depth&lt;/span&gt; 1 https://github.com/junegunn/fzf.git ~/.fzf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Install
&lt;/li&gt;
&lt;/ol&gt;

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

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Add this line to configuration file as explained in previous steps to reduce the width of the suggestions window (default is 100%)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;export FZF_DEFAULT_OPTS='--height 40%'&lt;/code&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Source the configuration file.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  More information
&lt;/h3&gt;

&lt;p&gt;You can refer the official documentation if you are an advanced user or just curious to know more about the projects.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  zoxide official GitHub repo - &lt;a href="https://github.com/ajeetdsouza/zoxide" rel="noopener noreferrer"&gt;https://github.com/ajeetdsouza/zoxide&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  fzf official GitHub repo - &lt;a href="https://github.com/junegunn/fzf" rel="noopener noreferrer"&gt;https://github.com/junegunn/fzf&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's it!&lt;/p&gt;

&lt;p&gt;Happy CLI life devs. ✌️&lt;/p&gt;

</description>
      <category>cli</category>
      <category>linux</category>
      <category>bash</category>
      <category>zsh</category>
    </item>
    <item>
      <title>Understanding the pointers in C</title>
      <dc:creator>Chamal Mallawaarachchi</dc:creator>
      <pubDate>Sun, 03 Mar 2024 20:18:25 +0000</pubDate>
      <link>https://forem.com/chamal1120/understanding-the-pointers-in-c-5amp</link>
      <guid>https://forem.com/chamal1120/understanding-the-pointers-in-c-5amp</guid>
      <description>&lt;p&gt;&lt;strong&gt;Hello coding pals 👋&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Today I'm going to give you a comprehensive yet simple guide to pointers in C.&lt;/p&gt;

&lt;p&gt;Before proceeding, make sure you are alt-east familiar with some basic c syntaxes like &lt;code&gt;printf&lt;/code&gt;, &lt;code&gt;scanf&lt;/code&gt;, &lt;code&gt;main&lt;/code&gt; and user defined functions.&lt;/p&gt;

&lt;p&gt;Understanding this will help you to deal with pointers in other languages as well. 😌&lt;/p&gt;

&lt;p&gt;Aright then!, let's begin shall we?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;First of all, what's a pointer?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Our computer programs are usually using the  main memory(RAM) when they are executing.&lt;/p&gt;

&lt;p&gt;The variables we assign in programs are stored in the main memory.&lt;/p&gt;

&lt;p&gt;So, when a variable is stored in the main memory, there is an address for that memory location where the variable is located in our main memory.&lt;/p&gt;

&lt;p&gt;That address is what we use to access the value which stored in that variable.&lt;/p&gt;

&lt;p&gt;A pointer's job is to provide a point to that exact address so we can access the value in that variable.&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%2F1p1tl2iqabjj8tzwfb16.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%2F1p1tl2iqabjj8tzwfb16.png" alt="Pointers visual representation - credits: GeeksforGeeks" width="800" height="332"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;image credit: &lt;a href="https://www.geeksforgeeks.org" rel="noopener noreferrer"&gt;geeksforgeeks.org&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The above image shows the difference between a pointer variable and a normal variable that pointer points to.&lt;/p&gt;

&lt;p&gt;NOTE: A pointer variable also occupies system memory, which gives it a memory address too. so we can even create another pointer variable to an already specified pointer variable as well.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;So simple terms, a pointer is a variable that stores a memory address.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Enough theory, now let's jump into practical examples to better understand how pointers works in a programming environment. &lt;/p&gt;

&lt;p&gt;We're going to use C as our programming language since it's one of the few languages that offers direct memory manipulation where proper use of pointers are needed.&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="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="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&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="n"&gt;a&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;Study the above code.&lt;/p&gt;

&lt;p&gt;Inside our main function, I have created a &lt;code&gt;int&lt;/code&gt; type variable named &lt;code&gt;b&lt;/code&gt; which stores the value &lt;code&gt;42&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;after that, I have created another &lt;code&gt;int&lt;/code&gt; type variable named &lt;code&gt;*a&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;You'll notice few differences in the declaration syntax.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;*&lt;/code&gt; means make it a pointer, So &lt;code&gt;*a&lt;/code&gt; means make &lt;code&gt;a&lt;/code&gt; a pointer. And &lt;code&gt;int&lt;/code&gt; means &lt;code&gt;a&lt;/code&gt; is going to point to &lt;code&gt;int&lt;/code&gt; values.&lt;/p&gt;

&lt;p&gt;With the above code nothing will happen actually. Bcuz we're just telling a is an &lt;code&gt;int&lt;/code&gt; pointer. We haven't tell it to where it should point to.&lt;/p&gt;

&lt;p&gt;Let's see how we do that now.&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="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="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&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="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;b&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 in the above code you'll notice I have added another thing to the end of the pointer variable declaration.&lt;/p&gt;

&lt;p&gt;This &lt;code&gt;&amp;amp;&lt;/code&gt; operator is used to get a memory address of a certain variable.&lt;/p&gt;

&lt;p&gt;So &lt;code&gt;&amp;amp;b&lt;/code&gt; means we are telling to get the memory address of &lt;code&gt;b&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So, the complete line &lt;code&gt;int *a = &amp;amp;b;&lt;/code&gt; means to create a pointer variable named &lt;code&gt;a&lt;/code&gt; that points to an &lt;code&gt;int&lt;/code&gt; value and assign the memory address of &lt;code&gt;b&lt;/code&gt; to it.&lt;/p&gt;

&lt;p&gt;Theoretically, now &lt;code&gt;*a&lt;/code&gt; should have the exact memory address of &lt;code&gt;b&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We can verify this by printing the both &lt;code&gt;b&lt;/code&gt;'s memory address and &lt;code&gt;*a&lt;/code&gt;'s memory address.&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="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="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&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="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;b&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;"b: %d&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;b&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// prints the value of b&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;"&amp;amp;b: %p&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="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// prints the memory address of b&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;"a: %p&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;a&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// prints the value of a&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;If compile and run the above code, You'll get the following output. (your memory addresses may be vary)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;b: 42
&amp;amp;b: 0x7ff7b3c403c8
a: 0x7ff7b3c403c8
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can see that both value of &amp;amp;b and value of a are equal. &lt;/p&gt;

&lt;p&gt;This what happens when we create a pointer variable and point it to another variable.&lt;/p&gt;

&lt;p&gt;There's another thing you need to know.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;We can de-reference a pointer&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;De-referencing a pointer means accessing the value stored at the memory address pointed to by that pointer&lt;/p&gt;

&lt;p&gt;by doing that, we can refer back a pointer and modify the contents of the variable that it points.&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="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="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&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="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;b&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;"b: %d&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;b&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;"&amp;amp;b: %p&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="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;b&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;"a: %p&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;a&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;50&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;"b: %d&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;b&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;"&amp;amp;b: %p&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="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;b&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;"a: %p&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;a&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;In the above code, I have added a few changes from the previous code.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;*a&lt;/code&gt; here is not telling to change value of a. Instead this tells to go get what &lt;code&gt;a&lt;/code&gt; is pointing to and use that.&lt;/p&gt;

&lt;p&gt;And with the rest of the code in that line, &lt;code&gt;*a = 50;&lt;/code&gt; tells the program to go get what &lt;code&gt;a&lt;/code&gt; is pointing to and change the value of it to &lt;code&gt;50&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Output of above code will look like follows,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;b: 42
&amp;amp;b: 0x7ff7b76443c8
a: 0x7ff7b76443c8
b: 50
&amp;amp;b: 0x7ff7b76443c8
a: 0x7ff7b76443c8
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll see that only the value of &lt;code&gt;b&lt;/code&gt; has changed. The memory addresses stay the same.&lt;/p&gt;

&lt;p&gt;This is how de-referencing is done using a pointer. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But what's the purpose of this huh?&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The &lt;code&gt;scanf&lt;/code&gt; function&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Scanf is a built in function in C that use the advantage of pointers to read values from an input.&lt;/p&gt;

&lt;p&gt;Let's see an implementation of it&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="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="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&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;"Enter 3 numbers:"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;scanf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%d %d %d"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;c&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;"Result: %d&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;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;c&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;In the above code, What &lt;code&gt;scanf&lt;/code&gt; does is, it's accepting 3 inputs from the user &lt;code&gt;%d %d %d&lt;/code&gt;(integers) and store them into a, b and c.&lt;/p&gt;

&lt;p&gt;You'll notice that we have assigned 0 to all a, b and c.&lt;/p&gt;

&lt;p&gt;But if you run this code you'll see that &lt;code&gt;scanf&lt;/code&gt; somehow modified the variables and provide the output as the addition of all three numbers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Enter 3 numbers:2 5 3
Result: 10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So how does &lt;code&gt;scanf&lt;/code&gt; is able modify the a, b and c?&lt;/p&gt;

&lt;p&gt;What &lt;code&gt;scanf&lt;/code&gt; function does is, it gets the values of &lt;code&gt;&amp;amp;a, &amp;amp;b, &amp;amp;c&lt;/code&gt; instead of &lt;code&gt;a, b, c&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;If you provide &lt;code&gt;a, b, c&lt;/code&gt; you just giving the values of those variables which are 3 zeros.&lt;/p&gt;

&lt;p&gt;By providing the variables as &lt;code&gt;&amp;amp;a, &amp;amp;b, &amp;amp;c&lt;/code&gt; to the &lt;code&gt;scanf&lt;/code&gt;, it can point to the addresses of the variables and modify them with the user assigned values.&lt;/p&gt;

&lt;p&gt;This is known as a &lt;strong&gt;pass by reference&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Since this is built in function we don't see what's happening inside the &lt;code&gt;scanf&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To get a clear idea, we'll create our own simple pass by reference function.&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="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;swap&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="n"&gt;a&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="n"&gt;b&lt;/span&gt;&lt;span class="p"&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="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&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;"x: %d, y: %d&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;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;//before the sawp&lt;/span&gt;
    &lt;span class="n"&gt;swap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;y&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;"x: %d, y: %d&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;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;//after the swap&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;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;swap&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="n"&gt;a&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="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&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;temp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;temp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;temp&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;In the above code, we have created a swap function which accepts addresses of variables as &lt;code&gt;int&lt;/code&gt; pointers.&lt;/p&gt;

&lt;p&gt;Simply said, when we pass the &lt;code&gt;&amp;amp;x&lt;/code&gt; and &lt;code&gt;&amp;amp;y&lt;/code&gt; to swap function following thing happens first,&lt;/p&gt;

&lt;p&gt;&lt;code&gt;int *a = &amp;amp;x&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;int *b = &amp;amp;y&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Familiar that?&lt;/p&gt;

&lt;p&gt;That's what we did before de-referencing in the code where I explained the de-referencing.&lt;/p&gt;

&lt;p&gt;After that, inside the swap function, whatever we do with &lt;code&gt;*a&lt;/code&gt; and &lt;code&gt;*b&lt;/code&gt; will happen using the values of the variables &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;temp = *a;&lt;/code&gt; will assign &lt;code&gt;5&lt;/code&gt; to the variable &lt;code&gt;temp&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;*a = *b;&lt;/code&gt; will assign &lt;code&gt;10&lt;/code&gt; to &lt;code&gt;*a&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;*b = temp;&lt;/code&gt; will assign &lt;code&gt;5&lt;/code&gt; to &lt;code&gt;*b&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So the final result of the code will display as follows,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;x: 5, y: 10
x: 10, y: 5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First line prints the values before swap and the next line prints the values after swap.&lt;/p&gt;

&lt;p&gt;If want to see how memory addresses are de-referred, you can add two more print statements as below in the 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="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;swap&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="n"&gt;a&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="n"&gt;b&lt;/span&gt;&lt;span class="p"&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="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&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;"x: %d, y: %d&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;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;//before the sawp&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;"&amp;amp;x: %p&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;&amp;amp;y: %p&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="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// addresses of x and y&lt;/span&gt;
    &lt;span class="n"&gt;swap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;y&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;"x: %d, y: %d&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;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;//after the swap&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;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;swap&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="n"&gt;a&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="n"&gt;b&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;"a: %p&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;b: %p&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;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// addresses of x and y&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;temp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;temp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;temp&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;Newly added print inside the main function prints the memory addresses of &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Newly added print inside the swap function prints the memory addresses of pointed by &lt;code&gt;*a&lt;/code&gt; and &lt;code&gt;*b&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Output will be shown as below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;x: 5, y: 10
&amp;amp;x: 0x7ff7bf5af3c8
&amp;amp;y: 0x7ff7bf5af3c4
a: 0x7ff7bf5af3c8
b: 0x7ff7bf5af3c4
x: 10, y: 5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can see now memory addresses of &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt; matches the memory addresses of &lt;code&gt;*a&lt;/code&gt; and &lt;code&gt;*b&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That means &lt;code&gt;*a&lt;/code&gt; and &lt;code&gt;*b&lt;/code&gt; are pointing to &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So, by using &lt;code&gt;*a&lt;/code&gt; and &lt;code&gt;*b&lt;/code&gt;, you can manipulates the values of &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt; inside the swap function without affecting the memory addresses.&lt;/p&gt;

&lt;p&gt;This is how a pass by reference works.&lt;/p&gt;

&lt;p&gt;There are many cool stuff you can do with pointers in C.&lt;/p&gt;

&lt;p&gt;But, I don't want to make this article very lengthy.😊&lt;/p&gt;

&lt;p&gt;So, let's see how pointers help the dynamic memory allocation in a future article.☝️😌&lt;/p&gt;

&lt;p&gt;Till then, ✌️&lt;/p&gt;

</description>
      <category>c</category>
      <category>programming</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
