Re: Dynamically Sized Structs

2014-04-17 Thread Steven Schveighoffer via Digitalmars-d-learn

On Thu, 17 Apr 2014 14:40:25 -0400, Kagamin s...@here.lot wrote:

So you assert that variable length structs can't be allocated on heap  
and sokoban example is a wrong example of variable length struct usage?


And how heap indirection is different from stack indirection? It's still  
indirection.


I think the biggest issue I would have with your implementation would be  
if I wrapped it in another struct that I wanted to store on the heap.


-Steve


Re: std.file.read returns void[] why?

2014-04-17 Thread Steven Schveighoffer via Digitalmars-d-learn
On Thu, 17 Apr 2014 17:04:25 -0400, monarch_dodra monarchdo...@gmail.com  
wrote:



On Thursday, 17 April 2014 at 12:59:20 UTC, Steven Schveighoffer wrote:

It was never possible. You must explicitly cast to void[].

void[] makes actually little sense as the result of whole-file read  
that allocates. byte[] is at least usable and more accurate. In fact,  
it's a little dangerous to use void[], since you could assign  
pointer-containing values to the void[] and it should be marked as  
NOSCAN (no pointers inside file data).


However, when using the more conventional read(void[]) makes a LOT of  
sense, since any T[] implicitly casts to void[].


-Steve


void[] will only make sense once you've accepted that void.sizeof == 1.


It is already accepted that when we talk about length in a void[], it's  
the number of bytes. But the data has no formal type.


But any array implicitly casts to void[]. This is why it makes a good  
parameter for read or write (when reading or writing the binary data).


Well, I guess void[] is C++'s char* for indiscriminate buffers.  
Speaking of which, does void* trigger strict aliasing in D? This  
subject seems like a hot potato no-one wants to touch.


No, it's equivalent to void *, not char *.

in D, ubyte[] would be the equivalent of C's char *.

-Steve


Re: std.file.read returns void[] why?

2014-04-18 Thread Steven Schveighoffer via Digitalmars-d-learn
On Fri, 18 Apr 2014 02:04:16 -0400, monarch_dodra monarchdo...@gmail.com  
wrote:



On Thursday, 17 April 2014 at 21:27:44 UTC, Steven Schveighoffer wrote:
On Thu, 17 Apr 2014 17:04:25 -0400, monarch_dodra  
monarchdo...@gmail.com wrote:
void[] will only make sense once you've accepted that void.sizeof ==  
1.


It is already accepted that when we talk about length in a void[], it's  
the number of bytes. But the data has no formal type.


Well, I always thought that void[] slice meant there are slice.length  
items, starting at slice.ptr. I don't know the size of the individual  
items.


For example, in C, a lot of functions take void* first, size_t num,  
size_t width.


In fact, most of druntime functions take void[] buffers that work that  
way. There's an associated typeid, so that you can now how large each  
individual items are.


import std.stdio;

void main()
{
   int[] x = new int[5];
   void[] y = x;
   writeln(y.length); // 20
}

When a function takes a typeid, that usually is because the translation is  
not made. In druntine cases, the compiler is removing the type, and  
sticking it into the typeid instead. But the length has not been  
translated to bytes! It's still in terms of the original type.


In those cases, it's equivalent to:

void[] y = *cast(void[]*)x;

which would make y.length == 5.

But any array implicitly casts to void[]. This is why it makes a good  
parameter for read or write (when reading or writing the binary data).


I guess. I just find it kind of strange that a type that has no type  
would have an actual sizeof. Then again, I thought void had no sizeof in  
C, but I just checked, and I was wrong.


It's a little strange, but while void has no size, void[] *does* have a  
size. The size is in bytes. You can think of an array as starts at this  
address, and ends at that address. Because addresses are in terms of  
bytes, so is the length of that array.


I admit, I didn't think C's void had a size ;) I'm pretty sure it doesn't  
in D, but then again...


-Steve


Re: Dynamically Sized Structs

2014-04-18 Thread Steven Schveighoffer via Digitalmars-d-learn

On Fri, 18 Apr 2014 00:05:03 -0400, Kagamin s...@here.lot wrote:

Well, it's proof of concept of bound checked variable-size struct, I  
wrote it in a minute. It even compiles and runs.


Please take no offense :) I just was pointing out a difference between a  
hand-managed and hand-written struct that I might have written and the one  
that you created. Depending on usage, yours might be sufficient.


Note, you could probably, with mixin magic, make a version that could be  
emplaced inside a struct or class without an extra indirection.


-Steve


Re: Dynamically Sized Structs

2014-04-18 Thread Steven Schveighoffer via Digitalmars-d-learn

On Fri, 18 Apr 2014 12:59:35 -0400, Kagamin s...@here.lot wrote:

Oh, and I don't believe, that a variable-size struct can be emplaced  
inside fixed-size struct or class. Only as a smart pointer from the  
example.


It goes at the end. Then you need to allocate the whole thing with that in  
mind.


-Steve


Re: Reducing an array

2014-04-18 Thread Steven Schveighoffer via Digitalmars-d-learn
On Thu, 17 Apr 2014 09:46:25 -0400, Tim Holzschuh via Digitalmars-d-learn  
digitalmars-d-learn@puremagic.com wrote:



Hi there,

I try to remove all equal elements of an array, thus [2,2] -- [2].

I thought this maybe would be possible with std.algorithm.reduce, but at  
least the way I tried it doesn't work:


arr.reduce( (a,b) = a != b );


reduce doesn't do what you think it does. It applies a function to all  
elements, keeping track of the result of each function call, and passing  
it to the next one.


In other words, reduce!fn(a, range) is like doing this:

