Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optional in the type system #5164

Open
FloVanGH opened this issue May 2, 2024 · 5 comments
Open

Optional in the type system #5164

FloVanGH opened this issue May 2, 2024 · 5 comments
Labels
a:language-slint Compiler for the .slint language (mO,bF) rfc Request for comments: proposals for changes

Comments

@FloVanGH
Copy link
Member

FloVanGH commented May 2, 2024

We should have a type that represent an optional type.
Syntax could be something like int? or ?int or option<int> or optional<int>

Original comment: Introduce undefined values for properties and struct fields

I have the following use case:

export struct Style {
    border-radius: length,
    border-top-left-radius: length,
    background: brush
}

component StyledRectangle {
      in property <Style> style;
      
      Rectangle {
            background: style.background;
            border-radius: style.border-radius;
            border-top-left-radius: style.border-top-left-radius;
      }
}

export component MyExample inherits Window {
      width: 600px;
      height: 400px;
      
      StyledRectangle {
            style: {
                  background: #000000;
                  border-top-left-radius: 8px;
            }
      }
}

The following example does not work as expected, because the top left border radius of inner Rectangle will not be rendered with 8px but instead with 0. The problem is, that if the border-radius field on Style is not explicit set it will defaults to 0 and it overwrites the setting of border-top-left-radius. What could help to solve this problem is to introduce undefined for values and use this as default e.g. for border-radius instead of 0, so that is handled like there is no value set on the property border-radius.

@FloVanGH FloVanGH added a:language-slint Compiler for the .slint language (mO,bF) rfc Request for comments: proposals for changes labels May 2, 2024
@ogoffart
Copy link
Member

ogoffart commented May 8, 2024

We could have default value for struct like propose in #2936 , you could do something like:

export struct Style {
    border-radius: length,
    border-top-left-radius: length = -1px,
    background: brush
}

component StyledRectangle {
      in property <Style> style;
      
      Rectangle {
            background: style.background;
            border-radius: style.border-radius;
            border-top-left-radius: style.border-top-left-radius >= 0 ? style.border-top-left-radius : style.border-radius;
      }
}

export component MyExample inherits Window {
      width: 600px;
      height: 400px;
      
      StyledRectangle {
            style: {
                  background: #000000;
                  border-top-left-radius: 8px;
            }
      }
}

But in general, we might want to have option<...> types.

@FloVanGH
Copy link
Member Author

FloVanGH commented May 8, 2024

border-top-left-radius: style.border-top-left-radius >= 0 ? style.border-top-left-radius : style.border-radius;

I think from user perspective that looks more like a workaround. As user I want to do something like on the Rectangle directly, if I do not define a value for border-radius it should be ignored and it should not override values like border-top-left-radius.

@ogoffart
Copy link
Member

ogoffart commented May 8, 2024

Right, for the general case, we would need to introduced a new type like option<length> or length? or something like that.
Somehow related: #615

@ogoffart ogoffart changed the title Introduce undefined values for properties and struct fields Optional in the type system Sep 16, 2024
@tronical
Copy link
Member

If we had say option like this:

property <option<length>> maybe-length;

We could either do it like typescript and say the compiler requires an earlier check:

clicked => {
    width = self.maybe-length; // ERROR
    if (self.maybe-length) {
        width = self.maybe-length; // OK, control-flow before reaching this checks if value is not none
    }
}

or we could have Rust like syntax:

clicked => {
    width = self.maybe-length; // ERROR
    if let Some(length) = self.maybe-length {
        width = length;
    }
}

but this requires the introduction of local variables....

@ogoffart
Copy link
Member

I think the typescript approach is fine.

We can also make it work with || so that self.maybe-length || 0 works.
And other operators such as ?.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
a:language-slint Compiler for the .slint language (mO,bF) rfc Request for comments: proposals for changes
Projects
None yet
Development

No branches or pull requests

3 participants