A constraint system / type variable question

Hello,

I’m trying to replace the explicit FunctionType returned by visitClosureExpr() in CSGen.cpp with a type variable; and ultimately a disjunction of two FunctionTypes with different ExtInfo flags set (one favored, one not).

After reviewing the code and making a few attempts, I haven’t been able to find a solution that works 100% of the time. Is there a good boilerplate example I should be looking at for how to make this work? How should I handle single expression closures?

Thanks,
Dave

Hello,

I’m trying to replace the explicit FunctionType returned by visitClosureExpr() in CSGen.cpp with a type variable; and ultimately a disjunction of two FunctionTypes with different ExtInfo flags set (one favored, one not).

I really don’t recommend doing this. Even the current late-binding of a proper function type in closure inference is an artifact of the old function type representation that needs to go away (you’re probably running into parameter inference doing weird things which is a symptom of the larger problem). What does it matter that the two function types have different ExtInfo? What are you trying to do here?

~Robert Widmann

···

On Sep 23, 2017, at 3:39 PM, David Zarzycki via swift-dev <swift-dev@swift.org> wrote:

Thanks,
Dave
_______________________________________________
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev

Hi Robert,

As a prerequisite to some other hacking I’m doing, I have an experimental implementation of value semantics; where (among other details), all functions have a bit in ExtInfo that denotes whether the function has enforced value semantics or not. As a matter of polish, I’d like the following code to work:

// reference semantic context
someValueTypeArray.sort({
  // hasValueSemantics ExtInfo bit propagates from the
  // parameter type of sort() to the ClosureExpr type
})

Hence the desire to have the closure’s type be a disjunction between two FunctionTypes, one where the “hasValueSemantics” bit is set, and one where it is not. If there is a better way to do this, I’m open. :slight_smile:

Thanks,
Dave

···

On Sep 23, 2017, at 20:11, Robert Widmann via swift-dev <swift-dev@swift.org> wrote:

On Sep 23, 2017, at 3:39 PM, David Zarzycki via swift-dev <swift-dev@swift.org> wrote:

Hello,

I’m trying to replace the explicit FunctionType returned by visitClosureExpr() in CSGen.cpp with a type variable; and ultimately a disjunction of two FunctionTypes with different ExtInfo flags set (one favored, one not).

I really don’t recommend doing this. Even the current late-binding of a proper function type in closure inference is an artifact of the old function type representation that needs to go away (you’re probably running into parameter inference doing weird things which is a symptom of the larger problem). What does it matter that the two function types have different ExtInfo? What are you trying to do here?

~Robert Widmann

Thanks,
Dave
_______________________________________________
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev

_______________________________________________
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev

Why is the arrow carrying the “Has Value Semantics Bit” rather than it being part of a protocol composition on an argument type, or a convention bit on the parameter like ‘inout’?

~Robert Widmann

···

On Sep 24, 2017, at 1:12 AM, David Zarzycki <dave@znu.io> wrote:

Hi Robert,

As a prerequisite to some other hacking I’m doing, I have an experimental implementation of value semantics; where (among other details), all functions have a bit in ExtInfo that denotes whether the function has enforced value semantics or not. As a matter of polish, I’d like the following code to work:

// reference semantic context
someValueTypeArray.sort({
  // hasValueSemantics ExtInfo bit propagates from the
  // parameter type of sort() to the ClosureExpr type
})

Hence the desire to have the closure’s type be a disjunction between two FunctionTypes, one where the “hasValueSemantics” bit is set, and one where it is not. If there is a better way to do this, I’m open. :slight_smile:

Thanks,
Dave

On Sep 23, 2017, at 20:11, Robert Widmann via swift-dev <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:

On Sep 23, 2017, at 3:39 PM, David Zarzycki via swift-dev <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:

Hello,

I’m trying to replace the explicit FunctionType returned by visitClosureExpr() in CSGen.cpp with a type variable; and ultimately a disjunction of two FunctionTypes with different ExtInfo flags set (one favored, one not).