fn(range[5], fn(range[4], fn(range[3], fn(range[2], fn(range[1],  
fn(range[0], a));


What you want is probably uniq:

http://dlang.org/library/std/algorithm/uniq.html

Note that it works on a SORTED range, so you want to sort first.

Note also that what it returns is not an array, but a lazily iterated  
range over the array. If you want another array, this is the code I would  
use:


arr.sort();
arr = arr.uniq.array();

-Steve


Re: toString() through interface

2014-04-21 Thread Steven Schveighoffer via Digitalmars-d-learn
On Sat, 19 Apr 2014 20:45:50 -0400, Adam D. Ruppe  
destructiona...@gmail.com wrote:



On Sunday, 20 April 2014 at 00:35:30 UTC, David Held wrote:

Since all implementations of an interface must derive from Object


That's not true. They can also come from IUnknown or a C++ interface.


This is also not true. Only interfaces derived from IUnknown point to a  
COM object. Only interfaces marked as extern(C++) can point to a C++  
object.


Any interface that is purely D MUST point at a D object that derives from  
Object, EVEN D-defined COM or C++ objects (the latter doesn't really  
exist).


His code should compile IMO.


cast(Object)(foo).toString();

(cast(Object)foo).toString() might work


This might return null tho if it is a non-D object through the interface!


As stated above, this is not possible.

-Steve


Re: toString() through interface

2014-04-21 Thread Steven Schveighoffer via Digitalmars-d-learn

On Sat, 19 Apr 2014 20:51:49 -0400, David Held d...@wyntrmute.com wrote:


On 4/19/2014 5:35 PM, David Held wrote:

interface Foo { }

class Bar : Foo
{
 override string toString() pure const { return Bar; }
}

void main()
{
 Foo foo = new Bar;
 foo.toString();
}


To make things more interesting, consider the call to toString() from  
inside a class (which is closer to my actual use case):


class Baz
{
 override string toString() pure const
 { return cast(Object)(foo).toString(); }

 Foo foo;
}

This really makes the compiler go bonkers:

src\Bug.d(11): Error: pure nested function 'toString' cannot access  
mutable data 'foo'
src\Bug.d(11): Error: pure nested function 'toString' cannot access  
mutable data 'foo'

src\Bug.d(11): Error: no property 'toString' for type 'Bug.Foo'
src\Bug.d(11): Error: pure nested function 'toString' cannot access  
mutable data 'foo'

src\Bug.d(11): Error: need 'this' for 'foo' of type 'Bug.Foo'

Apparently, DMD features high-availability error reporting, because  
the first message might not be received by the programmer, so it writes  
it again, then gives you a different message, and writes it one more  
time, just in case there was a communication error or some other fault  
preventing you from receiving this important message about access to  
'foo'.


Again, the cast appears to do absolutely nothing, as the compiler  
insists on looking up toString() in Foo instead of Object.  What is  
really peculiar is that message 1, 2, and 4 are complaining that  
Baz.toString() is not allowed to access foo because it is mutable.  And  
yet, the 5th error message tells us how to fix it: just add 'this.':


 override string toString() pure const
 { return cast(Object)(this.foo).toString(); }

Now we just get this:

src\Bug.d(11): Error: no property 'toString' for type 'const(Foo)'



To explain what the compiler is having trouble with, you have to  
understand precedence.


cast(Object) does not come before '.'

So what the compiler thinks you said is:

return cast(Object)(this.foo.toString());

Others have said how to fix it. I just wanted to point out why you need to  
fix it that way.


-Steve


Re: Regarding foreach loop index ranges

2014-04-21 Thread Steven Schveighoffer via Digitalmars-d-learn
On Mon, 21 Apr 2014 07:49:03 -0400, bearophile bearophileh...@lycos.com  
wrote:



In this case I am not sure about bug reports, so I ask here.

In this program the first loop doesn't compile, giving a nice error:

test.d(3,5): Error: index type 'ubyte' cannot cover index range 0..300

If you comment out the first loop, the second compiles and runs, but it  
seems to go in an infinite loop:



void main() {
 int[300] data;
 foreach (ubyte i, x; data)   {} // Error
 foreach (ubyte i, x; data[]) {} // compiles
}


For the second loop one possible alternative behavour is to refuse a  
ubyte index and accept only a size_t index if it loops on a dynamic  
array.
Another alternative is: the i variable can go from 0 to 255, then go up  
to the modulus of the remaining indexes, and then stop.


A third option is allow the code to compile, but throw an assert in  
non-release mode when the foreach statement is encountered ubyte cannot  
process all indexes of data.


This would be the least code-breaking option that saves a bug (you don't  
know that the code can handle modulo indexes).


Then you could deprecate to disallowing ubyte indexes.

-Steve


Re: Best way to check for an element in an array?

2014-04-22 Thread Steven Schveighoffer via Digitalmars-d-learn
On Mon, 21 Apr 2014 23:25:39 -0400, Taylor Hillegeist  
taylorh...@gmail.com wrote:


So I find myself Doing this kind of thing very frequently. I have a  
Array of Somethings and i want to see if something specific is inside  
the array. I wrote a template for it. but is this the best way to do  
this kind of thing. I feel like it doesn't help with readability. Is  
there a better way? Maybe i missed something in the std library.


import std.stdio;



Change this:


template FNDR(T){


To  this:

template isIn(T) {


 bool isIn(T Element, T[] Array){
 bool rtn=false;
 foreach(T ArrayElement; Array){
 if(Element==ArrayElement){
 rtn=true;
 }
 }
 return rtn;
 }
}

void main(string[] args)
{
 int[3] stuff=[0,1,2];
 if (FNDR!int.isIn(2,stuff))


now: if(isIn(2, stuff))

see implicit function template instantiation (IFTI) in docs.

Also, using UFCS (Unified Function Call Syntax (I think)), we can do:

if(2.isIn(stuff))

Or if you swap the parameters, and perhaps rename your template/function:

if(stuff.contains(2))


 {
 writeln(Hello World!);
 }
}


-Steve


Re: Named template constraints

2014-04-22 Thread Steven Schveighoffer via Digitalmars-d-learn
On Tue, 22 Apr 2014 10:58:41 -0400, Andrej Mitrovic via  
Digitalmars-d-learn digitalmars-d-learn@puremagic.com wrote:



On 4/22/14, Tim Holzschuh via Digitalmars-d-learn
digitalmars-d-learn@puremagic.com wrote:

What does (inout int = 0) mean/affect here?


This was asked recently, see my reponse here:
http://forum.dlang.org/post/mailman.102.1396007039.25518.digitalmars-d-le...@puremagic.com


I think this can be fixed a different way:

template isInputRange(R)
{
enum bool isInputRange = is(typeof(
(R r)
{
R r2 = R.init; // can define a range object
if (r.empty) {} // can test for empty
r.popFront(); // can invoke popFront()
auto h = r.front; // can get the front of the range
}));
}


Note, is the r2 = R.init needed? Not sure.

-Steve


Re: Named template constraints

2014-04-22 Thread Steven Schveighoffer via Digitalmars-d-learn
On Tue, 22 Apr 2014 11:15:14 -0400, monarch_dodra monarchdo...@gmail.com  
wrote:



On Tuesday, 22 April 2014 at 15:06:34 UTC, Steven Schveighoffer wrote:

Note, is the r2 = R.init needed? Not sure.


Yes: It R2 has no default init, or is an immutable, then that line will  
fail to compile.


I don't believe it's possible to have no 'init'.

I think the reason it says '= R.init' is for ranges that have @disable  
this().


Also, an immutable can be initialized that way:

immutable int[] = int[].init;

Of course, it wouldn't pass the rest of isInputRange.

-Steve


Re: Array of interface only with cast()?

2014-04-22 Thread Steven Schveighoffer via Digitalmars-d-learn

On Tue, 22 Apr 2014 11:19:57 -0400, Andre an...@s-e-a-p.de wrote:


Hi,

I just stumbled about this issue with array of interface. I want
to pass several objects (C and D) which shares the same interface A.
It seems somehow cumbersome that it only works if there is a cast on
the first element of the array.

interface A{}

class B: A{}

class C: B{};
class D: B{};

void main()
{
//A[] arr = [new C(), new D()]; // Does not work
A[] arr = [cast(A) new C(), new D()]; // Does work
}

Is the cast really needed?


At this point, yes. This is because the expression [new C(), new D()] does  
not take into account what you are assigning to (IMO it should).


The compiler will use the most derived type possible that all the elements  
implicitly cast to. In this case, it will be a B[].


-Steve


Re: The lifetime of reduce's internal seed

2014-04-22 Thread Steven Schveighoffer via Digitalmars-d-learn

On Tue, 22 Apr 2014 14:17:57 -0400, Ali Çehreli acehr...@yahoo.com wrote:

I don't think there is slicing an rvalue though. (?) reduce() is taking  
a copy of the seed and then returning a slice to it because the user  
slices it in their lambda. It effectively does the following, which  
unfortunately compiles:


int[] foo()
{
 int[1] sum;
 return sum[];// -- no warning
}


It's not slicing an rvalue, but the above is trivially no different than:

int[] foo()
{
   int[1] sum;
   return sum;
}

which does NOT compile.

The issue is that D's escape analysis is very very simplistic. It would be  
nice if it were better.


Ironically, because of return type inference in lambdas, you circumvented  
the check!


-Steve


Re: Named template constraints

2014-04-22 Thread Steven Schveighoffer via Digitalmars-d-learn
On Tue, 22 Apr 2014 11:36:07 -0400, monarch_dodra monarchdo...@gmail.com  
wrote:



On Tuesday, 22 April 2014 at 15:30:36 UTC, Steven Schveighoffer wrote:

Also, an immutable can be initialized that way:

immutable int[] = int[].init;


Isn't that exactly R.init ?


Yes, you said if it's an immutable it would fail to compile. I think this  
is not true.


-Steve


Re: The lifetime of reduce's internal seed

2014-04-22 Thread Steven Schveighoffer via Digitalmars-d-learn
On Tue, 22 Apr 2014 14:47:19 -0400, monarch_dodra monarchdo...@gmail.com  
wrote:



In this case no, but;
//
int[1] foo();
int[] a = foo();
//
*is* slicing an rvalue, and it *does* compile. I don't think there needs  
to be escape analysis to catch this.


Oh yeah, that's bad.

-Steve


Re: Named template constraints

2014-04-22 Thread Steven Schveighoffer via Digitalmars-d-learn
On Tue, 22 Apr 2014 14:50:44 -0400, monarch_dodra monarchdo...@gmail.com  
wrote:



On Tuesday, 22 April 2014 at 18:35:58 UTC, Steven Schveighoffer wrote:
On Tue, 22 Apr 2014 11:36:07 -0400, monarch_dodra  
monarchdo...@gmail.com wrote:



On Tuesday, 22 April 2014 at 15:30:36 UTC, Steven Schveighoffer wrote:

Also, an immutable can be initialized that way:

immutable int[] = int[].init;


Isn't that exactly R.init ?


Yes, you said if it's an immutable it would fail to compile. I think  
this is not true.


-Steve



Ah... you said:


Note, is the r2 = R.init needed? Not sure.


To whitch I replied:


Yes: It R2 has no default init, or is an immutable,
then that line will fail to compile.


I meant that if you *don't* add the R.init, then the code will *not*  
compile. EG = R.init is necessary.


Sorry for the mixup :/


OH!!! I meant is the whole *line* necessary, not the R.init part :)

Note that in my updated version, r is passed in as a parameter to the mock  
function. This means if R is inout(something), it will be part of the  
parameters, and you don't need a dummy inout parameter to shut the  
compiler up.


So the r2 = R.init; was just to keep things the same, but I'm not sure  
it's necessary to have. It has a comment saying can define a range  
object, whereas it could just be I need a range object to compile the  
rest of this code :)


-Steve


Re: Variable Naming Issue (Conflicts?)

2014-04-22 Thread Steven Schveighoffer via Digitalmars-d-learn

On Tue, 22 Apr 2014 15:35:33 -0400, Casey sybra...@gmail.com wrote:

If I prefix all of the generated variables with an underscore, it works  
fine.  It looks like the variable delete is the issue.  To me, it  
looks like it's expecting some sort of delete method.


delete is a keyword, it cannot be a symbol.

-Steve


Re: Undefined symbol ModuleInfoZ when including a SWIG generated module

2014-04-23 Thread Steven Schveighoffer via Digitalmars-d-learn
On Wed, 23 Apr 2014 20:34:11 -0400, Walter Gray walter.r.g...@gmail.com  
wrote:



Hi there,
  I'm currently trying to set up a small demo project using the Leap  
Motion API in D.  I've run SWIG with -d -d2, and created the  
intermediate C++ DLL along with a pair of .d files, leap.d and  
leap_im.d.  I'm new to D, but very interested and I'd like to set this  
up in an idiomatic way  be able to share it, but I'm running into a  
problem: When I create a simple sample project with Visual D and import  
the Leap module, I get a number of linker errors:


Error 42: Symbol Undefined  
_D4Leap10Controller6__ctorMFZC4Leap10Controller (Leap.Controller  
Leap.Controller.__ctor())

Error 42: Symbol Undefined _D4Leap10Controller7__ClassZ
Error 42: Symbol Undefined _D4Leap12__ModuleInfoZ

I've discovered that if I run dmd manually and link in the object files  
for leap.d and leap_im.d, these problems go away, and if I create a  
separate project to build a .lib and then link to that it also solves  
the issue.  Both of these options seem hacky to me though, and I'm  
wondering if there's some 3rd option I'm missing - the files contain the  
entire definitions, so why would it be necessary to link to them AND  
specify them as imports?  What am I missing here?


Every module in D generates a moduleinfo object. The runtime links all  
these together and uses it to run static constructors and destructors. It  
also contains runtime type info for any items defined within the module.


Even if a module has only templates, or even if it's empty! You still have  
to compile and include it in the link step if it's imported from a module  
you are compiling.


As for Visual D, I don't know much about how it works.

-Steve


Re: Is this a bug?

2014-04-28 Thread Steven Schveighoffer via Digitalmars-d-learn
On Mon, 28 Apr 2014 06:04:53 -0400, John Colvin  
john.loughran.col...@gmail.com wrote:



On Monday, 28 April 2014 at 09:36:08 UTC, Andrey wrote:

not a bug.

b.f[10] is indexing the pointer to the array, not the array itself.

b.f[0][10] is indexing the array (with the 10), but I would argue it  
is better to write *(b.f)[10] so as to be clear that f is not an array.


thank you, John.

compiler said that '*(b.f)[10]' is deprecated, and I should write like  
this


void foo()
{
   Type3 b;
   Type1  d;
   d = *(b.f[10]).ptr;
}


struct T
{
int[10]* f;
}

void main()
{
int[10] test;
T t = T(test);
T* b = t;

auto d = (*(b.f))[4]; //ugly but clear.
d = b.f[0][4]; //prettier but less clear.
}

note the extra brackets on the ugly one, I forgot them before.


You don't need them. (*b.f)[4] works. '.' has precedence over '*'.

-Steve


Re: Is this a bug?

2014-04-29 Thread Steven Schveighoffer via Digitalmars-d-learn

On Tue, 29 Apr 2014 03:43:54 -0400, Andrey n...@none.no wrote:


btw,

short a,b,c;

a = b + c; //error: cannot implicitly convert expression of type 'int'  
to 'short'


Guys!! Tell me that I have an old slutty version of the compiler...


No. It's due to integer promotion. All operations are done at the int  
level, so the expression b + c is actually an int. C allows this  
transgression because it's convenient. D makes you acknowledge that you  
are throwing away bits the compiler generated for you.


Note, += does work:

a = b;
a += c;

-Steve


Re: why arithmetic for bytes different than for ints?

2014-05-02 Thread Steven Schveighoffer via Digitalmars-d-learn
On Fri, 02 May 2014 16:32:54 -0400, Vlad Levenfeld vlevenf...@gmail.com  
wrote:



Dunno why I didn't try it earlier, but splitting it across lines like

y += 1;
y %= 2;
assert (y == 1);

works. So, bug, then?


Yes.

-Steve


Re: Any chance to avoid monitor field in my class?

2014-05-08 Thread Steven Schveighoffer via Digitalmars-d-learn

On Wed, 07 May 2014 10:44:55 -0400, Yuriy yuriy.gluk...@gmail.com wrote:

Hello, is there a way of reducing size of an empty class to just vtbl? I  
tried to declare it as extern(C++) which works, but has a nasty side  
effect of limited mangling.


The de-facto minimum size of a class is 16 bytes, due to the minimum block  
size of the heap.


8 bytes vtbl pointer on 64-bit systems would still allocate into 16-byte  
blocks.


-Steve


Re: Any chance to avoid monitor field in my class?

2014-05-08 Thread Steven Schveighoffer via Digitalmars-d-learn

On Thu, 08 May 2014 13:21:07 -0400, Yuriy yuriy.gluk...@gmail.com wrote:


On Thursday, 8 May 2014 at 14:57:37 UTC, Steven Schveighoffer wrote:
The de-facto minimum size of a class is 16 bytes, due to the minimum  
block size of the heap.


8 bytes vtbl pointer on 64-bit systems would still allocate into  
16-byte blocks.


-Steve


Yes, but still the question remains open for non-empty classes (e.g.  
want to use a 64bit useful payload), and for _emplacing_ any classes  
anywhere (e.g. on stack).


To what end? What are you trying to save?

Afaiu, there's no solution except for declaring extern(C++) (yes, i  
know, it's a hack), and it will not work, if a class is templated on  
something which can not be cpp-mangled. So the question is: is there any  
reason why this is not possible? I mean, maybe this question was closed  
long before.


It would not be derived from Object, which has the field. In other words,  
this would crash:


synchronized(cast(Object)obj) { ... }


Also, do shared classes actually require monitors?


Perhaps you meant unshared classes? No, they don't, but a monitor is only  
allocated on demand, so you don't have to worry about it.


However, note that it is perfectly acceptable to cast to and from shared  
as long as you guarantee the uniqueness of the reference. If the monitor  
is not present, this can cause problems.


-Steve


Re: Any chance to avoid monitor field in my class?

2014-05-08 Thread Steven Schveighoffer via Digitalmars-d-learn

On Thu, 08 May 2014 14:17:42 -0400, Yuriy yuriy.gluk...@gmail.com wrote:


On Thursday, 8 May 2014 at 17:49:01 UTC, Steven Schveighoffer wrote:

To what end? What are you trying to save?
I'm trying to reimplement std.variant in a nice OOP way, that supports  
CTFE, zero-size and a minimal amount of void*-casts. For that i'm using  
my VariantPayload(T) class, which i want to be as small as possible, as  
this is supposed to be an utility class which you never know how will be  
used.


Well, I don't think I know enough to judge whether what you are doing is  
worthwhile...


But my question more was about where do you plan to put so many of these  
objects that you will save a significant amount of bytes, aside from the  
heap (which already uses 16-byte blocks).


It would not be derived from Object, which has the field. In other  
words, this would crash:


synchronized(cast(Object)obj) { ... }
Wouldn't cast(Object) return null here, so that synchronized will throw  
or assert or smth? I see no reason for a crash.


Then what is this object? All D objects derive from Object.

Perhaps you meant unshared classes? No, they don't, but a monitor is  
only allocated on demand, so you don't have to worry about it.
Errm.. I'm not sure i understand the subject correctly, but according to  
Alexandrescu's book, a class declared as shared does not require  
synchronized() over it. I mean, it manages it's synchronization inside  
itself, and it's user just has to trust it. And if so, why ever  
synchronizing() on it?


The meaning of shared is not well defined. Even TDPL is outdated on this.

The idea in the book is that shared types would use memory barriers to  
ensure correct ordering of access, and correct data access. But it does  
not prevent races for multiple threads, you still need synchronized.


Unshared objects, on the other hand, should not ever need synchronization  
tools, since only one thread has access!


-Steve


Re: Any chance to avoid monitor field in my class?

2014-05-08 Thread Steven Schveighoffer via Digitalmars-d-learn

On Thu, 08 May 2014 15:47:46 -0400, Yuriy yuriy.gluk...@gmail.com wrote:

But my question more was about where do you plan to put so many of  
these objects that you will save a significant amount of bytes, aside  
from the heap (which already uses 16-byte blocks).

Hm.. Stack/emplace,


How many of these? In order to justify saving 8 bytes per instance, you  
have have a lot. I don't see emplacing thousands or tens of thousands of  
objects on the stack.



arrays, n-dimensional arrays?


Arrays of objects are stored as arrays of object references, with each one  
pointing at a separate block on the heap.


:) Besides, if we're talking of D as a system language to replace C++  
and to scratch everything out of a silicon wafer (also think of embedded  
platforms here), it's crucial for me to be able to control such things.  
From my experience, in a 5000-class project you would have about 20  
classes that need to be synchronized on. Moreover, mutex synchronization  
is not in fashion nowadays, as we tend to use transitional  
synchronization. And so my 4980 classes will contain an extra field i  
don't use. What?? =)


In D, class is not used for such things, struct is.



It would not be derived from Object, which has the field. In other  
words, this would crash:

Those are your words.


I'm assuming you want D classes, but without the monitor object. D classes  
derive from Object.





Then what is this object? All D objects derive from Object.

Those are your words also =)


Any chance to avoid monitor field in my class? Those are your words.  
What is it that you want?


The meaning of shared is not well defined. Even TDPL is outdated on  
this.


The idea in the book is that shared types would use memory barriers to  
ensure correct ordering of access, and correct data access. But it does  
not prevent races for multiple threads, you still need synchronized.
Yes, i understand that. By implementing a shared class, you're on your  
own with syncing, but also you tell the user, that your class doesn't  
need to be synchronized on. Right?


A defined shared class I think is supposed to imply that all its methods  
are shared (meaning the 'this' pointer must be shared). It does not imply  
that they are thread safe.


Unshared objects, on the other hand, should not ever need  
synchronization tools, since only one thread has access!

Here's two use-cases.
class A {}
shared class B {}

// Somewhere in code
{
 shared A sharedA; // This would need synchronized() on access.
 A unsharedA; // This would not. But since, the class is defined as  
unshared, we still will have __monitor in it, and that is good, since we  
can cast between unshared A and shared A.


 B b;
 shared B sharedB; // Here in both cases we know, that we will never  
need to sync on b or sharedB, as both of those are thread safe (it's  
not our business, how they do it, but they kinda are). So do we need  
this __monitor, which will never be used actually?

}


shared != thread safe. You still need to synchronize

-Steve


Re: Any chance to avoid monitor field in my class?

2014-05-08 Thread Steven Schveighoffer via Digitalmars-d-learn

On Thu, 08 May 2014 17:05:56 -0400, Yuriy yuriy.gluk...@gmail.com wrote:

How many of these? In order to justify saving 8 bytes per instance, you  
have have a lot. I don't see emplacing thousands or tens of thousands  
of objects on the stack.
Ok, i guess i have to agree with you. But. Why are you protecting  
__monitors so eagerly? :)


