Re: What's up with GDC?

2016-06-11 Thread Christophe Meessen via Digitalmars-d-learn
Real professionals won't have difficulties to find binaries for ldc: 
https://github.com/ldc-developers/ldc/releases

--
Bien cordialement,
Ch.Meessen

> Le 10 juin 2016 à 22:30, Joerg Joergonson via Digitalmars-d-learn 
>  a écrit :
> 
>> On Friday, 10 June 2016 at 19:51:19 UTC, Johan Engelen wrote:
>>> On Friday, 10 June 2016 at 19:37:13 UTC, Joerg Joergonson wrote:
>>> arm-linux-genuabi? arm-linux-gnueableihfqueridsofeyfh?  
>>> aifh-fkeif-f-fdsskjhfkjfafaa?
>> 
>> Rofl!
>> 
>>> and ldc requires building from sources(actually I didn't have too much 
>>> trouble with installing it but it doesn't work with my libs because of the 
>>> crappy coff issues that D has had since birth(it's like a tumor)).
>> 
>> Why do you have to build from sources? Any details about the problems you 
>> see?
>> 
>> Thanks,
>>  Johan
> 
> Well, the post was a bit incoherent because getting all this stuff working 
> is. I was searching for ldc and ran across some web site that had only the 
> sources(same for gdc).
> 
> The point of it all is that things seem to be a bit discombobulated and make 
> D look bad.  Professions won't use D if it can't be used professionally(not 
> that I'm a pro, just saying).
> 
> Why isn't there a proper binaries for ldc and gdc that work out of the box 
> like dmd?  There used to be. What's up with all this arm-linux-genuabi crap? 
> When one opens up the archive all the files are named that way too.  There is 
> no explanation of what that means. Did some kid write this stuff in his 
> basement or is this suppose to be serious? Do people think about the end user 
> when creating this stuff or is it just a eureka moment "Lightbulb: Lets 
> create some spaghetti!".
> 
> I would have thought things would have gotten easier and more logical but 
> that doesn't seem to be the case.
> 
> 


Re: String compare in words?

2016-05-30 Thread Christophe Meessen via Digitalmars-d-learn
I didn't check assembly for '=='. What I have seen is that struct 
comparison in dmd is implemented as byte per byte compare even if the 
struct is 64bit long (e.g. Rebindable).  I suppose dmd uses this 
strategy because struct/array may not be 64bit aligned, or they could 
have different alignment.


In order to use the suggested optimization we need a good planet 
alignment.  The effort to check that, or enforce it, is not worth the 
benefit on average.


There could be a benefit in specific use cases where the alignment is 
ensured.


I would be interested in such optimization with Rebindable. Can the 'is' 
operator be overloaded ?



Le 30/05/2016 11:28, ag0aep6g via Digitalmars-d-learn a écrit :

On 05/29/2016 10:40 PM, qznc wrote:

bool string_cmp_opt(immutable(ubyte)[] x, immutable(ubyte)[] y) {


Having "string" in the function name may be a bit misleading. This 
doesn't have any special functionality for text/characters/Unicode, 
does it?


Should have const parameters, not immutable.


 pragma(inline, false);


I think you have to put this pragma on the function signature, not in 
the body. Also, why prevent inlining of the function?



 if (x.length != y.length) return false;
 int i=0;


int isn't large enough for array lengths.


 // word-wise compare is faster than byte-wise
 if (x.length > size_t.sizeof)
 for (; i < x.length - size_t.sizeof; i+=size_t.sizeof) {
 size_t* xw = cast(size_t*) &x[i];
 size_t* yw = cast(size_t*) &x[i];


Typo: Should be `&y[i]` here.


 if (*xw != *yw) return false;
 }
 // last sub-word part
 for (; i < x.length; i+=1) {
 if (x[i] != y[i]) // byte compare
 return false;
 }
 return true;
}

Any comments or recommendations?


Did you benchmark this against the built-in `==`, with ldc or gdc?

If this is correct and faster than the built-in `==`, why isn't it the 
built-in `==`?


--
Bien cordialement,

Ch.Meessen



Re: Maximum size of an string ?

2013-11-14 Thread Jean Christophe


Than you Ali :0
I assume it is for UTF8 encoding.
That's quite large enough.

JC

On Thursday, 14 November 2013 at 11:50:28 UTC, Ali Çehreli wrote:

On 11/14/2013 02:10 AM, Jean Christophe wrote:

> Has someone tested the maximum size of a D string variable
for both 32
> and 64 bits platforms ? Is it different from the maximum size
of a char[] ?

Both string and char[] are implemented in the same way: a 
size_t for length and a pointer to data. (D arrays know their 
sizes.)


So, the theoretical limit for both are size_t, which is the 
equivalent of uint or ulong dependending on 32-bit versus 
64-bit.


Ali




Maximum size of an string ?

2013-11-14 Thread Jean Christophe


Hi :)

Has someone tested the maximum size of a D string variable for 
both 32 and 64 bits platforms ? Is it different from the maximum 
size of a char[] ?


Oo`

-- JC


Re: fedora libcurl-gnutls issue

2013-11-13 Thread jean christophe

On Friday, 27 September 2013 at 19:44:18 UTC, Joshua Niehus wrote:

On Friday, 27 September 2013 at 16:52:49 UTC, Dicebot wrote:
Simply building dmd/phobos from git tag should result in 
proper linkage.


Nothing is ever simple with me :)

Thanks Dejan and Dicebot


+1, build phobos from sources on your Fedora platform.

Anyway in my case after doing that, which was ok, I finally moved 
to Debian which has much less stupid bugs than Fedora 19 and 
provides me a far more stable D programming environment.


Re: std.json

2013-11-13 Thread jean christophe

On Thursday, 17 May 2012 at 18:55:57 UTC, Jarl André wrote:

On Thursday, 17 May 2012 at 18:36:22 UTC, Jarl André wrote:

On Thursday, 17 May 2012 at 14:08:27 UTC, Vincent wrote:
On Sunday, 25 March 2012 at 17:50:45 UTC, Andrea Fontana 
wrote:

Hope it's clear...


Nope, it's something like chess and have nothing common with 
simplicity of the real JSON usage! This is example from C#:


var p = JsonConvert.DeserializeObject("{some real 
JSON, not crapy EOS}");

var str = JsonConvert.SerializeObject(p);

That's it! And this is how it SHOULD be implemented. Cannot 
catch why this stupid realization came to standard library... 
:((


I'm pretty new to D, but I am an expert Java developer, self 
claimed. I am fluent in many other languages as well. In all 
languages there is a basis documentation.


Read the documentation for parseJSON and you'll see that it 
should be possible to send in a straight JSON string. I think 
the complex example is a bit stupid. It scares developers away 
from the lang.


Feel free to correct me of course.


The final proof of exisiting simplicity :)

JSONValue[string] value = parseJSON("{ \"test\": \"1\"
}").object;
writeln(value["test"].str);

This outputs "1"



+1



Re: Range of random numbers

2012-04-25 Thread Christophe Travert
"bearophile" , dans le message (digitalmars.D.learn:35148), a écrit :
> Why don't you write a little benchmark to compare the performance 
> of the two versions?

Because I'm interested in the code's meaning for the human reader, not 
the performance.

I actually think : "map!(_=> uniform(a, b))(repeat(0))" is better, 
because it puts the call to uniform first, and the _ indicates that the 
rest is unimportant.


For you curiosity, this is the benchmark using:
gdc (GCC) 4.7.0 20120322 (gdc 0.31 - r805:0414cec152c7, using dmd 2.057)
and
gdc -O3 testRNG.d && ./a.out


import std.array, std.range, std.algorithm, std.random, std.stdio, 
std.datetime;

auto uniformRange1(T1, T2, T3)(T1 a, T2 b, T3 gen)
{
  return map!((x) {return x();} ) (repeat((){return uniform(a, b, gen);}));
}

auto uniformRange2(T1, T2, T3)(T1 a, T2 b, T3 gen)
{
  return map!((x) { return uniform(a, b, gen); })(repeat(0));
}

auto uniformRange3(T1, T2, T3)(T1 a, T2 b, T3 gen)
{
  return map!((x) { return uniform(a, b, gen); })(cycle([0]));
}

void f1() { auto ur = array(take(uniformRange1(0, 10, Xorshift(1)), 
1000)); }
void f2() { auto ur = array(take(uniformRange2(0, 10, Xorshift(1)), 
1000)); }
void f3() { auto ur = array(take(uniformRange3(0, 10, Xorshift(1)), 
1000)); }

void main() {
  auto b=benchmark!(f1, f2, f3)(1000);
  writeln(b[0].to!("seconds",double),"s,  ", b[1].to!("seconds",double),
"s, ", b[2].to!("seconds",double),"s." );
  // outputs :
  // 0.040437s,  0.0393537s, 0.0486439s
}


f2 performs 23% better than f3, and 3% better than f1.

-- 
Christophe


Re: Range of random numbers

2012-04-24 Thread Christophe
"bearophile" , dans le message (digitalmars.D.learn:35108), a écrit :
> What about (untested):
> 
> auto uniformRange(T1 lower, T2 upper) {
>  return count().map!(_ => uniform(lower, upper))();
> }

That looks like a workarround, not meaningful code.

How about
  return repeat(_ =>uniform(lower, upper)).map!(x => x())();
?

We could also use a template to make a range out of a delegate and avoid 
this workarround...

struct RepeatDg(T)
{
  T delegate() dg;
  this(T delegate() dg_) { dg = dg_; }

  @property enum bool empty = false;
  @property T front() { return dg(); }
  @property void popFront() {}
}
  


Re: Allow empty field function arguments for default?

2012-04-23 Thread Christophe
"Jakob Ovrum" , dans le message (digitalmars.D.learn:34971), a écrit :
> That is exactly the problem though, it can silently change the 
> behaviour of existing code. It is the worst kind of breaking 
> change, hence I don't think it will ever be in D in this form, 
> much less the current iteration of the language.

Hum, an acceptable solution would be to give an error, asking to 
explicitely asking to fully qualify the name :

void fun(int c = 0) {...}

void main()
{
  int c;
  fun(c=5); // error, ambiguous qualifier "c"
  fun(main.c = 5); // ok
  fun((c=5)); // ok
  fun(fun.c = 5); // ok, but different meaning.
}

But still, raising an arror is not backward compatible.

-- 
Christophe


Re: Allow empty field function arguments for default?

2012-04-20 Thread Christophe
"Jakob Ovrum" , dans le message (digitalmars.D.learn:34948), a écrit :
> On Thursday, 19 April 2012 at 18:34:41 UTC, Jacob Carlborg wrote:
>>
>> Named arguments would probably be better for this.
>>
>> fun(c = 5);
> 
> Maybe so, but `fun(c = 5);` is not an additive change, while the 
> OP's suggestion actually is.

How about

int c;
fun(c = 5);

?

-- 
Christophe


Re: Access violation using chain()

2012-04-19 Thread Christophe
"Brad Anderson" , dans le message (digitalmars.D.learn:34902), a écrit :
> Perhaps I'm just misunderstanding something about closures but 
> the following code seems to behave oddly:
> 
>  import std.stdio, std.range, std.algorithm, std.string;
> 
>  void main()
>  {
>  auto lst = ["a", "b"];
>  auto rng = range_gen(lst);
>  writeln(rng.take(5));
>  }
>  auto range_gen(string[] lst)
>  {
>  auto a = sequence!"n+1"().map!(a=>format("%s%d", lst[0], 
> a))();
>  return chain(lst, a); // access violation
>  //return a; // works
>  }

My guess is that chain takes lst by reference, just like the delegates 
for map, wo both are working on the same slice instance. The chain first 
pops elements from lst, and then calls the mapped sequence. At that 
time, lst is empty.

You can just copy lst before you give it to chain (or to map's delegate) 
to solve this bug:

auto range_gen(string[] lst)
{
 auto a = sequence!"n+1"().map!(a=>format("%s%d", lst[0], a))();
 string[] lst2 = lst;
 return chain(lst2, a); // access violation
}



Re: Static Associative Arrays

2012-04-12 Thread Christophe
Jonathan M Davis , dans le message (digitalmars.D.learn:34332), a
 écrit :
> On Sunday, April 08, 2012 01:24:02 Caligo wrote:
>> On Sat, Apr 7, 2012 at 11:01 PM, Jonathan M Davis  
> wrote:
>> > What do you mean my static associative arrays? Are you asking why you
>> > can't
>> > initialize a static variable which is an AA at compile time? e.g.
>> > 
>> > - Jonathan M Davis
>> 
>> The same way I can create a static array:
>> 
>> int[4] = [1, 3, 4, 8];  // has value semantics
>> 
>> and dynamic arrays:
>> 
>> int[] = [1, 4, 2, 4];  // has reference semantics
>> 
>> I want an associative array that has value semantics and it's size
>> doesn't change, just like static arrays.
> 
> Associative arrays are always on the heap. They always have reference 
> semantics. It would be very expensive to have an AA with value semantics. 
> They 
> contains pointers all over the place. It would be equivalent to calling dup 
> on 
> them every time that you pass them to anything. And trying to put one on the 
> stack would get very messy because all of the pointers involved. AAs are 
> _completely_ different from dynamic and static arrays. Aside from the fact 
> that 
> they both have array in their name and both allow indexing of a sort, there's 
> really no relation between them at all.

Yet, one could imagine an associative array with a fixed size and fixed 
indexes, with no pointers. We could define a simple structure with a 
static array to store the data and methods to find the element 
associated with a key. But we could not use this structure in place of a 
classic associative array (for that we would need pointers obviously).


Re: Questions about the slice operator

2012-04-05 Thread Christophe
"Jonathan M Davis" , dans le message (digitalmars.D.learn:34243), a
> Except that opSlice already works with "..". What would this buy you?

Having a specific range for a .. operator allows you to have them as 
parameters of any function.

For example, this could be nice for multidimensional slicing:
Matrix!(double, 6, 6) A;
auto partOfA = A[1..3, 4..6];

Operations on several items of a container:
Container B;
B.remove(4..9); // remove 5 contiguous elements.

etc.



Re: writing iterators without code duplication. inout?

2011-12-21 Thread Christophe
"pompei2" , dans le message (digitalmars.D.learn:31164), a écrit :
> This is what I have, which works but has severe code duplication. 
> I hoped inout would help me here, but I just can't figure it out. 
> I also gave a try to ranges, but same thing again: I can only get 
> it to work if I define my things twice.


It's not optimal, and there is an ugly cast, but maybe this is a 
suitable workarrond for you :

  int delegate(int delegate(ref int)) doIter() const
{
  return (int delegate(ref int) dg)
{
  cast(typeof(this))(this).doIter()((ref int i) { int copy = i; 
dg(copy); });
}   
}


Until
  int delegate(ref inout int) opApply() inout;
and
  int delegate(int delegate(ref inout int)) doIter() inout;
are made to work. (I actually don't know if there is any obstacles to do 
this).


Re: newbie question: Can D do this?

2011-12-21 Thread Christophe
Timon Gehr , dans le message (digitalmars.D.learn:31142), a écrit :
> On 12/20/2011 03:18 PM, clk wrote:
>> Thank you for your quick replies. I'm impressed by the helpfulness and
>> dedication of the D community!
>> Here's another one. Is there a way to pass arguments to functions by
>> keyword as in the calls to f and g below?
>>
>> void f(int a = 0, int b = 1) {}
>> void g(int a) {}
>>
>> void main() {
>> f(b = 1, a = 0); // compile error
>> g(a = 0); // also compile error
>> }
>>
>>
> 
> No, there are no named arguments in D. Having them would sometimes be 
> useful,

> but the drawback is that the parameter names become part of the 
> public interface.

Well, that's precisely the point. And it is a drawback if parameters are 
systematically names, but not if it is triggered only on demand.

Example :

void foo(int a, int b:, int c:);

void main() {
foo(1, 2, 3);
foo(1, c: 3, b: 2;
foo(a: 1, b: 2, c: 3); // error : a is not a named parameter.
}

In the example, ":" is used to make a named parameter to recall the use 
when you call the function.



Re: Abstract functions in child classes

2011-12-05 Thread Christophe

FWIW, I agree with Addam. One of the things I like in D is that the 
langage is designed so that interpretations are made based on what you 
intend, and what you intend to do is checked. That is exactly what is 
done by using overwrite keyword. If you intend to make a non-abstract 
class, the compiler should check it is non-abstract and complain if it 
is not. This way, the error message pops where it belongs, i.e. at the 
class definition, not somewhere in another file where it is 
instanciated. It is not hard to add a specific unittest close to the 
class definition to test instanciation, but this is still much harder 
than writing 'abstract' at the beginning of the class definition when 
you intend to make it abstract (which is also much shorter than writing 
a sentence to indicate that the class is abstract in the documentation).

For special use-cases, when you don't know if the class is abstract or 
not because it is a template, you should just be allowed to write 
something like 'auto abstract' and the problem is solved.

Is is a really a larger pain to make this correction early to the 
langage, than to keep this little misfeature for years ? With an 
appropriate (and optional) warning to tell abstract class will soon have 
to be declared such for several years before there is an (optional) 
error, and maybe even a patch to make the correction automatically, that 
should not be such a pain.

-- 
Christophe


Re: How come a thread can access another thread's stack variable?

2011-11-25 Thread Christophe
Andrej Mitrovic , dans le message (digitalmars.D.learn:30764), a écrit :
> import core.thread;
> import std.stdio;
> 
> struct Foo
> {
> int field;
> void test()
> {
> writeln("field: ", &field);
> }
> }
> 
> void main()
> {
> Foo foo;
> auto thread = new Thread(&foo.test);
> thread.start();
> thread.join();
> foo.test();
> }
> 
> This prints the same addresses. std.concurrency won't let you do this,
> while std.parallelism uses some form of "weaker isolation", and it
> seems core.thread has the same weaker isolation principle.
> 
> If "foo" is in TLS, how come a new thread can access its members?

It could with a cast to shared, couldn't it ?

A fix would be to make Thread check the shared-ness of context pointer 
of the delegate (which may have to be fixed at the compiler level).

-- 
Christophe


Re: Stop TypeTuple as template parameter from expanding

2011-11-04 Thread Christophe
bearophile , dans le message (digitalmars.D.learn:30429), a écrit :
> Tobias Pankrath:
> 
>> How would you do this? Do I need an extra template TypeList?
> 
> It's the design of typetuples, they are auto-flattening. I have never 
> appreciated this design. Maybe Walter likes them this way, or they 
> can't be designed in another way, I don't know.

You could always make them non-flattening by default, and create an 
operator to flatten them.


Re: std.container & ranges

2011-11-03 Thread Christophe
"Steven Schveighoffer" , dans le message (digitalmars.D.learn:30402), a
> The primitive for a container is remove(range).  Ranges are essential to  
> containers, and should be the major interface to them.

Programmers have to learn ranges to use containers. Hiding ranges is not 
helping them.

But here, it is more complicated than that, because range may be more 
powerful than iterators, they are less friendly to use when a single 
element reference has to be used.

c.remove(find(c.all, E));

will not remove the first occurence of E, but all elements beyond E.
so instead we have to write:

c.remove(take(find(c[], E), 1));

Then it's too much.

The problem is that range are not practical to refer to a single element 
in the container. We need to have single-element reference to manipulate 
the range. Then a function should be used to find such one-element 
reference. std.find is already taken, and can hardly be changed 
(although it should be name popUntil), but we can still use a find 
method of the container.

auto r = take(find(c[], E), 1);

should just be written:

auto r = c.find(E);

Then the syntax to remove a single element from c is acceptable:
c.remove(c.find(E)).

Now let us remove several consecutive elements from c, let us say, all 
elements between the value E and the next value F:

| auto r = find(c[], E);
| int i=0;
| foreach(e, r)
|   if (e == F) break;
|   else ++i;
| c.remove(take(r, i+1));

That is not practical at all, and in addition, it is not efficient, 
since r is walked again from E to F.

If we add little methods to single element reference to make them behave 
a little like iterators, we can recreate ranges from two single element 
references, and regain all the power of iterators. To remove all 
elements from E to the next F included:

auto r = c.find( E);
c.remove(r, r.find(F)++);
// or c.remove(range(r, r.find(F)++));

(I use the find method a bit like a joker in this exemple, it is just 
to get the idea).

In conclusion, to refer to a single element of a container for simple 
operations, range looses against iterator. Ranges even loose to refer to 
a range of consecutive elements...
Many alternatives are possible, but a simple iterator structure to refer 
to a single element, and that you can combine to recreate a range (and 
use all range algorithms) would be enough, and would complete the range 
interface to make them have no drawback against iterators.


Re: An issue with setting delegates via templates

2011-11-02 Thread Christophe Travert
Andrej Mitrovic , dans le message (digitalmars.D.learn:30315), a écrit :
> The new one: https://gist.github.com/1194497
> 
> I'll investigate this further then.

OK, so there is indeed a filter to find a suitable delegate to load:

@trusted T connect(T)(T handler) if(isHandler!(T, Types));

But only the first Bar.x function is picked and given to isHandler!(T, 
int) to check it can be called. Bar.x(double) do not pass this filter.

I guess if the signature were:

T connect(void handler(Types));
T connect(bool handler(Types));
etc...

or maybe
T connect(T : void handler(Types)) (T handler);
T connect(T : bool handler(Types)) (T handler);
etc...

Then the compiler should be able to select the right Bar.x method. But 
with the isHandler filter,it is not able to find it. I don't see a way 
to improve isHandler to make it able to find the right Bar.x method, 
without modification of the compiler*, but I am not an expert here.

* the compiler should allow all overloads of a function given as a 
template argument to be tested against the filter to choose the right 
one, and complain if several overloads match the filter.

-- 
Christophe


Re: std.container & ranges

2011-11-02 Thread Christophe
Kagamin , dans le message (digitalmars.D.learn:30362), a écrit :
> Steven Schveighoffer Wrote:
> 
>> ahem, using dcollections:
>> 
>> foreach(ref doRemove, cell; &organism.purge)
>>  doRemove = cell.x == x && cell.y == y;
>> 
>> complexity: O(n)
> 
> may be a generic iteration handler would be more useful?
> 
> foreach(ref handler, cell; &organism.each)
>if(cell.x == x && cell.y == y) handler.removeCurrent();
> 
> it could provide a whole api, say, you may want to have lookahead
> 
> foreach(ref handler, cell; &organism.each)
>if(cell.x == x && cell.y == y && handler.next.x==0)
>   handler.removeCurrent();


That's not easier than using Tobias' improved foreach:

foreach(cell, cellRange; organism[])
  if (cell.x == x && cell.y == y)
organism.remove(cellRange);


If you want to use algorithm specialized and optimized for the 
container, I would prefer to use purge than each + handler. purge seems 
better to me, because it can be specialized for the container and for 
the action, and do not require to learn a new handler structure. "each" 
do not seem to add a lot  to foreach(cell, cellRange; range), since it 
must be able to cope with any operation provided by handler, and any 
operation combinaisons...



Re: Implicit cast to immutable

2011-10-27 Thread Christophe
"Steven Schveighoffer" , dans le message (digitalmars.D.learn:30255), a
 écrit :
> On Fri, 21 Oct 2011 11:20:01 -0400, Christophe  
>  wrote:
> 
>> "Daniel Murphy" , dans le message (digitalmars.D.learn:30139), a écrit :
>>> "bearophile"  wrote in message
>>> news:j7jepi$prp$1...@digitalmars.com...
>>>> Daniel Murphy:
>>>>
>>>>> 2)
>>>>> immutable(int[]) fun() { return new int[]; } // conversion happens  
>>>>> here
>>>>> immutable x  = fun();
>>>>>
>>>>> Bearophile's example is of the second, where it definately matters  
>>>>> what
>>>>> the
>>>>> purity of the function is.
>>>>
>>>> This is the enhancement request I have written days ago:
>>>> http://d.puremagic.com/issues/show_bug.cgi?id=6783
>>>>
>>>> Bye,
>>>> bearophile
>>>
>>> Yes, and the problem in that report is that the function is const-pure,  
>>> not
>>> strong-pure.
>>> Without checking if the return type can contain a non-immutable  
>>> reference
>>> from the arguments, it is not safe to implicitly convert the result to
>>> immutable.
>>>
>>> eg.
>>> immutable(int[]) foo(in int[] x) { return x; }
>>> auto g = [1, 2, 3];
>>> auto a = foo(g.idup); //safe
>>> auto b = foo(g); // unsafe
>>>
>>> Checking at the call site is possible, but not from inside the function.
>>>
>>> int[] foo(in int[] x) { return new int[](3); }
>>> auto g = [1, 2, 3];
>>> immutable a = foo(g.idup); // safe
>>> immutable b = foo(g); // unsafe, and easily rejected
>>>
>>> In your example, it is safe as the argument is not returned.  Allowing  
>>> this
>>> in the general case requires checking (recursively) that the return type
>>> does not contain any types that any of the arguments can implicitly  
>>> convert
>>> to that are non-immutable.
>>
>> What is the rule ?
> 
> The theoretical rule should be, if it can be proven (except for the case  
> where a cast is used) the result is not a subset of the input, then the  
> result can be implicitly cast to immutable.
> 
> The actual rule may be more conservative, since it may be difficult to  
> prove it.

OK, it must be proven from the signature of the function alone, and not 
from the function body.

>> The result of
>> pure int[] foo(in int[] x);
>> is castable to immutable, since elements of x are not supposed to escape
>> the function.
>>
>> The result of
>> pure int[] foo(const int[] x);
>> is not, because the value return by foo may be elements of x.
> 
> Only via cast.  How does foo legally change const int[] data to int[] data  
> without a cast?
> 
> Note that the two functions you wrote are equivalent, since in translates  
> to "const scope" and scope does nothing to array parameters.
> 

I meant:
pure const(int)[] foo(const/in int[] x);

But I thought scope was transitive like const, so it had effect on 
arrays. I find it pretty useless like that. A transitive scope could be 
very useful for purity checking and memory management optimisations. It 
would be useful for implicit casting to immutable too, even in no pure 
function. I may write about that later in another thread.


Re: An issue with setting delegates via templates

2011-10-27 Thread Christophe
Andrej Mitrovic , dans le message (digitalmars.D.learn:30286), a écrit :
> class Foo
> {
> void func(double) { }
> void func(int) { }
> 
> void set(T)(T handler) { dg = handler; }
> void delegate(int) dg;
> }
> 
> void main()
> {
> auto foo = new Foo;
> foo.set(&foo.func);  // NG, func(double) is picked up first
> }
> 
> Error: cannot implicitly convert expression (handler) of type void
> delegate(double _param_0) to void delegate(int)
> 
> The problem here is that `void func(double)` is declared first, and
> that's what the address-of operator picks up. If you swap the two
> overloads this sample will compile.
> 
> How could this be worked around /while still using templates/? There
> can only be one topmost function overload, so with two overloads this
> can be worked around, but with more overloads this workaround can't be
> used.
> 
> I've almost found a workaround via the getOverloads trait:
> 
> import std.traits;
> 
> class Foo
> {
> void func(double) { }
> void func(int) { }
> 
> void set(T)(T handler)
> {
> dg = handler;
> }
> 
> void delegate(int) dg;
> }
> 
> void main()
> {
> auto foo = new Foo;
> foo.set(&__traits(getOverloads, foo, "func")[1]);
> }
> 
> This works, but I can't use this from within a template. IOW, I can't
> pass a function pointer to a template and then figure out if that
> function is actually an overload of some class. I'd need more powerful
> compile-time features for that. If I were able to do that then I could
> enumerate all the overloads and pick one if it matches the type of
> 'dg'. It's kind of overkill but it could work, at least theoretically.
> 
> Otherwise I'd really need a way to explicitly specify which function
> overload to pass when I use the address-of operator, but that would
> probably have to be a language feature.


Once you are inside set, handler is just a function and context pointer 
pair. Finding out what are the overloads of handler just with it's 
adress will be very complicated for a very limitted usage. Maybe an 
approach would be to make handler an alias rather than a delegate (but 
this won't work here because you have to pass foo along with 
&Foo.func...).

Why does Foo.set has to be a template ?
The obvious workarround is to make set expect a void delegate(int), 
instead of an undefined type, since this is the only type you can assign 
to dg.

I think I need a better example to understand why set is a template, and 
how to work arround that.



Re: FIFO stack

2011-10-27 Thread Christophe
"Nick Sabalausky" , dans le message (digitalmars.D.learn:30309), a
 écrit :
> "Dominic Jones"  wrote in message 
> news:j89arh$2ua3$1...@digitalmars.com...
>>> Also an plain array is a good stack. :)
>>
>> I'd rather not use a plain array because (I assume) that when I push
>> or pop using arrays, a swap array is created to resize the original.
>> If this is not the case, then an array will certainly do.
>> -Dominic
> 
> The matter of using D's arrays as a LIFO is discussed the other branch of 
> this thread (ie, you can do it, but it's slow because a "pop then push" will 
> reallocate and copy), but as far as a FIFO: That may actually be reasonable 
> to do as an array:
> 
> Decreasing the length of an array (from either end) is a trivial matter that 
> never allocates or copies. Appending to the end *usually* doesn't involve 
> allocating. So the only issue I see it that the FIFO will "march" across 
> memory. I guess that's probably not a problem as long as the GC knows it can 
> reclaim the stuff you've popped off (Does it do that? Ie, if you do "x = 
> x[10..$];" and there's no other references, is the GC smart enough to 
> reclaim those first ten spots? I guess I would assume so.) 
> 
> 

As far as I understand, if there is a pointer to an allocated memory 
block, the GC keeps the whole memory block. So the data at the beginning 
of x will be kept as long as x is not reallocated (but x will be 
reallocated at some point, because it can't walk across memory 
indefinitely, unless the GC is particularly efficient at avoiding 
reallocation).

AFAIC, if I had to design a FIFO, I would use a circular array to avoid 
constant growing and reallocation of the array.


Re: scope struct?

2011-10-23 Thread Christophe
Steve Teale , dans le message (digitalmars.D.learn:30117), a écrit :
> Is not needed because structs are inherently scope.
> 
> I'm sure experienced D programmers do this all the time when they want 
> something done on exit from a scope, but I never had, and maybe there are 
> others who haven't, particularly if coming from a C++ 'use classes for 
> everything' background.
> 
> import std.stdio;
> 
> bool glob;
> 
> struct Sentinel
> {
>void function() doit;
>bool already;
>this(void function() f)
>{
>   doit = f;
>   already = false;
>}
> 
>~this()
>{
>   if (!already)
>   {
>  writeln("Doing it now");
>  doit();
>   }
>   else
>  writeln("Won't bother");
>}
> 
>void dontBother() { already = true; }
> }
> 
> void reset() { glob = false; }
> 
> void main(string[] args)
> {
>glob = true;
>{
>   Sentinel s = Sentinel(&reset);
>   writeln("Doing stuff in the scope");
>   if (args.length >= 2 && args[1] == "db")
>  s.dontBother();
>}
>writeln(glob);
> }



void main(string[] args)
{
  glob = true;
  {
dontBother=false;
scope(exit)
{
  if (!dontBother)
{
  writeln("Doing it now");
  glob = false;
}
  else
{
  writeln("Don't bother");
}
 }

 writeln("Doing stuff in the scope");
 if (args.length >= 2 && args[1] == "db")
   dontBother() = true;
  }
  writeln(glob);
}


If you're not running a test with a lot of writing, the scope clause is 
just:

scope(exit) if (!dontBother) glob() = false;

The scope exit clause will be run even if you exit via an exception 
(just like the sentinel's dstructor).

As you can see, D as its own syntax to make things when the scope exits, 
so you don't need to build a sentinel struct.
http://d-programming-language.org/exception-safe.html


Re: Implicit cast to immutable

2011-10-21 Thread Christophe
"Daniel Murphy" , dans le message (digitalmars.D.learn:30139), a écrit :
> "bearophile"  wrote in message 
> news:j7jepi$prp$1...@digitalmars.com...
>> Daniel Murphy:
>>
>>> 2)
>>> immutable(int[]) fun() { return new int[]; } // conversion happens here
>>> immutable x  = fun();
>>>
>>> Bearophile's example is of the second, where it definately matters what 
>>> the
>>> purity of the function is.
>>
>> This is the enhancement request I have written days ago:
>> http://d.puremagic.com/issues/show_bug.cgi?id=6783
>>
>> Bye,
>> bearophile
> 
> Yes, and the problem in that report is that the function is const-pure, not 
> strong-pure.
> Without checking if the return type can contain a non-immutable reference 
> from the arguments, it is not safe to implicitly convert the result to 
> immutable.
> 
> eg.
> immutable(int[]) foo(in int[] x) { return x; }
> auto g = [1, 2, 3];
> auto a = foo(g.idup); //safe
> auto b = foo(g); // unsafe
> 
> Checking at the call site is possible, but not from inside the function.
> 
> int[] foo(in int[] x) { return new int[](3); }
> auto g = [1, 2, 3];
> immutable a = foo(g.idup); // safe
> immutable b = foo(g); // unsafe, and easily rejected
> 
> In your example, it is safe as the argument is not returned.  Allowing this 
> in the general case requires checking (recursively) that the return type 
> does not contain any types that any of the arguments can implicitly convert 
> to that are non-immutable. 

What is the rule ?
The result of a pure function can be cast to immutable if the arguments 
are immutable. That requires specific checking by the compiler. The real 
type of the argument prior to the conversion to the argument type has to 
be checked.

in, scope, or inout arguments are supposed to solve the problem with 
function site checking: without call-site checking, which are IMO a 
rather bad idea.

The result of
pure int[] foo(in int[] x);
is castable to immutable, since elements of x are not supposed to escape 
the function.

The result of
pure int[] foo(const int[] x);
is not, because the value return by foo may be elements of x.


Re: Ranges help

2011-10-14 Thread Christophe
Xinok , dans le message (digitalmars.D.learn:30054), a écrit :
> This is in relation to my sorting algorithm. This is what I need to 
> accomplish with ranges in the most efficient way possible:
> 
> 1. Merge sort - This involves copying elements to a temporary buffer, 
> which can simply be an array, then merging the two lists together. The 
> important thing is that it may merge left to right, or right to left, 
> which requires a bidirectional range.
> 
> c[] = a[0..$/2];
> foreach(a; arr) if(!b.empty && !c.empty) if(b.front <= c.front){
>   a = b.front; b.popFront();
> } else{
>   a = c.front; c.popFront();
> }
> 
> 2. Range swap - First, I need to do a binary search, which requires a 
> random access range. Then I need to swap two ranges of elements.
> 
> while(!a.empty && !b.empty){
>   swap(a.front, b.front);
>   a.popFront(); b.popFront();
> }
> 
> 
> That's the best I can come up with. I'm wondering if there's a more 
> efficient way to accomplish what I have above.
> 
> I also need to figure out the template constraints. Would this be 
> correct? Or would this be too much?
> 
> isRandomAccessRange && !isFiniteRange && isBidirectionalRange && hasSlicing


You should look at:
std.algorithm.SetUnion
std.algorithm.swapRanges

-- 
Christophe


Re: contrary of std.utf.toUTFz!(const(wchar)*)

2011-10-07 Thread Christophe
Trass3r , dans le message (digitalmars.D.learn:29978), a écrit :
>> I feel a little stupid, but how to convert  a wchar* zero terminated  
>> string into a wstring (DMD 2.055)?
> 
> wstring w = cstr[0 .. strlenw(cstr)];

if cstr comes from c code, you cannot guarantee it is immutable.

Moreover, cstr might point to 0.



Re: contrary of std.utf.toUTFz!(const(wchar)*)

2011-10-07 Thread Christophe
Paolo Invernizzi , dans le message (digitalmars.D.learn:29974), a
 écrit :
> Hi all,
> 
> I feel a little stupid, but how to convert  a wchar* zero terminated string 
> into a wstring (DMD 2.055)?
> I'm digging into Phobos, but right now I've found no way...
> 
> Thanks, Paolo.

std.conv.to!wstring


Re: Implicit cast to immutable

2011-10-06 Thread Christophe
bearophile , dans le message (digitalmars.D.learn:29961), a écrit :
> Andrej Mitrovic:
> 
>> Maybe:
>> 
>> immutable(int[]) foo(in int[] x) pure {
>>return new immutable(int[1]);
>> }
>> 
>> void main() {}
> 
> I'd like to know why the code in my original post doesn't compile. I suspect 
> it's a DMD bug, but I am not sure.

The error message tells you why. new int[1] is not castable to immutable 
int[] (in a pure function). The solution is to change new int[1] to make 
it immutable directly. That is very consistent, so I don't think this 
should be considered as a bug. There may be an improvement to ask to 
make the compiler able to check when the cast to immutable is safe, but 
I don't think there is a bug.

>> Or does this have something to do with implicit casts to immutable for
>> pure functions?
> 
> Right.
> 
> 
>> I'm only vaguely familiar with pure..
> 
> I suggest you to use purity more and more in D, because it helps and 
> with the recent bug fixes it is also becoming usable in D (but there 
> are some significant problems left, example: map/filter are not pure 
> yet).

You would need to have pure delegates to have a real effect, wouldn't 
you ?

-- 
Christophe


Re: int C function

2011-09-30 Thread Christophe
Ellery Newcomer , dans le message (digitalmars.D.learn:29885), a écrit :
> weird error. anyone know what's going on?
> 
> [ellery@localhost d]$ cat test.d
> extern(C) int puts(const char *s);
> class X{
> @property void tt(int function(const char *) xz){
> }
> }
> void main(){
> X x = new X();
> x.tt = &puts;
> }
> [ellery@localhost d]$ dmd test
> test.d(8): Error: function test.X.tt (int function(const const(char*))
> xz) is not callable using argument types (int C function(const
> const(char*) s))
> test.d(8): Error: cannot implicitly convert expression (& puts) of type
> int C function(const const(char*) s) to int function(const const(char*))

The compiler is actually quite explicit: puts is a C function, and X.tt 
expects a normal D function. You can solve your problem with a wrapper. 
Try:

int cPuts(const char* s) { return puts(s); }

and then :
x.tt = &cPuts();

By the way, it is not very d-ish to use an "int function(const char*)".
we prefer: "int delegate(const char[])". And then:
| int cPuts(const char[] s) { return puts(toStringz(s)); }
But it depends on what you exactly are trying to do.

toStringz can be found in std.string.

-- 
Christophe


Re: Why an abstract pointer cannot be used as value in an associate array?

2011-09-30 Thread Christophe
Cheng Wei , dans le message (digitalmars.D.learn:29865), a écrit :
> Thanks a lot. This solves the problem.
> 
> However, it breaks the abstractness. Now in D side, we can call
> auto v = ab(). This does not make sense, because then &v cannot be used
> in the C library.
> 
> I don't understand why when we manipulate AB*, D compiler needs to know
> the size of struct ab. Moreover, when we use AB*[int], the D compiler
> complains about there's no opHash defined for AB. I don't think they are
> necessary at all.

I guess D is not designed to use abstract classes because they are not 
needed in the language: the compiler reads all the symbols in the file 
before doing the real compilation, but there may be no real issue for 
the compiler, as long as you do not use the ab* for anything else than 
passing it to C code.
 
You could file an enhancement request to support abstract pointer for 
the sake of interoperability with C.

-- 
Christophe


Re: Why an abstract pointer cannot be used as value in an associate array?

2011-09-29 Thread Christophe
what is the error message ?


Re: Multithreaded file IO?

2011-09-29 Thread Christophe
Jerry , dans le message (digitalmars.D.learn:29830), a écrit :
> trav...@phare.normalesup.org (Christophe) writes:
> 
>> Jerry Quinn , dans le message (digitalmars.D.learn:29763), a écrit :
>>> What I really want is a shared fifo where the input is lines from a 
>>> file, and many workers grab something from the fifo.  They then push 
>>> their results into a shared reordering output queue.
>>
>> My 2 cent advice:
>>
>> Does the queue really has to be a file ?
>> You could read it completely before starting, and then just share 
>> your instructions as strings for example.
> 
> Yes, these files could be large enough that the memory cost of loading
> is an issue.  Also, I should be able to do this with input from stdin.
> 
> At this point, I'm trying to figure out how to implement a shared
> fifo in D as much as solve my original problem :-)

Ok, an idea then could be to make a separate thread that deal with the 
File object, or a big shared object well protected with a mutex, to
ditribute instructions that are as much immutable as possible.

Good luck.


Re: Using allSatisfy with template that takes multiple type arguments

2011-09-28 Thread Christophe
Andrej Mitrovic , dans le message (digitalmars.D.learn:29825), a écrit :
> Thanks for the tips guys. I have another similar issue now, I want to
> check whether a type passes any of the predicates I list. This would
> be similar to anySatisfy, however anySatisfy takes one predicate and
> multiple types, and what I need is one type and multiple predicates,
> e.g.:
> 
> anyPredicateSatisfy!(int, isNumeric, isIntegral);
> 
> I've tried copying anySatisfy's code and modifying it to work:
> 
> template anyPredicateSatisfy(T, F...)
> {
> static if (F.length == 0)
> {
> enum bool anySatisfy = false;
> }
> else static if (F.length == 1)
> {
> enum bool anySatisfy = (F[0])!T;
> }
> else
> {
> enum bool anySatisfy = (F[0])!T) || anySatisfy!(T, F[1 .. $]);
  ^ you mean anyPredicateSatisfy
> }
> }
> 
> But the compiler thinks I'm doing C-style casts so this doesn't work. Any 
> clues?



Re: Why is std.string.format a c-style variadic function?

2011-09-27 Thread Christophe
Ellery Newcomer , dans le message (digitalmars.D.learn:29819), a écrit :
> On 09/26/2011 11:15 AM, Andrej Mitrovic wrote:
>> On 9/26/11, Ellery Newcomer  wrote:
>>> std.metastrings.Format wouldn't be what you want, would it?
>>>
>> 
>> Yep it is, Jonathan mentioned it above.
> 
> thunderbird hates me. second time I give an answer made redundant by
> orphaned subthread.
> 

I've got the same problem with most of Jonathan's posts. I use flrn, an 
obsure news reader that nobody here probably knows about, so I thought 
it was just me. It seems that the Reference field in Jonathan's posts 
are unusual and break threads in some news reader.

Would anyone know a solution (either for Elley and me, or for Jonathan)?

-- 
Christophe



Re: How to check all values in a range are equal to some predicate?

2011-09-26 Thread Christophe
Andrej Mitrovic , dans le message (digitalmars.D.learn:29755), a écrit :
> I want to use this in my unittests:
> 
> assert(allEqual(Foo(1), obj1, obj2, obj3));
> 
> How would you implement a function like allEqual(needle, objects...) ?
> Maybe via reduce?


I would use find. (the code was not compiled/tested at all)

bool allEqual(R)(R r) if (isInputRange!R)
{
auto a = r.front;
r.popFront();
return find!(b){return a!=b;}(r).empty;
}


and direct '==' operator for tuples:

bool allEqual(T...)(T t)
{
return t[0] == t[1] && allEqual(t[0], t[2..$]);
}

with an appropriate filter if I want to make something nice.


-- 
Christophe


Re: Multithreaded file IO?

2011-09-26 Thread Christophe
Jerry Quinn , dans le message (digitalmars.D.learn:29763), a écrit :
> Lutger Blijdestijn Wrote:
> 
>> If you didn't know, the concurrency chapter of tdpl is a free chapter: 
>> http://www.informit.com/articles/article.aspx?p=1609144
>> 
>> It has an example of file copying with message passing: 
>> http://www.informit.com/articles/article.aspx?p=1609144&seqNum=7
> 
> What I really want is a shared fifo where the input is lines from a 
> file, and many workers grab something from the fifo.  They then push 
> their results into a shared reordering output queue.

My 2 cent advice:

Does the queue really has to be a file ?
You could read it completely before starting, and then just share 
your instructions as strings for example.

That may make your life easier.
I would actually use a file if I use multiprocessing, but not 
necessarily for multithreading.


Re: Wrong const attribute?

2011-09-23 Thread Christophe
Paolo Invernizzi , dans le message (digitalmars.D.learn:29680), a
 écrit :
> 
> --Apple-Mail-7--919646864
> Content-Transfer-Encoding: quoted-printable
> Content-Type: text/plain;
>   charset=us-ascii
> 
> Hi all,=20
> 
> I've found nothing on bugzilla for that, what I'm missing? Or it's a =
> bug? (DMD 2.055)
> 
> struct Bar {
> immutable int i;
> this(int j){ i =3D j; }
> }
> 
> struct Foo {
> Bar bar;
> }
> 
> void main(){
>=20
> auto b =3D Bar(1);
>=20
> auto f =3D Foo();
> f.bar =3D Bar(2); // Error: can only initialize const member bar =
> inside constructor
>=20
> }
> 

Since your Bar has am immutable member, you cannot assign a Bar 
instance, which is what you do in the line where there is an error.

If you want to perform an assignment, Bar.i cannot be immutable. If you 
really want Bar.i to be immutable, Foo must hold a pointer to Bar, so 
you can change this pointer, or Bar can be a class instead of a struct 
(which means Foo does contain a pointer to Bar, but you don't have to
notice it).

-- 
Christophe Travert


Re: toUTFz and WinAPI GetTextExtentPoint32W

2011-09-21 Thread Christophe Travert
> Here is a more readable and a bit faster version on dmd windows:
> 
> size_t utfCount(string text)
> {
>  size_t n = 0;
>  for (uint i=0; i   n += ((text[i]>>6)^0b10)? 1: 0;
>  return n;
> }

Nice. It is better with gdc linux 64bits too. I wanted to avoid 
conditional expressions like ?: but it's actually slightly faster that 
way.

And now people can't tell it is dangerous because it could return a 
fuzzy number.

Even faster, through less readable:

size_t utfLength(string text)
{
  size_t n=0;
  for (size_t i=0; i>6)^0b10) != 0);
  return n;
}

Let's see how we can boost std.utf.stride that way...

-- 
Christophe


Re: toUTFz and WinAPI GetTextExtentPoint32W

2011-09-21 Thread Christophe
> Actually, I don't buy it. I guess the reason it's faster is that it 
> doesn't check if the codepoint is valid.

Why should it ? The documentation of std.utf.count says the string must 
be validly encoded, not that it will enforce that it is.
Checking a string is valid everytime you use it would be very expensive.

Actually, std.range.walkLength does not check the sequence is valid. See 
this test:

void main()
{
  string text = "aléluyah";
  char[] text2 = text.dup;
  text2[3] = 'a';
  writeln(walkLength(text2)); // outputs: 8
  writeln(text2); // outputs: al\303aluyah
}

There is probably a way to check an utf sequence is valid with an 
unrollable loop.

> In fact you can easily get ridiculous overflowed "negative" lengths. 
> Maybe we can put it here as unsafe and fast version though.

Unless I am mistaken, the minimum length myCount can return is 0 even 
if the string is invalid.

> Also check std.utf.stride to see if you can get it better, it's the 
> beast behind narrow string popFront.

stride does not make much checking. It can even return 5 or 6, which is 
not possible for a valid utf-8 string !

The equivalent of myCount to stride would be:

size_t myStride(char c)
{
// optional:
// if ( (((c>>7)+1)>>1) - (((c>>6)+1)>>2) + (((c>>3)+1)>>5))
// throw new UtfException("Not the start of the UTF-8 sequence");
return 1 + (((c>>6)+1)>>2) + (((c>>5)+1)>>3) + (((c>>4)+1)>>4);
}

That I compared to:

size_t utfLikeStride(char c)
{
  // optional:
  // immutable result = UTF8stride[c];
  // if (result == 0xFF)
  // throw new UtfException("Not the start of the UTF-8 sequence");
  // return result;
  return UTF8stride[c];
}

One table lookup is replaced by byte some arythmetic in myStride.

I also took only one char as input, since stride only looked at the i-th 
character. Actually, if stride signature is kept to uint "stride(char[] 
s, int i)", I did not find any change with -O3.

Average times for "a lot" of calls:
(compiled with gcc, tested with -O3 and a homogenous distribution of 
"valid" characters from '\x00'..'\x7F' and '\xC2'..'\xF4')

myStride no throws:  1112ms.
utfLikeStride no throws: 1433ms.
utfLikeStride throws:1868ms. (the current implementation).
myStride throws: 8269ms.

Removing throws from utfLikeStride makes it about 25% faster.
Removing throws from myStride makes it about 7 times faster.

With -O0, myStride gets less 10% slower than utfLikeStride (no throws).

In conclusion, the fastest implementation is myStride without throws, 
and it beats the current implementation by about 40%. Changing 
std.utf.stride may be desirable. As I said earlier, the throws do 
not enforce the validity of the string. Really checking the validity of 
the string would cost much more, which may not be desirable, so why 
bother checking at all? A more serious benchmark could justify to change 
std.utf.stride. The improvement could be even better in real situation, 
because the lookup table of utfLikeStride may not be always at hand - 
this actually really depends on what the compiler does.

In any case, this may not improve walkLength by more than a few 
percents.

-- 
Christophe

now I'll go back to my real work...


Re: toUTFz and WinAPI GetTextExtentPoint32W

2011-09-20 Thread Christophe
Timon Gehr , dans le message (digitalmars.D.learn:29641), a écrit :
>> Last point: WalkLength is not optimized for strings.
>> std.utf.count should be.
>>
>> This short implementation of count was 3 to 8 times faster than
>> walkLength is a simple benchmark:
>>
>> size_t myCount(string text)
>> {
>>size_t n = text.length;
>>for (uint i=0; i>  {
>>auto s = text[i]>>6;
>>n -= (s>>1) - ((s+1)>>2);
>>  }
>>return n;
>> }
>>
>> (compiled with gdc on 64 bits, the sample text was the introduction of
>> french wikipedia UTF-8 article down to the sommaire -
>> http://fr.wikipedia.org/wiki/UTF-8 ).
>>
>> The reason is that the loop can be unrolled by the compiler.
> 
> Very good point, you might want to file an enhancement request. It would 
> make the functionality different enough to prevent count from being 
> removed: walkLength throws on an invalid UTF sequence.

I would be glad to do so, but I am quite new here, so I don't know how 
to. A little pointer could help.

-- 
Christophe


Re: toUTFz and WinAPI GetTextExtentPoint32W

2011-09-20 Thread Christophe
"Jonathan M Davis" , dans le message (digitalmars.D.learn:29637), a
 écrit :
> On Tuesday, September 20, 2011 14:43 Andrej Mitrovic wrote:
>> On 9/20/11, Jonathan M Davis  wrote:
>> > Or std.range.walkLength. I don't know why we really have std.utf.count. I
>> > just
>> > calls walkLength anyway. I suspect that it's a function that predates
>> > walkLength and was made to use walkLength after walkLength was
>> > introduced. But
>> > it's kind of pointless now.
>> > 
>> > - Jonathan M Davis
>> 
>> I don't think having better-named aliases is a bad thing. Although now
>> I'm seeing it's not just an alias but a function.
> 

std.utf.count has on advantage: someone looking for the function will 
find it. The programmer might not look in std.range to find a function 
about UFT strings, and even if he did, it is not indicated in walkLength 
that it works with (narrow) strings the way it does. To know you can use 
walklength, you must know that:
-popFront works differently in string.
-hasLength is not true for strings.
-what is walkLength.

So yes, you experienced programmer don't need std.utf.count, but newbies 
do.

Last point: WalkLength is not optimized for strings.
std.utf.count should be.

This short implementation of count was 3 to 8 times faster than 
walkLength is a simple benchmark:

size_t myCount(string text)
{
  size_t n = text.length;
  for (uint i=0; i>6;
  n -= (s>>1) - ((s+1)>>2);
}
  return n;
}

(compiled with gdc on 64 bits, the sample text was the introduction of 
french wikipedia UTF-8 article down to the sommaire - 
http://fr.wikipedia.org/wiki/UTF-8 ).

The reason is that the loop can be unrolled by the compiler.


Re: Dynamic Array Question

2011-09-20 Thread Christophe
> To avoid having to change your other code, I'd do this:
> 
> wchar[] t = ...;
> scope(exit) delete t; // add this line to the end of the function (after  
> returning)
> 
> There is another way, but it's not as easy:
> 
> // put this at the top of file
> import core.memory;
> 
> ...
> 
> scope(exit) GC.free(t.ptr);

does "scope wchar[] t = ...;" work too ?


Re: const->immutable array argument?

2011-09-20 Thread Christophe
bearophile , dans le message (digitalmars.D.learn:29609), a écrit :
> what's wrong in this code?
> 
> 
> void foo(const ref int[5] a) {}
> void main() {
> immutable int[5] arr;
> foo(arr); // Error?
> }

I don't think it is wrong. Did you try changind the order of const and 
ref, or adding parenthesis ?


Re: Why can't templates with default arguments be instantiated without the bang syntax?

2011-09-15 Thread Christophe
"Simen Kjaeraas" , dans le message (digitalmars.D.learn:29539), a
 écrit :
> On Thu, 15 Sep 2011 16:46:24 +0200, Andrej Mitrovic  
>  wrote:
> 
>> struct Foo(T = int) {}
>>
>> void main()
>> {
>> Foo foo;  // fail
>> Foo!() bar;  // ok
>> }
>>
>> It would be very convenient to be able to default to one type like this.
>>
>> For example, in CairoD there's a Point structure which takes doubles
>> as its storage type, and then there's PointInt that takes ints. The
>> reason they're not both a template Point() that takes a type argument
>> is because in most cases the user will use the Point structure with
>> doubles, and only in rare cases Point with ints. So to simplify code
>> one doesn't have to write Point!double in all of their code, but
>> simply Point.
>>
>> If the bang syntax wasn't required in presence of default arguments
>> then these workarounds wouldn't be needed.
> 
> How would you then pass a single-argument template as a template alias
> parameter?
> 
> Example:
> 
> template Foo( ) {
>  template Bar( ) {
>  }
> }
> 
> template Baz(alias A) {
>  mixin A!();
> }
> 
> void main( ) {
>  mixin Baz!Foo;
> }
> 
> Does this mixin Foo or Bar to main's scope?

I don't get the problem. Maybe I am not used to mixin enough. Can you 
mixin normal templates, and not only mixin templates ?

Anyway, why would this mixin Bar ?
As I understand the proposition, only "mixin Baz!(Foo.Bar);" and of 
course "mixin Baz!(Foo!().Bar)" should mixin Bar.

-- 
Christophe


Re: Should the 2.054 feature about warning on implicit fallthrough

2011-09-15 Thread Christophe
bearophile , dans le message (digitalmars.D.learn:29532), a écrit :
> Well, I don't understand the error it gives :-) Are you able to explain it to 
> me?
> 
> 
> import std.stdio;
> void main() {
>  int i = 1;
>  switch(i) {
>  case 0:
>  writeln("case 0");
>  goto default; // needed here
>  aLabel:
>  writeln("a label");
>  default:
>  writeln("default");
>  // But always falls through here
>  }
> }
> 
> test.d(10): Error: switch case fallthrough - use 'goto default;' if intended

If there is a goto aLabel somewhere, the program could go to line 9. 
Then it should fall to the default statement, but the compiler asks for 
an explicit fallthrough, since default is not a simple label, but 
something like a case statement.

-- 
Christophe


Re: A question about purity

2011-09-13 Thread Christophe
bearophile , dans le message (digitalmars.D.learn:29490), a écrit :
> Jonathan M Davis:
> 
>> However, Foo.y is not encapsulated 
>> by a strongly pure function at all. Other functions can alter alter it. So, 
>> it 
>> breaks purity.
> 
> Thank you for your explanation :-)
> 
> So, let's change the situation a bit. If the struct Foo is the only 
> thing present in a module (to avoid someone to touch its private 
> members), and the y field is "private static" only foo2 is able to 
> touch it. In this case isn't foo2 weakly pure?

No, because you change a variable that is global, even if it is private.
In foo.foo1(), foo is changed, but it can be considered as an argument 
and a part of the result of foo1(). You cannot say this for Foo.y.

Here is an example to illustrate what was meant with "encapsulating with 
a pure function" :

struct Foo {
int x;
pure int foo1() {
return x++;
}
private static int y;
static pure int foo2() {
return Foo.y++; // not pure: a global variable changes
}
}

pure int test1(Foo foo)
{
  auto a = foo.foo1(); // nothing changes outside test1: only the local 
   // copy of foo changes.
  return a;
}

pure int test2()
{
  auto b = Foo.foo2(); // error: Foo.y changes
  return b;
}

void main()
{
  Foo foo;
  auto a = test1(foo); // only a copy of foo is changed.
  auto b = test1(foo);
  assert(a==b); // ok
  auto c = test2(); // error: Foo.y changes
  auto d = test2();
  assert(c==d); // fails if test2 was indeed run twice.
}



Re: package access specifier not usable within a class

2011-09-09 Thread Christophe
Christophe, dans le message (digitalmars.D.learn:29394), a écrit :
> Andrej Mitrovic , dans le message (digitalmars.D.learn:29388), a écrit :
>> abstract class Foo
>> {
>> package void test();
>> }
>> 
>> class Bar : Foo
>> {
>> override package void test() { }
>> }
>> 
>> function test.Bar.test cannot override a non-virtual function
>> 
>> TDPL says package can only be used at class-level (i.e. package class
>> Bar : Foo), outside classes or inside a struct.
>> 
>> I want to hide a virtual method from client code, but another free
>> function in a different module but in the same package as these
>> classes needs access to that method. Are there any technical reasons
>> why package is not allowed for virtual methods?
> 
> private function are not virtual.
> "All non-static non-private non-template member functions are virtual"
> The spirit of this is that if a function is private, it should not be 
> seen by its subclasses, which makes sens. However, this is a bit 
> inconsistent with the fact that it can actually be seen by the whole 
> file. It seems that package function inherited from the same behavior, 
> enlarging this inconsistency.
> 
> Your request seem to be reasonable, so I would say the langage should be 
> improved in two ways:
> - private (and package) function can be specifically made virtual, but  
> the problem is that virtual is not a keyword in d, and that would be 
> weird to have to write final sometimes, and virtual some other times.
> - package function are virtual by default, which is the best solution 
> IMO. It's not a huge problem if private methods cannot be virtual, if 
> you can make them package virtual.
> 
> In the meantime, I would make the method public, but prefix the name 
> with an underscore to indicate it is morally private. I agree that it is 
> relying on the client's good will.
> 
> -- 
> Christophe

I forgot about protected. Making the function protected may be fine.


Re: package access specifier not usable within a class

2011-09-09 Thread Christophe
Andrej Mitrovic , dans le message (digitalmars.D.learn:29388), a écrit :
> abstract class Foo
> {
> package void test();
> }
> 
> class Bar : Foo
> {
> override package void test() { }
> }
> 
> function test.Bar.test cannot override a non-virtual function
> 
> TDPL says package can only be used at class-level (i.e. package class
> Bar : Foo), outside classes or inside a struct.
> 
> I want to hide a virtual method from client code, but another free
> function in a different module but in the same package as these
> classes needs access to that method. Are there any technical reasons
> why package is not allowed for virtual methods?

private function are not virtual.
"All non-static non-private non-template member functions are virtual"
The spirit of this is that if a function is private, it should not be 
seen by its subclasses, which makes sens. However, this is a bit 
inconsistent with the fact that it can actually be seen by the whole 
file. It seems that package function inherited from the same behavior, 
enlarging this inconsistency.

Your request seem to be reasonable, so I would say the langage should be 
improved in two ways:
- private (and package) function can be specifically made virtual, but  
the problem is that virtual is not a keyword in d, and that would be 
weird to have to write final sometimes, and virtual some other times.
- package function are virtual by default, which is the best solution 
IMO. It's not a huge problem if private methods cannot be virtual, if 
you can make them package virtual.

In the meantime, I would make the method public, but prefix the name 
with an underscore to indicate it is morally private. I agree that it is 
relying on the client's good will.

-- 
Christophe


Re: How would I retrieve the stdout error message of a system/shell command?

2011-09-08 Thread Christophe
Justin Whear , dans le message (digitalmars.D.learn:29380), a écrit :
> That'll work if you don't mind normal output being mixed with error 
> messages.
> 
> 
> Timon Gehr wrote:
> 
>> On 09/08/2011 07:26 PM, Justin Whear wrote:
>>> The Posix solution is to use pipes. Basically, you'll want the parent
>>> process to set up a pipe for stderr, fork, then the child process uses
>>> the write end of the stderr while the parent reads from the other end.
>>> Not sure what the Windoze solution is.
>>> Alternatively, the cheap and easy way is to use redirects:
>>>
>>> system("dmd bla.d 2>error.log");
>>>
>>> If an error is thrown, read from error.log.
>> 
>> I think the easiest way on a posix system is this:
>> 
>> auto res=shell("dmd bla.d 2>&1");
>> 
>> I haven't tested it tough. What it should do is redirect dmd's stderr to
>> stdout, which can then be read.
> 

Well, if shell throws, it will not return, and the output will not be 
assigned to res.


Re: About static variables

2011-09-05 Thread Christophe
Nothing worth adding a confusing semantic to the langage. Just prefix 
your variable's name.
Nobody will want to use myFunctionPrivateVariable outside of myFunction:

class Foo {
  private size_t myFunctionPrivateCount;
  void myFunction() {
alias myFunctionPrivateCount count;
   // ..
   count++;
  } 
 
}



Re: opDispatch shadowing toString - feature or bug?

2011-09-01 Thread Christophe
Try to create the method:

const void toString(void delegate(const(char)[]) sink, string formatString)
{
  sink(toString());
}


Re: Create a foreach-able struct? Multi-dimensional even?

2011-08-25 Thread Christophe
> Still, is the multi-dimensional part possible?

Sure, you have to make an opApply that takes several parameters in its 
delegate.
An exemple:

struct TwoDArray(int nx, int ny)
{
  int[nx][ny] data;

  int opApply(int delegate(ref int i, ref int j, ref int cell)
{
  foreach (i; 0..nx)
foreach (j; 0..ny)
  {
int result = dg(i, j, data[i][j]);
if (result != 0) return result;
  }
   return 0;
}
}


// this program prints a multiplication table:
int main()
{
  TwoDArray!(10, 10) data;
  
  foreach(i, j, ref cell; data)
{
  cell = i * j;
}

  foreach(i, j, cell; data)
{
  writefln("%s * %s = %s", i, j, cell);
}
  return 0;
}



Re: reading in text files

2011-08-24 Thread Christophe
> The default stdin doesn't have an end, and unless you type something 
> in, there's no input at all. That's why the program just hangs.

You can end keyboard stdin by typing ^D (Ctrl + D) under unix.