Hi,In general, I think that would require quite a sophisticated data flow analysis  - the compiler would have to statically track the length of lists. Even then, you'd get false positives in cases a bit more complex than these (e.g. on user input)I do agree with you that the "Incomplete pattern matches" warning so far has been more of a nuisance than a help - usually I add a | _ -> failwith "Bug!" just to get rid of the warning, which is of course completely superfluous (otherwise I'd get a matchfailure on the exact same spot, telling me the exact same thing).Kurt

By on 2/3/2009 5:25 AM ()

Well, when I said "in the simple case" I really just meant "In the case where you have literally listed out every element of the list directly into your source code." In that case it just seems like a matter of parsing. The list definition (on the RHS of the = sign) is being parsed anyway to determine how many / what elements to put into the variables I've specified on the LHS of the = sign. The only thing that isn't happening is it correlating the number of elements in the list on the RHS to the number of elements in the list on the LHS, and making sure they're identical.

The following, for example, should probably still issue a warning:
let list1 = [1 .. 5]
let [a; b; c; d; e] = list1

Like you said, that probably requires complicated data flow analysis. But

let [a; b; c; d; e] = [1..5]

on the other hand (which the example I posted above is really just a glorified version is) seems like it can be easily determined without the compiler having to look at anything other than the line in question.

By on 2/3/2009 6:29 AM ()

You want to use a tuple instead of a list. If you statically know the size of your list, it means you can use a tuple.

1
let a, b, c, d, e = 1, 2, 3, 4, 5
By on 2/3/2009 11:07 PM ()

Well, in theory I agree, but in this case I actually wanted to sort the resulting items according to some custom comparison function, even though the list was relatively small with only a few elements so a list seemed like the most elegant way to express it.

By on 2/4/2009 6:18 AM ()

Well, if you sort the list, then it's not a simple case. The compiler would have to prove that the sort function returns a list with the same length as its input. That's a difficult problem.

For simple cases, use tuples. When it gets more complex, add a _ branch.

Laurent.

By on 2/4/2009 8:54 AM ()

Sigh, I'm not sure if I'm just not explaining this correctly or if I'm really just missing something obvious.

The code I typed in the OP was exactly as it appeared in the code I was writing. There is no call to List.sort in that line of code. I am just saying that I see no fundamental reason the compiler should issue a warning that the code

1
let ([a;b;c;d;e] as l) = [1;2;3;4;5]

has incomplete pattern matches. There is 0 possibility of an incomplete pattern match. The fact that I wanted to sort the list "l" later is not really relevant, and has no bearing on whether or not there is a possibility of an incomplete pattern match in the above expression. It merely explains why I felt a list was more appropriate than a tuple. Yes, normally I would say

1
let foo = (1,2,3,4,5)

Assuming that I did not need to perform some operation on foo that some other data structure such as a list provides elegantly and for free. In the above example, I needed to know specifically the values corresponding to Left, Right, Top, and Bottom discriminated union values. I also needed the results to be sorted. The simplest solution is put them in a list, name the left, right, top, and bottom according to how I specificied the list initializer, then sort the list on the next line of code after the list is declared. Another solution was the following (simplified):

1
2
3
let l = [a; b; c; d]
let (left,right,top,bottom) = (List.nth 0 l, List.nth 1 l, List.nth 2 l, List.nth 3 l)
let l = List.sort_by (fun x -> (*...*)) l

But this takes 3 lines of code instead of 2, and I think the list method is still probably more elegant. The solution with List.nth is maybe even more dangerous (in theory), because if you later decided that you wanted to an a 5th element "e" to l, or for that matter remove an item, you would have to remember to update the line below accordingly, whereas if you specify it all on a single line using a list, the compiler actually could give a meaningful warning if the number of items on the left and right hand side of the equal sign don't match up.

By on 2/4/2009 9:20 AM ()

Well - if you think about what a list looks like for the compiler you might see why to check an expression of the form you gave is rather tricky. The problem is the length of the list. In your code every human beeing would agree that it should be simple - but here is the catch: Assume you've got something like

1
let ([a;b;c;d;e] as l) = [1]::restList

now the compiler has to check restList for it's length as well - but what if this got constructed by - say Seq.to_list? - And if you think about this you might see that's practically impossible to check the length of a list at compile-time.

By on 2/4/2009 10:07 PM ()

Well, I already agreed in the first or second post that it would be difficult, if not impossible to do it in the general case, which is what you're talking about. I am only referring to the one single case where you have hardcoded a list on the right hand side of the equal sign, and have not used the @ or :: operators.

By on 2/5/2009 5:29 AM ()

Bad idea. Such a special case for a specific situation, it's not worth implementing in any compiler. Either do it right or don't do it - otherwise the next guy will come along and as why other examples (which are simple extensions of your simple examples) won't work. And so on. Before you know it the whole thing is incomprehensible.

Kurt

By on 2/5/2009 1:43 PM ()

exactly - start with "exceptional" cases and you will soon end coding nothing but ...

And when writing compilers - just like every other projekt - you will want to code as general and easy as possible.

By on 2/6/2009 1:27 AM ()
IntelliFactory Offices Copyright (c) 2011-2012 IntelliFactory. All rights reserved.
Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us | Terms of Use | Privacy Policy | Cookie Policy
Built with WebSharper