High Efficiency
Execution time and memory consumption on par with leading imperative languages
The efficiency of a software solution is one of the key qualities of the programming language in which it is written. To neglect this aspect of a language is to forfeit a lot of its applicability. By compiling directly to native machine code, Duckling will be among the leaders of the market. This strategy leads to fast execution, low energy consumption, low latency, and high applicability. Furthermore, it will allow Duckling's ecosystem to be independent of other languages, even in the implementation of libraries which prioritize efficiency.
Unique debugger
A dedicated virtual machine provides accessible and powerful debugging capabilities
A developer's work will inevitably require fixing errors in the software which they produce. Despite best efforts in detecting errors during compilation, no programming language can eliminate them completely.
One of the primary goals of the project is to create a high-performance virtual machine with architecture dedicated to effective runtime error detection. Apart from compilation to native machine code, Duckling will support running on this virtual machine which will fill the role of a specialised debugging environment. This will enable the programmer to precisely control the state of the execution with ease, thus facilitating the elimination of the three most important categories of errors:
- logic errors,
- memory errors, and
- concurrency errors.
Adaptable to your needs
Ideal for quick scripting and large projects alike
Although suitability for scripts may seem to contradict suitability for projects, we believe it not to be so. Our aim is to create a language which will combine the best of both worlds.
By tapping into the scripting world, a programmer will be able to iterate ideas frequently, and write prototypes quickly. This comes with effective testing and easy integration with existing code in both small and large applications.
By tapping into the large-scale world, a programmer will be able to use large modules and applications in their scripts without any complications. All will be available in a single cohesive language and its ecosystem.
We combine functionalities from both worlds with minimal differences between how the compiler treats scripts, compared to "standard" modules.
Structured concurrency
Direct correspondence between concurrent execution and program structure
As processors' thread counts increase, the ability for an application to get the most out of concurrent execution is increasingly important. At the same time, the proper design of multithreaded solutions is one of the hardest tasks which a programmer might face.
To remedy this problem, Duckling introduces "structured concurrency". Our goal is for the programmer to think about threads in the same way that they think about modules and functions. We also introduce a clear distinction between fragments of code which are thread-safe, those which are not, and those which share their state with other fragments.
This approach greatly facilitates program design and analysis. It also enables the compiler to perform static analysis which detects some concurrency errors before the application is even executed.
Modern typesystem
A refined blend of interfaces, algebraic data types, and generics
One of the most important design assumptions of Duckling is static typing. It facilitates early error detection, powerful support of editors and IDEs, and compilation to efficient machine code. Our goal is for Duckling's typesystem to be as helpful and unobtrusive for the programmer as possible. To accomplish this, we designed it form the ground up. While we are obviously inspired by existing solutions, we add a handful of ideas of our own. It is important for us to hide the typesystem when possible during scripting. Although all objects will be statically typed, the programmer will be able to skip most of the type specifications.
The most important functionalities of our type system are:
- interfaces, which allow precise definitions of the properties satisfied by a type,
- algebraic data types, which conveniently and legibly express product and union types and introduce structure to data, and
- generics, which prevent repetitive code and are statically checked for errors before their first use.
Duckling also introduces a refined reference system which allows a programmer to precisely define data flow and avoid unintended data access. We ensure that typical programs require only minimal annotations to express the desired properties of the references.
A practical approach
Duckling is designed with practice in mind
Although "practical approach" is a broad and imprecise term, for us it conveys an important idea that is crucial in a language with such an extensive range of functionalities as Duckling. Our interpretation of this slogan pertains to the programming experience in general, instead of the solutions of particular problems. We are committed to design a language that is consistent, intuitive, and easy to learn. Even if Duckling as a whole will be relatively complicated, its fundamental components shall be maximally approachable. We are cutting down on niche functionalities which would unnecessarily complicate the language. We intend to promote qualities which improve the language as a whole, e.g. by reducing boilerplate code.
Modern compiler
A modern compiler, with support of incremental compilation, rich IDE support and high quality of diagnostic messages
In the last few decades, programming evolved on all fronts. Today, applications are continuously growing bigger, and programming tools are getting increasingly advanced. That is why when designing a compiler, we focus not only on raw machine code generation, but also on several other important features.
First, it is paramount to ensure good support in code editors. This requires a compiler capable of functioning as a language server, with low response times and broad support for the functionalities of an IDE.
Second, from the very beginning, we're working on support for advanced incremental compilation. This aims to reduce recompilation time, which starts to matter at as few as a couple thousand lines of code.
Finally, we care about clear and informative error reporting. This involves not only proper message content and formatting, but also support for convenient functionalities such as control over the level of detail.
Powerful metaprogramming
An advanced metaprogramming system based on procedural macros, templates, and parametrized modules
Many of the languages currently in use implement the broad concept of metaprogramming. In Duckling, we introduce an advanced system which operates in compile-time only. This is achieved through several mechanism which allow for the modification or generation of code at various levels of granularity.
In order to handle the largest pieces of code, we introduce parametrised modules. These enable the creation of entire module trees containing many source files, all dependent on a specific set of parameters. These parameters can be either types or values.
For precise generation or modification of code at the lowest level of granularity, we introduce procedural macros, enhanced with a capable reflection system. Their use may result in automatic generation of complete fragments of code, or supplementing classes with additional methods.
In between these two levels, we also support templates. They behave similarly to parametrized modules, but apply to code segments such as functions, classes, or namespaces.
Integrated build system and package manager
Compile even the largest projects with minimal configuration and a single command
One of Duckling's important goals is to simplify the compilation process so that, during standard use, a programmer needs to write no more than a few lines of configuration for a package, and zero lines of configuration for scripts. This is made possible by introducing a precise system of packages and modules, allowing the compiler to unambiguously interpret source files. Tasks such as compiling, running an application, or testing a package should require executing a single command.
Additionally, the well-defined concept of a Duckling package enables the integration of a package manager, creating a cohesive ecosystem. This allows for the publishing of packages and using publicly available packages by writing just a few lines of configuration.