Memory optimizations of Differentiable: turned lists and dicts into tuples and used __slots__

When we're creating many millions of these nodes for on-the fly networks, memory is becoming a major bottleneck.
These optimizations reduced the memory footprint of a vanilla "Identity" node from 968 bytes to 288 bytes.
(Even bigger wins for nodes with more than two additional instance variables, which were up at ~1500 bytes due to the discrete jumps in dict sizes.)