<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: MiguelMJ</title>
    <description>The latest articles on Forem by MiguelMJ (@miguelmj).</description>
    <link>https://forem.com/miguelmj</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%2F449565%2Fc9a30852-1361-49c8-aa13-c385fd0c0b33.png</url>
      <title>Forem: MiguelMJ</title>
      <link>https://forem.com/miguelmj</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/miguelmj"/>
    <language>en</language>
    <item>
      <title>Código humano</title>
      <dc:creator>MiguelMJ</dc:creator>
      <pubDate>Thu, 25 Dec 2025 12:04:05 +0000</pubDate>
      <link>https://forem.com/miguelmj/codigo-humano-5dm9</link>
      <guid>https://forem.com/miguelmj/codigo-humano-5dm9</guid>
      <description>&lt;p&gt;Una perspectiva poco compartida sobre la naturaleza del código es lo que se puede saber de una persona por su manera de escribirlo. Algo así tenía en mente cuando escribí sobre &lt;a href="https://dev.to/miguelmj/programming-as-a-conversation-how-the-communicative-scheme-is-also-applied-in-the-written-code-itself-5378"&gt;la programación como conversación&lt;/a&gt;, pero en aquel entonces no había leído tanto código escrito por IA. No voy a entrar en cuestiones como la productividad, la calidad del código ni métricas software o buenas prácticas; estas incumben a la industria, y ahora quiero hablar de la programación como actividad humana.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Creo que puedo recordar cada vez que he sentido la impresión de otra persona al leer su código&lt;/strong&gt;. Y hablo de pasar a relacionarse con el código de manera cotidiana; no leer un fichero, una o dos funciones, sino a leer, día tras días, las líneas escritas por otro; a comprender un sistema de su autoría. Al hablar de textos narrativos, poéticos, diarios, cartas… la presencia de la persona nos llega a través de un lenguaje humano, el mismo lenguaje que usaría para hablarnos por la calle. Sin embargo, en el código se mezclan las imposiciones de un lenguaje formal y la definición de un algoritmo. Aun así, la personalidad del programador asoma en el conocimiento de sus herramientas, la comprensión del problema a solucionar y la forma de expresar estas soluciones, incluso cuando está mediada por convenciones y estándares. A menudo, a los programadores nos gusta que el código tenga cierto aspecto, cierta manera de leerse; eso después se convierte en convenciones de estilo, pero nace como una elección personal que persigue una subjetiva legibilidad. Incluso la ausencia de esta intención construye una identidad. Me pasa incluso cuando leo mi propio código, que tengo una reminiscencia de cómo era yo cuando lo escribí; qué me interesaba probar, con qué técnicas había adquirido soltura, o qué conocimientos no tenía todavía.&lt;/p&gt;

&lt;p&gt;Por eso, he tenido la sensación, algunas veces, de que &lt;strong&gt;se crea una pequeña intimidad en esa lectura de código&lt;/strong&gt;. Es una pequeña ventana a cómo funciona la maquinaria mental de otra persona. Cuando se trabaja en proyectos en equipo, llegas a reconocer de un vistazo al autor de trozos de código sin necesidad de preguntar. Y esta forma de conocimiento, a mí, me resulta entrañable incluso cuando maldigo a la persona que escribió semejante espagueti. Porque otras veces, si es un buen código, el autor te comunica cómo programar mejor; y cuando no lo es, llegas a compartir la confusión que pudo tener que soportar, o como mínimo, a empatizar con su nivel de experiencia, porque todos hemos empezado en algún lado.&lt;/p&gt;

&lt;p&gt;Cuando estoy programando un sistema un poco más complejo, me da la sensación de estar sosteniendo un pequeño edificio con la mente, y que al pasarlo a código, lo dejo plasmado en él. Como cualquier proceso técnico creativo, en ocasiones tiene un punto solitario. Y al leer el código de otra persona, al ver su elección de arquitectura, qué prácticas usa y cuáles no, voy reconstruyendo el edificio que él/ella sostuvo mentalmente en algún momento. Es como ponerse en sus zapatos. Al hacer eso muchas veces, adquieres familiaridad con su forma de trabajo, reconoces cómo estructura el código, cómo nombra variables y funciones, cómo segrega responsabilidades, cuándo decide dejar de anidar condiciones, qué estructuras de datos prefiere, cómo le gusta procesar colecciones de datos, sus inclinaciones dentro de los paradigmas de programación…&lt;/p&gt;

&lt;p&gt;El estilo de cada programador/a se parece a una especie de caligrafía, un acento al hablar o una colección de muletillas e incluso de palabrotas. No es algo que deba importar en la industria, pero sí es algo que, a veces, aparece. Y quería hablar de ello, porque desde fuera, parece que el código está libre de la humanidad de sus programadores; y no hay nada más lejos de la realidad. En la era de los LLMs, esto está cambiando; y no hago un juicio de valor, pero sí hay algo quería visibilizar. Muchas actividades humanas, aunque se deleguen en muchos casos o se automaticen para el consumo, no van a desaparecer de la vida de quienes las practican, por el simple hecho de que son inherentemente humanas; y &lt;strong&gt;como tecnólogo, siempre me ha parecido que programar es una de esas actividades&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>spanish</category>
    </item>
    <item>
      <title>Human code</title>
      <dc:creator>MiguelMJ</dc:creator>
      <pubDate>Thu, 25 Dec 2025 11:57:54 +0000</pubDate>
      <link>https://forem.com/miguelmj/human-code-1loe</link>
      <guid>https://forem.com/miguelmj/human-code-1loe</guid>
      <description>&lt;p&gt;A little-shared perspective on the nature of code is what you can learn about a person from the way they write it. I had something like this in mind when I wrote about &lt;a href="https://dev.to/miguelmj/programming-as-a-conversation-how-the-communicative-scheme-is-also-applied-in-the-written-code-itself-5378"&gt;Programming as Conversation&lt;/a&gt;, but at that time I hadn’t read as much code written by AI. I’m not going to get into issues such as productivity, code quality, software metrics or best practices; these are matters for the industry, and now I want to talk about programming as a human activity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I think I can remember every time I have felt the impression of another person when reading their code&lt;/strong&gt;. And I am talking about interacting with code on a daily basis; not reading a file or a pair of functions, but reading, day after day, the lines written by another person; understanding a system they have created. When we talk about narrative texts, poetry, diaries, letters… the presence of the person reaches us through human language, the same language they would use to talk to us on the street. However, in code, the impositions of a formal language and the definition of an algorithm are mixed together. Even so, the programmer’s personality shines through in their knowledge of their tools, their understanding of the problem to be solved, and the way they express these solutions, even when mediated by conventions and standards. Often, we programmers like the code to have a certain look, a certain way of reading; this then becomes style conventions, but it starts out as a personal choice pursuing some subjective legibility. Even the absence of this intention builds an identity. It happens to me even when I read my own code, that I feel a reminiscence of how I was when I wrote it; what I was interested in trying out, what techniques I had become proficient in, or what knowledge I did not yet have.&lt;/p&gt;

&lt;p&gt;That’s why I’ve sometimes felt that &lt;strong&gt;reading code creates a small sense of intimacy&lt;/strong&gt;. It’s a little window into how another person’s mind works. When working on team projects, you can recognise the author of pieces of code at a glance without having to ask. And I find this form of knowledge endearing, even when I curse the person who wrote such spaghetti code. Because other times, if it’s good code, the author tells you how to program better; and when it’s not, you get to share the confusion they may have had to endure, or at least empathise with their level of experience, because we all started somewhere.&lt;/p&gt;

&lt;p&gt;When I am programming a slightly more complex system, I feel like I am holding a small building in my mind, and when I translate it into code, I leave it imprinted on it. Like any creative technical process, it can sometimes feel lonely. And when I read someone else’s code, when I see their choice of architecture, what practices they use and which they don’t, I reconstruct the building that they held in their mind at some point. It’s like putting yourself in their shoes. By doing this many times, you become familiar with their way of working, you recognise how they structure the code, how they name variables and functions, how they segregate responsibilities, when they decide to stop nesting conditions, what data structures they prefer, how they like to process data collections, their inclinations within programming paradigms…&lt;/p&gt;

&lt;p&gt;Each programmer’s style is like a kind of calligraphy, a speech accent or a collection of catchphrases and even swear words. It’s not something that should matter in the industry, but it is something that sometimes just appears. And I wanted to talk about it, because from the outside, it seems that code is free from the humanity of its programmers; and nothing could be further from the truth. In the era of LLMs, this is changing; and I’m not making a value judgement, but there is something I wanted to highlight. Many human activities, even if they are delegated in many cases or automated for consumption, are not going to disappear from the lives of those who practise them, simply because they are inherently human; and &lt;strong&gt;as a technologist, I have always felt that programming is one of those activities&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>programming</category>
    </item>
    <item>
      <title>Programming as a conversation - How the communicative scheme is also applied in the written code itself</title>
      <dc:creator>MiguelMJ</dc:creator>
      <pubDate>Sat, 11 May 2024 14:28:09 +0000</pubDate>
      <link>https://forem.com/miguelmj/programming-as-a-conversation-how-the-communicative-scheme-is-also-applied-in-the-written-code-itself-5378</link>
      <guid>https://forem.com/miguelmj/programming-as-a-conversation-how-the-communicative-scheme-is-also-applied-in-the-written-code-itself-5378</guid>
      <description>&lt;p&gt;Coding conventions, documentation practices and nomenclature styles are commonly subject of strong opinions among developers. In my case, I really thought for years that the best way to write software had to exist, even if it was not mine. And, surely, there are objective criteria that make code better, from the best use of idioms to the readability-performance tradeoffs. However, I've come to think that &lt;strong&gt;understanding code as a conversation where subjectivity takes a role&lt;/strong&gt; might be the most valuable approach to write software, rather than one that assumes universal metrics.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Cover image by &lt;a href="https://www.pexels.com/photo/two-women-looking-at-the-code-at-laptop-1181263/" rel="noopener noreferrer"&gt;Christina Morillo&lt;/a&gt; from Pexels&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Introduction - Programming as talking to a machine
&lt;/h2&gt;

&lt;p&gt;When I was learning to program, my university teachers used to present programming as a way to communicate with a computer. Compilers are translators between high level programming languages (closer to human languages) and machine language, binary encoded in metal circuits; therefore, &lt;strong&gt;to program is to talk with a computer&lt;/strong&gt;. Obviously, this definition is not wrong, but in the software development industry context, it is clearly reductionist, as it ignores many other factors involved in development. However, this is precisely the approach that most academics I've worked with take, deliberately or not.&lt;/p&gt;

&lt;h2&gt;
  
  
  Academy and industry
&lt;/h2&gt;

&lt;p&gt;The reason for this difference between industry and academy is the fundamental understanding of what programming is and, as a consequence, what life cycle of software is.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In the academy, programming is a tool to build systems that model a theoretical problem, that solve particular tasks, that embody specific demonstrations or proofs&lt;/strong&gt;. Projects evolve from simple scripts to bigger systems, usually written collaboratively between professors, doctoral candidates and inexperienced, unsupervised, recently graduated students, neither of whom uses to care much about long term maintainability. This, along with a general lack of supervision, results in partial or absolute absence of tests, absence of style conventions, inconsistent coupling levels across the architecture and other usually considered bad consequences.&lt;/p&gt;

&lt;p&gt;On the other hand, &lt;strong&gt;industry software development takes programming as a tool to build products that need to meet requisites set by clients and changing markets&lt;/strong&gt;. Projects might last for many years and will be developed, extended, refactored and maintained by very different developers over the course of time. In the industry, this software is alive and evolving. Therefore, its architecture must be able to adapt and grow by the hand of whole teams that may also change over time.&lt;/p&gt;

&lt;p&gt;For this reason, projects that come from the academy to find a place in the market will eventually face a complete readjustment if they want to survive. However, not all software is meant to end up in the market. Not all projects are born to live long lives, to be built collaboratively or to evolve at some point. If a piece of software works and no one is meant to ever touch it again, apart from maybe the original creator, then complex architectures, coding conventions and best-practices can be an unnecessary overhead. &lt;strong&gt;It is very important to identify the expected cycle of life for a program&lt;/strong&gt;, to be objective about how it will need to be maintained.&lt;/p&gt;

&lt;h2&gt;
  
  
  Programming as a dialogue
&lt;/h2&gt;

&lt;p&gt;The first time I was told my code sucked was in an issue on one of my open source projects, where the developer in question told me, with no offense intended, that the unreadable code made it hard to contribute. I always tried to make my code readable, how could someone not understand it? So I went to the mentioned piece of code and, what a shame, it was ten times more unreadable than I remembered: obscure variable names, deep levels of nesting in control structures, walls of code without either comments or subroutine division... Basically, they were right.&lt;/p&gt;

&lt;p&gt;I didn't take time to improve it. In the end, it's an open source library used by very few people and contributed by even less, and I had better things to do. But a year or two later, I landed a new job and my new co-worker told me, during my first code review: &lt;strong&gt;&lt;em&gt;"You are not used to writing code in a team, right?".&lt;/em&gt;&lt;/strong&gt; Since he had seen I was willing to learn, he had a very good attitude towards me and showed me the clean code practices that the team followed. However, that particular question stuck with me. It was not my first job, but it was, indeed, the first time I was going to write code, on which my income would depend, that other people would be working with.&lt;/p&gt;

&lt;p&gt;I came to the realization that, when I wrote code without supervision (for personal projects or in a solo team) my inner discourse would go on like a &lt;strong&gt;monologue&lt;/strong&gt;. As I internalized at university, I was just talking to the computer. After that code review and more that came after, I was required to have an inner discourse that worked as a &lt;strong&gt;dialogue&lt;/strong&gt;. I had to talk to the machine but also to my teammates. But, how is that done through code?&lt;/p&gt;

&lt;h2&gt;
  
  
  Langue vs Parole
&lt;/h2&gt;

