[swift-evolution] ternary operator ?: suggestion

Paul Ossenbruggen possen at gmail.com
Fri Jan 15 00:49:10 CST 2016


Hi Craig,

I definitely like the proposal. It is a great start. I had gone down a similar path in working on my own proposal which included the ideas we were talking about here, largely for my own exploration, I will see if there are some things in my version that would be good to incorporate. 

I would like to get more of Thorsten’s suggestions in the partial functions fleshed out a bit because I think it is important to at least have that idea explored further. 

I have tried to keep this idea just for expressions because it is simpler, but when Thorsten talked about supporting, statements in the partial expressions, I started thinking the “cases” would actually be different than “case.”  So for expressions you would use “cases” and list each label:expression after that. For “case” you put “statements” But in that situation, maybe a different label would make the distinction clearer, like “expressions”. This is definitely half-baked but something like:

let result = color.map {
	expressions .Red: 0xFF0000, .Green: 0x00FF00, .Blue: 0x0000FF
	default: 0xFFFFFF
}

and if you had statement (admittedly contrived):

let result = color.map {
	case .Red: 
		let alpha = calculateRedColorAlpha()
		0xFF0000 * alpha
	case .Green:
		let alpha = calculateGreenColorAlpha() 
		0x00FF00 * alpha 
	case .Blue:
		let alpha = calculateBlueColorAlpha()
		0x0000FF * alpha
	default: 
		let alpha = calculateAlphaColor()
		0xFFFFFF * alpha
}

You could mix the two too. The “cases” would need to check that each had a result of compatible type. Any way, just thinking about it, it seems to add complexity though. 

- Paul


> On Jan 14, 2016, at 5:13 PM, Craig Cruden <ccruden at novafore.com> wrote:
> 
> I admit I am not a fan of cases as either but included it as a compromise because of a fairly even devision between those that want a concise multi-ternary solution and those that want a more robust solution.
> 
> I view “cases” to be syntactic sugar for the first form, and my gut thinks it is the first thing to go in the review…. so I made it as second in each of the sections.  
> 
> I did not include Partial Functions for a few reasons… One I see it as a much smaller use case and wanted to focus on pattern matching in this proposal, with potentially a followup refinement adding the ability to define Partial Functions.  I also have no idea how to communicate in my own mind it’s strengths and formulate a sales pitch in my own mind — let alone in writing.  I use both pattern matching and cases within closures in Scala extensively but never made use of Partial Functions.
> 
> Additionally the Haskell (functional paradigm language) folks seem to be arguing against the general use of partial functions:
> 
> https://wiki.haskell.org/Partial_functions <https://wiki.haskell.org/Partial_functions>
> 
> If you can write up a formal proposal for generalized partial functions and it’s sales pitch I could make reference to it in the Pattern Matching proposal and potentially submit them in unison.  I just worry that if the proposal is not focused their is a greater chance of Rejection or at best Deferred.
> 
> Craig
> 
>> On 2016-01-15, at 5:32:19, Thorsten Seitz <tseitz42 at icloud.com <mailto:tseitz42 at icloud.com>> wrote:
>> 
>> Hi Craig,
>> 
>> looks good so far!
>> I’m not a fan of the concise form, though, and would drop it.
>> 
>> The proposal should define what a partial function is supposed to be., i.e. a function that can check whether an argument is in its domain.
>> It should be possible to ask them isDefinedAt() like in Scala. And chain them with orElse() and andThen(). That would be really useful!
>> 
>> let stdColorCode = {
>> 	case .Red: 100
>> 	case .Green: 200
>> 	case .Blue: 300
>> }
>> 
>> // type of stdColorCode: partial Color -> Int
>> // or maybe: Color => Int
>> 
>> let colorCode = stdColorCode.orElse {
>> 	case .Yellow: 400
>> 	case .Cyan: 500
>> 	case .Magenta: 600
>> }
>> 
>> let x = colorCode(col).orElse(700)
>> 
>> Thinking about it, I have the feeling that it should be possible to force exhaustiveness checks somehow.
>> 
>> Maybe like follows:
>> 
>> // Defining a partial function has to be made explicit with a new keyword undefined in the default clause (or other case clauses)
>> // (I briefly thought about reusing „continue“ but that might collide with the proposal to make „break“, „continue“ and possibly „return“ to
>> // work properly in closures)
>> let stdColorCode = {
>> 	case .Red: 100
>> 	case .Green: 200
>> 	case .Blue: 300
>> 	default: undefined
>> }
>> 
>> // The following is *not* a partial function (and cannot be asked isDefinedAt() or chained).
>> // But the compiler would complain if the argument type (here inferred) has more cases (just like in a normal switch statement).
>> let stdColorCode = {
>> 	case .Red: 100
>> 	case .Green: 200
>> 	case .Blue: 300
>> 	case .Yellow: 400
>> 	case .Cyan: 500
>> 	case .Magenta: 600
>> }
>> 
>> -Thorsten
>> 
>> 
>>> Am 14.01.2016 um 20:23 schrieb Craig Cruden via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>>:
>>> 
>>> Paul, 
>>> 
>>> I tried to put my understanding on the latest proposal option into a draft on github (instead of my usual BitBucket repo).  
>>> 
>>> Take a look at it and see if there is anything useable.
>>> 
>>> https://github.com/cacruden/swift-evolution/blob/master/proposals/0000-Pattern-Matching-Partial-Function.md <https://github.com/cacruden/swift-evolution/blob/master/proposals/0000-Pattern-Matching-Partial-Function.md>
>>> 
>>> Craig
>>> 
>>>> On 2016-01-11, at 14:17:09, Craig Cruden <ccruden at novafore.com <mailto:ccruden at novafore.com>> wrote:
>>>> 
>>>> Ignore the last comment - tired and mistaken. :p
>>>> 
>>>> 
>>>>> On 2016-01-11, at 14:16:01, Craig Cruden <ccruden at novafore.com <mailto:ccruden at novafore.com>> wrote:
>>>>> 
>>>>> I just realized “cases” probably is not needed - if it see’s a comma after case but before “:” then it is the concise form.  
>>>>> 
>>>>> If the switch / case can do that , the partial function case should be able to do the same thing.
>>>>> 
>>>>> 
>>>>>> On 2016-01-11, at 13:23:19, Craig Cruden <ccruden at novafore.com <mailto:ccruden at novafore.com>> wrote:
>>>>>> 
>>>>>> I have thought about it a bit more and I think this would cover all the cases that interest me (in addition to others needs for a little more conciseness on the most simple case).  
>>>>>> 
>>>>>> I also think we need to be clear that the “case” (or cases) and “default” are is really just a partial function which in it’s entirety is really just a complete function for used wherever a complete function (exhaustive) can be passed (e.g. reduce, filter, etc.) - otherwise they might get confused on why we are adding it to “map”.  
>>>>>> 
>>>>>> The optional where clause should also be part of the case clause as part of the proposal.  
>>>>>> 
>>>>>> There would be no need for statement based “fallthrough”.
>>>>>> 
>>>>>> You mentioned your proposal….  have you drafted a formal proposal draft?
>>>>>> 
>>>>>> 
>>>>>> 
>>>>>>> On 2016-01-10, at 12:41:03, Paul Ossenbruggen via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>>>>>> 
>>>>>>> I agree that it would be really useful to keep things concise. I am going to suggest again an idea I had in the past, it is also in my proposal, which might work well for this problem. This might address the verbosity of the “case” and at the same time make it obvious we are dealing with a switch expression. So both would be valid: 
>>>>>>> 
>>>>>>> 	let num = color.map {
>>>>>>> 		cases   .Red: 100, 
>>>>>>> 			     .Green:  200, 
>>>>>>> 			     .Blue: 300
>>>>>>> 		default: -1 
>>>>>>> 	}
>>>>>>> 	let num = color.map {
>>>>>>> 		case     .Red: 100
>>>>>>> 		case     .Green:  200 
>>>>>>> 		case     .Blue: 300
>>>>>>> 		default: -1 
>>>>>>> 	}
>>>>>>> 
>>>>>> 
>>>>> 
>>>> 
>>> 
>>>  _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160114/1eb7190f/attachment.html>


More information about the swift-evolution mailing list