I'm not, I'm trying to help you justify the path your taking :) Because  
where it's currently leading is somewhere that D doesn't support. This  
means in order to support it, you have to maintain a parallel compiler, or  
somehow convince the compiler writers to add such support. Neither of  
these burdens is small.


Arrays of objects are stored as arrays of object references, with each  
one pointing at a separate block on the heap.
Or again you can emplace them in the heap, so that they occupy a  
continuous chunk.


This is not a good idea. The dtors of classes in the GC is stored per  
block, not per chunk of a block.



In D, class is not used for such things, struct is.
But classes have vtbls which is an ultimate feature for me, and  
moreover, it works in ctfe, while reinventing vtbls for ctfe might be  
a challenging task.


Removing the monitor could also prove quite challenging.

I don't doubt your reasons, but then again, you have what you have right  
now in D. Asking for more, you have to provide it, or convince others to.  
If it's the latter, you need to make a very very strong case.




I'm assuming you want D classes, but without the monitor object. D  
classes derive from Object.
Any chance to avoid monitor field in my class? Those are your words.  
What is it that you want?
Thats right. I was saying that extern(C++) almost suits me except for  
it's mangling. And you said that extern(C++) classes are not derived  
from Object? But still such objects would have RTTI which will forbid  
casting to Object, wouldn't they?


extern(C++) objects are not considered D objects. A D object can implement  
a C++ interface, but once you get to the C++ interface, you cannot go back.


This sounds to me very different from your goal.

-Steve


Re: why can't I call const methods on shared objects?

2014-05-09 Thread Steven Schveighoffer via Digitalmars-d-learn
On Fri, 09 May 2014 17:37:35 -0400, Vlad Levenfeld vlevenf...@gmail.com  
wrote:


Error: non-shared const method is not callable using a shared mutable  
object


Why not? If the method is const, it can't modify the object anyway.


Non-shared methods cannot be called on shared objects. Otherwise, you  
could have unintended race conditions.


-Steve


Re: why can't I call const methods on shared objects?

2014-05-09 Thread Steven Schveighoffer via Digitalmars-d-learn
On Fri, 09 May 2014 17:45:37 -0400, Vlad Levenfeld vlevenf...@gmail.com  
wrote:


Is there any way to declare a method as safe regardless of  
shared/mutability/etc (or some other way to avoid  
cast(Type)object.property every time I want to check a property which  
won't affect any state)?


Not really for shared. For everything else, there's const for value  
properties, and inout for reference properties.


Shared is quite different, because the method has to be cognizant of race  
conditions. It has to be implemented differently.


Casting away shared is somewhat dangerous, but OK if you logically know  
there is no race condition.


-Steve


Re: Array!T and find are slow

2014-05-15 Thread Steven Schveighoffer via Digitalmars-d-learn

On Wed, 14 May 2014 19:50:33 -0400, Meta jared...@gmail.com wrote:

On Wednesday, 14 May 2014 at 22:32:01 UTC, Jonathan M Davis via  
Digitalmars-d-learn wrote:
Yeah, much as Andrei would hate to hear it (enforce was his idea, and  
he quite
likes the idiom), the fact that lazy is so inefficient makes it so that  
it's
arguably bad practice to use it in high performance code. We really  
need to
find a way to make it so that lazy is optimized properly so that we  
_can_
safely use enforce, but for now, it's not a good idea unless the code  
that

you're working on can afford the performance hit.

Honestly, in general, I'd avoid most anything which uses lazy (e.g.  
that's why

I'd use explict try-catch blocks rather than use
std.exception.assumeWontThrow - like enforce, it's a nice idea, but  
it's too

expensive at this point).

- Jonathan M Davis


On the topic of lazy, why *is* it so slow, exactly?


Last time I remember, the issue is that functions with lazy parameters  
will never be inlined.


-Steve


Re: Why std.algorithm.sort can't be applied to char[]?

2014-05-15 Thread Steven Schveighoffer via Digitalmars-d-learn
On Wed, 14 May 2014 05:13:42 -0400, Jonathan M Davis via  
Digitalmars-d-learn digitalmars-d-learn@puremagic.com wrote:



On Wed, 14 May 2014 08:27:45 +
monarch_dodra via Digitalmars-d-learn
digitalmars-d-learn@puremagic.com wrote:


On Monday, 12 May 2014 at 18:44:22 UTC, Jonathan M Davis via
Digitalmars-d-learn wrote:
 Sure, you can cast char[] to ubyte[] and sort that if you know
 that the array
 only holds pure ASCII. In fact, you can use
 std.string.representation to do it
 - e.g.

 auto ascii = str.representation;

 and if str were mutable, then you could sort it. But that will
 only work if
 the string only contains ASCII characters. Regardless, he
 wanted to know why
 he couldn't sort char[], and I explained why - all strings are
 treated as
 ranges of dchar, making it so that if their element type is
 char or wchar, so
 they're not random access and thus can't be sorted.

Arguably, a smart enough implementation should know how to sort a
char[], while still preserving codepoint integrity.


I don't think that that can be done at the same algorithmic complexity  
though.
So, I don't know if that would be acceptable or not from the standpoint  
of

std.algorithm.sort. But even if it's a good idea, someone would have to
special case sort for char[], and no one has done that.


I think it can be done at O(nlgn) complexity, but you must allocate a  
block of scratch space to do the sorting. You can't do it in-place because  
swapping isn't available.


Might as well convert to dchar and back explicitly.

Merge sort may allow more promising speedups, but I still think you will  
need to allocate extra space.





As a matter of fact, the built in sort property does it.

void main()
{
 char[] s = éöeèûà.dup;
 s.sort;
 writeln(s);
}
//prints:
eàèéöû


I'm surprised. I thought that one of Bearophile's favorite complaints  
was that
it didn't sort unicode properly (and hence one of the reasons that it  
should

be removed). Regardless, I do think that it should be removed.


I can't believe this worked. I want to say that it's a freak accident for  
that set of characters. Looking in druntime, I don't see where the special  
case is.


-Steve


Re: Why std.algorithm.sort can't be applied to char[]?

2014-05-15 Thread Steven Schveighoffer via Digitalmars-d-learn
On Thu, 15 May 2014 11:37:07 -0400, monarch_dodra monarchdo...@gmail.com  
wrote:



On Thursday, 15 May 2014 at 13:26:45 UTC, Steven Schveighoffer
wrote:
On Wed, 14 May 2014 05:13:42 -0400, Jonathan M Davis via  
Digitalmars-d-learn digitalmars-d-learn@puremagic.com wrote:



On Wed, 14 May 2014 08:27:45 +
monarch_dodra via Digitalmars-d-learn
digitalmars-d-learn@puremagic.com wrote:

As a matter of fact, the built in sort property does it.

void main()
{
char[] s = éöeèûà.dup;
s.sort;
writeln(s);
}
//prints:
eàèéöû


I'm surprised. I thought that one of Bearophile's favorite complaints  
was that
it didn't sort unicode properly (and hence one of the reasons that it  
should

be removed). Regardless, I do think that it should be removed.


I can't believe this worked. I want to say that it's a freak accident  
for that set of characters. Looking in druntime, I don't see where the  
special case is.


-Steve


Must be a hell of a freak accident ;)

  auto s = é東öe京ûタèワà.dup;
  writeln(s.sort);

= eàèéöûタワ京東

It's in rt/adi.d


Seriously, I fucking hate the file names in druntime.

I looked in qsort.d.


extern (C) char[] _adSortChar(char[] a)

It's basically: string=dstring=sort=dstring=string.


OK, that's what I would have expected. I don't think we should support  
this.


BTW, the built in reverse also works with char[], and so does  
std.algorithm.reverse (and it does it pretty cleverly too, might I say).


This is a different algorithm. Sort requires random-access swapping.  
Reverse does not.


As far as I'm concerned, if we *can* do it in n.log(n), and somebody  
provides the implementation, then there is no reason to not offer dchar  
sorting for char[]/wchar.


I think there is nothing wrong with requiring the steps to be explicit. We  
should not hide such bloat behind sort.


-Steve


Re: Objects(from classes) at Compile time? no gc

2014-05-16 Thread Steven Schveighoffer via Digitalmars-d-learn

On Fri, 16 May 2014 02:31:18 -0400, Jacob Carlborg d...@me.com wrote:


On 16/05/14 06:59, Taylor Hillegeist wrote:

The subject says it all really. i have this example:

import core.memory;

class fruit{
   int value=5;
   public int getvalue(){
 return value;
   }
}

int main(string[] args) {
 GC.disable;
 static fruit myfruit;
 return myfruit.getvalue();
}

Most of the smart people will see that i want the program to return 5
but I did something dumb and didn't put in the new statement?

So my question is in longer words Can I create instances of objects at
compile time? and if not why not, i could build something
(roughly)equivalent out of structs and functions and have it at compile
time?


If you create an immutable instance it's possible to create it at  
compile time:


int main(string[] args) {
  GC.disable;
  immutable fruit myfruit = new immutable(fruit);
  pragma(msg, myfruit.getvalue); // will print 5 at compile time
  return myfruit.getvalue();
}

Although, I don't know if it will allocate it during  runtime as well.


It will not.

-Steve


Re: Array!T and find are slow

2014-05-16 Thread Steven Schveighoffer via Digitalmars-d-learn
On Fri, 16 May 2014 11:36:44 -0400, Jonathan M Davis via  
Digitalmars-d-learn digitalmars-d-learn@puremagic.com wrote:



On Thu, 15 May 2014 08:04:59 -0300
Ary Borenszweig via Digitalmars-d-learn
digitalmars-d-learn@puremagic.com wrote:


Isn't there a way in D to just expand:

enforce(cond, failure);

(or something with a similar syntax) to this, at compile-time:

if(!cond) throw new Exception(failure);

I thought D could do this, so enforce should do this instead of using
lazy arguments.


No. enforce is a function, and the only other things that it could be  
with
that syntax would be other callables (e.g. a lambda, delegate, or  
functor).


I think it *could* optimize properly, and that would be an amazing  
improvement to the compiler, if someone wants to implement that.


Essentially, you need to be able to inline enforce (not a problem since  
it's a template), and then deduce that the lazy calls can just be moved to  
where they are used, in this case, only once.


This would make a logging library even better too.

-Steve


Re: idup class

2014-05-16 Thread Steven Schveighoffer via Digitalmars-d-learn
On Fri, 16 May 2014 16:28:41 -0400, Joshua Niehus jm.nie...@gmail.com  
wrote:



trying to follow:
http://ddili.org/ders/d.en/class.html

//--- OSX 10.9 DMD 2.065
module test;

class Foo {
  int num;

  this(int num) {
  this.num = num;
  }

  Foo dup() const {
  return new Foo(this.num);
  }

  immutable(Foo) idup() const {
  return new immutable(Foo)(this.num);
  }
}

void main() {
  auto  foo = new Foo(1);
  auto mfoo = foo.dup();
  auto ifoo = foo.idup();
}

* test.d(15): Error: mutable method test.Foo.this is not callable
using a immutable object
* test.d(15): Error: no constructor for Foo
* Failed: [dmd, -v, -o-, test.d, -I.]
//---

What am i missing?


your constructor needs the immutable tag.

this(int num) immutable ...

However, you can avoid much of this by tagging things as pure:

(untested, but just keep the internals the same)

class Foo
{
   int num;
   this(int num) pure {...}
   Foo dup() const pure {...}
   immutable(Foo) idup() const pure {...}
}

void main()
{
   ... // same implementation
}

Note that doing this, you do not need to have an idup, this should work:

immutable ifoo = foo.dup();

-Steve


Re: idup class

2014-05-16 Thread Steven Schveighoffer via Digitalmars-d-learn

On Fri, 16 May 2014 16:36:36 -0400, Ali Çehreli acehr...@yahoo.com wrote:

Beat you by 8 seconds :)

-Steve


Re: string-ish range/stream from curl ubyte[] chunks?

2014-05-16 Thread Steven Schveighoffer via Digitalmars-d-learn

On Fri, 16 May 2014 16:57:41 -0400, Vlad b100d...@gmail.com wrote:


Hello D programmers,

I am toying with writing my own HTML parser as a pet project, and I  
strive to have a range API for the tokenizer and the parser output  
itself.