&lt;p&gt;In linguistics, there's a difference between &lt;em&gt;langue&lt;/em&gt; and &lt;em&gt;parole&lt;/em&gt;. The first one is the common code use to communicate with others (the languagSince he had seen that I was well disposed, he had a very good attitude towards me and showed me the clean code practices that the team followed.e), and the second one is the particular way it's used by an individual. For this difference, if you happen to be in the bus and listen to a conversation between two close friends, you might hear a lot of things that you don't understand, even though they are speaking the same language as you. Not only because you may lack context, but because (oversimplifying) their specific use of language might be alien to you. The same happens with code.&lt;/p&gt;

&lt;p&gt;If you alone are communicating with the computer, there is no problem to write code as a monologue. As far as I know, this is pretty frequent, for example, in indie game development. Some great indie games, like Undertale, are said to have terrible codebases. Given that many indie developers learn to code during the development of the game itself, it is not something strange. But, in the end, it doesn't matter at all. &lt;strong&gt;The game is finished, machines run it and people play it.&lt;/strong&gt; &lt;strong&gt;There would be absolutely no point in rewriting the game only for it to follow industry best-practices&lt;/strong&gt;. The same happens with &lt;em&gt;some&lt;/em&gt; university projects. Once you have processed a dataset and extracted what you needed, or once you have tested the algorithm you were developing, a new architecture won't make any improvement on your desired results.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr1cx0whguo9hafnxy2pt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr1cx0whguo9hafnxy2pt.png" alt="Diagram of a developer, software and a computer" width="490" height="180"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, if you work in a team and follow this "monologue approach", you will end up with &lt;strong&gt;serious&lt;/strong&gt; problems. And when I say team, I also mean open source contributors or future maintainers for solo projects. Interpret it in a broad sense. The codebase receives input from several channels that, the same way as in the bus example, exclude others from the conversation. &lt;strong&gt;Your teammates will need to understand the language and your use of it to comprehend the code&lt;/strong&gt;. This will be aggravated with each new contributor that joins the project.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0rfppmwz5rwy7q0vsq6c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0rfppmwz5rwy7q0vsq6c.png" alt="Diagram of a team of developers, software and a computer" width="410" height="361"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To avoid that, conventions are needed. Because, let's be real: even the most self-explanatory code can reach a point of complexity that require outside explanations, at the very least for inexperienced members of the team. Every developer that says otherwise is just assuming a level of experience and knowledge of industry standards that not everybody (starting with me) has reached yet. So, the conventions must include design patterns, code styling, nomenclature and even testing philosophy. &lt;strong&gt;Choosing the conventions that adjust the best to both the project requirements and the used technologies, and effectively communicating them to the other developers (usually via documentation or onboarding processes), can make the definitive difference for a project in the long term.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn9j3vcm47nbro21ahk9k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn9j3vcm47nbro21ahk9k.png" alt="Diagram of a team of developers, conventions, software and a computer" width="610" height="361"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Needless to say, it is not all about choosing the perfect conventions, that, to start with, don't exist. Unclear or changing requirements, too simple or too complex architectures, and many other factors are also determinants of this long term maintainability. Again, software development is a complex activity with many factors involved.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion - Ensuring conventions
&lt;/h2&gt;

&lt;p&gt;As in any form of communication, the code conventions chosen for a team and a project may be sometimes interpreted in different ways or with varying levels of rigor by each programmer. Subjectivity is like that. Therefore, &lt;strong&gt;code reviews become an inseparable part of the said conventions' proper application&lt;/strong&gt;. What is legible for you may (and will) not be legible for others. So having more eyes on the code is a good way to make it more accessible. Both giving and receiving feedback on written code must be handled with humanity and an open mind.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>productivity</category>
      <category>career</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>When numbers don't make sense</title>
      <dc:creator>MiguelMJ</dc:creator>
      <pubDate>Thu, 09 Mar 2023 16:30:00 +0000</pubDate>
      <link>https://forem.com/miguelmj/when-numbers-dont-make-sense-10gi</link>
      <guid>https://forem.com/miguelmj/when-numbers-dont-make-sense-10gi</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Most of the time, basic arithmetic is pretty simple and intuitive. Even working with powers and roots isn't that much of a headache. However, the IEEE standard for floating-point numbers includes special values that can mess things up: NaN (Not a Number), positive infinity and negative infinity. In fact, most algebraic properties of real numbers are no longer valid. The only purpose of this post is to show some cases I found interesting, where these values produce counterintuitive results.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Cover image by &lt;a href="https://unsplash.com/@armand_khoury" rel="noopener noreferrer"&gt;Armand Khoury&lt;/a&gt; from Unsplash&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Standard behavior of NaN and Infinity
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;For all x: &lt;code&gt;NaN &amp;gt; x&lt;/code&gt; is false.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For all x: &lt;code&gt;NaN &amp;lt; x&lt;/code&gt; is false.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For all x: &lt;code&gt;NaN == x&lt;/code&gt; is false.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For all x: &lt;code&gt;NaN != x&lt;/code&gt; is true.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For all x except NaN and +Infinity: &lt;code&gt;+Infinity &amp;gt; x&lt;/code&gt; is true.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For all x except Nan and -Infinity: &lt;code&gt;-Infinity &amp;lt; x&lt;/code&gt; is true.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;Infinity / Infinity = NaN&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;Infinity * 0 == NaN&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;Infinity - Infinity == NaN&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Any other arithmetic operation between a number and Infinity results in Infinity (with a possible change of sign).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Any other arithmetic operation between a number (or Infinity) and NaN results in NaN.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Everything I will tell you from now is trivially deduced from understanding the list above; in other words, if you understand all its implications, I won't tell you much new. Anyway, I think it is interesting to review some side effects that may escape from us when we don't keep them in mind.&lt;/p&gt;

&lt;h2&gt;
  
  
  Broken properties
&lt;/h2&gt;

&lt;p&gt;The following is a non-exhaustive list of properties that we use to expect while programming, but are no longer true due to the existence of NaN and Infinity. I will provide the statement of the property (which doesn't hold) and then a piece of code in JavaScript and Python that implements a check for it, followed by a call that returns false.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note&lt;/em&gt;: JavaScript produces &lt;code&gt;NaN&lt;/code&gt; and &lt;code&gt;Infinity&lt;/code&gt; values easily, not only because they are native values but because they result from regular operations (&lt;code&gt;Math.sqrt(-1)&lt;/code&gt; or &lt;code&gt;1/0&lt;/code&gt;). In the case of Python, they are implemented in the &lt;code&gt;math&lt;/code&gt; library (&lt;code&gt;math.nan&lt;/code&gt; and &lt;code&gt;math.inf&lt;/code&gt;) and operations that would produce them (&lt;code&gt;math.sqrt(-1)&lt;/code&gt; or &lt;code&gt;1/0&lt;/code&gt;) will raise an exception. For this reason, assume the following header in each Python snippet.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;math&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;nan&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;inf&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Disclaimer&lt;/em&gt;: The snippets of JavaScript will also fail with values like strings or objects. I'm not trying to make any point about errors in JavaScript. The point is about the NaN and Infinity values, which belong to numeric types in any language with full support for the IEEE standard.&lt;/p&gt;




&lt;p&gt;Now, behold the fall of the tautologies.&lt;/p&gt;

&lt;h3&gt;
  
  
  Identity
&lt;/h3&gt;

&lt;p&gt;Let's start with the most obvious and painful.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;identity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nf"&gt;identity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;NaN&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;identity&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="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;

&lt;span class="nf"&gt;identity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nan&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Some of the following are direct results of this.&lt;/p&gt;

&lt;h3&gt;
  
  
  A list can't contain elements that aren't equal to any element
&lt;/h3&gt;

&lt;p&gt;Sorry for the apparent redundancy in the statement: check the examples to see what I mean.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;checkIncludesEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)){&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;checkIncludesEqual&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;NaN&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="kc"&gt;NaN&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;checkIncludesEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arr&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="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;any&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;

&lt;span class="nf"&gt;checkIncludesEqual&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nan&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;nan&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The max value of a list is greater than or equal to the rest
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;checkMaxIsGE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;maxVal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;every&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;maxVal&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nf"&gt;checkMaxIsGE&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="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;NaN&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;checkMaxIsGE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;maxVal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maxVal&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;checkMaxIsGE&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="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nan&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The min value of a list is lesser than or equal to the rest
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;checkMinIsLE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;minVal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;every&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="nx"&gt;minVal&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nf"&gt;checkMinIsLE&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="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;NaN&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;checkMinIsLE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;minVal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;minVal&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;checkMinIsLE&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="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nan&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Dividend equals divisor times quotient
&lt;/h3&gt;

&lt;p&gt;This is the first we learn about division. &lt;code&gt;D / d = Q&lt;/code&gt; implies &lt;code&gt;D = Q * d&lt;/code&gt;. Well... no more. This example can only be shown in JavaScript because Python prevents division by zero.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;checkDdQ&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dividend&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;divisor&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="nx"&gt;quotient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;dividend&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;divisor&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;dividend&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nx"&gt;quotient&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;divisor&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nf"&gt;checkDdQ&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;checkDdQ&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;Infinity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The square of a value is either greater than or equal to itself or less than one
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;checkSquareIsGE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;  &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nf"&gt;checkSquareIsGE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;NaN&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;checkSquareIsGE&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="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

&lt;span class="nf"&gt;checkSquareIsGE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nan&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;checkSquareIsGE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inf&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  "Less than or equal to" is equivalent to "Not greater than"
&lt;/h3&gt;

&lt;p&gt;I find this particularly disturbing, not sure why.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;checkLEQisNGT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&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="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;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="nf"&gt;checkLEQisNGT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;NaN&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;checkLEQisNGT&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="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;

&lt;span class="nf"&gt;checkLEQisNGT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nan&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  A value divided by itself equals one
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;checkBetweenSelfIsOne&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&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="nf"&gt;checkBetweenSelfIsOne&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;NaN&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;checkBetweenSelfIsOne&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;Infinity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;checkBetweenSelfIsOne&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="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

&lt;span class="nf"&gt;checkBetweenSelfIsOne&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nan&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;checkBetweenSelfIsOne&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inf&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  A value minus itself equals zero
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;checkMinusSelfIsZero&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&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="p"&gt;}&lt;/span&gt;
&lt;span class="nf"&gt;checkMinusSelfIsZero&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;NaN&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;checkMinusSelfIsZero&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;Infinity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;checkMinusSelfIsZero&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="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

&lt;span class="nf"&gt;checkMinusSelfIsZero&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nan&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;checkMinusSelfIsZero&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inf&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  A value times zero equals zero
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;checkTimesZero&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

&lt;span class="nf"&gt;checkTimesZero&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;NaN&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;checkTimesZero&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;Infinity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;checkTimesZero&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="k"&gt;return&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="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

&lt;span class="nf"&gt;checkTimesZero&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nan&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;checkTimesZero&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inf&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;These last two have an interesting side effect too. One would expect that &lt;code&gt;1 / (x-x)&lt;/code&gt; and &lt;code&gt;1 / (x * 0)&lt;/code&gt; to result in Infinity. However, when &lt;code&gt;x&lt;/code&gt; is Infinity, they result in NaN. Don't you feel dizzy yet?&lt;/p&gt;

&lt;h2&gt;
  
  
  Bonus fun fact!
&lt;/h2&gt;

&lt;p&gt;Hey, while working on this article I found something interesting about square roots in Python. As I stated earlier, Python raises an exception if you try to compute the square root of a negative number. But &lt;a href="https://realpython.com/python-complex-numbers/" rel="noopener noreferrer"&gt;Python implements complex numbers&lt;/a&gt; natively so if you use the power operator (&lt;code&gt;**&lt;/code&gt;) instead, it returns a valid result!&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="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;math&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;sqrt&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;sqrt&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="p"&gt;)&lt;/span&gt;
&lt;span class="nc"&gt;Traceback &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;most&lt;/span&gt; &lt;span class="n"&gt;recent&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;stdin&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;module&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nb"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;math&lt;/span&gt; &lt;span class="n"&gt;domain&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&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="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;6.123233995736766e-17&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mf"&gt;1j&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The perfect result would have been &lt;code&gt;(0+1j)&lt;/code&gt; but due to floating-point precision issues, instead of &lt;code&gt;0&lt;/code&gt; you have a very, very small number. I hope you found it interesting too!&lt;/p&gt;

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

&lt;p&gt;Semantically sound code is much less prone to errors and reduces the need to be constantly catching exceptions. I hope these examples have served as a reminder that we cannot neglect special numeric values or take for granted many seemingly intuitive properties that, if overlooked, can cause apparently correct code to exhibit undesired behavior.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>python</category>
      <category>mathematics</category>
    </item>
    <item>
      <title>Programming mathematical objects</title>
      <dc:creator>MiguelMJ</dc:creator>
      <pubDate>Thu, 26 Jan 2023 17:31:42 +0000</pubDate>
      <link>https://forem.com/miguelmj/programming-mathematical-objects-1n3n</link>
      <guid>https://forem.com/miguelmj/programming-mathematical-objects-1n3n</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;This post is divided into two main parts. In the first one, I'm going to introduce mathematical objects and mathematical applications. It is programmer-oriented, but I assume some level of math knowledge. In the second part, I will tell my personal experience discovering and researching previous work on this same topic.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note&lt;/em&gt;: In case you know it, the &lt;a href="https://www.wolfram.com/language/" rel="noopener noreferrer"&gt;Wolfram Language&lt;/a&gt; may come to your mind while reading this post. It is probably the most powerful tool out there for programming mathematics, as it is the result of years of continuous work by a very talented team. However, I won't talk about it here because even though it is &lt;a href="https://blog.wolfram.com/2021/11/30/six-reasons-why-the-wolfram-language-is-like-open-source/" rel="noopener noreferrer"&gt;more accessible than I thought at first&lt;/a&gt;, it imposes restrictions that I didn't want to deal with. I was not going to expect my reader to do so if I didn't, in the first place.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are mathematical objects?
