<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Down from the metal, up through the cloud and back to the UX]]></title><description><![CDATA[Down from the metal, up through the cloud and back to the UX]]></description><link>https://chedim.com</link><generator>RSS for Node</generator><lastBuildDate>Tue, 08 Sep 2026 09:57:19 GMT</lastBuildDate><atom:link href="https://chedim.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Popups are bad]]></title><description><![CDATA[Grammarly just gave a great example of how NOT to treat your users:

I am happy for you. But also don't care. But also lightly irritated by you distracting me from the task at hand with your "great news". By showing unwanted popups to your users you ...]]></description><link>https://chedim.com/popups-are-bad</link><guid isPermaLink="true">https://chedim.com/popups-are-bad</guid><category><![CDATA[user experience]]></category><category><![CDATA[User Interface]]></category><category><![CDATA[Web Design]]></category><dc:creator><![CDATA[Chedim]]></dc:creator><pubDate>Tue, 07 Mar 2023 15:11:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1678201569744/567f4505-6887-4969-8ed5-c33354267914.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Grammarly just gave a great example of how NOT to treat your users:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1678201637851/a3e0d47b-74ca-4d7e-acee-8e27ef10e6fd.png" alt class="image--center mx-auto" /></p>
<p>I am happy for you. But also don't care. But also lightly irritated by you distracting me from the task at hand with your "great news". By showing unwanted popups to your users you tell them "our desire to show you something matters more than you".</p>
<p>Don't show popups. NEVER show popups.</p>
]]></content:encoded></item><item><title><![CDATA[Решил написать книгу]]></title><description><![CDATA[И даже название уже есть: "Resurrecting God".
Ага, будет на английском. Перевод на русский запрещу, только на украинский.
О чем она будет? Знающие, наверное, уже догадались — о философии и о возвращении нашей жизни уничтоженного эпохой просвещения см...]]></description><link>https://chedim.com/reshil-napisat-knigu</link><guid isPermaLink="true">https://chedim.com/reshil-napisat-knigu</guid><dc:creator><![CDATA[Chedim]]></dc:creator><pubDate>Tue, 07 Mar 2023 13:38:24 GMT</pubDate><content:encoded><![CDATA[<p>И даже название уже есть: "Resurrecting God".</p>
<p>Ага, будет на английском. Перевод на русский запрещу, только на украинский.</p>
<p>О чем она будет? Знающие, наверное, уже догадались — о философии и о возвращении нашей жизни уничтоженного эпохой просвещения смысла. О новом взгляде на религию с высот достижений информационной эры.</p>
]]></content:encoded></item><item><title><![CDATA[On suicide hotlines]]></title><description><![CDATA["There is but one truly serious philosophical problem, and that is suicide. Judging whether life is or is not worth living amounts to answering the fundamental question of philosophy."-- Albert Camus
Y'all just don't like the answer that people who c...]]></description><link>https://chedim.com/on-suicide-hotlines</link><guid isPermaLink="true">https://chedim.com/on-suicide-hotlines</guid><dc:creator><![CDATA[Chedim]]></dc:creator><pubDate>Tue, 07 Mar 2023 04:00:40 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1678164559233/089741b4-0186-46b6-a9a0-e959dca7e6e6.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>"There is but one truly serious philosophical problem, and that is suicide. Judging whether life is or is not worth living amounts to answering the fundamental question of philosophy."<br />-- Albert Camus</p>
<p>Y'all just don't like the answer that people who commit suicide gave. And that forces you to create those hotlines and yell about them (and suicide) on every corner into the faces of people who struggle with that question.</p>
<p>Read Ernest Becker.</p>
]]></content:encoded></item><item><title><![CDATA[Hey, Google, why go is ...]]></title><description><![CDATA[I meant "so ugly", but google suggested "better than java". And here's the answer it gave to me:
Golang is easy to learn and perfect for beginners, and as a newer language, it offers better-optimized features and less time typing. Go code is more com...]]></description><link>https://chedim.com/hey-google-why-go-is</link><guid isPermaLink="true">https://chedim.com/hey-google-why-go-is</guid><category><![CDATA[golang]]></category><category><![CDATA[Go Language]]></category><category><![CDATA[Java]]></category><dc:creator><![CDATA[Chedim]]></dc:creator><pubDate>Mon, 06 Mar 2023 17:02:19 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1678121647071/2914a0a3-402b-4f50-aef1-6814730a75b5.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I meant "so ugly", but google suggested "better than java". And here's the answer it gave to me:</p>
<p><code>Golang is easy to learn and perfect for beginners, and as a newer language, it offers better-optimized features and less time typing. Go code is more compact and doesn't have unnecessary parentheses in its syntax. On the other hand, Java is an object-oriented language with many libraries.</code></p>
<p>Oh, really? "better-optimized features"? Like what, like a terrible package management system?</p>
<p>Less typing? Is that the criteria we have for a good SDL? Not a good package management system, not a thought-through class system that encourages <em>good</em> design, no. Having to type <code>func</code> instead of <code>public void method</code> makes a better language now?</p>
<p>There was functional programming, object-oriented programming and now we've got keyboard-oriented programming? Have you heard of auto-completion?</p>
<p>In my practice, any language that uses <code>abyrvalgs</code> (watch "<a target="_blank" href="https://www.google.com/url?sa=t&amp;rct=j&amp;q=&amp;esrc=s&amp;source=web&amp;cd=&amp;cad=rja&amp;uact=8&amp;ved=2ahUKEwiKlOLu5Mf9AhX7D1kFHXsqClMQFnoECA4QAQ&amp;url=https%3A%2F%2Fwww.imdb.com%2Ftitle%2Ftt0096126%2F&amp;usg=AOvVaw1jLjQ-CdAZRbWZmJZ8spOc">Heart of a dog</a>", you brutes!) like <code>func</code> sacrifices <strong>readability</strong> of the language <strong><em>and is not suited for any large or commercial projects.</em></strong></p>
<p>Why? Because large and commercial projects require millions of dollars to be spent on supporting them and your ugly abbreviations make it only harder.</p>
<p>P.S.: Oh, and don't get me started on that "modern" feature of aliasing imports. Having the ability for the same library to be represented by different names in different importing source files is just begging for chaos in larger projects.</p>
]]></content:encoded></item><item><title><![CDATA[Weekend update with Dmitrii Che]]></title><description><![CDATA[This weekend I've done something that I truly shouldn't have.
I installed HomeAssistant onto my old Android Phone. It wasn't easy: first, I had to enable adb and install my termux-launcher without being able to use the broken touch screen (that's why...]]></description><link>https://chedim.com/weekend-update-with-dmitrii-che</link><guid isPermaLink="true">https://chedim.com/weekend-update-with-dmitrii-che</guid><category><![CDATA[Home Assistant]]></category><category><![CDATA[debian]]></category><category><![CDATA[termux]]></category><category><![CDATA[Python]]></category><dc:creator><![CDATA[Chedim]]></dc:creator><pubDate>Tue, 21 Feb 2023 20:55:43 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1677012598985/16688f1e-9e7c-449b-a8b7-4a67828d9cd5.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>This weekend I've done something that I truly shouldn't have.</p>
<p>I installed HomeAssistant onto my old Android Phone. It wasn't easy: first, I had to enable adb and install my termux-launcher without being able to use the broken touch screen (that's why it's an "old" phone :). I was hoping that hass would be able to run directly on it, but that didn't happen because of the dreaded <code>cryptography</code> module issues thatprevented it even from being installed :(</p>
<p>So, I had to install <code>debian</code> using <code>proot-distro</code>. Luckily, hass agreed not only to install onto it, but even (after some editing of the <code>usb</code> component) was able to start, despite three levels of containerization (android, termux, and then proot).</p>
<p>But now... oh, now my boat got some Android brains, which I, an Android developer, am very excited about :)</p>
<p>I also finally received plywood and now can start building the galley. I'll update you on that part of the project next week.</p>
]]></content:encoded></item><item><title><![CDATA[It's weekend update with Dmitrii Che!]]></title><description><![CDATA[I didn't go to the boat this weekend. Instead, I revived my 7th gen i3 intel NUC with kali running on it to be the boat brain: I installed homeboatassistant and esphome on it and even flashed esphome firmware onto an esp8266 board I've had lying on t...]]></description><link>https://chedim.com/its-weekend-update-with-dmitrii-che</link><guid isPermaLink="true">https://chedim.com/its-weekend-update-with-dmitrii-che</guid><category><![CDATA[weekend-update]]></category><dc:creator><![CDATA[Chedim]]></dc:creator><pubDate>Mon, 13 Feb 2023 18:22:39 GMT</pubDate><content:encoded><![CDATA[<p>I didn't go to the boat this weekend. Instead, I revived my 7th gen i3 intel NUC with kali running on it to be the boat brain: I installed <s>home</s>boatassistant and esphome on it and even flashed esphome firmware onto an esp8266 board I've had lying on the floor around my desk for the past couple of weeks :slightly_smiling_face: The MCU is now reporting some fake data until I connect it either to some sensors or relays. I even got the nuc connected to my vpn using my old phone so, now it should always be online.</p>
<p>Also, <a target="_blank" href="https://github.com/chedim/jcliff/commit/97f9df8bee2b9fe6d8c0c00c86028ff1599ba94c">got carried away with Cliffhanger on Saturday</a> and now I have a partially implemented distributed java dom XML implementation that represents a data tree and can be queried using XPath. I also got beanshell embedded for evaluating scripts that are triggered upon HTTP requests to a node and either define cascading HTTP requests to the distributed XML or external HTTP services or an HTTP response to be sent to the client:</p>
<pre><code class="lang-plaintext">WHEN /hello-world:
  POST https://pushbullet.com/notification
  Authorization: cliff.query("/external/pushbullet/token")
    String.format("someone requested hello-world page from ip %s", request.getRemoteIp())

  WHEN $method = "GET":
    HTTP 200 OK
    Content-type: "text/plain"
      String.format("Hello! Current value: %s", cliff.query("/hello-world"))
</code></pre>
<p>Partially (like, 90%) rebuilt my android notification announcer so that now it not only reads all your notification wisdom directly to my ears, but also reads out current time with intervals that can be changed using volume buttons on the phone (volup for longer intervals up to 15 minutes and voldown for shorter intervals up to a second for testing). Also now I can use volume buttons to open/delete a notification as it is being announced :) Human-machine convergence at its best :D</p>
]]></content:encoded></item><item><title><![CDATA[JWT as coins?]]></title><description><![CDATA[Why aren't we using JWT to excange goods?]]></description><link>https://chedim.com/jwt-as-coins</link><guid isPermaLink="true">https://chedim.com/jwt-as-coins</guid><category><![CDATA[JWT]]></category><category><![CDATA[Cryptocurrency]]></category><category><![CDATA[crypto]]></category><dc:creator><![CDATA[Chedim]]></dc:creator><pubDate>Thu, 01 Dec 2022 17:58:37 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1669917439144/QT2fDzE8K.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Why aren't we using JWT to excange goods?</p>
]]></content:encoded></item><item><title><![CDATA[How to become a good software developer?]]></title><description><![CDATA[How to become a good software developer? 
Well, first you need to understand that development is not a one-person process. 
Even when you're alone in the room and working on a personal project, that work involves re-using work done by countless numbe...]]></description><link>https://chedim.com/how-to-become-a-good-software-developer</link><guid isPermaLink="true">https://chedim.com/how-to-become-a-good-software-developer</guid><category><![CDATA[software development]]></category><category><![CDATA[self-improvement ]]></category><dc:creator><![CDATA[Chedim]]></dc:creator><pubDate>Thu, 03 Nov 2022 14:32:37 GMT</pubDate><content:encoded><![CDATA[<p>How to become a good software developer? </p>
<p>Well, first you need to understand that development is not a one-person process. </p>
<p>Even when you're alone in the room and working on a personal project, that work involves re-using work done by countless number of library and tooling authors. </p>
<p>Each one of them had their own expectations for you and how you use their work. Learn to study those expectations and respect them. </p>
<p>And that will make you a better developer.</p>
<p>https://mstdn.social/@chedim/109280322154350944</p>
]]></content:encoded></item><item><title><![CDATA[Doctor, I am a robot... or what's wrong with our approach towards AI]]></title><description><![CDATA[We, software developers, are a product of our society. We grew up reading stories and fairytales that were created by the people who came before us. These stories influenced us, and formed our views on how things should be. But, as we discover more, ...]]></description><link>https://chedim.com/doctor-i-am-a-robot-or-whats-wrong-with-our-approach-towards-ai</link><guid isPermaLink="true">https://chedim.com/doctor-i-am-a-robot-or-whats-wrong-with-our-approach-towards-ai</guid><dc:creator><![CDATA[Chedim]]></dc:creator><pubDate>Sat, 30 Apr 2022 01:02:59 GMT</pubDate><content:encoded><![CDATA[<p>We, software developers, are a product of our society. We grew up reading stories and fairytales that were created by the people who came before us. These stories influenced us, and formed our views on how things should be. But, as we discover more, build more, and gain knowledge, we may realize that some of these beloved stories may not be a good representation of our reality. What if one of these fairytales is how we view intelligence, and, by extension -- ourselves?</p>
<p>As a neuron simulation technology skeptic, I am very impressed with the achievements that this technology has reached. This breakthrough, coupled in time with the digitalization of our world, has clearly shown us the magic of big numbers and big data.</p>
<p>Let's stop for a moment and appreciate the big picture -- the amount of information that is being processed by the modern Internet is just astonishing. Elon Musk, for example, just bought one of the biggest commodities in human history -- Twitter, an archive of information about this world and us, humans. </p>
<p>Humor me and imagine an anarcho-capitalistic world, in which this commodity is allowed to be used without any restrictions. How much information can be extracted about an average user just by looking at what, when, and how they post on the service? Or if they posted tweets with geolocation markers?</p>
<p>If you had enough information on them, would you be able to train an AI to act like them? (Yes, you would -- although it would be a very shallow copy).</p>
<p>Now imagine if we had this kind of information on all human beings.</p>
<p>Could we predict wars? Could we predict crimes? 
Could we optimize our logistics to feed the world?</p>
<p>What if we add observations made using satellites and space telescopes? </p>
<p>And, finally, would this not make our Planet act and feel like that big living creature it is finally got intelligent?</p>
<p>Color me a crazy atheist, but sometimes I feel like the Bible is not about the past and God is not our father, and heaven is something that we will eventually build.</p>
<p>Oh, let me ramble a bit on a Friday :-D</p>
]]></content:encoded></item><item><title><![CDATA[How Kubernetes and Database Operators Drive the Data Revolution]]></title><description><![CDATA[Originally published at The New Stack.
These are challenging days for IT. The amount of data our systems need to process grows exponentially. This challenge is further amplified by the growing complexity of data. Information is useless without its co...]]></description><link>https://chedim.com/how-kubernetes-and-database-operators-drive-the-data-revolution</link><guid isPermaLink="true">https://chedim.com/how-kubernetes-and-database-operators-drive-the-data-revolution</guid><category><![CDATA[Kubernetes]]></category><category><![CDATA[Databases]]></category><category><![CDATA[Devops]]></category><dc:creator><![CDATA[Chedim]]></dc:creator><pubDate>Tue, 15 Mar 2022 21:27:24 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1647379364643/SsugW7ILd.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><a target="_blank" href="https://thenewstack.io/how-kubernetes-and-database-operators-drive-the-data-revolution/">Originally published at The New Stack</a>.</p>
<p>These are challenging days for IT. The amount of data our systems need to process grows exponentially. This challenge is further amplified by the growing complexity of data. Information is useless without its context, and context is established by relations between different data points, but each relation also requires logic and processing resources. As a result, demands on our data storage and retrieval systems and their management complexity increase, rendering manual database management practices less and less viable.</p>
<p>Luckily, this is not the first time engineers faced a problem like this. Our history is full of inspiring examples of how to deal with growing demand. From the first windmills through steam engines, and screw-cutting lathes to Ford’s conveyor belt — looking back at the Industrial Revolution, one can conclude that appropriate and successful automation can ignite new levels in productivity and increase economic growth.</p>
<h1 id="heading-kubernetes-as-a-lathe">Kubernetes as a Lathe</h1>
<p>Another example of successful automation comes from the early 2010s. At that time, we faced a similar problem but with software architecture: The internet changed everything about how a user application works. Our first approaches, rooted in applying well-known centralized architectures from the client/server era, did not work. Big, centralized application backends just could not provide the flexibility required to scale from thousands to millions of requests per second. Most of us probably can remember at least a couple of cases when “monolithic” web applications were experiencing severe performance issues after going viral.</p>
<p>The solution to this problem came from adapting an approach where organizations split these monoliths into smaller “micro” services running on <a target="_blank" href="https://www.docker.com/resources/what-container">docker containers</a> that can be horizontally scaled both independently of each other and much quicker than monoliths. With each microservice adding to the demand on development operations, this strategy, however, wouldn’t be so successful without container orchestration frameworks like Kubernetes. Introduced publicly in 2014, Kubernetes, formerly known inside Google as Borg, quickly proved itself as a top choice for automating deployment workflows and today is one of the industry standards for modern development operations.</p>
<p>Also, being an open source, cloud native component, Kubernetes continues to evolve and improve. Echoing the idea of automated software installation packages, Kubernetes not only abstracts away specific infrastructure implementations but also automates environment creation and deployment procedures. Most organizations that use Kubernetes trust it to <a target="_blank" href="https://dok.community/dokc-2021-report/">run at least 50%</a> of their overall workloads.</p>
<h1 id="heading-autonomous-operators">Autonomous Operators</h1>
<p>Today, we find ourselves in the early days of the data revolution. And, just like at the dawn of the Industrial Revolution, the world is expecting us to meet the demand in data processing by automating the management functions of our data platforms.</p>
<p>When it comes to working with data and databases, automating management operations can give impetus to the growth of any organization relying on data insights and decision-making: stability as well as agility through repeatability. Human operators, while being great at solving problems and innovating, are not that great with routine tasks and quickly become error-prone. Operations tasks like scaling up and down, backups, patching and routine database maintenance are examples of such activities. Hearing “oops, wrong command” from your database administrator can be a nerve-wracking experience.</p>
<p>The problem to solve is to take the best practices of these human operators and efficiently automate them in a standardized way.</p>
<p>Ten years ago, creating an automated management system for databases required a lot of effort, as it had to be built from scratch. This naturally caused the emergence of managed database-as-a-service (DBaaS) solutions. AWS was the first big company to create such a service with their DynamoDB launching in 2012. Following its success, other big players rushed to the new market as well. Using a generic DBaaS, however, has its problems (e.g. vendor lock-in, usage requirements for specific versions, minimal customization for specialized workloads, etc.).</p>
<p>The evolution of Kubernetes into an automation Swiss Army knife changed all that by providing a great and stable software management framework. An especially important milestone in this evolution was support for stateful sets and persistent volumes, as databases are a textbook example of a stateful application.</p>
<p>Employing elements of control theory, <a target="_blank" href="https://kubernetes.io/docs/concepts/extend-kubernetes/operator/">Operators</a> work as Kubernetes extensions/plugins and use custom resource definitions (CRDs) to define and control the state of your services. Building your database environment with declarative CRDs is fairly easy: What you type is literally what you get. The operator reads your CRDs of the desired state of the system and not only creates it for you but also monitors the environment using internal events and ensures that the system is always close to the desired state. No more complicated setup scripts — your whole database system is standardized, described in a declarative language (YAML) and is self-explanatory.</p>
<p><a target="_blank" href="https://www.couchbase.com/products/cloud/kubernetes">Couchbase Autonomous Operator</a> was one of the earliest products to utilize this framework extensively for database automation. Many other community-built <a target="_blank" href="https://operatorhub.io/?category=Database">database operators</a> for Kubernetes have also become popular in recent years. Several communities and interest groups have also arisen around the technology, for instance, the <a target="_blank" href="https://dok.community/">DoK (Data on Kubernetes) community</a>.</p>
<h1 id="heading-the-new-horizons">The New Horizons</h1>
<p>The rise of DevOps, DBaaS, Kubernetes and Operators creates a compelling end-to-end platform for distributed applications. Developers need not worry about how their code is deployed, or how different components communicate with each other. Instead, developers can concentrate on the data and the logic that governs its evolution to provide improved insights and decision-making abilities for the business. Finally, the same consistent tool/framework can be used for managing all layers of the application stack, including the mission-critical database layer. Freeing important resources of organizations from routine labor-intensive tasks, automation creates space and time for innovation and further progress.</p>
<p>More widely within the industry, the future looks bright. Cloud providers are turning to fully managed services to offer a new business model. With most of these database innovations being open source, some of the cloud providers added a wrapper around those open source technologies and offered it as a DBaaS. Unfortunately, this strategy hasn’t been good news for everybody. It has greatly impacted other database vendors’ revenue, forcing them to change their licenses. While the precise approach has differed from vendor to vendor — with some opting for Business Source Licenses (BSL) and others for Server Side Public Licenses (SSPL) — the end goal has been the same. However, this is an evolving landscape, and it’s hoped it will settle down to a state where it benefits most and original research and innovation are rewarded.</p>
]]></content:encoded></item><item><title><![CDATA[Cliffhanger FFI draft]]></title><description><![CDATA[Yesterday I published the first draft of Foreign Function Interface for cliffhanger and it's a bit of a crazy one :) 
You can read it in detail here: https://github.com/chedim/cliffhanger/blob/main/FFI.md
TLDR -- all communication between cliffhanger...]]></description><link>https://chedim.com/cliffhanger-ffi-draft</link><guid isPermaLink="true">https://chedim.com/cliffhanger-ffi-draft</guid><category><![CDATA[Cloud]]></category><category><![CDATA[programming languages]]></category><category><![CDATA[languages]]></category><dc:creator><![CDATA[Chedim]]></dc:creator><pubDate>Thu, 06 Jan 2022 17:55:30 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1641491633573/8IP2WyD7q.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Yesterday I published the first draft of Foreign Function Interface for cliffhanger and it's a bit of a crazy one :) </p>
<p>You can read it in detail here: https://github.com/chedim/cliffhanger/blob/main/FFI.md</p>
<p>TLDR -- all communication between cliffhanger application components will be done over network sockets, even if all components are running locally on the same machine.</p>
<p>In a sense, cliffhanger FFI interface is an RPC protocol.</p>
<p>You may rightly wonder why I chose this particular interpretation -- network calls are orders of magnitude more expensive than procedural calls, which means that cliffhanger applications will be very, very slow compared to applications built using classic languages like Java, Go, Rust, C++ or even python.</p>
<p>Well, so what if it is going to be slow? Cliffhanger is not a systems programming language. It is a data manipulation language, designed to glue microservices into a single application. This makes it more important for cliffhanger to be a useful programming language rather a fast one.</p>
<p>Using a network protocol to interact between application modules would allow independent deployments of CH application components. Clifhanger libraries are not just libraries in a classic sense -- they are services that can be hosted by their developers (or, if a developer allows that -- downloaded an run locally). It would also allow a single application to securely span across all the network barriers of the Internet. In a sense, cliffhanger is not a programming language, but a devops tool.</p>
<p>That's why I think that making CH a natively network-aware language is more beneficial to it than making it fast.</p>
<p>What do you think of my decision? Please leave your thoughts in a comment below or tweet them @chedim :)</p>
]]></content:encoded></item><item><title><![CDATA[Just some sample cliffhanger code, nothing to see here :)]]></title><description><![CDATA[Cliffhanger is a natural declarative stream processing language I've been working on for almost a year now (and haven't written a single line of compiler code yet ^_^). Today, I almost feel like  the draft of the language  is ready for general feedba...]]></description><link>https://chedim.com/just-some-sample-cliffhanger-code-nothing-to-see-here</link><guid isPermaLink="true">https://chedim.com/just-some-sample-cliffhanger-code-nothing-to-see-here</guid><category><![CDATA[programming languages]]></category><dc:creator><![CDATA[Chedim]]></dc:creator><pubDate>Tue, 02 Nov 2021 14:17:39 GMT</pubDate><content:encoded><![CDATA[<p>Cliffhanger is a natural declarative stream processing language I've been working on for almost a year now (and haven't written a single line of compiler code yet ^_^). Today, I almost feel like  <a target="_blank" href="https://github.com/chedim/cliffhanger/blob/main/README.md">the draft of the language</a>  is ready for general feedback :)</p>
<p>Here's an example CH application:</p>
<pre><code>a user:
  name <span class="hljs-keyword">is</span> an input text line after the output <span class="hljs-keyword">is</span> <span class="hljs-string">"Enter your name: "</span>
  age <span class="hljs-keyword">is</span> an input number after the output <span class="hljs-keyword">is</span> <span class="hljs-string">"Enter your age: "</span>
  email <span class="hljs-keyword">is</span> an input <span class="hljs-keyword">string</span> after the output <span class="hljs-keyword">is</span> <span class="hljs-string">"Enter your email: "</span>
  name must not be <span class="hljs-literal">false</span> <span class="hljs-keyword">when</span> the user <span class="hljs-keyword">is</span> verified
  <span class="hljs-keyword">is</span> verified <span class="hljs-keyword">when</span> the user email <span class="hljs-keyword">is</span> not <span class="hljs-literal">false</span>