However it occurs to me that in real-life browsers the advantage of this  
type of 'streaming' parsing would be given by also having the string  
that plays as input to the tokenizer treated as a 'stream'/'range'.


While D's *string classes do play as ranges, what I want to write is a  
'ChunkDecoder' range that would take curl 'byChunk' output and make it  
consumable by the tokenizer.


Now, the problem: string itself has ElementType!string == dchar.  
Consuming a string a dchar at a time looks like a wasteful operation if  
e.g. your string is UTF-8 or UTF-16.


So, naturally, I would like to use indexOf() - instead of countUntil() -  
and opSlice (without opDollar?) on my ChunkDecoder (forward) range.


Q: Is anything like this already in use somewhere in the standard  
library or a project you know?


There is an effort by myself and Dmitry Olshansky to create a stream API  
that looks like a range. I am way behind on getting it to work, but I have  
something that compiles.


The effort is to replace the underlying mechanism for std.stdio  
(optionally), and to replace std.stream


Q2: Or do you have any pointers for what the smallest API would be for a  
string-like range class?


I think Dmitry has a pretty good API. I will hopefully be posting my  
prototype soon. I hate to say wait for it, because I have been very lousy  
at getting things finished lately. But I want to have something to show  
before the conference.


The code I have will support all encodings, and provide a range API that  
works with dchar-like ranges. The idea is to be able to make code that  
works with both arrays and streams seamlessly.



And bonus:
Q3: any uses of such a string-ish range in other standard library  
methods that you can think of and could be contributed to? e.g. suppose  
this doesn't exist and I / we come up with a proposal of minimal API to  
consume a string from left to right.


I hate for you to duplicate efforts, hold off until we get something  
workable. Then we can discuss the API.


Dmitry's message is here:  
http://forum.dlang.org/post/l9q66g$2he3$1...@digitalmars.com


My updates have not been posted yet to github, I don't want to post  
half-baked code yet. Stay tuned.


-Steve


Re: string-ish range/stream from curl ubyte[] chunks?

2014-05-16 Thread Steven Schveighoffer via Digitalmars-d-learn

On Fri, 16 May 2014 18:36:02 -0400, Vlad b100d...@gmail.com wrote:


On Friday, 16 May 2014 at 21:35:04 UTC, Steven Schveighoffer wrote:

On Fri, 16 May 2014 16:57:41 -0400, Vlad b100d...@gmail.com wrote:



Q: Is anything like this already in use somewhere in the standard  
library or a project you know?


There is an effort by myself and Dmitry Olshansky to create a stream  
API that looks like a range. I am way behind on getting it to work, but  
I have something that compiles.


The effort is to replace the underlying mechanism for std.stdio  
(optionally), and to replace std.stream


Q2: Or do you have any pointers for what the smallest API would be for  
a string-like range class?


I think Dmitry has a pretty good API. I will hopefully be posting my  
prototype soon. I hate to say wait for it, because I have been very  
lousy at getting things finished lately. But I want to have something  
to show before the conference.


The code I have will support all encodings, and provide a range API  
that works with dchar-like ranges. The idea is to be able to make code  
that works with both arrays and streams seamlessly.



And bonus:
Q3: any uses of such a string-ish range in other standard library  
methods that you can think of and could be contributed to? e.g.  
suppose this doesn't exist and I / we come up with a proposal of  
minimal API to consume a string from left to right.


I hate for you to duplicate efforts, hold off until we get something  
workable. Then we can discuss the API.


Dmitry's message is here:  
http://forum.dlang.org/post/l9q66g$2he3$1...@digitalmars.com


My updates have not been posted yet to github, I don't want to post  
half-baked code yet. Stay tuned.


-Steve


Just to make one thing clear: would this future module work with e.g.  
the ubyte[] chunks I receive from curl?


Most likely. I would expect a curl-based stream to fit right in, it's just  
passing in bytes. One piece that I haven't quite fleshed out is how to  
drive the process. In some cases, you are pulling data from the source  
(traditional stream-based I/O), in other cases, something else is pushing  
the data (CURL). We need to handle both seamlessly. I admit I have never  
looked at D's curl package, just used it via C/C++.



p.s.
Is this the talk? http://dconf.org/2014/talks/olshansky.html


That is Dmitry's talk, from the same guy. But I think this is not about  
his I/O ideas, but his excellent std.regex package.


-Steve


Re: Is it possible to assumeSafeAppend malloced memory?

2014-05-19 Thread Steven Schveighoffer via Digitalmars-d-learn
On Mon, 19 May 2014 09:44:44 -0400, monarch_dodra monarchdo...@gmail.com  
wrote:



On Monday, 19 May 2014 at 06:08:18 UTC, Ali Çehreli wrote:
We know that most of the time memory is allocated more than the  
requested amount. Is there a way to take advantage of that extra  
trailing space? (And potentially the pages that come after that.)


import core.memory;

void main()
{
const count = 1;

// I think there is extra capacity beyond the 'count' elements
int* ptr = cast(int*)GC.malloc(count * int.sizeof);
int[] arr = ptr[0 .. count];

assert(arr.capacity == 0);
arr.assumeSafeAppend;
assert(arr.capacity == 0);// still 0. :(
}


This is because a block must contain 'used' information in order for  
capacity and assumeSafeAppend to work. This is enabled not only by adding  
the flag APPENDABLE to the allocation (or you can set the attribute  
later), but you must ALSO properly set up the 'used' field. This is best  
left to druntime. The mechanism to store the used size may change in the  
future.


Is there a reason you wouldn't want to do int[] arr = new int[count]? It's  
technically the same call.




This issue puts std.array.array to a disadvantage compared to proper  
slices because array() involves the following call chain, the last of  
which does call GC.malloc:


  trustedAllocateArray
  uninitializedArray
  arrayAllocImpl


This is a bug. arrayAllocImpl should alloc using the proper functions and  
flags.


auto arr = array(1, 2, 3);
assert(arr.capacity != 0); // should pass


Recently, a new function in druntime was added: _d_newarrayU.

This void allocates a new array *with* appendable information. We can  
hope it will be given a more formal and public interface, and it would  
then be useable by array and/or Appender, to produce slices that have  
appendable data.


Cool, I didn't know this!

-Steve


Re: Is it possible to assumeSafeAppend malloced memory?

2014-05-19 Thread Steven Schveighoffer via Digitalmars-d-learn
On Mon, 19 May 2014 14:46:59 -0400, monarch_dodra monarchdo...@gmail.com  
wrote:



On Monday, 19 May 2014 at 13:55:00 UTC, Steven Schveighoffer wrote:

On Monday, 19 May 2014 at 06:08:18 UTC, Ali Çehreli wrote:


This issue puts std.array.array to a disadvantage compared to proper  
slices because array() involves the following call chain, the last of  
which does call GC.malloc:


 trustedAllocateArray
 uninitializedArray
 arrayAllocImpl


This is a bug. arrayAllocImpl should alloc using the proper functions  
and flags.


Well, Yes and no. The issue is that there is no interface available to  
achieve this, that wouldn't completely destroy what `array` is going for  
anyways. So it's more of a design issue than a bug proper.


Yes, I understand. When allocating an array, you need to initialize the  
array properly, and the standard library should not have the  
implementation details of the array management leaked into it. I think you  
can replace the GC.malloc call with the new one you mentioned, no?


It's still a bug. The expectation of array(x, y, z) is that it's the same  
as [x, y, z]. That is not true currently.


-Steve


Re: Is there any way to differentiate between a type and an alias?

2014-05-25 Thread Steven Schveighoffer via Digitalmars-d-learn
On Sun, 25 May 2014 04:04:09 -0700, Rene Zwanenburg  
renezwanenb...@gmail.com wrote:



Given

alias GLenum = uint;
void glSomeFunction(GLenum, uint);

Now, is there some way to differentiate between GLenum and uint when  
using ParameterTypeTuple!glSomeFunction?


I'm writing a function which shows the arguments a GL function was  
called with when an error occurs. The GLenum needs to be printed as a  
stringified version of the constant's name, while the uint is just an  
uint.


An alias is simply another name for the same thing. There is no type  
difference.


You may be able to do some template trickery with template aliases to  
detect when an alias is used. But I'd recommend using enum instead of  
alias:


enum GLenum : uint { constant = value}

This creates a genuine new type, and also gives you a place to put  
constants. However, it's not implicitly castable from uint, so it has some  
drawbacks. You can cast back to uint implicitly though.


There is also a library typedef mechanism (in std.typecons perhaps?), you  
can look into that. It should have the same limitations as enum.


-Steve


Re: Is this a bug or illegal code?

2014-05-29 Thread Steven Schveighoffer via Digitalmars-d-learn
On Thu, 29 May 2014 10:45:28 -0400, safety0ff safety0ff@gmail.com  
wrote:



//*** CODE **
mixin(version = foo;);
version(foo)
{
void main(){}   
}
//** END CODE ***
If it's illegal in D, what is the reason  where is documented?

The reason I was considering such a construct is the following:
Some C libraries have an associated config.h header that gets  
generated when it is compiled.
I was thinking it may be possible to parse these config.h files at  
compile time (using text import) and convert some of the #define's into  
version = foo;


Even if that is valid code, you are much better off using enums and static  
if.


enum includeSomeFeature = ...

static if(includeSomeFeature)
{
 ...
}

These work much more like #defines, and can be seen outside the module.

-Steve


Re: enums

2014-05-30 Thread Steven Schveighoffer via Digitalmars-d-learn
On Fri, 30 May 2014 13:34:38 -0400, Philippe Sigaud via  
Digitalmars-d-learn digitalmars-d-learn@puremagic.com wrote:



On Fri, May 30, 2014 at 7:28 PM, Ali Çehreli
digitalmars-d-learn@puremagic.com wrote:

On 05/30/2014 08:30 AM, Russel Winder via Digitalmars-d-learn wrote:


 enum double p0 = 0.0045;


As others have already said, p0 is a manifest constant. Interestingly,  
it

can be thought of like a C macro, being pasted inside source code.

Avoid enums for arrays and associative arrays as they are hidden  
performance
sinks. The constant gets regenerated at runtime every time it is used  
in an

expression.


I guess that, in an ideal world, immutable variables could be use at
compile-time (template arguments, etc). We could then ditch
'enums-as-manifest-constants'.The best of both worlds.


You can as long as the value is known at compile time:

http://dpaste.dzfl.pl/5a710bd80ab0

-Steve


Re: Hiding types

2014-05-30 Thread Steven Schveighoffer via Digitalmars-d-learn
On Fri, 30 May 2014 15:50:41 -0400, Philippe Sigaud  
philippe.sig...@gmail.com wrote:


I'm trying to 'hide' a type, so as not to see it outside its module. I  
want to control the way it's created and used.


I know of Voldemort types and '@disable this', but for now I'm just  
trying to use 'private'. Halas, it seems it can be circumvented:


*

module A;

private struct Hidden {}

Hidden foo() { return Hidden();}

*

module B;

import A;

void main() {
 typeof(foo()) h;
}

*

Am I misunderstanding something or is that a bug?


Even voldemort types can be declared that way. If you want an opaque  
struct, you need to return it by pointer. Otherwise, the user must be able  
to know what type it is (otherwise, how would he use it?)


-Steve


Re: Hiding types

2014-05-30 Thread Steven Schveighoffer via Digitalmars-d-learn
On Fri, 30 May 2014 16:09:59 -0400, Philippe Sigaud  
philippe.sig...@gmail.com wrote:



On Friday, 30 May 2014 at 20:02:40 UTC, Steven Schveighoffer wrote:


If you want an opaque struct, you need to return it by pointer.


What do you mean? Like this?

Hidden* foo() { return new Hidden();}

?


Yes, this way you can control all aspects of the construction and use. You  
wouldn't need to make it private even, just don't lay out the struct in  
the normal import:


struct Hidden;

I think you would need to use a .di file to do this.



Otherwise, the user must be able to know what type it is (otherwise,  
how would he use it?)


I just fear that by using internal, public, functions, the user might  
get access to a private type. I guess the D answer to that is to make  
foo private also. That makes sense.


You can make the struct's methods and data all private, which would  
prevent any useful access to it. But I don't know your use case.


I now realize that I implicitly considered 'private' to be transitive  
(or viral). That is that:


Hidden foo() { return Hidden();}

as foo is returning a value from a private type, it should be considered  
private also. By the compiler, I mean.


No, private just makes the symbol not directly accessible. Since foo is  
not private, it's accessible.


-Steve


Re: delegate issue

2014-06-02 Thread Steven Schveighoffer via Digitalmars-d-learn

On Mon, 02 Jun 2014 10:37:07 -0400, captaindet 2k...@gmx.net wrote:


On 2014-06-02 08:03, MrSmith wrote:

On Monday, 2 June 2014 at 06:56:54 UTC, captaindet wrote:

hi,

i stumbled upon something weird - it looks like a bug to me but maybe  
it is a feature that is unclear to me.


so i know i can declare function and delegate pointers at module level.
for function pointers, i can initialize with a lambda.
BUT for delegates i get an error - see below

i found out that using module static this(){...} provides a  
workaround, but why is this necessary?


also, if there is a good reason after all then the error message  
should make more sense.


/det

ps: i know there is a shorthand syntax for this.


module demo;

int function(int) fn = function int(int){ return 42; };
// ok

int delegate(int) dg = delegate int(int){ return 666; };
// demo.d(6): Error: non-constant nested delegate literal expression  
__dgliteral6


void main(){}


You can't assign a delegate at compile time now.
But you can do this in static constructor like this:


int delegate(int) dg;
static this()
{
dg = delegate int(int){ return 666; };
}