&lt;/h2&gt;

&lt;p&gt;Anything we use to make math is a mathematical object. For example, numbers (

&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;33&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;3&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
, 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;2727&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;27&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
, 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;−80-80&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;−&lt;/span&gt;&lt;span class="mord"&gt;80&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
, 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;3.153.15&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;3.15&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
, ...), symbols (
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;++&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;+&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
, 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;−-&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;−&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
, 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;==&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
, 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;π\pi&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;π&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
, 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;ϵ\epsilon&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ϵ&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
, 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;\sqrt{}&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord sqrt"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span class="svg-align"&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="hide-tail"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
, ...) and variables (
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;xx&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
, 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;yy&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;y&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
, ...). From simple mathematical objects, we can build other more complex, like operations (
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;3+53+5&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;3&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;5&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
, 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;2x2^x&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;x&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
, 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;A∪BA \cup B&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;A&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;∪&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;B&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
 ...), relationships ( 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;2&amp;lt;32 \lt 3&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;3&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
, 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;x≠10x \ne 10&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;&lt;span class="mrel"&gt;&lt;span class="mord vbox"&gt;&lt;span class="thinbox"&gt;&lt;span class="rlap"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="inner"&gt;&lt;span class="mord"&gt;&lt;span class="mrel"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="fix"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;10&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
, 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;1=11 = 1&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
 ) and even full theorems ( 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;∀x,y∈N,x&amp;lt;y  ⟺  ∃z∈N:x+z=y\forall x, y \in \mathbb{N}, x&amp;lt;y \iff \exists z \in \mathbb{N}:x+z=y&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;∀&lt;/span&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;y&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;∈&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathbb"&gt;N&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;y&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;⟺&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;∃&lt;/span&gt;&lt;span class="mord mathnormal"&gt;z&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;∈&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathbb"&gt;N&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;:&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;z&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;y&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
 ).&lt;/p&gt;

&lt;p&gt;Modern programming languages provide all kinds of interfaces to represent and manipulate mathematical objects. Numbers, for example, are present in any non-esoteric language you will stumble upon. But what about more complex objects?&lt;/p&gt;
&lt;h2&gt;
  
  
  Mathematical objects in programming languages
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Mathematical objects as data structures
&lt;/h3&gt;

&lt;p&gt;While mathematical objects are relatively abstract concepts, their implementation in a computer is directly related to data structures. Different languages define different native data structures, and each compiler/interpreter implements the operations on said data structures, determining the mathematical objects that can be manipulated by that programming language without additional programming.&lt;/p&gt;

&lt;p&gt;I say "without additional programming" because, in the end, all programming languages (the Turing-complete ones) are equivalent. Since we live in the future, you will find that popular languages have libraries that implement anything you can think of.&lt;/p&gt;
&lt;h3&gt;
  
  
  Languages for mathematical applications
&lt;/h3&gt;

&lt;p&gt;MatLab works natively with matrices and their operations. Do you want to work with matrices in Python? With NumPy, you can, but it will be a little bit harder than with MatLab. Do you want to work with matrices in C? You also can, but it will be harder than with Python.&lt;/p&gt;

&lt;p&gt;This is just a crude case of how different languages handle better some mathematical objects. And while matrices are a relatively common thing to use in programming languages, other math concepts are not. Remember that we are talking about very different fields of mathematics. You would be surprised how cleaner or even faster can be a program written in less conventional languages like Haskell or Prolog, depending on the problem.&lt;/p&gt;

&lt;p&gt;So imagine you need an application capable of handling a lot of different math concepts: arithmetic, algebra, logic, geometry... What are your options as a programmer?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;You can choose a single multi-purpose language, like Python, R or Julia, that have immense repositories of libraries of all sorts. You may find redundancies that you would need to contemplate and probably translate to common data structures. Also, some concepts might end up being difficult to use in an idiomatic, clean way. Or, on the contrary, to make them idiomatic, they turn out to be poorly optimized.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You could use more than one language and glue them somehow or even embed one into another. This way, you could take advantage of the benefits of each. Have you ever wondered how powerful could be an application made with JavaScript + Python (PyScript) + Prolog (TauProlog)? That sounds like the &lt;a href="https://www.youtube.com/watch?v=-O01G3tSYpU" rel="noopener noreferrer"&gt;third wave of AI&lt;/a&gt; to me! Just kidding, sounds very interesting but just reading it already gives me a headache.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Another option is to turn your application into different distributed services. Collaboration is key to growth, isn't it? What if we implemented specialized services for different math fields and tasks and then make them talk to each other? It has the advantages of both previous points. You have a modular architecture, you can reuse code and you can use different languages, the most suited for each task.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Distributed math applications
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Shared formats as middleware
&lt;/h3&gt;

&lt;p&gt;When you connect several applications, you need formats. We could let each application communicate the way it wanted and enable the main system to interpret every possible format, but that's not scalable.&lt;/p&gt;

&lt;p&gt;The Web is the best example of this. Everything you display on a webpage is HTML &lt;strong&gt;by convention&lt;/strong&gt;. There are countless markup languages, document formats... but if you want something rendered in your browser, you better translate it to HTML. Look at Mathjax or KaTeX. We didn't want to write mathematical equations directly in HTML, because LaTeX was better for that. So we made applications that translated it into HTML.&lt;/p&gt;
&lt;h3&gt;
  
  
  Formats for humans vs Semantic formats for machines
&lt;/h3&gt;

&lt;p&gt;Standard formats are powerful. When machines are able to communicate, everything is better. But HTML and CSS, for example, are a special case for one reason: their final target are human eyes. An HTML page might be a complete mess, but if it renders into a human-readable page, it's alright.&lt;/p&gt;

&lt;p&gt;In fact, when we decided that we wanted the web to be machine-readable, the concept of the &lt;a href="https://en.wikipedia.org/wiki/Semantic_Web" rel="noopener noreferrer"&gt;semantic web&lt;/a&gt; was born. Because machines do not care about presentation, they care about &lt;strong&gt;semantics&lt;/strong&gt;: the meaningful information they can parse from the used formats.&lt;/p&gt;
&lt;h3&gt;
  
  
  Semantic math formats
&lt;/h3&gt;

&lt;p&gt;And here's the problem with a lot of formats for mathematical object representation; they are made to present information to humans, not to machines. LaTeX, for example, doesn't hold much semantic information.&lt;/p&gt;

&lt;p&gt;
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;xy+sin(e)xy + sin(e)&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="mord mathnormal"&gt;y&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;s&lt;/span&gt;&lt;span class="mord mathnormal"&gt;in&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;e&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/p&gt;

&lt;p&gt;The expression above is written in valid LaTeX, but it is pretty ambiguous. Is 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;xyxy&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="mord mathnormal"&gt;y&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
 a single variable, or the product of 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;xx&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
 and 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;yy&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;y&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
? Is 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;ee&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;e&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
 the Euler constant or an independent variable? We don't know, because LaTeX is not a semantic format. A human would know the answers thanks to the context in which we use the expression, but probably that context is not machine-readable.&lt;/p&gt;

&lt;p&gt;Wikipedia points out three main &lt;a href="https://en.wikipedia.org/wiki/Mathematical_markup_language" rel="noopener noreferrer"&gt;formats for computer interchange&lt;/a&gt;: MathML, OpenMath and OMDoc. The people involved in the development of each one worked on the others too, so they are sort of complementary.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.w3.org/TR/MathML3/" rel="noopener noreferrer"&gt;&lt;strong&gt;MathML&lt;/strong&gt;&lt;/a&gt; has two variants: Presentation MathML, which doesn't hold semantic information, and Content MathML, which does. The mechanism for describing the semantics of its symbols is not present in the format itself. For that, it relies on the OpenMath standard (or similar alternatives).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://openmath.org/" rel="noopener noreferrer"&gt;&lt;strong&gt;OpenMath&lt;/strong&gt;&lt;/a&gt; provides two encodings to represent mathematical objects and also defines an extensible mechanism to describe the semantics of its symbols: the &lt;strong&gt;Content Dictionaries&lt;/strong&gt;. There are official dictionaries that describe various symbols for different fields of mathematics, but any person or organization could define more dictionaries to extend the number of objects representable by the format. This way, an application that uses follows this standard only has to specify which dictionaries it supports.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.omdoc.org/" rel="noopener noreferrer"&gt;&lt;strong&gt;OMDoc&lt;/strong&gt;&lt;/a&gt;, on the other hand, is some kind of extension to both MathML and OpenMath, designed to represent mathematical documents for humans and machines alike.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Note&lt;/em&gt;: I shouldn't finish this section without mentioning the existence of SCSCP (Symbolic Computation Software Composability Protocol). It is a protocol developed to communicate distributed systems for mathematical computation, or CAS (Computer Algebra System). It is built on top of the OpenMath standard to describe a server-client communication oriented to mathematical objects.&lt;/p&gt;

&lt;h2&gt;
  
  
  My experience with the OpenMath standard
&lt;/h2&gt;

&lt;h3&gt;
  
  
  First encounter - Apparent death
&lt;/h3&gt;

&lt;p&gt;OpenMath is the best suited standard to communicate distributed math applications.&lt;/p&gt;

&lt;p&gt;I was really excited when I found this standard. As long as an application supported the OpenMath encoding (OM), it could be communicated with lots of other interesting applications easily, with a common format. A whole new world of possibilities for collaboration! I was sure I would find applications to transform OM into renderable formats like LaTeX or HTML, reduce or evaluate complex mathematical expressions, transform function definitions into code, etc.&lt;/p&gt;

&lt;p&gt;However, disappointment came when I continued to research. Reading the openmath.org page I found a list of projects that used the standard. The first time I clicked on one: broken link. But, hey! the next link works! ... and the linked project is obsolete; it has unresolved and unfindable dependencies. The official page is &lt;strong&gt;full&lt;/strong&gt; of broken links and obsolete, incomplete and undocumented projects.&lt;/p&gt;

&lt;p&gt;But it did not feel like abandonware from decades ago; there were things dated less than a few years ago. It was the same feeling as being late for a party that had just ended.&lt;/p&gt;

&lt;h3&gt;
  
  
  Finding the trail
&lt;/h3&gt;

&lt;p&gt;I only found a &lt;a href="https://github.com/OpenMath/py-openmath" rel="noopener noreferrer"&gt;Python library&lt;/a&gt; and a &lt;a href="https://lurchmath.github.io/openmath-js/site/" rel="noopener noreferrer"&gt;JS package&lt;/a&gt; implementing the standard, that seemed to be active to some extent... but neither of them contemplated the full specification.&lt;/p&gt;

&lt;p&gt;The one in JS is &lt;a href="https://lurchmath.github.io/openmath-js/site/work-done/" rel="noopener noreferrer"&gt;a bit basic&lt;/a&gt;. And when I tried to use the Python one, I didn't find it easy to do anything with it apart from parsing and serializing XML; it felt like the mathematical objects were not programmed to be manipulated easily. Of course, that can be (and probably is) my fault, because the library is used in another &lt;a href="https://github.com/OpenMath/py-scscp" rel="noopener noreferrer"&gt;SCSCP library&lt;/a&gt;, where it proves to be useful.&lt;/p&gt;

&lt;p&gt;At first, I didn't give too much attention to the SCSCP library, because I thought it was not related to what I was looking for. I started my own Python implementation of the standard (&lt;em&gt;if you visit it on my GitHub keep in mind it is very unstable and mostly experimental for now&lt;/em&gt;) and forgot about any official implementation.&lt;/p&gt;

&lt;p&gt;However, I recently returned to that library, trying to understand it better with the knowledge acquired by working with OpenMath on my own. The SCSCP library caught my attention this time, and I followed one link after another until I understood what was going on. Part of these projects was recently funded by the EU in a program to foster the development of a European research infrastructure called &lt;a href="https://github.com/OpenDreamKit" rel="noopener noreferrer"&gt;OpenDreamKit&lt;/a&gt; that happened to finish in 2020. In fact, there are two more projects built on top of both the OpenMath and SCSCP Python libraries that belong to said infrastructure and seem to have little attention from other developers, even though they seem to be the only current functioning projects based on that technologies.&lt;/p&gt;

&lt;h3&gt;
  
  
  My interpretation
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Disclaimer&lt;/em&gt;: I don't talk on behalf of anyone except myself and I might have incomplete or wrong information about what's been going with OpenMath on in the last decades.&lt;/p&gt;

&lt;p&gt;I've spent many hours browsing the pages related to OpenMath and I've come to a conclusion. It looks like a lot of this work started long ago, in the nineties, which explains why there is so much that's become obsolete (so it is in fact like abandonware from decades ago). To me, it looked like back then their work was more similar to projects of software development. But their society has always been closely related to universities and public funds (similar to the OpenDreamKit one). So their current available work is very academic! They have papers instead of documentation and research groups instead of communities.&lt;/p&gt;

&lt;p&gt;They made their last workshop a year and a half ago (Jul 2021) so they were active recently... But then, why don't they update their website to reflect the actual state of the project? Why isn't there any work to integrate the standard into modern, popular frameworks used for mathematics? I've come to think that it's just that, if they are actually still active, I'm out of the appropriate communication channels. I don't know if I'm in an empty room or just in the wrong room.&lt;/p&gt;

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

&lt;p&gt;Is the project just close to a death of disinterest? Or maybe the circles using and developing it are &lt;strong&gt;not&lt;/strong&gt; the circles of software developers, but of researchers and academics? I honestly don't know. But, also, I don't care! I found the project to be fascinating and full of potential. The OM Society might not have the same philosophy as other modern open source projects, but their work is there for us to use it.&lt;/p&gt;

