tl icon indicating copy to clipboard operation
tl copied to clipboard

Allow record fields to have pre-initialized value.

Open 0komo opened this issue 7 months ago • 9 comments

local record Foo
  name: string = "foo"
  isFoo: boolean = true
  length: number = 3
  getName: function(): string = function()
    return "foo"
  end
end

_ =
  Foo.name      --> foo
, Foo.isFoo     --> true
, Foo.length    --> 3
, Foo.getName   --> function: <address>
, Foo.getName() --> foo

0komo avatar May 11 '25 07:05 0komo

My concern about this is that people might assume that those initializations apply to instances of the Foo type, and not only to Foo's "prototype table".

hishamhm avatar May 12 '25 23:05 hishamhm

maybe with a "static" like keyword that is solved?

Because right now I do agree that it looks like a way to set defaults for instances of Foo.

lenscas avatar May 13 '25 00:05 lenscas

@lenscas I see what you mean. I'm not sure what would be a good word for it, though. static itself is one obvious choice, but that is so overloaded. And then people would most likely like to inline their functions in the record, which would require them mark as static, and then they'd attach the instances with a metatable and then use those functions in a non "static" way.

hishamhm avatar May 13 '25 15:05 hishamhm

Yea, it was just the first thing that came to mind.

lenscas avatar May 15 '25 13:05 lenscas

Here is an example of where I'd love to have this feature to set constant values (I need this all the time):

local record Assets
    MONO: string
end

Assets.MONO = "fonts/mono.png"

mtdowling avatar May 18 '25 04:05 mtdowling

Maybe we could use annotations instead of keywords?

local record Foo
   x <global>: integer
end

Foo.x = 5

The same syntax could be use for the other discusson about optional fields.

Andre-LA avatar May 18 '25 13:05 Andre-LA

Maybe we could use annotations instead of keywords?

local record Foo x : integer end

Foo.x = 5

The same syntax could be use for the other discusson about optional fields.

That also sufficient, and it also fits with the syntax of record field. What do you think about it @hishamhm?

0komo avatar May 18 '25 22:05 0komo

Maybe there could be support for a record "singleton" specifier? local record Foo <const> ...which would allow for its use as a type and for indexing, but not for declarations. Nested records would have to be marked <const> as well.

local record Foo <const>
  x: integer = 1
end

local new_foo: Foo = { -- error: cannot instantiate const record Foo
  x = 2
}

You could use it to create objects within closures:

local function make_foo(x: integer, y: integer): Foo
  local record Foo <const>
    x: integer = x
    y: integer = y
  end

  function Foo:move(x: integer, y: integer)
    self.x = self.x + x
    self.y = self.y + y
  end

  return Foo
end

local new_foo <const> = make_foo(1, 2) -- works!

I don't know if const is the right keyword, as the fields aren't constant, but it isn't too dissimilar from a const * in C. Semantics aside, I think communicating the record as a singleton would be the way to go for in-place assignment.

wu4 avatar May 22 '25 20:05 wu4

I don’t even necessarily think these are consts or static values, but rather just initial values of members. It’d be like this in Lua:

{foo = 10}

If I want that to be const, I suppose I could add <const> just like other Teal values, though not required. Function definitions would work the same way: an initial implementation of the function that’s assigned to the generated table. If you set and __metamethod on another table to make an “instance”, it works exactly how you’d expect.

mtdowling avatar May 22 '25 23:05 mtdowling