#[Solved] Parapoly struct fails type-checking for (personally, unclear) reason

1 messages · Page 1 of 1 (latest)

lavish lance
#

i'm writing a command-line framework (yes, I know Odin has one in the standard library, this is mostly a learning exercise for me :)) and i keep rubbing up against a really weird issue with parapoly and i was wondering if someone could give me some advice on how to handle it.

so basically, the idea for the framework side of things is that I have a Value struct that takes a type parameter of $T: typeid, which is fed into a procedure that parses a string into that type, essentially allowing any type to be defined as a potential value for a command argument. great! it looks like this:

Value :: struct($V: typeid) {
    parse: proc(string) -> (V, bool),
}

i also have a struct called Switch which defines a "flag" in a command-line program. switches are never are by themselves, and should always rely on a Value (even -a with no (visible) argument is actually flipping a boolean variable, so it can be represented as consuming a Value anyway). i try to do this here:

Switch :: struct($T: typeid) {
    long_forms:  []string,
    short_forms: []rune,

    expects:     ^Value(T),
    default_val: T,
}

the reason it's ^Value(T) is because i planned on defining a set of "basic types" in the program, like file_type, that a user could easily reference by passing in a pointer to the initialized Value as like bind_value(&command_node, &cmd.file_type, &target_var) or something.

but, this above struct errors when compiled!

/home/flora/dev/cmd.odin(36:5) Error: Invalid parameter type 
        expects:     ^Value(T), // :(
        ^~~~~~~~~~~~~~~~~~~~~^

every explanation i have for this only makes half-sense to me. like, i think it's doing this because it has to resolve the type parameters at compile-time, and so it fills it as Value(T), but because T on it's own isn't a type outside of the context of the type parameter, it's freaking out. but like... that doesn't actually make a whole lot of sense? if i put in int for $T, wouldn't it be ^Value(int)? @_@

the only problem is... i genuinely don't know how to design around this on a types level? i want to avoid loosening types that should be stricter (i.e. a parameter of typeid itself or god forbid just making it an any) as much as i can manage while writing this, because the types are the major thing upholding some form of "contract" for what can and cannot go into a command's arguments on the framework user's end

any advice on how i could avoid this problem would be appreciated ^^'

mossy fractal
#

What I'm not seeing here, and what's needed for polymorphic types and procedures to be type checked, is how you instantiate (type) or call (proc) them.

You show the error for Switch, but how are you declaring a struct of that type, and are there any other errors?

lavish lance
#

i haven't initialized any structure here yet, could that be the source of the error? just started building this, so i was just defining the structures that i wanted to have in the program before implementing it in the actual parser and things like that ^^

#

there aren't any other errors, what i've written is essentially just what i've shown here

package cmd

Switch :: struct($T: typeid) {
    long_forms:  []string,
    short_forms: []rune,

    expects:     ^Value(T),
    defaults:    T,
}

Value :: struct($V: typeid) {
    parse: proc(string) -> (V, bool),
}

main :: proc() {
    
}
mossy fractal
#

That gives me zero errors, which comes as no surprise to me as neither of these types are used, and polymorphic types and procedures are only type checked when used.

lavish lance
#

huh, interesting.

mossy fractal
#

If I use it, still no error:

main :: proc() {
    s: Switch(int)
    fmt.println(s)
}

Switch($T=int){long_forms = [], short_forms = [], expects = <nil>, defaults = 0}
lavish lance
#

if i use it, the errors go away

bold sorrel
#

can you give the output of odin report?

mossy fractal
#

Sure.

lavish lance
#

sure thing :)

#
    Odin:    dev-2025-06-nightly
    OS:      Ubuntu 25.04, Linux 6.14.0-22-generic
    CPU:     Intel(R) Core(TM) i5-10210U CPU @ 1.60GHz
    RAM:     15192 MiB
    Backend: LLVM 20.1.6
#

(on another note, i thought i clicked "latest release" but... i guess i didn't @_@)

mossy fractal
#

The latest releases package the nightly from the day before the release.

lavish lance
#

ohh

#

okay

mossy fractal
#

At some point we'll create a Release action on the CI to do the monthly release builds so it's reflected in the version string, but that's a low priority.

mossy fractal
lavish lance
#

i will try that

#

ope--no, i don't

#

.........i see what happened. i had two files which were different versions of the same thing (my previous attempt hadn't gone very well, so i was trying to just start again), and both defined a struct called Value

mossy fractal
#

Mystery solved. 🙂

Still, it couldn't hurt to clone the repo and track the latest version more closely. We're on a bug fixing marathon.

lavish lance
#

will do :) thank you! ^^'

#

SOLVED - Parapoly struct fails type-checking for (personally, unclear) reason

mossy fractal
#

[Solved] Parapoly struct fails type-checking for (personally, unclear) reason

lavish lance
#

ope

mossy fractal
#

jinx.