Assigning names to unnamed labels

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
0
down vote

favorite












I'm working on a compiler. During the final stage I will get a collection of Lines.



This is the method that takes the Lines and gives name to Labels that don't have it yet.



Lines can have Labels. When a Line doesn't have a Label, its Label property is set to null. Apart from this, Labels can be unnamed (Label.Name is null)



This is the method. It looks ugly and I'm using a nested method. Please, review it and try to improve it to be elegant. Performance isn't a requirment (at least, for now):



private static void GiveNameToUnnamedLabels(IEnumerable<Line> finalCode)

int count = 0;

void GiveName(Model.Label label)

label.Name = $"dyn_label++count";


var unnamed = finalCode.Where(x => x.Label != null && x.Label.Name == null).ToList();
unnamed.ForEach(x => GiveName(x.Label));







share|improve this question

















  • 2




    I'm not really a fan of slapping a .ToList() on LINQ queries just to use the .ForEach() method of the List<T> class. I would suggest removing it and using a normal foreach loop.
    – Jesse C. Slicer
    Mar 23 at 0:53
















up vote
0
down vote

favorite












I'm working on a compiler. During the final stage I will get a collection of Lines.



This is the method that takes the Lines and gives name to Labels that don't have it yet.



Lines can have Labels. When a Line doesn't have a Label, its Label property is set to null. Apart from this, Labels can be unnamed (Label.Name is null)



This is the method. It looks ugly and I'm using a nested method. Please, review it and try to improve it to be elegant. Performance isn't a requirment (at least, for now):



private static void GiveNameToUnnamedLabels(IEnumerable<Line> finalCode)

int count = 0;

void GiveName(Model.Label label)

label.Name = $"dyn_label++count";


var unnamed = finalCode.Where(x => x.Label != null && x.Label.Name == null).ToList();
unnamed.ForEach(x => GiveName(x.Label));







share|improve this question

















  • 2




    I'm not really a fan of slapping a .ToList() on LINQ queries just to use the .ForEach() method of the List<T> class. I would suggest removing it and using a normal foreach loop.
    – Jesse C. Slicer
    Mar 23 at 0:53












up vote
0
down vote

favorite









up vote
0
down vote

favorite











I'm working on a compiler. During the final stage I will get a collection of Lines.



This is the method that takes the Lines and gives name to Labels that don't have it yet.



Lines can have Labels. When a Line doesn't have a Label, its Label property is set to null. Apart from this, Labels can be unnamed (Label.Name is null)



This is the method. It looks ugly and I'm using a nested method. Please, review it and try to improve it to be elegant. Performance isn't a requirment (at least, for now):



private static void GiveNameToUnnamedLabels(IEnumerable<Line> finalCode)

int count = 0;

void GiveName(Model.Label label)

label.Name = $"dyn_label++count";


var unnamed = finalCode.Where(x => x.Label != null && x.Label.Name == null).ToList();
unnamed.ForEach(x => GiveName(x.Label));







share|improve this question













I'm working on a compiler. During the final stage I will get a collection of Lines.



This is the method that takes the Lines and gives name to Labels that don't have it yet.



Lines can have Labels. When a Line doesn't have a Label, its Label property is set to null. Apart from this, Labels can be unnamed (Label.Name is null)



This is the method. It looks ugly and I'm using a nested method. Please, review it and try to improve it to be elegant. Performance isn't a requirment (at least, for now):



private static void GiveNameToUnnamedLabels(IEnumerable<Line> finalCode)

int count = 0;

void GiveName(Model.Label label)

label.Name = $"dyn_label++count";


var unnamed = finalCode.Where(x => x.Label != null && x.Label.Name == null).ToList();
unnamed.ForEach(x => GiveName(x.Label));









share|improve this question












share|improve this question




share|improve this question








edited Mar 23 at 16:39
























asked Mar 22 at 23:55









SuperJMN

1415




