5

Increasing code quality with Hyperlambda

 2 years ago
source link: https://dzone.com/articles/increasing-code-quality-with-hyperlambda
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Increasing code quality with Hyperlambda

It is possible to create great code with C# and Java, but it's really hard. With Hyperlambda it's almost impossible to create bad code. See my reasoning here

Oct. 23, 21 · Agile Zone · Presentation

Join the DZone community and get the full member experience.

Join For Free

Fundamentally Hyperlambda is really just a Turing complete markup language, with some added capabilities resembling features from XSLT and XPath. You could argue Hyperlambda is the programming equivalent of YAML. On the index of "programming level abstractions" if we argue that CISC x86 assembly code is at level 1 (the bottom level) and C# and Java is at level 5, while Python and PHP are at level 10 - Hyperlambda is at level 100+ somewhere.

Of course, the point being, that 95% of the times you need a low level programming construct, Hyperlambda implicitly creates your C# objects and ties these together 100% correctly out of the box. This reduces the cognitive complexity of your resulting app's code by orders of magnitudes. To illustrate this difference, please have a look at the following code snippet taken from Microsoft's official documentation for how to correctly create an HTTP request from C#.

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }
    public IConfiguration Configuration { get; }
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddHttpClient();
        // Remaining code deleted for brevity.

In addition to the following snippet ...

public class BasicUsageModel : PageModel
{
    private readonly IHttpClientFactory _clientFactory;
    public IEnumerable<GitHubBranch> Branches { get; private set; }
    public bool GetBranchesError { get; private set; }
    public BasicUsageModel(IHttpClientFactory clientFactory)
    {
        _clientFactory = clientFactory;
    }
    public async Task OnGet()
    {
        var request = new HttpRequestMessage(HttpMethod.Get,
            "https://api.github.com/repos/dotnet/AspNetCore.Docs/branches");
        request.Headers.Add("Accept", "application/vnd.github.v3+json");
        request.Headers.Add("User-Agent", "HttpClientFactory-Sample");
        var client = _clientFactory.CreateClient();
        var response = await client.SendAsync(request);
        if (response.IsSuccessStatusCode)
        {
            using var responseStream = await response.Content.ReadAsStreamAsync();
            Branches = await JsonSerializer.DeserializeAsync
                <IEnumerable<GitHubBranch>>(responseStream);
        }
        else
        {
            GetBranchesError = true;
            Branches = Array.Empty<GitHubBranch>();
        }
    }
}

... there are some roughly 10 additional code snippets at Microsoft's example. However, I won't bore you with all the details in regards to these - The point is that it's extremely complex to simply GET a freakin' HTTP request using C#, and hundreds of things might go wrong in the process ...

All in all we're talking about 50+ lines of code, scattered in 3 different files, requiring the consumer of the class to understand constructs such as dependency injection, async method invocations, JSON serialisation and deserialisation, IDisposable objects, etc, etc, etc. Notice, the above code doesn't even include the model class for the returned objects either, so the actual code example would probably end up becoming almost 100 lines of code in at least 3 different files. Then look at the equivalent Hyperlambda example doing the exact same thing.

Plain Text
http.get:"http://github.com"

Under the hoods the Hyperlambda code snippet does the exact same thing, with one crucial difference of course, being that the C# example is 50 to 100 times more complex, implying it is 50 to 100 times as likely that something will go wrong. This is not unique for HTTP requests, and similar differences can be found if you try to retrieve data from your database, create multiple threads, save and load files, etc, etc, etc. All in all, this reduces the complexity of your end resulting code by orders of magnitudes, making it extremely easy to read, and more importantly resulting in that it becomes almost impossible for your junior developers to do something wrong as they create code in Hyperlambda.

SOLID

Another paradox with Hyperlambda is that even though the ideas of SOLID was originally invented to create best practices for OOP software development, and Hyperlambda doesn't contain a single OOP construct - Hyperlambda code is arguably "implicitly SOLID code". For instance, the S from SOLID implies "single responsibility". Hyperlambda is a functional programming language, and to correctly implement SOLID in OOP, you often end up with classes with one single public method. This single method of course, encapsulates the entirety of the "responsibility" of your class, often reflected as a single verb, such as "Run", "Download", "Open", etc. After you've created your "SOLID" class, you typically encapsulate it into an interface, wire up the interface through your IoC container, and allow the rest of your team to use it exclusively through your interface.

