# Simorg — full documentation dump for AI agentsGenerated for machine consumption. Prefer individual /raw/docs/*.md URLs when possible.Site: https://simorg.art/ ===== BLOG: Status Update (https://simorg.art/blog/status-update-genesis-version) ===== $$$Image fileName=the-future.jpg$$$ The first PoC release of simorg, code named <<>>, is available by May 23rd, 2026. This version is important because it ships the first release of simorg engine and the toolchain behind it so that our early adopters can try the basic functionalities of the language. <<>> is a <<>> release. While we are moving toward a stable version 1, it's quite important to make it possible for our early adopters to test the technology. ## What Can Go Wrong? We are still in the middle of the development. As an early adopter, you may experience, - Occasional crashes or unexpected errors. - Potential data loss or instability inside simorg applications. - Frequent updates as we patch the issues. - Unclear error logs. - Low performance as the software is in debug mode. ## Why A PoC Release You may ask, why then having a release when the software is not finalized. The answer is that we like to make it perfect with the help of our early adopters. Instead of spending time and waiting for an ideal release, we prefer to release early and receive feedback. Existing PoC version is all about core functionality of our engine and programming language. We believe there are enough features that our early adopters can start using our technology and share their opinions with us. This is important as we want to hear from you as soon as possible. ## What Is Next? Major milestones are documented under our $$$ToPageLinker keyword=Milestone Page toRoute=/milestones$$$. Meanwhile, we will provide frequent updates and enhancements all the time on a weekly basis. These updates include fixes to the above mentioned issues, enhancements and new features to different parts of our engine, compiler and toolchains. ## How You Can Help If you are an early adopter that wants to join our community and test our early versions, then the best way is to download and setup your local environment and test our product. Currently, due to lack of necessary resources, the source code is not available on GitHub BUT hopefully it will change in future. Meanwhile, don't forget to watch or star simorg's $$$ToPageLinker keyword=Engine Repository toRoute=https://github.com/simorg-platform/jerusalem-engine/tree/main$$$ on GitHub ;). Sharing issues and starting discussions in this phase of the project is important. For now GitHub Issues are the only channel for kick staring discussions or sharing issues. ## Please Be Mindful Simorg is not a full-fledged company at the moment. There are many things that need to be taken care of and the team has limited resources. Please expect delays in responses and be patient with support requests. The important fact is that we hear you and respect your time and effort. Every single message and comment will be read and no AI tool is in between you and us. For more details regarding this release, please refer to version $$$ToPageLinker keyword=Release Notes toRoute=/releases?version=genesis-0-1-0 $$$. ===== BLOG: Words to Create Worlds (https://simorg.art/blog/words-to-create-worlds) ===== $$$Image fileName=words.jpg$$$ In this article we will read more about Simorg's new approach in software engineering. We discussed the foundational layer of simorg in previous blog post, now it's a good time to see how the implementation of those fundamental rules is helping us having a better technology. This blog is about simorg's technology and programming language. Words are the channels of power and energy! Even after thousands of years this belief of our ancestors is holding true. As it seems the languages and words are the best medium of capturing and transferring the consciousness. Part of simorg's technology is its programming language. We deliberately use the same name and don't see this language separated from the platform. Simorg's language is quite young and in its early days but still it is important to discuss some of its aspects. Software engineering using digital computers is relatively a young field of engineering but still it had enough time so that we can analyze and understand some aspects of it that are making problems. Without any doubt, some of the bad parts that we experience these days are the result of an ontology of the programming language that we use - even if it exists! Let's follow a Problem-Solution approach. # Wisdom, Understanding And Consciousness ## Nothingness, No More As a developer we are all familiar with values like <<>>, <<>>, <<>>, <<>>, <<>> and <<>> even a few more. Classical Programming Languages (CPLs) still care about nothingness. But let's wait for a second and think about it. Why we are caring about nothingness? Is it possible to treat nothingness and void the same way as existence and being? Why are we mixing them? Isn't it more appropriate to see nothingness as a transitory step in the process of creation rather than a state of being? The way simorg reached to the conclusion that nothingness should have no place in a universe of existence goes back to the fundamental layer of Simorg. It is not wise to give nothingness the same value of existence. It is interesting that semitic ontology had a clear vision about nothingness and even Hebrew Bible is using different verbs to refer to concepts that involve nothingness. This is a topic of another blog post. For now let's focus on technical aspect of it. The goal was clear. In simorg's ontology nothingness and void are considered as temporary steps in the process of creation handled by the engine. In other words when a being is becoming into existence, nothingness is respected. Let's consider the example of darkness and light. Darkness can be seen as nothingness for light because there is no light. If you are looking for light you should not care about darkness. Darkness or nothingness only exists because there is no light or existence. Eventually light will become available and a driving force. The light in this case can be seen as Vibration or data, the result of processing. So Simorg achieves a nothingness-free architecture by re-arranging the building blocks of a digital system. Giving priority to light and ignoring anything else. So simorg considers the vibration and data as the light of the beings. Combining a data-driven pattern with an event-driven pattern makes simorg able to completely remove nothingness. These two together are representing vibration. ## A Mathematical Engine Simorg's runtime is a mathematical engine. Actually high-level user's code is interpreted into a set of mathematical entities. These mathematical entities are built based on Fourier Series/Transforms, a wonderful mathematical modeling tool on top of sine waves. Using this amazing tool, we can model our application entities in frequency-domain of signal processing so making it possible to have the concept of vibrations and frequencies. Without going into scientific concepts, the goal was to achieve a byte-level event-driven pattern, this all is happening thanks to a mathematical engine, aka Jerusalem Engine. As discussed in other blog post, the three layer architecture of simorg helps solving technical requirements by separation of concerns into their own layer. When for example simorg aims to completely remove nothingness from the existence, each of the three layers contributes to how this needs to be done. Using a mathematical/physical model to represent digital entities naturally contributes to the goal of removing nothingness from existence. So can you think of a moment that you saw nothingness in mathematics? well if you are thinking about 0 this is not the case as 0 is representing emptiness which is a valid form of existence as its definition is driven from existence. What about physics? how nothingness can vibrate? ## A Vibration Driven Architecture The decisions that are made on technical layer are direct implications of what we discuss in previous topics. If we want to remove the nothingness in technical layer then we should rely on something that guarantees the existence. Data is the only entity that can guarantee its own existence. Let's not forget in simorg's ontology, data is also equivalent to existence. Simorg achieved a data-driven pattern by re-shuffling and re-creating the existing forms so that data now is the driving force behind processing which is unique to simorg language. Finally, data needs a mechanism of interaction, it is called vibration. A vibration is the driving force of any dataflow. Shells are data containers which at some point are ready to release their data or according to physics, their energy hence generating a vibration. Now this phenomenon of releasing data from a shell is called vibration. A vibration in terms of execution is quite similar to Event in a classical programming language. But the difference is that unlike events in CPLs, simorg vibrations are the driving force behind the processing because they are guaranteed to contain data and processing is driven by data. So vibration can be defined as the combination of data and event that a shell releases as soon as its condition is met. A simple calculation like ``` 1+2 : x ``` is shaped around multiple vibrations that happen simultaneously or sequentially. This is a byte level data and event driven pattern or as we call it a vibration-driven pattern. ## Fighting The Illusion No one can ignore the roles of functions and arrays in today's software engineering. But again let's pause and see what are the implications of these decisions so far. Issues like dangling pointers, undefined and null objects, index out of bound exceptions and many more, are the results of a functional approach. Even the concept of exception which causes an application to abruptly terminate itself is a result of functional thinking. What about an alternative solution? What if we can replace functions with something else? What if we don't need to use arrays the way we use them today? Actually many decisions that are made in software engineering are due to historical reasons and our understanding of phenomena around us. The concept of a universe that is working based on functions is not new but we should ask, is it really the case? Is our universe function based or more event based? Simorg's answer to this question is that our universe is more aligned with an event-driven architecture. Everything exists in order to affect or being impacted. As a result Simorg has no functions but shells. Shells are enclosed digital atmospheres that may have holes on them through which vibrations can pass in and out. So holes themselves are direction agnostic. Again the concept of input and output is a functional concept but the nature doesn't care about direction but more about conditions of vibration. If data can pass one way it will pass and we don't have to think about direction. As another example let's consider arrays, this is another topic that our illusion is affecting our decisions. Do we need arrays or containers? One may say these are the same but simorg differentiates them. Arrays are independent entities of being that have their own memory and functionalities. But Simorg containers are another type of shells, their existence is a direct result of data and they do not have independent identity. This is a major difference between simorg containers and arrays. Please check Collector Operator in our reference book to experience how simorg takes care of collective data. So next time you went for buying some groceries, pay attention to the queue. Isn't the queue built on top of data? How a queue can exist when there is no customer in the shop? Using Simorg containers we create temporary placeholders in middle of our dataflow and streams. There is no indexing logic for containers as Data itself is responsible for its existence. In certain scenarios like sorting requirements, external plugins can be used. Although, simorg presented an experimental dataflow operator called Dimension Operator by which one can filter certain elements inside a collector or gate. ## Language Syntaxes Languages and their implications on our thinking is a fascinating topic in history of our consciousness. There are patterns behind every language that are rooted in much deeper realities. Simorg's language is not separated from these patterns. After all, languages are the paths on which the consciousness flows so that the meaning and idea reach their destination and purpose. Simorg's language is embracing simplicity. Being built on top of a mathematical runtime, it inherits some of the mathematical aspects of the engine. For example the concept of gates in classical logical circuits is now reformed into a collection of elements vibrating based on certain conditions. Also, the way simorg managed to remove some of the reserved keywords e.g. <<>>, <<>> is due to the natural flow of streams of data in the code. Adding to the list is the way equality operator = is acquiring back its mathematical meaning which is a symbol of equality. The classical usage of = operator known as assignment no longer is needed in simorg again due to the way data is flowing in the system. So we are not writing code to create a third party watchdog but we are writing code to give data the consciousness it needs to flow naturally. All the syntaxes that language provides are from data's point of view not from an external observer's view. It's interesting to share that what happened in language's syntax was not intentional and it came as a result of simorg's processing model. So there was no intention to remove <<>>, it turned out the language is even much simpler when we don't have any reserved keyword. Simorg believes the best rule is to have no rules. Simplicity, in itself, is beautiful. The best programming languages are those that do not turn humans into machines. In other words, machine problems should be solved by machines, while the minds of artisans are too lofty to be constrained by the rules and syntax of a programming language. This philosophy is reflected not only in our language, but also in the overall architecture of the platform. # How We See The Future Simorg as a platform is aiming to act as a glue between agents and digital elements. Each digital element has its own unique identity in the platform and is able to connect to others. Consider AI agents, models, 3D components, IoT devices, binaries and literally all kinds of digital elements being able to communicate and see each other using a common language and form. This is possible thanks to our mathematical representation of the universe. Simorg's mathematical architecture is giving the technology the opportunity to shine in two different sectors. AI and Metaverse. Let's discuss a bit more about each of them. ## Next Generation AI Native Applications Mathematical nature and runtime of simorg makes it possible to build hybrid applications which are benefitting from both, a classical processing model and, an AI-powered processing model. While our application starts processing the data using classical approach, it can train a micro-model at the same time so making it possible to understand repetitive patterns that are repeating over and over again so to avoid repeating expensive processing for them and to generate the correct output using less processing power. This is our vision for future of Simorg's engine. Of course we are in early steps toward this goal but the structure of engine is promising breakthroughs in this regard. ## Metaverse Friendly Applications Mathematical entities have amazing characteristics. They are extremely loosely coupled. You can shift, arrange, add, remove elements in a mathematical system with ease. Also, scalability is another aspect of any mathematical universe. The only limit is the processing and memory resources. Having every single digital element modeled as a unique mathematical entity, represented by Fourier Transform, provides a holistic unified approach in shaping next generation digital universes. From 3D components to IoT devices, engine sees them as mathematical entities which are represented as shells able to interact with other elements using the most native language of nature, the mathematics and by emitting vibrations. ## Future Of Simorg Applications that we create are a reflection of our consciousness. History of software engineering is showing an undeniable trend, our processing models are becoming more and more conscious each and every day. The race is not about processing time or performance but technologies which are providing higher level of consciousness, are the ones that lead the future. Simorg is not separated from this trend. Focusing on data and consciousness in core layers of our technology is a direct result of this observation. Although, we are focusing on software but having an eye on hardware helps us to see the reality which is unveiling a bit slower. Recent breakthroughs in AI are accelerating the emergence of new hardware architectures that are more and more powerful in running mathematical calculations. Classical multi-core CPUs are acting more and more as process managers rather than doing heavy processing required by modern day applications specifically in AI and 3D environments. Early versions of Simorg are running on CPUs but the mathematical runtime of simorg and discrete nature of its calculations is paving the way for next generation software that is going beyond the boundaries of a binary processing model. Detaching from classical software runtimes which are mostly inspired by CPU instructions we now have the opportunity to run our software in a new set of hardware in order to overcome existing limitations. The joy of creation is embedded in the human soul, we wish simorg will be a better tool in your hands to unlock this ability. Happy creation! ===== DOC: reference-book/1-introduction/words-creating-worlds (https://simorg.art/docs/reference-book/1-introduction/words-creating-worlds) ===== Software is a fascinating field of engineering. The act of creation involves transmitting our consciousness into a new dimension. This new dimension of time and space is built on top of the hardware we use, CPUs and memories. This makes software engineering so unique. This blog is designed to help you get the most out of Simorg’s technology. Simorg is not just another programming language! It is a new mindset and philosophy for software engineering! In this chapter, we will spend some time exploring Simorg’s ontology and worldview. ## Why Simorg? Simorg is a Programming Language as a Platform digital product. Its purpose is to enhance our digital experience—for both engineers and end users. To create a coherent digital universe, we first need a programming language that is aligned with that universe’s requirements. Simorg Language should be seen as a foundational tool for building the next generation of applications which, together, can form a unified digital universe. Using this approach we are envisioning to create a new experience for our digital users which is aligned with the latest technical breakthroughs in AI and Metaverse. ## What Is Different About Simorg? Recent breakthroughs in digital technologies—especially AI and Metaverse-related tools—have opened a new horizon of possibilities. We cannot fully benefit from this new era with an old mindset about software engineering. We need innovation. Today, we need to re-visit every fundamental agreement, rule and assumption. Simorg provides a new mindset for programming in which data is owning the processing not the other way around! When writing simorg code, we always think about the data and how it will flow. Our code will guide data toward its destination. In this model, data is no longer a passive element of our digital universe but a first class citizen that is absorbing the consciousness from the code which of course is generated by a conscious mind whether being a human or agent (which still is inheriting a collective consciousness). So a conscious entity transfers its consciousness (aka business logic) into code, creating a conscious environment and data flowing in this environment so absorbing this consciousness and fulfilling the goal. Simorg comes with “batteries included” for the next generation of digital applications. You can think of Simorg as “version 2” of programming languages. Simorg doesn't see a language as a passive tool of building but a medium by which a conscious entity transfers the consciousness into a new dimension, into a digital universe. It's a version 2 as it introduces a totally new form and ontology and architecture on how we should see the software. ## What Is Important About Simorg? Consciousness is a key ingredient in many fields of engineering, but it is especially dominant in software engineering. Simorg is the first programming language that explicitly recognizes **Consciousness** as a fundamental ingredient in its processing model. Simorg also starts from a new definition of “problem,” which naturally leads to a very different definition of “solution.” In classical programming languages—referred to here as **CPLs**—processing and data are separated. In a CPL, data is treated as a passive element to which processing is eventually applied. This separation is the root cause of many software incidents and exceptions. We are introducing a new form to solve this problem. Simorg’s solution is to make data conscious enough to participate in deciding how it should be processed. By writing simorg code, your consciousness eventually reaches all the way to the data itself. The code that we write is not always directly about data itself but mostly about the channels and pathways in which data flows. This approach leads to a new generation of applications which are quite AI and metaverse friendly. We are not going to create these applications but our artisans will do it. Simorg must be seen as a technology provider. ## What Is Irrelevant To Simorg? One should avoid seeing simorg as a generic language. In comparison with other programming languages, simorg is a lightweight, high-level scripting language focusing on solving the problem in existing AI and Metaverse sectors of Information Technology. Low-level functionalities are injected into simorg's runtime, thanks to artifacts. We will see them in future chapters. Artifacts are written and published in our package manager by artisans using c, c++ or rust etc. So avoiding certain language features is a strategy that helps us maintain a focus on areas that we think need urgent enhancement. ## How Does Simorg Do This? Simorg models its digital universe differently. In Simorg’s worldview, many classical forms and conventions of software engineering are critically reviewed and, when necessary, replaced to create new opportunities and value. Understanding this worldview is crucial if you want to write Simorg Code in the way it is intended to be written. ### Rules of Creation Our universe is a masterpiece: a finely tuned ecosystem of independent entities interacting with one another in a cohesive and holistic way. When it comes to creating a new programming language (or a new digital universe), we do not need to reinvent the wheel. Instead, we need to understand the principles of this universe and implement them in our digital one. This is how Simorg approaches the problem. We can't see a programming language in isolation, the words have the ability to capture the consciousness and on top of that consciousness worlds can be built. The success is about the ecosystem that we build or as we call it a digital universe. Thinking about the answers to those questions are essential for the success of the language. ### A Mathematical Runtime When we gradually move from those fundamental questions more toward implementation, it became clear that only a mathematical layer could satisfy simorg’s requirements. While a classical programming language compiles high-level human code into a set of binary instructions, Simorg’s Code is interpreted into a set of mathematical entities that interact inside Simorg’s mathematical engine or runtime. This interaction creates a dataflow through which, at a higher layer, the behavior we declare in our high-level code manifests itself. Like many other programming languages, Simorg is a tool for creation—but its approach leads to some remarkable consequences. For example, simorg has no concepts representing <<>>, <<>>, <<>>, <<>>, <<>>, and so on. There is also no garbage collector in Simorg. For similar reasons, Simorg does not include some familiar constructs such as <<>> and <<>>. Even Simorg’s lexer does not rely on reserved keywords, which means that if you wish, you can define a variable and name it <<>>. In order to create your own world, you must first express it through words. This is the beginning of your Simorg journey. We wish you a journey full of joy and consciousness. ===== DOC: reference-book/1-introduction/energy-vibration-and-shell (https://simorg.art/docs/reference-book/1-introduction/energy-vibration-and-shell) ===== Let's introduce three high-level abstract concepts. In Simorg's world, everything exists in the form of a **Vibration**. The concept of **Vibration** is similar to <<>> in a **CPL**, but soon we will see it's more than that. Let's see it by an example, ``` $myVar ``` here <<>> is a variable and at some point it can be vibrated. Now, each Vibration needs a space. According to programming language terminology these spaces are called scopes. For example putting our variable inside curly braces like, ``` { $myVar } ``` Simorg calls these spaces a **Shell**. Shells are a fundamental part of simorg's world modeling. Everything is a Shell and Vibrations are always wrapped in a shell. Simorg doesn't have the familiar concept of functions anymore. Although in some use cases the shells are appearing as classical functions. Shells can wrap each other to create more complex structures. So the whole universe of simorg is build on top of interactions between vibrations and shells. Long story short, the goal of writing simorg code is to create spaces in which data flows in order to become more conscious. This behavior can be seen when we add a const vibration to our app like, ``` { "Hello World!" $myVar } ``` This simple application can be represented by this shell diagram. As the engine starts, our <<<"Hello World!">>> value literal is first to vibrate. Then this vibration is reaching our variable <<>> and causing it to vibrate. $$$ShellDiagram diagramId=REFERENCE_BOOK_0_INTRO_02_ENERGY_VIBRATION_AND_SHELL_HELLO_WORLD$$$ This diagram is using a slow motion animation to show what is happening behind vibrations and how they are wrapped by shells so creating new layers of data. Each color is representing a unique identity, or according to simorg's terminology a **Frequency**. As the vibrations move between shells, they are acquiring different frequencies. Frequency is the unique characteristic of a shell. So simorg's engine is providing a medium in which the vibration can shape and flow. When a shell vibrates it adds its characteristic to underlying vibration (data). Thanks to this newly added layer, the data (vibration) becomes more conscious so it can flow inside more spaces and vibrate more shells. This cycle continues forever until data is reaching its destination. Now that we have some basic ideas about **Vibration** and **Shell**, we can explain the **Energy**. Actually, both Vibration and Shell are dealing with Energy in one way or another. A Vibration is a source of Energy that has been released. We call it vibration and not an "event" because it is an active element and a driving force of our application hence the energy. A Shell, on the other hand, is acting as a container/channel/vessel/space in which this energy can be at rest or flow. So Vibrations can happen inside a shell or later we will see they even can impact shells by entering or exiting from them. While vibrations are flowing in the system, they usually pass from multiple shells. These interactions gradually add new characteristics to our vibrations. We will discuss it in more details in next section. As developers, we usually deal with data, and based on the business rules we decide how data should flow in our code. In Simorg, data is the vibration or energy. So in the above example, we can consider the <<<"Hello World!">>> string as our data which, is vibrated by Simorg's engine so it can flow in our system. Everything starts with a vibration. As mentioned before, Simorg is changing the classical forms and brings a new form of thinking about software and digital elements. Simorg equates Existence with vibration. Everything in the engine e.g. variables, constants exist because they can vibrate. In Simorg’s ontology, each being exists in order to create an impact and/or to be influenced in return. This leads to a purely byte-level, event-driven worldview which is executed by data hence we call it vibration. In a not shell a vibration is representing an event and data driven paradigm woven together becoming the same. Thanks to this approach Simorg completely removed the abstract unnecessary concept of Nothingness (null, undefined, None, nil etc.). How Nothingness can contain energy to flow? $$$AlertBox type=INFO title=Amazing Topic Of Nothingness message=For many years owners of thought were puzzled by the concept of nothingness! Of course the state of nothingness is a valid state in the process of creating a new universe but it needs to be handled naturally. We as software engineers have seen the down side of mixing nothingness and existence in past decades by experiencing all forms of exceptions and errors in this regard! We forgot that nothingness doesn't need its own handlers but it should be solved by existence itself just as how the light removes the darkness $$$ Now, when you hear the terms vibration, energy and shell, the first thing that comes to mind is a physical system—and that is totally fine. Physical concepts are wrapping low-level mathematical concepts. So in order to be able to create a digital universe on top of our mathematical engine, we need to first create a physical layer on top of it. The limitless nature of mathematics needs to be limited by physical rules in order to create a bounded digital universe. Don't worry if these concepts sound a bit unusual at first glance. Soon we will see how they work in action using many examples. ## About Runtime Let's briefly talk about simorg's engine. Pure event driven nature of simorg is introducing new paradigms in programming. In this approach, the order of the code is no longer important, unless for some reason you decide to make it important. Vibration is determining what needs to go next not the line of the code that we write. Of course variable declaration is the only exception to this rule. A Variable declaration needs to be done before the usage. For now we are just focusing on logic. For example, these two code snippets are equivalent and both of them will successfully log the value of <<>> using logger operator <<<:?>>> the same exact way. ``` $x 10 x x ? // logger is after variable's assignment ``` ``` $x x ? // logger is before variable's assignment 10 x ``` This is quite natural for simorg because the code now is completely event driven. Simorg's engine is using a concept called <<>>. Tick, is a unit of processing in which engine gathers as much as possible vibrations to process them. During a tick vibrations are sent to target shells in order to be processed then results are gathered in order to shape the next tick. This process continues until there are no more vibrations in the queue. This architecture is leading to interesting results. - Parallel processing and multi-threading is now handled by engine. - Engine is free to use different hardwares as it sees fit to the amount of processing needed in a tick. It means it can decide to use GPU along the CPU or any other ASIC. $$$test.svg$$$ For now, we will stop there and come back to this topic in more details in future. ===== DOC: reference-book/1-introduction/concerning-data (https://simorg.art/docs/reference-book/1-introduction/concerning-data) ===== In the previous section we briefly introduced Data and saw how the idea of Vibration is related to it. Data is so important that it deserves its own dedicated discussion. Among Simorg’s distinctive features, perhaps the most revolutionary is its approach to Data. In a **CPL** approach, processing is applied to the data and when data is not available as expected, all sorts of errors and exceptions appear. This is no longer the case in simorg. Simorg provides a new mindset for programming in which Data is owning the processing not the other way around! When writing Simorg's code, we always think about the data and how it will flow then our code will guide data toward its destination. In this model, data is no longer a passive element of our digital universe but a first class citizen that is absorbing the consciousness from our code which of course is the source of consciousness. So a conscious entity transfers its consciousness (aka business logic) into code so creating a conscious environment and data flowing in this environment so absorbing this consciousness and fulfilling the goal. A conscious data is owning the processing. The solution to many of these problems lies in **how we treat Data**. Simorg’s view is that, instead of so to say babysitting Data, we should empower it to lead processing. As Data flows through the Engine, it absorbs processing, and processing in turn makes Data more conscious. This feedback loop between Data and processing continues until Data fulfills its purpose. A truly data-driven approach is embedded in the core processing model of the Engine. The entire ecosystem around Simorg is designed to make Data smart enough; everything is ultimately encapsulated in Data. Consciousness is not a separate entity; it is entangled with Data. Data has two aspects in Simorg: **Value** and **Frequency**. - **Value** is the aspect of Data that represents its content (for example, <<<10>>> or <<<"Hello World!">>>). - **Frequency** is the aspect of Data that carries its identity. As Data flows inside an application, it can absorb, carry, and shed different Frequencies. Comparing with CPLs, one can see Value as memory space and Frequency as the address of that memory. Simorg is using these new physical concepts to make a separation in classical approach toward data which is the root cause of many errors and incidents in software engineering. Together, these aspects allow Data to decide more consciously where it needs to flow, and as it continues to flow, Data becomes increasingly conscious. For example, consider this familiar `for` loop in a CPL. As we can see from the code, the behavior of iteration is imposed on the Data: ``` // a classical for loop for (int i=10; i>0; i--) { println("Hello World!"); } ``` Simorg's approach is different. Instead it provides a pathway for Data to flow through; the iterative behavior emerges naturally from this flow. Later you will see that this specific flow is part of our variable declaration, actually the behavior of a for loop is encoded and embedded in the declaration of the variable itself. This is similar to how water moves through a piped system or how electrons move through an electrical circuit: they follow natural pathways according to the laws of physics. ``` // declaration $i -- >0 i // initial vibration 10 i // each iteration impacts other elements // causing "Hello World!" to be logged 10 times i "Hello World!" ? ``` Soon we will discover how this code works in detail. ===== DOC: reference-book/1-introduction/take-aways (https://simorg.art/docs/reference-book/1-introduction/take-aways) ===== The final takeaway from this chapter is that simorg is benefiting from a byte-level Data and Event driven processing model, by which it finally promises a new, modern software engineering experience. After all, the digital universe of simorg is not separate from our real universe. The new forms and concepts introduced in simorg and all its building blocks should be examined using a holistic approach. The concepts of Shells and Vibrations and Data and how they interact with each other are essential for a universe that scales both in space and time. $$$AlertBox type=INFO title=Take Away message=The whole universe of simorg can be summarized as shells which are wrapping other shells creating spaces. These shells have holes on them letting vibrations flow in and out, utilizing processing and shaping the time. Shells are created at the byte level but continue to grow all the way to the simorg platform, which encompasses every single entity. The simorg platform itself is a shell wrapping the whole universe of simorg.$$$ Some of the decisions have reasons beyond the scope of the current document and are considering a long-term strategy. Although, we can write and talk about the philosophical and ontological aspects of simorg but it's better to keep them for a different space and time. From next chapter onward, we will start writing simorg code, starting by basic concepts and gradually moving to more advanced topics. If you are interested to know more about the non-technical aspects of simorg and discussions like what we had in this chapter, feel free to check our $$$ToPageLinker keyword=Blog Posts toRoute=/blog$$$. We wish you happy vibrations ahead :). ===== DOC: reference-book/10-platform/introduction (https://simorg.art/docs/reference-book/10-platform/introduction) ===== This section will be updated soon as **Logos** is available for the public in future milestones of the project. ===== DOC: reference-book/11-misc/comment (https://simorg.art/docs/reference-book/11-misc/comment) ===== Simorg provides three ways of adding comments in your code. ## Single Line Comment Using <<>> operator one can initialize a single line comment. ``` // This is a single line comment ``` ## Close Comment Block A comment block is shaped using a pair of comment block markers <<>> and <<<*/>>>. Anything wrapped inside them will be considered a comment. ``` /* This is a comment block */ ``` ## Open Comment Block It is also possible just to use <<< /\* >>> to mark the beginning of a comment block. Without using the closing pair <<<*/>>>, all the next lines will be considered comment block until reaching the end of the file <<>>. ``` :#myVar /* All the next lines will be considered a comment Until the EOF! ``` ===== DOC: Engine Logs (https://simorg.art/docs/reference-book/11-misc/engine-logs) ===== # Engine Logs Engine logs are a source of important data for debugging your application. As we know, a simorg application never throws exceptions, but that doesn't mean that things are always working fine. Unexpected data is a typical case of simorg errors. When something goes wrong the vibration won't happen and the engine logs a record depending on the severity of the issue. We will complete this document in future releases to include a list of engine logs. ===== DOC: reference-book/11-misc/error-types (https://simorg.art/docs/reference-book/11-misc/error-types) ===== This document will be completed in future versions, holding the list of simorg errors that may happen in runtime. ===== DOC: reference-book/12-what-is-next/what-is-next (https://simorg.art/docs/reference-book/12-what-is-next/what-is-next) ===== Thank you so much for spending time and reading the reference book. This document is just the beginning of the story of simorg, a journey toward a better software experience. Collaboration and the success of our community are the key factors that determine if our vision toward simorg is going to become a reality or not. This vision is going to be the vision of all of us. So please join us and let us know what are your ideas and recommendations about simorg's technology. Your ideas will determine the future of this product. Finally, in a broader perspective, we hope this book gave you a new mindset about software engineering. The point is detaching from the classical way of thinking and being innovative, WE have to innovate! As humans, innovation is in our essence, there is no other solution for our future but innovation. The next step regarding simorg is to move toward a stable version 1 for the language and its ecosystem. This is no longer a personal work or the responsibility of one entity. Now is a time for collaboration. At this point you are the one who can determine the future of this technology. Insisting again, we are eager to hear from our early adopters like you and understand how you think about the technology and what enhancements you have in mind. We promise to hear you. Some aspects of simorg intentionally are not included in our reference book. We gradually share our vision and long-term strategies through our blog posts. Check them at $$$ToPageLinker keyword=Blogs toRoute=/blog$$$ Don't forget to share your ideas and opinions using $$$ToPageLinker keyword=Contact Us toRoute=/community#contact$$$. You can always see how the project is progressing using our $$$ToPageLinker keyword=Milestones toRoute=/milestones$$$. ===== DOC: reference-book/2-variables/Variables (https://simorg.art/docs/reference-book/2-variables/Variables) ===== Variables play a major role in any programming language. They represent different building blocks of a digital solution and can refer back to data or logic. Some aspects of Simorg variables still follow the common rules of any programming language, but there are fundamental differences that make Simorg variables quite powerful. Simorg uses <<<$>>> character befor an identifier to mark variable declaration. ### What is common? - **Rule of Scope**: Each variable needs to be defined using a unique identifier in a Shell (scope rule). - **Naming Conventions**: Simorg variables follow naming conventions. ### What is unique to Simorg? - **No Ownership**: Simorg variables are data markers and they do not hold direct ownership of memory. - **Declaration not Definition**: Variables are always declared and it's the responsibility of data to define them. - **Event-Driven**: A Simorg variable represents an event, and this event only triggers if there is data. As we discussed, vibration is the combination of data and event. - **No Garbage Collection**: Simorg variables are part of the structure of the program so no clean up or garbage collection is required. Imagine a variable as a pipe that has inflow and outflow. Data can be seen as a stream of water which eventually flows into this pipe and exits from it. While data is passing through, it gains new characteristics that are inherited from these pathways. ### Rule of Scope Simorg variables, just like in any other **CPL**, are limited to their Shell (scope). It is not possible to declare two variables under the same scope with the same name. For example, the following code is declaring three number variables, ``` { 1 $numA 2 $numB 3 $numC // re-declaration is not allowed and will lead to // a compile time error 4 $numA } ``` ### Naming Conventions Simorg is following the same good naming convention rules including, - A name cannot start by a number but can include number. - A name cannot contain special characters when being declared except for <<<_>>>. $$$AlertBox type=INFO title=No Reserved Keywords message=Simorg does not have any reserved keyword so it is valid to use any word for your variable names.$$$ ### No Ownership In a **CPL**, variables are linked to allocated memory either in the heap or the stack. This usually causes all sorts of problems in software engineering, e.g. dangling pointers, null pointer exceptions. Most of these problems can be categorized under memory ownership. Of course, different languages have different solutions for this with their pros and cons, but the main problem is that the code we write (at compile time) does not give the respect that data and memory need. Simorg solves this problem by bringing a new idea of ownership. The mathematical-physical engine of Simorg gives it the ability to force data to flow inside the system. Actually, variables can be seen as the vessels/channels/pipes that the data is flowing inside. In Simorg it is the data itself that determines who can be its owner rather than the variable. A variable becomes an owner only when the data sees that it can be the owner. When data acquires a new owner, this new owner eventually gives a new characteristic to data, letting this cycle continue and letting data flow. In other words, variables can be seen as the layers/shells which are wrapping the data. Through these layers our data will have new characteristics. Data is the king in Simorg. According to this model, memory allocation and deallocation is always done by the engine whenever it is necessary, and in most cases it will be avoided. ### Declaration not Definition In a CPL, there is a difference between variable declaration and definition. Declaration is when the variable is given a known name and type, and definition is when a chunk of memory is assigned or, in other words, when the variable is implemented. The no-ownership model of Simorg allows it to give the responsibility of definition to data itself. When a program is executed it either receives its data from the constant variables that are initially defined (in physical systems this is known as Initial Conditions) or from different IOs of the system including network, file, etc. In both cases the engine is able to detect the data type with the help of special compiler syntaxes (for value literals) or later at run time when the data becomes available through IO. Data then flows in the system and eventually reaches its destination. During this process data may pass through multiple variables causing them to Vibrate. ### Event-Driven Simorg is a fully event-driven programming language. We discussed the concepts in a previous chapter, but it is worth mentioning that everything in Simorg is an event, and the only thing that causes an event to emit/vibrate is data. This very simple rule made Simorg able to completely remove the abstract and unreal concepts of void, null, None, nil, etc. A variable is only usable when it is vibrating—and it vibrates when data is available. Being a direct result of the two previous rules, a Simorg variable represents both the data and the event/vibration when the data becomes available. When a variable vibrates, depending on the logic, we can use the data or skip it. More details about this will be given in future sections (dataflow DoNotCare operator). But it is important to know that a Vibration is guaranteed to have data. ### No Garbage Collection Simorg variables are part of the space of our application. This is important when you consider using them. Data, on the other hand, is eventually moving into these spaces and flowing inside them. So this is detaching Simorg variables from the role of dealing with lifecycle of data. It may help to understand them more if we completely forget about a functional universe in which the execution at some point starts and then ends. Unlike this approach, data is responsible for its own lifecycle and variables are just adding certain marks on data in certain points of execution, making it able to access new spaces of our application. ## Variable Types Data inside Simorg is directly linked to the reality of our universe. This connection is reflected not only in how data flows through the system, but also in how data-types are defined. Simorg uses three Primitive data types <<>>, <<>> and <<>>. We call them primitive because they are the smallest units of memory in the engine. Technically, everything in memory is a <<>> but creating two other primitives helps us avoid unnecessary details of type systems. In next sections we will see how we can use them but now it's a good time to briefly touch upon the concept of Nothingness. It is important not to confuse **Emptiness** with **Voidness/Nothingness**. Emptiness is a state defined within existence and is a valid state for data because emptiness is always defined using a form of existence. For example empty String <<<"">>>, value <<<0>>> which represents the emptiness in numbers or value <<<0x>>> which represents empty buffer. An important aspect of Simorg is that data is responsible for finalizing variable declaration by providing the final definition. This design removes the need for concepts like `nil`, `null`, `undefined`, `None`, and similar constructs of **Nothingness** that are common in CPLs. We will explore this behavior in more detail in future chapters as we learn more about Simorg. ## Variable Declaration We will see more details later about dataflow operators and pipes, but for now let's just use a simple open-pipe dataflow operator, which is the most basic dataflow operator and just passes a vibration. The following syntax declares a variable called <<>> and pushes a default value of <<<"Hello World!">>> into it. Create a text file called <<>> and put the following code in it: ``` "Hello World!" $myFirstVar myFirstVar:? ``` By creating a variable, we are creating a data layer which is ready to wrap any incoming data. It gives a unique identity to incoming data identified by <<>>. Lets keep the discussion about dataflows for *Dataflow* chapter but for now it is enough to share that data moves from left to right. Think of them as pool balls, when the left token vibrates, vibration naturally moves to the next element. So in line 1 the value literal "Hello World!" is vibrated and <<>> is receiving the vibration as it is next to it. At the engine level <<>> is interpreted as a unique frequency which gives a unique identity to our data. Then data enters into this variable through an operator <<<:>>>, aka **Pipe Operator**, and eventually causing the vibration of <<>>. Run the app using, """ sim variable.art """ Hello World! !!!! As soon as <<>> becomes available it vibrates, and the vibration is received by the logger (<<<:?>>> operator) and printed out in the console. More details about these dataflow operators will be shared in the future chapters. $$$AlertBox type=HINT title=Mathematical Beauty message= As you may have noticed, Simorg doesn't consider <<<=>>> as assignment operator, helping it to take back its mathematical identity being an equality check, relational operator. The reason is obvious as now data is flowing naturally and we don't need to manually assign it using an assignment operator.$$$ $$$AlertBox type=HINT title=What About Booleans? message= So what happened to boolean data type which is quite common in every single CPL? Well a boolean value is not actually a real data type but as it seems it found its way into CPLs due to an unpleasant mixture between control flows and dataflows. It is a virtual abstraction on top of data. Later we will see how Simorg completely removed the necessity of boolean values. After all Simorg is built on top of a decimal mathematical engine which is keeping distance from an artificial binary world as much as possible. Although we understand in short-term it may seem a bit strange to have a programming language without boolean values but the long-term benefit of this mindset is highly valuable. After all data itself is the ultimate form of reality and we don't need to impose our illusions on top of it.$$$ In next sections of this chapter we will discuss different primitive types. It is important to mention that advanced logic regarding each data type will be supported later using Plugin Artifacts. ===== DOC: reference-book/2-variables/Buffer (https://simorg.art/docs/reference-book/2-variables/Buffer) ===== A buffer is a primitive type representing the simplest data form in Simorg. It can hold one or more bytes of data. A buffer is a raw data type that does not have any specific characteristics. For example, a number can be used in arithmetic operations due to its specific type, but this is not quite true for buffers. Buffer types are usually representing the chunks of bytes that do not require a specific processing in simorg engine. For example the raw bytes received from a microphone representing audio signals. In these cases we just pass them through. To define a buffer value literal, use hexadecimal numbering format. For example, ``` 0xff $myBufferVariable // A buffer taking one byte of data [255] ``` The above code creates a buffer with a single byte of data. To add one extra byte, one can continue adding extra bytes using more hex numbers. It's also possible to separate each numbers using <<<_>>> character for more readability. For example: ``` 0x01ab7763 $fourBytesBuffer // equivalent to 0x01_ab_77_63 ``` Using value <<<0x>>> without any extra hex number, lets us define an empty buffer value. ``` 0x ? // [] 0x0 ? // [0] 0x00 ? // [0] ``` ## Addition Operator Using addition operator <<<+>>> between two buffer value will append them together. This is considered a quick syntactic suggar for Buffers. ``` 0x10_20 + 0xff ? // [10,20,ff] ``` $$$AlertBox type=INFO title=Buffers are always LE message=Buffer values in simorg are considered Little Endian (LE) as to make them more network friendly. $$$ $$$AlertBox type=INFO title=Type Coercion message=Buffers do not participate in any type coercion operation. If they are used with relational operators e.g. equality check, the other value must be a Buffer.$$$ $$$AlertBox type=INFO title=More Utilities message=Simorg stl includes a dedicated library for Buffers, providing more advanced operations.$$$ ===== DOC: reference-book/2-variables/Number (https://simorg.art/docs/reference-book/2-variables/Number) ===== In Simorg, a Number is either a 64bit signed Integer or Decimal, although this is in an experimental phase and subject to change in future stable versions. Simorg's engine will perform type coercion if necessary between these two if necessary. The tendency is always toward more precision in result. ``` 10 $numA 10.0 $numB 10.5 $numC // logging the values in terminal numA? // 10 numB? // also 10 numC? // 10.5 ``` It's important to mention, Simorg does not consider <<>> as a primitive data type. Instead number value <<<0>>> is considered a falsy value and <<<1>>> is considered truthy. This agreement is similar to classical programming languages. $$$AlertBox type=INFO title=More Utilities message=Simorg stl includes a dedicated library for Numbers, providing more advanced operations.$$$ $$$AlertBox type=INFO title=Type Coercion message=Numbers actively participate in type coercion if they are used beside relational or arithmetic operators.$$$ ===== DOC: reference-book/2-variables/String (https://simorg.art/docs/reference-book/2-variables/String) ===== ### String A very useful data type representing a series of characters, e.g. an email address, the first name of a user, etc. ``` "Hello World!" $myStringVar myStringVar ? ``` Strings like Buffers are also supporting addition operator <<<+>>>. Using this we can quickly appened two strings together, ``` "Hello" + " World!" ? // Hello World! ``` Using value <<<"">>> or <<<''>>> without any extra hex number, lets us define an empty string value. ``` "" ? // "" '' ? // '' ``` For the time being, simorg doesn't differnetiate between <<<"">>> and <<<''>>> and considers both of them valid string wrappers. It actually helps you to use these characters inside string values more easily, ``` '"Double Quotation" in my string' ? // "Double Quotation" in my string ``` Othewise you could use the escape character <<<\>>>. ``` "\"Double Quotation\" in my string" ? // "Double Quotation" in my string ``` ### Special Values Using escape sequence, we can have access to special formating values including, - <<<\n>>> End of the line. - <<<\r>>> Same as End of the line. For compatibility reasons it may be used beside <<<\n>>>. - <<<\t>>> A tab space sequence. Inserts horizontal tab character. $$$AlertBox type=INFO title=More Utilities message=Simorg stl includes a dedicated library for Strings, providing more advanced operations.$$$ $$$AlertBox type=INFO title=Type Coercion message=Strings actively participate in type coercion if they are used beside relational or arithmetic operators and the other value is a Number. Engine tries to automatically convert String to Number if needed.$$$ ### Embedding values Embedding a value inside a string is quite handly using <<<{}>>> placeholder, ``` 100 "number {} is now embedded" ? ``` Using a <<<\>>> before <<<{}>>> this behavior will be skipped. ``` 100 "using \{} without embedding " ? ``` $$$AlertBox type=INFO title=Multi-Placeholder Support message=The support of multi-embedded values will be added in future versions.$$$ For more advanced formatting logics please check <<>> plugin which is part of simorg Standard Libraries (STL). ===== DOC: reference-book/3-gates/Gates (https://simorg.art/docs/reference-book/3-gates/Gates) ===== In this chapter we will continue with Gate Shells. Although a variable is quite useful, there are many use cases where a simple variable cannot handle the complexity of data models and flows. There are valid cases where we need to combine multiple vibrations in order to represent a more complex data structure or logic. This is where the Gates become quite handy. Gates are one of the Shell types in Simorg. They do exactly what their name suggests: they act as a Gate for Vibrations. Gate Shells can be seen as vibration aggregators. At the moment, Simorg has two Gate Shells and they are different based on their vibration condition. To use Gates we wrap our vibrations inside <<>> or <<>>. Each of these types has its own unique behavior. $$$AlertBox type=INFO title= Post-Vibration Behavior message= A Gate Shell will be cleared out after it releases its energy. $$$ ===== DOC: reference-book/3-gates/Or (https://simorg.art/docs/reference-book/3-gates/Or) ===== An <<>> gate will vibrate if at least one of its slots has vibration to release. We use <<<[ ]>>> characters to implement an <<>> gate. ``` [1,2,3] ? // [1,2,3] ``` As you can see, the logger operator respects the gate type and prints the data according to its gate type. Here, three different value literal vibrations are vibrating at the same time as soon as our application starts. Then the <<>> gate is receiving them. Because at least one slot has vibrated, the gate is also vibrated and eventually the logger receives the vibration. It is nice to mention that Simorg's engine is smart enough to aggregate vibrations if possible. We will see in future chapters how to affect the order of vibrations. $$$AlertBox type=INFO title=Vibration Is Existence message=Having 0 causing a vibration should not surprise anyone as we discussed it previously, values like 0 and "" are considered valid forms of existence as they are representing empty spaces. Gates care about vibration. In future chapters we will see how to add extra guards to help us guard against empty values.$$$ ## XOR Gate Similar to an <<>> gate, an <<>> will vibrate if at least one of its slots has vibration but with a major difference: it only releases one vibration in a tick, meaning if two of its slots have vibration, the act of release is done one by one. This behavior is making <<>> gates quite useful in creating sequential vibrations. Let's see the following examples, ``` [1;2;3] ? // 1 // 2 // 3 ``` Using a <<<;>>> character instead of <<<,>>> is changing the behavior and converts our <<>> gate to an <<>> gate. Now, as it seems from the output, unlike <<>> which was smart enough to gather all the vibrations in one tick, <<>> is guaranteeing that it won't let more than one vibration exit it at a cycle of processing, aka tick. $$$AlertBox type=HINT title=Async By Nature message=This specific usage of ';' character reminds us of sync code in CPLs when the execution runs the logic line by line from top to bottom. Initial prototypes of Simorg also had the same usage reserved for this character when it appeared at the end of a line, BUT, later it turned out that our code is much more solid and clear if we embrace a 100% async approach. We let the vibrations decide what needs to go next!$$$ We will see interesting use cases for the *XOR* gate in future chapters. ===== DOC: reference-book/3-gates/And (https://simorg.art/docs/reference-book/3-gates/And) ===== An <<>> gate will release its vibration only if all of its slots have vibration. We use <<<( )>>> characters to implement an AND gate. ``` 100 $var1 "hello" $var2 0.0 $var3 (var1, var2, var3) $myAndGate myAndGate? // (100, hello, 0.0) ``` Now let's remove the value of one of the variables and see what happens. ``` 100 $var1 "hello" $var2 $var3 (var1, var2, var3) $myAndGate myAndGate? ``` By running this code, nothing will be logged as the <<>> gate doesn't meet its vibration condition. It's nice to remind again that values like <<<0x>>>, <<<"">>>, <<<0>>>, <<<0x00>>>, <<<0.0>>> are valid vibrations representing empty states. Emptiness is not nothingness as emptiness is holding the definition of space. $$$AlertBox type=WARNING title=Avoid A Bad Practice message=Using a ';' inside an AND gate doesn't make any difference! If you have an AND gate, use ',' to separate the slots.$$$ ===== DOC: reference-book/3-gates/conclusion (https://simorg.art/docs/reference-book/3-gates/conclusion) ===== It's nice to wrap our discussion about gates with some general hints. - The behavior of Simorg gates is very similar to the logical behavior of any logical gate as in software/electronic engineering. Simorg's gates are in most parts equivalent to their classical counterparts. - The act of vibration is important for a gate, not the truthy or falsy nature of the vibration. So values like <<<"">>>, <<<0>>>, <<<0x00>>> are considered valid triggers. Later, while discussing dataflow operators, we will implement a truthy/falsy check for our Gates. One should not mistake these values for concepts like <<>>, <<>>, <<>>, etc. For example, the value <<<"">>> is a valid empty string value which of course is not equivalent to void and nothingness. - While we can use gates to hold our data, they are more than that. Gates can also define the dependency between multiple vibrations. For example, let's see the following code: ``` "Jacob" $name 21 $age "Istanbul" $city (name, age, city) $userInformation ``` By using an <<>> Gate we are implicitly saying <<>> is composed of the must-have fields <<>>, <<>> and <<>>. In other words, <<>> is guaranteed to contain these three fields together across our application whenever it is being vibrated. So in other words, whenever <<>> is vibrated, we are absolutely sure that it will contain <<>>, <<>> and <<>> fields. ## The Scope Of A Gate Gates have their own scope, meaning if you declare a variable inside a gate then that variable is only valid in that scope. For example, ``` ( "HELLO" $hello, "BYE" $bye ) $message message? ``` Here two variables are defined under our gate. It's also possible to access the fields using a <<<.>>> operator, ``` ( "HELLO" $hello, "BYE" $bye ) $message message.hello? ``` More about <<<.>>> operator later in *IO Wrapper Shells* section. This behavior is quite similar to object fields in **CPL**s. This topic will be discussed in more detail in the chapter of *Wrapper Shells*, for now it's nice to remember a gate has its own scope and space. We can see gates as a mixture of *object* and *array* concepts. Depending how you use gates, they change their behavior. If the gate can relate a slot to an identifier, then accessing that slot using <<<.>>> operator works just fine. It is similar to an object. But if you just try to read the value of gate while not caring about the specific identity of data it will be considered similar to an array. We will see more of this in future examples once we get to know more advanced concepts. ===== DOC: reference-book/4-dataflows/dataflow (https://simorg.art/docs/reference-book/4-dataflows/dataflow) ===== Finally, you have reached the heart of the book. From this chapter onward, the topics will have a different taste. As we saw so far, Simorg is all about vibrations and shells (spaces) in which the vibrations flow. Now, vibration alone does not do enough unless it is able to flow and stream. This is where the dataflow operators shine. Well, the fact is that all the operators we saw so far were dataflows. These operators are one of the most useful tools provided by the engine to make the flow of bytes happen naturally. When we write our simorg code, we are creating spaces and pathways in which the stream of data starts flowing.. In all these use cases dataflow operators play a crucial role and make streaming quite easy to manage. These operators are the glues between the shells. Since writing our first lines of simorg, we were using dataflows when logging data using <<>> or when declaring a variable using <<>>; more details about these operators soon. Simorg's building blocks are serving data and dataflows are shining among them. So in all dataflow operators, vibration starts from the left side and continues to flow toward the right side of the expression. This is shaping a <<>>. Dataflow pipelines are shaped when operators attach to one another in order to perform different processes on data. We can also combine/join pipelines with each other in order to create complex dataflows. A pipeline by default is not vibrating anything outside itself. So we may consider a pipeline quite similar to a real pipe that allows water to enter from one side, pass through it, and exit from the other side. Now depending on our logic we can inject vibrations in the middle of the pipe or take them out of the pipe. Now let's see how each of them works in action while explaining more concepts as we use them. ===== DOC: reference-book/4-dataflows/pipe (https://simorg.art/docs/reference-book/4-dataflows/pipe) ===== <<>> is the simplest dataflow operator and its job is to create a dataflow channel in which vibrations emitted from the source (left side) reach the destination (right side). Actually, it creates a channel between two shells, the one on the left and the one on the right. This operator does not apply any change on top of incoming data and just passes it through, acting as a link between two shells. The simplicity of this operator allows us to discuss general rules governing dataflow pipelines a bit more in detail. For example let's consider, ``` 100 : 200 :? // 200 ``` Here we have two value literal shells. Value <<<100>>> is starting the pipeline and it will vibrate as soon as the code is executed in engine because it is leading the pipeline as it doesn't have any dataflow operator before it so making it an initialization value. Then its vibration is piped into another value literal which has the value of <<<200>>>. So when a value literal receives a vibration it just absorbs the energy of incoming value and ignores the actual data of that vibration. The incoming vibration of <<<100>>> will trigger the vibration of <<<200>>> and finally we will have <<<200>>> logged in console. In this case our value literal shell can be seen as a const value which is triggered by incoming vibration. Now, let's assign this unique behavior to a variable and call it <<>>, ``` 100 : 200 :$myConst200 ``` Now, <<>> will only vibrate once when the application runs and will be seen as a const variable with value of <<<200>>>. We call this pipeline a <<>>. A closed pipeline is when it doesn't have an opening operator, meaning, it doesn't start with an operator. This kind of pipeline is useful to set initial states of our program. In the above example, <<>> is a variable and it is guaranteed to maintain the value of <<<200>>> across life cycle of our application, vibrating only once. Let's make this code cleaner and remove unnecessary value of <<<100>>>, ``` 200 :$myConst200 ``` The above code has the same behavior as before because value literal <<<200>>> doesn't have any operator before it and it will be vibrated as soon as our code executes and its vibration eventually reaches <<>> and vibrates it. Now, let's change the logic a little bit and have an open pipeline, ``` :200 :$myConst200 :? ``` By running the above code, nothing will be logged in the console, because now the pipeline is open and the value literal <<<200>>> no longer is able to do self-vibration as it now is dependent on an external vibration to trigger it. When a pipeline starts by an operator (like in the example above), we call this operator a <<>>. So in this example we have a head operator of <<<:>>>. $$$AlertBox type=INFO title=Open and Close Pipelines message=Depending on how we use our variables or value literals, they may act as source of vibration or targets of other vibrations. In the examples above first, <<>> was part of a closed pipeline, so value <<<200>>> was considered the source of vibration but when we added a head operator, the value literal was no longer self vibrating. Now, the act of vibration is dependent on a previous operator.$$$ A <<>> operator can also be used to push data into another pipeline. Let's add another simple pipeline to the previous example: ``` : 200 :$myConst200 100 : myConst200 :? ``` So now, by running the app, the value <<<100>>> will be auto-vibrated and pushed into <<>>. Because <<>> has a <<>> attached to it, all incoming vibrations will have to pass through this <<>> naturally and finally reach it. As soon as <<>> is vibrated, this vibration is received back by initial pipeline, continuing from where the pipeline was paused. Finally, the value is passed into the logger. Still we can have a separated usage of our variable to receive the vibration, ``` : 200 :$myConst200 100 : myConst200 myConst200 :? ``` As you can see from the above example, line 3 uses our variable as pipeline head, so this simple pipeline that has only one <<<:?>>> operator will be vibrated as soon as our variable vibrates. Using <<>> as the head of the pipeline without any opening operator makes it the initializer of the pipeline. The act of data passing through operators can be seen as a sequential mechanism for data processing. So when a pipeline is processing your data, it is smart enough to continue from where it was paused, waiting for another pipeline to finish, receiving back the value and then continue. It is also worth mentioning that now our <<>> is behaving a bit differently. Although it is still a <<>> variable, now the act of vibration can happen anytime during the lifecycle of our application because an open pipeline allows it to receive vibrations from outside. The specific behavior of vibrating a <<>> value multiple times during runtime is useful, as one can use these vibrations to synchronize certain parts of the application. As a final example, one may ask how to make it support both behaviors: first, automatically initialize <<>> when the app starts and also continue receiving extra vibrations during the lifecycle of the app. To achieve this, we can benefit from using <<>> shells in the pipeline: ``` :[ 200, :] :$myConst200 100 : myConst200 myConst200 :? ``` When you execute the above code, you will see the following output, """ sim pipe.art """ 200 100 !!!! Here is what happens in the engine: - <<>> is declared as part of an open pipeline, so it can receive vibrations later while the app is running. - A gate shell is used in the middle of the pipeline and the value literal <<<200>>> is used as one of its elements and it doesn't have any opening pipe, so it will vibrate right away as soon as app starts. - The <<>> gate will vibrate as soon as one of its elements vibrates, passing <<<200>>> out into <<>>. Please note having an OR gate in the middle of the pipeline still allows it to vibrate the pipeline from that point. If the gate needs to be completely dependent on incoming vibrations, then a head operator can connect the elements of the gate with the pipeline. - The second slot of our <<>> gate is using a single dataflow operator, which in this case, is receiving incoming vibration of the pipeline pushed into the gate. - When the value <<<100>>> is pushed into <<>>, it will eventually reach the second slot of the <<>> gate causing it to vibrate, resulting in a second vibration of <<>>. As we move forward we will see more interesting examples of combining dataflows with other Simorg shells, each of them bringing in different possibilities. $$$AlertBox type=HINT title=Different Outcome message=What do you think will happen if we replace the <<>> gate with AND gate? Try it out and answer why it happens?$$$ While we are moving through documents you will get familiar with more natural aspects of simorg. Here we saw how value literal and gate shells will behave in middle of a pipeline. Always remember streams of bytes are flowing inside the space that we create using our code. ## Pipe And Gate Shell Using a gate shell inside a dataflow pipeline is making possible to implement powerful data stream switching behaviors. Pipe operator is the only operator that can connect the slot of a gate to incoming flow of data. Let's see it using a simple example, ``` :("Data") $logMessage ? // Data ``` Running the code we will see <<>> in the terminal. The reason is that the gate is self vibrating because it is not caring about incoming dataflow. Let's change this a bit, ``` :(:"Data", :) $logMessage ? // (Data, Inflow) "Inflow" logMessage ``` Now, the new code will make the gate dependent on incoming flow of data as expected. It's important to remember that only a pipe operator <<<:>>> is able to connect gate slots to incoming flow so, ``` :(:+ 10, :- 10) $calculate? // (20, 0) 10 calculate ``` ## A Beautiful Fact As you can see so far we have used <<<:>>> operator everywhere e.g. beside variable declaration <<<$>>> or logger <<>> operators. Now, it's time to share a useful concept. If you put tokens after each other, they by default utilize pipe operator and become connected. The act of connection is what a pipe operator does, so putting tokens after each other, we can skip writing <<<:>>> operator. Let's re-write the last example as, ``` : [ 200, :] $myConst200 100 myConst200 myConst200? ``` This is still working the same and even a bit faster skipping unnecessary pipings saving a few cycles. From now on, we may or may not use <<<:>>> in middle of the pipelines. Of course using <<<:>>> in the head of a pipeline to open it up or, in a slot of a gate to consume incoming pipeline values is still necessary. These use cases both are visible in the above example. ===== DOC: reference-book/4-dataflows/arithmetic (https://simorg.art/docs/reference-book/4-dataflows/arithmetic) ===== Arithmetic operations are the most basic forms of calculations in simorg. Just like any other programming language, simorg supports basic mathematical operations at the engine level, including addition, subtraction, multiplication, division and modulo. As we shared briefly in the **Number** section, simorg does type coercion automatically for numbers. For example, depending on certain situations the engine may decide to use an Integer portion of a Decimal number. All these cases will be shared when we meet them in future sections. ## Basic Binary Operations ``` 19 $numA 2 $numB numA + numB $add numA - numB $sub numA * numB $mul numA / numB $div numA % numB $mod add? // 21 sub? // 17 mul? // 38 div? // 9.5 mod? // 1 ``` These binary operators always consume operands from their right side. $$$AlertBox type=WARNING title=Be Careful About Subtraction Operator message= The subtraction operator is a bit different because it can be used as the negative sign of a number. If you intend to use it as the subtraction operator make sure to include a space between - and the token after it. Otherwise it will be considered a negative sign. The reason behind this behavior will be discussed in the Dataflow chapter.$$$ $$$AlertBox type=WARNING title=Concerning Addition Operator message= Using a unary + sign beside a number e.g. +10, is not necessary. Later in the Dataflow chapter we will see how this operator is interpreted by the engine. So classical unary behavior in this case is not applied.$$$ ## Basic Unary Operations Simorg is using two unary calculation operations, ``` 19 $numA 2 $numB numA ++ ? // 20 numB -- ? // 1 ``` For now it is enough to mention that data is moving from left into the operator and passing through to the right. Unary nature of these operators doesn't require any operand. If the value is not a number, an INVALID_ARGUMENT error will be logged. ## Syntactic Sugars It's important to be aware that simorg has one Primitive data type for calculations and it is <<>>. One exception is when the <<<+>>> operator is used with <<>> and <<>>. <<>> is a frequent operation when working with String and Buffer types. So for these types, the <<<+>>> operator can be used as a syntactic sugar representing concatenation. The priority of type coercion in this case is first with <<>> then <<>> and finally <<>>, so if one operand is <<>> then the data of all other operands will be converted into <<>>. Please check this example, ``` "Hello " $strA "World!" $strB // Addition when all the operands are numbers 100 + 20 $num // 120 // + operator will concatenate strings strA + strB $strC // Hello World! // here type coercion priority is with String // so all the operands will be considered String // result will be String strC + 100 + 20 $strD // Hello World!10020 // here type coercion priority is with Buffer // so all the operands will be considered Buffer // result will be Buffer 0x00 + strA + 10 $buffer // [00,48,65,6c,6c,6f,20,00,00,00,00,00,00,00,0a] ``` Please note when type coercion happens from <<>> to <<>>, it will always be in Little Endian (LE) format, which is file, network and IoT friendly. $$$AlertBox type=INFO title=More Utilities message=More advanced mathematical operations will be supported by plugin artifacts, for example Math plugin from simorg's stl.$$$ $$$AlertBox type=INFO title=Operator Precedence message=Simorg arithmetic operators do not follow the classical operator precedence conventions common among CPLs. Instead the priority is from left to right. So expressions like "1 + 1 * 2" are evaluated from left to right, first evaluating "1 + 1" to 2, and then "2 * 2" to 4.$$$ Now the reason is clear. Every single operator in simorg is a dataflow operator, receiving data from left side of it, depending on its nature doing possible processing, and passing it through to the right. Some operators require operand and they consider the next token as their operand. This is how data naturally passes through different layers with no need for specific precedence between operators. For example, ``` 1 + 2 * 5 / 15? // 1 ``` <<<+>>> is an operator that always requires operand so number <<<2>>> is the object of the operator and will be considered its operand. But in the following example, Due to natural dataflow direction, no parentheses are required to affect evaluation priority. Don't forget that a classical pair of parentheses doesn't exist in simorg. If you use parentheses in the middle of a calculation, that will be interpreted as a gate! For example, ``` 10 + 5 - (120 + 2) ? ``` will result in an invalid operand error, """ sim -f parentheses.art """ [ERROR][DATAFLOW_SHELL][INVALID_OPERAND] Invalid dataflow operand! !!!! Unary operators do not require an object or operand, ``` 1 ++ 10 ? // 10 ``` <<<++>>> doesn't require any operand; it increases the incoming value by one and passes it through. So in this case value 1 is entering the pipeline, increased by 1 and then hitting value <<<10>>> which is a value literal shell causing it to vibrate. Adding a logger in between helps to see this behavior, ``` 1 ++ ? 10 ? // 2 // 10 ``` ===== DOC: reference-book/4-dataflows/relational (https://simorg.art/docs/reference-book/4-dataflows/relational) ===== Relational calculations are used to compare whether two values have a specific relation to each other or not. For example, an <<>> check is a relational calculation and checks if two values are equal to each other. Simorg uses familiar operators to perform relational calculations BUT with a fundamentally different approach. As you saw so far, data is the king. Now, relational operators are another proof of this fact. In **CPL**s, when a relational expression succeeds, the result falls back either to a <<>> or <<>> value. Leaving the philosophical aspects of this wrong behavior aside, this usually causes extra effort for engineers. Of course in many use cases the implicit behavior kicks in, reducing the effort, but it is still not quite the right decision. The above behavior is no longer the case in simorg. When a relational expression is used, the result is no longer a boolean value (as you know simorg even doesn't have this type) but the data itself that triggers the expression. All relational operators will return a value as soon as they are able to vibrate—meaning as soon as the operands are available. The result is always the left-hand side operand which is the subject of the expression. The right-hand side operand is the object which is being checked against. All relational operators are binary, meaning they need an operand. If for any reason the operator is not able to execute, for example, when an operand is holding an invalid data type, then the operator will never vibrate and there will be an <<>> or <<>> log depending on the severity of the case. ## Equality Check The equality check operator <<<=>>> is a quite useful relational operator. It is used to check whether two values are equal or not. Simorg is not using the classical assignment operator <<<=>>> as data itself is flowing and it doesn't need manual assignment hence <<<=>>> operator is embracing back its mathematical beauty and acting as expected. When it comes to numbers, simorg's equality check follows implicit data rules, meaning a value of <<<1>>> is considered equal to <<<1.0>>>, and <<<10=10.0>>>. Values which represent emptiness are not considered equal. So <<<0x>>> which represents empty <<>> is not equal to <<<"">>> which represents empty string. There will be no vibration and a warning log will be registered by engine. Also, a <<>> value of <<<"1">>> is not equal to a numeric value of <<<1>>> and the same is true about a buffer value of <<<0x01>>> which is not equal to either one of them. Primitive variable types are respected. Although a warning will be logged by the engine if this happens. Please refer to the engine logs chapter for a more detailed list. If you need any different behavior, it's always a good idea to check plugin artifacts for more advanced behaviors dedicated to specific use cases. For example, if the string conversion logic is needed then the <<>> plugin can be used. ``` 20 = 20 $x x? // 20 20 = 10 $y y? // will never vibrate ``` Using the <<>> operator instead of <<<=>>> performs a not-equal check, ``` 20 ! 10 $x x? // 20 20 ! 20 $y y? // will never vibrate ``` Equality check of two <<>> values will only pass if they are completely equal, including character casing. Equality check of two <<>> values will only pass if they are exactly the same, byte by byte. Now, finally, let's talk about the concept of <<>> and <<>>. This fact applies to all relational operators. From left to right the incoming data is considered <<>> and the operand is considered <<>>. So if the condition holds true, then the subject passes through the expression. It is important to remember always subject is the driver, lets see the following example, ``` [1;2;3] $x 2 $y x > y ? // will log only 3 ``` But by switching them, ``` [1;2;3] $x 2 $y y > x ? // will log only 2 ``` The reason is simple, relational operator will be executed as soon as both subject and object are available. In first example our operator runs three times but in second example it only runs once because the subject is vibrating only once. This is enough to log <<<2>>> because according to <<>> the first vibration is <<<1>>> and the relation holds true so passing <<<2>>>. ## Comparison Use it to compare the relation between numbers. Passing <<>> or <<>> values will lead to an <<>> error log. ### Greater than Checks if a number is greater than another one. ``` 20 > 10 $x x? // 20 20 > 20 $y y? // will never vibrate ``` To check equality at the same time: ``` 10 >= 10 $x x? // 10 ``` ### Less than Checks if a number is less than another one. ``` 20 < 10 $x x? // will never vibrate 20 <= 20 $y y? // 20 ``` ===== DOC: Truthy (https://simorg.art/docs/reference-book/4-dataflows/truthy) ===== # Truthy Truthy operator <<<&>>> is quite useful when the pipeline needs to continue only if the current value is considered <<>>. This operator is a unary operator meaning it won't take any operand. The following values are considered <<>>: - All numbers except <<<0>>>, <<<0.0>>>. - A string value if it is not empty <<<"">>>. - A Buffer value when it is not empty <<<0x>>>. Buffer values of <<<0x0>>>, <<<0x00>>>, etc. are considered truthy. Let's see a simple example of this operator, ``` 1 & "will pass the vibration through" ? 0 & "will never vibrate" ? ``` If the incoming value is a gate of multiple values, the <<>> logic is dependent on the type of the gate. An <<>> gate will be considered <<>> if all its vibrations are <<>>. This is following the definition of <<>> logic. As we saw before, <<>> gate is vibrating when all slots are available and vibrated. Using <<<&>>> you can have another layer of check. For example, ``` (1, "Hello", 0.1) & // ✅ (0, "Hello", 1.0) & // ⛔️ (1, "", 0x) & // ⛔️ (1, "Hello", 0.0) & // ⛔️ (1, "Hello", (1, "")) & // ⛔️ ``` An <<>> gate is considered <<>> if at least one of its vibrations is considered <<>>. This behavior is quite aligned with the behavior of an <<>> gate. ## Not Truthy <<>> operator behaves in the exact opposite way of <<<&>>> and will pass the vibration through only if it is considered a <<>> vibration. For example now, ``` 1 !& "Will not pass through" 0 !& "Value 0 passes through" ``` As we always insist, simorg is built upon data. So any interaction should be data-driven. So a classical <<>> branch no longer exists as this is not completely data-driven. Instead, all the possible pathways should explicitly be available to data. ``` "" $userInput userInput & // will pass through userInput !& "Invalid Empty Value Received!" ? ``` In the next chapter we will get familiar with <<>> shells, helping us with more advanced control flows. ===== DOC: reference-book/4-dataflows/declaration (https://simorg.art/docs/reference-book/4-dataflows/declaration) ===== Declaration operator <<<$>>> is used when we want to declare a new variable. A variable is representing a specific flow of data. One can see variable declaration as creating a pipeline that is not anonymous anymore. The only difference between <<<$>>> and simple <<<:>>> operator is that <<<$>>> marks the next token as a variable identifier. This is a compile time check and compiler makes sure variable declaration rules are applied. Variable definition will be done at runtime. <<<$>>> helps to make variable declaration explicit and helps identify variable declarations. It is important to remember that variables should always be declared before their usage. We will discuss the topic of scope in the next chapter whilst discussing the <<>> shells. A valid variable declaration includes fulfilling the following conditions, - It starts with an alphabetic character, upper/lower case. - The only special character valid to be used in a variable name is <<<_>>> character. - A variable name may include numbers but not in the beginning of the name. - The identifier or name is unique in the scope. Names like <<>>, <<>>, <<<_myVar>>>, <<>>, <<>> are valid and <<<1variable>>>, <<>>, <<<123>>> are considered invalid. ## Prefix and Suffix It's a good time to discuss the two important concepts: - Prefix: Any specific expression coming before variable declaration operator <<<$>>> is considered a <<>>. All these operations should be considered part of the essence of this new variable. - Suffix: Any specific expression coming after the identifier is considered a <<>>. Both prefix and suffix expressions are part of the essence of the variable. Let's consider a simple example, ``` % 3 $var ? 100 var ``` In the above example <<>> is benefiting from a prefix expression <<<% 3>>> and a suffix <>>. Now this variable has a specific behavior as part of its declaration. """ sim -f var.art """ 1 !!!! Now, it's nice that we have a variable that has two extra behaviors encoded in its essence. It always holds the result of a %3 and logs its value. There are valid cases where a variable may have a specific characteristic that needs to happen but is not part of the value it represents. These cases are more like a side effect of vibration which can continue the processing. We will see useful patterns later in the <<>> section that benefit from this behavior. Suffixes are exactly for this purpose. As soon as the identifier vibrates, its value is received in the initial caller pipeline and the <<>> logic continues running in the background. A combined use of <<>> and <<>> shines when we have complex data structures, for example similar to objects in CPLs. So we can define complex objects by combining declaration statements and gates. For example, let's define a <<>> object in a 3D space that has three fields of <<>>, <<>>, <<>> and its <<>> value is always <<<0>>>. We know that a point in 3D space is valid only if all three fields have value. To force this business logic we will use an <<>> gate. Also, each of the values should be valid at any time. So the concept of <<>> can be achieved only if all three fields of <<>>, <<>>, and <<>> are getting their values, hence making it a <<>> for our gate. Considering all these conditions, the following declaration will fulfill our requirements, ``` ($x, $y, 0 $z) $point // Setting values 1 point.x 2 point.y // will vibrate as soon as point.x is receiving its value point.x ? // will vibrate only after all the fields are available point ? ``` """ sim -f point.art """ 1 (x: 1, y: 2, z: 0) !!!! What we will see in the console consists of two logs, an object and a single value of <<<1>>> representing the <<>>. Using <<>> we can dig deeper into fields under <<>> and get their value. More details about this operator will be shared in the next chapter. As we can see the behavior of <<>> is quite dependent on <<>>, <<>>, and <<>> while <<>>, <<>>, and <<>> have their own logic and they are not even aware that there is a higher logic dependent on them. As another example, the following snippet shows a typical declaration of a boolean shell. ``` :[ & 1, !& 0 ] $boolean ``` $$$AlertBox type=HINT title=More Advanced Use Cases message=There are valid cases where a declaration needs more complex prefix and suffix logic. We will get back to these use cases in a future chapter of Wrapper Shells.$$$ ===== DOC: reference-book/4-dataflows/logger (https://simorg.art/docs/reference-book/4-dataflows/logger) ===== During the development process, we often need to see the data passing through our shells. Logging is a quick solution to check and verify if things work as expected. ## Log Line Operator Log operator <<>> is actually a light-weight dataflow operator which receives incoming data and logs it in the console. Logger operator is a pass-through operator, meaning it receives data, logs it and just passes it through without any change. So making it a unary operator which doesn need an object or operand. Let's see a series of typical logger operator usages: ``` "Hello World!"? // logs Hello World! ``` Later while discussing <<>> and <<>> artifacts, we will see that logs can be accessed by artifacts. The logs generated by this operator are included under <<>> log category. ## Log Operator There are cases that we don't need end-of-line, aka, newline <<<\n>>>> character. Using <<>> we can log the value without newline charcter at the end. For example, this is quite useful to quickly check the output stream of an agent as the output will become quite handly to read. ## Other Members In future releases there will be new members in logger family, including <<>>, <<>> and <<>>. ===== DOC: reference-book/4-dataflows/do-not-care (https://simorg.art/docs/reference-book/4-dataflows/do-not-care) ===== DoNotCare operator <<<|>>> is used when just the act of vibration is important so skipping the data itself. As we know, all vibrations are originally created on top of data. It's impossible to have a vibration without data, But it is totally fine to skip the data when we just need the act of vibration. It's different than what we experience in **CPL**s, when they allow you to execute a function or receive an event that doesn't have any data. Well this no longer the case in simorg, as data is driving everything, now the receiver have the right to skip the data if it's not needed. Let's see this in the following example: ``` $x (x, 1, 2) ? (x |, 20, 30) ? "Trigger" x ``` So here we have two <<>> gates and one of them is using <<<|>>> operator to skip the actual value of <<>>, just receiving its vibration to fulfill the <<>> condition. In other words, using <<<|>>> we can sync different pieces of our application while skipping the data that we don't need. Gates are smart enough to skip the slots that are holding a DoNotCare value. This operator is also contributing to one of the great achievements of Simorg, which is removing the necessity of any form of <<> e.g. <<>>, <<>>, <<>> as they are used in CPLs. This operator, like any other operator, can also be used in any part of a dataflow pipeline to achieve different purposes. For example, in the following code it is used in the declaration pipeline to make this variable a beacon or signal: ``` | $trigger 100 trigger "Start" trigger ``` In the above vibrations, <<>> is acting as a beacon, ignoring the actual values, focusing on the act of vibration itself. $$$AlertBox type=INFO title=Not Loggable message=A DO_NOT_CARE vibration will not show up in logs!$$$ $$$AlertBox type=HINT title=Do Not Care Behavior message= A DoNotCare vibration is still able to pass if it fulfills the condition of the check, meaning the fact that it is Do Not Care doesn't make any difference when checking its underlying data. It still is holding the same data but the receiver has the ability to choose to skip the data e.g. in the case of gates they don't include DoNotCare values in their vibrations.$$$ ===== DOC: reference-book/4-dataflows/filter (https://simorg.art/docs/reference-book/4-dataflows/filter) ===== As we are progressing toward more advanced features, now is a good time to meet filter operator <<<@>>>. We discussed the concept of frequency in introduction chapter. A vibration is wholding a layer around it and this layer is shaped from different frequencies. As data moves through the system it absorbs these frequencies. Now using a filter operator we can filter the incoming vibration and only pass those who fulfill our filter policy. If the incoming vibration has the specified frequency, then it will pass through. ``` $x $y (10 x,20 y) $pointA pointA @x ? // 10 ``` This operator is still a work in progress and more features will be added to it in future releases. It is a mechanism to quickly pick what we need from incoming data. ===== DOC: reference-book/4-dataflows/collector (https://simorg.art/docs/reference-book/4-dataflows/collector) ===== Collector operator <<<..>>> is used when data batching is required. As you may have noticed simorg doesn't have the familiar concept of <<>> similar to CPLs. The reason is simple, we don't want to interrupt and reshape the structure of data as much as possible. While data is moving through our system it can temporarily be accumulated in a point to fulfill certain requirements. Unlike CPLs that store the data in memory and then process it, Simorg promotes the idea of stream processing. So the best possible solution is to process data as part of natural dataflow and avoid storing it unless there is a certain business logic. One possible example is the logic that requires data to be stored in memory (temporarily) until a certain event happens, allowing it to move forward. In these scenarios <<<..>>> becomes quite handy. You can imagine it as a water tank which acts as a temporary storage for water in a distribution system. Let's see a simple example of this operator, ``` :[0, :] $data <10 ++data data ..10 ? ``` If you run the code you will see the following log in the console: ``` {0, 1, 2, 3, 4, 5, 6, 7, 8, 9} ``` The code is simple, line 1 generates a self vibrating variable that generates 10 vibrations and on line 3, each of those vibrations is captured inside our collector until it reaches the capacity so releasing its vibration. <<<{ }>>> wrapper is used to mark collectors in simorg. A <<>> is equivalent to an <<>> as data is stored inside it based on the order it is being received. But we avoid calling it an <<>> in order not to create the same expectation of an <<>> like in a CPL. Instead we call it a <<>>. It's not possible to access the data inside a <<>>, for example, using an <<>> mechanism as there is no <<>>. Iterating over data is possible by using another collector operator which is acting similar to a destructor. Let's continue our previous example by adding another collector in series to the first one. ``` :[0, :] $data <10 ++data data ..10..2 ? ``` Here we are using two collectors back to back in order to first batch the data and then destruct the batch and create a stream of data one by one. So first collector is not vibrating until its capacity has been reached and it has gathered <<<3>>> elements. Then it releases the vibration and the next collector vibrates as soon as it receives one element, meaning there will be three vibrations out of it. $$$AlertBox type=HINT title=Do Not Collect message=Collectors are temporary placeholders to gather vibrations and release them according to a business logic. Do not see them as arrays. Data should stream as natural as possible. If you need to apply a logic on each single vibration, then do it naturally while the vibrations are streaming.$$$ This is a powerful mechanism to batch and then process in parallel. As we will introduce in future sections, dataflow pipelines are quite powerful and smart to pick the best processing model for incoming data. For example in this case, the engine is smart enough to perform all these possible tasks in one <<>>. So there will be three different vibrations after the second collector but all of them in one <<>> which is quite efficient. We will talk about the concept of <<>> in future chapters but for now consider a <<>> a unit of processing. If the operand is not a <<>> (1,2,3,...), it will act as a trigger. So collector will continue collecting incoming vibrations until the operand is vibrated. This operator is usually used in combination with other operators to fulfill complex logic. To insist and emphasize more, simorg is promoting natural flow of data. According to this pattern the usage of <<>> in designing a solution should not have any place. Data itself should have enough characteristics to replace the necessity of having an <<>>. But still for some edge cases, it is possible to generate an index and attach it to incoming data and then push it into a collector. This is not an anti-pattern to what we mentioned earlier as now the data itself will have a field acting as an index. Still one should really be careful with this kind of implementation as data itself is the final actor, it should have enough facts inside it to overcome the necessity of an <<>>. This is quite similar to the concept of water flowing in a pipe or electrons flowing in a wire, we don't care about each specific molecule of water or each single electron but their act of being itself in a place is enough to fulfill their duty. Same is true about the stream of data (bytes), flowing inside Simorg's engine. The topic of <<>> length or size also can be seen as part of the same reasoning. Actually, instead of checking the length and size later, all the business logic about length and size should be taken care of in parallel as the collector is filling up. Let's not forget that these are vibrations that are filling up the collector. It's all about natural flow of data. Using this approach, data will be where it needs to be without babysitting it and manually managing it. Long story short, don't expect to fill up the collection and then try to know the size of it. Whatever the size dependent logic is, it should naturally happen in parallel when the collector is filling up. $$$AlertBox type=HINT title=Why Keeping Distance From Arrays? message= It is a valid question, the biggest problem with arrays is that they force us to embrace a sequential processing model which is no longer a modern way of processing. Decisions like this are rooted in a strategic model which is embracing mathematical data structures and parallel processing.$$$ We will see examples of size logic with collectors in Common Patterns chapter. A collection follows the definition of an <<>> gate for the <<>> check. If at least one element is <<>>, the whole collection is considered <<>>. Certain functionalities e.g. sorting will be supported using the <<>> plugin from simorg's stl. ===== DOC: reference-book/4-dataflows/Instantiate (https://simorg.art/docs/reference-book/4-dataflows/Instantiate) ===== We have reached one of the most special operators of Simorg, instantiate operator $$$KeywordSnippet keyword=#$$$. This operator can be seen as equivalent to <<>> statements of CPLs but, just like other operators, the similarity is only on the surface. As the name <<>> suggests, it is used to create new instances. These instances represent new shells which are generated from code. So this operator is actually doing compilation of simorg's code at runtime. The most powerful usage of it is when it is being used alongside <<>>, simorg's package manager. Simorg sees <<>> as the repository of blueprints. Actually, when you use $$$KeywordSnippet keyword=#$$$, a series of words are converted into entities or beings. More about *blueprints* and *logos* in future chapters. Instantiate operator is playing a major role in simorg's ontology by creating the shells (which are the units of being in simorg) out of simorg words (code). Let's see three different usages of this operator. ## Compiling Simorg Code $$$AlertBox type=WARNING title=To Be Available Soon... message=This behavior will be supported in futue releases and is not available in PoC version.$$$ Let's see our <<>> example, but this time using <<>> operator: ``` "'Hello World!'?" #myCode ``` The code <<<"Hello World!":?>>> is simply logging out <<>> but now we are using it as a string value and pushing it into instantiate operator. As soon as instantiate operator receives its vibration, it compiles the code and executes it in the current location. The result will be a series of shells created and added to the current location. So we will have our <<>> visible in the terminal. ### Logos Blueprints As we touched briefly, Simorg has a package manager called <<>>, the repository of blueprints of creation. They can be instantiated inside your application. We will discuss more details in *Blueprints* chapter. For now, let's just celebrate this amazing moment by bringing a delay plugin blueprint into our code and create 3 seconds of delay. ``` "@simorg/time0.1.0" #delay "Waiting for 3 Seconds..." ? 3 delay.sec "Done!" ? ``` By running this code, you will have two subsequent logs appear in console with a delay of <<<3>>> seconds. Actually, <<>> is receiving a number representing delay amount in seconds, then it vibrates back the same value out and it vibrates the value literal next to it and finally the logger will receive it. You got access to a piece of functionality that is created and published freely on Logos. ### Local Blueprints $$$AlertBox type=WARNING title=To Be Available Soon... message=This behavior will be supported in futue releases and is not available in PoC version.$$$ The final use-case is to instantiate a local blueprint which is represented by a local file. This approach is usually used to modularize the code in order to have a scalable structure. Let's see this using an example: Create a file beside the <<>> and let's call it <<>>. Add the following code inside <<>>: ``` "Hello from local.art"? ``` Inside <<>> we will use the following code, ``` "./local.art" #local ``` Running <<>>, """ sim main.sim """ Hello from local.art !!!! So we will have <<>> instantiated and executed, making our message appear in the console. $$$AlertBox type=INFO title=Instantiation Behavior message=Each time we instantiate, new sets of shells are created out of nothingness.$$$ $$$AlertBox type=INFO title=Identifier Is Required message=Using => itself is not enough to instantiate. Only when the vibration reaches a Declaration Reference, it will complete the instantiation process.$$$ ===== DOC: reference-book/4-dataflows/take-aways (https://simorg.art/docs/reference-book/4-dataflows/take-aways) ===== Dataflow operators are amazing! This is beautiful and expected. As we emphasized multiple times, data need channels and spaces to flow and these operators are exactly creating the same. $$$AlertBox type=HINT title=Optional Pipe Operator message= Using : operator in middle of a pipeline is optional. When two shells are used beside each other e.g. value literals, variables or gates, simorg considers this combination a pipeline and by default uses : operator to connect them.$$$ $$$AlertBox type=HINT title=Optional Pipe Operator message= As data is now flowing naturally in the system and inside pipelines from left to right, we no longer need operator precedence. The evaluation priority between all operators is from left to right.$$$ The following operators need an operand or object. If operand is missing a compile time error will be logged, - All the binary arithmetics: <<<+>>>, <<<->>>, <<<*>>>, <<>>, <<<%>>>. - All the relationals: <<<=>>>, <<>>, $$$KeywordSnippet keyword=>$$$, $$$KeywordSnippet keyword=>=$$$, $$$KeywordSnippet keyword=<$$$, $$$KeywordSnippet keyword=<=$$$. - Declaration <<<$>>>. - Instantiate $$$KeywordSnippet keyword=#$$$. - Filter <<<@>>>. - Collector <<<..>>>. The following operators are unary and do not need an operand or object, - Pipe <<<:>>>. - Truthy <<<&>>> and Not Truthy <<>>. - Log <<>> and <<>> - DoNotCare <<<|>>>. ===== DOC: reference-book/6-wrappers/wrappers (https://simorg.art/docs/reference-book/6-wrappers/wrappers) ===== As we discovered so far, the concept of vibration is the manifestation of the existence in simorg. Things exist because they can vibrate. Vibration itself is also limited to the shell in which it is vibrating. So it means a vibration also needs a shell or space to vibrate and manifest itself. The concepts of shell and existance are tied together in a way that one without the other doesn't have a meaningful impact and is just an abstract entity. So far we saw a series of shells, each having its own relation with vibration. For example, a <<>> is affecting the outcome in a certain way, or a <<>> shell which is receiving a vibration and sometimes changing it and passing it through. As we can see, the concept of wrapping and limiting the vibration is a main characteristic of a shell. A <<>> shell is a general purpose shell that can act as a pure wrapper when we want to limit the scope of our vibrations. Simorg wrapper shells are identical to the concept of <<>> in **CPL**s. Imagine you are in a room listening to music. While your music player is a source of vibration, the room is acting as a Shell, preventing the sound leaving the room. Of course, we can control if a shell needs to receive vibrations from outside or allow some vibrations to exit it and be received outside. We use curly brace pairs <<<{}>>> to create a wrapper shell. Simorg provides three types of wrappers, - An <<>> wrapper shell. - A <<>> wrapper shell. - An <<>> wrapper shell. Let's see how each one of them works. ===== DOC: reference-book/6-wrappers/isolator (https://simorg.art/docs/reference-book/6-wrappers/isolator) ===== An <<>> is a closed shell whose vibrations cannot exit from it. Meanwhile, it is able to re-use variables from outside. This shell can be used to segregate different parts of our code. Let's see how it works by an example: ``` "Outside the Shell" $myVariable myVariable:? { "Inside the shell" $myVariable myVariable:? } ``` Running the code, """ sim -f isolator.art """ Outside the shell Inside the shell !!!! As you can see, two different variables are declared and vibrated independently because we have a shell that is creating a new isolated space. An <<>> can still use a variable from the outer space (scope) if it is not declared within its space. For example, the following code will still print the value which is declared outside this shell. The concept of isolation will become more clear once we meet two other types of shells, but when a variable is explicitly used inside a shell then there is nothing to stop accessing the vibrations of that variable. ``` "Outside the Shell" $myVariable { myVariable ? } ``` The concept of activation will be checked in next sections but let's just remember an isolator shell is active if its parent is active. $$$AlertBox type=HINT title=No Internal Access message=An isolator shell is closing all kind of access to its internal elements.$$$ ===== DOC: reference-book/6-wrappers/conditional (https://simorg.art/docs/reference-book/6-wrappers/conditional) ===== Now what happens if you want to have a shell that needs to be impacted by an external vibration. This is the exact use case of a <<>> shell. Emphasizing again, everything in Simorg is either vibration or a Shell that wraps the vibration. So for the rest of this document, we will refer to a conditional wrapper shell simply as *conditional*. A *conditional* is an isolator shell but with a way to explicitly activate it. Let's see it in action, ``` 1 { "Hello World!" ? } ``` This is a super simple conditional shell. It is using an activator vibration (value literal <<<1>>>) to activate the shell. As soon as activation vibrates, the internal shells can also do their vibration. Now a more classical example of a conditional shell is of course an <<>>. Actually, it's due to these similarities that simorg is calling this category of wrapper shells a conditional wrapper shell. ``` 100 $a 200 $b (a > 50, b > 50) { "'a' and 'b' are greater than 50" ? } ``` In this example we are using an <<>> gate to create a condition between both elements. In this case the shell will vibrate only if two conditions are met. The following code is a classical representation of the same solution (C++ syntax), ``` #include int a = 100; int b = 200; if (a>50 && b>50) { std::cout<< "Both numbers are greater than 50"<< std::endl; } ``` Apart from extra lines that are related to the way <<>> works, the main body of code is quite similar. Thanks to the concept of vibration and the new data-centric approach of simorg, the code is behaving naturally even without extra reserved keywords. At this point mentioning a few points seems useful: - It's totally valid to use any kind of expressions to activate a Shell including variables, dataflows, calculations, gates, etc. - Simorg doesn't have an <<>> statement. This was touched on briefly in the *dataflow* chapter while discussing the *truthy* operator. This is due to the way the engine works. Our code is creating channels in which the data will be streamed. This also has roots in how our nature works. If something happens it is a pure result of the existence of necessary conditions, not because of the non-existence of a series of other conditions. This also helps writing code that is less error-prone. It's even possible to do variable declaration as part of a <<>> statement. This gives us two possibilities. - Having named Wrapper Shells which are variables plus a dedicated space to them to implement their own advanced logic, which we will discuss in the next section on *io* shells. - Receiving external data and use it inside the shell. ``` $externalData { externalData ? } "External Vibration" externalData ``` ``` $myVar { "Dedicated space to implement a complex suffix" ? } "External Vibration" myVar ``` $$$AlertBox type=HINT title=Shells As Spaces message=The condition of a wrapper shell can be seen as a hole that external vibrations are able to pass through it into the shell.$$$ $$$AlertBox type=HINT title=Let's Embrace Simplicity message=If the side effect of the codition is limited to one single action, it's best to avoid using wrapper shell as the code will become much cleaner.$$$ Let's now move forward with the final category of wrapper shells, the <<>> shells. ===== DOC: reference-book/6-wrappers/IO (https://simorg.art/docs/reference-book/6-wrappers/IO) ===== An <<>> wrapper shell has both an activation or input layer and also an output layer, both encoded into the activator expression. It's just a different use case of wrapper shells. An IO shell does not have any difference with conditional shell as it uses the same syntax. The difference is in how we setup the activation layer. As we saw in previous section, a conditional shell passes data only from outside to inside the shell. Using IO shell we can also send data out from inside the shell and have a bi-directional vibration flow. Before getting started with *io* shells, let's meet a useful operator. ## Layer Operator Layer operator <<<.>>> is a special operator which is quite useful. Let's first start with a short history. In **CPL**s it is called <<>> or simply <<>>. It is used to access members (fields, properties, methods) of an object, structure or class instance. While this application is almost similar to what <<<.>>> does in simorg, the mindset behind it is a bit different. Let's see a quick example, ``` ( "Hello!" $hello, "Bye!" $bye ) $message message.hello:? ``` You can see our <<>> gate is acting as a layer around <<>> and <<>> identifiers, binding them together. This layer is identified by another identifier called <<>>. Using <<<.>>> operator we can traverse through the layers of our vibration so to reach the exact data that we need. It's also possible to push data into a specific field of a gate. For example, ``` ( $hello, $bye ) $message "Hello" message.hello "Bye" message.bye message ? ``` """ sim -f layer.art """ (hello: Hello, bye: Bye) !!!! To make the usage even simpler, we can use *structure* and *destructure* patterns as, ``` ( $hello, $bye ) $message ("Hello", "Bye") message message ? ``` $$$AlertBox type=HINT title=Gates and Layer Operator message=As you may have noticed, gates are behaving more like CPL objects, making it possible for layer operator to read specific slot if the slot is already an identifier. So if a gate is using an identifier whether declared or not, you can access the slot using a . operator.$$$ If the gate on the receiver side is an <<>> then any number of vibrations that are available will be picked and pushed into the slots in order that they are used, otherwise if the receiver is an <<>> gate, it is mandatory for inflow vibration to have the same length, otherwise an <<>> error will be logged by the engine and vibration is discarded. ## IO Shells Now that we are more familiar with layer operator and pattern matching, let's see how we can have an *io* shell by an example, ``` $sum { // arg declaration ($a, $b) $args // destructuring incoming vibration sum args // logic args.a + args.b sum } (10, 20) sum ? // 30 ``` This classical example is representing an adder logic which receives two values and adds them together. - Line 3 does an API declaration for necessary arguments. - Line 6 is pushing whatever received through <<>> into our args declaration so utilizing destruction pattern. - Line 9 does the logic and pushes back the result into <<>>. A wrapper shell is smart enough to understand that this vibration is coming from inside the shell so it won't activate the shell again. Due to the same reason line 6 is not vibrated by an internal vibration of <<>>. - When sum is vibrated from inside, the value returns back so continuing and completing the pipeline and finally logging the value 30. $$$AlertBox type=HINT title=Mathematical IO message=The similar look and feel of an IO shell to the concept of a function should not mislead us! Although similar on the surface but fundamentally different in implementation. What happens here is a pure data driven mathematical structure in action without any program counter, return address management etc.$$$ Now, this is one possible way of having an IO behavior. If the logic is more complex with multiple inputs and outputs, the declaration can be done in activation layer. For example, ``` [$arg1, $arg2, $add, $sub, $mul, $div] $calculate { calculate.arg1 + calculate.arg2 calculate.add calculate.arg1 - calculate.arg2 calculate.sub calculate.arg1 * calculate.arg2 calculate.mul calculate.arg1 / calculate.arg2 calculate.div } (10,5)calculate? ``` Running the code will result in, """ sim -f calculator.art """ [add: 15, sub: 5, mul: 50, div: 2] !!!! This is how the usage of an <<>> gate becomes handy. This is just another possible way of declaring *io* behavior in simorg. Wrapper shells when combined with dataflow activator layers become quite powerful. Using wrappers we can even implement similar patterns of CPLs e.g. classes and traits. But the question is do we really need it? When a declaration is having its own wrapper shell, like the examples above, only the vibrations which are happening inside the shell are considered the final value of the identifier. So repeating the last example and adding a standalone logger on line 10, ``` [$arg1, $arg2, $add, $sub, $mul, $div] $calculate { calculate.arg1 + calculate.arg2 calculate.add calculate.arg1 - calculate.arg2 calculate.sub calculate.arg1 * calculate.arg2 calculate.mul calculate.arg1 / calculate.arg2 calculate.div } (10,5)calculate (20,5)calculate calculate ? ``` We can see that the values of <<>> and <<>> are not received. Line 10 is using our variable in the head of a pipeline so making it a pure receiver which will receive all possible vibrations from different pipelines. $$$AlertBox type=HINT title=Manifestation of Reality message=Simorg language is not trying to mimic similar patterns of CPLs. Some of the classical paradigms e.g object oriented programming must be avoided while writing simorg code. In code level we are focusing on creating a reality. The final look and result should be manifested in the creature as a result not as a mechanism.$$$ ===== DOC: reference-book/8-blueprints/introduction (https://simorg.art/docs/reference-book/8-blueprints/introduction) ===== It is amazing that you made it so far! Congratulations! Now it's time for joy, using our simorg knowledge to unlock the real power behind simorg, to use blueprints, on top of which we all can join together, collaborate, digitalize the innovation, and build the universe of simorg. Simorg is not only a programming language but also a platform to build and execute. Imagine an ecosystem of building blocks that can be tied together using simorg language and share vibrations between themselves. So far, all we did was understand simorg's processing mechanism and how we can use the language. From this point onward we will focus on how we can expand the universe of simorg by getting to know its worldview and its ecosystem. This is the moment that the language can have a chance to unleash its real potential by letting billions of digital elements communicate with each other in order to fulfill higher-level business solutions, e.g. Smart Cities, next-generation video games, AI-powered universes, etc. Actually, this is the first step toward building the universe of simorg: a digital universe which promises a new, unique digital experience. This is only possible if we join together and build it together. To make it happen we need a platform for collaboration. As we briefly touched upon, the platform side of simorg is called *logos*, the repository of blueprints of creation. More on this in future releases, for now, let's just focus on basic building blocks of this platform and get to know some of them. Let's quickly define a few important keywords. ## Machine We can define a <<>> as a device that is running simorg's applications. So a *machine* is hardware that provides processing power for the engine to execute. It's worth mentioning that you can definitely consider a *machine* as an implicit shell because it still is wrapping your vibrations at a higher level. We call it implicit because unlike other types of shells it doesn't have an explicit representation inside our code. ## Application The program that you create using simorg code is called an <<>>. Powered on top of simorg engine, applications are quite powerful entities, they can be published in *logos* and they can include agents making them able to demonstrate higher levels of consciousness. ## Artifact An <<>> is the most basic external building block that we can use inside our simorg application. These building blocks include all possible digital elements from 3D and web components to AI agents, binaries and plugins, and simply every digital element that can communicate with simorg engine. As you remember, *delay* was a plugin artifact we used in order to access more advanced capabilities. Now, solving real problems and implementing complex digital solutions should be done in a timely manner. This is an important reason behind artifacts. An *artifact* shell is a pre-built piece of software that can be used directly inside our code to help us build our complex solutions faster and more maintainably. It's nice to share that an artifact is actually a digital element and by instantiating it we wrap it into a mathematical representation so it can naturally embed into the engine's workflows. So this is a mechanism that unifies many different types of digital elements through a mathematical representation. To have a look at available artifacts, please visit $$$ToPageLinker keyword=Logos toRoute=https://logos.simorg.art$$$. $$$AlertBox type=HINT title=Simorg's Standard Library message=Simorg is providing a series of basic plugin artifacts that are quite useful. Make sure to visit our Standard Library documentation to know more about them.$$$ ## Bundles Using bundles we can package the artifacts and applications together and publish them in *logos* as a solution. Bundles are created using Simorg Programming Language. In future releases of simorg, more platform-related tools and documents will be available. The next section is about creating a famous version of a guessing game but this time, using simorg. ===== DOC: reference-book/8-blueprints/a-gussing-game (https://simorg.art/docs/reference-book/8-blueprints/a-gussing-game) ===== Let's create a simple guessing game using a few plugin artifacts and see how artifacts can work together. For this example we are going to utilize two plugins. A random number generator and a standard input plugin to read user input through terminal. Our application will pick a random number and ask the user to guess the number. ``` "@stl/terminal-input0.1.5" #terminal "@stl/random0.1.5" #random :terminal.promptAndReadLine $guess // generating a random number between 0 to 9 inclusive 9 random.integer $TARGET "Enter your guess: " guess guess = TARGET "Congratulations! You guessed right!" ? guess > TARGET "Target is smaller, Guess again: " guess guess < TARGET "Target is bigger, Guess again: " guess ``` This is a pure event and data driven, aka vibration driven, implementation. All the interactions will naturally happen when the vibrations are available. The code is quite straightforward, even while it is not using any reserved token, common in **CPL**s. Although these plugins are running on CPU, the application itself is compiled into a set of mathematical entities that can be executed on any hardware that is Simorg friendly, e.g. a GPU. ===== DOC: reference-book/9-common-patterns/introduction (https://simorg.art/docs/reference-book/9-common-patterns/introduction) ===== In this chapter we will see some classical patterns and their equivalent implementation in simorg. This list will grow over time as new patterns will be introduced. For now we kept it limited intentionally. ===== DOC: reference-book/9-common-patterns/const-variables (https://simorg.art/docs/reference-book/9-common-patterns/const-variables) ===== Constant values are initial state of any application, whether being a port number or the URL of a network resource, constant values play a major role in any application. We can use the following patterns to get the most out of them, We can consider two aspects of a variable when considering it a const, - Its value doesn't change. - The way it vibrates. ## Pure Const When our application needs a certain value to be vibrated only once in its whole lifecycle, then it is a pure const. ``` "My Pure Const Value" $PURE_CONST_EXAMPLE PURE_CONST_EXAMPLE ? ``` As you notice the dataflow pipe of our const variable doesn't have a head operator which means it will vibrate only once and it is impossible to vibrate it later. ## Semi Const Using <<>> variables still the value will always remain constant but the vibration can happen multiple times. The simplest example could be ``` :"My Semi Const Value" $SEMI_CONST_EXAMPLE SEMI_CONST_EXAMPLE ? "Trigger" SEMI_CONST_EXAMPLE ``` If you need to add auto-vibration feature for this const variable on application start then a simple <<>> becomes quite handy, ``` :["T", :] "My Semi Const Value" $SEMI_CONST_EXAMPLE SEMI_CONST_EXAMPLE ? "Trigger" SEMI_CONST_EXAMPLE ``` Now the or gate is holding a const value of <<<"T">>> and it will trigger the out const value as soon as the application starts. Also, this gate redirects all incoming head vibrations to our Value Literal causing it to vibrate again. ## Scoped Const Const values have interesting behavior when they are used inside a <<>>. In this case the wrapper's trigger can trigger their vibration. Let's check this example, ``` $input { "Hello World"? } ``` Unlike what we expect, this const value will never vibrate because now it is being used inside a shell which has a trigger. Although the value of <<>> is never used but the activation of shell is dependent to it. If we want to see it vibrating then we should trigger this wrapper shell, ``` $input { "Hello World" ? } "Trigger" input ``` ===== DOC: reference-book/9-common-patterns/if-condition (https://simorg.art/docs/reference-book/9-common-patterns/if-condition) ===== Conditions are a core feature of any programming language. Using conditions we will control the flow of program execution. A typical classical if condition in a CPL is more or less similar to, ``` if (x == 10 ) { printf("X is 10"); } ``` Considering what we saw so far in the previous chapters, it's quite clear that the above classical control flow now is naturally available using simorg's dataflow model. In fact the natural behavior of a <<>> is providing the same exact functionality of a classical <<>>. The above example can be re-written as, ``` x = 10 { "X is 10"? } ``` To support the <<>> we simply use an <<>>, ``` (x = 10, y = 20) { "X is 10 and Y is 20"? } ``` ===== DOC: reference-book/9-common-patterns/loops (https://simorg.art/docs/reference-book/9-common-patterns/loops) ===== As you know Simorg doesn't have any third party entity sitting in the code dictating its own rules to the data. Instead, we believe in data-driven approaches by which the data is being streamed in certain paths which demonstrate certain behaviors. Loops are a great example of this data-driven approach. This code is demonstrating a typical classical loop in the C language, ``` for (int i = 10; i>0; i--) { printf("index: %d", i); } ``` Now the same code according to a data-driven pattern is like, ``` $i >0 -- i ? 10 i ``` The above code is having a post-declaration syntax of a variable that continues reducing the counter and pushing data back into pipeline's head until it reaches 0. We can even use a gate and make it a self-starting counter. ``` :[10, :] $i > 0 -- i ? ``` The point here is that we made the behavior of a loop using a data-driven approach. If the initializer is always a positive value then the above loop can be even more simplified as, ``` $i--&i ? 10 i ``` Here, the truthy check operator <<<&>>> is replacing $$$KeywordSnippet keyword=>0 $$$ . This is possible because <<<&>>> will pass the vibration only if the incoming is a truthy value hence, preventing the flow to continue when <<>> is <<<0>>>. A typical usage of loop in **CPL**s is when we want to iterate over collections of items. Simorg doesn't need that approach either. As the collection itself naturally is iterable using <<>> so still the behavior of <<>> is following a data-driven pattern. ===== DOC: reference-book/introduction (https://simorg.art/docs/reference-book/introduction) ===== Simorg's reference book is a useful resource to get a full picture of all the capabilities of the language which builds our universe of simorg. If you are planning to read the full document for the first time, it is highly suggested to read until the chapter 5 by the order as these chapters include the most basic concepts. The rest of the book can be read without a specific order and based on your interest. Also, the last section includes a list of commonly used patterns in CPLs better to be read last. Among all chapters, the first introduction chapter is the most important one of them as we discuss the core mindset and WHYs behind the language, please be patient and read the chapter. It helps creating a true mindset about the language as it is completely different than a classical programming language. $$$AlertBox type=WARNING title=Not Production Ready Yet message=Please keep in mind, Simorg is currently in PoC mode! So avoid using existing tools and technology in production environment and wait for the first official LTS version. $$$ $$$AlertBox type=WARNING title=PoC Mode Situation message= Please keep in mind, Simorg is currently in PoC mode! Even while the runtime is super small but currently it is loaded with lots of unnecessary entities mainly for debugging. At this point topics like performance and memory footprint is premature. One should avoid starting to compare simorg to other languages at this point. In this PoC mode we encourage our community to embrace a problem-solution approach and share possible enhancement cases.$$$ $$$AlertBox type=WARNING title=PoC Mode Situation message= Being in PoC mode has another implications. There could be cases in our documentation that need more explanations, certain docs necessary to cover a topic could be missing or even the error logs in terminal are not quite clear. This is the moment that our collaboration is helpful. Please make sure to share your thoughts with us. It will help improving the quality of our tools and materials. We appreciate your understanding, time and support.$$$ ===== DOC: reference-book/simorg-in-10-minutes (https://simorg.art/docs/reference-book/simorg-in-10-minutes) ===== This is a quick start section, focusing on core functionalities of simorg. You need to setup your local environment before starting this quick tour. You can follow the instructions in $$$ToPageLinker keyword=Getting Started toRoute=/docs/getting-started/introduction$$$ section. We are going to discover simorg using a simple guessing game. Our application receives user's input from terminal and checks it against a target number. Guessing right leads to a success message, otherwise user needs to enter a new number. Create a new file and call it <<>>, we will add our simorg code inside this file. Let's start from the core functionalities by creating two variables. Using <<<$>>> before an identifier, marks that identifier as variable. ``` $TARGET $guess ``` Using capital letters we mark <<>> as being a const variable that is being set only once during the lifecycle of our app. Let's give it a default value by replacing line 1 by, ``` 3 $TARGET $guess ``` Simorg doesn't have classical assignment operator <<<=>>> instead it uses dataflows. As soon as our application starts value 3 is vibrated and starts a dataflow. When value reaches <<>> it again vibrates but this time using a new identity. A vibration simply is the combination of <<>> and <<>>. A vibration simply marks the availability of data. We can keep adding operators in our dataflow pipeline. Let's add a logger operator so we can see the value in terminal, ``` 3 $TARGET ? $guess ``` By running our app, """ sim -f guessing-game.art """ 3 !!!! Cool! Let's now add a basic condition and test it. ``` 3 $TARGET ? $guess guess = TARGET "Congratulations! You successfully guess the number!" ? ``` Simorg doesn't have any reserved keywords! So no more <<>>, <<>>, <<>>, etc..! Line 4 is again a dataflow pipeline which starts by the variable <<>>. if the value is equal to <<>> then it passes the vibration forward. In this case the incoming vibration will trigger our string value literal and cause it to vibrate. The incoming value is not used anymore. It will cause this value literal to pass it's value to logger operator. Let's give the same value to <<>> and test our application, ``` 3 $TARGET ? 3 $guess guess = TARGET "Congratulations! You successfully guess the number!" ? ``` By running our app, """ sim -f guessing-game.art """ Congratulations! You successfully guess the number! !!!! Let's add more conditions to cover other cases, ``` 3 $TARGET ? 3 $guess guess = TARGET "Congratulations! You successfully guess the number!" ? guess > TARGET "Target is smaller than your guess" ? guess < TARGET "Target is bigger than your guess" ? ``` Now we have the core functionality of our app. Let's complete it by importing two blueprints. Simorg like any modern programming language has its own package manager called $$$ToPageLinker keyword=Logos toRoute=https://logos.simorg.art$$$. Let's use a random number generator. Using <<<#>>> before an identifier will help us instantiate our blueprint and have an identifier to call it, ``` "@stl/random0.1.7" #random 9 random.integer $TARGET ? 3 $guess guess = TARGET "Congratulations! You successfully guess the number!" ? guess > TARGET "Target is smaller than your guess" ? guess < TARGET "Target is bigger than your guess" ? ``` By pushing <<<9>>> into <<>>, we will create a random number between <<<0>>> and <<<9>>>, inclusive. Then this value will be set as our target. Next blueprint is <<>>. It will help us read a value from terminal, ``` "@stl/random0.1.7" #random "@stl/terminal-input0.1.6" #terminal 9 random.integer $TARGET ? "Enter Your Guess: " terminal.promptAndReadLine $guess guess = TARGET "Congratulations! You successfully guess the number!" ? guess > TARGET "Target is smaller than your guess" ? guess < TARGET "Target is bigger than your guess" ? ``` Our application is almost complete. Line 5 will prompt and read a value from terminal. This will then vibrate guess. As you noticed Simorg doesn't use any type definitions. Engine tries to convert types automatically. In case of failure a log message will be logged by engine. Simorg doesn't throw any exception at runtime. If something fails, the expected vibration will not happen. Finally, let's re-arrange a few things to fulfill the requirement of our application and keep asking the user when the guess is not right, ``` "@stl/random0.1.7" #random "@stl/terminal-input0.1.6" #terminal :terminal.promptAndReadLine $guess 9 random.integer $TARGET "Enter your guess: " guess guess = TARGET "Congratulations! You guessed right!" ? guess > TARGET "Target is smaller, Guess again: " guess guess < TARGET "Target is bigger, Guess again: " guess ``` Line 4, is using an open pipe and helps us re-vibrate this pipeline when we need to receive a new guess. We use the natural logger capability of <<>> to ask user for new inputs. On lines 9 and 10, when user needs to guess again, the vibration is re-directed back into <<>>. The act of prompting and asking user to enter a number is now part of the declation of <<>> so whenever something is pushed into <<>> have to pass through all these pre-processors. Awesome! Now you have a basic understanding about core aspects of Simorg. The vibration-driven (data- and event-driven) nature of the language is helping us create a new declarative form of solutions. Also, every single token that we use is referring to an equivalent data entity, in other words we are writing code from data's point of view not from a third-party observer's point of view. This is contributing to the simplicity of the language as we don't need extra unnecessary tokens. This is how Simorg achieves a solution using zero reserved keywords. To gain a deeper knowledge about simorg, please continue reading our reference book. Happy Coding! ===== DOC: Let There Be Vibration (https://simorg.art/docs/getting-started/let-there-be-vibration) ===== # Let There Be Vibration Writing the first lines in a new programming language is always an exciting moment. Traditionally, this all starts with a <<<"Hello World!">>> app. * Create a directory and call it <<>>. * Under this directory create a new file called <<>> and write the following code in it. ``` "Hello World!"? ``` Open a terminal inside the directory containing this file and execute it using: """ sim -f main.art """ Hello World! !!!! Congratulations! You have experienced the first vibrations of Simorg. In Simorg's universe, everything exists in the form of an Event—or, as we call it, a **Vibration**. In our lovely <<>> example, the <<<"Hello World!">>> string is a Vibration. A Vibration is a chunk of data that has the ability to flow. So it is a package of energy and data together! This Vibration is then received by the logger operator <<>>, which absorbs the energy of the Vibration and logs the data to the terminal. ===== DOC: getting-started/hello-agent (https://simorg.art/docs/getting-started/hello-agent) ===== Now, let's add new dimensions to our application code and see how we can benefit from a 3D programming environment. In this mini project we are going to set up a 3D environment and insert a robot inside this environment and then utilize our lovely robot with an LLM model so we can chat with it like, $$$Image fileName=06-the-chat.png$$$ $$$AlertBox type=WARNING title=Driver Limitation message=At the moment, the driver of our 3D engine is only available for Windows Intel x64 operating systems. Hopefully, soon, there will be more drivers for this artifact to support Mac Metal and Linux operating systems. Make sure to subscribe to our newsletter to receive the latest updates as soon as possible.$$$ Let's start by downloading a 3D engine first. Engines add a graphical layer to our applications. In this case a 3D layer. It's time to introduce you to $$$ToPageLinker keyword=Logos toRoute=https://logos.simorg.art$$$ where simorg holds the blueprints of its universe. - Create a directory in your machine for our application and call it <<>>. - Head to $$$ToPageLinker keyword=unreal-sim toRoute=https://logos.simorg.art/in/milad/unreal-sim$$$ artifact's landing page in *logos* and click on <<>> tab and download available driver for your machine. This is a 3rd party Binary Artifact published by an artisan. - Follow the installation steps in the README section and set up the artifact. - Move your simple <<>> code into this directory. - Open a terminal window there and execute it using <<>> Now your simorg app is running behind default port <<<7117>>> and is ready to accept connections. While you still keep your hello-world app running, run 3D engine. This binary is not registered under windows 11 app store so if you received a security warning or access request, accept them. This binary app will try to connect to local port <<<7117>>> in order to communicate with our <<>> app, so please make sure your local firewall setting is allowing it. $$$Image fileName=security-request.png$$$ If everything works correctly, you will see the following welcome screen. $$$Image fileName=welcome-screen.png$$$ Perfect now follow the next steps on the screen. Once you reached the default script window just make sure the existing versions are the last available versions in logos. For now logos is limited in the amount of blueprints but in future once we opened it up to artisans, there will be many more artifacts to use. $$$Image fileName=default-script.png$$$ As you can see the code is quite simple, we are importing an island world, adding a compiler window so we can continue expand our application from inside and last but not least, an avatar to make us able to move around. Once done, press on <<>>. If you are doing this for the first time, the necessary artifacts will start to download. $$$Image fileName=download-progress.png$$$ Awesome! When downloads are done press <<>> and you will jump right into this beautiful world we created out of simorg code. $$$Image fileName=the-world.png$$$ ## Hello Agent Now that we are in our world, its time to bring in another robot and add an LLM, a source of consciousness, into it. - So press Q to open compiler window. We can use simorg scripts to bring in a 3D Component. - Add the following script there, ``` "@milad/robo-sim.1.3" #myRobot ``` $$$Image fileName=robot-script.png$$$ - This component artifact is registered in *logos* our package manager as $$$ToPageLinker keyword=A Wandering Robot toRoute=https://logos.simorg.art/in/milad/robo-sim?activeTab=readme$$$ and you are right we already imported it but this time it is imported as a standalone component. - Build the code by pressing *Build* button on the top. Because this artifact is a component, as soon as we *Build*, a new component instance will be added inside our inventory tab. - Click the *Inventory* tab and click <<>> to activate the Unreal driver, which is one of the drivers that this engine supports. Engines may support multiple drivers. $$$Image fileName=unreal-driver.png$$$ Because we already downloaded this driver, the artifact is usable right away. Press the <<>> button in order to instantiate this component in your universe. - If you drag the mouse near your location, our new robot should become visible. Click somewhere near to place it. - Move around and approach the avatar and press <<>> on your keyboard to interact with this robot. If you are too near, keep a bit of distance and approach again, PoC mode ;). $$$Image fileName=interact.png$$$ - This will open the interaction window of this robot. Now, we are ready to add consciousness to our robot. - Now here comes our second Artifact. $$$ToPageLinker keyword=LLama For Simorg toRoute=https://logos.simorg.art/in/milad/llama-sim?activeTab=readme$$$. An LLM model loader plugin that we embed inside this robot, making it able to have its own consciousness. To do so lets first download an LLM Model so we can run it locally. - Head to $$$ToPageLinker keyword=Huggingface toRoute=https://huggingface.co/$$$ and download a *gguf* formatted llm model depending on the spec of your machine. Save the model and note the path to *gguf* file as we will need this path to load the model. - Add the following code inside the consciousness window of this robot, ``` "@simorg/llama-sim.1.9" #llama ("path-to-llm.gguf", "You are a robot") llama.initialize $chatPrompt $streamStart $streamContent $streamEnd chatPrompt llama.prompt llama.streamStart streamStart llama.streamContent streamContent llama.streamEnd streamEnd ``` - In line 3, make sure to replace <<>> with absolute path of your downloaded *gguf* file e.g. <<>>. This will be used to initialize our plugin. - As you noted, a system prompt of <<<"You are a robot">>> also is used in initialization vibration. $$$Image fileName=llm-code.png$$$ - Now *Build* the consciousness. - Click the *Chat* button and type a question then press send! Boom! After a short while the llm should kick in and streams of answers starting to be received by our robot. $$$Image fileName=the-chat.png$$$ Congrats! You just utilized a local llm inside your machine and gave its power to a 3D component. Now, let's wait a sec and see what we have done! On the surface we created a mini 3D universe using simorg's code. But what happened under the hood is that we inject consciousness into a 3D component. This is now a piece of software in 3D form. These components are not passive elements of your universe; each of them can represent functionality or a piece of software. Each of them can hold a piece of consciousness. This makes us able to start building our applications from within. This simple robot can be powered by an instruction based model. This makes it able to do meaningful works in this 3D universe. The environment is quite agent friendly. It is possible to have a range of agents in this universe each contributing to a specific task. $$$AlertBox type=HINT title=Logos Holds Everything message=Don't forget to check logos, all you need is there ;).$$$ Well, the purpose of this demo is to present a very basic proof of concept regarding the power of simorg programming language and logos. It represents a new possibility of building next generation software. As you noticed the UI is not beautiful, it just gets the job done. All of these are awaiting talented *Artisans* who publish their artifacts in logos and make these applications more beautiful. Everything from the 3D engine, world, avatar and *llama-sim* are artifacts which are created by artisans and uploaded in *logos*. Simorg as a platform is responsible to provide the technology, and our talented community are the ones who build the applications. We believe in collaboration, this process may seem a bit slow in the beginning but soon when the community is there, it will gain momentum. Technologies like AI and Metaverse are more beautiful when they are open for everyone, there is no monolithic solution for them! The success of simorg is linked to your success and if there is going to be a prize, everyone who contributes to this success should have a fair share of it. Simorg provides all the tools and technology you need to embed AI in every single digital element, shape your workflows and create next generation software that yet, are not possible to be built using our existing programming languages. ===== DOC: getting-started/next-steps (https://simorg.art/docs/getting-started/next-steps) ===== Simorg is not just a piece of software. It's a new mindset about software. We encourage you to continue this tutorial and discover more powerful tools that give you the power of creation the way it needs to be. ## Next Steps? - Read $$$ToPageLinker keyword=Reference Book toRoute=/docs/reference-book/introduction$$$ to gain essential knowledge about Simorg's language. - Read $$$ToPageLinker keyword=Our Blogs toRoute=/blog$$$ to learn about the philosophy, ontology, and future of our technology. - Find inspiration from $$$ToPageLinker keyword=Logos toRoute=https://logos.simorg.art$$$. Each Blueprint has its own documentation. - When Logos becomes available, read $$$ToPageLinker keyword=For Artisans toRoute=/docs/for-artisans/introduction$$$ when you decide to share the beautiful results of your consciousness with the universe. - We build together; $$$ToPageLinker keyword=Our Community toRoute=/community$$$ is where collaboration starts. Don't forget to join our social media and share our story, as our power is in our community. - You can find the newsletter subscription links on the homepage; doing so, you will receive the latest news about our product directly from us. ===== DOC: Getting Started (https://simorg.art/docs/getting-started/introduction) ===== # Getting Started Simorg is a platform that we build it together, better to say, a digital universe. Simorg uses its own programming language which is built for the mission. You do not need any prior programming experience to use it. You will find this programming language quite natural and a whole lot of fun! ## Setting up your local environment The first thing we need to do is making sure your local environment is set up and you can run simorg on your machine. * Head to our $$$ToPageLinker keyword=Downloads toRoute=/download$$$ Page, pick the correct installation method based on your operating system and install simorg. * Open the console (terminal, cmd) and run the following command to check whether your installation was successful or not. """ sim --version """ genesis-0.1.0 !!!! If you receive an error please check installation steps again and if the issue persists please check our support channels. ===== DOC: Logos Of Artisans (https://simorg.art/docs/for-artisans/introduction) ===== # Logos Of Artisans Logos is the package manager of Simorg. In this document we will understand how it works and how you can publish different types of Artifacts, Modules and Applications. According to our roadmap $$$ToPageLinker keyword=Milestones toRoute=/milestones$$$, *logos* will be available by end of Quarter 3 (Q3) 2026. As part of this milestone, this document will be updated to include all the details on how to use engine APIs in order to create artifacts e.g. to create a plugin or a 3d engine for components. $$$AlertBox type=INFO title=Coming Soon... message=This document will be updated in future versions when publishing artifacts become available. $$$ ===== DOC: standard-library/3-IoTs/arduino (https://simorg.art/docs/standard-library/3-IoTs/arduino) ===== To be updated soon. ===== DOC: standard-library/3-IoTs/raspberry-pie (https://simorg.art/docs/standard-library/3-IoTs/raspberry-pie) ===== To be updated soon. ===== DOC: Delay (https://simorg.art/docs/standard-library/4-plugins/delay) ===== # Delay The delay plugin schedules timeout and interval timers and emits vibration callbacks when timers tick. Each vibration key maps to a timer operation function. Invalid timer payloads are rejected and reported through logs. ## Functions --- ## sec Schedules one-shot timeout using plain sec numeric input. ``` 2 delay.sec ? // vibrates 2 after 2 seconds ``` Collector input is invalid, no vibration will happen. ``` (1,2) delay.sec ? // no vibration ``` - **Type:** ERROR - **Code:** INVALID_ARGUMENT_TYPE - **Message:** delay.sec expects a single numeric value. Zero or invalid delay values are rejected, no vibration will happen. ``` 0 delay.sec ? // no vibration ``` - **Type:** ERROR - **Code:** INVALID_DELAY_VALUE - **Message:** Delay must be a positive number. --- ## ms Schedules one-shot timeout using plain ms numeric input. ``` 2000 delay.ms? // vibrates 2000 after 2000 milliseconds ``` Collector input is invalid, no vibration will happen. ``` (1,2) delay.ms ? // no vibration ``` - **Type:** ERROR - **Code:** INVALID_ARGUMENT_TYPE - **Message:** delay.ms expects a single numeric value. Zero or invalid delay values are rejected, no vibration will happen. ``` 0 delay.sec ? // no vibration ``` - **Type:** ERROR - **Code:** INVALID_DELAY_VALUE - **Message:** Delay must be a positive number. --- ## setTimeout Schedules one-time callback using array payload: index 0 is timer id (string), index 1 is delay in milliseconds (number). ``` ("t1",500) delay.setTimeout ? // schedules one-shot tick ``` Missing id at index 0 causes rejection. ``` (500) delay.setTimeout ? // no vibration ``` - **Type:** ERROR - **Code:** MISSING_REQUIRED_FIELD - **Message:** setTimeout payload must contain id at index 0. Missing delay milliseconds at index 1 causes rejection. ``` ("t1") delay.setTimeout ? // no vibration ``` - **Type:** ERROR - **Code:** MISSING_DELAY_VALUE - **Message:** setTimeout payload must contain delay ms at index 1. Non-array payload is invalid. ``` 500 delay.setTimeout ? // no vibration ``` - **Type:** ERROR - **Code:** INVALID_ARGUMENT_TYPE - **Message:** setTimeout expects an array payload. --- ## setInterval Receives an array with timer id at index 0 and interval milliseconds at index 1, then schedules repeating vibration. onTick can be used to receive the vibrations back. ``` ("i1",1000) delay.setInterval ? // repeats onTick ``` Missing id at index 0 causes rejection. ``` (1000) delay.setInterval ? // no vibration ``` - **Type:** ERROR - **Code:** MISSING_REQUIRED_FIELD - **Message:** setInterval payload must contain id at index 0. Missing delay milliseconds at index 1 causes rejection. ``` ("i1") delay.setInterval ? // no vibration ``` - **Type:** ERROR - **Code:** MISSING_DELAY_VALUE - **Message:** setInterval payload must contain delay ms at index 1. Non-array payload is invalid. ``` 1000 delay.setInterval ? // no vibration ``` - **Type:** ERROR - **Code:** INVALID_ARGUMENT_TYPE - **Message:** setInterval expects an array payload. --- ## onTick This function is used to receive the vibrations back from active intervals and timeouts. ``` delay.onTick? // vibrates with the id of the timer ``` --- ## ms Schedules one-shot timeout using plain ms numeric input. ``` 2000 delay.ms? // vibrates 2000 after 2000 milliseconds ``` Collector input is invalid, no vibration will happen. ``` (1,2) delay.ms ? // no vibration ``` - **Type:** ERROR - **Code:** INVALID_ARGUMENT_TYPE - **Message:** delay.ms expects a single numeric value. Zero or invalid delay values are rejected, no vibration will happen. ``` 0 delay.sec ? // no vibration ``` - **Type:** ERROR - **Code:** INVALID_DELAY_VALUE - **Message:** Delay must be a positive number. --- ## cancel Cancels interval/timeout by timer id string. ``` "i1" delay.cancel ? // clears timer i1 ``` Non-string id values are invalid. ``` 123 delay.cancel ? // no vibration ``` - **Type:** ERROR - **Code:** INVALID_ARGUMENT_TYPE - **Message:** cancel expects a string timer id. If Id is not found, no vibration will happen. ``` "invalid_id" delay.cancel ? // no vibration ``` - **Type:** ERROR - **Code:** INVALID_TIMER_ID - **Message:** cancel expects a valid timer id. ===== DOC: Number (https://simorg.art/docs/standard-library/4-plugins/number) ===== # Number The number plugin provides numeric conversion and representation helpers through the Simorg vibration API. Each vibration key maps to one number runtime function. Inputs are validated for type, range, and format, and the plugin returns either a converted value or no vibration for invalid arguments. ## Functions --- ## toU8 Converts input to unsigned 8-bit integer. ``` 255 number.toU8 ? // 255 ``` Out-of-range values no vibration will happen. ``` 256 number.toU8 ? // no vibration ``` - **Type:** ERROR - **Code:** RANGE_OVERFLOW - **Message:** Value is outside u8 range [0,255]. --- ## toU16 Converts input to unsigned 16-bit integer. ``` 65535 number.toU16 ? // 65535 ``` Negative values no vibration will happen. ``` -1 number.toU16 ? // no vibration ``` - **Type:** ERROR - **Code:** RANGE_UNDERFLOW - **Message:** Unsigned conversion cannot accept negative values. --- ## toU32 Converts input to unsigned 32-bit integer. ``` 4294967295 number.toU32 ? // 4294967295 ``` Fractional values no vibration will happen. ``` 12.5 number.toU32 ? // no vibration ``` - **Type:** ERROR - **Code:** INVALID_INTEGER_VALUE - **Message:** Integer conversions require whole numbers. --- ## toU64 Converts input to unsigned 64-bit integer. ``` 42 number.toU64 ? // 42 ``` Invalid numeric strings no vibration will happen. ``` "abc" number.toU64 ? // no vibration ``` - **Type:** ERROR - **Code:** INVALID_NUMBER_FORMAT - **Message:** Input must be numeric or a numeric string. --- ## toI8 Converts input to signed 8-bit integer. ``` -128 number.toI8 ? // -128 ``` Values above 127 no vibration will happen. ``` 128 number.toI8 ? // no vibration ``` - **Type:** ERROR - **Code:** RANGE_OVERFLOW - **Message:** Value is outside i8 range [-128,127]. --- ## toI16 Converts input to signed 16-bit integer. ``` -32768 number.toI16 ? // -32768 ``` Non-numeric input no vibration will happen. ``` "x" number.toI16 ? // no vibration ``` - **Type:** ERROR - **Code:** INVALID_NUMBER_FORMAT - **Message:** Input must be numeric or a numeric string. --- ## toI32 Converts input to signed 32-bit integer. ``` 1024 number.toI32 ? // 1024 ``` NaN-like values no vibration will happen. ``` "nan" number.toI32 ? // no vibration ``` - **Type:** ERROR - **Code:** INVALID_NUMBER_FORMAT - **Message:** Input must be a finite integer-compatible value. --- ## toI64 Converts input to signed 64-bit integer. ``` 9000000000 number.toI64 ? // 9000000000 ``` Values outside i64 range no vibration will happen. ``` "999999999999999999999" number.toI64 ? // no vibration ``` - **Type:** ERROR - **Code:** RANGE_OVERFLOW - **Message:** Value is outside i64 range. --- ## toDouble Converts input to double precision number. ``` "3.14" number.toDouble ? // 3.14 ``` Non-numeric strings no vibration will happen. ``` "abc" number.toDouble ? // no vibration ``` - **Type:** ERROR - **Code:** INVALID_NUMBER_FORMAT - **Message:** Input must be a valid numeric value. --- ## toFixed Formats a number with fixed decimal precision using [value, precision]. ``` (3.14159,2) number.toFixed ? // "3.14" ``` Precision outside [0,15] no vibration will happen. ``` (3.14,20) number.toFixed ? // no vibration ``` - **Type:** ERROR - **Code:** INVALID_PRECISION - **Message:** Precision must be between 0 and 15. --- ## inRange Checks whether value is in inclusive [min,max]. ``` (5,1,10) number.inRange ? // true ``` Invalid bounds no vibration will happen. ``` (5,10,1) number.inRange ? // no vibration ``` - **Type:** ERROR - **Code:** INVALID_RANGE_BOUNDS - **Message:** Minimum bound must be less than or equal to maximum bound. --- ## isInteger Checks whether input is a finite integer value. ``` 12.0 number.isInteger ? // true ``` Invalid input no vibration will happen. ``` "hello" number.isInteger ? // no vibration ``` - **Type:** ERROR - **Code:** INVALID_NUMBER_FORMAT - **Message:** Input must be numeric. --- ## fromString Parses a numeric string into best-fit numeric JSON type. ``` "42" number.fromString ? // 42 ``` Empty strings no vibration will happen. ``` " " number.fromString ? // no vibration ``` - **Type:** ERROR - **Code:** EMPTY_INPUT - **Message:** Input string must not be empty. --- ## toHex Converts integer input to lowercase hexadecimal string. ``` 255 number.toHex ? // "ff" ``` Negative values no vibration will happen. ``` -1 number.toHex ? // no vibration ``` - **Type:** ERROR - **Code:** INVALID_UNSIGNED_VALUE - **Message:** Hex conversion expects a non-negative integer. --- ## toBinary Converts integer input to binary string. ``` 10 number.toBinary ? // "1010" ``` Non-integer input no vibration will happen. ``` 3.5 number.toBinary ? // no vibration ``` - **Type:** ERROR - **Code:** INVALID_INTEGER_VALUE - **Message:** Binary conversion requires a whole number. --- ## fromHex Parses hexadecimal string into unsigned integer. ``` "ff" number.fromHex ? // 255 ``` Invalid hex strings no vibration will happen. ``` "xz" number.fromHex ? // no vibration ``` - **Type:** ERROR - **Code:** INVALID_HEX_STRING - **Message:** Input must be a valid hexadecimal string. --- ## fromBinary Parses binary string into unsigned integer. ``` "1010" number.fromBinary ? // 10 ``` Strings with characters other than 0/1 no vibration will happen. ``` "1021" number.fromBinary ? // no vibration ``` - **Type:** ERROR - **Code:** INVALID_BINARY_STRING - **Message:** Input must contain only '0' or '1'. ===== DOC: Random (https://simorg.art/docs/standard-library/4-plugins/random) ===== # Random The random plugin provides pseudo-random generators for decimal, integer, bool, and string values. Each vibration key maps to a random processing function. Invalid inputs are logged and result in no vibration. ## Functions --- ## decimal Generates random decimal in [0, max) for scalar max, or [min, max) for array input. The upper bound is exclusive. ``` 10 random.decimal ? // 4.2719 ``` Invalid decimal input no vibration will happen. ``` "bad" random.decimal ? // no vibration ``` - **Type:** ERROR - **Code:** INVALID_DECIMAL_INPUT - **Message:** Decimal random expects a number or [min,max] range. --- ## integer Generates random integer in [0, max] for scalar max, or [min, max] for array input. Both bounds are inclusive. ``` (1,6) random.integer ? // 4 ``` Invalid integer input no vibration will happen. ``` "x" random.integer ? // no vibration ``` - **Type:** ERROR - **Code:** INVALID_INTEGER_INPUT - **Message:** Integer random expects a number or [min,max] range. --- ## bool Generates random boolean using default 0.5 true probability. ``` random.bool ? // true ``` Input value is ignored for bool generation. ``` "anything" random.bool ? // false ``` --- ## string Generates random alphanumeric string of requested length. ``` 12 random.string ? // "aB9xQ2mN7pL1" ``` Negative or invalid length results in no vibration due to conversion failure. ``` "bad" random.string ? // no vibration ``` - **Type:** ERROR - **Code:** INVALID_STRING_LENGTH - **Message:** String random expects a valid non-negative length value. ===== DOC: String (https://simorg.art/docs/standard-library/4-plugins/string) ===== # String The string plugin exposes common string manipulation operations through Simorg vibrations. Each key maps to a dedicated string action function. Valid inputs produce a value and invalid inputs result in no vibration. ## Functions --- ## append Concatenates array of strings. ``` ("a","b","c") string.append ? // "abc" ``` Non-string array members result in no vibration. ``` ("a",1) string.append ? // no vibration ``` - **Type:** ERROR - **Code:** INVALID_ARGUMENT_TYPE - **Message:** append expects all arguments to be strings. --- ## at Returns character at index. ``` ("hello",1) string.at ? // "e" ``` Non-numeric index results in no vibration. ``` ("hello","1") string.at ? // no vibration ``` - **Type:** ERROR - **Code:** INVALID_INDEX_TYPE - **Message:** at expects a numeric index. --- ## format Replaces {} placeholders with provided values. ``` ("hello {}", "world") string.format ? // "hello world" ``` Placeholder/value count mismatch results in no vibration. ``` ("{} {}", "x") string.format ? // no vibration ``` - **Type:** ERROR - **Code:** FORMAT_ARG_MISMATCH - **Message:** Number of placeholders must match argument count. --- ## back Returns last character of a string. ``` "abc" string.back ? // "c" ``` Non-string input results in no vibration. ``` 12 string.back ? // no vibration ``` - **Type:** ERROR - **Code:** INVALID_ARGUMENT_TYPE - **Message:** back expects a string. --- ## erase Erases count chars starting at index. ``` ("abcdef",2,2) string.erase ? // "abef" ``` Invalid index types result in no vibration. ``` ("abcdef","2",2) string.erase ? // no vibration ``` - **Type:** ERROR - **Code:** INVALID_INDEX_TYPE - **Message:** erase expects numeric index and count. --- ## front Returns first character of a string. ``` "abc" string.front ? // "a" ``` Non-string input results in no vibration. ``` true string.front ? // no vibration ``` - **Type:** ERROR - **Code:** INVALID_ARGUMENT_TYPE - **Message:** front expects a string. --- ## insert Inserts string at index. ``` ("ac","b",1) string.insert ? // "abc" ``` Invalid index type results in no vibration. ``` ("ac","b","1") string.insert ? // no vibration ``` - **Type:** ERROR - **Code:** INVALID_INDEX_TYPE - **Message:** insert expects numeric position. --- ## popBack Removes last character. ``` "abc" string.popBack ? // "ab" ``` Non-string input results in no vibration. ``` 0 string.popBack ? // no vibration ``` - **Type:** ERROR - **Code:** INVALID_ARGUMENT_TYPE - **Message:** popBack expects a string. --- ## pushBack Appends one character from second arg. ``` ("ab","c") string.pushBack ? // "abc" ``` Non-string args result in no vibration. ``` ("ab",3) string.pushBack ? // no vibration ``` - **Type:** ERROR - **Code:** INVALID_ARGUMENT_TYPE - **Message:** pushBack expects string and character string. --- ## replace Replaces a substring at index with new string. ``` ("hello","y",1,1) string.replace ? // "hyllo" ``` Invalid numeric args result in no vibration. ``` ("hello","y","1",1) string.replace ? // no vibration ``` - **Type:** ERROR - **Code:** INVALID_INDEX_TYPE - **Message:** replace expects numeric position and length. --- ## substr Returns substring with start and length. ``` ("hello",1,3) string.substr ? // "ell" ``` Invalid index args result in no vibration. ``` ("hello",1,"3") string.substr ? // no vibration ``` - **Type:** ERROR - **Code:** INVALID_INDEX_TYPE - **Message:** substr expects numeric start and length. --- ## compare Lexicographically compares two strings. ``` ("a","b") string.compare ? // -1 ``` Non-string args result in no vibration. ``` ("a",1) string.compare ? // no vibration ``` - **Type:** ERROR - **Code:** INVALID_ARGUMENT_TYPE - **Message:** compare expects two strings. --- ## empty Checks whether string is empty. ``` "" string.empty ? // true ``` Non-string input results in no vibration. ``` 11 string.empty ? // no vibration ``` - **Type:** ERROR - **Code:** INVALID_ARGUMENT_TYPE - **Message:** empty expects a string. --- ## length Returns string length. ``` "hello" string.length ? // 5 ``` Non-string input results in no vibration. ``` 12 string.length ? // no vibration ``` - **Type:** ERROR - **Code:** INVALID_ARGUMENT_TYPE - **Message:** length expects a string. ===== DOC: Terminal Input (https://simorg.art/docs/standard-library/4-plugins/terminal-input) ===== # Terminal Input The terminal-input plugin controls terminal input listening and emits line events through Simorg vibrations. Actions are routed by key and invalid actions result in no vibration. ## Functions --- ## start Starts terminal input loop with a default terminal prompt string, prints the prompt, then reads a line when the user presses enter. Registers onReadLine listener for subsequent lines. ``` "> " terminal-input.start ? // 1 ``` Calling start repeatedly keeps listener active and returns start status. ``` "> " terminal-input.start ? // 1 ``` Non-string start value is rejected. ``` true terminal-input.start ? // no vibration ``` - **Type:** ERROR - **Code:** INVALID_ARGUMENT - **Message:** start expects a string default terminal prompt. --- ## stop Stops terminal input loop. ``` terminal-input.stop ? // no vibration ``` Stopping when not running still completes safely with no vibration. ``` terminal-input.stop ? // no vibration ``` --- ## onReadLine Event emitted when a new terminal line is read while input manager is running. ``` terminal-input.onReadLine ? // "user typed text" ``` If input manager is stopped, no line event is emitted. ``` terminal-input.onReadLine ? // no vibration ``` ===== DOC: Standard Library (https://simorg.art/docs/standard-library/introduction) ===== # Standard Library Simorg's Standard Libraries (STL) are a collection of frequently used blueprints, fufilling the initial requirements of artisans while the ecosystem is still young. $$$AlertBox type=WARNING title=PoC Mode message=Please keep in mind that current version of STL is in PoC mode, just like the other parts of the platform. So please avoid using them in production environment and wait for the first official LTS version. We will release more artifacts as we move forward.$$$ $$$AlertBox type=WARNING title=PoC Mode message=The existing list is not completed and more stl libraries will be added in future versions as we move toward a LTS version.$$$