#77Recursive types should be allowed in some cases

  • avatar~lino-levancommented · 2 years ago
    Author

    Not sure if they should always be allowed, or if there has to be a "terminating condition" or something. This is pretty critical to any interesting types so I would consider this pretty high priority.

    Repro:

    struct Element {
        type: string,
        children: []Element
    }
    

    Current behavior:

     ✘ error: type dependency loop (TODO: explain this better, consider using less inferred return types)
     ┬ /Users/linolevan/Desktop/language-0.1.5/demo.wl:3:17
    3│ children: []Element
     ╰─────────────━━━━━━━
    

    Expected behavior: It just works :tm:


    Milestone: 0.3.0.

  • avatar~lino-levan changed the status to Todo · 2 years ago
  • avatar~clovercommented · 2 years ago
    Owner

    What you have is allowed because arrays are likely going to be a sort of reference type (need to decide on copy semantics, currently has no issue)

    What wont be allowed is

    struct Element {
        type: string,
        parent: Element,
    }
    

    Since it has infinite "size" (not really relevant in JS backend). References solve this (not relevant in JS since every object is a heap pointer, but it's the semantics that matter)

    struct Element {
        type: string,
        parent: &Element,
    }
    

    (also need an issue for references, syntax may be &mut or &const or whatever is decided on; that's not for this issue)

  • avatar~clovercommented · 2 years ago
    Owner

    recursive decls right now are extremely half baked and it's honestly a hack. i hope this gets better after the sema rewrite (#44)

  • avatar~clovercommented · 2 years ago
    Owner

    i think the plan will be to add a third form of analysis unit that reifies the field values of a struct. this way analysis that defines a struct can get a Value without fully setting up it's fields. however, im very hesitant to add more node types.

    another idea is to make it still lazy, but still reified at some point during the declaration's analysis.

  • avatar~jeff-hykincommented · 2 years ago

    Wouldn't recursive types need to be optional or pointers? I suppose arrays are optional in a way 🤔

    References solve this

    Are references nullable?

  • avatar~clovercommented · 2 years ago
    Owner

    Wouldn't recursive types need to be optional or pointers?

    • optional does not break the recursion chain
    • pointers are essentially going to be what is referred to in this language as

    Are references nullable?

    not by default, you would have to combine it with an optional to make it "nullable", but this language wont have a value called null to distance ourselves from JavaScript's null; these will be called optionals, using void (possibly renamed in #102) as the "None" / "Null" / "Missing" state.

    i think the plan will be to

    This more and more feels like a good plan. I am slightly worried about adding a third variant to AnalysisUnit, but it is probably just what we need.

  • avatar~jeff-hykincommented · 2 years ago

    pointers are essentially going to be what is referred to in this language as

    (I'll assume you were going to finish that with "references")

    but this language wont have a value called null

    😬 this makes me nervous. So theres going to be null, undefined, (js) AND None (WL)?

    Ex:

    var a : int | none = 5;
    a = none;
    
  • avatar~jeff-hykincommented · 2 years ago

    Not to make things too painful too quickly, but there is also a case of mutually recursive types 😕

    // func needs expression
    struct FunctionAST {
        String name,
        ParametersAST parameters,
        []ExpressionAST body,
    }
    // expression needs func
    struct ExpressionAST {
         NumberLiteral | IfAST | FunctionAST content,
    }
    
  • avatar~lino-levancommented · 2 years ago
    Author

    None makes sense. I do really like rust's Some/None setup.

    😬 this makes me nervous. So theres going to be null, undefined, (js) AND None (WL)?

    I'd hope that it looks like

    var a : Optional<int> = Some(5); // maybe dave has an opinion on this
    a = None;
    

    or

    var a: ?int = Some(5); // maybe dave has an opinion on this
    a = None;
    

    Though in reality I think dave is gonna try and push for

    var a: ?int = 5;
    a = None;