1

I would like to have the following:

import _Differentiation

struct S {
    var f: @differentiable(reverse) (Double, Double) -> Double
}

but the compiler complains Error: Abort trap: 6 and the start of the stack trace is

Assertion failed: (isa<X>(Val) && "cast<Ty>() argument of incompatible type!"), function cast, file Casting.h, line 269.

If the member variable is a function of one parameter, the program builds:

import _Differentiation

struct S {
    var f: @differentiable(reverse) (Double) -> Double
}

but two or more parameters is not allowed.

We can write a function that has a differentiable function of two parameters as a parameter:

import _Differentiation

func g(f: @differentiable(reverse) (Double, Double) -> Double) {
    // function body
}

If a function can have this type of parameter, why can a struct not have a member variable of this type?

bjschoenfeld
  • 402
  • 6
  • 14

1 Answers1

0

This can be achieved by making the struct and/or the member variable function have fileprivate or private access control:

import _Differentiation

struct S {
    fileprivate var f: @differentiable(reverse) (Double, Double, Double) -> Double
}

or

import _Differentiation

fileprivate struct S {
    public var f: @differentiable(reverse) (Double, Double, Double) -> Double
}

Note in the second example that f can be public because S is restricted to at least fileprivate.

A work-around is to make f a function of another differentiable data structure, for example:

import _Differentiation

struct S {
    struct Tuple: Differentiable {
        var x: Double
        var y: Double
        @differentiable(reverse)
        init(x: Double, y: Double) {
            self.x = x
            self.y = y
        }
    }
    var f: @differentiable(reverse) (Tuple) -> Double
}

bjschoenfeld
  • 402
  • 6
  • 14