I really don’t recommend doing this. Even the current late-binding of a proper function type in closure inference is an artifact of the old function type representation that needs to go away (you’re probably running into parameter inference doing weird things which is a symptom of the larger problem). What does it matter that the two function types have different ExtInfo? What are you trying to do here?

~Robert Widmann

Thanks,
Dave
_______________________________________________
swift-dev mailing list
swift-dev@swift.org <mailto:swift-dev@swift.org>
https://lists.swift.org/mailman/listinfo/swift-dev

_______________________________________________
swift-dev mailing list
swift-dev@swift.org <mailto:swift-dev@swift.org>
https://lists.swift.org/mailman/listinfo/swift-dev

Hi Robert,

As a prerequisite to some other hacking I’m doing, I have an experimental implementation of value semantics; where (among other details), all functions have a bit in ExtInfo that denotes whether the function has enforced value semantics or not. As a matter of polish, I’d like the following code to work:

// reference semantic context
someValueTypeArray.sort({
  // hasValueSemantics ExtInfo bit propagates from the
  // parameter type of sort() to the ClosureExpr type
})

Hence the desire to have the closure’s type be a disjunction between two FunctionTypes, one where the “hasValueSemantics” bit is set, and one where it is not. If there is a better way to do this, I’m open. :slight_smile:

The working plan with closure type-checking is that we'll add a "this is a closure type" constraint to the type-checker where, instead of having to pick a concretely-structured function type during CSGen, we'll create a fresh type variable and say that its type is required to be structured compatibly with whatever information we've derived from the closure. Contextual information would then naturally flow from the context to the closure's type. The constraint solver would default the function type from the encoded closure structure of the constraint if it could prove that no other constraint applied.

If that was implemented, we'd be able to propagate arbitrary function-type structure from the context instead of having to eagerly create highly-complex constraint systems whenever we encountered a closure.

John.

···

On Sep 24, 2017, at 1:13 AM, David Zarzycki via swift-dev <swift-dev@swift.org> wrote:

Thanks,
Dave

On Sep 23, 2017, at 20:11, Robert Widmann via swift-dev <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:

On Sep 23, 2017, at 3:39 PM, David Zarzycki via swift-dev <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:

Hello,

I’m trying to replace the explicit FunctionType returned by visitClosureExpr() in CSGen.cpp with a type variable; and ultimately a disjunction of two FunctionTypes with different ExtInfo flags set (one favored, one not).

I really don’t recommend doing this. Even the current late-binding of a proper function type in closure inference is an artifact of the old function type representation that needs to go away (you’re probably running into parameter inference doing weird things which is a symptom of the larger problem). What does it matter that the two function types have different ExtInfo? What are you trying to do here?

~Robert Widmann

Thanks,
Dave
_______________________________________________
swift-dev mailing list
swift-dev@swift.org <mailto:swift-dev@swift.org>
https://lists.swift.org/mailman/listinfo/swift-dev

_______________________________________________
swift-dev mailing list
swift-dev@swift.org <mailto:swift-dev@swift.org>
https://lists.swift.org/mailman/listinfo/swift-dev

_______________________________________________
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev

Well, for starters, a function with zero arguments/parameters can be value semantic. For example:

func getMagicNumber() -> UInt64 {
  return 0x3A4B1C7539DA4922
}

Dave

···

On Sep 24, 2017, at 01:36, Robert Widmann via swift-dev <swift-dev@swift.org> wrote:

Why is the arrow carrying the “Has Value Semantics Bit” rather than it being part of a protocol composition on an argument type, or a convention bit on the parameter like ‘inout’?

~Robert Widmann

On Sep 24, 2017, at 1:12 AM, David Zarzycki <dave@znu.io <mailto:dave@znu.io>> wrote:

Hi Robert,

As a prerequisite to some other hacking I’m doing, I have an experimental implementation of value semantics; where (among other details), all functions have a bit in ExtInfo that denotes whether the function has enforced value semantics or not. As a matter of polish, I’d like the following code to work:

// reference semantic context
someValueTypeArray.sort({
  // hasValueSemantics ExtInfo bit propagates from the
  // parameter type of sort() to the ClosureExpr type
})

Hence the desire to have the closure’s type be a disjunction between two FunctionTypes, one where the “hasValueSemantics” bit is set, and one where it is not. If there is a better way to do this, I’m open. :slight_smile:

Thanks,
Dave

On Sep 23, 2017, at 20:11, Robert Widmann via swift-dev <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:

On Sep 23, 2017, at 3:39 PM, David Zarzycki via swift-dev <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:

Hello,

I’m trying to replace the explicit FunctionType returned by visitClosureExpr() in CSGen.cpp with a type variable; and ultimately a disjunction of two FunctionTypes with different ExtInfo flags set (one favored, one not).

I really don’t recommend doing this. Even the current late-binding of a proper function type in closure inference is an artifact of the old function type representation that needs to go away (you’re probably running into parameter inference doing weird things which is a symptom of the larger problem). What does it matter that the two function types have different ExtInfo? What are you trying to do here?

~Robert Widmann

Thanks,
Dave
_______________________________________________
swift-dev mailing list
swift-dev@swift.org <mailto:swift-dev@swift.org>
https://lists.swift.org/mailman/listinfo/swift-dev

_______________________________________________
swift-dev mailing list
swift-dev@swift.org <mailto:swift-dev@swift.org>
https://lists.swift.org/mailman/listinfo/swift-dev

_______________________________________________
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev

Thanks John!

I’ll find a workaround or just punt on this QoI work for now.

Dave

···

On Sep 24, 2017, at 23:06, John McCall <rjmccall@apple.com> wrote:

On Sep 24, 2017, at 1:13 AM, David Zarzycki via swift-dev <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:
Hi Robert,

As a prerequisite to some other hacking I’m doing, I have an experimental implementation of value semantics; where (among other details), all functions have a bit in ExtInfo that denotes whether the function has enforced value semantics or not. As a matter of polish, I’d like the following code to work:

// reference semantic context
someValueTypeArray.sort({
  // hasValueSemantics ExtInfo bit propagates from the
  // parameter type of sort() to the ClosureExpr type
})

Hence the desire to have the closure’s type be a disjunction between two FunctionTypes, one where the “hasValueSemantics” bit is set, and one where it is not. If there is a better way to do this, I’m open. :slight_smile:

The working plan with closure type-checking is that we'll add a "this is a closure type" constraint to the type-checker where, instead of having to pick a concretely-structured function type during CSGen, we'll create a fresh type variable and say that its type is required to be structured compatibly with whatever information we've derived from the closure. Contextual information would then naturally flow from the context to the closure's type. The constraint solver would default the function type from the encoded closure structure of the constraint if it could prove that no other constraint applied.

If that was implemented, we'd be able to propagate arbitrary function-type structure from the context instead of having to eagerly create highly-complex constraint systems whenever we encountered a closure.

John.

Thanks,
Dave

On Sep 23, 2017, at 20:11, Robert Widmann via swift-dev <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:

On Sep 23, 2017, at 3:39 PM, David Zarzycki via swift-dev <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:

Hello,

I’m trying to replace the explicit FunctionType returned by visitClosureExpr() in CSGen.cpp with a type variable; and ultimately a disjunction of two FunctionTypes with different ExtInfo flags set (one favored, one not).

I really don’t recommend doing this. Even the current late-binding of a proper function type in closure inference is an artifact of the old function type representation that needs to go away (you’re probably running into parameter inference doing weird things which is a symptom of the larger problem). What does it matter that the two function types have different ExtInfo? What are you trying to do here?

~Robert Widmann

Thanks,
Dave
_______________________________________________
swift-dev mailing list
swift-dev@swift.org <mailto:swift-dev@swift.org>
https://lists.swift.org/mailman/listinfo/swift-dev

_______________________________________________
swift-dev mailing list
swift-dev@swift.org <mailto:swift-dev@swift.org>
https://lists.swift.org/mailman/listinfo/swift-dev

_______________________________________________
swift-dev mailing list
swift-dev@swift.org <mailto:swift-dev@swift.org>
https://lists.swift.org/mailman/listinfo/swift-dev

Value semantics is a property of operations, not really of types. I would say the function arrow is the right place for it, since not-value-semantics propagates in the same manner as an effect like "throws". Dave, you might in fact look at how 'throws' type checking is implemented as a model for what you're trying to do.

-Joe

···

On Sep 23, 2017, at 10:36 PM, Robert Widmann via swift-dev <swift-dev@swift.org> wrote:

Why is the arrow carrying the “Has Value Semantics Bit” rather than it being part of a protocol composition on an argument type, or a convention bit on the parameter like ‘inout’?

Then the split you want isn’t at the level of the ClosureExpr, it’s at the level of the ApplyExpr. You should take a look at CSRanking and penalize/remove overloads that have arguments whose “I have value semantics” bits don’t match.

~Robert Widmann

···

On Sep 24, 2017, at 8:01 AM, David Zarzycki <dave@znu.io> wrote:

Well, for starters, a function with zero arguments/parameters can be value semantic. For example:

func getMagicNumber() -> UInt64 {
  return 0x3A4B1C7539DA4922
}

Dave

On Sep 24, 2017, at 01:36, Robert Widmann via swift-dev <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:

Why is the arrow carrying the “Has Value Semantics Bit” rather than it being part of a protocol composition on an argument type, or a convention bit on the parameter like ‘inout’?

~Robert Widmann

On Sep 24, 2017, at 1:12 AM, David Zarzycki <dave@znu.io <mailto:dave@znu.io>> wrote:

Hi Robert,

As a prerequisite to some other hacking I’m doing, I have an experimental implementation of value semantics; where (among other details), all functions have a bit in ExtInfo that denotes whether the function has enforced value semantics or not. As a matter of polish, I’d like the following code to work:

// reference semantic context
someValueTypeArray.sort({
  // hasValueSemantics ExtInfo bit propagates from the
  // parameter type of sort() to the ClosureExpr type
})

Hence the desire to have the closure’s type be a disjunction between two FunctionTypes, one where the “hasValueSemantics” bit is set, and one where it is not. If there is a better way to do this, I’m open. :slight_smile:

Thanks,
Dave

On Sep 23, 2017, at 20:11, Robert Widmann via swift-dev <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:

On Sep 23, 2017, at 3:39 PM, David Zarzycki via swift-dev <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:

Hello,

I’m trying to replace the explicit FunctionType returned by visitClosureExpr() in CSGen.cpp with a type variable; and ultimately a disjunction of two FunctionTypes with different ExtInfo flags set (one favored, one not).

I really don’t recommend doing this. Even the current late-binding of a proper function type in closure inference is an artifact of the old function type representation that needs to go away (you’re probably running into parameter inference doing weird things which is a symptom of the larger problem). What does it matter that the two function types have different ExtInfo? What are you trying to do here?

~Robert Widmann

Thanks,
Dave
_______________________________________________
swift-dev mailing list
swift-dev@swift.org <mailto:swift-dev@swift.org>
https://lists.swift.org/mailman/listinfo/swift-dev

_______________________________________________
swift-dev mailing list
swift-dev@swift.org <mailto:swift-dev@swift.org>
https://lists.swift.org/mailman/listinfo/swift-dev

_______________________________________________
swift-dev mailing list
swift-dev@swift.org <mailto:swift-dev@swift.org>
https://lists.swift.org/mailman/listinfo/swift-dev

Hi Joe,

In fact, I tried to replicate the “closureCanThrow()” logic before emailing this list, but that didn’t work due to a chicken-and-egg problem that arrises between when a ClosureExpr's body is type checked and knowing the type of the ClosureExpr. In other words, a closure has value semantics iff all operations within it have value semantics.

As I wrote earlier in this email thread, the “value semantics” implementation I’m working on is sufficient for the research that I’m doing. That being said, I took some shortcuts to get it working and the closure type shortcut bothered me the most. That is why I emailed this list about how to propagate the contextual ExtInfo bit onto the closure type. Based on John’s helpful email, I think I’ll just live with the shortcuts I made for now.

Thanks,
Dave

···

On Sep 25, 2017, at 14:37, Joe Groff <jgroff@apple.com> wrote:

On Sep 23, 2017, at 10:36 PM, Robert Widmann via swift-dev <swift-dev@swift.org> wrote:

