Re: Function to print a diamond shape

2014-03-23 Thread Luís.Marques

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

2014-03-21 Thread Luís.Marques
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

2014-03-21 Thread Luís.Marques

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

2014-03-21 Thread Luís.Marques

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

2014-03-21 Thread Luís.Marques

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

2014-03-21 Thread Luís.Marques

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

2014-03-21 Thread Luís.Marques

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

2013-05-27 Thread Luís.Marques

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

2013-05-24 Thread Luís.Marques

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

2013-05-24 Thread Luís.Marques

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

2013-05-24 Thread Luís.Marques

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?

2013-05-24 Thread Luís.Marques

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?

2013-05-24 Thread Luís.Marques

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?

2013-05-24 Thread Luís.Marques
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

2013-05-06 Thread Luís.Marques
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

2013-05-06 Thread Luís.Marques

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

2013-05-06 Thread Luís.Marques

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

2013-05-06 Thread Luís.Marques

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).