July 21, 2014
On Mon, Jul 21, 2014 at 06:36:04PM +0200, Daniel Gibson via Digitalmars-d-learn wrote: [...]
> However, having something like staticIota in the stdlib would probably make sense.
[...]

It's already in std.typecons.

(Admittedly, that's not exactly the most obvious place to look for it...)


T

-- 
There are two ways to write error-free programs; only the third one works.
July 21, 2014
H. S. Teoh:

> It's already in std.typecons.

But it is not online yet?

Bye,
bearophile
July 21, 2014
Am 21.07.2014 20:09, schrieb H. S. Teoh via Digitalmars-d-learn:
> On Mon, Jul 21, 2014 at 06:36:04PM +0200, Daniel Gibson via Digitalmars-d-learn wrote:
> [...]
>> However, having something like staticIota in the stdlib would probably
>> make sense.
> [...]
>
> It's already in std.typecons.
>
> (Admittedly, that's not exactly the most obvious place to look for it...)
>
>
> T
>

static.typecons is actually where I would have expected it, as it constructs a tuple.. but it isn't mentioned on http://dlang.org/library/std/typecons.html or http://dlang.org/phobos/std_typecons.html
and at least in my /usr/include/dmd/phobos/std/typecons.d (2.065) it's private:
private template staticIota(int beg, int end)
{ ... }
And it seems like I can't use it.
Anyway, good to know that it exists and hopefully future versions of D2 make that function public, so thanks for showing up another alternative to solve my problem :-)

BTW: The name "Iota" is horrible.. it doesn't describe at all what the function does.
And "But C++11 STL has a function of the same name that does the same thing" or "some obscure programming language from the 60ies (APL) used the Greek iota letter to do this" is no excuse, one shouldn't expect potential D users to know about that (even after using C++ for years I never encountered std::iota..)
Maybe "Numerate" or something like that would be more descriptive..

Cheers,
Daniel
July 21, 2014
On Monday, 21 July 2014 at 18:10:14 UTC, H. S. Teoh via Digitalmars-d-learn wrote:
> On Mon, Jul 21, 2014 at 12:55:34AM +0200, Daniel Gibson via Digitalmars-d-learn wrote:
>> Hi,
>> I have a variadic templated function and want to call a C varargs function.
>> I want to be able to pass static arrays, which D2 passes by value and C by
>> reference, so I'd like to automagically translate those arguments.
>> 
>> My idea was something like this:
>> 
>>   extern (C) origFun(int x, ...);
>> 
>>   T transTupleElem(T)(T arg) { return arg; }
>> 
>>   float* transTupleElem(T : float[3])(T arg) {
>>     return arg.ptr;
>>   }
>> 
>>   void fun(T...)(int x, T argTuple) {
>>     // create a new tuple type that replaces all static float[3]
>>     // arrays with float* to emulate C call-by-reference behavior
>>     alias ReplaceAll!(float[3], float*, T) ModifiedTuple;
>>     ModifiedTuple modTuple;
>> 
>>     foreach(size_t i ; 0 .. T.length)
>>       modTuple[i] = transTupleElem(argTuple[i]); // BOOM!
>> 
>>     origFun(modTuple); // or is it modTuple.expand ?
>>   }
>> 
>> However, this doesn't work (dmd 2.065 linux64), because:
>> "Error: variable i cannot be read at compile time"
> [...]
>
> Try this:
>
> 	import std.typecons : staticIota;
> 	foreach (i; staticIota!(0, T.length))
> 		modTuple[i] = transTupleElem(argTuple[i]);
>
>
> T

staticIota is marked package in std.typecons
July 21, 2014
On Mon, Jul 21, 2014 at 06:48:45PM +0000, bearophile via Digitalmars-d-learn wrote:
> H. S. Teoh:
> 
> >It's already in std.typecons.
> 
> But it is not online yet?
[...]

Hmph. Apparently it is undocumented. :-/  It has been in Phobos since last April, but was private until November when it became 'package'.

Hold on a sec... so how is it that my code compiles with it?! Apparently some package protection bug? Sigh...

Recently there was a pull request that implements static foreach / static while, but I can't seem to find it anymore. It's clear that this functionality is desirable. Maybe we should rouse a racket on the main D forum to either make staticIota public, or implement static foreach. ;-)


T

-- 
People tell me I'm stubborn, but I refuse to accept it!
July 22, 2014
On Monday, 21 July 2014 at 19:02:59 UTC, H. S. Teoh via Digitalmars-d-learn wrote:
> functionality is desirable. Maybe we should rouse a racket on the main D
> forum to either make staticIota public, or implement static foreach. ;-)