1415







  • 2




    I'm not really a fan of slapping a .ToList() on LINQ queries just to use the .ForEach() method of the List<T> class. I would suggest removing it and using a normal foreach loop.
    – Jesse C. Slicer
    Mar 23 at 0:53












  • 2




    I'm not really a fan of slapping a .ToList() on LINQ queries just to use the .ForEach() method of the List<T> class. I would suggest removing it and using a normal foreach loop.
    – Jesse C. Slicer
    Mar 23 at 0:53







2




2




I'm not really a fan of slapping a .ToList() on LINQ queries just to use the .ForEach() method of the List<T> class. I would suggest removing it and using a normal foreach loop.
– Jesse C. Slicer
Mar 23 at 0:53




I'm not really a fan of slapping a .ToList() on LINQ queries just to use the .ForEach() method of the List<T> class. I would suggest removing it and using a normal foreach loop.
– Jesse C. Slicer
Mar 23 at 0:53










2 Answers
2






active

oldest

votes

















up vote
4
down vote



accepted










A few notes about your code:



  • Both the inner and outer method are fairly small, and the name of the outer method is already aptly descriptive, so I see no need for a named inner method here. An anonymous method would suffice.


  • List<T>.ForEach is a bit of an odd duck, in my opinion. It looks like functional programming (similar to Linq), but it's actually used to produce side-effects. Combining the two is giving off conflicting signals. A for or foreach loop, on the other hand, is clearly not functional-style, so side-effects would not be surprising.

  • I agree with keeping anonymous method parameter names short, but x isn't very descriptive. line is a little longer but much more descriptive.

Also, I find it more readable to put chained Linq calls on a line of their own:



var unnamed = finalCode
.Where(x => x.Label != null && x.Label.Name == null)
.ToList();



Having that said, I would go for a plain old foreach loop. It may not be as fancy, but it's simple and to the point, which should make it easier to understand:



int count = 0;
foreach (var line in finalCode)

if (line.Label != null && line.Label.Name == null)

line.Label.Name = $"dyn_label++count";