The paradox I am coming to is that a functional programming language is fundamentally better at "single responsibilities" than OOP languages for these reasons, simply because when all functions are verbs, they are implicitly SOLID in nature. Violating single responsibility in a language where everything is a single function, doing only one thing, encapsulated through a single verb, arguably becomes impossible. I could go on with the rest of the 4 letters from SOLID, however I suspect you get the idea.

Removing complexity

Instead of asking ourselves exactly what Hyperlambda has, let's define the language from the perspective of what it does not have ...

  1. Hyperlambda does not have dependency injection
  2. Hyperlambda does not have polymorphism
  3. Hyperlambda does not have inheritance
  4. Hyperlambda does not have constructors
  5. Hyperlambda does not have interfaces

I could go on for hundreds of pages illustrating what Hyperlambda does not have, and also argue why this is Hyperlambda's advantage, but the point is that due to what it does not have, Hyperlambda becomes that much more easy to learn and use correctly. Learning how to correctly apply OOP in a language such as C# typically requires 10,000 hours of software development, often for a decade or more. And until you understand complex ideas such as IoC containers, interfaces, SOLID, design patterns, etc - Imagining you are able to create high quality code in a language such as C# is at best delusional.

Befriending the junior developer

This implies that you can take a junior developer with a weekend of programming experience, and simply assume he's (almost) able to implement perfect code out of the box. Of course, for a senior developer, with decades of experience, how SOLID, IoC containers, and interfaces, etc are supposed to be tied together is a no-brainer. But for a junior developer, understanding these constructs is extremely hard!

Assuming you work on a team, you'll be forced to collaborate with junior developers at some point in your career, and due to the extendibility features of Hyperlambda, the senior developer can do all the "complex stuff", and wrap it into a dead simple interface for the junior, such as illustrated below.

Plain Text
using magic.node;
using magic.signals.contracts;
namespace acme.foo
{
    [Slot(Name = "acme.foo")]
    public class Foo : ISlot
    {
        public void Signal(ISignaler signaler, Node input)
        {
            var arg1 = input.Children.First().Get<int>();
            var arg2 = input.Children.Skip(1).First().Get<int>();
            // ... do more complex stuff here ...
            input.Value = arg1 + arg2;
            input.Clear();
        }
    }
}

The above is actually a working example of how to extend Hyperlambda with the keyword [acme.foo], from where you've got access to all the complexity of C# and the CLR, and you can apply as much dependency injection and SOLID as you wish, exposing your beautifully created C# code through a single Hyperlambda keyword, ensuring that there's no way the juniors in your team could possibly mess things up for you.

In a typical enterprise software development environment, roughly 50% of all developers are junior developers. The above ideas results in higher quality code in the end, more stable and secure products, where all the complexity is implicitly hidden from view, while yet providing extendability for those times you need such things. I love analogies, and in a way this lubricates the engine of your software development department, allowing all to contribute at whatever level they're skilled enough to contribute at, without exposing complex things to the noobs, and/or the people simply integrating your advanced C# code at whatever level they're supposed to consume it through.

Reusability

As an added effect, all Hyperlambda slots you create using constructs such as illustrated in the above C# code implicitly becomes reusable, allowing you to think about Hyperlambda as the conductor of your symphonic orchestra, where your C# constructs becomes the individual instruments. The idea of course being that out of the box, Magic gives you hundreds of such reusable constructs before you even start your own project. A Famous man once said the following about reusability in OOP ...

You want the banana, you get a gorilla, holding a banana, in the rain forest

For everyone having tried to reuse things in C#, the above analogy becomes painfully true. With Hyperlambda though, the following is the truth ...

You want the banana, you get the banana, PERIOD!

No more gorillas or rain forests ...

15297985-banana.jpg


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK