How to define a function negation?

For example,

julia> f(::Int) = [1, 1]
f (generic function with 1 method)

Now I want to define the negation function of f:

julia> (!f)(::Int) = 2
ERROR: syntax: invalid function name "!(f)"
Stacktrace:
 [1] top-level scope at REPL[6]:1

However, this is not a valid syntax.

julia> f(x) = [x,x]
f (generic function with 1 method)

julia> Base.:!(::typeof(f)) = x -> f(x).^2

julia> f(3)
2-element Array{Int64,1}:
 3
 3

julia> (!f)(3)
2-element Array{Int64,1}:
 9
 9
2 Likes

By golly, this sounds like a bad idea, but out of sick curiosity, I would like to find out what you’re using this for :slight_smile:.

2 Likes

It’s the following case:

struct MyType1
    a::MyType2
    b::MyType2
    c::MyType2
    d::MyType2
    e::MyType3
    f::MyType3
    g::MyType3
end

available_mytype2(y::MyType1) = (:a, :b, :c, :d)
compulsory_mytype2(::MyType1) = (:a, :b)
optional_mytype2(::MyType1) = (:c, :d)

I don’t want to apply these methods onto MyType3, and getting the optional MyType2 can’t be just setdiff(fieldnames(MyType1), compulsory_mytype2(x)). But defining an optional_mytype2 seems to be overkill. So…

In summary, I don’t want the !compulsory_mytype2 to be the negation of (:a, :b) (It can’t be!), but a new behavior: the semantic negation/complement of compulsory_mytype2.

Just for fun, I find those also work:

julia> Base.:!(::typeof(!)) = x -> 2x

julia> (!!)(2)
4

julia> Base.:!(::typeof(!=)) = x -> 3x

julia> (!!=)(3)
9

Though it is too easy to be confused with !(!x). I can define new functions applied to arguments in a more general case.