On 24 April 2018 at 09:58, Louki Sumirniy <louki.sumirniy.stal...@gmail.com> wrote: > > > On Tuesday, 24 April 2018 11:15:34 UTC+3, rog wrote: >> >> On 23 April 2018 at 19:58, Louki Sumirniy >> <louki.sumir...@gmail.com> wrote: > > >> >> > I set many of those identifiers to export because I wanted to keep >> > separate >> > derived libraries that replaced the storage types embedded into the main >> > library. These limitations would not exist were the 'back store' over >> > the >> > wire or on disk. They only exist for the storage that is most accessible >> > to >> > the program, the main memory. >> >> I don't understand this. If you're replacing the underlying storage >> types, why would you need to export details of an algorithm that the >> storage types shouldn't need to have anything to do with? > > > Because if they can't be accessed outside of the scope of the file I am > forced to add the alternative data types within the same file.
I can't parse this sentence. There's nothing stopping you from having alternative storage implementations outside the package AFAICS. Also, file scope isn't really a thing in Go (*). > This is a > massive loss of flexibility (and means an importing application cannot > implement its own variant). In my experience, allowing external code to "implement its own variant" by exporting all the component pieces of an algorithm and allowing it to arbitrarily vary them is a recipe for cryptic APIs and broken invariants. This is a hallmark of class-hierarchy-based OOP, which is a style that Go specifically avoids. I'd suggest exposing as few moving parts as possible. If someone wants to change the algorithm, let them fork the code. >> > This idea that I should be hiding all the functions smells like OOP to >> > me. >> >> This isn't OOP - it's just good code hygiene. By hiding implementation >> details, you make the public interface clear and you prevent clients >> from relying on internal implementation details that you might want to >> change. > > > How do I override the functions to implement the data abstraction if the > overridden functions are not exported? Don't do that. You've got two principal abstractions here - the underlying storage (more-or-less a slice) and the algorithm itself. It's important to be able to change the storage implementation, but the algorithm itself does not need to be able to be overridden. I think you're still thinking as if you're in a subclass-based language. >> Private functions are not "security by obscurity". Private functions >> aren't "obscure" (you can see them in the source perfectly well) but >> they are "secure" because you cannot access them. > > > This is nonsense because all I have to do is fork and expose and what > exactly is the nature of the danger of me knowing the internals? There is no danger in *you* knowing the internals, but there is danger in *external code* depending on the internals. >> I think you overestimate the novelty of your algorithm. It sounds to >> me like it bears significant resemblance to a "complete binary tree" >> (see https://xlinux.nist.gov/dads/HTML/completeBinaryTree.html). > > > A complete binary tree does not have a concept of empty nodes. It must do, because a complete binary tree can be implemented by an array and does not have to have exactly 2^n nodes, so by implication some of the nodes in the array may be empty. > It uses references to bind nodes together, thus the overhead of memory > storage, and the randomness (usually insert order) in the array of nodes. If by "references", you mean "pointers", that's not true. As the link I included says: It can be efficiently implemented as an array, where a node at index i has children at indexes 2i and 2i+1 and a parent at index i/2 That sounds very like what you're doing. > The random memory locations of the node data is precisely what this > algorithm aims to eliminate, as well as reducing memory overhead. Your algorithm can waste up to half the overall storage space. I don't see how that's "reducing memory overhead" in general. > Benchmarks would require a completed algorithm. I will absolutely be > profiling it once it's done, in order to work out the comparative processing > loads for each type of operation. I have a vague concept of the heuristics > for optimisation operations, but I had been putting off filling these parts > in because I still hadn't achieved the data type abstraction at that point. I'd suggest starting with the basic algorithm without any abstraction (just hard-code in the type you want to store), then benchmark/tweak the algorithm, and only then try to make it general. > Thanks for your discussion about this... it's implicitly complimentary to > have my ruminations actually read and considered. Your ruminations are verbose enough that I suspect I won't be reading them much more in the future, I'm afraid, but I hope my thoughts have been useful to you. rog. (*) technically, package identifiers are in file scope, but I'm pretty sure that's not what you were referring to. -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.