On Fri, May 24, 2019 at 3:27 PM Ricky Teachey email@example.com wrote:
This seems like a hurdle you're going to have trouble passing... especially given that all the functionality that is required can be provided using existing descriptor behavior. You will need to pretty concretely demonstrate why the special handling of signals in assignment (no matter which operator is the operator of choice) is something the language at large really needs, and why descriptors aren't sufficient.
Just a quick example, suppose you have a class A and class B representing two circuit blocks, where in class C you want instantiate A() and B() and connecting them together. Please do let me know if you could have a more reasonable way of representation to make it working. class A: def __init__(self, output): self.output = output def process(self): self.output = 5 # !!! this does not work for descriptors passed in
# self.c_self.signal = 5 # this might work, but what the heck really?!
class C: signal = Signal() def __init__(self): a = A(output=self.signal)
# a = A(output=self) # it is only possible for signal to work
if you pass C's self into a ... b = B(input=self.signal)
# !!! This does not work !!!
Instead, a much more natural way of doing it is: class A: def __init__(self, output): self.output = output def process(self): self.output <== 5 # this always works!
class C: def __init__(self): signal = Signal() a = A(output=signal) b = B(input=signal) # this feels much better, isn't it?
And to be honest, working with a SignalDescriptor class seems like the most explicit and readable approach anyway, given that your stated first preference is to customize/"overload" the assignment operator. Python already provides nearly the exact syntax you want, you are just limited to confining it to your own Signal and SignalDescriptor objects.
If one thing PEP465 ever taught me is that readability really matters a lot. Having a identical python object structure mapping to the hardware structure, with proper localized values as it is in HDL, here is an example in verilog instantiating 3 flip-flops, one outputs connect the next input, it is really reflecting how engineers are thinking in hardware description. If you could tell me a way to implement something as elegant as below of cause I'd be happy and just use it. It doesn't make sense to create a new HDL which is even less intuitive and more difficult to use and understand ...
// D flip-flop module dff( input wire d, input wire clk, output reg q, output reg q_bar );
/* input d, clk; output q, q_bar;
wire d, clk; reg q, q_bar; */ wire qx, qbx;
always @ (posedge clk) begin q <= d; q_bar <= !d; end
module dff_tb(); // skipped signal stimuli part ... reg d, clk, test; wire q0, q0_bar,q1,q1_bar,q2,q2_bar;
dff d1(d, clk, q0, q0_bar); dff d2(q0, clk, q1, q1_bar); dff d3(q1, clk, q2, q2_bar);
Comparing this idea to adding a matrix operator: in the latter case, even if you created a Matrix class and customized __mul__ behavior, there were still two competing definitions for how multiplication can occur. So that couldn't be solved through customized classes. In this current case, the problem CAN be solved by pairing a customized Signal and SignalDescriptor. Unless you can demonstrate exactly why that this isn't a workable solution, I think you can expect it to be very difficult to get the buy-in you need.
I think the above example self-explains the situation. Do let me know if you think otherwise.