Nemerle, anyone?



  • @tar said:

    For a language which is essentially C# on steroids,

    Huh?

    Adding macros doesn't make C# better, it makes it worse. Although maybe you mean Nemerle is like C# but with shriveled genitals, in which case I get it.



  • Macros are one of those contentious topics that people either love or hate. Example:

    • Argument in favour of macros: "I can make my own if statement and have it look and work exactly like the builtin keyword!"
    • Argument against macros: "I can make my own if statement and have it look and work exactly like the builtin keyword?"


  • Adding programming language "power" (as geeky nerdy types usually describe it) without standardized syntax is a disaster in the waiting. Look at C++ for like 57,231 examples of that.



  • What's your opinion of building your own custom C# attributes?



  • I don't have an opinion on that subject.



  • Fair enough. I was going to try to make some 'it's all metaprogramming' parallel between the two...

    (In semi-related news, I recently discovered the Text Template Transformation Toolkit which is apparently Visual Studio's most top secret hidden feature. I've been meaning to have a play with it as well at some point...)


  • ♿ (Parody)

    @blakeyrat said:

    Adding macros doesn't make C# better, it makes it worse.

    Many people say the same thing about the human body on steroids.


  • Discourse touched me in a no-no place

    @boomzilla said:

    Many people say the same thing about the human body on steroids.

    It depends on what you're using them for. Reducing inflammation? Reasonable use. Giving yourself increased muscle mass? Don't do that.



  • Thinking about macros in general, I think they get a lot of bad rep because the most widespread example of macros that programmers run into is the C-preprocessor (and specifically the C89 preprocessor before C99 added variadic macros and opened it up to creative abuse), and possibly the demented mess that is m4, as "popularized" by Autotools and precisely nobody else ever, period.

    So the average joe programmer comes away with the opinion that macros are hard to use and to reason about, and are limited in what they can do anyway, so there's no obvious benefit, and a lot of cost, so why even bother, right? And macro systems which aren't shit do exist (i.e the various flavours of Lisp or Scheme macros), but to make use of them you need to learn some arcane punctuation-heavy language. Again, cost.

    But there do exists programming problems which are really easy to solve using macros and hard to solve using other methods. As a general rule, when we're writing code, we want to avoid repetition—if we find ourselves writing out the same boilerplate code over and over, then it's a sign that there's a function we need to write which encapsulates the repetitive code.

    But sometimes you can't fix your repetition with a function. Say for example in C++ you have a class which overloads all of the arithmetic operators +, -. *, / and each overload ends up looking almost identical except for the operator itself:

        Bob &operator +(const Bob &l, const Bob &r) { return l.add(r); }
        Bob &operator -(const Bob &l, const Bob &r) { return l.sub(r); }
        Bob &operator *(const Bob &l, const Bob &r) { return l.mul(r); }
        Bob &operator /(const Bob &l, const Bob &r) { return l.div(r); }
    

    And let's also pretend that we've got 10 Bob classes and 3 or 4 variations on each operator. There's no function you can write to 'fix' that. Your options are:

    1. Just suck it up, and write out all the code
    2. Write a macro to abstract the pattern
    MAKE_OPERATOR(Bob, +, add); MAKE_OPERATOR(Bob, -, sub); MAKE_OPERATOR(Bob, *, mul); MAKE_OPERATOR(Bob, /, div);
    If you have senior developers implementing these things and explaining how to use them to the rest of the team (ideally written docs), and the team prefers using macros over not using macros, then I say   go for it.
    
    The other point I wanted to make was, sure, in the hands of an inexperienced or incompetent programmer, macros can be  weaponized to produce code which is as incomprehensible as it is front-page-worthy. But if you take macros away from the idiots, they can be just as inventive using other programming features. If your team values clean and efficient code, your best bet is to enforce code reviews for every checkin, and to make sure that the junior team members have access to more senior developers, and can get mentored. If you want a codebase that looks uniform and adheres to a coding standard, you really want to make sure everyone on the team is willing to follow the standard, and to hold other developers to it in reviews.
    
    But taking macros away from the whole team just because there's this one guy who regularly drops timebombs into the codebase. That's a technical solution to a political problem. Train that guy, or let him go...


  • @tar said:

    If you have senior developers implementing these things and explaining how to use them to the rest of the team (ideally written docs), and the team prefers using macros over not using macros, then I say go for it.

    Yeah, then turn around and ask your talking pangolin sidekick to call up your good buddy God and have him rain down more free Ferraris filled with supermodels.



  • @blakeyrat said:

    Yeah, then turn around and ask your talking pangolin sidekick to call up your good buddy God and have him rain down more free Ferraris filled with supermodels.

    The sad thing is I was actually on one of those teams for a while back there. It didn't last though, the product was discarded for political reasons as much as technical ones and the team was scattered to the winds...

    One of these days, me and that pangolin, though, we'll get the band back together...


  • Discourse touched me in a no-no place

    @tar said:

    As a general rule, when we're writing code, we want to avoid repetition

    The most important reason to avoid repetition is that it breeds errors. Writing something correctly once is easier than writing something simpler a hundred times, even with copy-n-paste.


  • 🚽 Regular

    Not to mention "fix a bug once" vs "find all the places where the bug was repeated and fix it there too".



  • @Zecc said:

    Not to mention "fix a bug once" vs "find all the places where the bug was repeated and fix it there too".

    vs "find all the places where slightly different variations of the bug have evolved over time as various different partial fixes did or didn't hit each particular area..."



  • @CHUDbert said:

    That's what we need! A C# like language with perl features!

    No need any longer - C# will now have string interpolation built in:

    // C# 6
    Log.Information($$"Logged in {loggedInUserId}");
    

    (Reference)

    You are free to 180° your opinion on string interpolation now.



  • Uh, it's basically String.Format with somewhat more concise syntax? It seems nice, but not my-panties-are-now-around-my-ankles nice.



  • There's another feature Nemerle has which could be considered 'killer', perhaps more-so even than macros. It has tail-recursion optimization.

    As far as I can tell, C# Lambdas can detect whether or not they're capable of tail-recursion optimization, but I've never played with that.



  • I was actually reasonably surprised that tail-recursion wasn't made available from 'vanilla C#' the instant that it was implemented in the .NET platform...



  • If I remember correctly, they said it was a design decision in C#'s case. Now, if it could be done on expression-bodied members, that would really be something.



  • @Magus said:

    design decision

    I guess it can make callstacks harder to read, but I mean, they could stick it behind an optimization flag. TBH, if I'm going to do any .NET/mono stuff in my own time, I'm definitely doing it in Nemerle, so I suppose C# can do whatever it likes... :)


  • Discourse touched me in a no-no place

    @tar said:

    I guess it can make callstacks harder to read

    It can, and it does. Stack traces are tricky enough to interpret without having a whole bunch of stuff “randomly” (not really random; depends on what the programmer was doing) missing from them. It gets even more tricky once you start doing tail recursing to a different function/method. Sometimes it's a useful technique though. Just best used with care.



  • You might also look into what they're doing with .NET Core, since that cross-platform effort is very interesting too. I haven't looked too deeply, but they apparently intend to support tiny 'only what you need' versions of .NET that work on any platform, if I understand correctly.


  • ♿ (Parody)

    @tar said:

    I was actually reasonably surprised that tail-recursion wasn't made available from 'vanilla C#' the instant that it was implemented in the .NET platform...

    Holy shit...you mean it doesn't have it already? I remember playing with that stuff in ILASM, like, a decade ago. Or something. Baffling.


Log in to reply