Thread overview
The trailing closure is beautiful!
Dec 07, 2020
zoujiaqing
Dec 08, 2020
zoujiaqing
Dec 08, 2020
Jacob Carlborg
Dec 08, 2020
Adam D. Ruppe
Dec 08, 2020
Jacob Carlborg
Dec 08, 2020
H. S. Teoh
Dec 08, 2020
Jacob Carlborg
Dec 10, 2020
zoujiaqing
Dec 11, 2020
Jacob Carlborg
Dec 08, 2020
user2345
December 07, 2020
In swift:

```
import SwiftUI

struct ContentView: View {
    var body: some View {
        Text("Hello World")
    }
}
```


In kotlin:

```
@Composable
fun ArtistCard(artist: Artist) {
    Row(verticalGravity = Alignment.CenterVertically) {
        Image(...)
        Column {
            Text(artist.name)
            Text(artist.lastSeenOnline)
        }
    }
}
```
December 08, 2020
On Monday, 7 December 2020 at 19:37:43 UTC, zoujiaqing wrote:
> In swift:
>
> ```
> import SwiftUI
>
> struct ContentView: View {
>     var body: some View {
>         Text("Hello World")
>     }
> }
> ```
>
>
> In kotlin:
>
> ```
> @Composable
> fun ArtistCard(artist: Artist) {
>     Row(verticalGravity = Alignment.CenterVertically) {
>         Image(...)
>         Column {
>             Text(artist.name)
>             Text(artist.lastSeenOnline)
>         }
>     }
> }
> ```

How is this implemented in D?
December 08, 2020
On Monday, 7 December 2020 at 19:37:43 UTC, zoujiaqing wrote:
> In swift:
>
> ```
> import SwiftUI
>
> struct ContentView: View {
>     var body: some View {
>         Text("Hello World")
>     }
> }
> ```

I don't think these are trailing closures.

--
/Jacob Carlborg


December 08, 2020
On Tuesday, 8 December 2020 at 05:06:37 UTC, zoujiaqing wrote:

> How is this implemented in D?

D does not support trailing closures. But I've talked about that several times in the past [1][2][3]. Even did a proof of concept implementation. I'm all in favor of adding trailing closures or trailing delegates to D.

To implement the same in D you would have to pass the delegate within the parentheses:

Column({
    Text(artist.name);
    Text(artist.lastSeenOnline)
});

[1] https://forum.dlang.org/post/nfuurs$1kh7$1@digitalmars.com
[2] https://forum.dlang.org/post/mo6c8d$2o2a$1@digitalmars.com
[3] https://forum.dlang.org/post/mfguhp$2bmn$1@digitalmars.com

--
/Jacob Carlborg
December 08, 2020
On Monday, 7 December 2020 at 19:37:43 UTC, zoujiaqing wrote:
> In swift:
>
> ```
> import SwiftUI
>
> struct ContentView: View {
>     var body: some View {
>         Text("Hello World")
>     }
> }
> ```
>
>
> In kotlin:
>
> ```
> @Composable
> fun ArtistCard(artist: Artist) {
>     Row(verticalGravity = Alignment.CenterVertically) {
>         Image(...)
>         Column {
>             Text(artist.name)
>             Text(artist.lastSeenOnline)
>         }
>     }
> }
> ```

I've read a bit the Swift documentation and it seems that it works well for them because of how APIs are modeled, i.e optional trailing delegate is idomatic in their libraries.

Let's compare to D.
1. lambda are often used as template parameter.
2. non templatized lambda are often lazy, i.e build by the compiler from an expression.

  void get(lazy string) { }

  void main(string[] args)
  {
    get() {return "a";}; // would not work, similarly to "get({"a"})" that does not.
  }

Not sure if that would work well.
December 08, 2020
On Tuesday, 8 December 2020 at 11:14:19 UTC, Jacob Carlborg wrote:
> D does not support trailing closures. But I've talked about that several times in the past [1][2][3]. Even did a proof of concept implementation. I'm all in favor of adding trailing closures or trailing delegates to D.

