Re: Function to print a diamond shape
On Saturday, 22 March 2014 at 14:41:48 UTC, Jay Norwood wrote: The computation times of different methods can differ a lot. How do you suggest to measure this effectively without the overhead of the write and writeln output? Would a count of 11 and stubs like below be reasonable, or would there be something else that would prevent the optimizer from getting too aggressive? I used this to benchmark H. S. Teoh's calendar formatter: version(benchmark) { int main(string[] args) { enum MonthsPerRow = 3; auto t = benchmark!(function() { foreach(formattedYear; iota(1800, 2000).map!(year = formatYear(year, MonthsPerRow))) { foreach(_; formattedYear){}; } })(30); writeln(t[0].msecs * 0.001); return 0; } } While the optimizer could probably remove all of that, it doesn't. I also tested it against other options like walkLength, this ended up begin the better choice. (BTW, using joiner instead of join I was able to more than double the performance: https://github.com/luismarques/dcal/tree/benchmark . Once the pipeline is made lazy end to end that will probably have even more impact.)
Ranges/algorithms for aggregation
Is there a neat way to do this transformation with ranges and std.algorithms? Input: --- B foo B bar C ble B big A begga Output: (aggregated and sorted on length) --- B - [foo, bar, big] C - [ble] A - [begga] The most obvious way (to me) to do this without standard algorithms is with an AA to the aggregation. The most obvious way (to me) to do this with std.algorithms is: B foo B bar C ble B big A begga = [B, foo] [B, bar] [C, ble] [B, big] [A, begga] = [B, foo] [B, bar] [B, big] [C, ble] [A, begga] = B - [foo, bar, big] C - [ble] A - [begga] But this seems wasteful on memory. Is there a better way to do this in a more algorithmic way?
Re: Ranges/algorithms for aggregation
On Friday, 21 March 2014 at 15:38:23 UTC, bearophile wrote: Output: (aggregated and sorted on length) --- B - [foo, bar, big] C - [ble] A - [begga] What is the desired output data structure? An associative array of dynamic arrays? Or is a dynamic arrays of dynamic arrays of 2-tuples enough? I'm doing this for a D newbie, to teach him the range/algorithmic approach. The function he wrote to output the result of that transformation takes as an input an array of arrays (the latter), but he builds that input iteratively using an AA of arrays (the former). I asked him about that mismatch and at the time he told me that for now he only needed the latter, suggesting he had other future plans where he might need the AA, but I'm not sure. So let's just say that the client is unclear on his requirements, which does happen in the real world anyway :-). In any case, I think the hashGroupBy is what I was asking about :-). Neat. (did anyone actually implement it?) I'm not sure how if a dynamic arrays of dynamic arrays of 2-tuples sufficed that would help with the intermediate step, if we wanted to avoid the sorting step. Did you have anything in particular in mind there?
Re: Ranges/algorithms for aggregation
On Friday, 21 March 2014 at 16:04:45 UTC, bearophile wrote: I think this problem needs a sorting or a hash. One possible solution, if you don't need an associative array as output, is to use a multiSort followed by a building of groups using slicing. It could be efficient enough. Later you search the keys with a some kind of binary search. The number of keys is large and unbounded (not just three as in my example), so I guess this multiSort approach would not be practical, right? I think we really need the hashGroupBy.
Re: Ranges/algorithms for aggregation
On Friday, 21 March 2014 at 16:53:46 UTC, H. S. Teoh wrote: Be aware, though, that groupBy only compares *adjacent* elements for equivalence; it does not sort the input. So if your input has equivalent elements interspersed with non-equivalent elements, you will have the equivalent elements split into multiple runs in the output. I think that's why Justin used sort. The hashGroupBy proposed by bearophile would avoid the sort and the additional memory usage though, so that would be even better.
Re: Ranges/algorithms for aggregation
On Friday, 21 March 2014 at 17:20:38 UTC, Luís Marques wrote: I think that's why Justin used sort. The hashGroupBy proposed by bearophile would avoid the sort and the additional memory usage though, so that would be even better. I was thinking, we don't even need the full power of sort. Is there a standard algorithm that makes elements with equal keys be in sequence, but that otherwise is less expensive than sort?
Re: Ranges/algorithms for aggregation
On Saturday, 22 March 2014 at 01:08:11 UTC, bearophile wrote: how is it supposed to know where to group items? Usually you build an associative array for that. It would swap elements, like sort, so it doesn't need to put them anywhere, just permute them. The advantage is this: Input: [7, 3, 7, 1, 1, 1, 1] Output sort: [1, 1, 1, 1, 3, 7, 7] Output groupSort: [3, 7, 7, 1, 1, 1, 1] groupSort (or whatever it would be called) only makes one swap, while sort makes a lot of them. So groupSort is a lot cheaper. I'm not sure what the asymptotic time complexity of groupSort is, at this moment's notice (I guess it would depend on what strategy it would use).
Accepting delegates/functions in templates
I'm trying to accept delegates or functions in a templated method. My first try using isDelegate!dg || isFunctionPointer!dg did not work because isDelegate fails, although I'm not sure I understand exactly why: void main() { int x; static assert(isDelegate!(() { x = 4; })); // Error: static assert ... is false } If I changed that example to use isSomeFunction it works correctly. But when I tried to use isSomeFunction in the proper context it fails to compile: class A { void foo(alias dg)() if(isSomeFunction!dg) { } } void main() { int x; A a = new A; a.foo!((int param) { x = 4;}); // error: cannot use local '__lambda1' as parameter to non-global template foo(alias dg)() if (isSomeFunction!(dg)) } Can anyone help me understand this?
Re: Dispatching values to handlers, as in std.concurrency
On Tuesday, 7 May 2013 at 06:19:24 UTC, Idan Arye wrote: If it's not templated - make it templated! You don't have to make the entire `TypeHanler` templated, just the method that creates it. There, you can create an anonymous function that receives `Object` and returns `bool` and all it does is check for type, and you can have a field in `TypeHandler` that keeps that function and uses it to check if it can handle a certain type. Thanks. It took me a while to understand what you meant, but it's working.
deducing function/delegate in template method
In this code: // accepts a list of handlers, for the respective types void addHandlers(T...)(T handlers) { foreach(handler; handlers) { addHandler(handler); } } // accepts one handler, for type T void addHandler(T)(void delegate (T) handler) { ... } ... foo.addHandler((int x) { /* always deduced as delegate */ }); foo.addHandlers(delegate (int x) { /* if no scope access deduction fails */ }); If I call addHandler with a function/delegate literal then DMD deduces that the literal has to be a delegate, but if I call addHandlers then I have to explicitly mark my function/delegate literal as a delegate, otherwise the template match will fail if the function/delegate literal does not access something from its scope. Couldn't DMD also deduce this correctly in this case? Also, how can I change addHandler to accept delegates with heterogeneous varargs? Something like: void addHandler(T...)(void delegate (T...) handler); so that I can do: foo.addHandler((int x, float y) { });
Re: deducing function/delegate in template method
On Friday, 24 May 2013 at 22:37:49 UTC, Luís Marques wrote: foo.addHandlers(delegate (int x) { /* if no scope access deduction fails */ }); (I meant that deduction would fail if the literal was not marked as a delegate)
Re: How to translate this C++ preprocessor declaration in D?
On Saturday, 25 May 2013 at 00:02:50 UTC, Heinz wrote: #define my_id 'asdf' string my_id = asdf;
Re: How to translate this C++ preprocessor declaration in D?
On Saturday, 25 May 2013 at 00:07:02 UTC, Luís Marques wrote: On Saturday, 25 May 2013 at 00:02:50 UTC, Heinz wrote: #define my_id 'asdf' Ah, sorry, didn't notice the single quotes.
Re: How to translate this C++ preprocessor declaration in D?
I remember that there was a smarter way to do this, but you can do it manually. Something like: immutable long my_id = 'a' 24 + 'b' 16 + 'c' 8 + 'd'; Or you can create a CTFE function to do this from a string, which should be nicer, if you don't find an existing utility for this.
Dispatching values to handlers, as in std.concurrency
I have a list of functions which receive values of different types, like in std.concurrency... // example from std.concurrency receive( (int i) { writeln(Received the number , i);} ); ...although in my case I can probably live by with only accepting objects. I built a list of the handlers and the message classes they accept. My problem is that I don't know how to check if the message I have to dispatch is of the class the handler accepts *or a subclass*. I only managed to check for class equality: if(typeid(msg) == typeHandler.type) { typeHandler.handler(msg); } How can I also accept subclasses? Thanks, Luís
Re: Dispatching values to handlers, as in std.concurrency
On Monday, 6 May 2013 at 21:20:49 UTC, Idan Arye wrote: BTW, for this to work `typeHandler.type` needs to be known at compile-time. That's the rub. This list of handler is dynamic, so `typeHandler.type` is a TypeInfo, not a compile-time type.
Re: Dispatching values to handlers, as in std.concurrency
On Monday, 6 May 2013 at 23:53:51 UTC, Idan Arye wrote: If the type handlers are your own classes, then you can let them check it. Have a method in the handlers that check if an object can be handled by that handler, and use it on each handler until you find one that fits. I don't understand. Imagine I have: class X { void handleFoo(Foo msg) { ... } void handleBar(Bar msg) { ... } } I want to register an instance of X to receive messages of type Foo (or subclass) and messages of type Bar (or subclass) in the respective handler methods. Where are you proposing for your check to be implemented?
Re: Dispatching values to handlers, as in std.concurrency
On Monday, 6 May 2013 at 23:48:11 UTC, Sean Kelly wrote: How are the messages stored? std.concurrency uses Variant.convertsTo. I had looked at Variant.convertsTo but (IIRC) it accepts a type (not a TypeInfo) and in my design I no longer had the type avaliable in the place where I would use the convertsTo, only the TypeInfo. I dispatch my messages as they come, so I don't store them. I only store the handler info, in the format Tuple!(TypeInfo, handler).