As IDEs for statically typed languages become more powerful, and dynamic languages more popular we have two forces moving in opposite directions. It seems younger programmers are choosing dynamic languages over tools over what are widely considered best practices for the efficiency of runtimes, scalability of teams, and maintainability of solutions long term.
The code behind the dynamic runtime is always part of the build/run environment but not always part of the application runtime. You might only enable it for your application in a maintenance or customization mode and then turn it off for normal operation.
The StrataCode dynamic runtime can be used to watch for code changes and let you refresh as needed. If the changes only include configuration changes to reactively aware components, these changes can be applied "on the fly" - without restarting. If you happen to be running in the browser in a client/server environment, a patch is sent to update the client after the server has been updated. If you have made changes that require a recompile and restart, StrataCode lets you know a restart is needed. To speed up round trip times after code changes, incremental builds work in many cases which only take a few seconds.
You can also programmatically make a change to the code - for example, to change the initializer for a property or to change the expression in a data binding rule. Using the parselets framework, it makes an incremental change to the source file maintaining this change. This works even if the original source was provided by a developer. Comments and formatting are preserved.
These capabilities offer a wide-range of tooling possibilities for management UIs to be built which empower technical users to make customizations.
Dynamic Layers, Classes, Objects
StrataCode also supports dynamic layers, classes and objects - a full simulation environment for running StrataCode/Java directly from the parsed language model (the AST). This mode of interpreting a class is optimized for "run once" code: small amounts of code or configuration that do not have large loops or operate on large data sets. You can use dynamic layers when you want to reconfigure components without recompiling or change code quickly without restarting. It's also a great engine for running untrusted code because you have complete control over the runtime environment from simple Java code.
The dynamic runtime is also used for bootstrapping the system, to parse and run the layer definition files. It's a mostly accurate Java emulation layer that has been tested on over 100K lines of code without workarounds.
Interpreted or Compiled?
There's a tradeoff - small system prototyping is faster with interpreted languages. Large systems are more efficient with compiled systems. Rearchitecting at any stage of a business is usually not desirable for many reasons.
In addition to modularity, layers provide a way to place a moveable boundary between interpreted and compiled code. You have compiled layers which generate a typical .jar representation of your Java application. As you develop, or in production when you need dynamic code, you use dynamic layers on top of those compiled layers. These are read from disk and interpreted using dynamic types for any classes you define. Any classes modified by any dynamic layers are automatically made dynamic. Dynamic features of dynamic types can be modified at runtime. And for declarative applications, handling these changes can be easy using event listeners, and property change events. When frameworks support changing properties at runtime, this provides an excel-like experience for declarative programmers. But when you need production code, move this code into a compiled context and run it with all of the speed, and integrity benefits of Java.
Most interpreted languages also do not do static type checking. You do not have to declare your data types and can add attributes on a per-instance basis. StrataCode currently only supports static type checking, even in dynamic mode. Rather than abandon typing, we'd rather use multiple-inheritance and layers to keep static typing for as much of the system as possible.
Some changes made to dynamic types may require a recompilation and restart of the application - those that touch compiled-in features. For example, extending a new compiled class, or overridding a compiled method for the first time. Since StrataCode uses Java's runtime, when a compiled class changes, a restart is needed to pick up this change. In these cases, StrataCode detects this situation and can provide support for tools to make this manageable for the user.