&lt;p&gt;I think the idea of distributed mathematical systems is &lt;strong&gt;wonderful&lt;/strong&gt;. But not only for researchers, who are the people using them right now; &lt;strong&gt;also for developers&lt;/strong&gt;! My intention with this post was to make these concepts and possibilities known to people interested in working on open source projects like the ones we do know, in the hope that new, open and active communities can be formed.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;If you liked this topic, let me know and I will write more about it!&lt;/strong&gt; ✍🏻 I haven't explained anything about the format, encodings and content dictionaries of the OpenMath standard, so I'll probably write another post explaining how to use and implement them.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.omdoc.org/about/" rel="noopener noreferrer"&gt;https://www.omdoc.org/about/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://openmath.org/about/" rel="noopener noreferrer"&gt;https://openmath.org/about/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.w3.org/TR/MathML3/" rel="noopener noreferrer"&gt;https://www.w3.org/TR/MathML3/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/OpenMath/scscp/blob/master/revisions/SCSCP_1_3.pdf" rel="noopener noreferrer"&gt;Symbolic Computation Software Composability Protocol - SCSCP - Specification, Version 1.3&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://link.springer.com/content/pdf/10.1007/11826095.pdf?pdf=button" rel="noopener noreferrer"&gt;OMDoc – An Open Markup Format for Mathematical Documents&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/OpenDreamKit/OpenDreamKit/blob/master/WP6/CICM2016/published.pdf" rel="noopener noreferrer"&gt;Interoperability in the OpenDreamKit project: the Math-in-the-Middle approach&lt;/a&gt; (3rd section)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>mathematics</category>
      <category>opensource</category>
      <category>distributedsystems</category>
    </item>
    <item>
      <title>My blogging journey until now - I'm moving to Hashnode</title>
      <dc:creator>MiguelMJ</dc:creator>
      <pubDate>Thu, 19 Jan 2023 16:31:02 +0000</pubDate>
      <link>https://forem.com/miguelmj/my-blogging-journey-until-now-im-moving-to-hashnode-496b</link>
      <guid>https://forem.com/miguelmj/my-blogging-journey-until-now-im-moving-to-hashnode-496b</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Cover photo by &lt;a href="https://www.pexels.com/@jessbaileydesign/" rel="noopener noreferrer"&gt;Jess&lt;/a&gt; from Pexels&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  2020 - Starting a blog
&lt;/h2&gt;

&lt;p&gt;It's been more than two years since I began blogging. It all started with a development journal for one of my latest projects at the second half of 2020. I knew I wouldn't be graduating that year, so I decided that I could try to gain some online presence to compensate my lack of professional experience.&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/miguelmj" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F449565%2Fc9a30852-1361-49c8-aa13-c385fd0c0b33.png" alt="miguelmj"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/miguelmj/writing-a-conversational-user-interface-library-full-series-3dc5" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Writing a Conversational User Interface Library - Full Series&lt;/h2&gt;
      &lt;h3&gt;MiguelMJ ・ Dec 10 '20&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#closed&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;DEV.to was in a boom, I was seeing a lot of developers start blogs here, so I decided to give it a try. I found the other platforms a bit intimidating, but this one was very approachable and beginner friendly. I wrote every week or two and found some interesting people to follow. I didn't get much attention, but it didn't matter! I was here for the experience of writing and the growth that comes along.&lt;/p&gt;

&lt;p&gt;I wrote more than a development journal. I had a lot of opinions I had formed during my years in university and advice to give, so a lot of what I wrote at that moment was the kind of things I would've love to know as a freshman. It was a true pleasure to have a space to write it all down and share it.&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/miguelmj" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F449565%2Fc9a30852-1361-49c8-aa13-c385fd0c0b33.png" alt="miguelmj"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/miguelmj/why-and-how-to-use-pen-and-paper-design-an-algorithm-11nn" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Why and how to use pen and paper - Designing algorithms with no code&lt;/h2&gt;
      &lt;h3&gt;MiguelMJ ・ Dec 13 '20&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#beginners&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#codenewbie&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#productivity&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#codequality&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;Before the year ended, the DEV.to community did &lt;a&gt;a lot of work around the moderation&lt;/a&gt; of the platform. At that time I was made a trusted member and to say that I found it rewarding, for the short time I had been here, is an understatement.&lt;/p&gt;

&lt;h2&gt;
  
  
  2021 - A comfortable plateau and the seed of dissatisfaction
&lt;/h2&gt;

&lt;p&gt;With the new year, I slowed down my publication pace and started writing monthly. There was a lot going on in my life, so I felt comfortable with little activity; enough to continue the habit and keep my presence out there. You can tell it was a weird year for me because I have several unfinished series and a failed attempt to translate all my posts to Spanish (my native language). &lt;/p&gt;

&lt;p&gt;Despite all this, it was a great year in terms of growing my personal brand. My open source projects started to thrive (I was even featured in an &lt;a href="https://makerwork.substack.com/p/makerwork001" rel="noopener noreferrer"&gt;incipient newsletter, now dead&lt;/a&gt;) and I started writing for my current self, more than for my past self.&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/miguelmj" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F449565%2Fc9a30852-1361-49c8-aa13-c385fd0c0b33.png" alt="miguelmj"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/miguelmj/data-structures-in-prolog-where-to-start-53gm" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Data structures in Prolog - Where to start&lt;/h2&gt;
      &lt;h3&gt;MiguelMJ ・ Jun 15 '21&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#prolog&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#datastructures&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#resources&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;Also, a very strange episode happened that year.&lt;/p&gt;

&lt;p&gt;I was invited to write a featured post for another platform. As it was my first post written for someone else, I wanted to make it about a popular topic: JavaScript, something I had never written about before.&lt;/p&gt;

&lt;p&gt;Unfortunately, that site turned out to be a complete scam. Most of its content is stolen, their complete Q&amp;amp;A section is a literal scrap of the StackOverflow page and each and every user I interacted with was a bot (they even used watermarked stock photos as profile pics).&lt;/p&gt;

&lt;p&gt;I got out of there as quickly as possible and published my article here in DEV.to. &lt;strong&gt;In less than 24 hours, it had more traffic than all my previous posts together&lt;/strong&gt;. Today (January 2023) it is still my third most read post.&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/miguelmj" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F449565%2Fc9a30852-1361-49c8-aa13-c385fd0c0b33.png" alt="miguelmj"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/miguelmj/take-full-advantage-of-high-order-functions-examples-in-javascript-4ibg" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Take full advantage of high order functions - Examples in Javascript&lt;/h2&gt;
      &lt;h3&gt;MiguelMJ ・ Jun 22 '21&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#tutorial&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#javascript&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#functional&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;I remember reading several posts here talking about the spam, the clickbaity low-effort listicles, the daily copy-pasted git tutorials, etc. If you have been here for a while, you will know that the quality of the DEV.to content is still an unsolved issue. I didn't fully care, I was comfortable here and that was all that mattered. As a trusted user, I did my best to mark low-quality posts and boost well written, original content. &lt;/p&gt;

&lt;p&gt;However, dissatisfaction started to grow inside me, and a feeling that something was not fair here. Not only because of all my beloved posts eclipsed by my own single JavaScript tutorial, but also for the people I follow that publish interesting, advanced content, that get 1% of attention and feedback received by the mass of low quality posts focused on beginners.&lt;/p&gt;

&lt;h2&gt;
  
  
  2022 - Last year in DEV
&lt;/h2&gt;

&lt;p&gt;The following year I did very little blogging. Most of my posts in 2022 were for promoting a project or another (looking back, I coded some interesting stuff). The two biggest exceptions were very significant posts to me.&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/miguelmj" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F449565%2Fc9a30852-1361-49c8-aa13-c385fd0c0b33.png" alt="miguelmj"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/miguelmj/how-to-get-answers-on-stackoverflow-3pp7" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;How to get answers on StackOverflow&lt;/h2&gt;
      &lt;h3&gt;MiguelMJ ・ Feb 6 '22&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#beginners&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#codenewbie&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#productivity&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;This one came after I saw some people complaining about the StackOverflow community. I wanted to do an attempt on bringing closer two of the communities I love, from which beginners benefit specially. I expected some backslash in the comments (given the hate SO receives from some people) but instead I got a lot of comments from veteran devs, liking my post. It also gave more insight about who reads what.&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/miguelmj" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F449565%2Fc9a30852-1361-49c8-aa13-c385fd0c0b33.png" alt="miguelmj"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/miguelmj/javascript-is-not-an-untyped-language-1jkg" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;JavaScript is not an untyped language&lt;/h2&gt;
      &lt;h3&gt;MiguelMJ ・ Jun 24 '22&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#javascript&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#plt&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#computerscience&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#beginners&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;And then, there's this one. This one was an explosion. I know it was a controversial opinion on a perma-hot topic like JS, but damn, this post has &lt;strong&gt;five times&lt;/strong&gt; as many views as my next most viewed post, and it's my top reacted and commented post of all time. It got featured in the social networks of DEV, tweeted several times and even improperly published as material for an online course.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1541501371962253314-196" src="https://platform.twitter.com/embed/Tweet.html?id=1541501371962253314"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1541501371962253314-196');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1541501371962253314&amp;amp;theme=dark"
  }



  &lt;/p&gt;

&lt;p&gt;And it was a rant written in a single afternoon! This is perfectly one of the posts I've put the least effort into. I stopped writing, discouraged. I know effort doesn't correlate with impact when we talk about writing on the Internet. But I just didn't like the idea of going back to write high effort posts for no one, always tempted to write about JavaScript again only for reads.&lt;/p&gt;

&lt;p&gt;After some time, I was contacted yet by another platform, asking me to write a course for them. Another dev that had worked with them recommended me writing my own book, instead of just a course. Don't get me wrong, that platform is legit and has great content; in fact, I tried to make the course they wanted. But I didn't have enough time.&lt;/p&gt;

&lt;p&gt;Writing an article for a blog is something, but writing a course or a book is another dimension. It is something I want to do, but I probably won't anytime soon.&lt;/p&gt;
&lt;h2&gt;
  
  
  The big hiatus and the decision to move
&lt;/h2&gt;

&lt;p&gt;It's been months since I published anything. There are several things I want to write about, but these months have been very busy, plus I don't feel like I have found my audience yet, which disencourages me even more. I don't even read DEV anymore, as the content quality has only gone down, in spite of the efforts to implement tag filters and experience level for posts.&lt;/p&gt;

&lt;p&gt;So, to find new motivation, I have decided to move on. I need to keep looking for an audience that I feel I connect with. I &lt;strong&gt;love&lt;/strong&gt; DEV and everything I've achieved thanks to it, but I need to keep looking for a better space for my blog.&lt;/p&gt;

&lt;p&gt;I'm going to try my luck with Hashnode. I don't have any particular reason, so I don't know if it will be my definitive platform. I want to see what kind of audience I can build there and explore the possibilities of a different tool.&lt;/p&gt;
&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
      &lt;div class="c-embed__body flex items-center justify-between"&gt;
        &lt;a href="https://miguelmj.hashnode.dev/" rel="noopener noreferrer" class="c-link fw-bold flex items-center"&gt;
          &lt;span class="mr-2"&gt;miguelmj.hashnode.dev&lt;/span&gt;
          

        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;My first step has been to migrate there a curated list of my posts and polish them a bit. The canonical URLs will still point to the original posts, nonetheless. I will keep publishing in DEV everything, for the readers I already have here, but I will make Hashnode my main target.&lt;/p&gt;

&lt;p&gt;I guess that, as a lifelong student and an eventual teacher I will always have something to write for beginners. However, I want to try a different level of writing and even different types of content. I don't know how my blog might evolve, but, of course, that's the exciting part! &lt;/p&gt;

</description>
      <category>writing</category>
    </item>
    <item>
      <title>Make It Pixel! - Make pixel art from any image</title>
      <dc:creator>MiguelMJ</dc:creator>
      <pubDate>Sun, 17 Jul 2022 09:59:09 +0000</pubDate>
      <link>https://forem.com/miguelmj/make-it-pixel-make-pixel-art-from-any-image-2o4n</link>
      <guid>https://forem.com/miguelmj/make-it-pixel-make-pixel-art-from-any-image-2o4n</guid>
      <description>&lt;p&gt;There are several options out there for generating pixel art from images. However, none has all the things I would like to have at the same time, so I decided to make my own.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Cover generated by MakeItPixel from the Mona Lisa by Leonardo Da Vinci&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A little &lt;strong&gt;disclaimer&lt;/strong&gt;: I have great respect for pixel artists and I know that "pixel art" is not the most proper name for what programs like mine generate. But lacking a better term, and because everyone uses it, I'll do it too, being aware that generated generated pixel art has flaws that any artist could point out and correct. &lt;/p&gt;

&lt;h2&gt;
  
  
  Motivation
&lt;/h2&gt;

&lt;p&gt;What would I expect from a pixel art generator?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Re-scaling of an image to a given resolution.&lt;/li&gt;
&lt;li&gt;Optional use of fully customizable palettes.&lt;/li&gt;
&lt;li&gt;Parameterizable color quantization and dithering.&lt;/li&gt;
&lt;li&gt;Background removal.&lt;/li&gt;
&lt;li&gt;Optional outlines.&lt;/li&gt;
&lt;li&gt;Control over image preprocessing options.&lt;/li&gt;
&lt;li&gt;Fast to use over large amounts of images.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are tools out there pretty close to what I want, but, as I said, none has them all. Some have very basic and rigid algorithms others some are GUI based and thus must process the files one by one... and even worse, some don't work on Linux! Most of them discard the option of trying out different configurations on several files at once. In short, if I want to meet my needs, I must do it myself.&lt;/p&gt;

