Stop Coding, Start Configuring
When you think about your computer as a software developer, weird axioms emerges as a natural consequence of pursuing that idea to its natural result
Join the DZone community and get the full member experience.Join For Free
Most apps have commonalities that can be extracted, where generalised solutions can be created, based upon patterns of reusable components. Some examples here are Angular Material, BouncyCastle, and MimeKit. All of the previously mentioned libraries assumes you want to achieve something specific, for then to create high level components, allowing you to solve your problems. This of course is the very foundation of "libraries", "frameworks" and "components". As in; Reusability is king. However, the same is also true for your resulting end app. If you look at your last application, you will find that it has at least some of the following moving parts.
- It needs to authenticate users
- It needs to authorise access to its parts
- It needs to log events
- Etc, etc, etc
The AOP promise
The promise of Aspect Oriented Programming was that instead of "coding" these generalised parts, you could "apply them as aspects" to your code. Such as the following illustrates.
The above AOP example simplifies your code a lot, making things much more easily understood, and allows meta data to be extracted from your classes and components, to see what your classes and methods do from a high level perspective. Comparing this to the manually created solution, where you're creating code to achieve the same, becomes almost unfair. The number of lines of code would literally explode if you typed out the code needed to achieve the same as the above AOP example illustrates.
However, if you think about the above code, it's almost more like "configuring" than "coding". Hence, configuration could probably drive these ideas much further down the rabbit hole. For instance, why don't we allow for declaring our database connection as an attribute on our classes? This of course is because AOP can only bring us this far. In order to successfully use your database connection, you'll need it as a field on your class somehow - And AOP cannot inject fields into your classes for obvious reasons. AOP can only inject "code snippets" that in isolation achieves one thing, and one thing only. AOP doesn't allow you to orchestrate code blocks together, into a uniform whole, where each block of code has access to other blocks of code, to collaborate on solving a single task.
The configuration approach
Look at the following Hyperlambda.
It looks almost like YAML doesn't it ...?
Hyperlambda's idea is that if we can use YAML to configure our DevOps pipelines, we could probably use similar mechanisms to create our entire apps. And in fact the above "slots" resembles the attributes from the C# example further up once you think about it. With one crucial difference being that they are recursive in nature. For instance the following line of code ...
... does exactly what I said AOP couldn't do. It "declares" a database connection. The code inside of this [data.connect] block (everything below it) will implicitly use that database connection every time it connects to a database to do something. And since Hyperlambda is just a textual representation of a tree structure, it's almost as easily traversed as attributes on your C# classes. Hence, no meta data is lost during the process.
However, from a purely conceptual point of view, the first Hyperlambda code block above is really more similar to a "configuration" file than "code". For instance, it can be loaded and executed dynamically. If we change its content during runtime, no additional compilation is required, and whatever the code actually does will instantly change. In such a way we have "configured" our entire HTTP REST endpoint, allowing us to dynamically traverse the configuration, to intelligently deduct what it does, using automated processes, extracting meta data from our Hyperlambda.
Hence, we've stopped "coding" and replaced it with "semantic configurations". Changing from MySQL to SQL Server, is as easy as doing a "Find and Replace" substitution "database-type:mysql" with "database-type:mssql". The same could be said about changing table names, field names, etc, etc, etc. Simply because we no longer have "code", but only a bunch of loosely coupled configuration files, achieving the exact same thing as code used to do for us. And yes, the thing is Turing Complete before you ask ...
In case you're wondering what the above Hyperlambda code actually does, realise it joins three tables together, creating aggregate results, ordering records from the "topics" MySQL database table, according to which topic had recent activity, for then to return this back to the client as an array. In addition it adds HTTP caching, and a friendly description text part that explains with plain English what the endpoint actually does. The endpoint does not have authorisation requirements, allowing anyone to invoke it.
The final thing we need to do, is to simply wire up the above code to be executed as a result of some HTTP VERB and URL request towards our server, and voila; We're done! But wiring URLs will be the exercise of my next article. However, if you want a taste you can check out the documentation for magic.endpoint. To play around with these ideas, you'll need Magic - You can find it below ...
Psst, I published Magic as 100% Open Source as of yesterday in case you're afraid of "vendor lockin" ... ;)
Opinions expressed by DZone contributors are their own.