<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Taqmuraz</title>
    <description>The latest articles on DEV Community by Taqmuraz (@taqmuraz).</description>
    <link>https://dev.to/taqmuraz</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%2F1243539%2F46e68e82-4c06-430b-a0e2-bcb2f380b31a.png</url>
      <title>DEV Community: Taqmuraz</title>
      <link>https://dev.to/taqmuraz</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/taqmuraz"/>
    <language>en</language>
    <item>
      <title>Myth we believe #2</title>
      <dc:creator>Taqmuraz</dc:creator>
      <pubDate>Sun, 01 Feb 2026 13:33:28 +0000</pubDate>
      <link>https://dev.to/taqmuraz/myth-we-believe-2-2l0i</link>
      <guid>https://dev.to/taqmuraz/myth-we-believe-2-2l0i</guid>
      <description>&lt;h3&gt;
  
  
  Memory allocation in games
&lt;/h3&gt;

&lt;p&gt;In my previous article I touch this question, but it wasn't the primary topic. Today we discuss garbage collection (&lt;strong&gt;GC&lt;/strong&gt;) in games and graphics/physics simulation software, where program speed most important.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where best practices come from?
&lt;/h3&gt;

&lt;p&gt;Almost everywhere you may hear or read that opinion, presented as fact : "Avoid lots of allocations, reuse objects you already allocated, practice objects pool".&lt;br&gt;
Those arguments (I confidently suppose) come from the world of programming languages with no default &lt;strong&gt;GC&lt;/strong&gt; (C, C++, Rust and others), where memory allocations are, by default, &lt;code&gt;malloc&lt;/code&gt; calls, which might be &lt;strong&gt;slow&lt;/strong&gt;.&lt;br&gt;
Today we give attention to languages with &lt;strong&gt;GC&lt;/strong&gt;, such as C#, Java and Python (&lt;em&gt;missed your favorite language? Ask for it in comments!&lt;/em&gt;).&lt;br&gt;
For those languages (C#/Java/Python), advice to avoid allocations and reusing memory in object pools will lead to performance losses and unnecessary code complexity. And why so, you will know after reading this article.&lt;/p&gt;
&lt;h3&gt;
  
  
  Objects pool vs GC
&lt;/h3&gt;

&lt;p&gt;What &lt;strong&gt;objects pool&lt;/strong&gt; is? It is an optimization pattern, supposed to save time on allocating/releasing memory for massively used objects. Applying this pattern in language with GC, you have lots of long-living objects in heap and almost no short-living objects, what gives several negative effects :&lt;/p&gt;
&lt;h4&gt;
  
  
  objects pool
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;longer garbage collection for objects out of pool due to lots of old objects in heap&lt;/li&gt;
&lt;li&gt;heap fragmentation&lt;/li&gt;
&lt;li&gt;constantly moving objects in pool increase CPU cache misses&lt;/li&gt;
&lt;li&gt;no predictable allocation patterns, GC can't optimize&lt;/li&gt;
&lt;li&gt;overhead of adding/removing/searching objects in pool&lt;/li&gt;
&lt;li&gt;reallocating memory on extending objects pool&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In practice, results I observed were exactly what I describe here - less performance, less FPS.&lt;br&gt;
Now, what about to not use &lt;strong&gt;objects pool&lt;/strong&gt; and let &lt;strong&gt;GC&lt;/strong&gt; do its work? Picture completely opposite :&lt;/p&gt;
&lt;h4&gt;
  
  
  GC
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;shorter garbage collection, because most of objects are young&lt;/li&gt;
&lt;li&gt;no heap fragmentation&lt;/li&gt;
&lt;li&gt;objects are allocated sequentially, perfect for CPU cache&lt;/li&gt;
&lt;li&gt;all young objects born and die together, forming predictable patterns for GC&lt;/li&gt;
&lt;li&gt;GC allocation generally is just increasing heap pointer, very fast&lt;/li&gt;
&lt;li&gt;very flexible, no necessary to control object numbers&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Why it doesn't work in Unity, Godot, Unreal Engine?
&lt;/h3&gt;

&lt;p&gt;My advises work in context of developing the whole system in single approach. Popular game engines, such as Unity, Godot, Unreal Engine, provide ready-to-use systems, optimized for common practices. Unity engine references all &lt;em&gt;active&lt;/em&gt; instances of &lt;code&gt;GameObject&lt;/code&gt;, &lt;code&gt;Component&lt;/code&gt; and other &lt;code&gt;UnityEngine.Object&lt;/code&gt; descendants, and &lt;em&gt;destroying&lt;/em&gt; those objects is removing references on them from engine. Those objects expected to live long, respond to engine events and change internal state accordingly. So, unity engine reminds one large &lt;strong&gt;objects pool&lt;/strong&gt; in sense of negative effects for performance.&lt;br&gt;
Unreal Engine and Godot both implemented with C++, so they implement own ways to manage memory, optimizing it for most common use cases, so lots of allocations will definitely reduce performance there.&lt;/p&gt;
&lt;h3&gt;
  
  
  Real evidence
&lt;/h3&gt;

&lt;p&gt;There is a cut from &lt;strong&gt;GC&lt;/strong&gt; logs one of &lt;a href="https://youtu.be/0V4gXC3i36k?si=U5XpRxjS8OXiNU9M" rel="noopener noreferrer"&gt;my game demos&lt;/a&gt; made with Clojure and Java.&lt;br&gt;
These logs demonstrate performance on 25vs25 battle scene with 50 units in total.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[50,037s][info][gc] GC(62) Pause Young (Normal) (G1 Evacuation Pause) 447M-&amp;gt;213M(505M) 7,961ms
[51,514s][info][gc] GC(63) Pause Young (Normal) (G1 Evacuation Pause) 448M-&amp;gt;213M(505M) 4,246ms
[52,978s][info][gc] GC(64) Pause Young (Normal) (G1 Evacuation Pause) 448M-&amp;gt;213M(505M) 3,502ms
[54,363s][info][gc] GC(65) Pause Young (Normal) (G1 Evacuation Pause) 449M-&amp;gt;213M(505M) 3,223ms
[55,727s][info][gc] GC(66) Pause Young (Normal) (G1 Evacuation Pause) 448M-&amp;gt;213M(505M) 2,372ms
[57,044s][info][gc] GC(67) Pause Young (Normal) (G1 Evacuation Pause) 448M-&amp;gt;213M(505M) 2,780ms
[58,419s][info][gc] GC(68) Pause Young (Normal) (G1 Evacuation Pause) 448M-&amp;gt;213M(505M) 2,282ms
[59,752s][info][gc] GC(69) Pause Young (Normal) (G1 Evacuation Pause) 449M-&amp;gt;213M(505M) 3,023ms
[61,066s][info][gc] GC(70) Pause Young (Normal) (G1 Evacuation Pause) 449M-&amp;gt;213M(505M) 3,137ms
[62,388s][info][gc] GC(71) Pause Young (Normal) (G1 Evacuation Pause) 449M-&amp;gt;213M(505M) 2,975ms
[63,694s][info][gc] GC(72) Pause Young (Normal) (G1 Evacuation Pause) 449M-&amp;gt;213M(505M) 2,451ms
[65,016s][info][gc] GC(73) Pause Young (Normal) (G1 Evacuation Pause) 449M-&amp;gt;213M(505M) 4,378ms
[66,620s][info][gc] GC(74) Pause Young (Normal) (G1 Evacuation Pause) 449M-&amp;gt;213M(505M) 3,651ms
[67,930s][info][gc] GC(75) Pause Young (Normal) (G1 Evacuation Pause) 449M-&amp;gt;213M(505M) 2,560ms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you may see, garbage collection is happening approximately once in 1 second, generally taking &lt;code&gt;~3ms&lt;/code&gt; and collecting &lt;code&gt;~300MB&lt;/code&gt; of garbage. It also means, that those &lt;code&gt;~300MB&lt;/code&gt; were allocated during that 1 second. What do we have?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;game is allocating &lt;strong&gt;GC&lt;/strong&gt; memory in rate of &lt;code&gt;~300MB/sec&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GC&lt;/strong&gt; happening once each second&lt;/li&gt;
&lt;li&gt;taking &lt;code&gt;~0.3%&lt;/code&gt; of all time in total&lt;/li&gt;
&lt;li&gt;collecting &lt;code&gt;~300MB&lt;/code&gt; of garbage each second&lt;/li&gt;
&lt;li&gt;keeping peak memory consumption on &lt;code&gt;505MB&lt;/code&gt; (perfect for systems with limited RAM)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Someone would expect me using some 16 cores 5GHz CPU for achieving those results, but no, it's this one :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;lulook@lulook:~&lt;span class="nv"&gt;$ &lt;/span&gt;lscpu | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"Model name"&lt;/span&gt;
Model name:                   
        Intel&lt;span class="o"&gt;(&lt;/span&gt;R&lt;span class="o"&gt;)&lt;/span&gt; Core&lt;span class="o"&gt;(&lt;/span&gt;TM&lt;span class="o"&gt;)&lt;/span&gt; m3-8100Y CPU @ 1.10GHz
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Repeating my previous article
&lt;/h3&gt;

&lt;p&gt;Most of programming advises work only in context, so don't believe them, always test applying to your use cases.&lt;br&gt;
Limits everyone talk about may exist only because of poor system design or premature optimizations in one context, but step out that context and rules change.&lt;/p&gt;

</description>
      <category>gamedev</category>
      <category>csharp</category>
      <category>java</category>
      <category>cpp</category>
    </item>
    <item>
      <title>Myths we believe : Stack vs Heap</title>
      <dc:creator>Taqmuraz</dc:creator>
      <pubDate>Sat, 31 Jan 2026 11:01:43 +0000</pubDate>
      <link>https://dev.to/taqmuraz/myths-we-believe-stack-vs-heap-72m</link>
      <guid>https://dev.to/taqmuraz/myths-we-believe-stack-vs-heap-72m</guid>
      <description>&lt;p&gt;Being C# programmer, I have heard a lot about stack memory, heap memory and difference between those. Usually it is "&lt;strong&gt;stack is faster&lt;/strong&gt;, because no GC happens and &lt;strong&gt;heap is slower&lt;/strong&gt; so you should avoid using it". This idea spreads not over C#, but also Java, C, C++, and many other compiled languages.&lt;br&gt;
In this article I will speak on performance questions, not covering abstract concepts of stack and heap, and how they are different in C#/Java and C/C++.&lt;/p&gt;
&lt;h3&gt;
  
  
  Dare experiment
&lt;/h3&gt;

&lt;p&gt;For some time I believed that, but once had courage to try using heap instead of stack, and...nothing bad happened.&lt;br&gt;
I wasn't writing some ASP.NET backend, where latency &lt;strong&gt;500ms&lt;/strong&gt; is considered normal, instead I was developing a game engine, where even &lt;strong&gt;10ms&lt;/strong&gt; delay is critical for FPS.&lt;br&gt;
I didn't hesitate on using heap memory, and, after I had surprisingly good performance with C# &lt;strong&gt;garbage collector&lt;/strong&gt;, I kept my approaches for Java, making mobile rendering library with OpenGLES.&lt;br&gt;
Still being surprised with good performance, I tried to disable Java garbage collector (&lt;code&gt;-XX:+UseEpsilonGC&lt;/code&gt;) and see what happens.&lt;br&gt;
And, I was surprised again - program terminated (due to out of memory) 5 seconds after it started. It consumed nearly 4GB of RAM in 5 sec, what is 800MB/sec.&lt;br&gt;
All of this time my code was consuming that much of RAM, and still didn't have any problems with performance?&lt;/p&gt;
&lt;h3&gt;
  
  
  Old fairy tales
&lt;/h3&gt;

&lt;p&gt;Yes, modern garbage collectors are that good. You may consume hundreds megabytes of RAM and still see no performance lost. If someone tell they have problems with slow GC, consider that as :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;they consume RAM in rate about 5-10GB/sec&lt;/li&gt;
&lt;li&gt;RAM consumption is acceptable, but they have large memory leaks&lt;/li&gt;
&lt;li&gt;they use/used some old language or it's old compiler/runtime version&lt;/li&gt;
&lt;li&gt;cause of performance loss is not in GC but somewhere else&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, those stories about "slow" heap memory are mostly outdated and can be considered as just fairy tales.&lt;/p&gt;
&lt;h3&gt;
  
  
  Is access to stack memory faster?
&lt;/h3&gt;

&lt;p&gt;We covered topic on GC, but it can't be only difference between stack and heap, right?&lt;br&gt;
Some of you may know that stack and heap are located on the same physical device (RAM) and approached by CPU in the same way. Difference appears when a compiler tries to optimize our code, replacing use of stack with use of registers. For an unknown reason, nobody talks about that in context of stack/heap separation.&lt;br&gt;
Example :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt;  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;SomeFunc&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="kt"&gt;int&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;c&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="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;d&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;c&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;e&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&amp;lt;&lt;/span&gt;  &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you ask a C# programmer, how much of stack space (in bytes) this function would use, answers may be different. Some would count only variables (&lt;code&gt;3 x int = 12 bytes&lt;/code&gt;), some would count arguments as well (&lt;code&gt;5 x int = 20 bytes&lt;/code&gt;). In fact, it's just guesswork, and all depends on compiler version and it's implementation.&lt;br&gt;
I used the &lt;a href="//godbolt.org"&gt;godbolt app&lt;/a&gt; to do researches on .NET compiler, and that's result I got for our C# code snippet :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Program:.ctor():this  (FullOpts):
ret

Program:SomeFunc(int,int):int  (FullOpts):
add  edi, esi
mov  eax, edi
imul  eax, edi
add  eax, eax
ret
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you can read assembly code, you already understand, what is going on. There is no stack frame at all. Arguments are passed in registers (&lt;code&gt;edi&lt;/code&gt; and &lt;code&gt;esi&lt;/code&gt;), and value is returned in &lt;code&gt;eax&lt;/code&gt; register. This assembly code does not access RAM, what makes it much faster. Generally, access to stack memory is same slow as access to any other area of RAM (slow comparing to accessing a register).&lt;br&gt;
So, difference between stack and heap exist only in context of specific compiler and it's optimization mechanisms. C# standard says nothing about stack being faster than heap.&lt;br&gt;
CPU caches? Yes, they might make access to stack much faster, but same works with memory on heap.&lt;/p&gt;

&lt;h3&gt;
  
  
  Don't believe, do research
&lt;/h3&gt;

&lt;p&gt;A lot of things you may hear from old Senior developers were true long time ago, but software changes and (usually) old performance problems are being solved.&lt;br&gt;
Now, when I hear something like "A is slow, use B", I write a short program to compare A with B. Is B really good? By what cost? Is A really much worse than B? May A be improved? And, usually, I get contrary results, where A is same as B or even faster, because my often use case is different from common one.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bonus content : a story about importance of doubt
&lt;/h3&gt;

&lt;p&gt;A remarkable story happened with my brother, who makes games with Godot. He has heard a lot about Vulkan being faster than OpenGL because it's modern, supports parallelism and gives more control on GPU. So, he compared them, and discovered that version of game with Vulkan had much worse performance than same one but using OpenGL.&lt;br&gt;
So what it tells us? Maybe, performance potential of Vulkan is real, maybe it's just marketing. Maybe, there are special cases where Vulkan in Godot is much faster than OpenGL. Maybe it is only so with specific GPU models. Maybe, Godot developers didn't manage to benefit from Vulkan speed yet.&lt;br&gt;
Everything must be tested, compared and applied in supposed field, and words are just words.&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>gamedev</category>
      <category>programming</category>
    </item>
    <item>
      <title>Best programming paradigm?</title>
      <dc:creator>Taqmuraz</dc:creator>
      <pubDate>Fri, 26 Dec 2025 08:20:12 +0000</pubDate>
      <link>https://dev.to/taqmuraz/best-programming-paradigm-3f05</link>
      <guid>https://dev.to/taqmuraz/best-programming-paradigm-3f05</guid>
      <description>&lt;p&gt;There are many programming paradigms, but two of them have most spread : &lt;strong&gt;OOP&lt;/strong&gt; (object-oriented programming) and &lt;strong&gt;FP&lt;/strong&gt; (functional programming). Under &lt;strong&gt;OOP&lt;/strong&gt; I use here Simula design and not Smalltalk one. They are different, so I bring clarity.&lt;br&gt;
Whatever team of programmers you work in, there will prevail one of those two paradigms (today it's usually OOP). &lt;strong&gt;Reactive programming&lt;/strong&gt; found popularity in the modern web and mobile programming. There's also &lt;strong&gt;procedural programming&lt;/strong&gt;, that is rarely used in isolation from other paradigms. Must mention that exist &lt;strong&gt;aspect-oriented programming&lt;/strong&gt;, &lt;strong&gt;agent-oriented programming&lt;/strong&gt;, &lt;strong&gt;stack-oriented programming&lt;/strong&gt;, &lt;strong&gt;event-driven programming&lt;/strong&gt;, &lt;strong&gt;data-driven programming&lt;/strong&gt; and many other paradigms, focused on problems of special fields.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is the purpose of paradigms?
&lt;/h3&gt;

&lt;p&gt;Just using of one or more paradigms doesn't make your code better. Usually it's opposite. Paradigms bring complexity, unnecessary for the most of programming problems. To bring benefits, they require theoretical understanding, experience solving simpler problems with them, and even ability to discard using them when they are not needed.&lt;br&gt;
Most of modern object-oriented and functional languages give means to write procedural imperative code, and purely functional or object-oriented programs are rarely useful.&lt;br&gt;
Many programmers approach paradigms like solving puzzles, making a game inside of the coding process. It's entertaining and gives feeling of doing something smart.&lt;br&gt;
Many of others use paradigms to control and discipline young programmers, who would write an alien-style code impossible to understand for anyone but themselves.&lt;br&gt;
If every programmer would work alone, writing all solutions by himself, there wouldn't be need in paradigms.&lt;br&gt;
So, purpose of paradigms is to limit programmer's thinking, focusing on use of existing practices and standards.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is the best programming paradigm?
&lt;/h3&gt;

&lt;p&gt;Best programming paradigm is one you create yourself &lt;strong&gt;for yourself&lt;/strong&gt;. Only this way you can reach top limits of your productivity and creativity. Of course, you will create better paradigm, if you already are familiar with other ones. If you know well only OOP, most likely anything you will try to invent will become OOP, same about every other paradigm. Ones who really benefit from paradigms are their creators. Many programmers may feel comfortable with them, never meeting potential ceiling of a specific paradigm, but talented minds shouldn't stay there for long.&lt;/p&gt;

&lt;h3&gt;
  
  
  No harm in trying
&lt;/h3&gt;

&lt;p&gt;Paradigms that work bad for one languages may work great with other languages. Try other languages, experiment with ideas, or even invent your own programming language. &lt;strong&gt;Stack-oriented paradigm&lt;/strong&gt; is a bright example of a daring experiment, challenging common understanding of programming. &lt;strong&gt;Forth&lt;/strong&gt; language demonstrates power and elegance of stack programming.&lt;br&gt;
Most of modern programming languages (C#, Java, C, C++) inherit ideas from 60 years old languages, reminding more syntactic sugar for those, not separate languages.&lt;br&gt;
Good knowledge of mathematics would do great work for inventing new programming paradigms and languages.&lt;br&gt;
It's common to think that abstract concepts align badly with hardware, and you should choose between programs performance and abstract ideas.&lt;br&gt;
In fact, translating abstract ideas into assembly language is much more effective than doing so with C or C++ "low-level" mechanisms.&lt;br&gt;
Abstract mathematical ideas give more freedom for portability over different platforms, and resulting assembly code may be better optimized and be much simpler.&lt;/p&gt;

&lt;h3&gt;
  
  
  Final
&lt;/h3&gt;

&lt;p&gt;That's my second article, where I am trying to inspire young programmers to challenge spread ideas, experimenting and investigating. Thanks for reading.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>C and C++ don't give you actual control on memory</title>
      <dc:creator>Taqmuraz</dc:creator>
      <pubDate>Wed, 03 Dec 2025 16:53:31 +0000</pubDate>
      <link>https://dev.to/taqmuraz/c-and-c-dont-give-you-actual-control-on-memory-n91</link>
      <guid>https://dev.to/taqmuraz/c-and-c-dont-give-you-actual-control-on-memory-n91</guid>
      <description>&lt;p&gt;It's common to think that Java, C# and Python have high level of abstraction over hardware, while C and C++ are low level, close to hardware, giving you full control on usage of this exact hardware -- CPU and memory.&lt;br&gt;
And, it's true that you can't allocate memory manually in C#, Java or Python, same as you don't have complete control on what machine does. These languages keep enough distance from hardware, so you, programmer, may forget about memory management and platform-dependent code. Right. But, what about C and C++?&lt;/p&gt;
&lt;h3&gt;
  
  
  C standard and Undefined Behavior
&lt;/h3&gt;

&lt;p&gt;It's also common to know that C and C++ have such thing as undefined behavior (UB).  Usually people call UB something that causes weird bugs or changes program logic when switching platforms. In reality, UB means that if code logic is not defined by standard or explicitly stated as undefined, compiler may generate any code it likes and your program may do whatever compiler developers designed (or made by mistake) to do. Compiler expects that your code never has UB, so when it has, it won't warn you.&lt;br&gt;
Undefined Behavior is not unique for C/C++ standards. Common Lisp standard, for example, also uses term "undefined" to define when compiler developers have freedom designing and optimizing Common Lisp implementation. Though, I am not aware of Common Lisp implementation that leaves such places undefined. In some cases they extend standard, filling "undefined" gaps, in other cases they signal an error when "undefined" scenario happens.&lt;br&gt;
What is really unique about C/C++, is entering "undefined behavior" silently, considering it normal, and moving all responsibility for UB from compiler developers to compiler users. It could be kind of correct, if programs you write would do what you mean them to do. But, C/C++ programs are not the case.&lt;/p&gt;
&lt;h3&gt;
  
  
  Code you write is not the code you run
&lt;/h3&gt;

&lt;p&gt;C/C++ compilers aggressively force bunch of optimizations, most of which are weird, unnecessary, and dangerous for most of programmers. Such optimizations may be enabled with &lt;code&gt;-O&lt;/code&gt;, &lt;code&gt;-O1&lt;/code&gt;, &lt;code&gt;-O2&lt;/code&gt;, &lt;code&gt;-O3&lt;/code&gt; flags, and some of them may be disabled after with own dedicated flags.&lt;br&gt;
Here is an example. Everyone, who programs on C and C++, knows that if pointers have same binary value, they are equal. Now it's time to surprise, because standard says :&lt;br&gt;
C standard 6.5.10.7&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Two pointers compare equal if and only if both are null pointers, both&lt;br&gt;
are pointers to the same object (including a pointer to an object and&lt;br&gt;
a subobject at its beginning) or function, both are pointers to one&lt;br&gt;
past the last element of the same array object, or one is a pointer to&lt;br&gt;
one past the end of one array object and the other is a pointer to the&lt;br&gt;
start of a different array object that happens to immediately follow&lt;br&gt;
the first array object in the address space&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Nothing is said about pointers being just integer byte addresses. Instead, it treats pointers as some abstract entities on level higher than system memory control. Why it doesn't say that pointers are equal if their integer addresses are equal? Simple, because C standard thinks they don't. Don't believe me? Check that :&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;"stdio.h"&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="n"&gt;argv&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="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;y&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;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&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="o"&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;"%p, %p, %s&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="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="s"&gt;"true"&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"false"&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;Simple program. Outputs are clear for all C programmers : two same pointers and true after. Compiling, running, and...yes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;g++ pointers_eq.c &lt;span class="nt"&gt;-o&lt;/span&gt; peq&lt;span class="p"&gt;;&lt;/span&gt; ./peq
0x7ffc4bd50194, 0x7ffc4bd50194, &lt;span class="nb"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, C standard wins? Not yet. We must enable optimizations so miracles start happening.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;g++ &lt;span class="nt"&gt;-O&lt;/span&gt; pointers_eq.c &lt;span class="nt"&gt;-o&lt;/span&gt; peq&lt;span class="p"&gt;;&lt;/span&gt; ./peq
0x7ffffb069694, 0x7ffffb069694, &lt;span class="nb"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Well, we see with own eyes that &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt; addresses are equal, how they aren't? Because, C compiler sees that &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt; pointers have different origins, and assumes that origins are different enough to replace &lt;code&gt;a == b&lt;/code&gt; with &lt;code&gt;false&lt;/code&gt;.&lt;br&gt;
You can tell, that nobody is going to write such a program exploiting stack layout. Then I have another example for you.&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;"stdio.h"&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;fun&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;float&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="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;0&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="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;33&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;a&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="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;union&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="kt"&gt;float&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;ab&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;int&lt;/span&gt; &lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;ab&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;fun&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="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;x&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;"%d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;%f&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&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;x&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two pointers, &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt;, share same memory, but point on different types. Naive logic tells, that after calling &lt;code&gt;fun&lt;/code&gt;, &lt;code&gt;x.a&lt;/code&gt; will have some garbage value and &lt;code&gt;x.b&lt;/code&gt; will have corrupt float value close to &lt;code&gt;3.33&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;g++ two_pointers.c &lt;span class="nt"&gt;-o&lt;/span&gt; tp&lt;span class="p"&gt;;&lt;/span&gt; ./tp
1079320258
3.330002
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, using &lt;code&gt;-O3&lt;/code&gt; flag&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;g++ &lt;span class="nt"&gt;-O3&lt;/span&gt; two_pointers.c &lt;span class="nt"&gt;-o&lt;/span&gt; tp&lt;span class="p"&gt;;&lt;/span&gt; ./tp
10
0.000000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let me explain what happened. C standard has a rule named &lt;code&gt;strict aliasing&lt;/code&gt;. It regulates how program must access values from memory. Behavior is Undefined, when program reads or writes values in the same memory, accessing it by pointers of incompatible types. While optimizing function &lt;code&gt;fun&lt;/code&gt; with &lt;code&gt;-O3,&lt;/code&gt;compiler assumed, that &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt; point to different memory addresses, otherwise program would violate &lt;code&gt;strict aliasing&lt;/code&gt; rule, causing UB. Then, it transformed &lt;code&gt;fun&lt;/code&gt; code to the following :&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="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;fun&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;float&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="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;0&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="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;33&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;10&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;Because &lt;code&gt;*a&lt;/code&gt; is equal to &lt;code&gt;0&lt;/code&gt;, it removes addition and assigns it &lt;code&gt;10&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  No real control
&lt;/h3&gt;

&lt;p&gt;There is a lot more of such cases, most confusing for me is that integer numbers overflow causes UB.&lt;br&gt;
Writing program causing UB is so easy that most of existing C programs have it.&lt;br&gt;
You don't have real control on hardware, because when you start doing things you couldn't do in Java, C# or Python, you go beyond C standard and cause UB. C standard does not provide a sandbox, where you can do whatever you want, nobody to blame but you. Instead, it aggressively modifies your code, assuming you don't step out standard bounds. You may argue that you can avoid using compiler optimizations. Yes, you can, but, C and C++ are shamefully slow without those optimizations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Control is a burden
&lt;/h3&gt;

&lt;p&gt;Language, that would have complete control on memory (let's call it &lt;em&gt;the naive C&lt;/em&gt;), makes programs very difficult to optimize. Usually programs don't use all language means, what allows language developers to optimize such cases (like caching short string values in processor's registry). But, &lt;em&gt;the naive C&lt;/em&gt; allows programmer to modify any memory at any time, any function call may cause side effects, changing any byte of memory it told to change.&lt;br&gt;
&lt;em&gt;The naive C&lt;/em&gt; can't rely on aggressive optimizations, and without them programs won't show performance miracles. Then, writing originally optimized programs would require deeper knowledge of target hardware and intelligence above average (which is rare). And even if you could do so, it would require rewriting all C/C++ standard header files, because their runtime speed depends a lot on aggressive optimizations.&lt;/p&gt;

&lt;h3&gt;
  
  
  C is an abstract, high level language
&lt;/h3&gt;

&lt;p&gt;Reading C standard, I can't erase impression of being distanced away from hardware and reality. It tries to stand close to hardware, but avoids specifying cases of exact close interaction with hardware. Forget that pointers are integer addresses, forget that integer overflow is a thing, forget that memory is just bytes and bits, with no types. Types supposed to be just hints on how to use memory, but in fact they are way more than that.&lt;br&gt;
I don't mention C++ here, because it's even more distant from hardware than C. Most of C++ programmers avoid using raw pointers and C-like structs, preferring complex object-oriented models with overloaded operators/constructors/destructors. Even though C++ "extends" C, they are very different in real world code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Final
&lt;/h3&gt;

&lt;p&gt;C/C++ don't give you to actually control memory, instead they give you to play with memory. They give feeling of control, of making impact on computer's state, and nothing more than that.&lt;br&gt;
Thinking there are operations you can do in C/C++ and can't do in other (better) languages is a spread fallacy, based on lack of experience with other, "foreign" languages/concepts.&lt;br&gt;
I am developing graphics/games/compilers using 0 lines of C/C++ code. It is possible, and it is a pleasure.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Choosing game engine in 2025</title>
      <dc:creator>Taqmuraz</dc:creator>
      <pubDate>Tue, 10 Jun 2025 10:28:59 +0000</pubDate>
      <link>https://dev.to/taqmuraz/choosing-game-engine-in-2025-327p</link>
      <guid>https://dev.to/taqmuraz/choosing-game-engine-in-2025-327p</guid>
      <description>&lt;h2&gt;
  
  
  It's just a tool
&lt;/h2&gt;

&lt;p&gt;Game engine is a tool, so it may be analyzed and rated. In order to do so, we need to understand, what game engine is.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a game engine?
&lt;/h2&gt;

&lt;p&gt;I present my own definition : &lt;strong&gt;game engine is an abstraction layer over separate autonomous systems : graphics, physics, sound, networking, user input, storage&lt;/strong&gt;. Design of such abstraction layer may vary.&lt;br&gt;
&lt;strong&gt;This is what game engine must be&lt;/strong&gt;. Flexible, customizable for almost any needs. Now let's find a definition for modern and popular game engines, such as Unity, Unreal Engine, Godot : &lt;strong&gt;an ecosystem, that provides means for user to create games, including a visual editor for game contents and assets&lt;/strong&gt;.&lt;br&gt;
No access to separate engine systems, you get all systems at once, monolith. More than that, 95% of your game consists not of your code, but files generated by engine and useless anywhere beyond.&lt;br&gt;
Most of game developers don't see problem here. Though, what happens if the publisher of this engine changes terms of license? Or even cancels your free license, asking for an annual subscription? Or forces you to use an updated version of the engine, which breaks your game?&lt;br&gt;
When you make a game with such "game engines", you don't really have a game. You have a product, which, de facto, belongs to the engine publisher.&lt;/p&gt;

&lt;h2&gt;
  
  
  What code architecture is best?
&lt;/h2&gt;

&lt;p&gt;Answering short, best architecture is no architecture.&lt;br&gt;
Limiting yourself with specific programming patterns you decrease your own efficiency. We all love to play puzzles, but doing so while writing game code is not efficient.&lt;br&gt;
Best approach is to avoid building complex abstractions, such as &lt;strong&gt;entity component system (ECS)&lt;/strong&gt;, &lt;strong&gt;MVC&lt;/strong&gt; or &lt;strong&gt;OOP patterns&lt;/strong&gt;.&lt;br&gt;
Don't put strict rules on how your game works, allow each system and each entity to decide what and how to do. Especially if you are an experienced programmer.&lt;br&gt;
With time you may develop your own approaches of writing code without useless complexity.&lt;br&gt;
After you can write games with simple and flexible code, using libraries for graphics, physics, sound, user input -- switching to Unity or Unreal Engine will become obviously over-complicated and inefficient.&lt;/p&gt;

&lt;h2&gt;
  
  
  What programming language is best?
&lt;/h2&gt;

&lt;p&gt;I personally would recommend &lt;strong&gt;dynamically typed languages&lt;/strong&gt; with &lt;strong&gt;FFI (foreign function interface) to C or Java&lt;/strong&gt;.&lt;br&gt;
&lt;strong&gt;Python, Groovy, Lua&lt;/strong&gt; or similar.&lt;br&gt;
Most of game developers explain choosing C++ by it's performance and strict access to memory, though 99% lines of game code don't need that.&lt;br&gt;
That 1% of code you can rewrite on C or Java and call it from a code in &lt;strong&gt;dynamically typed language&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What game engine is best?
&lt;/h2&gt;

&lt;p&gt;Following idea of this article, best game engine is no game engine.&lt;br&gt;
&lt;strong&gt;My definition&lt;/strong&gt; of game engine is very close to that. Game engine must be a thin abstraction layer over separate independent systems, so after you just write game logic.&lt;br&gt;
This way, 100% of your game will belong to you. Also, you can port your game between platforms, change rendering methods or networking technologies, encode resources or leave them accessible to user. It won't die in 5 or 10 years because of Windows update or game engine API changes (as it happened to one of my Unity games).&lt;/p&gt;

&lt;h2&gt;
  
  
  Ambitions
&lt;/h2&gt;

&lt;p&gt;Mostly, game programmers don't understand their desires. What game they want to do. So, they choose a game engine to make an AAA game, usually it's Unity or Unreal Engine. And, usually they end up making 2D platformers or 3D hyper-casual games with low-poly graphics.&lt;br&gt;
If you want to make an AAA game with a photo-realistic graphics by yourself, having no hundreds millions of dollars, think again.&lt;br&gt;
And, even if you do have a lot of money, using Unity or Unreal Engine would be inefficient (look on AAA games we have in 2025).&lt;/p&gt;

&lt;h2&gt;
  
  
  Game engines keep you from thinking
&lt;/h2&gt;

&lt;p&gt;Unity, Unreal Engine and Godot give their users an illusion of comprehension and development, while they don't clearly understand how most of systems work.&lt;br&gt;
I won't say it is bad or good.&lt;br&gt;
Just consider the fact. Game engines are made for amateurs, who are not capable to make even simplest games independently. As popular meme says, "If you are nothing without this game engine, then you shouldn't have it".&lt;/p&gt;

&lt;h2&gt;
  
  
  What then?
&lt;/h2&gt;

&lt;p&gt;Instead of choosing game engine, choose programming language and libraries, and start writing games. You will thank me later.&lt;/p&gt;

</description>
      <category>gamedev</category>
      <category>programming</category>
      <category>python</category>
    </item>
    <item>
      <title>C and C++ are really so fast?</title>
      <dc:creator>Taqmuraz</dc:creator>
      <pubDate>Tue, 03 Dec 2024 17:38:29 +0000</pubDate>
      <link>https://dev.to/taqmuraz/c-and-c-are-really-so-fast-5gf1</link>
      <guid>https://dev.to/taqmuraz/c-and-c-are-really-so-fast-5gf1</guid>
      <description>&lt;p&gt;During all that time I am engaged with programming, I hear that C and C++ are the speed standards. Fastest of the fastest, compiled straight to assembly code, nothing may compete in speed with C or C++. And, nobody seem to challenge that common belief.&lt;/p&gt;

&lt;h2&gt;
  
  
  Computing performance
&lt;/h2&gt;

&lt;p&gt;Arithmetic operations with numbers, obviously, must work significantly faster in C than in any other language. But do they?&lt;br&gt;
Some time ago I decided to write a set of simple benchmarks for many different languages to see, how large difference in speed really is.&lt;br&gt;
Idea was simple : to find the sum of the one billion integer numbers, starting from zero, using straight-forward computing. Some compilers (&lt;strong&gt;rustc&lt;/strong&gt;, for example) replace such simple cycles with formula expression, which, of course, will be evaluated in the constant time. To avoid that with such compilers. I used similar in costs operations with numbers, such as &lt;strong&gt;bitwise or&lt;/strong&gt;.&lt;br&gt;
After I got results, I was surprised very much. My world view turned upside down, and I had to reconsider everything I knew about speed of programming languages.&lt;br&gt;
You may see my results in the table below :&lt;/p&gt;

&lt;p&gt;Linux &lt;strong&gt;64bit&lt;/strong&gt;, &lt;strong&gt;1.1 GHz&lt;/strong&gt; CPU, &lt;strong&gt;4GB&lt;/strong&gt; RAM&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Language&lt;/th&gt;
&lt;th&gt;compiler/version/args&lt;/th&gt;
&lt;th&gt;time&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Rust (&lt;strong&gt;bitwise or&lt;/strong&gt; instead of &lt;strong&gt;+&lt;/strong&gt;)&lt;/td&gt;
&lt;td&gt;rustc 1.75.0 with -O3&lt;/td&gt;
&lt;td&gt;167 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C&lt;/td&gt;
&lt;td&gt;gcc 11.4.0 with -O3&lt;/td&gt;
&lt;td&gt;335 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NASM&lt;/td&gt;
&lt;td&gt;2.15.05&lt;/td&gt;
&lt;td&gt;339 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Go&lt;/td&gt;
&lt;td&gt;1.18.1&lt;/td&gt;
&lt;td&gt;340 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Java&lt;/td&gt;
&lt;td&gt;17.0.13&lt;/td&gt;
&lt;td&gt;345 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Common Lisp&lt;/td&gt;
&lt;td&gt;SBCL 2.4.11.26&lt;/td&gt;
&lt;td&gt;363 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Clojure&lt;/td&gt;
&lt;td&gt;1.10.2&lt;/td&gt;
&lt;td&gt;373 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Python 3&lt;/td&gt;
&lt;td&gt;pypy 3.8.13&lt;/td&gt;
&lt;td&gt;1.6 sec&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Python 3&lt;/td&gt;
&lt;td&gt;cpython 3.10.12&lt;/td&gt;
&lt;td&gt;26  sec&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ruby&lt;/td&gt;
&lt;td&gt;3.0.2p107&lt;/td&gt;
&lt;td&gt;38  sec&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;All tests sources you may find here :&lt;br&gt;
&lt;a href="https://github.com/Taqmuraz/speed-table" rel="noopener noreferrer"&gt;https://github.com/Taqmuraz/speed-table&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, as we may see, &lt;strong&gt;C is not very much faster than Java&lt;/strong&gt;, difference is about &lt;strong&gt;3%&lt;/strong&gt;. Also, we see that other compiled languages are very close in arithmetic operations performance to C (Rust is even faster). Dynamic languages, compiled with &lt;strong&gt;JIT compiler&lt;/strong&gt;, show worse results -- mostly because arithmetic operations are wrapped into dynamically dispatched functions there.&lt;br&gt;
Interpreted dynamic languages &lt;strong&gt;with no JIT compiler&lt;/strong&gt; show worst performance, not a surprise.&lt;/p&gt;

&lt;h2&gt;
  
  
  Memory allocation performance
&lt;/h2&gt;

&lt;p&gt;After that crushing defeat, C fans would say that memory allocation in C is very much faster, because you are allocating it straight from the system, not asking &lt;strong&gt;GC&lt;/strong&gt;.&lt;br&gt;
Now and after I will use &lt;strong&gt;GC&lt;/strong&gt; term both as &lt;strong&gt;garbage collector&lt;/strong&gt; and as &lt;strong&gt;managed heap&lt;/strong&gt;, depending on the context.&lt;br&gt;
So, why people think, that &lt;strong&gt;GC&lt;/strong&gt; is so slow? In fact, &lt;strong&gt;GC&lt;/strong&gt; has pre-allocated memory, and allocation is &lt;strong&gt;simply moving pointer to the right&lt;/strong&gt;. Mostly &lt;strong&gt;GC&lt;/strong&gt; fills allocated memory by zeros using system call, similar to &lt;strong&gt;memset&lt;/strong&gt; from C, so it takes &lt;strong&gt;constant time&lt;/strong&gt;. While memory allocation in C takes undefined time, because it depends on the system and already allocated memory.&lt;br&gt;
But, even considering this knowledge, I could not expect so good results from Java, which you may see in following tables :&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;1.1 GHz&lt;/strong&gt; 2 cores, &lt;strong&gt;4 GB&lt;/strong&gt; RAM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Running tests on &lt;strong&gt;single thread&lt;/strong&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Result format : "Xms-Yms ~Z ms" means tests took from X to Y milliseconds, and Z milliseconds in average&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h4&gt;
  
  
  Allocating integer arrays
&lt;/h4&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;integers array size&lt;/th&gt;
&lt;th&gt;times&lt;/th&gt;
&lt;th&gt;Java 17.0.13 new[]&lt;/th&gt;
&lt;th&gt;C gcc 11.4.0 malloc&lt;/th&gt;
&lt;th&gt;Common Lisp SBCL 2.1.11 make-array&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;10000&lt;/td&gt;
&lt;td&gt;0-1ms, ~0.9ms&lt;/td&gt;
&lt;td&gt;1-2ms, ~1.2ms&lt;/td&gt;
&lt;td&gt;0-4ms, ~0.73ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;32&lt;/td&gt;
&lt;td&gt;10000&lt;/td&gt;
&lt;td&gt;1-3ms, ~1.7ms&lt;/td&gt;
&lt;td&gt;1-3ms, ~1.7ms&lt;/td&gt;
&lt;td&gt;0-8ms, ~2.ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1024&lt;/td&gt;
&lt;td&gt;10000&lt;/td&gt;
&lt;td&gt;6-26ms, ~12ms&lt;/td&gt;
&lt;td&gt;21-46ms, ~26ms&lt;/td&gt;
&lt;td&gt;12-40ms, ~7ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2048&lt;/td&gt;
&lt;td&gt;10000&lt;/td&gt;
&lt;td&gt;9-53ms, ~22ms&lt;/td&gt;
&lt;td&gt;24-52ms, ~28ms&lt;/td&gt;
&lt;td&gt;12-40ms, ~19ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;100000&lt;/td&gt;
&lt;td&gt;0-9ms, ~2ms&lt;/td&gt;
&lt;td&gt;6-23ms, ~9ms&lt;/td&gt;
&lt;td&gt;4-24ms, ~7ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;32&lt;/td&gt;
&lt;td&gt;100000&lt;/td&gt;
&lt;td&gt;0-14ms, ~3ms&lt;/td&gt;
&lt;td&gt;10-15ms, ~11ms&lt;/td&gt;
&lt;td&gt;3-8ms, ~7ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1024&lt;/td&gt;
&lt;td&gt;100000&lt;/td&gt;
&lt;td&gt;0-113ms, ~16ms&lt;/td&gt;
&lt;td&gt;234-1156ms, ~654ms&lt;/td&gt;
&lt;td&gt;147-183ms, ~155ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2048&lt;/td&gt;
&lt;td&gt;100000&lt;/td&gt;
&lt;td&gt;0-223ms, ~26ms&lt;/td&gt;
&lt;td&gt;216-1376ms, ~568ms&lt;/td&gt;
&lt;td&gt;299-339ms, ~307ms&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h4&gt;
  
  
  Allocating instance of the class Person with one integer field.
&lt;/h4&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;how many instances&lt;/th&gt;
&lt;th&gt;Java 17.0.3 new Person(n)&lt;/th&gt;
&lt;th&gt;C++ g++ 11.4.0 new Person(n)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;100000&lt;/td&gt;
&lt;td&gt;0-6ms, ~1.3ms&lt;/td&gt;
&lt;td&gt;4-8ms, ~5ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1 million&lt;/td&gt;
&lt;td&gt;0-11ms, ~2ms&lt;/td&gt;
&lt;td&gt;43-69ms, ~47ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1 billion&lt;/td&gt;
&lt;td&gt;22-50ms, ~28ms&lt;/td&gt;
&lt;td&gt;process terminated&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;All tests sources you may find here :&lt;br&gt;
&lt;a href="https://github.com/Taqmuraz/alloc-table" rel="noopener noreferrer"&gt;https://github.com/Taqmuraz/alloc-table&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There I tested four languages in total : C, C++, Java and Lisp. And, languages with &lt;strong&gt;GC&lt;/strong&gt; always show better results, though I tested them much stricter, than C and C++. For example, in Java I am allocating memory through the virtual function call, so it may not be statically optimized, and in Lisp I am checking first element of the allocated array, so compiler won't skip allocation call.&lt;/p&gt;

&lt;h2&gt;
  
  
  Releasing memory
&lt;/h2&gt;

&lt;p&gt;C fans are still motivated to protect their beliefs, so, they say "Yes, you do allocate memory faster, but you have to release it after!".&lt;br&gt;
True. And, suddenly, &lt;strong&gt;GC&lt;/strong&gt; releases memory faster, than C. But how? Imagine, we made 1 million allocations from &lt;strong&gt;GC&lt;/strong&gt;, but later we have only 1000 objects referenced in our program. And, let's say, those objects are distributed through all of that long span of memory. &lt;strong&gt;GC&lt;/strong&gt; does stack tracing, finding those 1000 "alive" objects, moves them to the previous generation heap peak and puts heap peak pointer after the last of them. That's all.&lt;br&gt;
So, &lt;strong&gt;no matter, how many objects you allocate&lt;/strong&gt;, &lt;strong&gt;GC&lt;/strong&gt;'s work time is decided by &lt;strong&gt;how many of them you keep after&lt;/strong&gt;.&lt;br&gt;
And, in opposite with that, in C you have to release all allocated memory manually, so, if you allocated memory 1 million times, you have to make 1 million release calls as well (or you are going to have memory leaks). That means, &lt;strong&gt;O(1)-O(n)&lt;/strong&gt; of &lt;strong&gt;GC&lt;/strong&gt; against &lt;strong&gt;O(n) or worse&lt;/strong&gt; of C, where &lt;strong&gt;n&lt;/strong&gt; is the number of allocations happened before.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;So, I want to consolidate the victory of garbage collected languages over C and C++. Here is the summary table :&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;demands&lt;/th&gt;
&lt;th&gt;languages with GC&lt;/th&gt;
&lt;th&gt;C/C++&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;arithmetic&lt;/td&gt;
&lt;td&gt;fast with &lt;strong&gt;JIT&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;fast&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;allocating memory&lt;/td&gt;
&lt;td&gt;fast &lt;strong&gt;O(1)&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;slow&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;releasing memory&lt;/td&gt;
&lt;td&gt;fast &lt;strong&gt;O(1)&lt;/strong&gt; best case, &lt;strong&gt;O(n)&lt;/strong&gt; worst case&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;O(n)&lt;/strong&gt; or slower&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;memory safe&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Now we may see -- garbage collection is not a necessary evil, but the best thing we could only wish to have. It gives us safety &lt;strong&gt;and&lt;/strong&gt; performance &lt;strong&gt;both&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tribute to C
&lt;/h2&gt;

&lt;p&gt;While C does show worse results on my tests, it is still an important language and it has own application field. My article does not aim for C rejection or obliteration. C is not bad, it is just not that superior as people think. Many good projects collapsed only because some people decided to use C instead of Java, for example, because they have been told that C is very much faster, and Java is incredibly slow because of garbage collection. C is good, when we write very small and simple programs. But, I would never recommend writing complex programs or games with C.&lt;/p&gt;

&lt;h2&gt;
  
  
  C++ is different
&lt;/h2&gt;

&lt;p&gt;C++ is not simple, is not flexible, has overloaded syntax and too much complicated specification. Programming with C++ you will not implement own ideas but fight with compiler and memory errors 90% of the time.&lt;br&gt;
This article &lt;strong&gt;does aim&lt;/strong&gt; for rejection of C++, because speed and performance are only excuses people give for using this language in software development. Using C++, you are paying with your time, your program performance and your mental health. So, when you have choice between C++ and &lt;strong&gt;any other language&lt;/strong&gt;, I hope you choose the last one.&lt;/p&gt;

</description>
      <category>c</category>
      <category>cpp</category>
      <category>java</category>
      <category>lisp</category>
    </item>
    <item>
      <title>Why do programs wear out?</title>
      <dc:creator>Taqmuraz</dc:creator>
      <pubDate>Mon, 29 Jul 2024 20:31:15 +0000</pubDate>
      <link>https://dev.to/taqmuraz/why-do-programs-wear-out-j58</link>
      <guid>https://dev.to/taqmuraz/why-do-programs-wear-out-j58</guid>
      <description>&lt;h3&gt;
  
  
  What is a program?
&lt;/h3&gt;

&lt;p&gt;Program is a code. A text. How text may wear out?&lt;br&gt;
Have you ever heard about a mathematical theorem that was replaced with a new one? Or, maybe, about a mathematical function becoming obsolete?&lt;br&gt;
Once proven, a mathematical idea is correct forever.&lt;br&gt;
Programs must be same. But, they are not. Why?&lt;br&gt;
The short answer : a lack of mathematics (and abstraction) in modern programming.&lt;br&gt;
Now, let us sort it out.&lt;/p&gt;
&lt;h3&gt;
  
  
  Speed bigotry
&lt;/h3&gt;

&lt;p&gt;Machines become obsolete, we are inventing new technologies and ways of production. Software becomes outdated with its target hardware. But, why does it have target hardware? To work as fast as possible, to exploit as much implementation details as it may reach. A small abstraction level would bring loss in speed, but give independence from hardware. Written once, used forever.&lt;/p&gt;
&lt;h3&gt;
  
  
  Program or programmer : one must die
&lt;/h3&gt;

&lt;p&gt;Well, we have C# and Java, that have &lt;strong&gt;abstraction layer&lt;/strong&gt; over hardware. So, they would be good to write programs once and use forever?&lt;br&gt;
Yes, they could be...but.&lt;br&gt;
We don't really need programs that would work forever.&lt;br&gt;
Try to imagine that. 99% of software engineering would become pointless. All those C# and Java developers would lose their jobs.&lt;br&gt;
Fortunately for them, they have OOP. &lt;strong&gt;Software killer&lt;/strong&gt;.&lt;br&gt;
OOP was invented bad for a purpose. We are killing our software constantly, because we are getting paid for programming new software.&lt;br&gt;
Eventual death for any program is essential for us, &lt;strong&gt;otherwise we would have no money&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  How does OOP kill programs
&lt;/h3&gt;

&lt;p&gt;Classes are perfect for making code rigid and useless.&lt;br&gt;
Perfect example -- you may meet such classes as &lt;strong&gt;Vector2&lt;/strong&gt;, &lt;strong&gt;Vector3&lt;/strong&gt;, &lt;strong&gt;Matrix3&lt;/strong&gt;, &lt;strong&gt;Matrix4&lt;/strong&gt;, &lt;strong&gt;Quaternion&lt;/strong&gt; in any library, related to computer graphics or mathematical modeling.&lt;br&gt;
Why don't everyone use only one best implementation, like everyone does with &lt;strong&gt;int&lt;/strong&gt;, &lt;strong&gt;float&lt;/strong&gt;, &lt;strong&gt;char&lt;/strong&gt;, &lt;strong&gt;byte&lt;/strong&gt;? Answer is simple -- primitive types are not classes.&lt;br&gt;
They were designed once to be used forever, and you can't achieve such design level with classes.&lt;br&gt;
Classes are designed to make program "disabled" everywhere, excepting limited purpose, that is demanded by current moment.&lt;br&gt;
&lt;strong&gt;OOP&lt;/strong&gt; is about resolving thousand times the same problem, implementing brand new (&lt;strong&gt;one more bad&lt;/strong&gt;) solution.&lt;/p&gt;
&lt;h3&gt;
  
  
  Way out
&lt;/h3&gt;

&lt;p&gt;Well, let us imagine, how would look an immortal &lt;strong&gt;vector&lt;/strong&gt; implementation? First, it must have no mutable state. Same as &lt;strong&gt;string&lt;/strong&gt;, &lt;strong&gt;int&lt;/strong&gt;, &lt;strong&gt;char&lt;/strong&gt;. You can't mutate them, you can only create new.&lt;br&gt;
And, we already have such vector implementation in &lt;strong&gt;Lisp&lt;/strong&gt; (&lt;strong&gt;Clojure&lt;/strong&gt;) :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight clojure"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;; same as (vector 1 2 3)&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;; vector deconstruction&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;println&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;; [1 2 3]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;println&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;; 1 2 3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, we don't need classes. More than that : we don't even need to declare functions to calculate dot product, or vectors sum, or transposed matrix :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight clojure"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;apply&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;map&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;; a and b dot product&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;mapv&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;; a and b sum&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;vector&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;; 3x2 matrix from a and b&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;apply&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mapv&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;vector&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;; transposing matrix e&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is no &lt;strong&gt;OOP&lt;/strong&gt;, code is simple, flexible and it will never face necessity to be edited. Written once, used forever. &lt;/p&gt;

&lt;h3&gt;
  
  
  Does not fit for business
&lt;/h3&gt;

&lt;p&gt;I frequently hear, that functional approaches do not fit for business. That &lt;strong&gt;OOP&lt;/strong&gt; is only one and best choice for software design.&lt;br&gt;
Well, there is a particle of truth. &lt;strong&gt;OOP&lt;/strong&gt; is truly best choice for business, if you ask programmers. And, it is a deadly mistake, if you consider interests of business itself.&lt;br&gt;
Do you want to pay programmers for doing same job hundred times? Or you want them to resolve actual business problems?&lt;br&gt;
Choice is clear.&lt;/p&gt;

</description>
      <category>development</category>
      <category>analytics</category>
      <category>oop</category>
    </item>
    <item>
      <title>C++ : speed obsession in the game industry</title>
      <dc:creator>Taqmuraz</dc:creator>
      <pubDate>Fri, 26 Jul 2024 16:05:24 +0000</pubDate>
      <link>https://dev.to/taqmuraz/speed-obsession-in-the-game-industry-1p4i</link>
      <guid>https://dev.to/taqmuraz/speed-obsession-in-the-game-industry-1p4i</guid>
      <description>&lt;h3&gt;
  
  
  When do we really need speed
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;C++&lt;/strong&gt; became a standard language for games and graphics software a long time ago. And, there was actual reason -- work with &lt;strong&gt;real-time graphics&lt;/strong&gt; and &lt;strong&gt;physics&lt;/strong&gt; requires high performance. Processing geometry, managing buffers, matrix calculations - all of that does take time.&lt;br&gt;
But, what about high-level logic? Game mechanics, user interface, storage management, network requests? &lt;strong&gt;Stability and safety&lt;/strong&gt; are much more demanded there, than speed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Responsibility distribution
&lt;/h3&gt;

&lt;p&gt;We may implement performance-demanding functions in  a compiled language, such as C++, and call them from a program written in a dynamic language, such as Python.&lt;br&gt;
But, today we already have well-documented and easy to use libraries for Python (&lt;strong&gt;pygame, pyopengl, pyassimp, pybullet, numpy&lt;/strong&gt;), that are implemented primarily on C/C++ and do provide functions for heavy calculations, or physics/graphics in particular. We may never face necessity to implement such libraries on our own.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is C++ the only choice?
&lt;/h3&gt;

&lt;p&gt;It is generally accepted, that garbage collected languages, such as Java or C#, are slower than C++ and don't really meet requirements for heavy calculations. &lt;strong&gt;This is, of course, not true&lt;/strong&gt;.&lt;br&gt;
C++ may overcome Java or C# in performance by 20-30% in some special cases, but when it comes to &lt;strong&gt;runtime abstractions&lt;/strong&gt;, such as dynamic function dispatch, languages interaction, asynchronous tasks, text or abstract collections management, Java and C# show much higher efficiency than C++.&lt;br&gt;
Also, we may run our Python programs on the same runtime with Java or C#, using Jython or IronPython. It brings a lot of benefits, such as &lt;strong&gt;shared garbage-collected memory&lt;/strong&gt;, types system and easy &lt;strong&gt;access to C# or Java libraries&lt;/strong&gt; right out of the box. On Java are implemented such nice dynamic languages as &lt;strong&gt;Clojure and Groovy&lt;/strong&gt;, that have complete access to Java Class Library and share previously mentioned benefits.&lt;/p&gt;

&lt;h3&gt;
  
  
  What really makes influence on performance?
&lt;/h3&gt;

&lt;p&gt;Today personal computers are much faster, than 15-20 years ago. But, most of desktop programs or games do not work as fast as expected (despite that they are still mostly implemented on C/C++). Today we need good &lt;strong&gt;algorithms&lt;/strong&gt; and &lt;strong&gt;effective approaches&lt;/strong&gt; much more, than just language speed. Function with &lt;strong&gt;constant complexity&lt;/strong&gt; on Python is more preferable than function with &lt;strong&gt;linear complexity&lt;/strong&gt; on C. To paint 100 trees by 15 lines of Python code is more preferable than to paint 500 trees by 300 lines of C++ code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Care about game, not language
&lt;/h3&gt;

&lt;p&gt;It is not really important, what language you use, when you don't have any game made, right?&lt;br&gt;
Making game on C++ is much more &lt;strong&gt;demanding and exhausting&lt;/strong&gt;, than doing same on Python or Ruby. When you would make &lt;strong&gt;1 game with C++&lt;/strong&gt;, you would make &lt;strong&gt;10 games with Python&lt;/strong&gt;. When you would make &lt;strong&gt;5 games with Python&lt;/strong&gt;, it would be &lt;strong&gt;0 games with C++&lt;/strong&gt;.&lt;br&gt;
Let us care about games and fun, otherwise what the point?&lt;/p&gt;

</description>
      <category>cpp</category>
      <category>python</category>
      <category>java</category>
      <category>csharp</category>
    </item>
    <item>
      <title>Python : advanced way to reduce the amount of repetitive code</title>
      <dc:creator>Taqmuraz</dc:creator>
      <pubDate>Sat, 24 Feb 2024 18:44:36 +0000</pubDate>
      <link>https://dev.to/taqmuraz/python-advanced-way-to-reduce-the-amount-of-repetitive-code-4c25</link>
      <guid>https://dev.to/taqmuraz/python-advanced-way-to-reduce-the-amount-of-repetitive-code-4c25</guid>
      <description>&lt;p&gt;Let us imagine, that you have some list of objects.&lt;br&gt;
You need to call one specific function on each object in that list.&lt;br&gt;
Here is an example :&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="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Dog&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;sound&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Woof&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Cat&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;sound&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Meow&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Cow&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;sound&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Mooo&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;animals&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nc"&gt;Cat&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nc"&gt;Cow&lt;/span&gt;&lt;span class="p"&gt;()]&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;animals&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="nf"&gt;sound&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nice. Now, imagine that each &lt;strong&gt;animal&lt;/strong&gt; object must have at least two functions : &lt;code&gt;sound&lt;/code&gt; and &lt;code&gt;insight&lt;/code&gt;.&lt;br&gt;
&lt;code&gt;sound&lt;/code&gt; does write line to the output stream and returns nothing, &lt;code&gt;insight&lt;/code&gt; does nothing but returns a &lt;strong&gt;string&lt;/strong&gt;.&lt;br&gt;
We would like to call &lt;code&gt;sound&lt;/code&gt; in each function and to print list containing &lt;code&gt;insight&lt;/code&gt; &lt;strong&gt;string&lt;/strong&gt; of each animal :&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="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Dog&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;sound&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Woof&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;insight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&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;Humans are best!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Cat&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;sound&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Meow&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;insight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&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;Humans are slaves of cats&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Cow&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;sound&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Mooo&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;insight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&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;Humans are violent indeed&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="n"&gt;animals&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nc"&gt;Cat&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nc"&gt;Cow&lt;/span&gt;&lt;span class="p"&gt;()]&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;animals&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="nf"&gt;sound&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Insights : &lt;/span&gt;&lt;span class="si"&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="nf"&gt;insight&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;animals&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It may seem nice, but we use &lt;strong&gt;for loop&lt;/strong&gt; each time we need to do the same thing with each animal. How may we reduce number of such syntax constructs? We could declare &lt;strong&gt;wrapper-class&lt;/strong&gt; to wrap list of animals, intercepting function calls and returning lists of results :&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="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PluralAnimal&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;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;animals&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;animals&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;animals&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;sound&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;animals&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="nf"&gt;sound&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;insight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&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="nf"&gt;insight&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;animals&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;plural&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;PluralAnimal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;animals&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plural&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sound&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Insights : &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;plural&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;insight&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Looks much better? Yes, but I have one concern : now we have to declare such &lt;strong&gt;wrapper-class&lt;/strong&gt; for each case of use. For animals, vehicles, employees we have to declare &lt;code&gt;PluralAnimal&lt;/code&gt;, &lt;code&gt;PluralVehicle&lt;/code&gt;, &lt;code&gt;PluralEmployee&lt;/code&gt;.&lt;br&gt;
How may we avoid that?&lt;/p&gt;
&lt;h2&gt;
  
  
  Dynamic function call interception
&lt;/h2&gt;

&lt;p&gt;If we want to access some attribute of the object in runtime, using name of that attribute, we may use &lt;code&gt;getattr&lt;/code&gt; function :&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="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Example&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;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello, example!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;obj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Example&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;func&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getattr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;func&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;# output : Hello, example!
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let us write &lt;strong&gt;wrapper-class&lt;/strong&gt;, using &lt;code&gt;getattr&lt;/code&gt; function :&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="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Plural&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;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;objs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;objs&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__getattr__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;getattr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;o&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="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objs&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;func&lt;/span&gt;

&lt;span class="n"&gt;plural&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Plural&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;animals&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plural&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sound&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Insights : &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;plural&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;insight&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;That's all for today. Thank you for reading, &lt;strong&gt;I would be pleased to read and answer your comments&lt;/strong&gt;. See you next time.&lt;/p&gt;

</description>
      <category>python</category>
      <category>functional</category>
      <category>oop</category>
      <category>pattern</category>
    </item>
    <item>
      <title>OOP via FP : functional nature of classes and objects</title>
      <dc:creator>Taqmuraz</dc:creator>
      <pubDate>Wed, 07 Feb 2024 22:31:45 +0000</pubDate>
      <link>https://dev.to/taqmuraz/oop-via-fp-functional-nature-of-classes-and-objects-1i3m</link>
      <guid>https://dev.to/taqmuraz/oop-via-fp-functional-nature-of-classes-and-objects-1i3m</guid>
      <description>&lt;h2&gt;
  
  
  Topic for today
&lt;/h2&gt;

&lt;p&gt;Today I would like to tell you, why such &lt;strong&gt;OOP&lt;/strong&gt; concepts as &lt;strong&gt;classes&lt;/strong&gt; and &lt;strong&gt;objects&lt;/strong&gt; are just particular cases of &lt;strong&gt;functions&lt;/strong&gt;, using examples of code in &lt;strong&gt;Ruby&lt;/strong&gt; and in my own language, &lt;strong&gt;Jena&lt;/strong&gt;.&lt;br&gt;
Why &lt;strong&gt;Ruby&lt;/strong&gt;? Despite that it is an object-oriented language, it also provides a &lt;strong&gt;good foundation for functional approaches&lt;/strong&gt;. In that, I hope, my article will convince you, though it is a secondary point today.&lt;/p&gt;
&lt;h2&gt;
  
  
  Jena references
&lt;/h2&gt;

&lt;p&gt;If you are not familiar with &lt;strong&gt;Jena&lt;/strong&gt;, you may read dedicated &lt;a href="https://dev.to/taqmuraz/jena-one-more-programming-language-1llc"&gt;article about this language&lt;/a&gt;.&lt;br&gt;
If you want to try &lt;strong&gt;Jena&lt;/strong&gt;, you are welcome to visit its &lt;a href="https://github.com/Taqmuraz/JenaLang"&gt;github repository&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Object as a table of functions
&lt;/h2&gt;

&lt;p&gt;Let us watch on an example of a class declaration in Ruby :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Human&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;walk&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"walking!"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;stand&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"standing!"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Human&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;walk&lt;/span&gt;
&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stand&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Class is a popular idea, that has wide spread in modern languages, such as &lt;strong&gt;Python&lt;/strong&gt;, &lt;strong&gt;Java&lt;/strong&gt;, &lt;strong&gt;C#&lt;/strong&gt;, &lt;strong&gt;C++&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;What exactly do we see here?&lt;br&gt;
Class &lt;code&gt;Human&lt;/code&gt; seem to be a function, that creates objects.&lt;br&gt;
But, also, object &lt;code&gt;h&lt;/code&gt; here has two functions, and we may call them by their names.&lt;/p&gt;

&lt;p&gt;May we try to implement the same behaviour, using only functions? Let us try :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;Human&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="ss"&gt;:walk&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"walking!"&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="ss"&gt;:stand&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"standing!"&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;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Human&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:walk&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;
&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:stand&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I feel important to explain, what I am doing here. Function &lt;code&gt;Human&lt;/code&gt; creates a hash-map, where symbols are associated with &lt;br&gt;
anonymous functions. Yes, &lt;code&gt;:walk&lt;/code&gt; and &lt;code&gt;:stand&lt;/code&gt; are symbols, it is a part of &lt;strong&gt;Ruby&lt;/strong&gt; syntax, very uncommon in other languages.&lt;br&gt;
As you may see, I chose &lt;strong&gt;Ruby&lt;/strong&gt; for a reason. This language has one thing in common with &lt;strong&gt;Jena&lt;/strong&gt; -- symbol literals.&lt;/p&gt;
&lt;h2&gt;
  
  
  Honesty and clarity
&lt;/h2&gt;

&lt;p&gt;More honest implementation of an object through a function would be this one :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;Human&lt;/span&gt;
  &lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="ss"&gt;:walk&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"walking!"&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="ss"&gt;:stand&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"standing!"&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;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;key&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="n"&gt;h&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Human&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:walk&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;
&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:stand&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we are not using a dedicated syntax, &lt;strong&gt;hiding object implementation&lt;/strong&gt; behind a function. You may say, that &lt;code&gt;Human&lt;/code&gt; class code does look better, and code with functions is verbose and complicated. It is true, because syntax of &lt;strong&gt;Ruby&lt;/strong&gt; (and most of other object-oriented languages) is &lt;strong&gt;designed to make use of classes and objects easy&lt;/strong&gt;, sacrificing for that ease and clarity of functions.&lt;/p&gt;

&lt;p&gt;Let me demonstrate the same behaviour, implemented in &lt;strong&gt;Jena&lt;/strong&gt; :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;Human&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;.walk:()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;println&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"walking!"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;.stand:()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;println&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"standing!"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;h&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Human()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;h.walk()&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;h.stand()&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code does &lt;strong&gt;exactly&lt;/strong&gt; the same thing that the last &lt;strong&gt;Ruby&lt;/strong&gt; code does : creates a &lt;code&gt;Human&lt;/code&gt; function, that returns table of functions, calls it, storing result as &lt;code&gt;h&lt;/code&gt; and, after that, calls &lt;code&gt;walk&lt;/code&gt; and &lt;code&gt;stand&lt;/code&gt; functions, taking them from table, using &lt;code&gt;.walk&lt;/code&gt; and &lt;code&gt;.stand&lt;/code&gt; symbols as keys.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mutable state
&lt;/h2&gt;

&lt;p&gt;You may say, that objects have a mutable state, and, sometimes, it may be very useful. Methods may change attributes of an object, but may functions do the same?&lt;br&gt;
Short answer is yes. Let us write some &lt;strong&gt;Ruby&lt;/strong&gt; code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Human&lt;/span&gt;
  &lt;span class="vi"&gt;@x&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;
    &lt;span class="vi"&gt;@x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;moveLeft&lt;/span&gt;
    &lt;span class="vi"&gt;@x&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;moveRight&lt;/span&gt;
    &lt;span class="vi"&gt;@x&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;status&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"x = &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="vi"&gt;@x&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&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="n"&gt;h&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Human&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;moveLeft&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;moveRight&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;moveRight&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;How would look the same code in our approach, where object is a function?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;Human&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;0&lt;/span&gt;
  &lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="ss"&gt;:walkLeft&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;do&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;1&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="ss"&gt;:walkRight&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;do&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;1&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="ss"&gt;:status&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"x = &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&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;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;key&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="n"&gt;h&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Human&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:walkLeft&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;
&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:walkRight&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;
&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:walkRight&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;
&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:status&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And, in &lt;strong&gt;Jena&lt;/strong&gt; it would be implemented next way :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;Human&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;box(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;.walkLeft:()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;x.apply(&lt;/span&gt;&lt;span class="mi"&gt;-1&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;.walkRight:()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;x.apply&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;.status:()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;print&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"x = "&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;(x.get))&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;h&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Human()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;h.walkLeft()&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;h.walkRight()&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;h.walkRight()&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;h.status()&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dynamic languages, such as &lt;strong&gt;Ruby&lt;/strong&gt;, provide us flexibility in control of program state, &lt;strong&gt;we don't have to explicitly allocate memory&lt;/strong&gt; for a mutable state, &lt;strong&gt;local variables already do present a state&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Performance
&lt;/h2&gt;

&lt;p&gt;Our function-based objects have one serious flaw : low performance. We are building a functions table &lt;strong&gt;each time we create a new object&lt;/strong&gt;, can we optimize that? Yes, of course we can, all we need is to &lt;strong&gt;separate an object state from functions table&lt;/strong&gt; :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="vg"&gt;$table&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="ss"&gt;:walkLeft&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:x&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;:walkRight&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:x&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;:status&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"x = &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:x&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&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;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;Human&lt;/span&gt;
  &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;:x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="vg"&gt;$table&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&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="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Human&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:walkLeft&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;
&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:walkRight&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;
&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:walkRight&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;
&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:status&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And &lt;strong&gt;Jena&lt;/strong&gt; :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;Human&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;table&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;.walkLeft:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;obj&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;obj.x.apply(&lt;/span&gt;&lt;span class="mi"&gt;-1&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;.walkRight:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;obj&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;obj.x.apply&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;.status:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;obj&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;print&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"x = "&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;(obj.x.get))&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;state&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;.x:(box&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;key&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;table&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;key&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;state&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;h&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Human()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;h.walkLeft()&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;h.walkRight()&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;h.walkRight()&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;h.status()&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Looks overloaded? I agree. But, we may simplify that. Let us create a &lt;strong&gt;class factory function&lt;/strong&gt;, so we may distract from building table and state functions each time we want to create a class :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;Class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;table&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;constructor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;args&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;state&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;constructor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;args&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;key&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;arg&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;table&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;key&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;args&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;state&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;arg&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;Human&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;.walkLeft:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;obj&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;obj.x.apply(&lt;/span&gt;&lt;span class="mi"&gt;-1&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;.walkRight:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;obj&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;obj.x.apply&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;.status:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;obj&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;println(&lt;/span&gt;&lt;span class="s2"&gt;"x = "&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;(obj.x.get))&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;args&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;.x:(box&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;(args.x))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;h&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Human&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;.x:&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;h.walkLeft()&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;h.walkRight()&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;h.walkRight()&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;h.status()&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you see, now we even can pass constructor arguments to build our object, it is a &lt;strong&gt;full complete object-oriented class&lt;/strong&gt;, implemented by &lt;strong&gt;functions only&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Other reasons to choose functions over objects
&lt;/h2&gt;

&lt;p&gt;For many of readers solution with classes looks more familiar and pleasant, but only because you already have experience using that solution.&lt;br&gt;
&lt;strong&gt;Functions are coming from a mathematical world&lt;/strong&gt;, their &lt;strong&gt;abstraction and distraction from implementation details&lt;/strong&gt; are attractive indeed. Functions have simple and consistent concept behind, while objects are very specific and domain-oriented.&lt;br&gt;
Finally, class in most of the object-oriented languages is a &lt;strong&gt;separate syntax&lt;/strong&gt;, what brings more complexity and involves a &lt;strong&gt;special logic for constructors, methods and attributes&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That's all for today. &lt;strong&gt;Thank you for reading, and please, share your thoughts in comments&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>functional</category>
      <category>lisp</category>
      <category>ruby</category>
      <category>oop</category>
    </item>
    <item>
      <title>C#: functional approaches explained solving one specific problem</title>
      <dc:creator>Taqmuraz</dc:creator>
      <pubDate>Sun, 04 Feb 2024 17:15:00 +0000</pubDate>
      <link>https://dev.to/taqmuraz/c-functional-approaches-explained-solving-one-specific-problem-20k2</link>
      <guid>https://dev.to/taqmuraz/c-functional-approaches-explained-solving-one-specific-problem-20k2</guid>
      <description>&lt;p&gt;Today I would like to tell you about functional approaches. Why they are good, and why they are simple.&lt;/p&gt;

&lt;h2&gt;
  
  
  We need to write some code
&lt;/h2&gt;

&lt;p&gt;Let us imagine, that we have some array of strings. It may be an array of names :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var items = new[]
{
    "Peter",
    "Albert",
    "John",
    "Jim",
    "Pavel",
    "Robert"
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We would like to choose only names with a unique first character : "Peter", "Albert", "John", "Robert".&lt;br&gt;
In &lt;strong&gt;C#&lt;/strong&gt; we have &lt;strong&gt;LINQ&lt;/strong&gt; to operate collections, and it has &lt;code&gt;Distinct&lt;/code&gt; function. But, this function would compare full names, when we need to compare only their first characters.&lt;br&gt;
&lt;strong&gt;.NET&lt;/strong&gt; has &lt;code&gt;DistinctBy&lt;/code&gt; function starting from &lt;strong&gt;.NET 6&lt;/strong&gt;. But, what if we use another versions of &lt;strong&gt;.NET&lt;/strong&gt;, or even &lt;strong&gt;.NET framework&lt;/strong&gt;?&lt;br&gt;
We are going to write an own &lt;code&gt;DistinctBy&lt;/code&gt; implementation then.&lt;/p&gt;
&lt;h2&gt;
  
  
  Procedural approach
&lt;/h2&gt;

&lt;p&gt;Many times, in someone else's code, I met exactly this procedural implementation :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using System.Collections.Generic;

static class EnumerableExtensions
{
    public static IEnumerable&amp;lt;TSource&amp;gt; DistinctBy&amp;lt;TSource, TKey&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector)
    {
        HashSet&amp;lt;TKey&amp;gt; keys = new HashSet&amp;lt;TKey&amp;gt;();
        foreach(var item in source)
        {
            var key = keySelector(item);
            if(!keys.Contains(key))
            {
                keys.Add(key);
                yield return item;
            }
        }
    }
}
class Program
{
    static void Main()
    {
        var items = new[] { "Peter", "Albert", "John", "Jim", "Pavel", "Robert"};
        Console.WriteLine(string.Join(", ", items.DistinctBy(n =&amp;gt; n[0])));
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It does work, and it is not so bad.&lt;br&gt;
But, now we have two separate implementations of almost the same thing : &lt;code&gt;Distinct&lt;/code&gt; and &lt;code&gt;DistinctBy&lt;/code&gt; functions. How may we solve that?&lt;/p&gt;
&lt;h2&gt;
  
  
  Object-oriented approach
&lt;/h2&gt;

&lt;p&gt;It may seem obvious to use a special overload of the &lt;code&gt;Distinct&lt;/code&gt; function, that accepts &lt;code&gt;IEqualityComparer&lt;/code&gt; parameter. This way we have a control over how the &lt;code&gt;Distinct&lt;/code&gt; function compares names. Let us implement &lt;code&gt;IEqualityComparer&lt;/code&gt; interface with a necessary logic and apply it to our solution :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using System.Collections.Generic;
using System;

class FirstCharacterComparer : IEqualityComparer&amp;lt;string&amp;gt;
{
    public bool Equals(string x, string y)
    {
        return x[0] == y[0];
    }

    public int GetHashCode(string obj)
    {
        return obj[0].GetHashCode();
    }
}

class Program
{
    static void Main()
    {
        var items = new[] { "Peter", "Albert", "John", "Jim", "Pavel", "Robert"};
        Console.WriteLine(string.Join(", ", items.Distinct(new FirstCharacterComparer())));
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Much better? I agree, but, how many classes we would create to implement such a small logic? If we would need to compare last characters, we would create a &lt;code&gt;LastCharacterComparer&lt;/code&gt; class? And, to compare first decimal symbols of two numbers, we would create a &lt;code&gt;FirstDecimalSymbolComparer&lt;/code&gt;? Object-oriented approach does give us a flexibility, but class declarations are too verbose.&lt;/p&gt;

&lt;h2&gt;
  
  
  Semi-functional approach
&lt;/h2&gt;

&lt;p&gt;Let us describe our problem in a mathematical way.&lt;br&gt;
We have some set &lt;strong&gt;X&lt;/strong&gt; as an input (array of strings), a selector function &lt;code&gt;X -&amp;gt; Y&lt;/code&gt; (where &lt;strong&gt;Y&lt;/strong&gt; is a set of first characters respectively) and a distinct function &lt;code&gt;(X, (X -&amp;gt; Y)) -&amp;gt; Z&lt;/code&gt; (where &lt;strong&gt;Z&lt;/strong&gt; is a set of names with unique first symbols).&lt;br&gt;
A selector function, in our case, is &lt;code&gt;s =&amp;gt; s[0]&lt;/code&gt;, a distinct function is &lt;code&gt;System.LINQ.Enumerable.Distinct&lt;/code&gt;.&lt;br&gt;
Now, keeping this model in mind, let us implement and apply &lt;code&gt;IEqualityComparer&lt;/code&gt; again :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using System.Collections.Generic;
using System;

class KeyComparer&amp;lt;TSource, TKey&amp;gt; : IEqualityComparer&amp;lt;TSource&amp;gt;
{
    Func&amp;lt;TSource, TKey&amp;gt; keySelector;

    public KeyComparer(Func&amp;lt;TSource, TKey&amp;gt; keySelector)
    {
        this.keySelector = keySelector;
    }

    public bool Equals(TSource x, TSource y)
    {
        return keySelector(x).Equals(keySelector(y));
    }

    public int GetHashCode(TSource obj)
    {
        return keySelector(obj).GetHashCode();
    }
}

class Program
{
    static void Main()
    {
        var items = new[] { "Peter", "Albert", "John", "Jim", "Pavel", "Robert"};
        Console.WriteLine(string.Join(", ", items.Distinct(new KeyComparer&amp;lt;string, char&amp;gt;(s =&amp;gt; s[0]))));
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yes, now we have a common solution to make a set with unique items from an input set, comparing content by its property.&lt;br&gt;
But, expression &lt;code&gt;new KeyComparer&amp;lt;string, char&amp;gt;(s =&amp;gt; s[0])&lt;/code&gt; looks redundant. &lt;strong&gt;C#&lt;/strong&gt; &lt;strong&gt;compiler can't infer generic type arguments for a constructor call&lt;/strong&gt;, what increases amount of code.&lt;/p&gt;
&lt;h2&gt;
  
  
  Functional approach
&lt;/h2&gt;

&lt;p&gt;Final step to perfection is to replace a constructor call with something else, or wrap it into something.&lt;br&gt;
An obvious solution -- to wrap in into a &lt;code&gt;DistinctBy&lt;/code&gt; function. &lt;strong&gt;Compiler will easily infer generic type arguments&lt;/strong&gt;, we don't even need to think anymore.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;static class EnumerableExtensions
{
    public static IEnumerable&amp;lt;TSource&amp;gt; DistinctBy&amp;lt;TSource, TKey&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TKey&amp;gt; keySelector)
    {
        return source.Distinct(new KeyComparer&amp;lt;TSource, TKey&amp;gt;(keySelector));
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And, updated &lt;code&gt;Main&lt;/code&gt; method :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;static void Main()
{
    var items = new[] { "Peter", "Albert", "John", "Jim", "Pavel", "Robert"};
        Console.WriteLine(string.Join(", ", items.DistinctBy(s =&amp;gt; s[0])));
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Same approach may be used in many other cases. It keeps code simple, and does not repeat already existing one.&lt;br&gt;
Also, we found today one more evidence that &lt;strong&gt;static functions are better, than constructors&lt;/strong&gt;. If you did not read yet my article about that -- &lt;a href="https://dev.to/taqmuraz/modern-java-do-we-need-explicit-class-declarations-5409"&gt;you may read it&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;That's all for today. &lt;strong&gt;Thanks for reading this article, would be nice to read your thoughts in comments&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>functional</category>
      <category>dotnet</category>
      <category>csharp</category>
      <category>linq</category>
    </item>
    <item>
      <title>Modern Java - do we need explicit class declarations?</title>
      <dc:creator>Taqmuraz</dc:creator>
      <pubDate>Sun, 31 Dec 2023 15:10:39 +0000</pubDate>
      <link>https://dev.to/taqmuraz/modern-java-do-we-need-explicit-class-declarations-5409</link>
      <guid>https://dev.to/taqmuraz/modern-java-do-we-need-explicit-class-declarations-5409</guid>
      <description>&lt;p&gt;When we develop a &lt;strong&gt;public API&lt;/strong&gt;, we hope it will live long or forever.&lt;br&gt;
Do we? Then why do we still write and use &lt;strong&gt;public constructors&lt;/strong&gt;? They &lt;strong&gt;do not present any abstraction&lt;/strong&gt;. Once you mentioned in your code some constructors, you nailed them to your program for eternity.&lt;/p&gt;

&lt;p&gt;In this article I will explain, how to create objects in a better way, without declaring constructors or classes explicitly.&lt;/p&gt;
&lt;h2&gt;
  
  
  We need to write a program
&lt;/h2&gt;

&lt;p&gt;Now, let us imagine we want to write a program that would paint the following image :&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--z8ak670v--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rysz8l022zggzept2agm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--z8ak670v--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rysz8l022zggzept2agm.png" alt="Image description" width="200" height="200"&gt;&lt;/a&gt;&lt;br&gt;
Let us write code then.&lt;br&gt;
First, we have to declare common abstractions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.awt.Graphics2D;
interface Drawing
{
    void draw(Graphics2D graphics);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Good enough.&lt;br&gt;
Now we may write a code that uses our &lt;code&gt;Drawing&lt;/code&gt; interface to paint something into image :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;static BufferedImage paint(int width, int height, Drawing drawing)
{
    var image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    drawing.draw((Graphics2D)image.getGraphics());
    return image;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that, we need an implementation for a &lt;strong&gt;circle drawing&lt;/strong&gt; :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Color;
class Circle implements Drawing
{
    Point center;
    int radius;
    Color color;
    Circle(Point center, int radius, Color color)
    {
        this.center = center;
        this.radius = radius;
        this.color = color;
    }
    @Override
    public void draw(Graphics2D graphics)
    {
        graphics.setColor(color);
        int dr = radius &amp;lt;&amp;lt; 1;
        graphics.fillOval(center.x - radius, center.y - radius, dr, dr);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now a &lt;strong&gt;box drawing&lt;/strong&gt; :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.awt.Graphics2D;
import java.awt.Color;
import java.awt.Rectangle;
class Box implements Drawing
{
    Rectangle rect;
    Color color;
    Box(Rectangle rect, Color color)
    {
        this.rect = rect;
        this.color = color;
    }
    @Override
    public void draw(Graphics2D graphics)
    {
        graphics.setColor(color);
        graphics.fillRect(rect.x, rect.y, rect.width, rect.height);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As we see, our &lt;code&gt;paint&lt;/code&gt; method does accept only one &lt;code&gt;Drawing&lt;/code&gt; object, so, we need an implementation that would &lt;strong&gt;combine many drawings into one&lt;/strong&gt; :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Scene implements Drawing
{
    Drawing[] drawings;

    Scene(Drawing... drawings)
    {
        this.drawings = drawings;
    }

    @Override
    public void draw(Graphics2D graphics)
    {
        for(var drawing : drawings) drawing.draw(graphics);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And, all we have left is to write the &lt;code&gt;main&lt;/code&gt; function :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public static void main(String[] args) throws Throwable
{
    var file = new File(args[0]);

    int width = 200;
    int height = 200;

    var drawing = new Scene(
        new Box(new Rectangle(0, 0, width, height), Color.WHITE),
        new Circle(new Point(100, 100), 50, Color.RED),
        new Box(new Rectangle(25, 25, 100, 50), Color.GREEN));
    var image = paint(width, height, drawing);
    ImageIO.write(image, "png", file);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It took &lt;strong&gt;85&lt;/strong&gt; lines of code. This code is flexible, maintainable, readable. But, don't you see its redundant parts? Almost &lt;strong&gt;30%&lt;/strong&gt; of lines are about &lt;strong&gt;fields and constructors declaration&lt;/strong&gt;.&lt;br&gt;
Also, we have repeated code here : &lt;code&gt;Graphics2D.setColor&lt;/code&gt; calls.&lt;br&gt;
&lt;strong&gt;How may we improve this code?&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Static functions are better than constructors
&lt;/h2&gt;

&lt;p&gt;What constructor is? A function, that we call to create a new object. Wait...a function, that we call to create a new object...&lt;strong&gt;do we need constructors at all&lt;/strong&gt;?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Java&lt;/strong&gt; has a brilliant syntaxes - anonymous class expression and lambda expression. Using such expressions we may write code without declaring any classes.&lt;/p&gt;
&lt;h2&gt;
  
  
  What we are going to do
&lt;/h2&gt;

&lt;p&gt;Here is an example :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface FloatFunction
{
    float apply(float a);
}
class SumFloatFunction implements FloatFunction
{
    float addition;
    SumFloatFunction(float addition)
    {
        this.addition = addition;
    }
    @Override
    public float apply(float a)
    {
        return a + addition;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let us replace class declaration with a static function declaration inside of the &lt;code&gt;FloatFunction&lt;/code&gt; interface :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface FloatFunction
{
    float apply(float a);

    static FloatFunction sum(float addition)
    {
        return a -&amp;gt; a + addition;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do you see, how small our code now is?&lt;br&gt;
More than that, now we may see all &lt;code&gt;FloatFunction&lt;/code&gt; interface implementations available - we don't have to read documentation each time to refresh information about existing implementations. All what we need is declared in the one place.&lt;/p&gt;

&lt;p&gt;Using our new approach, let us change solution with &lt;code&gt;Drawing&lt;/code&gt; interface.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface Drawing
{
    void draw(Graphics2D graphics);

    static Drawing box(Rectangle rect, Color color)
    {
        return graphics -&amp;gt;
        {
            graphics.setColor(color);
            graphics.fillRect(rect.x, rect.y, rect.width, rect.height);
        };
    }
    static Drawing circle(Point center, int radius, Color color)
    {
        return graphics -&amp;gt;
        {
            graphics.setColor(color);
            int dr = radius &amp;lt;&amp;lt; 1;
            graphics.fillOval(center.x - radius, center.y - radius, dr, dr);
        };
    }
    static Drawing scene(Drawing... drawings)
    {
        return graphics -&amp;gt;
        {
            for(var drawing : drawings) drawing.draw(graphics);
        };
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And &lt;code&gt;main&lt;/code&gt; function also has changes :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public static void main(String[] args) throws Throwable
{
    var file = new File(args[0]);

    int width = 200;
    int height = 200;

    var drawing = Drawing.scene(
        Drawing.box(new Rectangle(0, 0, width, height), Color.WHITE),
        Drawing.circle(new Point(100, 100), 50, Color.RED),
        Drawing.box(new Rectangle(25, 25, 100, 50), Color.GREEN));
    var image = paint(width, height, drawing);
    ImageIO.write(image, "png", file);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Looks much better? Right. And that was only a first step.&lt;/p&gt;

&lt;h2&gt;
  
  
  Methods with default implementation
&lt;/h2&gt;

&lt;p&gt;As I said earlier, I don't like we have &lt;code&gt;Graphics2D.setColor&lt;/code&gt; calls repeated. If we would paint 1000 boxes of the same color, do we need to call &lt;code&gt;setColor&lt;/code&gt; method 1000 times? No.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What then we may do?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let us create a wrapping function, that will change color as many times as we need :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;default Drawing ofColor(Color color)
{
    return graphics -&amp;gt;
    {
        graphics.setColor(color);
        draw(graphics);
    };
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And, we are going to change &lt;code&gt;Drawing&lt;/code&gt; static functions as well, because now they have no business with &lt;code&gt;Color&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;interface Drawing
{
    void draw(Graphics2D graphics);

    static Drawing box(Rectangle rect)
    {
        return graphics -&amp;gt;
        {
            graphics.fillRect(rect.x, rect.y, rect.width, rect.height);
        };
    }
    static Drawing circle(Point center, int radius)
    {
        return graphics -&amp;gt;
        {
            int dr = radius &amp;lt;&amp;lt; 1;
            graphics.fillOval(center.x - radius, center.y - radius, dr, dr);
        };
    }
    static Drawing scene(Drawing... drawings)
    {
        return graphics -&amp;gt;
        {
            for(var drawing : drawings) drawing.draw(graphics);
        };
    }
    default Drawing ofColor(Color color)
    {
        return graphics -&amp;gt;
        {
            graphics.setColor(color);
            draw(graphics);
        };
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then code that creates many boxes of the same color would look like that :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;static Drawing manyBoxes(Color color, Rectangle... rects)
{
    var boxes = Stream.of(rects).map(Drawing::box).toArray(Drawing[]::new);
    return Drawing.scene(boxes).ofColor(color);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;I don't propose to always avoid use of classes. We may need them to describe &lt;strong&gt;data structures or program entries&lt;/strong&gt;. But, anywhere else, I would like to use lambda or anonymous class expressions only.&lt;/p&gt;

&lt;p&gt;After all, functions let us to decouple from a real program structure and to forget about exact implementation. You can't redirect a constructor call, but you can redirect a function call.&lt;br&gt;
When you develop a large product, &lt;strong&gt;you can't rename class or change its accessibility&lt;/strong&gt;, if it had once a public constructor. &lt;strong&gt;Give self more comfort and space, use functions instead of constructors&lt;/strong&gt;.&lt;br&gt;
That's all for today, thanks if you read this article to the end.&lt;br&gt;
&lt;strong&gt;Please, share your thoughts in comments.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>java</category>
      <category>functional</category>
      <category>designpatterns</category>
      <category>architecture</category>
    </item>
  </channel>
</rss>