Why is the arrow carrying the “Has Value Semantics Bit” rather than it being part of a protocol composition on an argument type, or a convention bit on the parameter like ‘inout’?

Value semantics is a property of operations, not really of types. I would say the function arrow is the right place for it, since not-value-semantics propagates in the same manner as an effect like "throws". Dave, you might in fact look at how 'throws' type checking is implemented as a model for what you're trying to do.

If you have something working well enough for your prototype, then great. If you do decide to look at this again, I think it might be easier to flip the polarity of the check—a closure is not-value-semantics if it does anything that's not-value-semantics—which should make it the exact same kind of problem as `throws` propagation.

-Joe

···

On Sep 25, 2017, at 1:04 PM, David Zarzycki <dave@znu.io> wrote:

On Sep 25, 2017, at 14:37, Joe Groff <jgroff@apple.com> wrote:

On Sep 23, 2017, at 10:36 PM, Robert Widmann via swift-dev <swift-dev@swift.org> wrote:

Why is the arrow carrying the “Has Value Semantics Bit” rather than it being part of a protocol composition on an argument type, or a convention bit on the parameter like ‘inout’?

Value semantics is a property of operations, not really of types. I would say the function arrow is the right place for it, since not-value-semantics propagates in the same manner as an effect like "throws". Dave, you might in fact look at how 'throws' type checking is implemented as a model for what you're trying to do.

Hi Joe,

In fact, I tried to replicate the “closureCanThrow()” logic before emailing this list, but that didn’t work due to a chicken-and-egg problem that arrises between when a ClosureExpr's body is type checked and knowing the type of the ClosureExpr. In other words, a closure has value semantics iff all operations within it have value semantics.

As I wrote earlier in this email thread, the “value semantics” implementation I’m working on is sufficient for the research that I’m doing. That being said, I took some shortcuts to get it working and the closure type shortcut bothered me the most. That is why I emailed this list about how to propagate the contextual ExtInfo bit onto the closure type. Based on John’s helpful email, I think I’ll just live with the shortcuts I made for now.

Thanks. FWIW – I thought about that because ExtInfo has a bias towards “false” as the default for flags within it, and that forced me to contemplate what the default semantics should be. Unfortunately, either default doesn’t work for the same reason: the ExtInfo bits are stored in the type, but closure body type checking is done after the type of the closure is needed.

Dave

···

On Sep 25, 2017, at 18:23, Joe Groff <jgroff@apple.com> wrote:

On Sep 25, 2017, at 1:04 PM, David Zarzycki <dave@znu.io> wrote:

On Sep 25, 2017, at 14:37, Joe Groff <jgroff@apple.com> wrote:

On Sep 23, 2017, at 10:36 PM, Robert Widmann via swift-dev <swift-dev@swift.org> wrote:

Why is the arrow carrying the “Has Value Semantics Bit” rather than it being part of a protocol composition on an argument type, or a convention bit on the parameter like ‘inout’?

Value semantics is a property of operations, not really of types. I would say the function arrow is the right place for it, since not-value-semantics propagates in the same manner as an effect like "throws". Dave, you might in fact look at how 'throws' type checking is implemented as a model for what you're trying to do.

Hi Joe,

In fact, I tried to replicate the “closureCanThrow()” logic before emailing this list, but that didn’t work due to a chicken-and-egg problem that arrises between when a ClosureExpr's body is type checked and knowing the type of the ClosureExpr. In other words, a closure has value semantics iff all operations within it have value semantics.

As I wrote earlier in this email thread, the “value semantics” implementation I’m working on is sufficient for the research that I’m doing. That being said, I took some shortcuts to get it working and the closure type shortcut bothered me the most. That is why I emailed this list about how to propagate the contextual ExtInfo bit onto the closure type. Based on John’s helpful email, I think I’ll just live with the shortcuts I made for now.

If you have something working well enough for your prototype, then great. If you do decide to look at this again, I think it might be easier to flip the polarity of the check—a closure is not-value-semantics if it does anything that's not-value-semantics—which should make it the exact same kind of problem as `throws` propagation.

The other thing `throws` does is establish a subtype relationship from nonthrowing to throwing functions, so if analysis determines a closure doesn't throw, but we later determine that we need a throwing one, we can implicitly convert. I think it'd be appropriate to allow a similar conversion from pure-value-semantics to non-value-semantics, and I think that'd address your issue.

···

On Sep 25, 2017, at 3:41 PM, David Zarzycki <dave@znu.io> wrote:

On Sep 25, 2017, at 18:23, Joe Groff <jgroff@apple.com> wrote:

On Sep 25, 2017, at 1:04 PM, David Zarzycki <dave@znu.io> wrote:

On Sep 25, 2017, at 14:37, Joe Groff <jgroff@apple.com> wrote:

On Sep 23, 2017, at 10:36 PM, Robert Widmann via swift-dev <swift-dev@swift.org> wrote:

Why is the arrow carrying the “Has Value Semantics Bit” rather than it being part of a protocol composition on an argument type, or a convention bit on the parameter like ‘inout’?

Value semantics is a property of operations, not really of types. I would say the function arrow is the right place for it, since not-value-semantics propagates in the same manner as an effect like "throws". Dave, you might in fact look at how 'throws' type checking is implemented as a model for what you're trying to do.

Hi Joe,

In fact, I tried to replicate the “closureCanThrow()” logic before emailing this list, but that didn’t work due to a chicken-and-egg problem that arrises between when a ClosureExpr's body is type checked and knowing the type of the ClosureExpr. In other words, a closure has value semantics iff all operations within it have value semantics.

As I wrote earlier in this email thread, the “value semantics” implementation I’m working on is sufficient for the research that I’m doing. That being said, I took some shortcuts to get it working and the closure type shortcut bothered me the most. That is why I emailed this list about how to propagate the contextual ExtInfo bit onto the closure type. Based on John’s helpful email, I think I’ll just live with the shortcuts I made for now.

If you have something working well enough for your prototype, then great. If you do decide to look at this again, I think it might be easier to flip the polarity of the check—a closure is not-value-semantics if it does anything that's not-value-semantics—which should make it the exact same kind of problem as `throws` propagation.

Thanks. FWIW – I thought about that because ExtInfo has a bias towards “false” as the default for flags within it, and that forced me to contemplate what the default semantics should be. Unfortunately, either default doesn’t work for the same reason: the ExtInfo bits are stored in the type, but closure body type checking is done after the type of the closure is needed.

Ya, the “throws” subtyping and related conversion was useful to crib from, but I don’t see how that helps the contextual ClosureExpr type scenario. Unlike “throws” (and absent a contextual type), deducing the value semantic nature of a closure requires type checking the body first. Am I missing something? Is there a scenario that I can crib from where ExtInfo bits of the contextual function type propagate onto the type of a ClosureExpr?

Dave

···

On Sep 25, 2017, at 21:59, Joe Groff via swift-dev <swift-dev@swift.org> wrote:

On Sep 25, 2017, at 3:41 PM, David Zarzycki <dave@znu.io <mailto:dave@znu.io>> wrote:

On Sep 25, 2017, at 18:23, Joe Groff <jgroff@apple.com <mailto:jgroff@apple.com>> wrote:

On Sep 25, 2017, at 1:04 PM, David Zarzycki <dave@znu.io <mailto:dave@znu.io>> wrote:

On Sep 25, 2017, at 14:37, Joe Groff <jgroff@apple.com <mailto:jgroff@apple.com>> wrote:

On Sep 23, 2017, at 10:36 PM, Robert Widmann via swift-dev <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:

Why is the arrow carrying the “Has Value Semantics Bit” rather than it being part of a protocol composition on an argument type, or a convention bit on the parameter like ‘inout’?

Value semantics is a property of operations, not really of types. I would say the function arrow is the right place for it, since not-value-semantics propagates in the same manner as an effect like "throws". Dave, you might in fact look at how 'throws' type checking is implemented as a model for what you're trying to do.

Hi Joe,

In fact, I tried to replicate the “closureCanThrow()” logic before emailing this list, but that didn’t work due to a chicken-and-egg problem that arrises between when a ClosureExpr's body is type checked and knowing the type of the ClosureExpr. In other words, a closure has value semantics iff all operations within it have value semantics.

