Express lambdas simply as "incomplete expressions" with _ (or $1) and no argument list declaration
- Dominant language
- No language data
- Stars
- 328
- Forks
- 71
- PR merge metrics
- No merged PRs in 30d
Description
Express lambdas as "incomplete expressions," using a "placeholder character" (here, `_` as in Scala).
- Greatly improves readability, reducing the noise of `Function(parameter)`
- Reduces the need for for LINQ query comprehensions
- Well-received in Scala/Swift
- A perfect match for VB -- as it was decided that C# arrow syntax did not fit well into BASIC, whereas this one fits in very well
```vb
'Old way (goes off the page...):
Dim activeCustomers = customers.Where(Function(c) c.LastActive > lastMonth).OrderBy(Function(c) c.LastName)
Dim lastNameList = activeCustomers.Select(Function(c) $"{c.LastName}, {c.FirstName}")
'New way:
Dim activeCustomers = customers.Where(_.LastActive > lastMonth).OrderBy(_.LastName)
Dim lastNameList = activeCustomers.Select($"{_.LastName}, {_.FirstName}")
'Here's how it works:
'An expression that contains a reference to '_' is wrapped into a function.
```
### Technical details
- If you pass an expression where a function is expected, AND the `_` pseudo-identifier is used somewhere in the expression, convert it into something like `Function(arg1) exprGoesHere` with the `_`s converted to `arg1`.
```vb
Dim isActiveLately As Func(Of Customer, DateTime) = _.LastActive > Now.AddMonths(-1)
Dim isActiveLately As Func(Of Customer, DateTime) = Function(c) c.LastActive > Now.AddMonths(-1)
```
- Argument and return types can easily be inferred, just as we do for the regular `Function(args)` syntax. As a matter of fact, we can do even better this way; see below.
- Nesting two "incomplete expressions" should probably not be allowed. There wouldn't a clear argument for `_` to reference.
### Use in 'partial application'
This also shines for highly expressive and concise partial application:
```vb
'Old way:
Dim GetFirstChar = Function(str As String) Strings.Left(str, 1)
'New way:
Dim GetFirstChar = Strings.Left(_, 1)
'Notice how it also makes better type inference possible.
```
### Multi-argument functions
Swift actually goes further and lets you use `$1`, `$2`, and so on, for lambdas where a multi-argument function is expected -- for instance, comparer/aggregator functions:
```vb
'Old way:
Dim totalOrders = activeCustomers.Aggregate(0, Function(r, c) r + c.Orders.Count)
'New way:
Dim totalOrders = activeCustomers.Aggregate(0, $1 + $2.Orders.Count)
```
VB could implement either `_` or `$1` or both -- input would be appreciated.
### Use in pattern matching
If we ever get pattern matching done _(note: we should!)_ 😃, and we allow providing a function as a pattern, then again `_` makes this very concise and expressive -- it would be a game-changer for Select Case:
```vb
Select Case lastIssueId
Case 0: 'no issues -- throw an exception
Case 1: 'first issue in the repo -- award the "First Issue" badge
Case _ Mod 256 = 0: 'issue has won the jackpot and should be implemented immediately! :-)
'WITHOUT OUR NEW FEATURE the above line would have to be:
Case Function(i) i Mod 256 = 0
'...so it really saves the day here.
End Select
```
### Another example: conditionally selected lambdas
Sometimes you want to use one or more lambdas based on a condition. `_` really shines here:
**NOTE:** There are caveats in this specific usage related to type inference and precedence. But I wanted to convey the idea.
```vb
Dim sortByTitle = (Request.Params("sort") = "title")
'Old way:
Dim sortFunc = If(sortByTitle, Function(i As Issue) i.Title, Function(i As Issue) i.PostDate)
Dim sortedIssues = allIssues.OrderBy(sortFunc)
'New way -- much simpler:
Dim sortedIssues = allIssues.OrderBy(If(sortByTitle, _.Title, _.PostDate))
```
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.