M
Modular•3mo ago
banananas

"Linking" structs together?

I'm not talking about inheritance from other structs, but is there a way to refer to other structs as well when referring to one of them? For example:
var thing = MyStruct()
var other_thing = MyOtherStruct()
var list_of_things = List[MyStruct](thing, other_thing) # this is valid code since MyOtherStruct is linked to MyStruct
var thing = MyStruct()
var other_thing = MyOtherStruct()
var list_of_things = List[MyStruct](thing, other_thing) # this is valid code since MyOtherStruct is linked to MyStruct
21 Replies
ModularBot
ModularBot•3mo ago
Congrats @banananas, you just advanced to level 2!
sb
sb•3mo ago
Not entirely sure what this is trying to do Is this wanting MyOtherStruct to "act like" a MyStruct? Like using duck typing or something?
banananas
banananasOP•3mo ago
Well, rn i'm only trying to get a list with one struct as a parameter to be able to have other structs inside the list, if that makes sense
sb
sb•3mo ago
uh, hm so do you want a list of basically multiple different types of structs? [MyStruct(), MyOtherStruct()] style thing?
banananas
banananasOP•3mo ago
Yeah but without defining all of the possible structs in params because there's going to be a lot of them
sb
sb•3mo ago
that pattern isn't really supported at the moment afaik it requires either inheritance/trait objects or some form of duck typing which..........is hard to do with compiled languages :) I've tried, it gets nasty pretty quickly
banananas
banananasOP•3mo ago
Hmm alright i'll see if there's a way around it maybe
sb
sb•3mo ago
What's the "goal" if you don't mind me asking?
ModularBot
ModularBot•3mo ago
Congrats @Sawyer Bergeron, you just advanced to level 14!
banananas
banananasOP•3mo ago
I'm trying to create a (rn pretty janky) ECS-like system and i'm thinking of storing the component structs in an array probably a better way of doing it tbh
sb
sb•3mo ago
oh 🫠 yeah, ECS may be a tad difficult with things the way they are I think trait objects are pretty much exactly what you're hoping for You could batch by entity type and do a branch and call, which may enable additional optimizations, but.... yeah, that's a bit of a pain point at the moment
banananas
banananasOP•3mo ago
Yeah true hopefully i'll figure smth out
sb
sb•3mo ago
I think you might be able to do something dubious with object maybe, but it would be very far from anything "performant" you'd be doing dynamic lookups for every single entity interaction, which are very expensive in this kind of scenario
banananas
banananasOP•3mo ago
Yeah that could be a bit of a problem as well
sb
sb•3mo ago
You could do a signal based system ig with like broadcast channels, but that also gets kinda messy and may have a relatively large perf hit lemme check if we really don't have trait objects yet, we might or it might be really soon in the pipeline
capt_falamer
capt_falamer•3mo ago
Does the list have to be ordered in relation to other types of objects? Thinking you might get away with struct with a list for each type
banananas
banananasOP•3mo ago
Actually i think i might have found a "solution"
bpr
bpr•3mo ago
from utils.variant import Variant

@value
struct MyStruct(CollectionElement):
var name: String
fn __str__(self) -> String:
return self.name

@value
struct MyOtherStruct(CollectionElement):
var id: Int64
fn __str__(self) -> String:
return str(self.id)

alias MyObject = Variant[MyStruct, MyOtherStruct]

def main():
var list = List[MyObject]()
list.append(MyObject(MyStruct("Brian")))
list.append(MyObject(MyOtherStruct(23)))

for i in range(len(list)):
v = list[i]
if v.isa[MyStruct](): print(str(v[MyStruct]))
if v.isa[MyOtherStruct](): print(str(v[MyOtherStruct]))
from utils.variant import Variant

@value
struct MyStruct(CollectionElement):
var name: String
fn __str__(self) -> String:
return self.name

@value
struct MyOtherStruct(CollectionElement):
var id: Int64
fn __str__(self) -> String:
return str(self.id)

alias MyObject = Variant[MyStruct, MyOtherStruct]

def main():
var list = List[MyObject]()
list.append(MyObject(MyStruct("Brian")))
list.append(MyObject(MyOtherStruct(23)))

for i in range(len(list)):
v = list[i]
if v.isa[MyStruct](): print(str(v[MyStruct]))
if v.isa[MyOtherStruct](): print(str(v[MyOtherStruct]))
If Mojo had enums like Rust, that solution would be nicer.
Nick!
Nick!•3mo ago
(Mojo doesn't need enums for that to be nicer. It just needs a refined version of Variant, plus support for the sugar MyStruct|MyOtherStruct.)
bpr
bpr•3mo ago
Show me what you mean. Please rewrite that code with your refined version of variant and your union type sugar. I find Mojo's Variant unwieldy even compared to Nim's object variant and Ada's variant records. In those, you have a tag field to discriminate the cases rather than some generic type. If that's the refinement you have in mind, that and the addition of Python 3.10+ match-case construct would go a long way to making it look better in my eyes.
Nick!
Nick!•3mo ago
I'm talking about a hypothetical future version of Variant. I haven't completed a design for that. Basically you can always replace a sum type declaration with an alias, e.g. alias Error = Variant[Error1, Error2, Error3]. But we need to upgrade the UX of Variant so that it matches sum types. (Also I think Variant should be renamed to Tagged, since it's meant to be a tagged union.)
Want results from more Discord servers?
Add your server