i knew about the static constructor, mentioned it in my OP ;)

tried it in my project proper and got run-time cycle detected between  
modules ctors/dtors :(

something new to figure out now.


FYI, the module ctor/dtor cycles thing is an interesting problem. When D  
decides to call module ctors or dtors, it wants to initialize them in an  
order where two initializations don't depend on one another. For instance:


module a;
import b;

int x;

static this() { x = b.x;}

module b;
import a;

int x;

static this() { x = a.x;}

But of course, D does not know what exactly is done in module a, and  
module b. It could be:


module a;
import b;

int x;

static this() { x = b.x; }

module b;
import a;

int x;

static this() { x = 15;}

Which could be perfectly legal, as long as module b is initialized before  
module a.


But D doesn't have the information to sort this out. So at the moment, it  
has to assume the first situation, and reject the code. And it can only  
detect this at runtime, since we have no way to tell the linker to refuse  
to link this code.


The typical solution is to put your static ctors into another module,  
which nothing will import (and therefore cannot be part of a cycle). A  
module with no static ctors/dtors will not be flagged as causing a problem.


-Steve


Re: for, foreach identifier allowed in c throws error in d

2014-06-02 Thread Steven Schveighoffer via Digitalmars-d-learn
On Mon, 02 Jun 2014 15:21:06 -0400, Logesh Pillay  
lp.court.jes...@gmail.com wrote:


It is common in a recursive function to amend a global array using the  
function parameter to refer to the element eg


int[10];

void foo (int i) {
   foreach (x; 0 .. 9) {
  t[i] = x;
  foo ();

C in a for loop allows use of t[i] directly as the iterating variable so  
you don't need the dummy variable x which has no real function.


D does not.  The error generated is no identifier for declarator t[i].  
For a long time, I thought that was specific to foreach but the same  
thing happens with for.


It looks like an unnecessary restriction.  Am I missing something?


Can you post a full compiling example? I can't figure out what you are  
trying to do with this code.


-Steve


Re: for, foreach identifier allowed in c throws error in d

2014-06-02 Thread Steven Schveighoffer via Digitalmars-d-learn
On Mon, 02 Jun 2014 15:47:02 -0400, Logesh Pillay  
lp.court.jes...@gmail.com wrote:


Issue has nothing to do with recursion.  That's only where I keep seeing  
it.


eg a function to generate combinations.

import std.stdio;

int[3] t;

void foo (int i) {
   if (i == 3)
 writef(%s\n, t);
   else foreach (x; 0 .. 3) {
 t[i] = x;
 foo(i+1);
   }
}

void main() {
   foo(0);
}

In C, I could put in the equivalent for statement for foreach, t[i] as  
the iterating variable. I won't need x which exists as a middleman only  
and save myself two lines.


OK, I get it. You want to do:

foreach(t[i]; 0 .. 3)

But this doesn't work.

This should (the equivalent for C):

for(t[i] = 0; t[i]  3; ++t[i])

I'm trying to think of a way to do this without loops, but not sure. Note  
that foreach is expected to be given a new variable to declare, so you  
can't foreach with an existing variable on the left.


-Steve


Re: for, foreach identifier allowed in c throws error in d

2014-06-02 Thread Steven Schveighoffer via Digitalmars-d-learn
On Mon, 02 Jun 2014 15:58:01 -0400, Steven Schveighoffer  
schvei...@yahoo.com wrote:




I'm trying to think of a way to do this without loops, but not sure.


I'm surprised, I looked for some kind of apply function like map, but  
just calls some function with each element in the range.


Something like this would make this a 1 (2?) liner:

if(i == t.length) writeln(t) else each!((x) = {t[i] = x;  
foo(i+1);})(iota(x.length));


But I can't find a phobos primitive for each. Would have expected it in  
std.algorithm or std.functional?


-Steve


Re: for, foreach identifier allowed in c throws error in d

2014-06-03 Thread Steven Schveighoffer via Digitalmars-d-learn
On Mon, 02 Jun 2014 17:25:24 -0400, John Colvin  
john.loughran.col...@gmail.com wrote:



On Monday, 2 June 2014 at 20:23:12 UTC, Steven Schveighoffer wrote:
On Mon, 02 Jun 2014 15:58:01 -0400, Steven Schveighoffer  
schvei...@yahoo.com wrote:




I'm trying to think of a way to do this without loops, but not sure.


I'm surprised, I looked for some kind of apply function like map, but  
just calls some function with each element in the range.


Something like this would make this a 1 (2?) liner:

if(i == t.length) writeln(t) else each!((x) = {t[i] = x;  
foo(i+1);})(iota(x.length));


But I can't find a phobos primitive for each. Would have expected it in  
std.algorithm or std.functional?


-Steve


Its been discussed a few times. There were some objections (IIRC Walter  
thought that there was no significant advantage over plain foreach).


Indeed, foreach is like such a construct:

... else each!((x) {t[i] = x; foo(i+1);})(iota(t.length));
... else foreach(x; 0 .. t.length) {t[i] = x; foo(i+1);}

It's even shorter and clearer.

I agree with Walter. Since such a construct by definition wouldn't return  
anything, you can't chain it. There really is little reason to have it.


-Steve


Re: Delegate, scope and associative array

2014-06-03 Thread Steven Schveighoffer via Digitalmars-d-learn
On Mon, 02 Jun 2014 19:43:58 -0400, Rene Zwanenburg  
renezwanenb...@gmail.com wrote:



On Monday, 2 June 2014 at 20:09:12 UTC, Edwin van Leeuwen wrote:
I'm probably missing something basic, but I am confused by what is  
going on in the following code.


unittest {
size_t delegate()[size_t] events;
foreach( i; 1..4 ) {
events[i] = { return i; };
}
writeln( events[1]() ); // This outputs 3
assert( events[1]() == 1 );
}

I thought that i should be copied from the local scope and therefore  
when I call events[1]() the return value should be 1, but in this case  
it is 3 (it always seems to be the last value of i in the loop).


Cheers, Edwin


Yeah this is a known problem. At the moment the foreach loop is  
internally rewritten to something like


int i = 1;
while(i  4)
{
   // foreach loop body

   ++i;
}

While it usually would be preferrable if it were rewritten as

int __compilergeneratedname = 1;
while(__compilergeneratedname  4)
{
   auto i = __compilergeneratedname++;

   // foreach loop body
}

With the current approach every delegate refers to the same variable.  
Another problem is that it's possible to alter the iteration index from  
inside the foreach body.


As you may have guessed, a workaround is to copy the iteration variable  
yourself:


unittest {
 size_t delegate()[size_t] events;
 foreach(_i; 1..4 ) {
 auto i = _i;
 events[i] = { return i; };
 }
 assert( events[1]() == 1 );
}

This should work though it's less than ideal. There is an open bug  
report:

https://issues.dlang.org/show_bug.cgi?id=8621


There is a school of thought (to which I subscribe) that says you  
shouldn't allocate a separate closure for each loop iteration.


Basically, a closure will only use the stack frame of the calling  
function, not any loop iteration.


This way, you can clearly delineate what scope the closure has, and avoid  
unnecessary allocations.


-Steve


Re: When is a slice not a slice?

2014-06-05 Thread Steven Schveighoffer via Digitalmars-d-learn
On Thu, 05 Jun 2014 15:56:00 -0400, Philippe Sigaud via  
Digitalmars-d-learn digitalmars-d-learn@puremagic.com wrote:



enum b = DataAndView(1);
assert (!sameTail(b.data, b.view));


I suppose it's because enums are manifest constants: the value they
represent is 'copy-pasted' anew everywhere it appears in the code. So
for arrays and associative arrays, it means recreating a new value
each and every time.
In your case, your code is equivalent to:

assert (!sameTail(DataAndView(1).data,DataAndView(1).view));

And the two DataAndView(1), being completely separated, do not have
the same tail.


Yes, this should work (and execute the initializer at compile time):

static b = ...

-Steve


Re: When is a slice not a slice?

2014-06-06 Thread Steven Schveighoffer via Digitalmars-d-learn
On Fri, 06 Jun 2014 06:14:30 -0400, Rene Zwanenburg  
renezwanenb...@gmail.com wrote:



On Friday, 6 June 2014 at 08:17:43 UTC, Alix Pexton wrote:

On 05/06/2014 8:58 PM, Steven Schveighoffer wrote:




Yes, this should work (and execute the initializer at compile time):

static b = ...


Ah, the problem with static is that I want to use the values at compile  
time to create other values. Using static puts construction between  
compile time and run time.


Not exactly (at least I don't think). The static initializer itself is  
generated at compile time. But the assignment to the static variable is  
done at run time.


Initialising in static this means that the symbols need to be declared  
without initializers and that means not disabling default construction




Immutables should be usable at compile time and not allocate a new  
instance on every use when in module scope.


I was about to say this. But immutable can have its own set of issues. If  
you want strictly compile-time generation of data, then immutable is the  
way to go.


But if you want to use it at runtime as well, immutable can hamper some  
things. I'm sure your example is a very small or reduced snippet of what  
you are actually doing.


-Steve


Re: splitter for strings

2014-06-09 Thread Steven Schveighoffer via Digitalmars-d-learn

On Mon, 09 Jun 2014 07:04:11 -0400, Chris wend...@tcd.ie wrote:


On Monday, 9 June 2014 at 10:54:09 UTC, monarch_dodra wrote:

On Monday, 9 June 2014 at 10:23:16 UTC, Chris wrote:


Ok, thanks. I'll keep that in mind for the next version.


Seems to me to also work with 2.065 and 2.064.


 From the library reference:

assert(equal(splitter(hello  world, ' '), [ hello, , world ]));


Note the 2 spaces between hello and world


and

If a range with one separator is given, the result is a range with two  
empty elements.


Right, it allows you to distinguish cases where the range starts or ends  
with the separator.



My problem was that if I have input like

auto word = bla-;

it will return parts.data.length == 2, so I would have to check  
parts.data[1] != . This is too awkward. I just want the parts of the  
word, i.e.


length == 2 // grab [0] grab [1]
length == 1 // grab [0] (no second part, as in bla-)
length  2 // do something else


One thing you could do is strip any leading or trailing hyphens:


assert(-bla-.chomp(-).chompPrefix(-).split('-').length == 1);

Just looked at std.string for a strip function that allows custom  
character strippage, but apparently not there. The above is quite awkward.


-Steve


Re: splitter for strings

2014-06-09 Thread Steven Schveighoffer via Digitalmars-d-learn

On Mon, 09 Jun 2014 10:39:39 -0400, Chris wend...@tcd.ie wrote:


Atm, I have

auto parts = appender!(string[]);
w.splitter('-').filter!(a = !a.empty).copy(parts);

Which looks more elegant and gives me what I want. IMO, the module that  
handles the splitting of hyphenated words should be able to deal with  
cases like blah- without the input being prepared in a certain way.


It's not mishandled. It's handled exactly as I would have expected. If  
blah- and blah result in the same thing, then how do you know the  
difference?


Stripping any possible leading or trailing hyphens is much more efficient  
than checking every single word to see if it's empty.


However, if you have an instance of --, your solution will remove the  
extra empty string, whereas mine does not. Not sure if that's important.


-Steve


Re: splitter for strings

2014-06-09 Thread Steven Schveighoffer via Digitalmars-d-learn
On Mon, 09 Jun 2014 12:06:13 -0400, monarch_dodra monarchdo...@gmail.com  
wrote:



On Monday, 9 June 2014 at 15:54:29 UTC, Steven Schveighoffer wrote:
On Mon, 09 Jun 2014 11:49:29 -0400, monarch_dodra  
monarchdo...@gmail.com wrote:



On Monday, 9 June 2014 at 14:21:21 UTC, Steven Schveighoffer wrote:
Just looked at std.string for a strip function that allows custom  
character strippage, but apparently not there. The above is quite  
awkward.


-Steve


It's in algorithm, because it's more generic than just strings.


Ugh.. This makes things difficult. If I want to work with strings, I  
import std.string.


I understand that the algorithm is applicable to all types, but this  
makes for some awkward coding. What if you wanted to use both? Surely  
we can come up with a better solution than this.


-Steve




I think we are confusing things here, I was talking about strip :)


There's 2 different issues: The first, is that split(string) was  
pre-existing in std.string, and *then* split was introduced in  
algorithm. Where ideally (?) everything would have been placed in the  
same module, we true to avoid moving things around now.


The second thing is that split without any predicate/item can only  
make sense for strings, but not for generic ranges.


For what it's worth, I find it makes sense.


Well, I suppose it should probably work if you try both strip and  
strip('-')...


and indeed it does. It is not as bad as I thought (I thought they would  
conflict).


It still leaves me a bit uneasy that std.string does not provide  
everything you would need to work with strings. But we don't want  
std.string importing std.algorithm, or at least we don't want it importing  
ALL of std.algorithm.


If we could split up std.algorithm into individual modules, that would  
probably help.


-Steve


Re: Basic dynamic array question. Use of new versus no new.

2014-06-11 Thread Steven Schveighoffer via Digitalmars-d-learn

On Tue, 10 Jun 2014 23:28:16 -0400, Kapps opantm2+s...@gmail.com wrote:


On Wednesday, 11 June 2014 at 02:30:01 UTC, WhatMeWorry wrote:

In Mr. Cehreli's book it says

Additionally, the length of dynamic arrays can be changed by assigning  
a value to this property:


int[] array; // initially empty
array.length = 5; // now has 5 elements

while in Mr. Alexandrescu's book, it says

To create a dynamic array, use a new expression (§ 2.3.6.1 on page 51)  
as follows:


int[] array = new int[20]; // Create an array of 20 integers


Could someone please compare and contrast the two syntaxes. I presume  
the new command places the 2nd array in heap memory.


They both do the same, create an array of n integers on the heap and set  
the length to n. You can also use .capacity instead of .length to  
allocate n but not adjust length.


This is slightly incorrect. Here is the difference as I see it:

1. Setting length goes through the extra steps of checking the current  
length, looking up the existing block (obviously with initial value of  
null, there isn't one), and allocating if necessary. A lot more code is  
executed.
2. The 'new' call will ALWAYS allocate a new block, even if array  
previously had data in it.

3. The block size allocated is not always n, it could be more.
4. You meant 'reserve', not 'capacity'. capacity checks how many elements  
the block can support.


Which way is easier/better? If you know you are starting with a blank  
array, then new is the way to go. This avoids any unnecessary extra checks  
for existing data.


The second way is required if you may already have some data in the array  
(i.e. prior to setting the length, arr.length != 0).


Also, I would recommend to use:

auto array = new int[20]

To avoid repeating the type.

-Steve


Re: Cannot understand deprecation message recently added to Phobos

2014-06-11 Thread Steven Schveighoffer via Digitalmars-d-learn

On Wed, 11 Jun 2014 16:59:24 -0400, Nordlöw per.nord...@gmail.com wrote:


Can somebody explain the meaning of split in the error message

Deprecation: function core.time.Duration.weeks is deprecated - Please  
use split instead. weeks was too frequently confused for total!weeks.


given by function

shortDurationString()

at

https://github.com/nordlow/justd/blob/master/pprint.d


Actually, that may not be a valid deprecation message.

All the other unit functions do not get the total number of units, but  
there are not larger units supported by Duration. In fact, dur.weeks was  
the equivalent of dur.total!weeks.


You can safely change your code to use total!weeks instead.

Jonathan, can we update this deprecation message?

The function is going away because of the confusion with smaller units.  
For example, dur.seconds could be confused as the number of seconds in  
this duration, but it's really the number of seconds that do not make up  
a whole minute in this duration. Basically, it's the mod remainder for  
the seconds.


-Steve


Re: Cannot understand deprecation message recently added to Phobos

2014-06-12 Thread Steven Schveighoffer via Digitalmars-d-learn

On Wed, 11 Jun 2014 17:06:41 -0400, Kapps opantm2+s...@gmail.com wrote:


On Wednesday, 11 June 2014 at 20:59:25 UTC, Nordlöw wrote:

Can somebody explain the meaning of split in the error message

Deprecation: function core.time.Duration.weeks is deprecated - Please  
use split instead. weeks was too frequently confused for total!weeks.


given by function

shortDurationString()

at

https://github.com/nordlow/justd/blob/master/pprint.d


https://github.com/D-Programming-Language/druntime/pull/825


Now fixed, is the message clearer for you?

https://github.com/D-Programming-Language/druntime/pull/837

-Steve


Re: Is it normal that unittests of phobos are executed with my project build?

2014-06-16 Thread Steven Schveighoffer via Digitalmars-d-learn
On Sat, 14 Jun 2014 10:32:04 -0400, Xavier Bigand  
flamaros.xav...@gmail.com wrote:


I get a failure on a test in format.d when I build my own project with  
unittest. I though importing phobos header would not regenerate their  
unittest modules.


Any idea of what can cause this issue? I already have reinstalled dmd  
with visualD completely.


Templates are not compiled fully until you use them.

If a unit test is inside a template, and that template wasn't instantiated  
inside phobos itself (likely for formatting), it will be instantiated,  
unit test and all, inside your code that used it.


This is a big limitation on the unit test system. There is no way to say  
what unit tests to enable, and what to disable. It's just all or nothing.


-Steve


Re: interface is interface

2014-06-17 Thread Steven Schveighoffer via Digitalmars-d-learn

On Tue, 17 Jun 2014 15:02:33 -0400, Pavel phond...@gmail.com wrote:


Hello!

import std.stdio;

interface I {

}

interface B : I {
void test();
}

interface C : I {
void test1();
}

class A : B, C {
   override void test() {}
   override void test1() {}
}

void main() {
A a = new A();
I b = cast(B)a;
I c = cast(C)a;

writeln(cast(void*)a,   , cast(void*)b,   , cast(void*)c); //  
1EE1FE0  1EE1FE8  1EE1FEC


b and c should be identical IMO. This means there are 2 entries for I  
inside the object, which is a waste of space.




assert (a is b); // OK


This should also fail. It seems like a bug to me. 'is' should compare  
pointers, not anything else.


-Steve


Re: Run child process with null stdin/stdout

2014-06-19 Thread Steven Schveighoffer via Digitalmars-d-learn
On Wed, 18 Jun 2014 16:15:40 -0400, David Nadlinger c...@klickverbot.at  
wrote:



On Wednesday, 18 June 2014 at 20:00:43 UTC, Justin Whear wrote:

For POSIX, seems like you could pass `File(/dev/null, r)` for stdin
and `File(/dev/null, w)`.  On Windows I believe you can use `File
(nul)` for the same effect.


Implementing this myself is of course always an option, yes, but I would  
have liked to avoid platform-dependent code.


Hm, I just checked the source, and there doesn't seem to be a better  
option indeed…




I think a mechanism to open a null stream in an OS independent way would  
be a good addition to std.stdio (or perhaps std.process?)


-Steve


Re: Question about iteger literals

2014-06-23 Thread Steven Schveighoffer via Digitalmars-d-learn

On Sun, 22 Jun 2014 08:23:45 -0400, Uranuz neura...@gmail.com wrote:

If these rules are not so clear and have some exceptions (but I don't  
understand why they are needed) then some documentation needed about  
this.


See integer promotion rules:

http://dlang.org/type.html#Integer%20Promotions

And the section below it.

-Steve


Re: Passing around a list of differently typed functions

2014-06-23 Thread Steven Schveighoffer via Digitalmars-d-learn

On Mon, 23 Jun 2014 14:30:12 -0400, Ali Çehreli acehr...@yahoo.com wrote:

On 06/22/2014 11:32 PM, FreeSlave wrote: On Monday, 23 June 2014 at  
01:16:49 UTC, Evan Davis wrote:

  As the subject says, I would like to pass around an array of
  functions. The trick is, that the functions have different type
  signatures. Is there a way to put the two functions
 
  int foo(int a, int b);
  bool bar(bool a, bool b);
 
  into one array, that I can pass around and cast as necessary?
 
  Thanks, Evan
 
  You can pass them as pointers, for example cast to void*. But you  
still
  need correct signature to cast pointer to actual type before call  
function.


In C and C++, void* is for data pointers only. As function pointers are  
a different kind of beast, casting to and from void* is undefined  
behavior. (Note: It works on all common platforms.)


Wow, really? That is strange.


I wonder whether D has any decision on that.


I would hope it's defined. A pointer is a pointer.

-Steve


Re: Converting from C const(dchar*) to dstring

2014-06-24 Thread Steven Schveighoffer via Digitalmars-d-learn
On Tue, 24 Jun 2014 13:37:41 -0400, Danyal Zia catofdan...@yahoo.com  
wrote:


Hi, I like to print the strings from a C function that returns  
const(dchar*), but I can't make the conversion to dstring. I can convert  
vice versa by:


dstring text = Hello;
const(dchar)* str = toUTFz!(const(dchar)*)(text);
// passing it to C function prints Hello

However, I don't have the idea how can I go the other way. I tried  
several methods such as using to!dstring, toUTF32 etc which compiles  
successfully however printing them gives address of them instead of text.


const(dchar *)x = ...;

// assuming 0 terminated
dstring text = x[0..x.strlen].idup;

-Steve


Re: Converting from C const(dchar*) to dstring

2014-06-24 Thread Steven Schveighoffer via Digitalmars-d-learn

On Tue, 24 Jun 2014 14:28:58 -0400, Chris Cain zsh...@gmail.com wrote:


On Tuesday, 24 June 2014 at 17:59:41 UTC, Steven Schveighoffer wrote:

// assuming 0 terminated
dstring text = x[0..x.strlen].idup;


strlen is only defined for char, not dchar:
https://github.com/D-Programming-Language/druntime/blob/master/src/core/stdc/string.d#L44



Right, I forgot about that.

-Steve


Re: Is their a way for a Child process to modify its Parent's environment?

2014-06-26 Thread Steven Schveighoffer via Digitalmars-d-learn
On Tue, 24 Jun 2014 21:53:51 -0400, WhatMeWorry kc_hea...@yahoo.com  
wrote:



I open a command line window, and run the following 6 line program

void main()
{
string envPath = environment[PATH];

writeln(PATH is: , envPath);

envPath ~= r;F:\dmd2\windows\bin;

environment[PATH] = envPath;

envPath = environment[PATH];

writeln(PATH is: , envPath);

}

It prints out the following

PATH is: C:\Windows\system32;C:\Windows...
PATH is: C:\Windows\system32;C:\Windows...F:\dmd2\windows\bin

when the program exits, I'm back at the command line and I do a

echo %PATH%

which just shows C:\Windows\system32;C:\Windows...

Anybody know of a way to make the change stick for the lifetime of the
command window?


Only the command shell can change it's own environment. When you execute  
commands that set an environment variable, those are shell builtins, not  
external programs.


You can run a batch file (which is not run in a separate process) which  
sets environment variables. This may be the only way to affect the  
environment. Basically, have a program run that dictates what to set,  
builds a batch file, then run that batch file from the command line. This  
could be done in another batch file.


-Steve


Re: Redirect to different overloads at compile time?

2014-06-29 Thread Steven Schveighoffer via Digitalmars-d-learn

On Sun, 29 Jun 2014 22:24:09 -0400, David Bregman d...@sfu.ca wrote:

Suppose I have a C library which implements a function for several  
types. C doesn't have overloading, so their names will be distinct.


extern(C):
double foo_double(double);
float foo_float(float);

Now I want to build a D wrapper, and merge them into a single function  
with overloading:


T foo(T)

I could write out the two overloads manually:
double foo(double d) { return foo_double(d); }
float foo(float f) { return foo_float(f); }

but this isn't compile time, it will generate a stub function for each  
overload, meaning the wrapper will have performance overhead unless  
inlining can be guaranteed somehow.


This is the correct answer. It should be inlined, and inlining should work  
as long as -inline is passed to the compiler. I don't think there is  
another way.




Is it possible to do something like
alias foo = foo_double;
alias foo = foo_float;


Right, you cannot overload aliases as far as I know. foo either refers to  
foo_double, or foo_float. You can't bring in those as overloads under the  
name foo.




or

template(T) foo {
   static if(T is double) {
 alias foo = foo_double;
   } else {
 // etc.
   }
}

These doesn't work of course.


This last one looks like it should work. But IFTI ONLY works if you don't  
do what you did :) Basically, IFTI cannot see through static if to  
determine how to instantiate. It needs to be a clear single function.


For example, how would IFTI figure it out if you did this?

template(T) foo {
   static if(T is double) {
  alias foo = foo_float;
   } else {
  // etc.
   }
}

It can't figure out what T is without looking at what the alias would be,  
but in order to look at the alias, it needs to decide T!


I don't fully understand the template syntax yet, but I have a feeling  
this is possible with templates. Is it possible to do what I'm trying to  
do?


It seems like it should be possible, but I think we would need a new type  
of implicit determination for templates that was not a function template.


-Steve


Re: linux ipv4 multicast

2014-09-19 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/18/14 10:55 PM, james wrote:

I just started doing D networking today, so I may just be doing
something wrong / stupid but I can not find the ip_mreq
struct anywhere.

I ended up just making my own in my module

struct ip_mreq
{
   in_addr imr_multiaddr;
   in_addr imr_interface;
}

And then I was able to continue and successfully process
multicast.

The ipv6 things seem to be available.

I was hoping it would be picked up by import std.c.linux.socket;

In /usr/include/dmd , running
   find . -type f -exec grep -Hi ip_mreq {} \;
returns no results.

Am I doing something wrong or is this just an oversight somehow?

DMD v2.065


The vast amount of C declarations that could be done on D simply aren't 
done until someone needs them. So no, you aren't doing anything wrong, 
no it's not an oversight :)


If you like it to be part of the main library, submit a pull request, 
and I'll be happy to review.


One thing -- you should extern(C) the struct so the symbol is not 
mangled (extern(C): is probably already done at the top of the file, so 
you may not need to do this if you add it to std.c.linux.socket)


-Steve


Re: How does GC.addRange work?

2014-09-22 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/21/14 3:00 PM, Gary Willoughby wrote:

On Saturday, 20 September 2014 at 23:08:08 UTC, ketmar via
Digitalmars-d-learn wrote:

On Sat, 20 Sep 2014 22:21:13 +
Gary Willoughby via Digitalmars-d-learn
digitalmars-d-learn@puremagic.com wrote:


So zeroing values will inform the GC the reference has gone?

yes.


Thanks, i just wanted to make it clear in my mind.


Just to be crystal clear, zeroing values in that range will make the GC 
able to collect the memory that those values previously pointed at. 
However, you have to remove the range in order for the GC to ignore that 
data. In other words, if you zero that memory, the GC will continue to 
scan those zeros until you GC.removeRange it.


-Steve


Re: can't understand why code do not working

2014-09-22 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/22/14 4:37 PM, Cliff wrote:



Is stdout threadsafe?


Yes, stdout is thread safe, it's based on C's stdout which is thread safe.

-Steve


Re: Does remove immutability using cast to pass in a function make sense?

2014-09-23 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/22/14 10:07 PM, AsmMan wrote:

I have this array:

static immutable string[] months = [jan, fev, ...];

I need to pass it into canFind(). But it doesn't works with immutables
so I need to cast it like in canFind(cast(string[]) months, month) to
work. There's a reason related to design why it doesn't work with
immutables or a function just wasn't written?

What I want to know is if I'm doing something wrong in casting it to
work. I know from C which such casts should be done carefully


Yes, casting should be used very sparingly, and only when you have no 
other choice.


Ali suggests that the latest version of DMD on git handles this, but 
just an FYI, you do not need to cast to get a mutable array of strings:


canFind(months[], month)

should work.

-Steve


Re: How to export a deduced template type to the enclosing scope?

2014-09-25 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/23/14 7:12 PM, Ali Çehreli wrote:


Can we get rid of the ResultT template parameter? Tricks with variadic
templates, the with statement, etc. come to mind but I could not manage it.


I don't think so.

yield just returns control back to another fiber. It's not an entry point.

What you *could* do is match an expectation function with the yield 
result. In other words, at the place where you expect the fiber to yield 
you a result, pass in a pointer to a value for the yield to fill in:


expectYield(someint); - fiber runs, yields an int, and then when this 
yields the result, someint is filled in.


I'm not super familiar with how D fibers work, or fibers in general. But 
perhaps it's the 'call' function that could be made to take parameters.


-Steve


Re: Does D has C#'s string.Empty?

2014-09-25 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/25/14 2:41 AM, SlomoTheBrave wrote:

On Thursday, 25 September 2014 at 05:29:37 UTC, AsmMan wrote:

Does D has C#'s string.Empty?


string.init ?


 string a;
 a = string.init;
 assert( a == );


does the job for the type string at least.

null also works. In fact, in the above, a is already string.init or null 
before assigning (D always initializes variables unless asked not to).


a = null; // same as a = string.init;

-Steve


Re: immutable T.init, and pointers to mutable data

2014-09-25 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/25/14 5:47 AM, monarch_dodra wrote:

I was playing around with how T.init works. And I think I may have found
a type loophole.

Given that you may initialize a pointer member to the address to a
static global:

//
__gshared int a = 0;
struct S
{
 int* p = a;
}
//

Then, in theory, any variable, be they mutable or const, are initialized
to T.init:

//
void main()
{
 immutable S s;
}
//

This is an issue, because I now have an immutable pointer that points to
mutable data:
//
 immutable S s = S.init;
 immutable int* p = s.p;
 assert(*p == 0); //OK
 a = 5;
 assert(*p == 5); //OK
//

So this violates the type system...

The question here is:
Is this legit code? At what point do you think my code should have
been rejected?


It should be rejected. The declaration of s (the variable) should be the 
trigger, since it casts the pointer to immutable.


Please file a bug report.

-Steve


Re: immutable T.init, and pointers to mutable data

2014-09-25 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/25/14 9:00 AM, monarch_dodra wrote:

On Thursday, 25 September 2014 at 12:46:01 UTC, Steven Schveighoffer wrote:

On 9/25/14 5:47 AM, monarch_dodra wrote:

I was playing around with how T.init works. And I think I may have found
a type loophole.

Given that you may initialize a pointer member to the address to a
static global:

//
__gshared int a = 0;
struct S
{
int* p = a;
}
//

Then, in theory, any variable, be they mutable or const, are initialized
to T.init:

//
void main()
{
immutable S s;
}
//

This is an issue, because I now have an immutable pointer that points to
mutable data:
//
immutable S s = S.init;
immutable int* p = s.p;
assert(*p == 0); //OK
a = 5;
assert(*p == 5); //OK
//

So this violates the type system...

The question here is:
Is this legit code? At what point do you think my code should have
been rejected?


It should be rejected. The declaration of s (the variable) should be
the trigger, since it casts the pointer to immutable.

Please file a bug report.

-Steve


Hum... So that means certain types just *can't* be initialized (as
immutable) at all?


I wouldn't say that:

immutable s = S(null);

But clearly, any code that results in an immutable pointer to mutable 
data without casts is incorrect. We should start by outlawing such code, 
and if there are ways we can carve out certain usages, we can do that.


-Steve


Re: immutable T.init, and pointers to mutable data

2014-09-25 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/25/14 10:56 AM, monarch_dodra wrote:

On Thursday, 25 September 2014 at 13:37:52 UTC, Steven Schveighoffer wrote:



But clearly, any code that results in an immutable pointer to mutable
data without casts is incorrect. We should start by outlawing such
code, and if there are ways we can carve out certain usages, we can do
that.


Hum... right, but I meant T.init itself would not be valid. As in:
alias T = immutable(S);
T t = T.init; //Illegal?


I would say yes, illegal.

There's some interesting issues with this. For instance, what about:

T[] t;
t.length = 2;

This is a runtime function, and the runtime isn't necessarily aware of 
all the intricacies of a type, it has only blunt instruments (namely the 
TypeInfo init data). So it really can't be asked to know what to do.


I'm kind of leaning towards the notion that immutable(S) should just be 
illegal on principle. But that is quite limiting if you wanted to just 
override the type system.


If we had better implicit casting mechanisms, there may have been a way 
to fix this, but I don't know.



This might be a borderline case, but I kind of figured that that piece
of code was the *only* one that was universally valid in generic code.


I think it's very borderline, not likely to affect many projects.

-Steve


Re: Does D has C#'s string.Empty?

2014-09-26 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/25/14 8:24 PM, AsmMan wrote:

On Thursday, 25 September 2014 at 12:43:57 UTC, Steven
Schveighoffer wrote:

On 9/25/14 2:41 AM, SlomoTheBrave wrote:

On Thursday, 25 September 2014 at 05:29:37 UTC, AsmMan wrote:

Does D has C#'s string.Empty?


string.init ?


string a;
a = string.init;
assert( a == );


does the job for the type string at least.


null also works. In fact, in the above, a is already string.init or
null before assigning (D always initializes variables unless asked not
to).

a = null; // same as a = string.init;



It made me a bit confusing. How is the implementation of string
comparasion in D? (if someone could point to actual code used in
these comparasion would be really great otherwise I'll check out
assembly output, maybe) in no language I know of (including C#)
 == null is true


A string is simply an array of char in D, similar to how it is in C. It 
is NOT a full-blown class type, unlike many languages, C# included.


The code to compare all arrays is somewhere in the runtime, not sure 
exactly where, but the compiler has some tricks it can use when 
generating code, so it may not call those functions.


Essentially, comparison is a foreach over the length of the arrays. If 
they are null, then their lengths are 0. But the actual pointers may be 
different, it doesn't matter.


Interestingly:

string s = ;
string t = [];

Note that both are valid, because both are arrays. but...

assert(s.ptr !is null);
assert(t.ptr is null);

Why? Because string literals are special in that they actually point to 
null terminated memory. So hello is actually an array of 5 chars + a 
6th '\0' char. However, the length of hello is set to 5. The reason 
for this is so you can just pass a string literal into a C function, and 
it works. But due to this rule,  cannot point at null, it must point 
to valid memory for the terminating '\0'.


An array does not need to conform to C rules, so it can safely set the 
pointer to null.


If we compare s and t:

assert(s == t);
assert(s !is t);

this is because == checks to see if the arrays are *equivalent*, meaning 
they have the same length, and all the elements are equivalent. 'is' 
checks to see if the arrays are *identical*, meaning they point at the 
same memory.


-Steve


Re: A few questions regarding GC.malloc

2014-09-26 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/25/14 6:03 PM, Sean Kelly wrote:

On Thursday, 25 September 2014 at 21:43:53 UTC, monarch_dodra wrote:

On Thursday, 25 September 2014 at 20:58:29 UTC, Gary Willoughby wrote:

What does BlkAttr.FINALIZE do when used in the GC.malloc call?


I have no idea. I think its for classes though, since we (currently)
don't finalize structs anyways.


Yes it's for memory blocks containing class instances.  It basically
tells the GC to call Object.~this() when collecting the block.


Just to add to Sean's statement, don't use this flag. It will crash the 
runtime, unless you have properly set up the classinfo pointer :) It 
does NOT work on structs, though I think there is a PR in the works to 
have structs destroyed from the GC.


-Steve


Re: Can I make a variable public and readonly (outside where was declared) at same time?

2014-09-26 Thread Steven Schveighoffer via Digitalmars-d-learn
On 9/26/14 1:36 PM, Marc =?UTF-8?B?U2Now7x0eiI=?= schue...@gmx.net 
wrote:



Alternatively, you could create a union with a private and a public
member with the same types, but I wouldn't recommend it. Besides, the
members would need to have different names:

 class Foo {
 union {
 private int a;
 public int b;
 }
 }


Hm.. that doesn't provide readonly access to either a or b.

But it gave me an idea:

class Foo {
   union {
  private int _a;
  public const int a;
   }
   void setA(int x) { _a = x; }
}

Hot damn! It works too :) Can't access _a from outside the module, can 
access a, but can't write it (even from within Foo). It's like an 
auto-inlined property function.


I don't know how it would affect the optimizer, or the GC scanner. 
Unions are ugly things...


-Steve


Re: A few questions regarding GC.malloc

2014-09-26 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/26/14 3:24 PM, monarch_dodra wrote:

On Friday, 26 September 2014 at 18:03:40 UTC, Steven Schveighoffer wrote:

On 9/25/14 6:03 PM, Sean Kelly wrote:

On Thursday, 25 September 2014 at 21:43:53 UTC, monarch_dodra wrote:

On Thursday, 25 September 2014 at 20:58:29 UTC, Gary Willoughby wrote:

What does BlkAttr.FINALIZE do when used in the GC.malloc call?


I have no idea. I think its for classes though, since we (currently)
don't finalize structs anyways.


Yes it's for memory blocks containing class instances.  It basically
tells the GC to call Object.~this() when collecting the block.


Just to add to Sean's statement, don't use this flag. It will crash
the runtime, unless you have properly set up the classinfo pointer :)
It does NOT work on structs, though I think there is a PR in the works
to have structs destroyed from the GC.


Kind of like APPENDABLE I guess, since it only works if you correctly
setup the appendable data, and correctly slice at the correct offset,
both of which are implementation defined.


Well, kind of yes.

But the difference here is that if APPENDABLE is set, and you never 
actually append to an array in that block, then you are going to be 
fine. Even if you didn't set it up, it's most likely that you will not 
encounter a problem, because whatever is there is likely not the right 
size (and that simply results in a reallocation without touching 
anything). Even if you do manage to use appending on that block, and the 
data that happens to be where the allocated size is matches the current 
slice end, it will corrupt some data (or not, the smaller block sizes 
keep the append data at the end of the block). This could potentially 
crash, or it could do nothing.


If FINALIZE is set, when the GC collects the memory it WILL crash if you 
didn't set up some sort of mock classinfo.


I don't recommend using either, but FINALIZE is a much worse outcome IMO :)

-Steve


Re: Can I make a variable public and readonly (outside where was declared) at same time?

2014-09-27 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/27/14 5:48 AM, Marc =?UTF-8?B?U2Now7x0eiI=?= schue...@gmx.net

Yes, that's what I originally intended. Just forgot the const, and
didn't even notice it after I reread it :-P


I wondered... ;)

-Steve


Re: Initialising multidimensional dynamic arrays

2014-09-30 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/30/14 12:40 PM, Mike James wrote:

On Tuesday, 30 September 2014 at 16:07:28 UTC, ketmar via
Digitalmars-d-learn wrote:



  auto a = new int[][](42, 69);


...



You'll notice that it's actually a dynamic array of structs containing
dynamic arrays - does this change your initializing?


That is what his code does.

-Steve


Re: What is a sink delegate?

2014-09-30 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/30/14 1:22 PM, Gary Willoughby wrote:

What is a sink delegate?

Discussed here:
http://forum.dlang.org/thread/m0bdgg$1t7j$1...@digitalmars.com?page=6#post-m0emvc:242av5:241:40digitalmars.com



Aside from Adam's answer, the term 'sink' means to draw out something, 
as in 'heat sink'. So basically a sink delegate is a place to put the 
string data.


-Steve


Re: is there any reason UFCS can't be used with 'new'?

2014-09-30 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/30/14 2:07 PM, Ali Çehreli wrote:



Apparently, a class definition even inside a unittest blocks are
considered to be nested classes.

Normally, objects of nested classes are created by the 'this.new'
syntax, 'this' meaning the object that wraps the nested class.


I think unit test blocks are actually functions disguised as attributes.

