[Dlang Episode 91] D Language - Templates - Part 6 of n - Template Mixins

Поділитися
Вставка
  • Опубліковано 26 вер 2024
  • ►Full DLang Series Playlist: • D Language (DLang) Pro...
    ►Find full courses on: courses.mshah.io/
    ►Join as member to get perks: / @mikeshah
    ►Lesson Description: In this lesson I introduce the idea of a 'template mixin' a powerful feature that combines what we have learned about in regards to both templates and mixins. Templates in D are parameterized code blocks that generate blocks of code at compile-time based on which are used. Combine that with the idea of a mixin, which allows us to mixin templated code 'as a string', and we get a really powerful feature. I've seen folks use this for things like serialization and deserialization, and we'll take a basic look at writing a 'getter' function for a struct as a template mixin. Let me know otherwise if you have found some pragmatic uses of this powerful feature.
    ►Please like and subscribe to help the channel!
    ►UA-cam Channel: / mikeshah
    ►Join our free community: courses.mshah....

КОМЕНТАРІ • 17

  • @Chupe_chupe
    @Chupe_chupe 4 місяці тому +1

    Great feature and great video Mike

  • @twenty-fifth420
    @twenty-fifth420 4 місяці тому +1

    HAHA FIRST!
    yeah, I got a D… file opened.
    And yeah, it is a new idea but only from a c-like lang. I am from Nim and Crystal. Both have templates.

  • @cyberninja005
    @cyberninja005 4 місяці тому +1

    @Mike Can you please do a tutorial on meta-programming in C++, and how it compares to other languages like Dlang.

    • @MikeShah
      @MikeShah  4 місяці тому

      I've done some videos on generics in C++ (e.g. ua-cam.com/video/irFkMavpL9A/v-deo.html), but not too much on C++ meta-programming. Will be something I cover more in the C++ series -- thought a comparison may be nice indeed.

  • @disdroid
    @disdroid 4 місяці тому +1

    Ive just had an amusing encounter with d language idiosyncrasies. I thought, since ordinary templates can be mixed in as well as the explicit mixin templates, what do we do about eponymity? Why not use our mixins in the same way, making use of a template that aliases itself to a symbol matching the name of the template (via TemplateOf in std.traits). This works great, until i try to use the mixin template a second time - i got symbol not found. This stumped me until i realised that i was overriding the name of the template in local scope. by defining the name of the template as a symbol for the output of the template, i had overriden the template's name. The solution was to use the fully qualified name to invoke the mixin template. This is less of a problem in this particular project because the templates are intended for use in generated code, so they wouldn't be used directly in an application or library.

    • @MikeShah
      @MikeShah  4 місяці тому +1

      We will talk about eponymous templates as you have stumbled upon -- coming up :) Indeed, sometimes having the fully qualified name (FQN) is the solution to some of these problems where names and scope collide.

    • @disdroid
      @disdroid 4 місяці тому +1

      @@MikeShah I didn't know where my symbol had gone - how could it disappear from one statement to the next? I had expected the compiler to backtrack after finding that the symbol in local scope didn't match the instantiation but it showed an error rather than checking the containing scope.

  • @TAKIROLI07
    @TAKIROLI07 4 місяці тому +1

    Hi Mike, I think it would be a good idea if you made explanations about Win32 api

    • @MikeShah
      @MikeShah  4 місяці тому +1

      Thank you for the kind words! I'll have to explore the Win32 API -- it's been a while since I've done anything beyond opening a window for OpenGL :)

  • @bsdooby
    @bsdooby 4 місяці тому +2

    So this functionality is like an API on steroids for instrumenting the (generated) code or the compiler. What are some exemplary use cases?

    • @MikeShah
      @MikeShah  4 місяці тому +2

      For me serialization and deserialization is a common use case. This has come in handy for both saving/loading data, and also for cases where I need to pack bytes together to send using the std.sockets API. Folks will also use template mixins to avoid the costs of inheritance (i.e. virtual calls), by just 'adding functionality', rather than having to resort to inheritance and creating an is-a relationship (which may or may not be necessary. I'd say it's necessary to use inheritnace as soon as you need to group objects together in a container as one example).
      Probably folks can think of other more wild (but useful) examples :)

    • @bsdooby
      @bsdooby 4 місяці тому +1

      @@MikeShah Thank you for this excellent response and good use case! much appreciated...

    • @disdroid
      @disdroid 4 місяці тому +1

      I'm working an idea for a language backend that runs in the compiler. mixin templates are used to represent all the parts of the parse tree. every token represents a mixin template, even the variables and function arguments. a script gets converted into a tuple that you can use in a class or anything at all, wherever you add the mixin to invoke the meta-compiler. or, instead of a tuple it can export a string constant that can easily be written to a file. so it's using template mixins as a middleware between a parse tree and blocks of D code.

    • @bsdooby
      @bsdooby 4 місяці тому +1

      @@disdroid What type or kind of language do you have in mind? You seem to know your way round...

    • @disdroid
      @disdroid 4 місяці тому

      @@bsdooby an example would be rule based languages, or things like rdf/owl. We could also make parts of JavaScript happen in the compiler, but not eval of a variable, nor anything to do with async/await or threads. I have an idea for a language that appears more like a script than D - but we can have features such as algebraic classes, so we can say "anything which isn't an InpuRange automatically inherits interface X (although it doesn't - there is no actual interface X, its just a set of mixins).
      Another point to be made is that inside the compiler mixins we purposely don't import tokens that are part of the language implementation - we require the user to provide implementations for certain symbols. Let's say I'm parsing an expression that uses + and this resolves to a template instantiation called add. If I want to ensure that my code is fully ctfe based I can use the version of add that composes an enum, whereas if I want it to read the current value from a variable every time the expression gets evaluated at runtime, I might choose a version of add that uses lambdas. So before I mixin the compiler I need to "import foo.bar : add = addLambdas;". We can then decide how we treat each token, either enum or lambda usually, but I've just written a small interpreter that mixes in each identifier as a mixin template in scope, and aliases the result, inside an expression, which means that we could create custom behaviour for a particular variable without affecting the grammar or the parser. This hasn't been committed yet - the project is called coregrammars and the module is coregrammars.parsers.expr - look right at the end of the file, the last few unittests do a variety of things with the identifiers in the parse tree. I've got compilation time back to normal at last! Hopefully I will push this code to GitHub today.
      In actual fact, parameters in mixin templates are unnecessary in respect of adding symbols into scope.