Cognibotics Logo
Cognibotics Logo
ArticlesJuliet the real time sister of julia programming language

Juliet: The Sister Language of Julia for Motion Programming

In the ever-evolving world of programming languages, Julia has made a name for itself as a high-performance, high-level language designed for technical and scientific computing. Known for its speed and flexibility, Julia has been widely adopted in fields like data science, machine learning, and scientific research. However, as real-time computing and programming of motions become increasingly essential in modern applications—such as robotics, automation, real-time data processing, and embedded systems for machine control—Julia got a sister who is very helpful for programming real-time motions, which Julia herself is not quite suited for. 

Thus, Juliet can be viewed as real-time Julia for programming physical machine motions.

What is Juliet?

Juliet is a programming language built on the foundational ideas of Julia but tailored specifically for programming of real-time motions and other types of real-time data processing. These systems require guaranteed responsiveness within stringent time constraints, a critical requirement in fields like autonomous vehicles, industrial automation, and medical devices. While Julia excels in number-crunching and parallel computations, it was not designed with the features needed for deterministic operations. This is where Juliet steps in, bringing real-time performance guarantees to the table while maintaining many of the strengths and conveniences that make Julia popular.

Key Features of Juliet

  1. Safe Execution: Juliet is a safe language. Another safe language is C#, unless the keyword unsafe is used, but the design of C# prevents a real-time version. Actually, there is only one language that is safe, real-time performant, efficient, preemptive, multitasking, and is building on an accepted base language that has a vital and growing community. That one and only language is Juliet! Juliet being safe means that every Juliet program defines what running the program can result in, even if there are errors in it.  Programs written in unsafe languages like Python, C, and C++ define possible results if there are no errors. But in practice you cannot know if there are errors and what those could be, and in an unsafe language, errors may result in illegal memory access and undefined behavior. Juliet programs can of course contain bugs, but those only effect result in a local and well defined way.

  2. Meta programming: One important feature of a new programming language is programs for programs. It means that a program can be designed to read, generate, analyze, or transform other programs, and even derive new versions of itself, while running. A robot can thereby provide AI-suitable symbolic functions and interfaces.

  3. Multiple dispatch: A key feature of a programming language is to provide the ability to define function behavior across combinations of argument types. To make code more reusable, functions having different sets of arguments can co-exist coherently in modules such that new functionality can be added easily. Juliet supports keyword arguments and default values of arguments, as well as anonymous functions.

  4. Concurrency and Parallelism: While Julia is renowned for its concurrency and parallelism capabilities, Juliet enhances these features to better support real-time requirements. Juliet has libraries for the real-time tasks as supported by the Romeo runtime. Juliet also has libraries for real-time concurrent message handling and asynchronous event processing for quick reactions to sensor inputs. 

  5. Generic functions and parametric types: To avoid duplicate code, modern languages support generic functions and parametric types. This allows developers to avoid writing the same functions for different types among other things. In combination with meta-programming this is useful for composing motion statements within the context of the manufacturing process at hand. Think about grinding a sharp corner of a workpiece that has an uncertain position relative to the robot tool.

  6. Built in package management: Juliet uses packages just like Julia as an entity for distributing (specific versions of) solutions and offered features. Juliet supports both source code packages and compiled packages. The package manager connects to local or remote Juliet registries and users can set up their own registries. Compatibility with Julia enables seamless integration of AI functions.

  7. Byte code generation: The Juliet compiler generates bytecode for the Romeo runtime. Other compilers producing Romeo bytecode can reuse compiled Juliet packages. This allows simpler languages to utilize the full expressiveness and power of Juliet. For specific purposes, tailored binaries can be generated from Juliet as well, for instance LLVM code as Julia uses, but Romeo byte-codes are on a higher level.

  8. Early error detection: Juliet strives to be a language easy to learn and easy to use but also drives the mantra of “rather an error at compile time than at runtime” to help developers to deliver better code. This is also related to predictability. Compared to Julia there are a few restrictions on dynamic definition of data types, mainly visible in that variable declarations have to use the VAR keyword like in javascript.

  9. Incremental compilation: The Juliet compiler works incrementally such that developers perceive the language as being dynamically interpreted. Together with the incremental code loading in Romeo, this gives the developer a great experience when debugging and developing the code, in particular for physical robot motions.

  10. REPL: The Juliet compiler holds a Read, Evaluate and Print Loop which is an interface where the developer can test code and get an immediate answer if the code compiles or not. It is like working with an interpreter. Julia is doing this without Romeo, but without real-time guarantees. Both Julia and Python have REPL implementations, the Julia one being safe and thereby better suited for being embedded into machine interfaces. This helps in making the language more dynamic to the developer.