So it makes sense.

void foo()
{
   class C {}
   auto c = New!C; // same error
}

-Steve


Re: Initialising multidimensional dynamic arrays

2014-10-01 Thread Steven Schveighoffer via Digitalmars-d-learn

On 10/1/14 3:13 AM, Mike James wrote:

Hi Steve,

It's true that his code initialises an array of arrays - but my array is
an array of structs containing a dynamic array.

Regards, -=mike=-


Ah, ok.

There is no trivial way to do it. Unlike C++, struct default ctors 
cannot be overridden.


I see your question has been answered, but I would just tweak it a bit:

foreach(ref m; mda) m.data = new short[y];

Only reason for that is, setting length will call some specialized 
function which eventually ends up doing exactly the same thing. The 
above is clearer and more correct IMO.


-Steve


Re: array append result type

2014-10-06 Thread Steven Schveighoffer via Digitalmars-d-learn

On 10/6/14 7:28 AM, John Colvin wrote:

string a;
char[] b;
pragma(msg, typeof(a ~ b)); // char[]

why not string?


It really should be whatever you want. a ~ b is going to generate a 
completely unique independent copy of a and b.



What are the rules that determine this?


Not sure. I would have expected at least one of a ~ b or  b ~ a to be 
string, but both generate char[].


I filed this ER ages ago: https://issues.dlang.org/show_bug.cgi?id=1654

