Replies: 1 comment 1 reply
-
What you are suggesting is a better API, but it will result in slower code. That is why I originally wrote it as it currently is (a struct wrapping a union). Before world-splitting: edit = haplotype.edits[i]
f(edit) After world-splitting edit = haplotype.edits[i]
if edit isa Deletion
deletion_implementation(x)
elseif edit isa Insertion
insertion_implementation(x)
elseif edit isa Substitution
substitution_implementation(x)
else
f(edit) # fallback branch to throw the right MethodError
end I.e. world-splitting automatically produces the same code that you are currently doing manually. The problem with that is:
In contrast, if-else statements are, and will always be, fast. Their main drawback is that they are annoying to write and error-prone. The ideal situation would be if Julia had native support for match statements like Rust. They're essentially just a more ergonomic way of writing these if-else blocks. I propose either:
On the other hand you can just use SumTypes for now and then change it to if/else statements later if need be. |
Beta Was this translation helpful? Give feedback.
-
Hi all,
It's been a while since I've had a chance to really sit down with this project, and I think that has helped clear my head of some preconceived notions and let me see where the cracks are in the current API setup.
All of the issues on the issue tracker right now are in the same vein of "since a
Haplotype
can come from an alignment, then find a way to translate an alignment back to aHaplotype
." That should be trivial, but it hasn't been. #42 is still in draft mode because there are edge cases that I can't find a way to detect and deal using the current API.One of the primary problems I have with the current API is that there is no way to deal with
Variation
s that represent different types ofEdit
. For example, counting up in a cigar string should add 1 forVariation
s that contain aSubstitution
, but add the length of theInsertion
orDeletion
otherwise. There are way too many times that I have to do the ugly hack of reflection andif
statements.Julia's thing is multiple dispatch, but the way the API is constructed doesn't allow for multiple dispatch to be used effectively. Maybe I'm conflating me not finding a reverse-alignment solution with the clunkiness of the API, but considering how much time I've spent hacking together private methods just to make my alignment methods work, I think it's time I invest in a new API before moving on to alignment.
My proposal is to make both
Variation
andEdit
into abstract types, then makeSubstitution
, etc. into the concrete implementations. This diagram should present the type structure I'm thinking of.(I did not include parametric types here in the diagram for brevity, but those would stay).
Now, instead of doing reflection and delegating based on
if
trees, the above code chunk would behave something likeThat feels more Julian, and it should bring performance benefits from losing branches.
I want to get some feedback on what impacts this API change might have, since it basically will require a bottom-up rewrite of the entire package. Two basic questions:
Thoughts, comments and feedback of all kinds are welcome before I start tearing this library's guts out. Thanks.
Beta Was this translation helpful? Give feedback.
All reactions