umka-lang icon indicating copy to clipboard operation
umka-lang copied to clipboard

Inferring constant list instantiation size

Open ske2004 opened this issue 3 years ago • 6 comments

type (
        Prs* = struct {
                name: str
                image: str
                font: str
                imageY: int
        } 
)

const people = []Prs{
        Prs{"triangle" , "faces.png", "data/font.ttf", 0},
        Prs{"rectangle", "faces.png", "data/font.ttf", 1},
        Prs{"star"     , "faces.png", "data/font.ttf", 2},
        Prs{"circle"   , "faces.png", "data/font.ttf", 3}}

This code will result in an error "Dynamic array literals are not allowed for constants". It would be rather convenient if the size could be calculated by itself, since it's known at compile time.

ske2004 avatar May 20 '22 07:05 ske2004

@skejeton Please clarify the issue. Which of these options do you mean?

Option 1. Static array literals with inferred size. This is what the issue title implies. Something like Go's [...]string{"Sat", "Sun"} notation. Applies to both const and non-const arrays. Quite easy to implement.

Option 2. Constant dynamic array literals. This is what your code example implies. Very hard to implement, since a dynamic array cannot be constructed at compile time.

If you strongly need a dynamic array now, you can construct it from a static array:

const peopleList = [4]Prs{
        Prs{"triangle" , "faces.png", "data/font.ttf", 0},
        Prs{"rectangle", "faces.png", "data/font.ttf", 1},
        Prs{"star"     , "faces.png", "data/font.ttf", 2},
        Prs{"circle"   , "faces.png", "data/font.ttf", 3}}

var people: []Prs
        
fn main() {
        people = peopleList
}

Or, you can construct a non-const dynamic array literal inside a function:

var people: []Prs

fn main() {
    people = []Prs{
        Prs{"triangle" , "faces.png", "data/font.ttf", 0},
        Prs{"rectangle", "faces.png", "data/font.ttf", 1},
        Prs{"star"     , "faces.png", "data/font.ttf", 2},
        Prs{"circle"   , "faces.png", "data/font.ttf", 3}}
}

vtereshkov avatar May 20 '22 10:05 vtereshkov

Yes static is enough (Option 1) I don't see how my code implies dynamic initialization though

ske2004 avatar May 20 '22 10:05 ske2004

@skejeton In your code, you are trying to construct a const dynamic array literal ([]Prs). That means that the program must allocate 1) a control block (possibly in the static storage), 2) a data block (in the heap). The latter cannot be done without executing some code.

vtereshkov avatar May 20 '22 11:05 vtereshkov

[]Prs seems like a syntactic thing to me, I don't mind using other syntax

ske2004 avatar May 20 '22 18:05 ske2004

@skejeton No, that's not just syntax. In Go, [3]int{1, 2, 3} is an array literal, [...]int{1, 2, 3} is an array literal with an inferred length, and []int{1, 2, 3} is a slice literal. A slice is not an array.

Though Umka's dynamic arrays are not fully equivalent to Go's slices, they are quite similar to them, so that the distinction between a static array and a dynamic array is still important.

As I said before, a dynamic array requires a control block and a data block, the latter being allocated in the heap. A static array is just a data block allocated anywhere.

vtereshkov avatar May 20 '22 20:05 vtereshkov

Bumping this again here, I'm aware that semantics here are different, because you can't append to a static array, but any kind of syntax for inferring the array length would be better than nothing. I think this is a nice feature overall. If we can append to [3]int{1, 2, 3}, then it's just a matter of syntax.

ske2004 avatar Jun 22 '23 12:06 ske2004