question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Invocation syntax for functions accepting single argument lambdas

See original GitHub issue

A very common scenario in many projects and libraries is one involving functions which accept a single argument, where the single argument is a zero- or single-argument function or lambda. In these cases, it would be useful to have a syntax which allows the body of the lambda directly in the function call’s braces without needing to wrap the lambda with additional curly braces, improving readability quite a bit.

The syntax would need to be able to disambiguate this usage from other possible usages of the named argument function invocation syntax.

To invent a fictional implementation as an example, one might be similar to the invoke operator but where the opening curly brace of the named argument invocation syntax is immediately followed by a colon, resulting in a new function invocation operator which opens with {: as an indicator that the invocation braces directly contain the body (i.e. not wrapped in additional curly braces) of the single lambda argument being supplied.

{Integer*} ints = { 1, 2, 3 };

// 1.

ints.each((it) => print(it));      // today
ints.each {: print(it) };          // after - lambda statements directly in {: } invoke operator

// 2.

ints.map((it) {                    // today
    print(it);
    return it * 2;
});

ints.map {:                        // after - single param list ommitted
    print(it);
    return it * 2;
};

// 3.

ints.map((it) => it * 2);          // today
ints.map {: => it * 2 };           // after - with fat arrow for explicit return

Basically:

  • For single-argument lambdas, a special keyword (e.g. it) only available inside the lambda could be supported for accessing its single argument, and the need for an explicit parameter list relaxed. (Nested lambdas that would create nested its or shadowed its could be disallowed).
  • When using the new syntax, relax the requirement for a terminating ; at the end of the last statement or expression within the lambda block, as the ambiguity with other possible usages of the name argument syntax would not exist when using the new invoke operator. This will particularly eliminate the noise of the terminating semi-colon ; for lambdas with a single statement or expression.
  • For single expression lambdas that return a value, the fat arrow is used to satisfy explicit return.
  • Finally, for multi-argument lambdas, which is not a primary use-case of this feature, the argument list could be between the opening curly { and the colon :, surrounded by parentheses.

ints.sort((a, b) {          // today
    print("``a`` +");
    print(b);
    return a <=> b;
});

ints.sort {(a, b):          // after
    print(a);
    print(b);
    return a <=> b;
};

Issue Analytics

  • State:open
  • Created 6 years ago
  • Comments:68 (62 by maintainers)

github_iconTop GitHub Comments

3reactions
jvasileffcommented, Sep 6, 2017

I’m going to be the contrarian here, take this as you will:

I think friendly identifier names are unimportant for this feature. The identifiers will normally be used immediately, as they are in the majority of the examples, and with obvious meaning.

And, in fact, “standard” names like it or $0 (I know there are problems with the latter) actually highlight that the identifier is implicit, so you don’t have to read through a bunch of code to figure out which identifiers in an expression (or whatever) are the implicit ones.

So why do we force you to redeclare the name?

The names are not part of the type system, and are often different in method refinements.

Further, names chosen for documentation purposes which make sense for a particular function or method may be very confusing from the perspective of the caller’s code.

2reactions
lucaswerkmeistercommented, Sep 6, 2017

Hm, interesting… not sure about the look either, but I like the idea behind it very much. It gives a use to those parameter names besides documentation, it’s consistent, it lets you provide better names than it (I think I actually prefer element over it 😃 ), and it supports functions with multiple parameters (great).

Read more comments on GitHub >

github_iconTop Results From Across the Web

Invoke - AWS Lambda - AWS Documentation
Invokes a Lambda function. You can invoke a function synchronously (and wait for the response), or asynchronously. To invoke a function asynchronously, ...
Read more >
Python Lambda Functions with EXAMPLES - Guru99
Syntax and Examples · 1. The lambda keyword used to define an anonymous function. · 2. x and y are the parameters that...
Read more >
High-order functions and lambdas | Kotlin
Invoking a function type instance​​ A value of a function type can be invoked by using its invoke(...) operator: f.invoke(x) or just f(x)...
Read more >
Lambda Functions and Anonymous Functions in Python
Above, lambda x: x*x defines an anonymous function and call it once by passing arguments in the parenthesis (lambda x: x*x)(5) . In...
Read more >
How to Use Python Lambda Functions
At first glance, you may accept that a lambda function is a function with some syntactic sugar shortening the code to define or...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found