Post
Topic
Board Altcoin Discussion
Re: [neㄘcash, ᨇcash, net⚷eys, or viᖚes?] Name AnonyMint's vapor coin?
by
TPTB_need_war
on 16/05/2016, 22:01:59 UTC
Follow-up:

Quote from: myself
Quote from: keean
Its no good knowing the types that 'may' be in the collection, when I read the head of the list what can I do with it?

Perhaps I need to expand that? If I don't know whether the element at the head of the list is a String or an Int I cannot do anything with the value.

That is true even if you use a nominal enum, a trait object, or even your HList. There is no way to avoid branching in software unless you only have one type () (unit) in the entire program.

Effectively you are arguing you don't want a program. You want a brick.

Even though there might be more than one data type of the trait bound dictionary, it can be possible to optimize this selection by for example keeping branches nearby in instruction cache and pipelines. What I am saying is an optimizing compiler can receive these dictionaries at compile-time so it can fiddle with them to optimize the branching performance. Rather than having them in some vtable that entirely breaks pipelining.

There is nothing you can do to avoid branching. It is part of software. Sorry can't help you there. Lol.

Any way thanks for the point. You indeed drove this issue straight to the point which is why I really appreciate you. I couldn't have seen those issues immediately without you raising the issue.

Btw, I just realized that we could actually count the number of each data type in the collection using typing and then compiler would know which cases are likely to occur most often. Or a hotspot VM can attempt these profiling low-level optimizations with run-time profiling.

Quote from: keean
If I know all elements in the collection implement the X trait, then I know I can call any method of the X trait on the value of unknown type safely.

I can do that because I know that all elements in the collection must implement trait X, because I know the memory layout of the vtable for trait X, and I can then indirect function call to the vtable to access the method no matter what the type is at the head of the list.

Knowing which trait implementations are possible not just which trait bounds, can enable optimizations as I mentioned above. If you can't limit which trait implementations, you can't make the above optimizations and you'll be stuck with indirecting to a vtable and stalling the CPU pipeline.

Quote from: keean
So the important thing is to know what traits all elements in the collection must implement, I don't care about their types, and I cannot know their types at runtime. knowing that the collection is Int \/ String does not help me do anything with the value at the list head, because I don't know if that particular value is a String or an Int .

Incorrect as explained above.


Quote
Quote from: keean
All my performance work is based on benchmarking and profiling. Unfortunately not all algorithms parallelise well. One of my monte-carlo simulations gains so much information from a single run, anything in parallel is useless (because you now have much better parameters, all your parallel runs are no longer relevant).

Okay that is I guess true in some or even many cases. But I think for most what I would refer to as "mobile apps" and server apps (which is my first use case) that concurrency is vital. Parallelism also maybe to some degree.


Quote from: myself aka shelby3
Quote from: keean
Quote from: shelby3
Afaik, HKT are necessary when we need to abstract over the type constructor of ourself (speaking from the perspective of a data type). So for example, Self is a HKT when it is an result type in a trait, because this means any application of that trait requires to know which data type implemented that trait.

We can see this more clearly in Scala, where we would write:

Code:
trait Foo[Self <: Foo[Self]] {
  def myself: Self = this;
}
class Bar extends Foo[Bar];

I am not sure that the Scala is saying? The type parameter of Foo must be a subtype of Foo with the parameter Self? It doesn't really make sense to me.

Yes it is saying that Foo[Self] takes a parameter Self. Then it also constrains the parameter Self to be a subtype of Foo[Self]. So then means that Self must extends Foo[Self].

So this makes Self a HKT because it is a type parameter that over the type instance construction operator of Foo. When we declare an instance (not data but declare a type) of Foo[Self], we also set the parameter Self to that instance that was declared. So that is HKT.

How do you think about and visualize HKT?