output <span class="hljs-keyword">is</span>:
  before exit:
    <span class="hljs-keyword">when</span> the user <span class="hljs-keyword">is</span> verified: <span class="hljs-string">"You've been verified, {the user name} of age {the user age}. Good luck!"</span>
    <span class="hljs-keyword">else</span>: <span class="hljs-string">"Goodbye, anonymous!"</span>
</code></pre><p>This example application asks a user for his name, age, and email, and then prints a greeting to the user. 
If the user does not enter their email then the application will not verify him and output "Goodbye, anonymous".</p>
<p>Note the "must not be" construct that can be used to verify the integrity of the data.</p>
<p>As you can see from the source code, I hope to implement non-linear control flow in cliffhanger, making it an event-driven language. Cliffhanger's execution mechanism is very similar to Javascript's event loop but, instead of executing code, cliffhanger's event loop processes data mutations according to provided by developers data definitions.</p>
<p>Why is it a stream processing language? Because cliffhanger datapoints correspond to streams of values of that datapoint and the stream can be accessed using the plural form of datapoint name:</p>
<p>message.cliff:</p>
<pre><code>a message:
  subject <span class="hljs-keyword">is</span> a <span class="hljs-keyword">string</span>
  author <span class="hljs-keyword">is</span> a user
  recipient <span class="hljs-keyword">is</span> a user
  text <span class="hljs-keyword">is</span> a <span class="hljs-keyword">string</span>

