开发者

What's the name of this programming feature?

开发者 https://www.devze.com 2023-02-18 07:24 出处:网络
In some dynamic languages I have seen this kind of s开发者_如何学编程yntax: myValue = if (this.IsValidObject)

In some dynamic languages I have seen this kind of s开发者_如何学编程yntax:

myValue = if (this.IsValidObject)
{
    UpdateGraph();
    UpdateCount();
    this.Name;
}
else
{
    Debug.Log (Exceptions.UninitializedObject);
    3;
}

Basically being able to return the last statement in a branch as the return value for a variable, not necessarily only for method returns, but they could be achieved as well.

What's the name of this feature?

Can this also be achieved in staticly typed languages such as C#? I know C# has ternary operator, but I mean using if statements, switch statements as shown above.


It is called "conditional-branches-are-expressions" or "death to the statement/expression divide".

See Conditional If Expressions:

Many languages support if expressions, which are similar to if statements, but return a value as a result. Thus, they are true expressions (which evaluate to a value), not statements (which just perform an action).

That is, if (expr) { ... } is an expression (could possible be an expression or a statement depending upon context) in the language grammar just as ?: is an expression in languages like C, C# or Java.

This form is common in functional programming languages (which eschew side-effects) -- however, it is not "functional programming" per se and exists in other language that accept/allow a "functional like syntax" while still utilizing heavy side-effects and other paradigms (e.g. Ruby).

Some languages like Perl allow this behavior to be simulated. That is, $x = eval { if (true) { "hello world!" } else { "goodbye" } }; print $x will display "hello world!" because the eval expression evaluates to the last value evaluated inside even though the if grammar production itself is not an expression. ($x = if ... is a syntax error in Perl).

Happy coding.


To answer your other question:

Can this also be achieved in staticly typed languages such as C#?

Is it a thing the language supports? No. Can it be achieved? Kind of.

C# --like C++, Java, and all that ilk-- has expressions and statements. Statements, like if-then and switch-case, don't return values and there fore can't be used as expressions. Also, as a slight aside, your example assigns myValue to either a string or an integer, which C# can't do because it is strongly typed. You'd either have to use object myValue and then accept the casting and boxing costs, use var myValue (which is still static typed, just inferred), or some other bizarre cleverness.

Anyway, so if if-then is a statement, how do you do that in C#? You'd have to build a method to accomplish the goal of if-then-else. You could use a static method as an extension to bools, to model the Smalltalk way of doing it:

public static T IfTrue(this bool value, Action doThen, Action doElse ) { if(value) return doThen(); else return doElse(); }

To use this, you'd do something like

var myVal = (6 < 7).IfTrue(() => return "Less than", () => return "Greater than");
  • Disclaimer: I tested none of that, so it may not quite work due to typos, but I think the principle is correct.

The new IfTrue() function checks the boolean it is attached to and executes one of two delegates passed into it. They must have the same return type, and neither accepts arguments (use closures, so it won't matter).

Now, should you do that? No, almost certainly not. Its not the proper C# way of doing things so it's confusing, and its much less efficient than using an if-then. You're trading off something like 1 IL instruction for a complex mess of classes and method calls that .NET will build behind the scenes to support that.


It is a ternary conditional.

In C you can use, for example:

printf("Debug? %s\n", debug?"yes":"no");

Edited:

A compound statement list can be evaluated as a expression in C. The last statement should be a expression and the whole compound statement surrounded by braces.

For example:

#include <stdio.h>

int main(void)
{
    int a=0, b=1;

    a=({
            printf("testing compound statement\n");
            if(b==a)
                printf("equals\n");
            b+1;
        });

    printf("a=%d\n", a);
    return 0;
}

So the name of the characteristic you are doing is assigning to a (local) variable a compound statement. Now I think this helps you a little bit more. For more, please visit this source: http://www.chemie.fu-berlin.de/chemnet/use/info/gcc/gcc_8.html

Take care, Beco.

PS. This example makes more sense in the context of your question:

a=({
        int c;
        if(b==a)
            c=b+1;
        else
            c=a-1;
        c;
    });


In addition to returning the value of the last expression in a branch, it's likely (depending on the language) that myValue is being assigned to an anonymous function -- or in Smalltalk / Ruby, code blocks:

A block of code (an anonymous function) can be expressed as a literal value (which is an object, since all values are objects.)

In this case, since myValue is actually pointing to a function that gets invoked only when myValue is used, the language probably implements them as closures, which are originally a feature of functional languages.

Because closures are first-class functions with free variables, closures exist in C#. However, the implicit return does not occur; in C# they're simply anonymous delegates! Consider:

Func<Object> myValue = delegate() 
{
    if (this.IsValidObject)
    {
        UpdateGraph();
        UpdateCount();
        return this.Name;
    }
    else
    {
        Debug.Log (Exceptions.UninitializedObject);
        return 3;
    }
};

This can also be done in C# using lambda expressions:

Func<Object> myValue = () => 
{
    if (this.IsValidObject) { ... }
    else                    { ... }
};

I realize your question is asking about the implicit return value, but I am trying to illustrate that there is more than just "conditional branches are expressions" going on here.


Can this also be achieved in staticly typed languages?

Sure, the types of the involved expressions can be statically and strictly checked. There seems to be nothing dependent on dynamic typing in the "if-as-expression" approach.

For example, Haskell--a strict statically typed language with a rich system of types:

$ ghci
Prelude> let x = if True then "a" else "b" in x
"a"

(the example expression could be simpler, I just wanted to reflect the assignment from your question, but the expression to demonstrate the feature could be simlpler:

Prelude> if True then "a" else "b"
"a"

.)

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号