berry icon indicating copy to clipboard operation
berry copied to clipboard

Closed interval maybe a mistake?

Open skiars opened this issue 2 years ago • 9 comments

In my current experience, the expression 0..5 means that [0,1,2,3,4,5] doesn't seem to work as well as [0,1,2,3,4], so the half-closed interval $[a, b)$ might be better?

skiars avatar Feb 10 '23 02:02 skiars

I'm afraid it would be a huge breaking change.

What about the math version: [0..5] for [0,1,2,3,4,5] and [0..5[ for [0,1,2,3,4] (if the syntax is possible)

The other option would be to use the Python equivalent [0:5]

s-hadinger avatar Feb 10 '23 03:02 s-hadinger

Indeed, and I find some interesting uses of range:

> [1, 2, 3, 4][0 .. -1]
[1, 2, 3, 4]
> [1, 2, 3, 4][0 .. 0] # not an empty range
[1]
> [1, 2, 3, 4][0 .. -4]
[1]
> [1, 2, 3, 4][0 .. -5]
[]

skiars avatar Feb 10 '23 07:02 skiars

You could also use Ruby syntax by adding another dot, but i can see how that would be confusing.

> [0..5]
[0,1,2,3,4,5]
> [0...5]
[0,1,2,3,4]

Another idea is having ..= and ..< to be more explicit, but it may look too ugly/verbose

> [0..=5]
[0,1,2,3,4,5]
> [0..<5]
[0,1,2,3,4]

nobodywasishere avatar Oct 09 '23 08:10 nobodywasishere

The other option would be to use the Python equivalent [0:5]

I agree with this.

skiars avatar Oct 09 '23 08:10 skiars

Revisiting some old issues. Are you still in favor of this syntax for excluded last value?

s-hadinger avatar Apr 17 '24 08:04 s-hadinger

I'm just a casual observer who thinks Berry is really neat, but IMHO Python's a[start:stop:step] slice syntax strikes a nice balance between expressiveness and complexity. Especially with support for negative numbers.

bartgrantham avatar Dec 09 '24 09:12 bartgrantham

This may be possible. Considering:

# if operator : has the following rules:
a : b # => range(a, b) if `a`, `b` is integer
a : b # => range(a.lower(), a.upper(), b) if `a` is a range, then update its step!

# examples:
1 : 10 : 2 # => range(1, 10, 2)

skiars avatar Dec 11 '24 02:12 skiars

Revisiting some old issues. Are you still in favor of this syntax for excluded last value?

It doesn't seem like a big deal?

skiars avatar Dec 11 '24 02:12 skiars

My main concern is still with loops. The majority of the loops in my code is the following:

var l
# populate l
for idx: 0..size(l)-1
  # do something
end

This compiles as follows:

; line 2
  0000  LDNIL	R0
; line 4
  0001  GETGBL	R1	G16
  0002  GETGBL	R2	G12
  0003  MOVE	R3	R0
  0004  CALL	R2	1
  0005  SUB	R2	R2	K1
  0006  CONNECT	R2	K0	R2
  0007  CALL	R1	1
  0008  EXBLK	0	#000C
  0009  MOVE	R2	R1
  000A  CALL	R2	0
  000B  JMP		#0009
  000C  LDCONST	R1	K2
  000D  CATCH	R1	1	0
  000E  RAISE	2	R0	R0
; line 6
  000F  RET	0

The main problems are:

  • CONNECT creates a temporary range() object that is later garbage collected
  • the loop exits with an exception, which is a heavy construct

I understand that using an iterator and an instance solves the general case, but I end up often writing the following instead:

var l
# populate l
var idx = 0
while idx < size(l)
  # do something
  idx += 1
end

The compiled code is much shorter and faster:

; line 3
  0000  LDNIL	R0
; line 5
  0001  LDCONST	R1	K0
; line 6
  0002  GETGBL	R2	G12
  0003  MOVE	R3	R0
  0004  CALL	R2	1
  0005  LT	R2	R1	R2
  0006  JMPF	R2	#0009
; line 8
  0007  ADD	R1	R1	K1
  0008  JMP		#0002
; line 9
  0009  RET	0

Hence I would be in favor of doing a alternative construct for simple loops with 1 increments:

var l
# populate l
for idx: 0:size(l)
  # do something
end

I'm also concerned by the readbility especially if you don't add a space: for idx:0:size(l) would be hard to read.

Any thoughts or alternative syntax?

s-hadinger avatar Mar 04 '25 12:03 s-hadinger