a user message <span class="hljs-keyword">is</span> a message

total message count <span class="hljs-keyword">is</span> messages count  <span class="hljs-comment">// messages is a stream of 'message' objects</span>
</code></pre><p>In this example, cliffhanger will create <code>a message</code> class datapoint and <code>messages</code> stream for the instances of that class. This stream can later be filtered into other streams:
<code>a message is a spam if a spam word is in the message text</code></p>
<p>Cliffhanger datapoint values will be automatically updated, for example, a datapoint with a value defined like this:
<code>the last 10 messages</code>
will always point to the last 10 objects of the <code>messages</code> stream.</p>
<p>I am still working out the details of the language by periodically updating the README.md of its <a target="_blank" href="https://github.com/chedim/cliffhanger">github project</a>.</p>
<p>Cliffhanger is an experimental language. I hope to have a simple execution environment for it around or before May 2022. In the meanwhile, I would really appreciate your feedback on the language. </p>
<p>Thank you!</p>
]]></content:encoded></item><item><title><![CDATA[Gitpod+Flask: Port Not Found Error in Preview Browser]]></title><description><![CDATA[After spending hours trying to figure out why gitpod shows the "Port not found" error page instead of our flask-based application's index page, the diagnosis is:

The root cause of the problem is still unknown.
Most likely this is caused by unexpecte...]]></description><link>https://chedim.com/gitpodflask-port-not-found-error-in-preview-browser</link><guid isPermaLink="true">https://chedim.com/gitpodflask-port-not-found-error-in-preview-browser</guid><category><![CDATA[Flask Framework]]></category><category><![CDATA[Python]]></category><dc:creator><![CDATA[Chedim]]></dc:creator><pubDate>Wed, 14 Jul 2021 00:31:28 GMT</pubDate><content:encoded><![CDATA[<p>After spending hours trying to figure out why gitpod shows the "Port not found" error page instead of our flask-based application's index page, the diagnosis is:</p>
<ol>
<li>The root cause of the problem is still unknown.</li>
<li>Most likely this is caused by unexpected behavior of flask as on startup it briefly opens and closes the port and just moments later reopens it again. </li>
<li>I think that the first time flask opens the port, gitpod detects that and opens the preview browser which, unfortunately, sends its request to the port just after flask closed it, which causes the browser to show the error page.</li>
<li>It is possible to use <code>socat</code> (or a similar tool) to fix the issue. </li>
<li>To do so, instruct gitpod to ignore flask's port and open preview on some other port, i.g. 8080.</li>
<li>Start your flask app and then run socat like this: <code>socat TCP-LISTEN:8080,fork TCP4:localhost:5000</code></li>
</ol>
<p><code>socat</code> (SOcket CAT) is a great tool!</p>
]]></content:encoded></item><item><title><![CDATA[Tip: unlocking i3lock with fingerprint scanner]]></title><description><![CDATA[i3lock, the go-to locker for i3wm, does not support unlocking with fingerprint scanners. Until now, that is :) 
To unlock your linux computer by simply scanning your fingerprint, install fprintd and then use this script instead of i3lock to lock your...]]></description><link>https://chedim.com/tip-unlocking-i3lock-with-fingerprint-scanner</link><guid isPermaLink="true">https://chedim.com/tip-unlocking-i3lock-with-fingerprint-scanner</guid><category><![CDATA[Linux]]></category><dc:creator><![CDATA[Chedim]]></dc:creator><pubDate>Sun, 30 May 2021 03:48:57 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1622346483552/i09iwZdKG.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>i3lock, the go-to locker for i3wm, does not support unlocking with fingerprint scanners. Until now, that is :) 
To unlock your linux computer by simply scanning your fingerprint, install fprintd and then use this script instead of i3lock to lock your session:</p>
<pre><code>i3lock &amp;
(while pidof i3lock; <span class="hljs-keyword">do</span>
  <span class="hljs-keyword">if</span> (fprintd-<span class="hljs-keyword">verify</span> | grep <span class="hljs-keyword">verify</span>-<span class="hljs-keyword">match</span>); then 
    killall i3lock
  fi
done) &amp;
</code></pre>]]></content:encoded></item><item><title><![CDATA[Down from the metal: computer keyboards.]]></title><description><![CDATA[We meet again, stranger!
Thank you for reading this second post in my blog about computers, software engineering and cloud applications. In the  first post  I introduced myself and my philosophy around coding and computer systems. This post marks the...]]></description><link>https://chedim.com/down-from-the-metal-computer-keyboards</link><guid isPermaLink="true">https://chedim.com/down-from-the-metal-computer-keyboards</guid><category><![CDATA[Foundation]]></category><category><![CDATA[data]]></category><category><![CDATA[streaming]]></category><dc:creator><![CDATA[Chedim]]></dc:creator><pubDate>Fri, 14 May 2021 23:23:17 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1621030927167/52Pbwvkhe.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>We meet again, stranger!</p>
<p>Thank you for reading this second post in my blog about computers, software engineering and cloud applications. In the  <a target="_blank" href="https://chedim.com/why-i-code">first post</a>  I introduced myself and my philosophy around coding and computer systems. This post marks the beginning in our exploration of how computers work and how humans build the incredible interactive experiences of the modern Web.</p>
<p>I named this blog "Down from the metal, up through the cloud, and back to the UX" because it captures the general flow of data in modern computer systems. This title will also serve as my plan for publishing articles on this blog. And so, in this article, I am getting down to the metal and exploring how human input devices capture our thoughts and ideas and transform them into electric signals useful for computers. </p>
<p>Computers work by performing a list of repeatable operations (a program) on some data. It is common to refer to this as  <a target="_blank" href="https://en.wikipedia.org/wiki/Von_Neumann_architecture">Von Neumann architecture</a> . Guaranteeing repeatability and correctness of these operations was the main problem of early computer technology as the entropy of our world tends to destroy any organized data. Von Neumann architecture addresses this problem by creating an isolated computational environment that communicates with the world only via a set of specialized input/output devices. </p>
<p>Many different types of input devices were invented throughout the history of computer technology. But none of them was as impactful on our world as computer keyboard, which makes exploring how it works the best starting point for learning about computers and data.</p>
<p>It is hard to trace who authored the source code for the first keyboard controller and driver, but it likely to be someone who worked on MIT's Multics operating system as it was the first computer system to introduce the computer terminal as we know it. </p>
<p>So, how do keyboards work? I will answer this question using the mobile keyboard I designed for my phone as an example. And, as a bonus for my readers, I will publish for the first time design files for this keyboard at the end of this post. </p>
<blockquote>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1621031981341/1IEBD0x6J.jpeg" alt="An early prototype of my mobile keyboard on the back of a Surface tablet" /> An early prototype of my mobile keyboard on the back of a Surface tablet</p>
</blockquote>
<p>Although it may not look like any other keyboard you've seen before, it uses the same principles, technologies, and components that you may find inside of any other desktop or mobile keyboard produced in the last 40 years or so. The journey of any textual data entered by humans into a computer system can be traced to the most fundamental component of the keyboard. And so, please welcome the queen of computer technologies - <a target="_blank" href="https://beta.docs.qmk.fm/developing-qmk/for-a-deeper-understanding/how_a_matrix_works"> the keyboard matrix</a> .</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1621031422234/o4kC8h4_9.png" alt="Screenshot 2021-05-14 183032.png" /></p>
<p>A keyboard matrix is an electrical circuit that allows computers to capture the state of multiple keyboard keys arranged into rows and columns. It may seem excessive and too complex to people somewhat familiar with analog electrical circuits. Some of my readers may even wonder why can't the keys be connected directly to the computer as you'd see on the classic electric circuit that shows a single switch and a bulb. Although it is possible to build a keyboard by connecting the keys directly to a microcontroller, such a solution requires more connections to the controller, and using more pins (points of electrical connection between the controller and its circuit) means using either more complex and more expensive microcontrollers or, alternatively, more less powerful microcontrollers (which ends up being even more expensive than using a single more capable controller). There are other hardware design problems that affect reliability of such a design, but diving into them is out of scope for this post.</p>
<p>For example, one of the most popular microcontrollers, the ATMega32u, has 4 8-bit GPIO ports, which results in 32 pins available to the designer. One would need at least five ATMega32u to read the state of a regular keyboard if the keys were connected directly to the controller, while arranging keys in a matrix pattern allows one to read the same state with just a single microchip. </p>
<p>To be able to read the state of the keyboard keys, a microcontroller needs to know how exactly is it connected to every key of the keyboard. This is where keyboard firmware first comes into the picture. The basic element of any keyboard firmware is the matrix scanning loop, during which the state of every key is read and stored into the microcontroller's memory. </p>
<p>The matrix state, however, does not represent the information a user enters on their keyboard because such a state is just a snapshot in time. All it can tell us is that some of the keys are pressed while others are not, but it tells us nothing about the order in which these keys are pressed. The information we enter using our keyboards is retrieved by the keyboard firmware by continuously comparing these snapshots to each other. Only by looking at the changes between these snapshots the firmware can detect what exactly and in which order was entered by the user. And it is these changes, not raw matrix states, that microcontroller's firmware sends to the computer that keyboard is connected to. When you press a key, it changes the state of the keyboard matrix that is read into the microcontroller's memory. Comparing this new state with the previous allows the firmware to detect a keypress and report it up to the computer.</p>
<p>Calculated by the firmware matrix state changes are usually sent to the computer using a special set of predefined codes called scan codes. Every time a new matrix state change is detected and its scan code is calculated, the keyboard firmware notifies your computer about such a change. For example, one scan code can be used to notify your computer that the "A" key was pressed on your keyboard, while another will be used when it is released. Different protocols and transfer mediums can be used to send these changes and reviewing them all is well beyond the scope of this article. Instead, I will describe this process in general terms of x86 architecture and will leave a more detailed review of HID protocols for future articles.</p>
<p>In x86 as well as in many other architectures every input or output device is connected to the main CPU of your computer via input/output ports, repeating the same pattern we saw when talking about microcontroller pins. When keyboard firmware wants to send a new scan code to the computer it sets the port through which it is connected to the computer into a special state. In the real mode of x86 architecture, such a change results in a special kind of event called an interrupt. It is called that way because in early computers handling such an event would involve interrupting the currently running application by switching the CPU to execute the event handler. </p>
<p>A keyboard interrupt handler, when invoked, would read sent by the keyboard firmware scan code from the port and put it into the computer's keyboard input buffer, from where it can be later read by the computer's operating system or a user application, which would process the scan code either by transforming it back into entered by the user text or handle it in some different way. In a sense, the only job of the interrupt handler is to ensure that data flows from the keyboard into the system buffer without being lost or corrupt in the process.</p>
<p>Describing how user input is handled inside of an OS is, however, a topic for a whole different article that will continue our journey through computer technologies later. But to prepare us and make these next steps easier, I want to finish this article by providing you a bigger picture of the keyboard input subsystem and pointing out the long-reaching implications that can be drawn from such an overview. The easiest way to do so is to represent the keyboard subsystem as a set of layers through which the data you enter has to travel to reach your computer:</p>
<blockquote>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1621033999619/nxYmUR1oq.png" alt="A simplified overview of a typical keyboard data pipeline" /> A simplified overview of a typical keyboard data pipeline</p>
</blockquote>
<p>Understanding general principles of how computer keyboards work is very helpful to understanding how modern computer systems work. By guiding our journey to the first glimpse into what data is and how it wants to be handled it shifts our focus from learning algorithms to learning about how data behaves inside computer systems. It shows us that, on the lowest levels, data is not just a set of bits and bytes. Instead, it is more beneficial to think of information as history of changes that some system (in this example - the circuitry of a keyboard) goes over time. This view is not limited only to textual data and is also applicable to audio and video: audio information describes changes in air density of a system and video information most often describes changes in visible part of electromagnetic spectrum.</p>
<p>Although knowing how keyboards work is not required to be a coder, going through this showed us some fundamental properties of information that dictate how modern computer systems are built:</p>
<p>Any data processed by a computer can be viewed as a stream of changes of some state over time. Thus, one can say that data is not simply operated upon or stored by computers but that it flows through computer circuits in the form of events and electrical signals. As it flows through the system, data goes through different layers of logic and causes that system to change its state. Every logic layer analyzes the data that flows through it and adds more meaning to it. This additional meaning is used then by higher levels to either perform some action or to add even more meaning to the data. Therefore, engineering computer systems comes down to designing these layers and adding more meaning to data as it flows through the system. This pattern governs how all computer systems behave and can be observed in every single one of them. The OSI network model, a cornerstone technology of the Web that I will review in one of the next articles, is a great example of a system design that uses these principles with great success. </p>
<p>Even if you don't write firmware or device drivers and your work is mostly concentrated in building web applications, adopting this datacentric view and promoting data and its flow to the center of your thinking about a computer system will allow you to avoid many bugs and performance bottlenecks and design better computer systems, be it a simple calculator application or a complex decentralized social network that runs on millions of physical nodes built with different internal designs.</p>
<p>Please stay tuned for the next article "Down from the metal: making sense of the input", in which I plan to go over how computers parse keyboard (or any
 other) input and use it to react to the changes in the surrounding world and satisfy requests from their users.</p>
]]></content:encoded></item><item><title><![CDATA[Why I code]]></title><description><![CDATA[Well hello, stranger! 
This — my first post both on chedim.com and hashnode.com — a personalized blogging service for devs that allows you to host your blog on your domain. And it just so happens that I was recently thinking about finding(building? :...]]></description><link>https://chedim.com/why-i-code</link><guid isPermaLink="true">https://chedim.com/why-i-code</guid><category><![CDATA[first post]]></category><dc:creator><![CDATA[Chedim]]></dc:creator><pubDate>Thu, 13 May 2021 02:20:32 GMT</pubDate><content:encoded><![CDATA[<p>Well hello, stranger! </p>
<p>This — my first post both on chedim.com and hashnode.com — a personalized blogging service for devs that allows you to host your blog on your domain. And it just so happens that I was recently thinking about finding(building? :-D) some similar solution. And using such a service means that I'm not just promoting my domain, but also have the freedom to move my blog to any similar system (or just switch to Jekyll, which I'm using to build my more specialized  <a target="_blank" href="https://chebits.com">blog</a>  about my hardware projects). </p>
<p>Freedom is good :-)</p>
<p>As it always happens, choosing a topic for your first post on a new platform is, arguably, the hardest part of blogging. So, I decided to first read some of the other first posts made by people on this platform. Many of the posts were about some kind of technology or development environment. But what inspired me the most was <a target="_blank" href="https://girlthatlovestocode.com/my-path-to-coding">this first post</a> by <a class="user-mention" href="https://hashnode.com/@GirlThatLovesToCode">GirlThatLovesToCode</a> in which she was kind enough to share with us her story of becoming a software engineer. I liked the personal touch of such a first post. Although I intend to publish only professional posts on this blog, it may be interesting for my future readers to discover something a little bit more personal about me than technical guides :)</p>
<p>And so, I decided to write my first post about why I code and what coding is for me today.</p>
<p>I was introduced into... no, I was infected with coding by a child book (of which title has been long forgotten) about robots and how they work that my grandfather bought for me when I was 9 years old. I remember being increasingly disappointed the more I was reading the book -- the robots in that book had nothing to do with any of the robots I saw before! They were dumb! They required being taught and warned about every little detail of such a simple task as going to the store! Even R2 is smarter than that...</p>
<p>But, as I said, I was already infected with the idea of coding. This dramatic difference between my childish expectations and reality would not leave me alone. Ever since I always wanted to make robots smarter. </p>
<p>Today I am a quarter-century older kid with the same goal and 15 years of experience in software development. I didn't get to build robots much, though :) Instead, I got to be one of the guys who build the Web. I worked on many interesting projects across different industries of two dramatically different societies that spent half of the 20th century arguing about whose  <a target="_blank" href="https://en.m.wikipedia.org/wiki/Blind_men_and_an_elephant">economical ideology</a> is better. I've built a unique hardware device and can brag about knowing how computers work down to the lowest physical levels. My interests shifted from computer science to mathematics, biology, chemistry and physics. So, why do I continue to code and what do I think about coding?</p>
<blockquote>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1620870937561/h2nHtn-rG.jpeg" alt="The latest iteration of mobile keyboard I've built last month and used to type this post." /> The latest iteration of the mobile keyboard I've built last month and used to type this post.</p>
</blockquote>
<p>I have a somewhat unusual view of coding. I believe that developers don't just write code but, by putting algorithms and logic down in the form of source code, they (quite literally) upload parts of their brains into a computer. This process happens 24/7 around the world. And our code is not just being "executed". Every instruction we put down results in a measurable and repeatable change in the physical world. Even if it's just a simple "Hello, world!", execution of an application results, at a minimum, in some movement of energy through electromagnetic fields. As we build the Web, our thoughts and knowledge connect and change that field. I believe that realizing this real physical aspect of our job is one of the most important steps of becoming a good coder.</p>
<p>I long believe that the Internet will if haven't already, become conscious. This thought, to be honest, is a scary one. So, why do I <em>continue</em> to code?</p>
<p>To make It better.</p>
]]></content:encoded></item></channel></rss>