&lt;p&gt;With this motivation, I created &lt;strong&gt;MakeItPixel&lt;/strong&gt;.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/MiguelMJ" rel="noopener noreferrer"&gt;
        MiguelMJ
      &lt;/a&gt; / &lt;a href="https://github.com/MiguelMJ/MakeItPixel" rel="noopener noreferrer"&gt;
        MakeItPixel
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Image processing tool to make images look like pixel art
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/MiguelMJ/MakeItPixel/doc/logo.png"&gt;&lt;img height="64px" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FMiguelMJ%2FMakeItPixel%2Fdoc%2Flogo.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Make images look like pixel art&lt;/h3&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/393f814d60babe457c81407422bd9a97c54221c8172e16fc2db95ddbc744729b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f432b2b2d31312d3030353939433f7374796c653d666c61742d737175617265266c6f676f3d63253242253242"&gt;&lt;img src="https://camo.githubusercontent.com/393f814d60babe457c81407422bd9a97c54221c8172e16fc2db95ddbc744729b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f432b2b2d31312d3030353939433f7374796c653d666c61742d737175617265266c6f676f3d63253242253242"&gt;&lt;/a&gt; &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/8c75e380f81a47824a69996e2069ba49b0bbb1ee15736d14844ef1a9bab1cf59/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f53464d4c2d76322e352e312d3843433434353f6c6f676f3d53464d4c267374796c653d666c61742d737175617265"&gt;&lt;img src="https://camo.githubusercontent.com/8c75e380f81a47824a69996e2069ba49b0bbb1ee15736d14844ef1a9bab1cf59/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f53464d4c2d76322e352e312d3843433434353f6c6f676f3d53464d4c267374796c653d666c61742d737175617265"&gt;&lt;/a&gt; &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/da306fe1f2938421f54cf63bfec757f4bcf12df0c035b62aee1ca51746c9997c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f76657273696f6e2d76302e312d696e666f726d6174696f6e616c3f7374796c653d666c61742d737175617265"&gt;&lt;img src="https://camo.githubusercontent.com/da306fe1f2938421f54cf63bfec757f4bcf12df0c035b62aee1ca51746c9997c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f76657273696f6e2d76302e312d696e666f726d6174696f6e616c3f7374796c653d666c61742d737175617265"&gt;&lt;/a&gt; &lt;a href="https://github.com/MiguelMJ/MakeItPixel/LICENSE" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/b7bf31ac85269986ebc9e0190e415704570b14926183525342c922106f5b91e0/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d696e666f726d6174696f6e616c3f7374796c653d666c61742d737175617265"&gt;&lt;/a&gt;&lt;a href="https://github.com/MiguelMJ/MakeItPixel/wiki" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/45a4150036bd385862ce98e5726d55cdaf2fc73f9daee242f35e15158550fc0b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f636f64652d646f63756d656e7465642d737563636573733f7374796c653d666c61742d737175617265"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Preview&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;Original:&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/MiguelMJ/MakeItPixel/examples/monalisa.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FMiguelMJ%2FMakeItPixel%2Fexamples%2Fmonalisa.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Example results:&lt;/p&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/MiguelMJ/MakeItPixel/examples/config1.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FMiguelMJ%2FMakeItPixel%2Fexamples%2Fconfig1.png"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/MiguelMJ/MakeItPixel/examples/config2.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FMiguelMJ%2FMakeItPixel%2Fexamples%2Fconfig2.png"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/MiguelMJ/MakeItPixel/examples/config3.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FMiguelMJ%2FMakeItPixel%2Fexamples%2Fconfig3.png"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/MiguelMJ/MakeItPixel/examples/config4.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FMiguelMJ%2FMakeItPixel%2Fexamples%2Fconfig4.png"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Table of contents&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/MiguelMJ/MakeItPixel#preview" rel="noopener noreferrer"&gt;Preview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/MiguelMJ/MakeItPixel#features" rel="noopener noreferrer"&gt;Features&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/MiguelMJ/MakeItPixel#future-features" rel="noopener noreferrer"&gt;Future features&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/MiguelMJ/MakeItPixel#dependencies" rel="noopener noreferrer"&gt;Dependencies&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/MiguelMJ/MakeItPixel#build" rel="noopener noreferrer"&gt;Build&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/MiguelMJ/MakeItPixel#contributing" rel="noopener noreferrer"&gt;Contributing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/MiguelMJ/MakeItPixel#contributors" rel="noopener noreferrer"&gt;Contributors&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/MiguelMJ/MakeItPixel#usage" rel="noopener noreferrer"&gt;Usage&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/MiguelMJ/MakeItPixel#cli-options" rel="noopener noreferrer"&gt;CLI options&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/MiguelMJ/MakeItPixel#configuration" rel="noopener noreferrer"&gt;Configuration&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/MiguelMJ/MakeItPixel#scaling" rel="noopener noreferrer"&gt;Scaling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/MiguelMJ/MakeItPixel#color-quantization" rel="noopener noreferrer"&gt;Color quantization&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/MiguelMJ/MakeItPixel#palette" rel="noopener noreferrer"&gt;Palette&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/MiguelMJ/MakeItPixel#examples" rel="noopener noreferrer"&gt;Examples&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/MiguelMJ/MakeItPixel#license" rel="noopener noreferrer"&gt;License&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Features&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Intelligent and customizable handling of color and palettes.&lt;/li&gt;
&lt;li&gt;Configure color selection during downscaling.&lt;/li&gt;
&lt;li&gt;Configure color quantization and dithering.&lt;/li&gt;
&lt;li&gt;Fully customizable both by file and console.&lt;/li&gt;
&lt;li&gt;Process dozens of files with in a single run.&lt;/li&gt;
&lt;li&gt;Fully documented.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Future features&lt;/h3&gt;

&lt;/div&gt;
&lt;ul class="contains-task-list"&gt;
&lt;li class="task-list-item"&gt;
 Parameters to generate outlines using border detection.&lt;/li&gt;
&lt;li class="task-list-item"&gt;
 Add options to blur before downscaling to reduce noice.&lt;/li&gt;
&lt;li class="task-list-item"&gt;
 Smart palette extraction from images.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Dependencies&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.sfml-dev.org/index.php" rel="nofollow noopener noreferrer"&gt;SFML v2.5.1&lt;/a&gt; (&lt;a href="https://github.com/SFML/SFML/releases/tag/2.5.1" rel="noopener noreferrer"&gt;release&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Build&lt;/h2&gt;

&lt;/div&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;g++ src/&lt;span class="pl-k"&gt;*&lt;/span&gt; -Iinclude -lsfml-graphics -o makeitpixel&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Contributing&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Read the &lt;a href="https://github.com/MiguelMJ/MakeItPixel/CONTRIBUTING.md" rel="noopener noreferrer"&gt;contributing guidelines&lt;/a&gt; if you want to contribute to the code.&lt;/li&gt;
&lt;li&gt;Open a new issue &lt;a href="https://github.com/MiguelMJ/Candle/issues/new" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/352a3aac2118c2e3a494ac0cc8135ef87d8ed96b9d6931c4072a3cc27eab17b6/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6973737565732f4d696775656c4d4a2f4d616b654974506978656c3f6c6f676f3d676974687562267374796c653d736f6369616c" alt="(issues)"&gt;&lt;/a&gt; to make a request or report a bug.&lt;/li&gt;
&lt;li&gt;Alternatively, comment it on the &lt;a href="https://en.sfml-dev.org/forums/index.php?topic=28619.0" rel="nofollow noopener noreferrer"&gt;SFML forum&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;If you use it in a project, you don't have to give…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/MiguelMJ/MakeItPixel" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;The ideal design I had in mind would offer as much customization as possible, implementing different algorithms to get the best of each possibility. But with great flexibility, comes a big headache trying to find the perfect configuration; so the system would have to be intelligent enough to consider autonomously the best  alternatives to get a quality pixel-art-like image. I wouldn't say that this version achieves this, but it's definitely on the right path.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementation
&lt;/h2&gt;

&lt;p&gt;The prototype only implemented two basic scaling and color quantization algorithms, based on RGB distance and gray values distance, and automatic palette generation, based on what I learnt of color schemes from &lt;a href="https://www.w3schools.com/colors/colors_schemes.asp" rel="noopener noreferrer"&gt;W3school&lt;/a&gt; and &lt;a href="https://en.wikipedia.org/wiki/Color_scheme" rel="noopener noreferrer"&gt;Wikipedia&lt;/a&gt;. Then, I saw the &lt;a href="https://www.youtube.com/watch?v=lseR6ZguBNY" rel="noopener noreferrer"&gt;video from javidx9 on dithering&lt;/a&gt; and I immediately added options to apply both the Floyd-Steinberg algorithm explained in the video and &lt;a href="https://en.wikipedia.org/wiki/Ordered_dithering" rel="noopener noreferrer"&gt;ordered dithering&lt;/a&gt;, that I read again on Wikipedia.&lt;/p&gt;

&lt;p&gt;The steps of a MakeItPixel run for a loaded image are the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Generate a palette if necessary.&lt;/li&gt;
&lt;li&gt;Downscale the image. &lt;/li&gt;
&lt;li&gt;Apply color quantization.&lt;/li&gt;
&lt;li&gt;Apply dithering.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Each and every step can be configured in different ways or skipped.&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;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fua3msrfqwfpovicgmdcw.png" alt="original" width="300" height="300"&gt; &lt;br&gt; Original&lt;/td&gt;
&lt;td&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuod0yxj8iqf48gvutzsy.png" alt="scaled" width="300" height="300"&gt; &lt;br&gt; Scaled&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffberrcua19tadusjnnq2.png" alt="quantized" width="300" height="300"&gt; &lt;br&gt; Quantization&lt;/td&gt;
&lt;td&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg5c17sts5gdf08zlw1vq.png" alt="dithered" width="300" height="300"&gt; &lt;br&gt; Dithering&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Steps 3 and 4 are actually performed at the same time but I think it's more visual to see it like this.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A more detailed description of the process can be found in the &lt;a href="https://github.com/MiguelMJ/MakeItPixel/wiki/Process" rel="noopener noreferrer"&gt;wiki&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Plans for the future
&lt;/h2&gt;

&lt;p&gt;This first version already has some interesant features that differentiate MakeItPixel from others: the full customizability of the palette, automatic palette generation, selection of different quantization and dithering algorithms or the independence from a GUI, that comes with the possibility to  process hundreds of images quickly.&lt;/p&gt;

&lt;p&gt;However, it still lacks some of the features I first envisioned. Mainly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Smart palette extraction from an image.&lt;/li&gt;
&lt;li&gt;More preprocessing options, like blurring to reduce noice before downscaling.&lt;/li&gt;
&lt;li&gt;Implementation of border detection to include outlines in the generated pixel art.&lt;/li&gt;
&lt;li&gt;Customization for matrices used in ordered dithering. Right now MakeItPixel only offers hard coded matrices.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Don't have a doubt that all these will exist in a future version.&lt;/p&gt;

&lt;p&gt;Also, I used SFML to work with the images because is a library I've used for a long time and I feel really comfortable with it. However, the last year I've been using ImageMagick a lot and I found a great, great advantage: ImageMagick has support for GIFs, while SFML doesn't. Unless SFML 2.3 or SFML 3 changes that, it is possible that I would change the graphic library... but there is still time before that happens.&lt;/p&gt;

&lt;h2&gt;
  
  
  MakeItPixel is open source!
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/MiguelMJ/MakeItPixel" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/MiguelMJ/MakeItPixel" rel="noopener noreferrer"&gt;Official documentation (wiki)&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The project is open to contributions, comments, feature requests... Star it if you like it to give it visibility and feel free to share your pixelated art online with the #MakeItPixel hashtag! &lt;/p&gt;

&lt;p&gt;I'll be happy to read your thoughts in the comments.&lt;/p&gt;

</description>
      <category>computervision</category>
      <category>imageprocessing</category>
      <category>programming</category>
      <category>showdev</category>
    </item>
    <item>
      <title>High level programming - Explaining abstraction</title>
      <dc:creator>MiguelMJ</dc:creator>
      <pubDate>Tue, 05 Jul 2022 11:41:09 +0000</pubDate>
      <link>https://forem.com/miguelmj/high-level-programming-explaining-abstraction-4ko</link>
      <guid>https://forem.com/miguelmj/high-level-programming-explaining-abstraction-4ko</guid>
      <description>&lt;p&gt;When designing our programs, we make use of abstraction while also providing it. In this post I want to analyze the concept of abstraction in the context of programming and software development.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Cover photo by &lt;a href="https://www.pexels.com/@vanessa-garcia?utm_content=attributionCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=pexels" rel="noopener noreferrer"&gt;Vanessa Garcia&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What are "high level" and "low level" languages? When we talk about level, we are not talking about performance or power, but about the &lt;em&gt;level of abstraction&lt;/em&gt;. Let's see what this means.&lt;/p&gt;

&lt;h2&gt;
  
  
  Abstraction as thinking about "what" and not "how"
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Anything that provides an interface to simplify a complex structure or algorithm behind it&lt;/strong&gt; provides a form of abstraction. We find this constantly while programming, using functions, subroutines, APIs, libraries...&lt;/p&gt;

&lt;p&gt;The same algorithm can be expressed in &lt;strong&gt;different levels of abstraction&lt;/strong&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Level of abstraction&lt;/th&gt;
&lt;th&gt;Algorithm&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Highest&lt;/td&gt;
&lt;td&gt;1. Prepare a cup of coffee&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;1. Boil some water.&lt;br&gt;2. Place the filter with coffee over a cup.&lt;br&gt;3. Pour slowly the water into the filter.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;1. Fill a cup of water.&lt;br&gt;2. Pour it into a pot.&lt;br&gt;3. Heat the pot until the water boils.&lt;br&gt;4. Place a coffee filter over a cup.&lt;br&gt;5. Put a spoon of coffee in the filter.&lt;br&gt;6. Pour slowly the water into the filter.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Very low&lt;/td&gt;
&lt;td&gt;Steps that could include how to traverse your kitchen, how to look for each tool in your drawers and even the movements of your wrist and fingers for each task.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The higher the level, the more information is taken for granted. The lower, less complexity is hidden.&lt;/p&gt;