share|improve this answer




























    up vote
    0
    down vote













    I wouldn't make a lot of changes.



    I don't know which ForEach you are using. There are third-party libraries implementing extensions to the standard LINQ extension methods. If you are using one of them, there is no need for .ToList();. The ForEach can directly work on the IEnumerable<T>. Otherwise keep .ToList().



    I would let the query return labels, not lines. This enables you to pass GiveName as a delegate to ForEach without an extra lambda.



    I also tweaked the names a little bit and used the new C# 6.0 expression-bodied methods and inlined the temp unnamed.



    private static void NameUnnamedLabels(IEnumerable<Line> finalCode)

    int labelNo = 0;

    void GiveName(Model.Label label) => label.Name = $"dyn_label++labelNo";

    finalCode
    .Select(ln => ln.Label)
    .Where(lbl => lbl != null && lbl.Name == null)
    .ToList()
    .ForEach(GiveName);



    By projecting (Select) the line on the label before Where, this also slightly simplifies the latter.






    share|improve this answer



















    • 2




      Your first statement is incorrect. .ForEach() is not a supplied extension method on IEnumerable<T>.
      – Jesse C. Slicer
      Mar 23 at 0:55










    • The signature of ForEach is probably public static void ForEach<T>(this IEnumerable<T> source, Action<T> action). So yes, it works on IEnumerable<T>. This does not mean that it is implemented in the base class library.
      – Olivier Jacot-Descombes
      Mar 23 at 0:58






    • 4




      That makes no sense whatsoever. .ForEach() is a method on List<T> and no extension method with that signature exists in the standard .NET LINQ libraries. If you're writing it, supply it, otherwise it's useless to the OP.
      – Jesse C. Slicer
      Mar 23 at 1:00







    • 1




      There is a ForEach operator in MoreLinq. Don't know if the OP is using it. I was not aware of the one in List<T>.
      – Olivier Jacot-Descombes
      Mar 23 at 1:06







    • 2




      Ok, then you should state that as a requirement for your solution to work.
      – Jesse C. Slicer
      Mar 23 at 1:07










    Your Answer




    StackExchange.ifUsing("editor", function ()
    return StackExchange.using("mathjaxEditing", function ()
    StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
    StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
    );
    );
    , "mathjax-editing");

    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "196"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    convertImagesToLinks: false,
    noModals: false,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );








     

    draft saved


    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f190253%2fassigning-names-to-unnamed-labels%23new-answer', 'question_page');

    );

    Post as a guest






























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    4
    down vote



    accepted










    A few notes about your code:



    • Both the inner and outer method are fairly small, and the name of the outer method is already aptly descriptive, so I see no need for a named inner method here. An anonymous method would suffice.


    • List<T>.ForEach is a bit of an odd duck, in my opinion. It looks like functional programming (similar to Linq), but it's actually used to produce side-effects. Combining the two is giving off conflicting signals. A for or foreach loop, on the other hand, is clearly not functional-style, so side-effects would not be surprising.

    • I agree with keeping anonymous method parameter names short, but x isn't very descriptive. line is a little longer but much more descriptive.

    Also, I find it more readable to put chained Linq calls on a line of their own:



    var unnamed = finalCode
    .Where(x => x.Label != null && x.Label.Name == null)
    .ToList();



    Having that said, I would go for a plain old foreach loop. It may not be as fancy, but it's simple and to the point, which should make it easier to understand:



    int count = 0;
    foreach (var line in finalCode)

    if (line.Label != null && line.Label.Name == null)

    line.Label.Name = $"dyn_label++count";







    share|improve this answer

























      up vote
      4
      down vote



      accepted










      A few notes about your code:



      • Both the inner and outer method are fairly small, and the name of the outer method is already aptly descriptive, so I see no need for a named inner method here. An anonymous method would suffice.


      • List<T>.ForEach is a bit of an odd duck, in my opinion. It looks like functional programming (similar to Linq), but it's actually used to produce side-effects. Combining the two is giving off conflicting signals. A for or foreach loop, on the other hand, is clearly not functional-style, so side-effects would not be surprising.

      • I agree with keeping anonymous method parameter names short, but x isn't very descriptive. line is a little longer but much more descriptive.

      Also, I find it more readable to put chained Linq calls on a line of their own:



      var unnamed = finalCode
      .Where(x => x.Label != null && x.Label.Name == null)
      .ToList();



      Having that said, I would go for a plain old foreach loop. It may not be as fancy, but it's simple and to the point, which should make it easier to understand:



      int count = 0;
      foreach (var line in finalCode)

      if (line.Label != null && line.Label.Name == null)

      line.Label.Name = $"dyn_label++count";







      share|improve this answer























        up vote
        4
        down vote



        accepted







        up vote
        4
        down vote



        accepted






        A few notes about your code:



        • Both the inner and outer method are fairly small, and the name of the outer method is already aptly descriptive, so I see no need for a named inner method here. An anonymous method would suffice.


        • List<T>.ForEach is a bit of an odd duck, in my opinion. It looks like functional programming (similar to Linq), but it's actually used to produce side-effects. Combining the two is giving off conflicting signals. A for or foreach loop, on the other hand, is clearly not functional-style, so side-effects would not be surprising.

        • I agree with keeping anonymous method parameter names short, but x isn't very descriptive. line is a little longer but much more descriptive.

        Also, I find it more readable to put chained Linq calls on a line of their own:



        var unnamed = finalCode
        .Where(x => x.Label != null && x.Label.Name == null)
        .ToList();



        Having that said, I would go for a plain old foreach loop. It may not be as fancy, but it's simple and to the point, which should make it easier to understand:



        int count = 0;
        foreach (var line in finalCode)

        if (line.Label != null && line.Label.Name == null)

        line.Label.Name = $"dyn_label++count";







        share|improve this answer













        A few notes about your code:



        • Both the inner and outer method are fairly small, and the name of the outer method is already aptly descriptive, so I see no need for a named inner method here. An anonymous method would suffice.


        • List<T>.ForEach is a bit of an odd duck, in my opinion. It looks like functional programming (similar to Linq), but it's actually used to produce side-effects. Combining the two is giving off conflicting signals. A for or foreach loop, on the other hand, is clearly not functional-style, so side-effects would not be surprising.

        • I agree with keeping anonymous method parameter names short, but x isn't very descriptive. line is a little longer but much more descriptive.

        Also, I find it more readable to put chained Linq calls on a line of their own:



        var unnamed = finalCode
        .Where(x => x.Label != null && x.Label.Name == null)
        .ToList();



        Having that said, I would go for a plain old foreach loop. It may not be as fancy, but it's simple and to the point, which should make it easier to understand:



        int count = 0;
        foreach (var line in finalCode)

        if (line.Label != null && line.Label.Name == null)

        line.Label.Name = $"dyn_label++count";








        share|improve this answer













        share|improve this answer



        share|improve this answer











        answered Mar 23 at 12:56









        Pieter Witvoet

        3,611721




        3,611721






















            up vote
            0
            down vote













            I wouldn't make a lot of changes.



            I don't know which ForEach you are using. There are third-party libraries implementing extensions to the standard LINQ extension methods. If you are using one of them, there is no need for .ToList();. The ForEach can directly work on the IEnumerable<T>. Otherwise keep .ToList().



            I would let the query return labels, not lines. This enables you to pass GiveName as a delegate to ForEach without an extra lambda.



            I also tweaked the names a little bit and used the new C# 6.0 expression-bodied methods and inlined the temp unnamed.



            private static void NameUnnamedLabels(IEnumerable<Line> finalCode)

            int labelNo = 0;

            void GiveName(Model.Label label) => label.Name = $"dyn_label++labelNo";

            finalCode
            .Select(ln => ln.Label)
            .Where(lbl => lbl != null && lbl.Name == null)
            .ToList()
            .ForEach(GiveName);



            By projecting (Select) the line on the label before Where, this also slightly simplifies the latter.






            share|improve this answer



















            • 2




              Your first statement is incorrect. .ForEach() is not a supplied extension method on IEnumerable<T>.
              – Jesse C. Slicer
              Mar 23 at 0:55










            • The signature of ForEach is probably public static void ForEach<T>(this IEnumerable<T> source, Action<T> action). So yes, it works on IEnumerable<T>. This does not mean that it is implemented in the base class library.
              – Olivier Jacot-Descombes
              Mar 23 at 0:58






            • 4




              That makes no sense whatsoever. .ForEach() is a method on List<T> and no extension method with that signature exists in the standard .NET LINQ libraries. If you're writing it, supply it, otherwise it's useless to the OP.
              – Jesse C. Slicer
              Mar 23 at 1:00







            • 1




              There is a ForEach operator in MoreLinq. Don't know if the OP is using it. I was not aware of the one in List<T>.
              – Olivier Jacot-Descombes
              Mar 23 at 1:06







            • 2




              Ok, then you should state that as a requirement for your solution to work.
              – Jesse C. Slicer
              Mar 23 at 1:07














            up vote
            0
            down vote













            I wouldn't make a lot of changes.



            I don't know which ForEach you are using. There are third-party libraries implementing extensions to the standard LINQ extension methods. If you are using one of them, there is no need for .ToList();. The ForEach can directly work on the IEnumerable<T>. Otherwise keep .ToList().



            I would let the query return labels, not lines. This enables you to pass GiveName as a delegate to ForEach without an extra lambda.



            I also tweaked the names a little bit and used the new C# 6.0 expression-bodied methods and inlined the temp unnamed.



            private static void NameUnnamedLabels(IEnumerable<Line> finalCode)

            int labelNo = 0;

            void GiveName(Model.Label label) => label.Name = $"dyn_label++labelNo";

            finalCode
            .Select(ln => ln.Label)
            .Where(lbl => lbl != null && lbl.Name == null)
            .ToList()
            .ForEach(GiveName);



            By projecting (Select) the line on the label before Where, this also slightly simplifies the latter.






            share|improve this answer



















            • 2




              Your first statement is incorrect. .ForEach() is not a supplied extension method on IEnumerable<T>.
              – Jesse C. Slicer
              Mar 23 at 0:55










            • The signature of ForEach is probably public static void ForEach<T>(this IEnumerable<T> source, Action<T> action). So yes, it works on IEnumerable<T>. This does not mean that it is implemented in the base class library.
              – Olivier Jacot-Descombes
              Mar 23 at 0:58






            • 4




              That makes no sense whatsoever. .ForEach() is a method on List<T> and no extension method with that signature exists in the standard .NET LINQ libraries. If you're writing it, supply it, otherwise it's useless to the OP.
              – Jesse C. Slicer
              Mar 23 at 1:00







            • 1




              There is a ForEach operator in MoreLinq. Don't know if the OP is using it. I was not aware of the one in List<T>.
              – Olivier Jacot-Descombes
              Mar 23 at 1:06







            • 2




              Ok, then you should state that as a requirement for your solution to work.
              – Jesse C. Slicer
              Mar 23 at 1:07












            up vote
            0
            down vote










            up vote
            0
            down vote









            I wouldn't make a lot of changes.



            I don't know which ForEach you are using. There are third-party libraries implementing extensions to the standard LINQ extension methods. If you are using one of them, there is no need for .ToList();. The ForEach can directly work on the IEnumerable<T>. Otherwise keep .ToList().



            I would let the query return labels, not lines. This enables you to pass GiveName as a delegate to ForEach without an extra lambda.



            I also tweaked the names a little bit and used the new C# 6.0 expression-bodied methods and inlined the temp unnamed.



            private static void NameUnnamedLabels(IEnumerable<Line> finalCode)

            int labelNo = 0;

            void GiveName(Model.Label label) => label.Name = $"dyn_label++labelNo";

            finalCode
            .Select(ln => ln.Label)
            .Where(lbl => lbl != null && lbl.Name == null)
            .ToList()
            .ForEach(GiveName);



            By projecting (Select) the line on the label before Where, this also slightly simplifies the latter.






            share|improve this answer















            I wouldn't make a lot of changes.



            I don't know which ForEach you are using. There are third-party libraries implementing extensions to the standard LINQ extension methods. If you are using one of them, there is no need for .ToList();. The ForEach can directly work on the IEnumerable<T>. Otherwise keep .ToList().



            I would let the query return labels, not lines. This enables you to pass GiveName as a delegate to ForEach without an extra lambda.



            I also tweaked the names a little bit and used the new C# 6.0 expression-bodied methods and inlined the temp unnamed.



            private static void NameUnnamedLabels(IEnumerable<Line> finalCode)

            int labelNo = 0;

            void GiveName(Model.Label label) => label.Name = $"dyn_label++labelNo";

            finalCode
            .Select(ln => ln.Label)
            .Where(lbl => lbl != null && lbl.Name == null)
            .ToList()
            .ForEach(GiveName);



            By projecting (Select) the line on the label before Where, this also slightly simplifies the latter.







            share|improve this answer















            share|improve this answer



            share|improve this answer








            edited Mar 23 at 1:22


























            answered Mar 23 at 0:53









            Olivier Jacot-Descombes

            2,3611016




            2,3611016







            • 2




              Your first statement is incorrect. .ForEach() is not a supplied extension method on IEnumerable<T>.
              – Jesse C. Slicer
              Mar 23 at 0:55










            • The signature of ForEach is probably public static void ForEach<T>(this IEnumerable<T> source, Action<T> action). So yes, it works on IEnumerable<T>. This does not mean that it is implemented in the base class library.
              – Olivier Jacot-Descombes
              Mar 23 at 0:58






            • 4




              That makes no sense whatsoever. .ForEach() is a method on List<T> and no extension method with that signature exists in the standard .NET LINQ libraries. If you're writing it, supply it, otherwise it's useless to the OP.
              – Jesse C. Slicer
              Mar 23 at 1:00







            • 1




              There is a ForEach operator in MoreLinq. Don't know if the OP is using it. I was not aware of the one in List<T>.
              – Olivier Jacot-Descombes
              Mar 23 at 1:06







            • 2




              Ok, then you should state that as a requirement for your solution to work.
              – Jesse C. Slicer
              Mar 23 at 1:07












            • 2




              Your first statement is incorrect. .ForEach() is not a supplied extension method on IEnumerable<T>.
              – Jesse C. Slicer
              Mar 23 at 0:55










            • The signature of ForEach is probably public static void ForEach<T>(this IEnumerable<T> source, Action<T> action). So yes, it works on IEnumerable<T>. This does not mean that it is implemented in the base class library.
              – Olivier Jacot-Descombes
              Mar 23 at 0:58






            • 4




              That makes no sense whatsoever. .ForEach() is a method on List<T> and no extension method with that signature exists in the standard .NET LINQ libraries. If you're writing it, supply it, otherwise it's useless to the OP.
              – Jesse C. Slicer
              Mar 23 at 1:00







            • 1




              There is a ForEach operator in MoreLinq. Don't know if the OP is using it. I was not aware of the one in List<T>.
              – Olivier Jacot-Descombes
              Mar 23 at 1:06







            • 2




              Ok, then you should state that as a requirement for your solution to work.
              – Jesse C. Slicer
              Mar 23 at 1:07







            2




            2




            Your first statement is incorrect. .ForEach() is not a supplied extension method on IEnumerable<T>.
            – Jesse C. Slicer
            Mar 23 at 0:55




            Your first statement is incorrect. .ForEach() is not a supplied extension method on IEnumerable<T>.
            – Jesse C. Slicer
            Mar 23 at 0:55












            The signature of ForEach is probably public static void ForEach<T>(this IEnumerable<T> source, Action<T> action). So yes, it works on IEnumerable<T>. This does not mean that it is implemented in the base class library.
            – Olivier Jacot-Descombes
            Mar 23 at 0:58




            The signature of ForEach is probably public static void ForEach<T>(this IEnumerable<T> source, Action<T> action). So yes, it works on IEnumerable<T>. This does not mean that it is implemented in the base class library.
            – Olivier Jacot-Descombes
            Mar 23 at 0:58




            4




            4




            That makes no sense whatsoever. .ForEach() is a method on List<T> and no extension method with that signature exists in the standard .NET LINQ libraries. If you're writing it, supply it, otherwise it's useless to the OP.
            – Jesse C. Slicer
            Mar 23 at 1:00





            That makes no sense whatsoever. .ForEach() is a method on List<T> and no extension method with that signature exists in the standard .NET LINQ libraries. If you're writing it, supply it, otherwise it's useless to the OP.
            – Jesse C. Slicer
            Mar 23 at 1:00





            1




            1




            There is a ForEach operator in MoreLinq. Don't know if the OP is using it. I was not aware of the one in List<T>.
            – Olivier Jacot-Descombes
            Mar 23 at 1:06





            There is a ForEach operator in MoreLinq. Don't know if the OP is using it. I was not aware of the one in List<T>.
            – Olivier Jacot-Descombes
            Mar 23 at 1:06





            2




            2




            Ok, then you should state that as a requirement for your solution to work.
            – Jesse C. Slicer
            Mar 23 at 1:07




            Ok, then you should state that as a requirement for your solution to work.
            – Jesse C. Slicer
            Mar 23 at 1:07












             

            draft saved


            draft discarded


























             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f190253%2fassigning-names-to-unnamed-labels%23new-answer', 'question_page');

            );

            Post as a guest













































































            Popular posts from this blog

            Greedy Best First Search implementation in Rust

            Function to Return a JSON Like Objects Using VBA Collections and Arrays

            C++11 CLH Lock Implementation