1

I have a mutable structure in Julia

@with_kw mutable struct Param
x::Float64 = 0.1
y::Float64 = 1/x
end

Now I want to change x to 0.2, so I set para = Param() and para.x = 0.2. However, para.y does not change. But what I want is to change y automatically, is there any way in Julia to do this?

Ken White
  • 123,280
  • 14
  • 225
  • 444
jgr
  • 125
  • 4

2 Answers2

1

You are specifying the default value for a parameter, not an algorithmic relationship. If y is always supposed to be calculated like that and never set on it's own you can define

y(p::Param) = 1/p.x
vchuravy
  • 1,208
  • 10
  • 22
  • I see, thanks for the explanation. Just want to confirm, I can not define `y(p::Param) = 1/p.x` inside the structure, and can only do this after the structure is defined, right? – jgr Dec 01 '22 at 16:07
1

For now, Julia isn't so flexible in updating attributes based on other ones. But, gladfully, it's possible to simulate the expected behavior. For this, you need to define a custom getproperty function. Suppose I have defined a mutable composite type as follows:

julia> Base.@kwdef mutable struct Param
           x::Float64=0.1
       end
Param

Now I want to settle the situation to simulate the expected behavior. For this, I go for defining a custom getproperty function specifically for Param:

julia> function Base.getproperty(the_type::Param, prop::Symbol)
           if prop == :y
               return 1/the_type.x
           end
           return getfield(the_type, prop)
       end

Now I create an instance of type Param holding the default value:

julia> instance = Param()
Param(0.1)

The output shows just the value of one field (x). But meanwhile, we can have the y property as we defined our custom getproperty function recently:

julia> instance.y
10.0

Now let's update the x field and observe if the y field gets updated automatically or not:

julia> instance.x = 0.2
0.2

julia> instance.y
5.0

Yes, it does!


Further setting

But still, I can't utilize the autocomplete ability of the REPL by hitting the Tab key to write instance.y. For this, I can define a custom propertynames function specifically for my composite type Param:

julia> Base.propertynames(the_type::Param) = (:x, :y)

julia> instance. #Hit Tab
x  y

Now I can benefit from the autocomplete option in the REPL for y as well.

Shayan
  • 5,165
  • 4
  • 16
  • 45