&lt;p&gt;Why is it useful to understand this?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;For design&lt;/strong&gt;. When you define an algorithm to solve a problem, it's usually better to start with a high-level approach, and then break each step down into smaller steps, solving each one at a time (this is related to &lt;a href="https://stackoverflow.blog/2022/01/31/the-complete-beginners-guide-to-dynamic-programming/" rel="noopener noreferrer"&gt;dynamic programming&lt;/a&gt;). Also, this top-down design process usually results in more modular code, which is easier to work with to a certain extent for larger programs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;For documentation&lt;/strong&gt;. A common beginner mistake is to write low level documentation, when a high level one would provide more useful information. If you have written a piece of code I'm going to use, just let me know how to use it. Give me low level information in case I'm going to review or modify the code, or if I need to understand technical details for any reason.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;For optimization&lt;/strong&gt;. You might have heard that low level languages run faster than high level languages. This is only half true. Every high level language performs behind-the-scenes optimizations that a low level program should match to be as fast. One of my favorite quotes, whose source I don't remember, is: &lt;em&gt;"Badly written C is slower than Python"&lt;/em&gt;. So don't assume that just because something is low level is faster than a high level alternative, unless you understand the objective complexity of both cases.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Abstraction as generalization of specific cases
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Any process that operates with independence from the nature of one or more of its elements&lt;/strong&gt; provides a form of abstraction.&lt;/p&gt;

&lt;p&gt;A structure or algorithm may have more specific instances, and be, at the same time, a specific instance of a more general case:&lt;/p&gt;

&lt;p&gt;Data structures, for example, are identified at high level by the insertion, access and deletion rules, while in the low level are identified by the type and arrangement of their values.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Level of abstraction&lt;/th&gt;
&lt;th&gt;Structure&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;General&lt;/td&gt;
&lt;td&gt;Set of values identified by a key of any type&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Less general&lt;/td&gt;
&lt;td&gt;Set of values identified by any number&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Specific&lt;/td&gt;
&lt;td&gt;A list of values&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Very specific&lt;/td&gt;
&lt;td&gt;A linked list of strings&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The abstraction level of an algorithm depends on the abstraction level of the structures involved and how much you can determine the result for any specific input.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Level of abstraction&lt;/th&gt;
&lt;th&gt;Algorithm&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;General&lt;/td&gt;
&lt;td&gt;Traverse any iterable structure and apply an operation to its values&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Less general&lt;/td&gt;
&lt;td&gt;Iterate a list and apply an operation to its values&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Specific&lt;/td&gt;
&lt;td&gt;Iterate a list of numbers and apply an operation to its values&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Very Specific&lt;/td&gt;
&lt;td&gt;Iterate a list of numbers and duplicate each value&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Why is it useful to understand this?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Using abstractions already present in programming languages&lt;/strong&gt;. Most high level languages offer tools like templates, high order functions, interfaces, etc, that usually spare you a lot of work, when you are able to identify the best opportunities to use them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reusing logic to improve your code&lt;/strong&gt;. Taking recurrent logic in a program and making it abstract results in shorter, more flexible and scalable code.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Good practices and conclusion
&lt;/h2&gt;

&lt;p&gt;Now, you must be careful. Too abstract code might be sometimes more difficult to read and difficult to optimize, because there exist more dependencies and procedures tend to take more parameters. The complete opposite is also true: code with zero abstraction is going to be a pain in the neck to write, review or maintain. &lt;/p&gt;

&lt;p&gt;Always try to find a balance between ingenious and maintainable solutions.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;&lt;em&gt;Recommended reading&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag__link"&gt;
  &lt;a href="/miguelmj" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F449565%2Fc9a30852-1361-49c8-aa13-c385fd0c0b33.png" alt="miguelmj"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/miguelmj/hackathon-submission-an-audio-search-engine-powered-by-deepgram-3cf" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Hackathon submission - An audio search engine powered by Deepgram&lt;/h2&gt;
      &lt;h3&gt;MiguelMJ ・ Mar 28 '22&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#hackwithdg&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#telegram&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#showdev&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#python&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;div class="ltag__link"&gt;
  &lt;a href="/miguelmj" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F449565%2Fc9a30852-1361-49c8-aa13-c385fd0c0b33.png" alt="miguelmj"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/miguelmj/the-turing-machine-made-understandable-35po" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;The Turing Machine made understandable&lt;/h2&gt;
      &lt;h3&gt;MiguelMJ ・ Dec 8 '20&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#computerscience&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#algorithms&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#learn&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://twitter.com/MiguelMJdev" rel="noopener noreferrer"&gt;You can follow me on Twitter! 🐦&lt;/a&gt;&lt;/p&gt;

</description>
      <category>codequality</category>
      <category>beginners</category>
    </item>
    <item>
      <title>JavaScript is not an untyped language</title>
      <dc:creator>MiguelMJ</dc:creator>
      <pubDate>Fri, 24 Jun 2022 10:40:22 +0000</pubDate>
      <link>https://forem.com/miguelmj/javascript-is-not-an-untyped-language-1jkg</link>
      <guid>https://forem.com/miguelmj/javascript-is-not-an-untyped-language-1jkg</guid>
      <description>&lt;h2&gt;
  
  
  JavaScript's popularity
&lt;/h2&gt;

&lt;p&gt;At the time of writing this post (Jun 2022), JavaScript &lt;strong&gt;is #3 in the &lt;a href="https://pypl.github.io/PYPL.html" rel="noopener noreferrer"&gt;PYPL&lt;/a&gt; index&lt;/strong&gt;, only beaten by Java and Python in popularity. In the &lt;a href="https://survey.stackoverflow.co/2022/#most-popular-technologies-language" rel="noopener noreferrer"&gt;latest Stack Overflow Developer survey&lt;/a&gt;, it came out as &lt;strong&gt;the most used language for the tenth year in a row&lt;/strong&gt;. Being the main language for programming web applications in a connected world, it's not that of a surprise that programmers of all levels of experience work with it, both for learning and professionally.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Cover by &lt;a href="https://www.pexels.com/@fionaart/" rel="noopener noreferrer"&gt;Fiona Art&lt;/a&gt; from Pexels&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But JavaScript is a peculiar language. Designed for running on web browsers, some people wanted to use it out of them so much that they even created NodeJS for that. JavaScript has contributed to create things like AJAX and JSON (they liked greek myths) that would still be used even if another scripting language appeared someday to replace it, something that won't happen soon. So it's clear that people love it.&lt;/p&gt;

&lt;p&gt;Love it? When you listen and read about it, you'll quickly notice that people tend to have very strong opinions (maybe it's a common trait in developers) on this language. They either love it or hate it. And a lot of people have an opinion, just because &lt;strong&gt;depending on what part of the industry you work, it's just inevitable to use it daily&lt;/strong&gt;. Yet, it is so error prone and unsafe, &lt;strong&gt;unless you have really consolidated good practices&lt;/strong&gt;, that it's unbelievable that it's still a standard.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tech-influencers
&lt;/h2&gt;

&lt;p&gt;What calls my attention the most is the fact that &lt;strong&gt;lots beginners are so centered around it&lt;/strong&gt;. In fact, the same phenomenon goes on with Python. Their high level, dynamic nature, makes them easy to start with. Dictionaries are primitive types, functions are first class citizens... they are just so flexible! And it's so easy to write listicles about JavaScript, 30 secs tutorials or make 3 slides explaining how great it is compared to other languages to get traffic on your posts, videos, etc.&lt;/p&gt;

&lt;p&gt;Some tech-influencers even build their brands specifically on this kind of JavaScript content. The damage that these tech-influencers do in general is not the matter of this post, but there's something very specific that's wrong and that I've read a lot that I would like to explain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Is JavaScript an untyped language?
&lt;/h2&gt;

&lt;p&gt;If there's something new programmers hate is error messages. I guess that's why I've seen listed as one of its advantages over other languages that &lt;strong&gt;JavaScript produces no type errors because it's an untyped language&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;This is just wrong&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes, JavaScript raises less errors than other languages in the same context. Is this good? If the infamous &lt;code&gt;"ba" + +"a" + "a" == "baNaNa"&lt;/code&gt; is not a red flag for you... Anyways, that's not the matter of this post either. The point I really want to make is: &lt;strong&gt;&lt;em&gt;JavaScript is a typed language&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;There was a &lt;a href="https://stackoverflow.com/questions/964910/is-javascript-an-untyped-language" rel="noopener noreferrer"&gt;discussion on Stack Overflow&lt;/a&gt; in 2015 on this topic (and I'm sure in many other sites over the years) where the top answer summarizes the problem very well. The key is what you mean as &lt;em&gt;"untyped"&lt;/em&gt;. Well, Brendan Eich himself used this term to describe JavaScript, meaning that it's not statically typed. However, one thing lots of programmers missed is that &lt;strong&gt;even he pointed out that the term is used differently in academia and that JavaScript, in fact, had typed values&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It's important for professionals to use standard terminology, and like it or not, &lt;em&gt;"untyped"&lt;/em&gt; is not appropiate to describe a non statically typed language. If &lt;em&gt;"untyped"&lt;/em&gt; already has another use: &lt;em&gt;a programming language with no types&lt;/em&gt;; and what you are saying also has an unambiguous term associated: &lt;em&gt;"dynamically typed"&lt;/em&gt;, then the more &lt;strong&gt;clear and distinct&lt;/strong&gt; option should be preferred.&lt;/p&gt;

&lt;p&gt;Let's consider the following points:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A programming language with types is a typed language. No matter if statically-typed or dynamically-typed: it is typed.&lt;/li&gt;
&lt;li&gt;Types impose semantic restrictions: &lt;strong&gt;type errors occur&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;JavaScript might perform almost every possible casting (this means weakly typed) to prevent this errors, but the can still raise. Examples:

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;null[0]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;undefined[0]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;null(1)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;undefined(1)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;1(1)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;All of these operations could silence their errors with more castings, like turning &lt;code&gt;null&lt;/code&gt; and &lt;code&gt;undefined&lt;/code&gt; into empty dictionaries, or any non-function value to a bottom function that always returns a nullish value. But even for JavaScript that would be too much of a bad decision. Because type errors are not there to annoy you, but to help you. Type safety is a good thing.&lt;/p&gt;

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

&lt;p&gt;JavaScript is a typed language that can raise type errors and the fact that a lot of implicit castings may be happening all the time is just a feature of the language that demands extra attention from the programmer.&lt;/p&gt;

&lt;p&gt;Let me know your thoughts on the comments!&lt;/p&gt;




&lt;h2&gt;
  
  
  EDIT
&lt;/h2&gt;