ideally too it would be slightly magic and handle flow control keywords too. so `return` returns from the whole function not just the delegate. similar to D's existing opApply perhaps.
December 08, 2020
On Tuesday, 8 December 2020 at 13:25:38 UTC, Adam D. Ruppe wrote:

> ideally too it would be slightly magic and handle flow control keywords too. so `return` returns from the whole function not just the delegate. similar to D's existing opApply perhaps.

Yeah, that's how it works in Ruby as well.

--
/Jacob Carlborg
December 08, 2020
> On Tuesday, 8 December 2020 at 13:25:38 UTC, Adam D. Ruppe wrote:
> 
> > ideally too it would be slightly magic and handle flow control keywords too. so `return` returns from the whole function not just the delegate.  similar to D's existing opApply perhaps.
[...]

To implement this, there would need to be a standard protocol for the delegate to signal to the parent function that it should return from the entire call chain. E.g., the function could have been recursively traversing some tree or graph structure, so it's not necessarily just 2 (or some other fixed number of) calls deep.  The delegate would also ideally be able to return a value that gets propagated to the return value of the whole function.

I thought about how this might be implemented in today's language, sans syntactic sugar. Maybe something along these lines:

	void iterate(Args...)(void delegate(Args) cb) {
		...
		cb(args);
		...
	}

	ReturnType myFunc(...) {
		class ReturnChute : Exception {
			ReturnType value;
			this(ReturnType v) { value = v; }
		}

		try {
			iterate(..., (args) {
				//return ReturnType(1);
				throw new ReturnChute(ReturnType(1));
			});
		} catch (ReturnChute rc) {
			return rc.value;
		}
	}

Of course, the actual implementation may not necessarily use exceptions, but this is just to express the desired semantics.  I thought about a non-exception based solution based on a standard library type that encapsulates the intent to return from the delegate plus the boxed return value, but that would require a lot of boilerplate on the part of the `iterate` function -- you'd also be at the mercy of its implementation to actually carry out the intent to return and not simply ignore it or do something different.  The exception based solution seems to be the least error-prone approach.


BTW, I also vote for trailing closures in D.


T

-- 
Prosperity breeds contempt, and poverty breeds consent. -- Suck.com
December 10, 2020
On Tuesday, 8 December 2020 at 11:07:19 UTC, Jacob Carlborg wrote:
> On Monday, 7 December 2020 at 19:37:43 UTC, zoujiaqing wrote:
>> In swift:
>>
>> ```
>> import SwiftUI
>>
>> struct ContentView: View {
>>     var body: some View {
>>         Text("Hello World")
>>     }
>> }
>> ```
>
> I don't think these are trailing closures.
>
> --
> /Jacob Carlborg

Look this:

https://www.hackingwithswift.com/sixty/6/5/trailing-closure-syntax
https://swiftwithmajid.com/2019/11/06/the-power-of-closures-in-swiftui/
https://stackoverflow.com/questions/63956441/swiftui-menu-with-failing-trailing-closure-menustyleconfiguration

December 11, 2020
On 2020-12-10 17:05, zoujiaqing wrote:
> On Tuesday, 8 December 2020 at 11:07:19 UTC, Jacob Carlborg wrote:
>> On Monday, 7 December 2020 at 19:37:43 UTC, zoujiaqing wrote:
>>> In swift:
>>>
>>> ```
>>> import SwiftUI
>>>
>>> struct ContentView: View {
>>>     var body: some View {
>>>         Text("Hello World")
>>>     }
>>> }
>>> ```
>>
>> I don't think these are trailing closures.
>>
>> -- 
>> /Jacob Carlborg
> 
> Look this:

In your example, the first curly brace is for the body of the struct. The second curly brace is for the body of the a read only computed property [1]. Yes, Swift does have trailing closures, but unfortunately your example didn't include any.

[1] https://docs.swift.org/swift-book/LanguageGuide/Properties.html#ID261

-- 
/Jacob Carlborg