Primary constructor

struct St[T: AnyType]{
# Declares both fields a and b.
  var a: T,
  var b: T
}
# Use here something like @ or params, idk
@(
# Doesn't declare a field. It are regular parameter to be used inside the struct block
  p1: Int,
  p2: Int
)(Copyable):
  var field_non_instantiable_initialized: Int = 4
  var c: Int = p1 + p2
  var d: Int = c + field_non_instantiable_initialized

# I don't know how exactly would be declared get and set in languages like Mojo and Python, so, please overlook it.
  var e: Int = block:
    get: c + field_non_instantiable_initialized
    set: c = newValue
    # or
    set(newC): c = newC

# accessible only inside the struct
  priv var f: p1 + 5

def main():
  var st: St = St[String]{a = "a", b = "b"}(p1 = 1, p2 = 2)

  print(st.p1) # error, p1 is not a field

  print(st.f) # error, f is private

  print(st.field_non_instantiable_initialized) # prints 4

  print(st.c) # access c, which is p1 + p2, in this case: 3

  print(st.d) # access d, which is c + field_non_instantiable_initialized
, in this case: 7

  print(st.e) # access e, which is c + field_non_instantiable_initialized, in this case: 7

  st.c = 6

  print(st.d) # continues being 7

  print(st.e) # now is 10

References:

“Primary constructors” are a cool feature, but are just “syntactic sugar”. These aren’t things we’ve had time to fully consider and are not something that is a priority unless unambiguous. That said, we do have initializer lists which serve the same purpose, try them out!