Not sure if anyone has it on their radar at this point.

-Steve


Re: array append result type

2014-10-06 Thread Steven Schveighoffer via Digitalmars-d-learn

On 10/6/14 1:01 PM, monarch_dodra wrote:

On Monday, 6 October 2014 at 16:38:37 UTC, Steven Schveighoffer wrote:

I filed this ER ages ago: https://issues.dlang.org/show_bug.cgi?id=1654

Not sure if anyone has it on their radar at this point.

-Steve


I didn't read the whole thing, but wouldn't purity be a major game
changer for 1654?


Of course! It was immediately what I thought of when purity = unique was 
introduced (that and dup/idup).


This aspect has not been mentioned on the thread, but that issue is 
really old.


-Steve


Re: function not callable using argument types - i disagree

2014-10-08 Thread Steven Schveighoffer via Digitalmars-d-learn

On 10/7/14 3:15 PM, Vlad Levenfeld wrote:

Update: I just did a manual cast. Still getting there error. Here's the
new argument lists:

(void**, const(PaStreamParameters*), const(PaStreamParameters*), double,
uint, uint, extern (C) int function(const(void)*, void*, uint,
const(PaStreamCallbackTimeInfo)*, uint, void*), void*)

(void**, const(PaStreamParameters*), const(PaStreamParameters*), double,
uint, uint, extern (C) int function(const(void)*, void*, uint,
const(PaStreamCallbackTimeInfo)*, uint, void*), void*)

They're identical... unless I'm losing my mind. Yet still its not
callable using argument types



I would suggest removing each parameter from the function prototype and 
call, until you find the culprit. Then put everything else back in. Try 
moving the parameters around.


Yes, the compiled code won't work, but this looks to me like a compiler 
bug (at least a diagnostic issue), and it will help narrow down a simple 
case you can submit.


-Steve


Re: Simple import question

2014-10-09 Thread Steven Schveighoffer via Digitalmars-d-learn

On 10/9/14 3:30 PM, Adam D. Ruppe wrote:

On Thursday, 9 October 2014 at 18:21:32 UTC, WhatMeWorry wrote:

To import one module from another, specify the name of the module in
an import declaration. The name must include the relative path
computed from the directory where compilation takes place


This is not true. It is a REALLY common misconception, but it is not
true. The import name must match the name given in the module
declaration of the file.

So in the file you're importing, add module your.name; to the top. In
the main file, import it as import your.name;. If those two don't
match, it will complain cannot import module foo as foo.bar or
something like that.


Yes, but in order to read the file, it has to be passed to the compiler, 
or reside at the location dictated by that module name.


This is something quite different from C/C++, because the location in 
the filesystem doesn't matter at all for the compiler, only the 
preprocessor. Here, the file location AND module declaration are important.




It is recommended that the module name match the file name and folder
name, but it is the module declaration at the top that matters, not the
file/folder name.


You will encounter great pains to not do this (match folder/file names 
with package/module names).


-Steve


Re: What is a sink delegate?

2014-10-10 Thread Steven Schveighoffer via Digitalmars-d-learn

On 10/10/14 1:00 AM, Ali Çehreli wrote:

On 10/09/2014 08:06 PM, Joel wrote:

On Tuesday, 30 September 2014 at 17:27:09 UTC, Adam D. Ruppe wrote:

On Tuesday, 30 September 2014 at 17:22:44 UTC, Gary Willoughby wrote:

What is a sink delegate?


Instead of

string toString() { return foo; }

for example, you would use:

void toString(void delegate(string) sink) { sink(foo); }

The sink argument there is then free to view and discard the data or
to make a private copy using whatever scheme it desires.



How do you use that toString? Maybe an example? Below is my failed
effort.

import std.stdio;

struct Try {
 string name;
 long age;

 void toString(void delegate(string) sink) {
 sink(foo);
 }
}

void main() {
 Try t = Try(Joel, 35);
 writeln(t);
}


The signature of that toString is different from what I have been seeing
and using. The following works:

 void toString(void delegate(const(char)[]) sink) const {


The delegate parameter is what is important. The function that is going 
to be passed in takes a const(char)[], which actually should, but does 
not, implicitly cast to a delegate(string) (see issue 
https://issues.dlang.org/show_bug.cgi?id=3075).


The const outside is irrelevant to whether it will accept it or not, 
that is a contract between the toString function and your object. If you 
want a non-const toString, I think that should work.


(actually, testing it...) Yep, it works without the const on the outside.

-Steve


Re: What is a sink delegate?

2014-10-10 Thread Steven Schveighoffer via Digitalmars-d-learn

On 10/10/14 11:20 AM, Ali Çehreli wrote:

On 10/10/2014 06:30 AM, Steven Schveighoffer wrote:

  The const outside is irrelevant to whether it will accept it or not,
  that is a contract between the toString function and your object. If you
  want a non-const toString, I think that should work.
 
  (actually, testing it...) Yep, it works without the const on the
outside.

But not for const objects.


I think that's what I said :) It's a contract between the toString 
function and your object, it has nothing to do with writeln accepting 
the function. There are some quirky requirements for certain magic 
functions in phobos that have to be exactly a certain signature for the 
compiler to use it.


Now, obviously, the toy example can be labeled const. But not one that 
might, say, cache some state in order to compute the output.



The following program does not call the user
defined toString:

import std.stdio;
import std.conv;

struct S
{
 int i;

 void toString(void delegate(const(char)[]) sink)
 {
 sink(i.to!string);


Don't do this. Do this instead:

import std.format;
sink.formattedWrite(i);

The former allocates memory on the heap, just to throw it away. You are 
completely losing the benefit of the sink.


-Steve


Re: how to call class' template constructor

2014-10-12 Thread Steven Schveighoffer via Digitalmars-d-learn

On 10/12/14 3:46 PM, ketmar via Digitalmars-d-learn wrote:

Hello.

please, how to call template constructor of a class? it's completely
escaped my mind. i.e. i have this class:

   class A {
 this(alias ent) (string name) {
   ...
 }
   }

and i want to do:

   void foo () { ... }
   auto a = new A!foo(xFn);

yet compiler tells me that

template instance A!foo A is not a template declaration, it is a class

yes, i know that i can rewrite constructor to something like this:

   this(T) (string name, T fn) if (isCallable!T) {
 ...
   }

and then use autodeduction, but i want the first form! ;-)


Hm... I don't think it's very possible, unless you want to call ctor 
directly and not conflate with new (i.e. define a factory function 
instead). Unfortunately, some things can only be done within constructors.


At least someone else has found a similar issue before: 
https://issues.dlang.org/show_bug.cgi?id=10689


I'm not sure what proper syntax would be, perhaps:

auto a = (new A)!foo(xFn);

A good pattern should be able to be discovered here, to help with the 
existing state of affairs...


-Steve


Re: dsource and WinAPI

2014-10-13 Thread Steven Schveighoffer via Digitalmars-d-learn

On 10/13/14 8:17 PM, dcrepid wrote:

I've tried to create an account on dsource.org without success, and am
wondering if anyone here knows if they are no longer accepting new users
or whatnot?


dsource is no longer actively maintained. I don't think anyone knows how 
to contact the admin. Most D projects these days are done on github.




I've added a new winhttp.d source file for the win32 folder and would
like to somehow contribute it.


Which project are you looking at?

-Steve


Re: dsource and WinAPI

2014-10-14 Thread Steven Schveighoffer via Digitalmars-d-learn

On 10/14/14 5:03 AM, dcrepid wrote:

Which project are you looking at?


Bindings for the Windows API:

http://www.dsource.org/projects/bindings/wiki/WindowsApi

This is a pretty important project, especially for getting more Windows
programmers on board..

thanks for your help


Looks like they are still using dsource for that project, latest update 
is 9/7/14.


It does have a github mirror though: 
https://github.com/CS-svnmirror/dsource-bindings


You may be able to at least post a pull request there, and maybe get the 
thing included. The two most recent contributors are regulars here, they 
may be able to get your code considered.


It also looks like the github link is pretty recent (8/16/14), perhaps a 
move to github is forthcoming?


-Steve


Re: Simple import question

2014-10-15 Thread Steven Schveighoffer via Digitalmars-d-learn

On 10/15/14 4:59 AM, Rei Roldan wrote:

I don't see how passing all required files to the compiler could
possible raise an issue with module discoverability. Unless I'm missing
something? In regards to pains if folder|file names / package|module
names don't match, imho, physical organization of files should never
(ever) be of any concern to the compiler.



import a.b.c;

If you didn't pass the file for a.b.c to the compiler, how does it know 
where to find it?


The module system is inherently linked to the filesystem. The way around 
it is to pass all modules to the compiler that you will be importing so 
it knows where they are. But this can lead to problems if you don't 
actually want to compile them, just reference them.


The simplest thing to do is to make your file organization match your 
package/module structure. The compiler understands that and works well 
with it, no matter what you are doing.


-Steve


Re: Simple import question

2014-10-16 Thread Steven Schveighoffer via Digitalmars-d-learn

On 10/16/14 6:59 AM, Rei Roldan wrote:

On Wednesday, 15 October 2014 at 16:11:22 UTC, Steven Schveighoffer wrote:

*snip*


You might of missed Adam's response up there:

 But the best way is to explicitly pass all the file names to the
compiler:

dmd yourfile.d file2.d folder/file3.d and so on...

Doing that will serve you best in the long run, it will work with
any module name and will link better too. 


No, I didn't miss it. As I said, you can do this with mismatched module 
and file names, but you will encounter issues if your files need to be 
imported elsewhere.


Note, you can send all the files to the compiler, AND name your 
files/directories after your modules/packages. Matching the names 
actually gives you the most options.



I also prefer explicitly telling the compiler what I want to be compiled
instead of the start here and pull everything you can find approach.


What I am specifically identifying as a problem is if you purposely do 
not name your files and directories after your module structure. Then 
you are REQUIRED to pass all the files to the compiler, and this doesn't 
work out well if you just want to import them (and not compile them), 
e.g. for a pre-compiled library.


-Steve


Re: Constructor params with same name as members

2014-10-23 Thread Steven Schveighoffer via Digitalmars-d-learn

On 10/23/14 1:03 AM, Shriramana Sharma via Digitalmars-d-learn wrote:

Hello. Please see the following code:

import std.stdio ;
struct Pair {
int x, y ;
this (int x, int y) { x = x ; y = y ; }
}
void main() {
auto P = Pair(1, 2) ;
writeln(P.x, ' ', P.y) ;
}

This outputs 0 0, whereas the equivalent C++ code outputs 1 2 correctly:

# include iostream
struct Pair {
int x, y ;
Pair(int x, int y) : x(x), y(y) {}
} ;


This is not the same. In the above, the x outside the parens is ALWAYS a 
member. D does not have this syntax. Change it to the same as your D 
implementation, and you get the same result (actually worse, because C++ 
will not initialize x and y for you).



int main() {
auto P = Pair(1, 2) ;
std::cout  P.x  ' '  P.y  std::endl ;
}

It seems to me that D should either not permit argument names to
shadow the member names, since it has no initializer lists and all
members are automatically initialized. Comments?


You're missing the or part of that statement :)

But 2 things:

x = x;

This should produce an error, or at least a warning I think, as it does 
nothing. However, even with dmd -w, it does not. I know I have seen the 
compiler complain about noop statements before, I just don't know under 
what circumstances


and 2, you would use the same mechanism as you use with C++ to 
initialize the items inside the ctor:


this.x = x;

Note, the rules for shadowing are the same as for any function 
parameters to any function vs. members or module variables. Nothing is 
inconsistent here.


-Steve


Re: Bug?

2014-10-23 Thread Steven Schveighoffer via Digitalmars-d-learn

On 10/23/14 1:08 PM, deed wrote:

// DMD v2.066.0
// All asserts pass (!)


Using equality is not a good idea with floating point.

The compiler will on a whim, or depending on whether it can inline or 
not, use higher precision floats, changing the outcome slightly.


I cannot say for certain whether this explains all the issues you have, 
the very last one seems troubling to me at least.


-Steve


Re: Bug?

2014-10-23 Thread Steven Schveighoffer via Digitalmars-d-learn

On 10/23/14 2:18 PM, deed wrote:

Using equality is not a good idea with floating point.

The compiler will on a whim, or depending on whether it can inline or
not, use higher precision floats, changing the outcome slightly.

I cannot say for certain whether this explains all the issues you
have, the very last one seems troubling to me at least.



Sure, in many cases it's a bad idea. While I understand that sin(PI) !=
0.0, but approxEqual(sin(PI), 0.0) == true, I would expect the following
to pass:

assert (0.0 == 0.0);
assert (1.2345 == 1.2345);
F a = 1.2345, b = 9.8765;

assert (a+b == b+a);
assert (a*b == b*a);


None of these fail on my system


F fun (F a) pure;

assert (fun(a) + fun(b) == fun(b) + fun(a));
assert (fun(a) * fun(b) == fun(b) * fun(a));

auto a = fun(100);
auto b = fun(100);

assert (a == b);
assert (fun(100) == fun(100));



Not sure what body of fun is, so I cannot test this.



Now, if fun's body is { return sin(a); }, the behaviour changes to:

auto c = fun(100);
auto d = fun(100);

assert (c == d);  // Ok
assert (fun(100) != fun(100)) // I have a hard time understanding
   // this is correct behaviour


Tried that out, it does not fail on my machine. Can you be more specific 
on your testing? What compiler/platform? Stock compiler, or did you 
build it yourself?


-Steve


  1   2   3   4   5   6   7   8   9   10   >