Use Cases for Juliet

Juliet’s capabilities make it well-suited for a variety of real-time computing applications. Below are some examples where it can play a pivotal role:

  1. Motion Programming: A robot program can on one hand be considered as just being a computer program with some special functions for performing motions. This holds for simpler applications where PLC programming is used today, with a reset-and-redo type of interaction with the motion programmer. However, for more advanced applications where there is also an interaction with some manufacturing process like drilling or grinding that has a physical state to be dealt with, the programming and execution needs to be different, as supported by Juliet.

  2. Package and library development: Systems today do not let different technology providers keep their know-how and embedded resources isolated within the resulting system, which limits business since motion apps can only work for a more complex version of the digital twin without real-time performance. In contrast, Juliet’s combination of encapsulated safe execution, proper package management as in Julia, code encryption, and the real-time features make it a natural choice for implementing control systems parts in robots without risking IP leakage.

  3. Event driven automation: Automation has for a long time been the domain of the IEC 61131 languages and runtimes. However the world is continuously changing and IEC 61131 is today a too limited tool for many more demanding applications. Also moving from the cyclic execution of the PLC paradigm is very often wanted by modern developers. At the same time Juliet code can coexist with most IEC 61131 runtimes and seamlessly exchange data.

  4. Real-Time Data Processing: Applications in robotics and automation are increasingly forced to handle real-time data streams from complex sensors and connected AI systems. Juliet and the real-time capabilities allows user-level functions to deal with these challenges without compromising instant reactions to external events. Event services can easily be defined to react like motion reflexes.

  5. Embedded Systems: Embedded systems that control hardware devices—such as industrial machines, pacemakers, or home automation systems—benefit from Juliet's real-time guarantees. In these systems, it is crucial that control logic executes with precision and without delay.

How Juliet Differs from Julia

While Juliet shares its roots with Julia, the two languages serve different purposes and cater to different domains. Julia is designed for general-purpose high-performance computing, particularly for numerical analysis and machine learning, and prioritizes speed through techniques like just-in-time (JIT) compilation and efficient handling of mathematical computations.

Juliet, on the other hand, sacrifices some of Julia's flexibility and dynamism in favor of predictability and real-time guarantees as for example by static typing and compilation to byte code. Where Julia focuses on maximizing throughput and performance, Juliet is designed to ensure that operations are completed within strict time constraints. This makes Julia better for exploratory data analysis or high-performance scientific computing, but Julia being the choice for real-time systems, while still supporting an interactive mode of operation.

Juliet will always stay close to Julia so that a developer shall immediately feel comfortable with switching between the two and if you learn one the threshold shall be really small to learn the other. Juliet and Julia also have the necessary libraries to easily exchange data between the two. In contrast to object-oriented languages like Python, Java, C++ and C#, both Julia and Juliet are defined such that data structures always have a known size in memory at runtime, thereby permitting optimizations that others cannot do.

The Future of Real-Time Computing with Juliet

As the world becomes increasingly interconnected with IoT devices, autonomous systems, and real-time data-driven applications, the need for a language like Juliet becomes more apparent. By providing a robust platform for real-time systems, Juliet fills a gap in the current landscape of programming languages, where few high-level languages offer real-time performance guarantees while at the same time being safe (opposed to C/C++, which we however use at system and device-driver level via the Juliet foreign-function interface).

As more industries shift toward automation, smart devices, and AI-driven real-time decision-making, Juliet is poised to become an essential tool for developers working on cutting-edge technology. Its integration with real-time systems and real-time operating systems will allow developers to push the boundaries of what's possible in fields like robotics, industrial automation, and real-time data analytics.

Conclusion

Juliet is more than just a real-time sister of Julia—it's a significant leap toward real-time computing in high-level languages. By building on Julia’s strengths in high-performance computation while adding features together with Romeo like deterministic execution and real-time garbage collection, Juliet and the tight integration with Romeo runtime environment provides developers with a powerful tool for building the next generation of real-time systems. As real-time applications become more prevalent, Juliet is well-positioned to lead the change, offering the performance, predictability and interactivity that is required for these complex time-critical tasks.