C#: WTF are they doing with that language?



  • <disclaimer>this is not going to be true infuriated rant/wtf, but bear with me for a whie, if you will</disclaimer>

    I recently came across this, and as I started reading, and went on, and stopped at the lambda expression

    MyDeleg<int,bool> IsPositive = num => num > 0;


    like "WTF are they doing with that language?", scared, excited, fascinated, eager to try it... (and a little hurt because i don't really get it yet...)

    anyways, I wanted to ask you if anyone of you maybe had similar thoughts?
    (oh yeah, and is it (/are those) already a long time known and used feature(s) and I'm just discovering America a little too late*, or is it news for some of you too?)

    *maybe wrong reference, not sure right now



  • TRWTF is people not getting the glimpse of functional programming some imperative languages have recently adopted.

    I'm not a .NET guy, but I hold C# in respect for not being limiting to a (rather suboptimal implementation of a) single paradigm like, say, Java. Multiparadigm rules.



  • In my functional programming course at university they told me that even though languages like Haskell will probably never be very popular, the concepts of those languages have started to appear in traditional languages as well, and that's why we have to learn Haskell: to understand functional programming. And be able to write better python code.

    After I implemented insertion sort in Haskell, I decided that I'm just going to ignore these new functional features in i.e. C# and stick to good old for/while/whatever, even "goto" seems a lot more sane to me. :-)



  • ...@metax said:

    TRWTF is people not getting the glimpse of functional programming some imperative languages have recently adopted.

    so this is the real meaning of the term "functional programming"? i have been taught otherwise when i was young padawan. could all the teachers have lied to me??



  • That's called a lambda expression. It's helpful with anonymous methods (which were introduced in C# 2.0). Anonymous methods are cool, and give us the power of functional programming, but alas the syntax is very verbose. So along comes lambda expressions, which gives a far more concise 'functional programming' type syntax. So this statement 

    CodeMyDeleg<int,bool> IsPositive = num => num > 0;

    Is far less verbose (and easier to read) than the alternative

    CodeMyDeleg< int,bool > IsPositive = delegate(int num) {
                                       return num > 0;};


  • And LPC (Well, the MudOS dialect, at least) had both full-blown anonymous funcs

    function f = function(mixed x) { return arrayp(x) && sizeof(x) > 3; };
    some_call(f, var_here);

    and happycode lambdas

    some_call( (: arrayp($1) && sizeof($1) > 3 :) , var_here );

    for about... hmm, something between twelve and fifteen years now...



    Too bad most coders out there never heard of it.



  • @SEMI-HYBRID code said:

    ...so this is the real meaning of the term "functional programming"? i have been taught otherwise when i was young padawan. could all the teachers have lied to me??
     

    Come again? Lambdas (anonymous functions) are one feature of functional programming languages. Of course there's much much more (although C# has at least two other cool things influenced by functional languages, type inference - by the way, thanks for not confusing var with dynamic typing, it's surprising how often this happens - and LINQ), that's why I speak of a "glimpse of functional programming".

    What did they tell you functional programming means?



  • @metax said:

    type inference - by the way, thanks for not confusing var with dynamic typing

    yup, found out that one too, pretty nice.

    @metax said:

    and LINQ

    yup, that's why I was reading the page in the first place

    @metax said:

    What did they tell you functional programming means?

    i was told that it's the opposite of object oriented programming. where OOP encapsulates data in objects that operate on it, procedural programming uses mainly static data that is operated on by funcions. Okay, probably not really a lie, but a drastic (and stupid) underestimation/simplification.



  • @SEMI-HYBRID code said:

    @metax said:
    What did they tell you functional programming means?

    i was told that it's the opposite of object oriented programming. where OOP encapsulates data in objects that operate on it, procedural programming uses mainly static data that is operated on by funcions. Okay, probably not really a lie, but a drastic (and stupid) underestimation/simplification.

    Procedural <> functional.



  • @SEMI-HYBRID code said:

    <disclaimer>this is not going to be true infuriated rant/wtf, but bear with me for a whie, if you will</disclaimer>

    I recently came across this, and as I started reading, and went on, and stopped at the lambda expression

    MyDeleg IsPositive = num => num > 0;


    like "WTF are they doing with that language?", scared, excited, fascinated, eager to try it... (and a little hurt because i don't really get it yet...)

    anyways, I wanted to ask you if anyone of you maybe had similar thoughts?
    (oh yeah, and is it (/are those) already a long time known and used feature(s) and I'm just discovering America a little too late*, or is it news for some of you too?)

    *maybe wrong reference, not sure right now

    I've never used, say, Haskell or F#, but I've done my share of functional programming in JavaScript. (Take a look at the jQuery source sometime.)

    I'm not going to say I'd use it personally, but I understand that it's valuable in a lot of cases. The textbook one being Map/Reduce. If Microsoft added an easy module to let you farm out work on your LAN, kind of like Apple's XCode-integrated distcc, but for all operations, they could have a real winner on their hands. Right now, Amazon has the easiest plug-and-play implementation of Map/Reduce, and it's a) not all that easy, and b) certainly not doing MS any favors by running on Linux.



  • @Spectre said:

    @SEMI-HYBRID code said:
    @metax said:
    What did they tell you functional programming means?

    i was told that it's the opposite of object oriented programming. where OOP encapsulates data in objects that operate on it, procedural programming uses mainly static data that is operated on by funcions. Okay, probably not really a lie, but a drastic (and stupid) underestimation/simplification.

    Procedural <> functional.

    The possibly-stupid way it was explained to me is that in "normal" (procedural, OO) programming, you pass the variables to functions. In a functional program, you pass the functions to variables.

    But the word "functional" is overloaded. I've also heard it to refer to languages that use functions. But, eh, definitions change over time.



  • Functional programming is more than just having first-class functions. You can do stuff like that in JavaScript and still be ridiculously procedural. When I think of functional programming, I think "functions like they taught in math class" (and it was sadly a very short math class that taught about them, but.) They have some nice properties. F(x) is F(x) is F(x) and it doesn't change 'x' and it doesn't have some internal state which can change things or be left in some inconsistent manner. It's safe to call them. And you write about what F(x) is instead of merely what steps you take to get to get it.

    The style is a good thing to keep in mind if you're doing other programming. For instance, my company once had a method, something like $object->config_mismatches(%desired_config_here). It computed the list of config mismatches between the "desired" config and the "actual" config.... and then it went and set a flag on the object saying "My config is mismatched!" and wrote to the log if that was the case. As it turns out, if you have archived configurations and you want to compare them to the actual configuration after the fact, that may not always be appropriate.

    In a procedurally-oriented world, what I've seen that works well involves dividing the work between methods that compute something to return a useful value, and methods that update the database / write to logs / etc. You need some decent tools, though. A few easy-to-use list / mapping manipulators work wonders (e.g. Perl's map, grep, and my company's homegrown hashtable equivalents, hashmap / hashgrep).

    my %if_speed_bytes = hashmap { $a => $b / 8 } %if_speed_bits;
    is much less clunky than if you had to write out something like
    if_speed_bytes = HashUtils.hashmap(function(a,b){ return [a, b/2] }, if_speed_bits);
    (or worse, make some private inner class which implements the HashMapping interface, then instantiate an object of that class to pass to the function...)


  • In my option, the real WTF is softcoding a check for a positive number. It's like saying int four = 4;, pretty much useless* and harder to identify then the constant itself.

    Plus they seem to be using a custom delegate type instead of an Func<int, int>, but I'd let that slide if it's needed for a class somewhere.

    (I know it's supposed to be a trivial example, but I don't think I've ever really had to declare a lambda that way.)

    * In C#. Last time I tried to explain this, the primary response seemed to be something about interoperating assembly code and C.



  • I haven't touched .Net since like version 1.1 and even I knew about its lambda expressions. Talk about different exposure.


    Anyway, TRWTF is this:

    // Based on http://lua-users.org/wiki/FunctionalTuples 
    // JavaScript looks better than Lua
    

    function X(x, y, z){ return x };
    function Y(x, y, z){ return y };
    function Z(x, y, z){ return z };

    function Vector(x, y, z){
    var v = function(fn){ return fn.call(this, x, y, z); };
    v.toString = function(){
    return '{' + this(X) + '; ' + this(Y) + '; ' + this(Z) + '}';
    }
    return v;
    }

    function equals(v){
    return function(x, y, z){
    return x == v(X) && y == v(Y) && z == v(Z);
    }
    }

    function add(v){
    return function(x, y, z){
    return Vector( x+v(X), y+v(Y), z+v(Z) );
    }
    }

    function subtract(v){
    return function(x, y, z){
    return Vector( x-v(X), y-v(Y), z-v(Z) );
    }
    }

    function cross(v){
    return function(x, y, z){
    return Vector( yv(Z)-zv(Y), zv(X)-xv(Z) , xv(Y)-yv(X) );
    }
    }

    //
    // Usage examples//
    v1 = Vector(1, 2, 3);
    v2 = Vector(4, 5, 6);
    v3 = Vector(7, 8, 9)

    v1( add( v2 ) ); // {5; 7; 9}

    v3( subtract( v1 ) ); // {6; 6; 6}

    Vector(1, 0, 0)( cross( Vector(1, 0, 0) )) // {0; 0; 0}
    Vector(1, 0, 0)( cross( Vector(0, 1, 0) )) // {0; 0; 1}

     

    I wrote this, but it's not my original idea.

    But see, it's functional*: there are absolutely no side-effects and, as per typical functional code, there are functions that return functions.

     

    Btw, all Haskell functions take at most a single parameter. Doesn't that blow your mind?

     

    <font size="1">*it works, haha</font>



  • @Spectre said:

    Procedural <> functional.

    this would be the missing piece.



  • @Zecc said:

    Anyway, TRWTF is this:

    Where's the WTF?



  • @Shortjob said:

    Where's the WTF?
    That I wasted time writing such a contrived implementation of Vector?

    But actually, it was a good learning experience.



  • @fennec said:

    A few easy-to-use list / mapping manipulators work wonders (e.g. Perl's map, grep, and my company's homegrown hashtable equivalents, hashmap / hashgrep).

    Just FYI, ECMAScript 5 has Map.



  • The only WTF I see here is that:

    [code]MyDeleg IsPositive = num => num > 0;[/code]
    Is also valid C syntax, which always returns false or 0.



  • @Daid said:

    The only WTF I see here is that:
    <font size="2" face="Lucida Console">MyDeleg IsPositive = num => num > 0;</font> Is also valid C syntax, which always returns false or 0.

    => is not a C operator, >= is. It wouldn't compile.



  • @Daid said:

    The only WTF I see here is that:
    <FONT size=2 face="Lucida Console">MyDeleg IsPositive = num => num > 0;</FONT> Is also valid C syntax, which always returns false or 0.
    I must be missing the part where this is different from the OP, why this wouldn't compile, or what (in general) is wrong with it.



  • @Sutherlands said:

    @Daid said:

    The only WTF I see here is that:
    <font size="2" face="Lucida Console">MyDeleg IsPositive = num => num > 0;</font> Is also valid C syntax, which always returns false or 0.
    I must be missing the part where this is different from the OP, why this wouldn't compile, or what (in general) is wrong with it.

     

    It's not different from the OP. Daid is stating that the OP's C# code is also valid syntax in C. That statement appears to be incorrect, since => is not a valid operator in C.



  •  Oh great, another shortcut that's longer than what it replaces. "IsPositive(x)" takes more characters than "x > 0".



  • 1) The lambda makes perfect sense. Consider a method where you pass an expression that evaulated each element and returns each that matches. In this case they want any positive value. Perhaps in another case they want any number which was a winning lottery pick in the past 30 days...

     2) Using an explicit type instead of Func *MAY* make sense. It depends on the type of checking you want to be able to enforce. For example if you have different categories of lambdas which have the same signature, it is impossible to do compile or run time to make sure that "lambdas from group a" are only used when the underlying type of Func<T,bool>



  • @Bumble Bee Tuna said:

     Oh great, another shortcut that's longer than what it replaces. "IsPositive(x)" takes more characters than "x > 0".

    Good luck trying to pass "x > 0" to a method or constructor...



  • @toth said:

    [quote user="Bumble Bee Tuna"]

     Oh great, another shortcut that's longer than what it replaces. "IsPositive(x)" takes more characters than "x > 0".

    Good luck trying to pass "x > 0" to a method or constructor...[/quote]

    int[] intsGreaterThenZero = listOfInts.Where(x => x > 0).ToArray();

    Was that so hard?



  • @MiffTheFox said:

    @toth said:
    @Bumble Bee Tuna said:

     Oh great, another shortcut that's longer than what it replaces. "IsPositive(x)" takes more characters than "x > 0".

    Good luck trying to pass "x > 0" to a method or constructor...
    int[] intsGreaterThenZero = listOfInts.Where(x => x > 0).ToArray();

    Was that so hard?

    You are missing the point, the point is somebody is bitching about lambda expresion, and somebody else is telling him//her good luck passing an expresion like x>0 to a method without a lambda expresion. You using the lambda operator to disprove that point doesn't help.

     



  • @serguey123 said:

    [quote user="MiffTheFox"][quote user="toth"][quote user="Bumble Bee Tuna"]

     Oh great, another shortcut that's longer than what it replaces. "IsPositive(x)" takes more characters than "x > 0".

    Good luck trying to pass "x > 0" to a method or constructor...[/quote]
    int[ intsGreaterThenZero = listOfInts.Where(x => x > 0).ToArray();

    Was that so hard?[/quote]

    You are missing the point, the point is somebody is bitching about lambda expresion, and somebody else is telling him//her good luck passing an expresion like x>0 to a method without a lambda expresion. You using the lambda operator to disprove that point doesn't help.

     

    [/quote]

    Whoops! I thought this was about assigning a lambda to a variable instead of just putting it in a function call. My bad!



  • Part of the point is that the C# compiler is at least smart enough to know that if you're using => that you're probably using the "Equal to or greater than" operator. Lamdas also have strange invocations, making them look just like functions on occasion (except, they're variables!)

    static public Func <double[], double[], double[]> arrAdd = (a, b) => { if (a.Length != b.Length) { throw new ArgumentException("Arrays must be same length"); } for (int i = 0; i < a.Length; i++) { (a[i]) += (float)b[i]; } return a; };


  • Discourse touched me in a no-no place

    @Indrora said:

    Part of the point is that the C# compiler is at least smart enough to know that if you're using => that you're probably using the "Equal to or greater than" operator.
    I would not call a language that has DWIM as part of its implementation particularly smart. c.f. the apocryphal tale of Warren Teitelman and delete *$



  • @Indrora said:

    Part of the point is that the C# compiler is at least smart enough to know that if you're using => that you're probably using the "Equal to or greater than" operator.

    >= greater than or equal

    => lambda operator

    @Indrora said:

     Lamdas also have strange invocations, making them look just like functions on occasion (except, they're variables!)

    Also from the documentation

    A lambda expression is an anonymous function that can contain expressions and statements, and can be used to create delegates or expression tree types.

    Get your facts straight or stick to furry porn (with added pun for added efect)


Log in to reply