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*) [i];
 size_t* yw = cast(size_t*) [i];


Typo: Should be `[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



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: 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




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.DeserializeObjectPerson({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: 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: 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-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 jmdavisp...@gmx.com 
 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: 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: 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: 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: 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: 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: 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: FIFO stack

2011-10-27 Thread Christophe
Nick Sabalausky , dans le message (digitalmars.D.learn:30309), a
 écrit :
 Dominic Jones dominic.jo...@qmul.ac.uk 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: 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  
 trav...@phare.normalesup.org wrote:
 
 Daniel Murphy , dans le message (digitalmars.D.learn:30139), a écrit :
 bearophile bearophileh...@lycos.com 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: 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 bearophileh...@lycos.com 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: 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: 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: 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: Why an abstract pointer cannot be used as value in an associate array?

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


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 ellery-newco...@utulsa.edu 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: 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
 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 ( (((c7)+1)1) - (((c6)+1)2) + (((c3)+1)5))
// throw new UtfException(Not the start of the UTF-8 sequence);
return 1 + (((c6)+1)2) + (((c5)+1)3) + (((c4)+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: 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: 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: 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 jmdavisp...@gmx.com 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; itext.length; ++i)
{
  auto s = text[i]6;
  n -= (s1) - ((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: 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; itext.length; ++i)
  {
auto s = text[i]6;
n -= (s1) - ((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: 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: 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  
 andrej.mitrov...@gmail.com 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: 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
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: 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: 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: 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.