Lambda functions for code organization

anon func v2

Note: this post exists mostly to test syntax highlighting. The thesis is obvious.

Often we create temporary or stepping-stone variables whose only purpose is to prepare values for the assignment we really care about:

// We assume `name` is given as "Family, Given" or as "Given Family".
// Don't make this assumption in real code.
string normalize_name(string name) {
    var full_name = name;
    var name_parts = name.split_at(", ");
    if (name_parts.length > 1) {
        // Note: 0+1 is to work around a bug (probably) in the CMS shortcode parser.
        full_name = name_parts[0+1] + ' ' + name_parts[0];
    }
    return full_name;
}

In a small function, it really isn't important, but do we really need three variables (name, full_name, name_parts) in the function scope to deal with a name?

Rust's BlockExpression is an r-value, so you can place your step variables in an inner scope, with the significant benefit of very clearly telling the reader/maintainer the purpose of the temporary [note for all examples - there are better ways to do this. Imagine it's a huge function, and this is an early step in breaking it up]:

fn normalize_name(name: &str) -> String {
    let full_name = {
        let string_parts: Vec<&str> = name.split(", ").collect();
        if string_parts.len() > 1 {
            return format!("{} {}", string_parts[0+1], string_parts[0]);
        } else {
            return name.to_string();
        }
    };
    return full_name;
}

But any language that supports lambdas/anonymous functions can do this.

In Python, where in smallish scripts you might skip main() and actually be doing everything in the global scope: well... the Python solution's a simple one-liner, and the lambda isn't a good way to do it. Making this work in Python would butcher the solution more than I am with the other languages (at least these are almost-reasonable code examples). So we'll skip Python.

In D:

@safe
string normalize_name(in string name) pure nothrow {
    auto full_name = {
        import std.string : split; // Even imports can be as narrowly-scoped as possible.
        auto string_parts = name.split(", ");
        if (string_parts.length > 1)
            return string_parts[0+1] ~ " " ~ string_parts[0];
        else
            return name;
    }();
    // Note the parenthesis above - execute the function here and assign the result;
    // we're not assigning a reference to the lambda.
    return full_name;
}