[julia]syntax: invalid assignment location "getproperty(f, n)"

Viewed 57

My julia version is 1.7.1.
These code can recurrent my problem:

struct Foo1
    sixsix
    aa
    bb
    disposion
end

struct Foo2
    aa
    bb
end

function Base.:+(f1::Foo1, f2 :: Foo2)
    newf = f1
    for n in fieldnames(typeof(f2))
        getproperty(newf, n) += getproperty(f2, n)
    end
    return newf
end

returned LoadError: syntax: invalid assignment location "getproperty(newf, n)"
same LoadError happened when I try to use getfield:

function Base.:+(f1::Foo1, f2 :: Foo2)
    newf = f1
    for n in fieldnames(typeof(f2))
        getfield(newf, n) += getfield(f2, n)
    end
    return newf
end
2 Answers

I would rather recommend you to do the following:

Base.:+(f1::Foo1, f2 :: Foo2) =
    Foo1(f1.sixsix, f1.aa+f2.aa, f1.bb+f2.bb, f1.disposion)

Your code is wrong for the following reasons:

  1. Foo1 is not mutable, so you cannot change values of its elements
  2. to set a field of mutable struct (which your struct is not) you use setfield!
  3. You mix properties and fields of a struct which are not the same.
  4. fieldnames works on types not on instances of type.

If you wanted to be more fancy and do automatic detection of matching fields you could do:

Base.:+(f1::Foo1, f2 :: Foo2) =
    Foo1((n in fieldnames(Foo2) ?
          getfield(f1, n) + getfield(f2, n) :
          getfield(f1, n) for n in fieldnames(Foo1))...)

However, I would not recommend it, as I feel that it is overly complicated.

Firstly, you must make your structs mutable for this to work.

Secondly, this:

getproperty(newf, n) += getproperty(f2, n)

is expanded into

getproperty(newf, n) = getproperty(newf, n) + getproperty(f2, n)

In other words you are apparently trying to assign a value into a function call. In Julia you can only assign to variables, not to values. The only thing this syntax is allowed for is function definition. From the manual:

There is a second, more terse syntax for defining a function in Julia. The traditional function declaration syntax demonstrated above is equivalent to the following compact "assignment form":

julia> f(x,y) = x + y

f (generic function with 1 method)

So the syntax you are using doesn't do what you want, and what you want to do is not possible anyway, since you can only assign to variables, not to values.

What you are trying to do can be achieved like this (assuming n is a Symbol):

setfield!(newf, n, getfield(newf, n) + getfield(f2, n))
Related