&lt;p&gt;There have already been several people asking the same things in the comments so I'm going to write here the answers for anyone going to ask the same things again:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Where have you read that JavaScript is untyped?&lt;/em&gt;&lt;/strong&gt;. Scroll up a bit. &lt;strong&gt;As I say in the post&lt;/strong&gt;, Brendan Eich (creator of JS) uses that word to describe JS, in the SO discussion linked above there people saying the same thing, tech-influencers I don't want to promote do so too and finally some users in the comment section. &lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;There are no untyped languages, that makes no sense&lt;/em&gt;&lt;/strong&gt;. Using the description of untyped languages as languages without a type system (a definition used by authors like L. Cardelli or R. Harper &lt;strong&gt;very different from dynamically or weakly typed&lt;/strong&gt;), untyped languages do exist.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A lot of Turing complete formal languages are untyped, from the Turing machines themselves to cellular automata.&lt;/li&gt;
&lt;li&gt;Assembly languages are untyped. Some may provide syntax sugar to work with primitive typed-like values, but there is not a type system that imposes restrictions on operations based on types (in most of them).&lt;/li&gt;
&lt;li&gt;Some shell languages are untyped. The type-like restrictions come from subprocesses, not from a native type system.&lt;/li&gt;
&lt;li&gt;Pure Prolog is untyped. Without the IO stream entities, everything is a Horn clause that can be evaluated to true or false, without type restrictions.&lt;/li&gt;
&lt;li&gt;Some esoteric languages are untyped. Brainf*ck being the most popular, lots of languages, usually minimalistic, don't have a type system.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Yes, I know typed languages are more present in the industry (except for assembly and shell languages), but that doesn't make the distinction pointless. Remember the software industry came way much later than computer science itself and both still develop in separate streams.&lt;/p&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;That's not how type systems work&lt;/em&gt;&lt;/strong&gt;. If you read the thread in the comments with &lt;a class="mentioned-user" href="https://dev.to/darkwiiplayer"&gt;@darkwiiplayer&lt;/a&gt;, you'll find that there doesn't seem to be a consensus on whether types are syntactic or semantic information, so depending on the sources you use, all this will make sense or not. The paradigm I'm adjusting to is that types are semantic information, not syntactic. It's a complex topic so instead of elaborating further I'll link some references.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;L. Cardelli &amp;amp; P. Wegner (1985) &lt;em&gt;On Understanding Types, Data Abstraction, and Polymorphism&lt;/em&gt; (&lt;a href="http://lucacardelli.name/Papers/OnUnderstanding.A4.pdf" rel="noopener noreferrer"&gt;PDF&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;R. Harper (2016) &lt;em&gt;Practical Foundations for Programming Languages&lt;/em&gt; (2nd ed.) (&lt;a href="http://www.cs.cmu.edu/~rwh/pfpl/2nded.pdf" rel="noopener noreferrer"&gt;PDF&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Is type-checking "syntactic" or "semantic"?&lt;/em&gt; Computer Science Stack Exchange (&lt;a href="https://cs.stackexchange.com/questions/119002/is-type-checking-syntactic-or-semantic" rel="noopener noreferrer"&gt;link&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To be fair with the opposite paradigm, here's their reference too.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;H. Geuvers (2019) &lt;em&gt;Introduction to type theory&lt;/em&gt; (&lt;a href="https://www.cs.ru.nl/~herman/onderwijs/provingwithCA/paper-lncs.pdf" rel="noopener noreferrer"&gt;PDF&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Thank you to all those who have participated in the comments!&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;&lt;em&gt;Recommended reading&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag__link"&gt;
  &lt;a href="/miguelmj" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F449565%2Fc9a30852-1361-49c8-aa13-c385fd0c0b33.png" alt="miguelmj"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/miguelmj/take-full-advantage-of-high-order-functions-examples-in-javascript-4ibg" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Take full advantage of high order functions - Examples in Javascript&lt;/h2&gt;
      &lt;h3&gt;MiguelMJ ・ Jun 22 '21&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#tutorial&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#javascript&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#functional&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;div class="ltag__link"&gt;
  &lt;a href="/miguelmj" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F449565%2Fc9a30852-1361-49c8-aa13-c385fd0c0b33.png" alt="miguelmj"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/miguelmj/introduction-to-markov-chains-ai-for-text-generation-part-i-eha" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Introduction to Markov chains - AI for text generation - Part I&lt;/h2&gt;
      &lt;h3&gt;MiguelMJ ・ Jul 9 '21&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#ai&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#machinelearning&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#nlp&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;a href="https://miguelmj.github.io" rel="noopener noreferrer"&gt;Let's connect!&lt;/a&gt;

</description>
      <category>javascript</category>
      <category>plt</category>
      <category>computerscience</category>
      <category>beginners</category>
    </item>
    <item>
      <title>How to build a basic REST API in Lua - Milua micro framework</title>
      <dc:creator>MiguelMJ</dc:creator>
      <pubDate>Tue, 17 May 2022 06:13:47 +0000</pubDate>
      <link>https://forem.com/miguelmj/how-to-build-a-basic-rest-api-in-lua-milua-micro-framework-332h</link>
      <guid>https://forem.com/miguelmj/how-to-build-a-basic-rest-api-in-lua-milua-micro-framework-332h</guid>
      <description>&lt;h2&gt;
  
  
  Prelude
&lt;/h2&gt;

&lt;p&gt;I recently started a new project, for which I wanted to build a REST API. Here are the alternatives I considered and why I rejected them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Using a framework I'm more familiar with, in a different language, like &lt;a href="https://flask.palletsprojects.com/en/2.1.x/" rel="noopener noreferrer"&gt;Flask&lt;/a&gt; for Python&lt;/strong&gt;. My project already required Lua and used a bunch of different technologies, so I'd prefer to keep it simple and not add a whole new language and framework to the list.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Using an existing framework in Lua, like &lt;a href="https://leafo.net/lapis/" rel="noopener noreferrer"&gt;Lapis&lt;/a&gt;&lt;/strong&gt;. The problem here was that Lapis relies on third-party software, like Nginx, so the dependencies list would keep growing. This wouldn't be a problem in a more heavy project, but the API I need here is really small, so I would consider overkill anything more than a single technology for it.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Cover image by &lt;a href="https://pixabay.com/users/aloiswohlfahrt-123449/" rel="noopener noreferrer"&gt;aloiswohlfahrt&lt;/a&gt; from Pixabay&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Milua
&lt;/h2&gt;

&lt;p&gt;I felt clearly that what I really wanted was a pure Lua solution. After a bit of research I didn't find any de-facto standard (I might be wrong), but I &lt;em&gt;did&lt;/em&gt; find a &lt;code&gt;http&lt;/code&gt; library by &lt;a href="https://github.com/duarnimator" rel="noopener noreferrer"&gt;duarnimator&lt;/a&gt; that provided an excellent set of functionalities to launch a simple server in a few lines.&lt;/p&gt;

&lt;p&gt;So inspired by the experience of using Flask I made &lt;strong&gt;Milua&lt;/strong&gt;&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/MiguelMJ" rel="noopener noreferrer"&gt;
        MiguelMJ
      &lt;/a&gt; / &lt;a href="https://github.com/MiguelMJ/Milua" rel="noopener noreferrer"&gt;
        Milua
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Lua micro framework for web development
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/MiguelMJ/Milua/doc/logo.svg"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FMiguelMJ%2FMilua%2Fdoc%2Flogo.svg" height="200px"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Milua&lt;/h1&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Lua micro framework for web development&lt;/h3&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/9728520d30f14e3fa3c3a1e55a7301241be1a013a7b61d3df290ffc2bd9cac6c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c75612d352e342d3243324437323f7374796c653d666c61742d737175617265266c6f676f3d6c7561"&gt;&lt;img src="https://camo.githubusercontent.com/9728520d30f14e3fa3c3a1e55a7301241be1a013a7b61d3df290ffc2bd9cac6c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c75612d352e342d3243324437323f7374796c653d666c61742d737175617265266c6f676f3d6c7561"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/8237fbace47a3ffdeeb6c334ef02352a448f12292cba65035945cf7e0a557354/68747470733a2f2f696d672e736869656c64732e696f2f6c7561726f636b732f762f4d696775656c4d4a2f6d696c75613f7374796c653d666c61742d737175617265"&gt;&lt;img src="https://camo.githubusercontent.com/8237fbace47a3ffdeeb6c334ef02352a448f12292cba65035945cf7e0a557354/68747470733a2f2f696d672e736869656c64732e696f2f6c7561726f636b732f762f4d696775656c4d4a2f6d696c75613f7374796c653d666c61742d737175617265"&gt;&lt;/a&gt;
&lt;a href="https://github.com/MiguelMJ/Milua/LICENSE" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/b7bf31ac85269986ebc9e0190e415704570b14926183525342c922106f5b91e0/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d696e666f726d6174696f6e616c3f7374796c653d666c61742d737175617265"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;Milua is inspired by frameworks like Flask or Express, so it just aims to be quick to install and simple to use, enough to prototype any idea you have in mind without needing to worry too much about third-party software.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/MiguelMJ/Milua#preview" rel="noopener noreferrer"&gt;Preview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/MiguelMJ/Milua#features" rel="noopener noreferrer"&gt;Features&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/MiguelMJ/Milua#installation" rel="noopener noreferrer"&gt;Installation&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/MiguelMJ/Milua#troubleshooting" rel="noopener noreferrer"&gt;Troubleshooting&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;a href="https://github.com/MiguelMJ/Milua#contributors" rel="noopener noreferrer"&gt;Contributors&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href="https://github.com/MiguelMJ/Milua#alternatives" rel="noopener noreferrer"&gt;Alternatives&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href="https://github.com/MiguelMJ/Milua#license" rel="noopener noreferrer"&gt;License&lt;/a&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Preview&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;Here's a minimal example of how to use Milua:&lt;/p&gt;

&lt;div class="highlight highlight-source-lua notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-k"&gt;local&lt;/span&gt; &lt;span class="pl-smi"&gt;app&lt;/span&gt; &lt;span class="pl-k"&gt;=&lt;/span&gt; &lt;span class="pl-c1"&gt;require&lt;/span&gt;(&lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;"&lt;/span&gt;milua&lt;span class="pl-pds"&gt;"&lt;/span&gt;&lt;/span&gt;)
&lt;span class="pl-smi"&gt;app&lt;/span&gt;.&lt;span class="pl-c1"&gt;get&lt;/span&gt;(
    &lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;"&lt;/span&gt;/&lt;span class="pl-pds"&gt;"&lt;/span&gt;&lt;/span&gt;,
    &lt;span class="pl-k"&gt;function&lt;/span&gt;()
        &lt;span class="pl-k"&gt;return&lt;/span&gt; &lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;"&lt;/span&gt;&amp;lt;h1&amp;gt;Welcome to the &amp;lt;i&amp;gt;handsome&amp;lt;/i&amp;gt; server!&amp;lt;/h1&amp;gt;&lt;span class="pl-pds"&gt;"&lt;/span&gt;&lt;/span&gt;, {
            [&lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;"&lt;/span&gt;Content-Type&lt;span class="pl-pds"&gt;"&lt;/span&gt;&lt;/span&gt;] &lt;span class="pl-k"&gt;=&lt;/span&gt; &lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;"&lt;/span&gt;text/html&lt;span class="pl-pds"&gt;"&lt;/span&gt;&lt;/span&gt;
        }
    &lt;span class="pl-k"&gt;end&lt;/span&gt;
)

&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;--&lt;/span&gt; Example capturing a path variable&lt;/span&gt;
&lt;span class="pl-smi"&gt;app&lt;/span&gt;.&lt;span class="pl-c1"&gt;get&lt;/span&gt;(
    &lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;"&lt;/span&gt;/user/{username}/tell&lt;span class="pl-pds"&gt;"&lt;/span&gt;&lt;/span&gt;,
    &lt;span class="pl-k"&gt;function&lt;/span&gt;(&lt;span class="pl-smi"&gt;path_params&lt;/span&gt;, &lt;span class="pl-smi"&gt;query&lt;/span&gt;)
        &lt;span class="pl-k"&gt;local&lt;/span&gt; &lt;span class="pl-smi"&gt;times&lt;/span&gt; &lt;span class="pl-k"&gt;=&lt;/span&gt; &lt;span class="pl-smi"&gt;query&lt;/span&gt;.&lt;span class="pl-e"&gt;times&lt;/span&gt; &lt;span class="pl-k"&gt;or&lt;/span&gt; &lt;span class="pl-c1"&gt;1&lt;/span&gt;
        &lt;span class="pl-k"&gt;return&lt;/span&gt; &lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;"&lt;/span&gt;The user &lt;span class="pl-pds"&gt;" &lt;/span&gt;&lt;/span&gt;&lt;span class="pl-k"&gt;..&lt;/span&gt; &lt;span class="pl-smi"&gt;path_params&lt;/span&gt;.&lt;span class="pl-e"&gt;username&lt;/span&gt; &lt;span class="pl-k"&gt;..&lt;/span&gt; &lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;"&lt;/span&gt; is&lt;span class="pl-pds"&gt;" &lt;/span&gt;&lt;/span&gt;&lt;span class="pl-k"&gt;..&lt;/span&gt; (&lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;"&lt;/span&gt; very&lt;/span&gt;&lt;/pre&gt;…
&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/MiguelMJ/Milua" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;



&lt;h3&gt;
  
  
  Installation
&lt;/h3&gt;

&lt;p&gt;I learned how the &lt;code&gt;luarocks&lt;/code&gt;, a lua package manager, works and published the first version, so you can install it with it's dependencies only with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;luarocks &lt;span class="nb"&gt;install &lt;/span&gt;milua
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Examples
&lt;/h3&gt;

&lt;p&gt;Right after, you can try the example that comes in the repository.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lua"&gt;&lt;code&gt;&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"milua"&lt;/span&gt;

&lt;span class="c1"&gt;-- Basic example&lt;/span&gt;
&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;"GET"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;h1&amp;gt;Welcome to the handsome server!&amp;lt;/h1&amp;gt;"&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;-- Example capturing a path variable&lt;/span&gt;
&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;"GET"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"/user/..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;captures&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;captures&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;times&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;times&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;"The user "&lt;/span&gt; &lt;span class="o"&gt;..&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="o"&gt;..&lt;/span&gt; &lt;span class="s2"&gt;" is"&lt;/span&gt; &lt;span class="o"&gt;..&lt;/span&gt;
               &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;" very"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="n"&gt;rep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;times&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;..&lt;/span&gt; &lt;span class="s2"&gt;" handsome"&lt;/span&gt;

    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Launching this would just require you to execute the script after installing Milua. Then, you can test it with &lt;code&gt;curl&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ curl localhost:8800/
&amp;lt;h1&amp;gt;Welcome to the handsome server!&amp;lt;/h1&amp;gt; 

$ curl localhost:8800/user/foo
The user foo is very handsome

$ curl localhost:8800/user/foo?times=3
The user foo is very very very handsome
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Features
&lt;/h3&gt;

&lt;p&gt;For now, version 0.1 as I write, the &lt;code&gt;milua&lt;/code&gt; module only offers two functions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;add_handler(method, pattern, handler)&lt;/code&gt; to associate a method and a path to a handler.

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;handler&lt;/code&gt; function must accept the following arguments:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;captures&lt;/code&gt;: An array with the variables fields of the path, specified with three dots (&lt;code&gt;...&lt;/code&gt;) in the pattern string. In fact, this pattern is just a regular Lua pattern with some syntactic sugar, so you can capture anything you like in your path and be as specific as you want: &lt;code&gt;/([0-9]+)&lt;/code&gt; would capture a path to a numeric value; &lt;code&gt;/admin_...&lt;/code&gt; would capture the destination without the prefix &lt;code&gt;admin_&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;query&lt;/code&gt;: A table with the key-value pairs of the query in the URL (the options that come after the &lt;code&gt;?&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;headers&lt;/code&gt;: The headers of the HTTP request.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;body&lt;/code&gt;: The body of the HTTP request.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;and must return the following values:

&lt;ul&gt;
&lt;li&gt;The body of the repsonse.&lt;/li&gt;
&lt;li&gt;(Optional) A table with the headers of the response.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;start(config)&lt;/code&gt; where config contains the &lt;code&gt;host&lt;/code&gt; and the &lt;code&gt;port&lt;/code&gt; to run the application.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;There is still room for a couple of modifications that would keep the complexity at the same level, like adding error handlers (to allow a &lt;code&gt;404.html&lt;/code&gt; page, for example) or specifying directories for static files. For example, it has no templating functionalities (maybe in a future), but you can require any of your preference and use it in your app. But for now it servers its purpose and it's compatible with anything you want to throw at it, thanks to its minimal nature.&lt;/p&gt;



&lt;p&gt;I'm still learning about Lua and its tools and might write more about this language in the future. What's your experience with Lua? Have you used before for web development? I'll be happy to read any comment you have!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Recommended reading&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag__link"&gt;
  &lt;a href="/miguelmj" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F449565%2Fc9a30852-1361-49c8-aa13-c385fd0c0b33.png" alt="miguelmj"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/miguelmj/data-structures-in-prolog-where-to-start-53gm" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Data structures in Prolog - Where to start&lt;/h2&gt;
      &lt;h3&gt;MiguelMJ ・ Jun 15 '21&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#prolog&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#datastructures&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#resources&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;



&lt;div class="ltag__link"&gt;
  &lt;a href="/miguelmj" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F449565%2Fc9a30852-1361-49c8-aa13-c385fd0c0b33.png" alt="miguelmj"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/miguelmj/how-to-get-answers-on-stackoverflow-3pp7" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;How to get answers on StackOverflow&lt;/h2&gt;
      &lt;h3&gt;MiguelMJ ・ Feb 6 '22&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#beginners&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#codenewbie&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#productivity&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;



&lt;p&gt;&lt;a href="https://twitter.com/MiguelMJdev" rel="noopener noreferrer"&gt;You can follow me on Twitter! 🐦&lt;/a&gt;&lt;/p&gt;

</description>
      <category>lua</category>
      <category>webdev</category>
      <category>api</category>
    </item>
    <item>
      <title>Hackathon submission - Idea: Group dynamics analysis</title>
      <dc:creator>MiguelMJ</dc:creator>
      <pubDate>Fri, 08 Apr 2022 10:45:55 +0000</pubDate>
      <link>https://forem.com/miguelmj/hackathon-submission-idea-group-dynamics-analysis-13dd</link>
      <guid>https://forem.com/miguelmj/hackathon-submission-idea-group-dynamics-analysis-13dd</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;Well, this is my third submission for this hackathon. I guess Automatic Speech Recognition (ASR) really inspired me. This time I'm participating in the &lt;strong&gt;Innovative Ideas&lt;/strong&gt; challenge because I don't know if I'll have time to program anything else and I prefer just to write.&lt;/p&gt;

&lt;p&gt;Natural Language Processing (NLP) and conversational interfaces are one of my favorite topics in technology. That's why I've tried to find interesting use cases for ASR, more than just plain transcription functionalities, which is just a little part of what Deepgram provides. I was surprised to discover how easily you could get other useful data like timing (timestamps of start and end of words) and source recognition (differentiate speakers). We know there's a lot of useful information in speech and I think that's the main reason I've felt so inspired. I'll write more in depth about my thought process behind each submission in the next and final post of this series.&lt;/p&gt;

&lt;h3&gt;
  
  
  My Deepgram Use-Case
&lt;/h3&gt;

&lt;p&gt;For a long time, I've been interested in &lt;strong&gt;group dynamics&lt;/strong&gt;. We all know from experience that each person feels more motivated to participate in different groups or to talk about certain topics. I think it's important to observe the behavior of each speaker and their reactions in different situations in order to create more comfortable and productive conversations in the future.&lt;/p&gt;

&lt;p&gt;So one possible use case for Deepgram and ASR technology could be to analyze recordings of meetings to extract &lt;strong&gt;useful information about the dynamics of a group&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;What topic makes the quiet one speak more? What kind of words prevent interruptions? What topics are more polemic to certain people?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This kind of analysis would be useful in cases like work meetings, community moderation and even psychology experiments.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dive into Details
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Technical approach
&lt;/h4&gt;

&lt;h5&gt;
  
  
  Get the data
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;First of all, the program would use Deepgram to &lt;strong&gt;get the punctuated and diarized transcription&lt;/strong&gt;, with additional information about the utterances.&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  Enrich the data
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;From that information, it would &lt;strong&gt;reconstruct the conversation&lt;/strong&gt;, separating the intervention of each speaker, counting the number of utterances and also the time separating each one. It might be interesting also to mark profanity.&lt;/li&gt;
&lt;li&gt;Now we could find anomalies in the time separating interventions to &lt;strong&gt;detect possible interruptions&lt;/strong&gt; or long silences.&lt;/li&gt;
&lt;li&gt;Then, it might be necessary to make several runs of LDA (Latent Dirichlet Distribution) to &lt;strong&gt;find the topics&lt;/strong&gt; treated in the conversation, when they change, who brings them, etc.&lt;/li&gt;
&lt;li&gt;Similarly, it would run several &lt;strong&gt;sentiment analyses&lt;/strong&gt; by topic, by person, by intervention and of course a general one.&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  Summarize and present the data
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;With some probabilistic analysis, it could be possible to estimate &lt;strong&gt;correlation&lt;/strong&gt; with interruptions, silences, topics, topic changes, people, sentiments, etc. &lt;em&gt;I would propose either a Bayesian network or a Rule discovery algorithm, like Apriori&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Finally, the program would make a &lt;strong&gt;summary of the interventions of each person&lt;/strong&gt;. Some possible data to extract would be:

&lt;ul&gt;
&lt;li&gt;Time spent speaking&lt;/li&gt;
&lt;li&gt;Topics where they intervene more/less.&lt;/li&gt;
&lt;li&gt;Who speaks usually before or after them.&lt;/li&gt;
&lt;li&gt;Sentiment correlation with topics and other people.&lt;/li&gt;
&lt;li&gt;Most repeated words.&lt;/li&gt;
&lt;li&gt;Exceptional words. By this I mean relevant words that nobody else said or that has little relation with the topics of the conversation... You never know if you'll learn something important about that speaker.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h4&gt;
  
  
  Application
&lt;/h4&gt;

&lt;p&gt;One of the first things I realized was that this wouldn't be of much use in controlled environments, like interviews. The interest comes from &lt;strong&gt;natural dynamics that arise from the interaction between individuals&lt;/strong&gt; when discussing everyday topics.&lt;/p&gt;

&lt;p&gt;So one clear context where this could be useful would be work meetings, that can be recorded and analyzed. However, I feel like recording conversations in other settings is somewhat intrusive, so I can't actually propose specific, additional use cases. As I said before, maybe use it with event recordings for community moderation and somehow in psychology experiments... &lt;strong&gt;I'm interested in what's your opinion and what case can you come up with&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Edit:&lt;/em&gt; I've been told that there's an interesting use case, related to studying cultural differences. There are cultures where an interruption meant to express agreement is considered polite, while in others the convention is to leave seconds of silence between interventions. I guess that another application would be to study &lt;strong&gt;group dynamics in multicultural groups&lt;/strong&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;I've had real fun thinking and working on this hackathon, so thanks a lot to Deepgram and DEV for organizing it. As I said at the beginning, I've felt really inspired and I'm sure I'll work further with the projects born from it. I'll soon post the last post of this series, &lt;/p&gt;

</description>
      <category>hackwithdg</category>
    </item>
    <item>
      <title>Hackathon submission - Interactive conversation scripts for language learning</title>
      <dc:creator>MiguelMJ</dc:creator>
      <pubDate>Sun, 03 Apr 2022 10:35:18 +0000</pubDate>
      <link>https://forem.com/miguelmj/hackathon-submission-interactive-conversation-scripts-for-language-learning-110c</link>
      <guid>https://forem.com/miguelmj/hackathon-submission-interactive-conversation-scripts-for-language-learning-110c</guid>
      <description>&lt;h2&gt;
  
  
  Overview of My Submission
&lt;/h2&gt;

&lt;p&gt;My second submission consists on a tool designed for languages teachers and students. Audios with recorded conversations are a common and good resource in language lessons, so I thought it would be useful not only to have a transcription to read while you listen, but also make them interactive to show phrase by phrase translations and to quickly navigate the audio to listen again certain part of the conversation.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Cover image by &lt;a href="https://www.pexels.com/@filirovska/" rel="noopener noreferrer"&gt;Julia Filirovska&lt;/a&gt; from Pexels&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Submission Category
&lt;/h2&gt;

&lt;p&gt;Accessibility Advocates&lt;br&gt;
Wacky Wildcards&lt;/p&gt;
&lt;h2&gt;
  
  
  Link to Code on GitHub
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/MiguelMJ" rel="noopener noreferrer"&gt;
        MiguelMJ
      &lt;/a&gt; / &lt;a href="https://github.com/MiguelMJ/Scripter" rel="noopener noreferrer"&gt;
        Scripter
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Create interactive scripts from recordings for language learning. Deepgram + DEV hackathon submission.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Scripter&lt;/h1&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Create interactive scripts from recordings for language learning&lt;/h3&gt;
&lt;/div&gt;
&lt;p&gt;
    &lt;a href="https://www.python.org/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/9431caa7ebd7dfb99a4f42f0e0fc369ffbe8668d118be24fc601363aca55da2e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f2d507974686f6e5f332d626c61636b3f7374796c653d666f722d7468652d6261646765266c6f676f3d707974686f6e"&gt;&lt;/a&gt;
    &lt;a href="https://deepgram.com" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/58d1f9f815fa8f6f0663e524a062162796db123d45e082476c56d38d85b9e5c0/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f2d446565706772616d2d626c61636b3f7374796c653d666f722d7468652d6261646765"&gt;&lt;/a&gt;
    &lt;a href="https://github.com/LibreTranslate/LibreTranslate" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/2eea6b0c3e52be0cadac3fcf68f7024199d8f0be1b5f71208463b3a819d3a311/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f2d4c696272655472616e736c6174652d626c61636b3f7374796c653d666f722d7468652d6261646765"&gt;&lt;/a&gt;
    &lt;a href="https://github.com/MiguelMJ/Scripter/LICENSE" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/d2bb5d3ade63f60d274a491547c227313238cfea625b9308c6ec48036cd84fde/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d626c61636b3f7374796c653d666f722d7468652d6261646765"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;Create interactive HTML5 pages with a script from a recorded conversation. Powered by Deepgram. Requires API key from Deepgram. Submission for Deepgram+DEV hackathon, 2022.&lt;/p&gt;

&lt;p&gt;Yout might want to read the &lt;a href="https://dev.to/miguelmj/hackathon-submission-interactive-conversation-scripts-for-language-learning-110c" rel="nofollow"&gt;submission post&lt;/a&gt;, where you will also find a demo.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Get the API key&lt;/h2&gt;
&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Deepgram (required): Create an account in deepgram.com and get an API key.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Store it in a file named &lt;code&gt;deepgramApiKey&lt;/code&gt; in the root folder or pass it directly in the CLI using the &lt;code&gt;--deepgram-api-key&lt;/code&gt; argument.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Features&lt;/h2&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tune the voice recognition process&lt;/strong&gt; with the Deepgram &lt;a href="https://developers.deepgram.com/api-reference/#transcription-prerecorded" rel="nofollow noopener noreferrer"&gt;query parameters for transcriptions pre-recorded audio&lt;/a&gt; with &lt;code&gt;-P|--param KEY=VALUE&lt;/code&gt; arguments.&lt;/li&gt;
&lt;li&gt;Downloads and results are &lt;strong&gt;cached to reduce redundant traffic&lt;/strong&gt;, but you can force it using the &lt;code&gt;-F|--force&lt;/code&gt; flag or directly removing the &lt;code&gt;_cache&lt;/code&gt; folder.&lt;/li&gt;
&lt;li&gt;All log information outputs through stderr and the search output through stdout (or a file, with the &lt;code&gt;-o|--output-file FILE&lt;/code&gt;…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/MiguelMJ/Scripter" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2&gt;
  
  
  Additional Resources / Info
&lt;/h2&gt;

&lt;p&gt;This time I reused most of the code from my previous submission. In that one I forgot to tell a bit of background, so as most of the code is the same, I will do it here.&lt;/p&gt;

&lt;p&gt;In spite of using Python for the program, I didn't want to use the Deepgram SDK. I know other participants have done the same; in my case, it's just because I'm used to making HTTP requests for lots of things, so I chose not to add more dependencies to the application. I felt that the Deepgram API is accesible enough for me.&lt;/p&gt;

&lt;p&gt;I've once more used another API: LibreTranslate. This time, the difference is that LibreTranslate is a open source API, so there are different available mirrors, and you can even set up one yourself, so I allowed the user to specify which one to use with a &lt;code&gt;-H|--host&lt;/code&gt; parameter and made a quick guide on it on the README.&lt;/p&gt;

&lt;p&gt;I'm not actually a webdev person, so the resultant HTML file might not be very polished, but I thought is more than enough for a prototype. I learned to use the &lt;code&gt;&amp;lt;audio&amp;gt;&lt;/code&gt; element of HTML5 and manipulate it via JS, which is nice. Thanks to it and the rich information returned by the Deepgram API, the interactive scripts have the following features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The audio is embedded in the HTML file, so it can be played directly from there (as long as the path of the source audio doesn't change).&lt;/li&gt;
&lt;li&gt;Each sentence of the audio is printed in a different color, according to who is the speaker.&lt;/li&gt;
&lt;li&gt;If you hover over a sentence, the translation to your language (if supported) appears.&lt;/li&gt;
&lt;li&gt;If you click on a sentence, the audio plays only the sentence you clicked on, making it more easy to replay specific parts of the audio.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's a little demonstration on this features.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/RYa6a9MX8-U"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;I recorded a short, sample conversation with my sister, who also provided the voice recorder. Some notes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The translation on hover is not immediate because it uses the &lt;code&gt;title&lt;/code&gt; HTML attribute, that has a little delay.&lt;/li&gt;
&lt;li&gt;If you speak Spanish (or have a good ear) you'll notice that for the 4th intervention, it doesn't notice that it's a question, so both the transcription and the translation are wrong. That's what happens with automation!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In any case, I think it's neat and even those little mistakes made by the audio recognition and translation can be manually fixed by the teacher, and most of the work would be automatic.&lt;/p&gt;

&lt;h3&gt;
  
  
  Possible future improvements
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Allow usage of output templates.&lt;/li&gt;
&lt;li&gt;Add some tool for easy manual fixes.&lt;/li&gt;
&lt;li&gt;Enable more flexibility on the options to use different services, if the user wants to.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;I hope you like it! And if you are a language teacher or student, feel free to use it and please, give me some feedback!&lt;/p&gt;

</description>
      <category>hackwithdg</category>
      <category>showdev</category>
      <category>python</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
