Skip to content

Instantly share code, notes, and snippets.

@DeedleFake
Last active February 20, 2019 04:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DeedleFake/5e8e9e39203dff4839793981f79123aa to your computer and use it in GitHub Desktop.
Save DeedleFake/5e8e9e39203dff4839793981f79123aa to your computer and use it in GitHub Desktop.
Possible Solution to check Awkwardness with Chained Method Calls

Syntax Problem

One of the issues with the syntax of check, as proposed, is that chaining method calls with error returns will look really, really bad. For example, check (check (check v.m1()).m2()).m3(). The common way around this in many languages, as mentioned in the draft, is the use of ? as a postfix operator instead of prefix keyword, but this has other problems, including resulting in similar illegibility if there are nested function calls, such as in f1(f2(f3()?)?)?. It also would make it unique amongst the various Go control flow modifiying language structures as all of the other ones are keywords.

Proposed Solution

When check is given a compound function expression, such as nested function calls or chained methods, it applies to all calls in the expression, not just the one it was specifically attached to. The previous two examples then become check v.m1().m2().m3() and check f1(f2(f3())), respectively. All other aspects of check remain the same, meaning that you could still use something like v, err := f1(check f2()) and whatnot.

Possible Issues

One potential awkwardness with this solution is the case of multiple returns being intended for use directly, such as in

func f1(int, error)
func f2() (int, error)
check f1(f2())

It may be possible, however, for the application of check to be conditional on the usage of the types of each call, so it simply wouldn't affect the inner call to f2() in this case, the same as it not affecting a call to a function with no error return value. It would also be possible to get around this by manually calling f2() on a previous line, assigning the returns to values, and then passing those to f1(). If it's not possible, it could simply be a compile-time error if such an ambiguity arises.

@networkimprov
Copy link

networkimprov commented Sep 22, 2018

Looks great in gist :-)

In the requirements list below, see C.1) Identify syntax to select a named handler.
There's an option which avoids the keyword/operator prefix & postfix issues you describe.
https://gist.github.com/networkimprov/961c9caa2631ad3b95413f7d44a2c98a

@go101
Copy link

go101 commented Feb 19, 2019

What's the problem of f1(f2(f3()?)?)?? I feel it and v.m1()?.m2()?.m3()? are both ok.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment