dotnet / vblang

The home for design of the Visual Basic .NET programming language and runtime library.
289 stars 65 forks source link

[Proposal] Add support for ranges #418

Open Berrysoft opened 5 years ago

Berrysoft commented 5 years ago

As C# is going to support ranges in 8.0, I think Visual Basic should also support it. Considering the old grammer to declare array in VB6, we can support ranges like:

Dim s = "Hello!"
Dim c1 = s(1) ' c1 = "e"c
Dim c2 = s(^2) ' c2 = "o"c, the `^` indicates it counts from the end
Dim s1 = s(2 To 3) ' s1 = "ll"
Dim s2 = s(2 To ^3) ' s2 = "ll"

I chose - instead of ^ at first, but then I changed my mind because the original indexer accepts Integer.

pricerc commented 5 years ago

I chose - instead of ^ at first, but then I changed my mind because the original indexer accepts Integer.

I was going to ask you to expand on that, because when I see ^, I see XOR. But then I looked at the examples again, and I realised that:

Dim s2 = s(2 To -3) 

would look like "Give me 2, 1, 0, -1, -2, -3"

Still not sure about using the caret (or 'hat' as the C# proposal calls it), but is probably less likely to cause confusion than the minus sign.

Otherwise, I can see the value.

Berrysoft commented 5 years ago

Then how about to put minus sign after the number?

Dim c2 = s(2-)
Dim s2 = s(2 To 3-)
pricerc commented 5 years ago

Then how about to put minus sign after the number?

hmm. Maybe, although it looks like there's something forgotten after the minus sign.

I'm sure the C# peeps thought this all through, the caret is probably fine; I don't think there are that many people like me who associate it with XOR :)

Berrysoft commented 5 years ago

Maybe we should wait for others' ideas.😀

AdamSpeight2008 commented 5 years ago

To me we already have the making of a range expression, in the current syntax. That of expr To expr (Step expr)? which is from the inside of a For Loop statement. Which would follow similar semantic rules.

We just need a little additional syntax to handle;=

Clusive Ranges

Clusivity   ::= Inclusive | Exclusive ; 
Inclusive   ::= "In" ; 
Exclusice   ::= "Ex" ;
ClusiveExpr ::= Clusivity? Expr ; ' If clusivity is missing, default to inclusive.
StepExpr    ::= "Step" Expr ;
ToExpr      ::= "To" ClusiveExpr ;
RangeExpr   ::= ClusiveExpr ToExpr StepExpr? ;
Dim IncIncRange0 = first To last
Dim IncIncRange1 = first To In last
Dim IncIncRange2 = In first To last
Dim IncIncRange3 = In First To In last

Dim IncExcRange  = first To Ex last
Dim ExcIncRange  = Ex first To last
Dim ExcExcRange  = Ex first To Ex last
Berrysoft commented 5 years ago

We can simply perform exclusive by +1 and -1:

Dim ExcIncRange = first + 1 To last
Dim ExcExcRange = first + 1 To last - 1

and from start/end range can be written like:

Dim FromStartRange = 0 To last
Dim FromEndRange = ^last To ^1
AdamSpeight2008 commented 5 years ago

@Berrysoft Rather than stating the range must of the form (Inclusive , Inclusive). I'd prefer that I have the choice to explicitly specify them, by allowing the "range" type encode the clusivity into itself. Rather that than adding / subtracting some offset.

If index <>  Inc 0 To Ex items.Length Then
 ' Out of range
End If

What if the range is return from a function call, it would good the have clusivity information at the call stie.

Function F() As Range
 Return In start To Ex finish Step step
End Function

Especially when debugging hover over a range variable, would be possible to display bound clusivity.

[ start .. finish ) step needs work

Berrysoft commented 5 years ago

@AdamSpeight2008 But the For loop in VB states the range must of the form of both inclusive. I think ranges in VB may be better to behave the same as the old statements. Also, the type System.Range doesn't support steps now, therefore Step in ranges may be difficult to implement. In addition, the System.Range doesn't overload operator =, and you can't compare two ranges.

AdamSpeight2008 commented 5 years ago

@Berrysoft I know that. Ranges are not restrict to For loops, I borrowing it's syntax as it is a known "range" like syntax that currently in use. I am abstracting out the notion of range into it's own form, so it can be used elsewhere.

Berrysoft commented 5 years ago

@AdamSpeight2008 You're right, though I don't like to add new keywords...I prefer a simple proposal in order to make it more possible for LDM to approve, but we can continue discussing.😄 If we should support inclusive and exculsive, I'd rather like the representation in math, like (first, last), (first, last], [first, last), [first, last], and [first,) & (, last] for from start/end ranges.