As I wrote earlier in this email thread, the “value semantics” implementation I’m working on is sufficient for the research that I’m doing. That being said, I took some shortcuts to get it working and the closure type shortcut bothered me the most. That is why I emailed this list about how to propagate the contextual ExtInfo bit onto the closure type. Based on John’s helpful email, I think I’ll just live with the shortcuts I made for now.

If you have something working well enough for your prototype, then great. If you do decide to look at this again, I think it might be easier to flip the polarity of the check—a closure is not-value-semantics if it does anything that's not-value-semantics—which should make it the exact same kind of problem as `throws` propagation.

Thanks. FWIW – I thought about that because ExtInfo has a bias towards “false” as the default for flags within it, and that forced me to contemplate what the default semantics should be. Unfortunately, either default doesn’t work for the same reason: the ExtInfo bits are stored in the type, but closure body type checking is done after the type of the closure is needed.

The other thing `throws` does is establish a subtype relationship from nonthrowing to throwing functions, so if analysis determines a closure doesn't throw, but we later determine that we need a throwing one, we can implicitly convert. I think it'd be appropriate to allow a similar conversion from pure-value-semantics to non-value-semantics, and I think that'd address your issue.

Checking whether a function throws or not also requires type-checking the body, since otherwise we don't know whether 'catch' blocks are exhaustive or whether 'try' subexpressions actually cover a failable operation. I'm definitely not an expert on the type checker, so I'm probably missing something, but it seems like the same problem.

-Joe

···

On Sep 25, 2017, at 7:53 PM, David Zarzycki <dave@znu.io> wrote:

On Sep 25, 2017, at 21:59, Joe Groff via swift-dev <swift-dev@swift.org> wrote:

On Sep 25, 2017, at 3:41 PM, David Zarzycki <dave@znu.io> wrote:

On Sep 25, 2017, at 18:23, Joe Groff <jgroff@apple.com> wrote:

On Sep 25, 2017, at 1:04 PM, David Zarzycki <dave@znu.io> wrote:

On Sep 25, 2017, at 14:37, Joe Groff <jgroff@apple.com> wrote:

On Sep 23, 2017, at 10:36 PM, Robert Widmann via swift-dev <swift-dev@swift.org> wrote:

Why is the arrow carrying the “Has Value Semantics Bit” rather than it being part of a protocol composition on an argument type, or a convention bit on the parameter like ‘inout’?

Value semantics is a property of operations, not really of types. I would say the function arrow is the right place for it, since not-value-semantics propagates in the same manner as an effect like "throws". Dave, you might in fact look at how 'throws' type checking is implemented as a model for what you're trying to do.

Hi Joe,

In fact, I tried to replicate the “closureCanThrow()” logic before emailing this list, but that didn’t work due to a chicken-and-egg problem that arrises between when a ClosureExpr's body is type checked and knowing the type of the ClosureExpr. In other words, a closure has value semantics iff all operations within it have value semantics.

As I wrote earlier in this email thread, the “value semantics” implementation I’m working on is sufficient for the research that I’m doing. That being said, I took some shortcuts to get it working and the closure type shortcut bothered me the most. That is why I emailed this list about how to propagate the contextual ExtInfo bit onto the closure type. Based on John’s helpful email, I think I’ll just live with the shortcuts I made for now.

If you have something working well enough for your prototype, then great. If you do decide to look at this again, I think it might be easier to flip the polarity of the check—a closure is not-value-semantics if it does anything that's not-value-semantics—which should make it the exact same kind of problem as `throws` propagation.

Thanks. FWIW – I thought about that because ExtInfo has a bias towards “false” as the default for flags within it, and that forced me to contemplate what the default semantics should be. Unfortunately, either default doesn’t work for the same reason: the ExtInfo bits are stored in the type, but closure body type checking is done after the type of the closure is needed.

The other thing `throws` does is establish a subtype relationship from nonthrowing to throwing functions, so if analysis determines a closure doesn't throw, but we later determine that we need a throwing one, we can implicitly convert. I think it'd be appropriate to allow a similar conversion from pure-value-semantics to non-value-semantics, and I think that'd address your issue.

