Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A C#-style syntax for function signatures #13220

Closed
Richiban opened this issue Aug 17, 2016 · 1 comment
Closed

A C#-style syntax for function signatures #13220

Richiban opened this issue Aug 17, 2016 · 1 comment
Labels
Area-Language Design Language-C# Resolution-Duplicate The described behavior is tracked in another issue

Comments

@Richiban
Copy link

After reading the Ceylon language tour http://ceylon-lang.org/documentation/1.2/tour/functions/ I realised that they have a very nice way of representing function signatures (i.e. the type of a lambda function) using a type-first, C-style syntax.

Currently, we have to use the Func<> and Action<> types if we wish to write a higher order function, such as in this fictional MyList class:

public class MyList<TElement>
{
    public List<TReturn> Select<TReturn>(Func<TElement, TReturn> selector)
    {
        // ...
    }

    public void ForEach(Action<TElement> action)
    {
        // ...
    }
}

but using this new syntax we can write Func<TArg, TReturn> function as TReturn function(TArg), which is easier to understand as it looks a lot like a method signature on a class. Also, we can represent actions using void function(TArg). If we apply this to the example above we get:

public class MyList<TElement>
{
    public List<T> Select<T>(T selector(TElement))
    {
        // ...
    }

    public void ForEach(void action(T))
    {
        // ...
    }
}

In addition to the advantages already mentioned this would allow us to name the arguments in our functions. Sometimes the type alone isn't helpful, such as the Select overload that takes a Func<int, TElement, TResult>. If we are dealing with an IEnumerable<int> then the signature is Func<int, int, TResult> and we can easily get confused as to which lambda argument is the index and which is the element from the list.

If we can declare pseudonames for the lambda arguments (using the same magic as the new named Tuples?) then, lifting from Ceylon again, we would be able to write:

public List<TResult> Select<TResult>(TResult selector(int index, TElement element))
{
    // ...
}

And the calling code would be able to distinguish between the lambda arguments because instead of seeing the signature as Func<int, int, TResult> they would see TResult selector(int index, int element).

You could also used named & positional parameters when calling one of these lambdas. Currently, when calling a lambda with the signature Action<int, int>, you see the signature .Invoke<int, int>(int arg1, int arg2), for example. Under the new system I would be able to write:

public void Do(void printLocation(int x, int y))
{
    printLocation(x : 4, y : 5);
}
@svick
Copy link
Contributor

svick commented Aug 17, 2016

This looks like a duplicate of #10303.

@gafter gafter added Resolution-Duplicate The described behavior is tracked in another issue Language-C# Area-Language Design labels Aug 17, 2016
@gafter gafter closed this as completed Aug 17, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Language Design Language-C# Resolution-Duplicate The described behavior is tracked in another issue
Projects
None yet
Development

No branches or pull requests

3 participants