<mwk>
josuah: it's just the IRC room via the default bridge
<mwk>
#amaranth-lang:libera.chat
<josuah>
thanks! plain matrix <-> IRC all right. I might try it. :)
<whitequark>
#amaranth-lang:libera.chat and #amaranth-lang:matrix.org are both the same channel (this one)
jjsuperpower has joined #amaranth-lang
<josuah>
thank you!
jjsuperpower has quit [Ping timeout: 245 seconds]
cr1901_ has joined #amaranth-lang
cr1901_ is now known as cr1901
richardeoin has quit [Ping timeout: 240 seconds]
richardeoin has joined #amaranth-lang
jjsuperpower has joined #amaranth-lang
jjsuperpower_ has joined #amaranth-lang
jjsuperpower has quit [Ping timeout: 260 seconds]
<whitequark>
hm, I could replace sig.create_members() with `sig.members.create()~
<whitequark>
s//`/, s//`/, s/~/`/
<whitequark>
which works way better semantics wise and doesn't give people ideas to override create_members
<whitequark>
so there's both SignatureMembers and FlippedSignatureMembers, necessarily
<whitequark>
to support sig.flip().members
<whitequark>
yea, you have to flip the member flow on every read or write through the flipped one
<whitequark>
and that code has to live somewhere
<whitequark>
yes. and also it's a bit wasteful to keep creating flipped instances anytime you flip a signature
<whitequark>
since 99% of them will just be garbage
<whitequark>
this is probably not a bottleneck most of the time but I can see it being an issue in very heavily abstracted code
<whitequark>
and especially with dimensions and stuff
<whitequark>
if this wasn't also nicer to implement I'd not bother with the optimization, but if we can do both at the same time, perfect
<whitequark>
one really cursed case is eq on signatures that's overridden in a user derived signature
<whitequark>
I don't know how to implement that
<whitequark>
on the signature itself
<whitequark>
the idea is that you can have two bus signatures that have the same signals but different semantics due to misc attributes
<whitequark>
eg one requires comb feedback and the other is registered
<whitequark>
yes sorry
<whitequark>
__eq__
<whitequark>
kinda feels like, hm
<whitequark>
yes. if you derive from Signature then the default __eq__ is is
<whitequark>
which is the most strict
<whitequark>
and then you can relax it in your implementation
<whitequark>
this is honestly a good question
<whitequark>
hm
<whitequark>
I don't like where this is going
<whitequark>
that's too much like Python's arithmetics to my taste
<whitequark>
I'm seriously thinking about dropping __eq__ but I'm not fully sure about it
<whitequark>
there is also the question of user attributes that should change when the signature is flipped
<whitequark>
do we want that to be a thing?
<whitequark>
zyp: yeah so I think I'll drop `__eq__` and in large part I want to do this because signatures are mutable
<whitequark>
if you want structural equality on signals, you can do a.members == b.members which is not any more onerous
<whitequark>
and makes the intent clear
<whitequark>
there is also benefit to having as few members as possible on Signature
<whitequark>
zyp: `sig_a.compatible(sig_b)` is a type error
<whitequark>
.compatible operates on objects
<whitequark>
this is why sig.implemented_by(obj) might be a better name, as pointed out in the end of the RFC
<whitequark>
so far I find it unconvincing
<whitequark>
to be clear all I'm stating is that I don't see the utility. that could be on me
<whitequark>
doesn't mean it lacks utility
<whitequark>
ah I see
<whitequark>
I wonder if sig["x", "y", ...] interface is even useful at all
<whitequark>
it was originally used in .compatible but it's not anymore
<whitequark>
ah, a more concrete question I have
<whitequark>
so Out(sig).signature == sig, always
<whitequark>
but should In(sig).signature == sig, or ``In(sig).signature == sig.flip()`?
<whitequark>
s//`/, s/,/`,/, s/``/`/
<whitequark>
right now there's a bunch of if member.flow == Out: do_sth(member.signature) else: do_sth(member.signature.flip()) and this seems annoying
<whitequark>
there is a certain purity to having Member(flow, signature).signature == signature for every flow but in practice this seems to be just inconvenient
<whitequark>
FL4SHK: \`
<whitequark>
it's markdown (internally it's html actually)
<whitequark>
heh
<whitequark>
FL4SHK: yeah so everything gets better if `sig.flip()` is used
<whitequark>
and in fact the current signatures RFC is partly inspired by FIRRTL, which does not have In and Out, but only flip and no flip
<whitequark>
so only In doing a flip operation makes perfect sense in this context
<whitequark>
zyp: there hasn't been a discussion of it but I quietly removed the `~` option because I felt like that might be going overboard with sigils that may not even represent the operation all that well
<whitequark>
galibert: `In(ShapeCastable)`
<whitequark>
well, In(ShapeCastable or Signature)
<whitequark>
yes
<whitequark>
it's all designed to work together
jjsuperpower_ has quit [Quit: Leaving]
jjsuperpower has joined #amaranth-lang
<whitequark>
yeah it works out in that code written for Amaranth will be incompatible in both conceptual and practical way with (n)Migen
<whitequark>
any opinions on whether Signature.iter and Signature.getitem should even exist?
<whitequark>
* any opinions on whether Signature.__iter__ and Signature.__getitem__ should even exist?
<whitequark>
yea
<whitequark>
you always have Signature.members of course
<whitequark>
but __iter__ returns the flat list of names, and __getitem__ returns a member at path
<whitequark>
but for that I think you should look at a signature attribute
<whitequark>
yes, you could do that, but it would be much better if you were able to do if "err" in bus.signature.features
<whitequark>
which is something that existing WishboneInterface does, even
<whitequark>
can you elaborate?
<whitequark>
you can do if "err" in bus.signature.members already, that's supported, and doesn't require anything on signature itself
<whitequark>
oh, like hasattr(bus, "err")? well yes but thats kind of cursed when you have the set of features on the bus itself
<whitequark>
but testing for optional features is always a contract between the definition of the interface and the use point
<whitequark>
so it's not something that has to be decided globally
<whitequark>
meaning it doesn't make anything non-optional, it's always up to whatever the author of that particular interface library chooses
<whitequark>
yeah
<whitequark>
we actually don't have that many options and I'm actively trying to reduce them (like arguing for removing __iter__ and __getitem__ on signatures)
<whitequark>
I think that usually instead of x.signature["y", "z", "t"] you would do x.y.z.signature["t"] anyway since all the intermediate objects have their signature property instantiated as well
<whitequark>
for the latter case (should signatures be created in class or function if it's not changeable): I'd say in the class, like sig = Signature({...}).freeze()
<whitequark>
since there is no benefit to make it a property accessor
<whitequark>
either could work, the only difference is aliasing
<whitequark>
for the former case, it's actually complicated and there is no single answer
<whitequark>
if you create submodules in the constructor, you can assign them in self.x, and then these become introspectable from the outside
<whitequark>
elaborate is not supposed to ever mutate self
<whitequark>
but if you create submodules in the constructor, their configuration (usually derived from parameters passed to the constructor) is fixed, and you must make any properties you also set in the constructor read-only to make sure everything remains consistent
<whitequark>
yes, we need to have a code style guide
<whitequark>
we'll get there
<whitequark>
but not at the cost of my health
<whitequark>
good luck
<WilliamDJones[m]>
I'm sorry, I only have the bandwidth right now to follow changes to the Interfaces RFC as edits are made to the actual RFC document. But from reading today's convo: I've no objections for whatever wq wants to remove or modify. At "worst", I'll have some questions when looking at the RFC diff.
<whitequark>
William D. Jones: pushed some changes just for you
<_whitenotifier-6>
[amaranth-lang/rfcs] whitequark 27c4e2b - Remove `Signature.__eq__()` since it's hard to implement when flipping exists
<_whitenotifier-6>
[amaranth-lang/rfcs] ... and 6 more commits.
<WilliamDJones[m]>
Why thank you :P
<whitequark>
well, I mean, it's for everyone, but you reminded me of doing it
<whitequark>
okay, I think I have a complete implementation of the RFC. I haven't ran it, <del>I've only proven its correctness</del>
<WilliamDJones[m]>
Flawed analogy: Today's convo was an Out-of-Order CPU doing work. The RFC is a memory barrier w/ mutex. I'm a core somewhere else on the bus that just saw the RFC mutex released.
<whitequark>
in fact x[1,2] is the same as x.__getitem__((1,2))
<whitequark>
<charlottia> "Was a really good way to learn..." <- oh that's incredible
robtaylor has joined #amaranth-lang
fl4shk[m] has joined #amaranth-lang
galibert[m] has joined #amaranth-lang
zyp[m] has joined #amaranth-lang
<adamgreig[m]>
whitequark: I'm a fan of the new syntax for In/Out and the Component type annotations for signature, looks great! I think I already know the answer is "no because lib.component can't be special" but wouldn't it be nice if you could `m.connect(source, sink)`...probably not nice enough to warrant a new `Module` wrapper or special method on `Component`s though
<adamgreig[m]>
thanks for updating the guide section of the rfc too
<adamgreig[m]>
ah, you'll see I did not read to the end of the updated rfc yet where you specifically address the m.connect point :P
<whitequark>
I think that paragraph has been there almost since day 1
<whitequark>
or maybe not day 1, but it was there a week ago...
<adamgreig[m]>
yea... I guess I just forgot about reading it the first time when I had the thought this time
<zyp[m]>
I've been wondering slightly why it's connect(m, …) and not the m.comb += connect(…) that I'm used to, but I've been chalking it up to «it's shorter and if you want anything other than a combinatorial connection, this is the wrong tool for the job»
<whitequark>
it's the latter part that really made me decide to go with a free function
<whitequark>
m.d.sync += connect() is always wrong, but sometimes it's wrong in a subtle evil way