4

I would like to able to define a static variable inside a Julia struct. E.g I would like to define something along the lines of:

mutable struct MyStruct
  global const a = 1
  b = 2
end

Then I would like to be able to access a, in a similar fashion to static constants in the Java or C++ languages, e.g:

MyStruct.a

I am very well aware that this way of writing code is not-Julian, and that I just could use a module for this purpose.

However, I am interested in whether it is possible or not for mutable structs. E.g I am interested in in details why this is not possible and techniques to emulate this pattern of programming.

JKRT
  • 1,179
  • 12
  • 25
  • As I said in my answer, the reason why Julia doesn't let you emulate this OOP patern is that it's an unfortunate result of OOP. Static variables aren't naturally part of a struct, so why would you put them there? – Oscar Smith Aug 17 '19 at 15:39
  • As stated in my question. This not about the proper way of writing Julia, rather it is similar to https://stackoverflow.com/questions/39133424/how-to-create-a-single-dispatch-object-oriented-class-in-julia-that-behaves-l albeit more specialized. Regarding if they are a part of a struct or not it is in a sense dependent on the language. For instance in C++ the syntax I wrote above would be allowed. – JKRT Aug 17 '19 at 16:25

3 Answers3

3

(edit since you asked for something that does not require an instance of the struct)

Another way to do this is:

julia> mutable struct MyStruct b::Int end

julia> a(::Type{MyStruct}) = 1
a (generic function with 1 method)

julia> a(MyStruct)
1

which is accessed as a(Mystruct) instead of MyStruct.a

============================================================ (first answer):

You will need one more struct, and the syntax would be x.a.a not x.a:

julia> struct A
   a::Int
   end

julia> A() = A(1)
A

julia> s = A()
A(1)

julia> s.a
1

julia> mutable struct MyStruct
   a::A
   b::Int
   end

julia> MyStruct(b) = MyStruct(A(), b)
MyStruct

julia> c = MyStruct(3)
MyStruct(A(1), 3)

julia> c.a.a
1

julia> c.a.a = 5
ERROR: type A is immutable
Bill
  • 5,600
  • 15
  • 27
  • I get that you get the same behavior this way (Sharing of constants). To get similar syntax as in Java/C++ we would need to define a macro as there is no syntactic sugar? – JKRT Aug 13 '19 at 10:00
  • In general there is no need to have a static variable for a class. You get similar behavior with a function taking a struct instance such as static_a(::MyStruct) = 1; without the extra slot in the structure. But you wanted the syntax to imitate another language, so yes a macro might be needed for the imitative syntax if you required it. – Bill Aug 13 '19 at 18:58
  • The issue with the updated example is that the static value has no relation to the actual field b right? – JKRT Aug 17 '19 at 16:27
1

Not sure exactly what you want, but

mutable struct MyStruct end

Base.getproperty(s::MyStruct, sym::Symbol) = (sym==:a ? 1 : getfield(s, sym))

julia> m = MyStruct()

julia> m.a
1

julia> m.a = 2
ERROR: type MyStruct has no field a
Stacktrace:
 [1] setproperty!(::MyStruct, ::Symbol, ::Int64) at ./Base.jl:21
 [2] top-level scope at REPL[18]:1

Or you can type MyStruct().a

You could also overload setproperty! to provide a more informative error message.

DNF
  • 11,584
  • 1
  • 26
  • 40
  • This is neater and does not require an extra struct due to the getProperty overload. Still, it does require object creation each time I would want to access my static member? – JKRT Aug 13 '19 at 10:48
  • Yes it does. Julia doesn't have classes that can behave like this. Maybe there's some other way, but not that uses types, I think. – DNF Aug 13 '19 at 10:50
0

I think the answer you are actually looking for is a const variable outside of a struct. The reason static variables exist in OOP languages is that sometimes you want a variable that isn't connected to an instance of a class. In Julia, you can do that just by using a variable.

const a = 1
mutable struct Mystruct
    b::Int
end

will provide the functionality you want. It won't look object oriented, because that isn't how Julia is designed.

Oscar Smith
  • 5,766
  • 1
  • 20
  • 34