AdamSpeight2008 commented 5 years ago

@Berrysoft #80 ?

Berrysoft commented 5 years ago

@AdamSpeight2008 That sounds more complicated. I originally want a syntax sugar for New Range(New Index(1), New Index(3, True)), so I want it simple, and VB'ish looking.

pricerc commented 5 years ago

I'd rather like the representation in math, like (first, last), (first, last], [first, last), [first, last], and [first,) & (, last] for from start/end ranges.

That messes with my OCD - brackets. must. match. :P

Berrysoft commented 5 years ago

That messes with my OCD - brackets. must. match. :P

Maybe that's why most languages doesn't use this syntax - the praser suffers.😄

rrvenki commented 5 years ago

@Berrysoft how about using "~" instead of "^"? Does it overlap with any other functionality? Or can "/" be used otherwise? Because I like the functionality you have given.

pricerc commented 5 years ago

@rrvenki whatever gets used, there will be someone who won't like it 😃

So on that basis, I'm tempted to recommend just doing what the C# team did. But then I slap myself and realise that whatever they've done VB could probably do better 😛

Berrysoft commented 5 years ago

@Berrysoft how about using "~" instead of "^"? Does it overlap with any other functionality? Or can "/" be used otherwise? Because I like the functionality you have given.

@rrvenki I like ~, but considering that someone sees ^ as XOR, he/she may see ~ as NOT😜. Maybe ~ is a better idea, because VB haven't use it in any cases yet. (^ has been used for power)

AdamSpeight2008 commented 5 years ago

I hate it when I think a feature is in VB.net, when you try it out but you get errors because it is VB6 code. Dim Sign( -1 To 1) As String So wanting to write Dim Sign(-1 To 1) From { "Negative", "Zero", "Positive"} Or ReDim Sign( 0 To 2 )

pricerc commented 5 years ago

I hate it when I think a feature is in VB.net, when you try it out but you get errors because it is VB6 code. Dim Sign( -1 To 1) As String So wanting to write Dim Sign(-1 To 1) From { "Negative", "Zero", "Positive"} Or ReDim Sign( 0 To 2 )

LOL.

I always felt that it was a 'regression' that VB lost arrays with arbitrary dimension bounds instead of just (0..n). I get it was to make it easier to work with the arrays of other languages, but it was a loss for high-level programmers.

That could actually be a useful thing to resurrect: arrays with arbitrary bounds. I would think that it wouldn't need to be a very fat wrapper around a standard array.

pricerc commented 5 years ago

Would braces or brackets be a better choice (and by better, I mean easier for humans and compilers to parse) than parentheses ?

Braces would be consistent with 'set notation', arrays and initialisers; knowing whether to parsing {1 to 10} or {1,2,3,4} should be 'easy enough' to figure out.

Brackets are currently only used (as far as I know) for 'quoting' identifiers, so are a potential candidate.

edit: 'twas a dumb question.

Berrysoft commented 5 years ago

Actually I didn't propose to use parentheses, it's only the syntax of indexer. I think To is enough to represent a range.

pricerc commented 5 years ago

Actually I didn't propose to use parentheses, it's only the syntax of indexer. I think To is enough to represent a range.

Sure enough, you didn't, I was just seeing things that weren't there. A good example of why you should never post things in haste without thinking them through fully!

As you were.

I was thinking about the range on its own, not a range of somethings, I think #25 is more the scenario I'm thinking of

Berrysoft commented 5 years ago

I was thinking about the range on its own, ...

I think it is much more simple to write Dim myRange = 1 To 100.

pricerc commented 5 years ago

I was thinking about the range on its own, ...

I think it is much more simple to write Dim myRange = 1 To 100.

That's fine, but inside a query isn't so pretty, it gets a bit lost.

    Dim qx = 
    <div>
        <%= From i In 1 To 10 Select <item ref=<%= $"{i}" %> /> %>
    </div>

Actually, is this really a different discussion than #25, or are they two sides of the same polyhedron?

Berrysoft commented 5 years ago

If you want it clearer, just put parentheses to ensure the priority like From i In (1 To 10). It doesn't need new grammer, I think. If you write {1 To 10}, I would consider it as an array of System.Range with one element.

pricerc commented 5 years ago

If you want it clearer, just put parentheses to ensure the priority like From i In (1 To 10). It doesn't need new grammer, I think. If you write {1 To 10}, I would consider it as an array of System.Range with one element.

Fair point. Works for me.