Ya, the “throws” subtyping and related conversion was useful to crib from, but I don’t see how that helps the contextual ClosureExpr type scenario. Unlike “throws” (and absent a contextual type), deducing the value semantic nature of a closure requires type checking the body first. Am I missing something? Is there a scenario that I can crib from where ExtInfo bits of the contextual function type propagate onto the type of a ClosureExpr?

We actually just use a heuristic to infer it from scratch, by looking for 'try's that aren't inside any apparently-exhaustive do/catch. It's not illegal for 'try' to not cover a failable operation, but in practice the heuristic seems to have worked well.

It is something we would probably need to completely rewrite if we had typed-throws, of course.

John.

···

On Sep 26, 2017, at 11:22 AM, Joe Groff via swift-dev <swift-dev@swift.org> wrote:

On Sep 25, 2017, at 7:53 PM, David Zarzycki <dave@znu.io> wrote:

On Sep 25, 2017, at 21:59, Joe Groff via swift-dev <swift-dev@swift.org> wrote:
On Sep 25, 2017, at 3:41 PM, David Zarzycki <dave@znu.io> wrote:

On Sep 25, 2017, at 18:23, Joe Groff <jgroff@apple.com> wrote:

On Sep 25, 2017, at 1:04 PM, David Zarzycki <dave@znu.io> wrote:

On Sep 25, 2017, at 14:37, Joe Groff <jgroff@apple.com> wrote:

On Sep 23, 2017, at 10:36 PM, Robert Widmann via swift-dev <swift-dev@swift.org> wrote:

Why is the arrow carrying the “Has Value Semantics Bit” rather than it being part of a protocol composition on an argument type, or a convention bit on the parameter like ‘inout’?

Value semantics is a property of operations, not really of types. I would say the function arrow is the right place for it, since not-value-semantics propagates in the same manner as an effect like "throws". Dave, you might in fact look at how 'throws' type checking is implemented as a model for what you're trying to do.

Hi Joe,

In fact, I tried to replicate the “closureCanThrow()” logic before emailing this list, but that didn’t work due to a chicken-and-egg problem that arrises between when a ClosureExpr's body is type checked and knowing the type of the ClosureExpr. In other words, a closure has value semantics iff all operations within it have value semantics.

As I wrote earlier in this email thread, the “value semantics” implementation I’m working on is sufficient for the research that I’m doing. That being said, I took some shortcuts to get it working and the closure type shortcut bothered me the most. That is why I emailed this list about how to propagate the contextual ExtInfo bit onto the closure type. Based on John’s helpful email, I think I’ll just live with the shortcuts I made for now.

If you have something working well enough for your prototype, then great. If you do decide to look at this again, I think it might be easier to flip the polarity of the check—a closure is not-value-semantics if it does anything that's not-value-semantics—which should make it the exact same kind of problem as `throws` propagation.

Thanks. FWIW – I thought about that because ExtInfo has a bias towards “false” as the default for flags within it, and that forced me to contemplate what the default semantics should be. Unfortunately, either default doesn’t work for the same reason: the ExtInfo bits are stored in the type, but closure body type checking is done after the type of the closure is needed.

The other thing `throws` does is establish a subtype relationship from nonthrowing to throwing functions, so if analysis determines a closure doesn't throw, but we later determine that we need a throwing one, we can implicitly convert. I think it'd be appropriate to allow a similar conversion from pure-value-semantics to non-value-semantics, and I think that'd address your issue.

Ya, the “throws” subtyping and related conversion was useful to crib from, but I don’t see how that helps the contextual ClosureExpr type scenario. Unlike “throws” (and absent a contextual type), deducing the value semantic nature of a closure requires type checking the body first. Am I missing something? Is there a scenario that I can crib from where ExtInfo bits of the contextual function type propagate onto the type of a ClosureExpr?

Checking whether a function throws or not also requires type-checking the body, since otherwise we don't know whether 'catch' blocks are exhaustive or whether 'try' subexpressions actually cover a failable operation. I'm definitely not an expert on the type checker, so I'm probably missing something, but it seems like the same problem.