static switch would be so sick. I frequently find myself doing some compile-time branching with more than 2 branches or with an enum (like for policies/strategies/whatever). Compile-time case labels would clean that code up, and final switch would be a maintenance improvement as well.

static while sounds cool, but how would it work? (as in use case, not implementation). The condition would have to be immutable, wouldn't it?
July 22, 2014
On Tue, Jul 22, 2014 at 02:47:51AM +0000, Vlad Levenfeld via Digitalmars-d-learn wrote:
> On Monday, 21 July 2014 at 19:02:59 UTC, H. S. Teoh via Digitalmars-d-learn wrote:
> >functionality is desirable. Maybe we should rouse a racket on the main D forum to either make staticIota public, or implement static foreach. ;-)
> 
> static switch would be so sick. I frequently find myself doing some compile-time branching with more than 2 branches or with an enum (like for policies/strategies/whatever). Compile-time case labels would clean that code up, and final switch would be a maintenance improvement as well.
> 
> static while sounds cool, but how would it work? (as in use case, not implementation). The condition would have to be immutable, wouldn't it?

I don't know about use cases in general, but one place where it comes in handy is in iterating over template argument lists ("type tuples"). Currently, I have to resort to:

	Tuple!(int,int,int,int,int) fields;
	foreach (i; staticIota!(0, n))
	{
		fields[i]++; // for example
	}

Which is not bad for simple operations, but would be cleaner if we had static while / static foreach.


T

-- 
We've all heard that a million monkeys banging on a million typewriters will eventually reproduce the entire works of Shakespeare.  Now, thanks to the Internet, we know this is not true. -- Robert Wilensk
July 22, 2014
I'm just confused about how static while is supposed to work because static foreach, to my understanding, would have to work by making a new type for each iteration. I say this because, 1) runtime foreach works like that (with type => range), and 2) without ctfe foreach, the only way I know of to iterate a typelist is to make a new type with one less element, so I imagine static foreach lowers to that.

I suppose its possible to make a struct with static immutable start and end iterators, and make new types out of advancing the start iterator until it was equal to the end. Seems like a step backward though.

Anyway my actual question is: if all values are constant at compile time, how would a static while loop terminate?
July 22, 2014
On Tue, Jul 22, 2014 at 03:52:14PM +0000, Vlad Levenfeld via Digitalmars-d-learn wrote:
> I'm just confused about how static while is supposed to work because static foreach, to my understanding, would have to work by making a new type for each iteration. I say this because, 1) runtime foreach works like that (with type => range), and 2) without ctfe foreach, the only way I know of to iterate a typelist is to make a new type with one less element, so I imagine static foreach lowers to that.
> 
> I suppose its possible to make a struct with static immutable start and end iterators, and make new types out of advancing the start iterator until it was equal to the end. Seems like a step backward though.
> 
> Anyway my actual question is: if all values are constant at compile time, how would a static while loop terminate?

Basically, think of it as custom loop unrolling:

	TypeTuple!(
		int, "x",
		float, "y",
		uint, "z"
	) t;

	// This loop:
	foreach (i; staticIota(0, 3)) {
		t[i]++;
	}

	// Is equivalent to:
	t[0]++;
	t[1]++;
	t[2]++;

	// Which is equivalent to:
	t.x++;
	t.y++;
	t.z++;

The loop body is basically expanded for each iteration, with the loop variable suitably substituted with each element of the typelist.


T

-- 
Microsoft is to operating systems & security ... what McDonalds is to gourmet cooking.
July 22, 2014
On Tuesday, 22 July 2014 at 16:42:14 UTC, H. S. Teoh via Digitalmars-d-learn wrote:
> On Tue, Jul 22, 2014 at 03:52:14PM +0000, Vlad Levenfeld via Digitalmars-d-learn wrote:
>> Anyway my actual question is: if all values are constant at compile
>> time, how would a static while loop terminate?
>
> Basically, think of it as custom loop unrolling:
>
> 	TypeTuple!(
> 		int, "x",
> 		float, "y",
> 		uint, "z"
> 	) t;
>
> 	// This loop:
> 	foreach (i; staticIota(0, 3)) {
> 		t[i]++;
> 	}
>
> 	// Is equivalent to:
> 	t[0]++;
> 	t[1]++;
> 	t[2]++;
>
> 	// Which is equivalent to:
> 	t.x++;
> 	t.y++;
> 	t.z++;
>
> The loop body is basically expanded for each iteration, with the loop
> variable suitably substituted with each element of the typelist.

You're misunderstanding him. Your example is a static foreach, but Vlad asked about static while. I too don't see how a static while is supposed to work.