Re: rdmd bug?

2010-12-20 Thread spir
On Mon, 20 Dec 2010 04:27:33 +0300
Nick Voronin  wrote:

> On Mon, 20 Dec 2010 01:24:02 +0100
> CrypticMetaphor  wrote:
> 
> > Anyway, the problem is, if I call rdmd from outside the folder in which 
> > the main source resides in, and main includes another file in that 
> > folder, I get an error.
> 
> > // If I'm in a shell, and I do this, I get an error:
> > ...\projectfolder>rdmd src\main.d
> > src\main.d(2): Error: module test is in file 'test.d' which cannot be read
> > import path[0] = C:\D\dmd2\windows\bin\..\..\src\phobos
> > import path[1] = C:\D\dmd2\windows\bin\..\..\src\druntime\import
> 
> > Anyway, I want to be able to compile with rdmd from a different folder, 
> > is this a bug? or should I use a different tool? :-S
> > *aahhh*
> 
> Add -Ifullpath_to_projectfolder\src. It's the way it works IMHO, if you 
> import something it must be relative to search path or to current dir. There 
> may be a better way (replace current dir with the dir where source is, but it 
> will take away control), but this works.
> 
> There is a bug though, I can't make it work with -Irelative_path_to_src. 
> Looks like .deps contain paths relative to where rdmd was ran, while dmd 
> interprets them as paths relative to where .deps file is.

Yes, I think it cannot work, since -I is a option of dmd, not of rdmd. rdmd 
just passes by options to dmd if I understand correctly. What you want is to 
influence a feature provided dy rdmd, not dmd, namely automatic inclusion of 
(non-standard) imports.
But sure, it may be a bug: rdmd should look for imports using pathes relative 
to the location of the (app) module it is given. Or, for simplicity, we can 
just state it must be called from this location.

Denis
-- -- -- -- -- -- --
vit esse estrany ☣

spir.wikidot.com



Re: Classes or stucts :: Newbie

2010-12-20 Thread spir
On Sun, 19 Dec 2010 21:33:56 -0500
bearophile  wrote:

> >So, putting classes on the stack kind of negates the whole point of having 
> >both structs and classes in the first place.<  
> 
> This is false, the definition of D class instance doesn't specify where the 
> instance memory is allocated.

For me, the important difference is that classes are referenced, while structs 
are plain values. This is a semantic distinction of highest importance. I would 
like structs to be subtype-able and to implement (runtime-type-based) 
polymorphism.

Denis
-- -- -- -- -- -- --
vit esse estrany ☣

spir.wikidot.com



Re: Classes or stucts :: Newbie

2010-12-20 Thread Jonathan M Davis
On Monday 20 December 2010 01:19:31 spir wrote:
> On Sun, 19 Dec 2010 21:33:56 -0500
> 
> bearophile  wrote:
> > >So, putting classes on the stack kind of negates the whole point of
> > >having both structs and classes in the first place.<
> > 
> > This is false, the definition of D class instance doesn't specify where
> > the instance memory is allocated.
> 
> For me, the important difference is that classes are referenced, while
> structs are plain values. This is a semantic distinction of highest
> importance. I would like structs to be subtype-able and to implement
> (runtime-type-based) polymorphism.

Except that contradicts the facts that they're value types. You can't have a 
type which has polymorphism and is a value type. By its very nature, 
polymorphism requires you to deal with a reference.

C++ allows you to put classes on the stack. It even allows you to assign a 
derived type to a base type where the variable being assigned to is on the 
stack. The result is shearing. The only part assigned is the base type portion, 
and the data which is part of the derived type is lost. That's because the 
variable _is_ the base type. A value type _is_ a particular type _exactly_ and 
_cannot_ be any other type. This is distinctly different from a reference of a 
base type which points to an object which is of a derived type. In that case, 
the variable is a reference of the base type, but the object referenced is in 
fact the derived type. The indirection allows you to use the derived type as if 
it were the base type. It allows you to use polymorphism. Without that 
indirection, you can't do that.

So, you _could_ make structs have inheritance, but doing so would introduce 
shearing, which causes a number of problems. One of the main reasons that 
structs in D do _not_ have inheritance is to avoid shearing.

- Jonathan M Davis


enum ubyte[] vs enum ubyte[3]

2010-12-20 Thread Johannes Pfau

Hi,
I'm currently patching Ragel (http://www.complang.org/ragel/) to generate  
D2 compatible code. Right now it creates output like this for static  
arrays:


enum ubyte[] _parseResponseLine_key_offsets = [
0, 0, 17, 18, 37, 41, 42, 44,
50, 51, 57, 58, 78, 98, 118, 136,
138, 141, 143, 146, 148, 150, 152, 153,
159, 160, 160, 162, 164
];

Making it output "enum ubyte[30]" would be more complicated, so I wonder  
if there's a difference between "enum ubyte[]" and "enum ubyte[30]"?


--
Johannes Pfau


Re: Classes or stucts :: Newbie

2010-12-20 Thread spir
On Mon, 20 Dec 2010 01:29:13 -0800
Jonathan M Davis  wrote:

> > For me, the important difference is that classes are referenced, while
> > structs are plain values. This is a semantic distinction of highest
> > importance. I would like structs to be subtype-able and to implement
> > (runtime-type-based) polymorphism.  
> 
> Except that contradicts the facts that they're value types. You can't have a 
> type which has polymorphism and is a value type. By its very nature, 
> polymorphism requires you to deal with a reference.

Can you expand on this?

At least Oberon has value structs ("records") with inheritance and 
polyporphism; I guess the turbo Pascal OO model was of that kind, too (unsure) 
-- at least the version implemented in freepascal seems to work fine that way. 
And probably loads of less known PLs provide such a feature.
D structs could as well IIUC: I do not see the relation with instances beeing 
implicitely referenced. (Except that they must be passed by ref to "member 
functions" they are the receiver of, but this is true for any kind of OO, 
including present D structs.)

(I guess we have very different notions of "reference", as shown by previous 
threads.)


Denis
-- -- -- -- -- -- --
vit esse estrany ☣

spir.wikidot.com



Re: enum ubyte[] vs enum ubyte[3]

2010-12-20 Thread bearophile
Johannes Pfau:

Hello Johannes and thank you for developing your tool for D2 too :-)


> Making it output "enum ubyte[30]" would be more complicated, so I wonder  
> if there's a difference between "enum ubyte[]" and "enum ubyte[30]"?

In D1 a enum ubyte[] is a compile-time constant dynamic array of unsigned 
bytes, it is a 2 word long struct that contains a pointer and a length.
In D1 you express the same thing with "const ubyte[]".

In D2 a "enum ubyte[30]" is a compile-time constant fixed size array of 32 
unsigned bytes that gets passed around by value.
In D1 a "const ubyte[30]" is a compile-time constant fixed size array of 32 
unsigned bytes that gets passed around by reference.

So they are two different things and you use one or the other according to your 
needs. Currently there are also some low performance issues in D with enums 
that get re-created each time you use them (this is true for associative 
arrays, but I don't remember if this is true for dynamic arrays too). So better 
to take a look at the produced asm to be sure, if you want to avoid performance 
pitfalls.

Regardless the array kind you want to use, also take a look at "Hex Strings":
http://www.digitalmars.com/d/2.0/lex.html
That allow you to write bytes arrays as hex data:
x"00 FBCD 32FD 0A"

Bye,
bearophile


Re: enum ubyte[] vs enum ubyte[3]

2010-12-20 Thread Johannes Pfau

At 20.12.2010, 11:02, bearophile wrote :


Hello Johannes and thank you for developing your tool for D2 too :-)

Actually it's not mine, I'm just a regular user. I don't think I could  
ever understand the finite state machine code (especially because it's  
c++), but patching the c/d1 codegen to output d2 code is easy enough ;-)


In D1 a enum ubyte[] is a compile-time constant dynamic array of  
unsigned bytes, it is a 2 word long struct that contains a pointer and a  
length.

Did you mean in D2? I feared that, so I'll have to do some extra work...

In D2 a "enum ubyte[30]" is a compile-time constant fixed size array of  
32 unsigned bytes that gets passed around by value.

Yep, that's what I want.



Regardless the array kind you want to use, also take a look at "Hex  
Strings":

http://www.digitalmars.com/d/2.0/lex.html
That allow you to write bytes arrays as hex data:
x"00 FBCD 32FD 0A"
That's interesting, I'll have a look at it, but ragel shares big parts of  
the c/c++/d code, so as long as the C syntax works there's no need to  
change that.




Bye,
bearophile


Thanks for your help!

--
Johannes Pfau


Re: enum ubyte[] vs enum ubyte[3]

2010-12-20 Thread bearophile
Johannes Pfau:

> Did you mean in D2?

Right, sorry.
Bye,
bearophile


Re: Classes or stucts :: Newbie

2010-12-20 Thread bearophile
Nick Voronin:

> Here is where we diverge. Choosing struct vs class on criteria of their 
> placement makes no sense to me. 

In D you use a class if you want inheritance or when you (often) need reference 
semantics, and you use a struct when you need a little value passed around by 
value or when you want a simple form of RAII or when you want to implement 
something manually (like using PIMPL), or when you want max performance (and 
you manage structs by pointer, you may even put a tag inside the stuct or the 
pointer and implement manually some kind of inheritance). With structs you have 
a literal syntax, postblits, in-place allocation, and you are free to use 
align() too.

Bye,
bearophile


Re: define methods apart

2010-12-20 Thread Christopher Nicholson-Sauls
On 12/19/10 06:52, spir wrote:
> On Sun, 19 Dec 2010 03:37:37 -0600
> Christopher Nicholson-Sauls  wrote:
> 
>> On 12/18/10 07:19, spir wrote:
>>> Hello,
>>>
>>>
>>> I cannot find a way to define methods (I mean "member functions) outside 
>>> the main type-definition body:
>>>
>>> struct X {}
>>> void X.say () {writeln("I say!");}
>>> ==>
>>> Element.d(85): semicolon expected, not '.'
>>>
>>> Do I overlook anything, or is this simply impossible? In the latter case, 
>>> what is the problem?
>>> (In many languages, not only dynamic ones, method are or at least can be 
>>> defined apart.)
>>>
>>>
>>> Denis
>>> -- -- -- -- -- -- --
>>> vit esse estrany ☣
>>>
>>> spir.wikidot.com
>>>
>>
>> As bearophile says, it just isn't the "D way" to do things.
>>
>> But, if you absolutely must (or just want to, for "playing" sakes) there
>> are ways of faking it using opDispatch.  Here's one I just tossed
>> together and tested (DMD 2.050) right now.
>>
>> [code snipped]
>>
>> Generally speaking, though, I'm not sure what the real value would be in
>> doing this in D.  Did you have a particular use case in mind, or was it
>> just idle exploration?
> 
> Thank you very for this example use of opdispatch :-)
> I'm still exploring the language (which I like very much, except for some 
> given features *). Actually, I just wanted to know whether it's possible, 
> because I'm used to this way and find it more practicle or readable in 
> various cases. But it is not a problem.
> 
> Denis
> 
> (*) Some inherited from C/C++ (unhelpful syntax or semantics, mainly), some 
> among the newest (too abstract or complicated, i'd say).
> -- -- -- -- -- -- --
> vit esse estrany ☣
> 
> spir.wikidot.com
> 

No problem.  opDispatch has a number of possible uses.  Another thing
I've done with it before is to wrap the message passing system from
std.concurrency, to ease defining message protocols.  Basically I define
a message as a struct, then define an opDispatch that looks for the
pattern 'sendBLAH(...)' and forwards that to 'tid.send(BLAHMessage(...),
thisTid())' auto-magically.  To make it really magical I had to create
some code-generation for the receiving end so it would provide an
argument to receive/receiveTimeout for each handleBLAH method I define.

It had a few little bugs/quirks though, which is why I haven't ever
shared it.

-- Chris N-S


Re: Classes or stucts :: Newbie

2010-12-20 Thread Jonathan M Davis
On Monday 20 December 2010 01:52:58 spir wrote:
> On Mon, 20 Dec 2010 01:29:13 -0800
> 
> Jonathan M Davis  wrote:
> > > For me, the important difference is that classes are referenced, while
> > > structs are plain values. This is a semantic distinction of highest
> > > importance. I would like structs to be subtype-able and to implement
> > > (runtime-type-based) polymorphism.
> > 
> > Except that contradicts the facts that they're value types. You can't
> > have a type which has polymorphism and is a value type. By its very
> > nature, polymorphism requires you to deal with a reference.
> 
> Can you expand on this?
> 
> At least Oberon has value structs ("records") with inheritance and
> polyporphism; I guess the turbo Pascal OO model was of that kind, too
> (unsure) -- at least the version implemented in freepascal seems to work
> fine that way. And probably loads of less known PLs provide such a
> feature. D structs could as well IIUC: I do not see the relation with
> instances beeing implicitely referenced. (Except that they must be passed
> by ref to "member functions" they are the receiver of, but this is true
> for any kind of OO, including present D structs.)
> 
> (I guess we have very different notions of "reference", as shown by
> previous threads.)

Okay. This can get pretty complicated, so I'm likely to screw up on some of the 
details, but this should give you a basic idea of what's going on.

In essentially any C-based language, when you declare an integer on the stack 
like so:

int a = 2;

you set aside a portion of the stack which is the exact size of an int 
(typically 32 bits, but that will depend on the language). If you declare a 
pointer,

int* a;

then you're setting aside a portion of the stack the size of a pointer (32 bits 
on a 32 bit machine and 64 bits on a 64 bit machine). That variable then holds 
an address - typically to somewhere on the heap, though it could be to an 
address on the stack somewhere. In the case of int*, the address pointed to 
will 
refer to a 32-bit block of memory which holds an int.

If you have a struct or a class that you put on the stack. Say,

class A
{
int a;
float b;
}

then you're setting aside exactly as much space as that type requires to hold 
itself. At minimum, that will be the total size of its member variables (in 
this 
case an int and a float, so probably a total of 64 bits), but it often will 
include extra padding to align the variables along appropriate boundaries for 
the sake of efficiency, and depending on the language, it could have extra type 
information. If the class has a virtual table (which it will if it has virtual 
functions, which in most any language other than C++ would mean that it 
definitely has a virtual table), then that would be part of the space required 
for the class as well (virtual functions are polymorphic; when you call a 
virtual function, it calls the version of the function for the actual type that 
an object is rather than the pointer or reference that you're using to refer to 
the object; when a non-virtual function function is called, then the version of 
the function which the pointer or reference is is used; all class functions are 
virtual in D unless the compiler determines that they don't have to be and 
optimizes it out (typically because they're final); struct functions and stand-
alone functions are never virtual). The exact memory layout of a type _must_ be 
known at compile time. The exact amount of space required is then known, so 
that 
the stack layout can be done appropriately.

If you're dealing with a pointer, then the exact memory layout of the memory 
being pointed to needs to be known when that memory is initialized, but the 
pointer doesn't necessarily need to know it. This means that you can have a 
pointer of one type point to a variable of another type. Now, assuming that 
you're not subverting the type system (e.g. my casting int* to float*), you're 
dealing with inheritance. For instance, you have

class B : A
{
bool c;
}

and a variable of type A*. That pointer could point to an object which is 
exactly of type A, or it could point to any subtype of A. B is derived from A, 
so the object could be a B. As long as the functions are virtual, you can have 
polymorphic functions by having the virtual table used to call the version of 
the function for the type that the object actually is rather than the type that 
the pointer is.

References are essentially the same as pointers (though they may have some 
extra 
information with them, making them a bit bigger than a pointer would be in 
terms 
of the amount of space required on the stack). However, in the case of D, 
pointers are _not_ treated as polymorphic (regardless of whether a function is 
virtual or not), whereas references _are_ treated as polymorphic (why, I don't 
know - probably to simplify pointers). In C++ though, pointers are polymorphic.

Now, if you have a variable of type A*, you could do something l

Re: enum ubyte[] vs enum ubyte[3]

2010-12-20 Thread Nick Voronin
On Mon, 20 Dec 2010 10:26:16 +0100
"Johannes Pfau"  wrote:

> Hi,
> I'm currently patching Ragel (http://www.complang.org/ragel/) to generate  
> D2 compatible code.

Interesting. Ragel-generated code works fine for me in D2. I suppose it mostly 
uses such a restricted C-like subset of language that it didn't change much 
from D1 to D2. But if you are going to patch it, please make it add extra {} 
around action code! The thing is that when there is a label before {} block 
(and in ragel generated code I saw it's always so) the block isn't considered 
as a new scope which causes problems when you have local variables declaration 
inside actions.

Anyway, good luck with whatever you plan :) Ragel is cool.

> Right now it creates output like this for static  
> arrays:
> 
> enum ubyte[] _parseResponseLine_key_offsets = [
>   0, 0, 17, 18, 37, 41, 42, 44,
>   50, 51, 57, 58, 78, 98, 118, 136,
>   138, 141, 143, 146, 148, 150, 152, 153,
>   159, 160, 160, 162, 164
> ];
> 
> Making it output "enum ubyte[30]" would be more complicated, so I wonder  
> if there's a difference between "enum ubyte[]" and "enum ubyte[30]"?

One is fixed size array and other is dynamic. Honestly I doubt that it matters 
for code generated by Ragel, since this is constant and won't be passed around. 
If it's harder to make it fixed-size then don't bother.

-- 
Nick Voronin 


Re: enum ubyte[] vs enum ubyte[3]

2010-12-20 Thread Jonathan M Davis
On Monday 20 December 2010 01:26:16 Johannes Pfau wrote:
> Hi,
> I'm currently patching Ragel (http://www.complang.org/ragel/) to generate
> D2 compatible code. Right now it creates output like this for static
> arrays:
> 
> enum ubyte[] _parseResponseLine_key_offsets = [
>   0, 0, 17, 18, 37, 41, 42, 44,
>   50, 51, 57, 58, 78, 98, 118, 136,
>   138, 141, 143, 146, 148, 150, 152, 153,
>   159, 160, 160, 162, 164
> ];
> 
> Making it output "enum ubyte[30]" would be more complicated, so I wonder
> if there's a difference between "enum ubyte[]" and "enum ubyte[30]"?

ubyte[] is a dynamic array. ubyte[30] is a static array. They are inherently 
different types. The fact that you're dealing with an enum is irrelevant. So, 
the 
code that you're generating is _not_ a static array. It's a dynamic array. This 
is inherently different from C or C++ where having [] on a type (whether it has 
a 
number or not) is _always_ a static array.

- Jonathan M Davis


Re: Classes or stucts :: Newbie

2010-12-20 Thread bearophile
Jonathan M Davis:

> So, putting classes on the stack kind of negates the whole point of having
> both structs and classes in the first place.

Where you put the instance is mostly a matter of implementation. This is why a 
smart JavaVM is able to perform escape analysis and choose where to allocate 
the class instance.

Keep in mind that if you allocate a class on the stack or in-place inside 
another class, you don't turn it into a value, because beside the class 
instance you reserve space for its reference too (this reference may even be 
immutable, if you want).


> scoped classes are definitely not in SafeD.

Well implemented scoped classes are safe enough (compared to the other things). 
The compiler may perform escape analysis of all the aliases of a scoped object 
and statically raise an error if a reference escapes. This isn't 100% safe in a 
language that has all kind of casts and low-level features, but it's often safe 
enough, compared to other things. And those casts and low level features that 
can fool the escape analysis can be disabled statically (with something like 
@safe), this makes scoped classes 100% safe, probably safer than heap 
allocations.


>The whole point of "safe" when talking about safe in D is memory saftey.

I know, but some people (including me) think that "safe D" is a misleading name 
because it just means "memory safe D".


>If the compiler can determine that a particular class object can be put on the 
>stack and optimize it that way. Fine, but it's pretty rare that it can do that 
>- essentially only in cases where you don't pass it to _anything_ except for 
>pure functions (including calls to member functions).

I don't agree that it's rare. If a function that allocates an object calls a 
function (or member function) that's present in the same compilation unit (this 
more or less means same module), then the compiler is able to continue the 
escape analysis and determine if the called function escapes the reference. If 
this doesn't happen, then the class instance is free to be scoped. This 
situation is common enough.


>And if the compiler can do that, then it there's no need for the programmer to 
>use scope explicitly.<

I don't agree. An annotation like "@scope" is a contract between the programmer 
and the compiler. It means that if the compiler sees a reference escape, then 
it stops the compilation.


>And no, a compiler _can't_ do pure optimizations on its own, 
>generally-speaking, because that would require looking not only at the body of 
>the function that's being called but at the function bodies of any functions 
>that it calls. D is not designed in a way that the compiler even necessarily 
>has _access_ to a function's body when compiling, and you can't generally look 
>at a function's body when doing optimizations when calling that function. So, 
>_some_ pure optimizations could be done, but most couldn't. This is not the 
>case with scoped classes, because purity already gives you the information 
>that you need.<

Quite often a function calls another function in thee same compilation unit, in 
this case the analysis is possible. So you limit the optimizations to this 
common but limited case.

And LDC compiler and in future GDC too, have link-time optimization, this means 
the compiler packs or sees the program code code in a single compilation unit. 
In this case it's able to perform a more complete analysis (including 
de-virtualization of some virtual functions).


>Safety by convention means that the language and the compiler do not enforce 
>it in any way.<

This is not fully true. If the syntax of the unsafe thing is ugly and long, the 
programmer is discouraged to use it. This makes the unsafe thing more visible 
for the eyes of the programmer. Statistically this may reduce bug count.


>There's nothing contradictory about Walter's stance. He's for having safety 
>built into the language as much as reasonably possible and against having it 
>thrust upon the programmer to program in a particular way to avoid unsafe 
>stuff.<

I think you have missed part of the context of my comments for Nick Voronin, he 
was trying to say something here:

>Yet we won't have library solution for pointers instead of language support 
>(hopefully)? :) I think it all goes against "being practical" as an objective 
>of the language. Safety is important but you don't achieve safety by means of 
>making unsafe thing unconvenient and inefficient. If there is emplace() then 
>there is no reason not to have scope storage class. At least looking from 
>user's POV. I don't know how hard it is on the compiler.<
>In _general_ case there is no safety in D. With all low-level capabilities one 
>can always defeat compiler. Removing intermediate-level safer (yet unsafe) 
>capabilities arguabily gains nothing but frustration. I'm all for encouraging 
>good practices, but this is different.<

In D the convention is to not use certain low-level means to do something (and 
@s

Re: string comparison

2010-12-20 Thread Lars T. Kyllingstad
On Sun, 19 Dec 2010 07:01:30 +, doubleagent wrote:

> Andrei's quick dictionary illustration [in his book, 'The D Programming
> Language'] doesn't seem to work.  Code attached.

That's strange.  I ran the example you posted using DMD 2.050 myself, and 
it works for me.  Are you 100% sure that you are running this version, 
and that it is not using an outdated Phobos version (from an older 
installation, for instance)?

One suggestion:  Try replacing the next-to-last line with this:

  dictionary[word.idup] = newId;

The 'word' array is mutable and reused by byLine() on each iteration.  By 
doing the above you use an immutable copy of it as the key instead.


> On my computer, with d2-0.5.0, I got the following output while testing.
> 
> andrei
> 0 andrei
>  andrei
> 1 andrei
> 
> 
> Also, why doesn't 'splitter' show up on the site's documentation of
> std.string?  And what advantage does 'splitter(strip(line))' offer over
> 'split(line)'?

splitter is defined in std.algorithm.  The fact that it becomes visible 
when you import std.string is due to bug 314:

  http://d.puremagic.com/issues/show_bug.cgi?id=314

(std.string is supposed to publically import just a few symbols from 
std.algorithm, but because of this bug the whole module gets imported 
publically.)

The advantage with splitter is that it is lazy and therefore more 
efficient.  split() is eager and allocates memory to hold the string 
fragments.

-Lars


Re: Classes or stucts :: Newbie

2010-12-20 Thread spir
On Mon, 20 Dec 2010 03:11:49 -0800
Jonathan M Davis  wrote:

> Now, you could conceivably have a language where all of its objects were 
> actually pointers, but they were treated as value types. So,
> 
> B b;
> A a = b;
> 
> would actually be declaring
> 
> B* b;
> A* a = b;
> 
> underneath the hood, except that the assignment would do a deep copy and 
> allocate the appropriate meemory rather than just copying the pointer like 
> would 
> happen in a language like C++ or D. Perhaps that's what Oberon does. I have 
> no 
> idea. I have never heard of the language before, let alone used it.

I don't know how Oberon works. But I'm sure that its records are plain values, 
_not_ "pointed" under the hood. And their methods all are virtual (they have a 
virtual method table). I have no more details, sorry.

Denis
-- -- -- -- -- -- --
vit esse estrany ☣

spir.wikidot.com



Re: string comparison

2010-12-20 Thread Stanislav Blinov

20.12.2010 8:35, doubleagent пишет:

Compared to the relatively snappy response other threads have been receiving I'm
going to assume that nobody is interested in my inquiry.

That's cool.  Can anybody point me to an IRC chatroom for D noobs, and is there
anywhere to post errata for the book?

Please don't feel offended if you don't get response quickly. Even if it 
may seem that people are active in other threads doesn't mean they are 
fast enough to analyse arising questions and problems while discussing 
some recent ideas and improvements and not forgetting to work and sleep ;)
Besides, there are many people here from different parts of the world, 
different time zones.


And lastly, hasn't this by chance been your first post? AFAIR, the first 
message is being moderated so it doesn't get to the public at once.


BTW, There is a #D channel on freenode, if my memory serves.


Re: enum ubyte[] vs enum ubyte[3]

2010-12-20 Thread Johannes Pfau

On Monday, December 20, 2010, Nick Voronin  wrote:


On Mon, 20 Dec 2010 10:26:16 +0100
"Johannes Pfau"  wrote:


Hi,
I'm currently patching Ragel (http://www.complang.org/ragel/) to  
generate

D2 compatible code.


Interesting. Ragel-generated code works fine for me in D2. I suppose it  
mostly uses such a restricted C-like subset of language that it didn't  
change much from D1 to D2.
The most important change is const correctness. Because of that table  
based output didn't work with D2. And you couldn't directly pass const  
data (like string.ptr) to Ragel.


But if you are going to patch it, please make it add extra {} around  
action code! The thing is that when there is a label before {} block  
(and in ragel generated code I saw it's always so) the block isn't  
considered as a new scope which causes problems when you have local  
variables declaration inside actions.


You mean like this code:
-
tr15:
#line 228 "jpf/http/parser.rl"
{
if(start != p)
{
key = line[(start - line.ptr) .. (p - line.ptr)];
}
}
-
should become: ?
-
tr15:
#line 228 "jpf/http/parser.rl"
{{
if(start != p)
{
key = line[(start - line.ptr) .. (p - line.ptr)];
}
}}
-

One is fixed size array and other is dynamic. Honestly I doubt that it  
matters for code generated by Ragel, since this is constant and won't be  
passed around. If it's harder to make it fixed-size then don't bother.


Could a dynamic array cause heap allocations, even if it's data is never  
changed? If not, dynamic arrays would work fine.


--
Johannes Pfau


Re: Problems with Reflection in Static library

2010-12-20 Thread Stanislav Blinov

19.12.2010 10:51, Mandeep Singh Brar пишет:

Thanks a lot for your reply Tomek. I understand what you are saying
but this would not work for me. The reason is that i am trying to
make some kind of plugins from these libs. So i would not know the
name objectFactory also in advance (multiple plugins will not be
implementing the same named method and linking statically).

For now i am just merging these two into the same place.
In general, it's not a very good idea to make plugins using static 
linkage. Even if your plugins will be dynamic libraries (dll/so), which 
is currently not possible at least on Linux (and at least with dmd, I 
don't know about gdc2), but the core to which they are plugged-in 
remains static library, you may and most certainly will get unpleasant 
surprises. Reason being, any static data contained in the static library 
will be duplicated for every executable/dll that links to it. I don't 
know if anything can be done with it (actually, I think nothing can be). 
So for plugins, it's better to keep the 'core' also as a dynamic 
library. But, again, dmd is currently is not on good terms with dynamic 
linking (aside from loading a C dll at runtime, but that doesn't count).


Re: string comparison

2010-12-20 Thread Jonathan M Davis
On Monday, December 20, 2010 06:01:23 Lars T. Kyllingstad wrote:
> On Sun, 19 Dec 2010 07:01:30 +, doubleagent wrote:
> > Andrei's quick dictionary illustration [in his book, 'The D Programming
> > Language'] doesn't seem to work.  Code attached.
> 
> That's strange.  I ran the example you posted using DMD 2.050 myself, and
> it works for me.  Are you 100% sure that you are running this version,
> and that it is not using an outdated Phobos version (from an older
> installation, for instance)?
> 
> One suggestion:  Try replacing the next-to-last line with this:
> 
>   dictionary[word.idup] = newId;
> 
> The 'word' array is mutable and reused by byLine() on each iteration.  By
> doing the above you use an immutable copy of it as the key instead.
> 
> > On my computer, with d2-0.5.0, I got the following output while testing.
> > 
> > andrei
> > 0   andrei
> > 
> >  andrei
> > 
> > 1   andrei
> > 
> > 
> > Also, why doesn't 'splitter' show up on the site's documentation of
> > std.string?  And what advantage does 'splitter(strip(line))' offer over
> > 'split(line)'?
> 
> splitter is defined in std.algorithm.  The fact that it becomes visible
> when you import std.string is due to bug 314:
> 
>   http://d.puremagic.com/issues/show_bug.cgi?id=314
> 
> (std.string is supposed to publically import just a few symbols from
> std.algorithm, but because of this bug the whole module gets imported
> publically.)

Actually, while that is a definite bug, splitter() _is_ defined in std.string 
as 
well (though it calls std.algorithm.splitter()), but it returns auto, so it 
doesn't show up in the docs, which is a different bug.

- Jonathan M Davis


Re: Classes or stucts :: Newbie

2010-12-20 Thread Jonathan M Davis
On Monday, December 20, 2010 03:19:48 bearophile wrote:
> Jonathan M Davis:
> > So, putting classes on the stack kind of negates the whole point of
> > having both structs and classes in the first place.
> 
> Where you put the instance is mostly a matter of implementation. This is
> why a smart JavaVM is able to perform escape analysis and choose where to
> allocate the class instance.
> 
> Keep in mind that if you allocate a class on the stack or in-place inside
> another class, you don't turn it into a value, because beside the class
> instance you reserve space for its reference too (this reference may even
> be immutable, if you want).
> 
> > scoped classes are definitely not in SafeD.
> 
> Well implemented scoped classes are safe enough (compared to the other
> things). The compiler may perform escape analysis of all the aliases of a
> scoped object and statically raise an error if a reference escapes. This
> isn't 100% safe in a language that has all kind of casts and low-level
> features, but it's often safe enough, compared to other things. And those
> casts and low level features that can fool the escape analysis can be
> disabled statically (with something like @safe), this makes scoped classes
> 100% safe, probably safer than heap allocations.
> 
> >The whole point of "safe" when talking about safe in D is memory saftey.
> 
> I know, but some people (including me) think that "safe D" is a misleading
> name because it just means "memory safe D".

Talking about SafeD meaning memory safety makes the meaning of safety clear. If 
you try and make the term safety encompass more than that, it takes very little 
for "safety" to become subjective. Regardless of whether it would be nice if 
SafeD gave types of safety other than memory safety, when D documentation and 
any of the main D devs talk about safety, it is memory safety which is being 
referred to. Trying to expand the meaning beyond that will just cause confusion 
regardless of whether the non-memory safety being discussed is desirable or not.

> >If the compiler can determine that a particular class object can be put on
> >the stack and optimize it that way. Fine, but it's pretty rare that it
> >can do that - essentially only in cases where you don't pass it to
> >_anything_ except for pure functions (including calls to member
> >functions).
> 
> I don't agree that it's rare. If a function that allocates an object calls
> a function (or member function) that's present in the same compilation
> unit (this more or less means same module), then the compiler is able to
> continue the escape analysis and determine if the called function escapes
> the reference. If this doesn't happen, then the class instance is free to
> be scoped. This situation is common enough.
> 
> >And if the compiler can do that, then it there's no need for the
> >programmer to use scope explicitly.<
> 
> I don't agree. An annotation like "@scope" is a contract between the
> programmer and the compiler. It means that if the compiler sees a
> reference escape, then it stops the compilation.
> 
> >And no, a compiler _can't_ do pure optimizations on its own,
> >generally-speaking, because that would require looking not only at the
> >body of the function that's being called but at the function bodies of
> >any functions that it calls. D is not designed in a way that the compiler
> >even necessarily has _access_ to a function's body when compiling, and
> >you can't generally look at a function's body when doing optimizations
> >when calling that function. So, _some_ pure optimizations could be done,
> >but most couldn't. This is not the case with scoped classes, because
> >purity already gives you the information that you need.<
> 
> Quite often a function calls another function in thee same compilation
> unit, in this case the analysis is possible. So you limit the
> optimizations to this common but limited case.
> 
> And LDC compiler and in future GDC too, have link-time optimization, this
> means the compiler packs or sees the program code code in a single
> compilation unit. In this case it's able to perform a more complete
> analysis (including de-virtualization of some virtual functions).

It's trivial to get a reference or pointer to escape and make undetectable to 
the compiler. Some escape analysis can be and is done, but all it takes is 
passing a pointer or a reference to another function and the compiler can't 
determine it anymore unless it has access to the called functions body, and 
perhaps the bodies of functions that that function calls. And if the compiler 
can't be 100% correct with escape analysis, then any feature that requires it 
is 
not safe.

And as great as fancier optimizations such as link-time optimizations may be, 
the existence of dynamic libraries eliminates any and all guarantees that such 
optimizations would be able to make if they had all of the source to look at. 
So, you can't rely on them. They help, and they're great, but no feature can 
re

Re: Classes or stucts :: Newbie

2010-12-20 Thread Jonathan M Davis
On Monday, December 20, 2010 06:24:56 spir wrote:
> On Mon, 20 Dec 2010 03:11:49 -0800
> 
> Jonathan M Davis  wrote:
> > Now, you could conceivably have a language where all of its objects were
> > actually pointers, but they were treated as value types. So,
> > 
> > B b;
> > A a = b;
> > 
> > would actually be declaring
> > 
> > B* b;
> > A* a = b;
> > 
> > underneath the hood, except that the assignment would do a deep copy and
> > allocate the appropriate meemory rather than just copying the pointer
> > like would happen in a language like C++ or D. Perhaps that's what
> > Oberon does. I have no idea. I have never heard of the language before,
> > let alone used it.
> 
> I don't know how Oberon works. But I'm sure that its records are plain
> values, _not_ "pointed" under the hood. And their methods all are virtual
> (they have a virtual method table). I have no more details, sorry.

Well, given C's memory model - which D uses - you can't do that. Oberon could 
use a different memory model and have some other way of doing it, but it won't 
work for D, so you'll never see structs with polymorphic behavior in D.

- Jonthan M Davis


Re: string comparison

2010-12-20 Thread Steven Schveighoffer
On Mon, 20 Dec 2010 00:35:53 -0500, doubleagent   
wrote:


Compared to the relatively snappy response other threads have been  
receiving I'm

going to assume that nobody is interested in my inquiry.


Just a tip, don't expect snappy responses on Sunday...  We all have lives  
you know ;)  I for one usually have my computer that I do D stuff with off  
for most of the weekend.


-Steve


Re: Classes or stucts :: Newbie

2010-12-20 Thread Steven Schveighoffer
On Sun, 19 Dec 2010 17:38:17 -0500, Jonathan M Davis   
wrote:



On Sunday 19 December 2010 14:26:19 bearophile wrote:

Jonathan M Davis:
> There will be a library solution to do it, but again, it's unsafe.

It can be safer if the compiler gives some help. For me it's one of the
important unfinished parts of D.


Whereas, I would argue that it's completely unnecessary. structs and  
classes

serve different purposes. There is no need for scoped classes. They may
perodically be useful, but on the whole, they're completely unnecessary.

The compiler can help, but it can't fix the problem any more that it can
guarantee that a pointer to a local variable doesn't escape once you've  
passed
it to another function. In _some_ circumstances, it can catch escaping  
pointers

and references, but in the general case, it can't.

If we have library solutions for people who want to play with fire,  
that's fine.
But scoped classes is just not one of those things that the language  
really

needs. They complicate things unnecessarily for minimal benefit.


I don't mind having a solution as long as there is a solution.

The main need I see for scoped classes is for when you *know* as the  
programmer that the lifetime of a class or struct will not exceed the  
lifetime of a function, but you don't want to incur the penalty of  
allocating on the heap.  Mostly this is because the functions you want to  
call take classes or interfaces.


It's difficult to find an example with Phobos since there are not many  
classes.  But with Tango, scoped classes are used everywhere.


-Steve


Re: string comparison

2010-12-20 Thread doubleagent
> Are you 100% sure that you are running this version

I have to be.  There are no other versions of phobos on this box and 'which dmd'
points to the correct binary.

>  dictionary[word.idup] = newId;

That fixes it.

> The 'word' array is mutable and reused by byLine() on each iteration.  By
> doing the above you use an immutable copy of it as the key instead.

I REALLY don't understand this explanation.  Why does the mutability of 'word'
matter when the associative array 'dictionary' assigns keys by value...it's got 
to
assign them by value, right?  Otherwise we would only get one entry in
'dictionary' and the key would be constantly changing.

The behavior itself seems really unpredictable prior to testing, and really
unintended after testing.  I suspect it's due to some sort of a bug.  The 
program,
on my box anyway, only fails when we give it identical strings, except one is
prefixed with a space.  That should tell us that 'splitter' and 'strip' didn't 
do
their job properly.  The fly in the ointment is that when we output the strings,
they appear as we would expect.

I suspect D does string comparisons (when the 'in' keyword is used) based on 
some
kind of a hash, and that hash doesn't get correctly updated when 'strip' or
'splitter' is applied, or upon the next comparison or whatever.  Calling 'idup'
must force the hash to get recalculated.  Obviously, you guys would know if
there's any merit to this, but it seems to explain the problem.

> The advantage with splitter is that it is lazy and therefore more
> efficient.  split() is eager and allocates memory to hold the string
> fragments.

Yeah, that's what I thought would be the answer.  Kudos to you guys for thinking
of laziness out of the box.  This is a major boon for D.

You know, there's something this touches on which I was curious about.  If D
defaults to 'safety first', and with some work you can get down-to-the-metal, 
why
doesn't the language default to immutable variables, with an explicit modifier 
for
mutable ones?  C compatibility?


Re: string comparison

2010-12-20 Thread doubleagent
I understand.  Thank you, and thanks for pointing out the chatroom.


Re: string comparison

2010-12-20 Thread Steven Schveighoffer
On Mon, 20 Dec 2010 11:13:34 -0500, Stanislav Blinov   
wrote:


And lastly, hasn't this by chance been your first post? AFAIR, the first  
message is being moderated so it doesn't get to the public at once.


BTW, this message board is not moderated.

-Steve


Re: string comparison

2010-12-20 Thread Steven Schveighoffer
On Mon, 20 Dec 2010 14:05:56 -0500, Steven Schveighoffer  
 wrote:


On Mon, 20 Dec 2010 11:13:34 -0500, Stanislav Blinov   
wrote:


And lastly, hasn't this by chance been your first post? AFAIR, the  
first message is being moderated so it doesn't get to the public at  
once.


BTW, this message board is not moderated.


I should clarify, it's retroactively moderated :)  That is, if spam  
appears, it's allowed to go through, but then removed once discovered.


-Steve


Re: string comparison

2010-12-20 Thread doubleagent
> The reason that std.string.splitter() does not show in the documentation is 
> that
> its return type is auto, and there is currently a bug in ddoc that makes it so
> that auto functions don't end up in the generated documentation. Looking at 
> the
> code, it pretty much just forwards to std.algorithm.splitter() using 
> whitespace
> as its separator, so you can look at the documentation there if you'd like.

Thanks.  The code was pretty self-explanatory but it's helpful to know that auto
functions currently don't get documented.


Re: string comparison

2010-12-20 Thread Jonathan M Davis
On Monday, December 20, 2010 10:44:12 doubleagent wrote:
> > Are you 100% sure that you are running this version
> 
> I have to be.  There are no other versions of phobos on this box and 'which
> dmd' points to the correct binary.
> 
> >  dictionary[word.idup] = newId;
> 
> That fixes it.
> 
> > The 'word' array is mutable and reused by byLine() on each iteration.  By
> > doing the above you use an immutable copy of it as the key instead.
> 
> I REALLY don't understand this explanation.  Why does the mutability of
> 'word' matter when the associative array 'dictionary' assigns keys by
> value...it's got to assign them by value, right?  Otherwise we would only
> get one entry in 'dictionary' and the key would be constantly changing.

Okay. I don't know what the actual code looks like, but word is obviously a 
dynamic array, and if it's from byLine(), then that dynamic array is mutable - 
both the array itself and its elements. Using idup gets you an immutable copy. 
When copying dynamic arrays, you really get a slice of that array. So, you get 
an array that points to the same array as the original. Any changes to the 
elements in one affects the other. If you append to one of them and it doesn't 
have the space to resize in place or dyou o anything else which could cause it 
to reallocate, then that array is reallocated and they no longer point to the 
same data and changing will not change the other.

If the elements of the array are const or immutable, then the fact that the two 
arrays point to the same data isn't a problem because the elements can't be 
changed (except in cases where you'red dealing with const rather than immutable 
and another array points to the same data but doesn't have const elements). So, 
assigning one string to another, for instance (string being an alias for 
immutable(char)[]), will never result in one string altering another. However, 
if you're dealing with char[] rather than string, one array _can_ affect the 
elements of another. I believe that byLine() deals with a char[], not a string.

Now, as for associative arrays, they don't really deal with const correctly. I 
believe that they're actually implemented with void* and you can actually do 
things like put const elements in them in spite of the fact that toHash() on 
Object is not currently const (there is an open bug on the fact that Object is 
not const-correct). So, it does not surprise me in the least if it will take 
mutable types as its key and then allow them to be altered (assuming that 
they're pointers or reference types and you can therefore have other references 
to them). But to fix the problem in this case would require immutability rather 
than const, because you're dealing with a reference type (well, 
pseudo-reference 
type since dynamic arrays share their elements such that changes to their 
elements affect all arrays which point to those elements, but other changes - 
such as altering their length don't affect other arrays and will even likely 
result in the arrays then being completely separate).

> The behavior itself seems really unpredictable prior to testing, and really
> unintended after testing.  I suspect it's due to some sort of a bug.  The
> program, on my box anyway, only fails when we give it identical strings,
> except one is prefixed with a space.  That should tell us that 'splitter'
> and 'strip' didn't do their job properly.  The fly in the ointment is that
> when we output the strings, they appear as we would expect.
> 
> I suspect D does string comparisons (when the 'in' keyword is used) based
> on some kind of a hash, and that hash doesn't get correctly updated when
> 'strip' or 'splitter' is applied, or upon the next comparison or whatever.
>  Calling 'idup' must force the hash to get recalculated.  Obviously, you
> guys would know if there's any merit to this, but it seems to explain the
> problem.

in should use toHash() (or whatever built-in functions for built-in types if 
you're not dealing with a struct or class) followed by ==. I'd be stunned if 
there were any caching involved. The problem is that byLine() is using a 
mutable 
array, so the elements pointed to by the array that you just put in the 
associative array changed, which means that the hash for them is wrong, and == 
will fail when used to compare the array to what it was before.

> > The advantage with splitter is that it is lazy and therefore more
> > efficient.  split() is eager and allocates memory to hold the string
> > fragments.
> 
> Yeah, that's what I thought would be the answer.  Kudos to you guys for
> thinking of laziness out of the box.  This is a major boon for D.
> 
> You know, there's something this touches on which I was curious about.  If
> D defaults to 'safety first', and with some work you can get
> down-to-the-metal, why doesn't the language default to immutable
> variables, with an explicit modifier for mutable ones?  C compatibility?

C compatability would be one reason. Familiarity would 

Re: string comparison

2010-12-20 Thread Lars T. Kyllingstad
On Mon, 20 Dec 2010 18:44:12 +, doubleagent wrote:

>> Are you 100% sure that you are running this version
> 
> I have to be.  There are no other versions of phobos on this box and
> 'which dmd' points to the correct binary.
> 
>>  dictionary[word.idup] = newId;
> 
> That fixes it.
> 
>> The 'word' array is mutable and reused by byLine() on each iteration. 
>> By doing the above you use an immutable copy of it as the key instead.
> 
> I REALLY don't understand this explanation.  Why does the mutability of
> 'word' matter when the associative array 'dictionary' assigns keys by
> value...it's got to assign them by value, right?  Otherwise we would
> only get one entry in 'dictionary' and the key would be constantly
> changing.

This could be related to bug 2954, for which a fix will be released in 
the next version of DMD.

  http://d.puremagic.com/issues/show_bug.cgi?id=2954

-Lars


Re: string comparison

2010-12-20 Thread doubleagent
> Okay. I don't know what the actual code looks like

Here.

import std.stdio, std.string;

void main() {
uint[string] dictionary; // v[k], so string->uint
foreach (line; stdin.byLine()) {
// break sentence into words
// Add each word in the sentence to the vocabulary
foreach (word; splitter(strip(line))) {
if (word in dictionary) continue; // nothing to do
auto newId = dictionary.length;
dictionary[word] = newId;
writefln("%s\t%s", newId, word);
}
}
}

> ...

Okay, suppose you're right.  The behavior is still incorrect because the
associative array has allowed two identical keys...identical because the only
difference between two strings which I care about are the contents of their
character arrays.

> Also, it
> would be _really_ annoying to have to mark variables mutable all over the 
> place
> as you would inevitably have to do.

Obviously your other points are valid, but I haven't found this to be true
(Clojure is pure joy).  Maybe you're right because D is a systems language and
mutability needs to be preferred, however after only a day or two of exposure to
this language that assumption also appears to be wrong.  Take a look at Walter's
first attempted patch to bug 2954: 13 lines altered to explicitly include
immutable, and 4 altered to treat variables as const:
http://www.dsource.org/projects/dmd/changeset/749

But I'm willing to admit that my exposure is limited, and that particular 
example
is a little biased.


Re: string comparison

2010-12-20 Thread doubleagent
> This could be related to bug 2954, for which a fix will be released in
> the next version of DMD.

Looking at that new descriptive error message ie error("associative arrays can
only be assigned values with immutable keys, not %s", e2->type->toChars());  it
appears to be a distinct possibility.  Thanks.


Re: string comparison

2010-12-20 Thread Jonathan M Davis
On Monday, December 20, 2010 16:45:20 doubleagent wrote:
> > Okay. I don't know what the actual code looks like
> 
> Here.
> 
> import std.stdio, std.string;
> 
> void main() {
> uint[string] dictionary; // v[k], so string->uint
> foreach (line; stdin.byLine()) {
> // break sentence into words
> // Add each word in the sentence to the vocabulary
> foreach (word; splitter(strip(line))) {
> if (word in dictionary) continue; // nothing to do
> auto newId = dictionary.length;
> dictionary[word] = newId;
> writefln("%s\t%s", newId, word);
> }
> }
> }
> 
> > ...
> 
> Okay, suppose you're right.  The behavior is still incorrect because the
> associative array has allowed two identical keys...identical because the
> only difference between two strings which I care about are the contents of
> their character arrays.

Array comparison cares about the contents of the array. It may shortcut 
comparisons if lengths differ or if they point to the same point in memory and 
have the same length, but array comparison is all about comparing their 
elements.

In this case, you'd have two arrays/strings which point to the same point in 
memory but have different lengths. Because their lengths differ, they'd be 
deemed 
unequal. If you managed to try and put a string in the associative array which 
has the same length as one that you already inserted, then they'll be 
considered 
equal, since their lengths are identical and they point to same point in 
memory, 
so in that case, I would expect the original value to be replaced with the new 
one. But other than that, the keys will be considered unequal in spite of the 
fact that they point to the same place in memory.

The real problem here is that associative arrays currently allow non-immutable 
keys. Once that's fixed, then it won't be a problem anymore.

> > Also, it
> > would be _really_ annoying to have to mark variables mutable all over the
> > place as you would inevitably have to do.
> 
> Obviously your other points are valid, but I haven't found this to be true
> (Clojure is pure joy).  Maybe you're right because D is a systems language
> and mutability needs to be preferred, however after only a day or two of
> exposure to this language that assumption also appears to be wrong.  Take
> a look at Walter's first attempted patch to bug 2954: 13 lines altered to
> explicitly include immutable, and 4 altered to treat variables as const:
> http://www.dsource.org/projects/dmd/changeset/749
> 
> But I'm willing to admit that my exposure is limited, and that particular
> example is a little biased.

Most programmers don't use const even in languages that have it. And with many 
programmers programming primarily in languages like Java or C# which don't 
really have const (IIRC, C# has more of a const than Java, but it's still 
pretty 
limited), many, many programmers never use const and see no value in it. So, 
for 
most programmers, mutable variables will be the norm, and they'll likely only 
use const or immutable if they have to. There are plenty of C++ programmers who 
will seek to use const (and possibly immutable) heavily, but they're definitely 
not the norm. And, of course, there are plenty of other languages out there 
with 
const or immutable types of one sort or another (particularly most functional 
languages), but those aren't the types of languages that most programmers use. 
The result is that most beginning D programmers will be looking for mutable to 
be the norm, and forcing const and/or immutable on them could be seriously off-
putting.

Now, most code which is going to actually use const and immutable is likely to 
be a fair mix of mutable, const, and immutable - especially if you don't try to 
make everything immutable at the cost of efficiency like you'd typically get in 
a 
functional language. That being the case, regardless of whether mutable, const, 
or immutable is the default, you're going to have to mark a fair number of 
variables as something other than the default. So, making const or immutable 
the 
default would likely not save any typing, and it would annoy a _lot_ of 
programmers.

So, the overall gain of making const or immutable the default is pretty minimal 
if not outright negative.

Personally, I use const and immutable a lot, but I still  wouldn't want const 
or 
immutable to be the default.

- Jonathan M Davis


Re: enum ubyte[] vs enum ubyte[3]

2010-12-20 Thread Nick Voronin
On Mon, 20 Dec 2010 17:17:05 +0100
"Johannes Pfau"  wrote:

> > But if you are going to patch it, please make it add extra {} around  
> > action code! The thing is that when there is a label before {} block  
> > (and in ragel generated code I saw it's always so) the block isn't  
> > considered as a new scope which causes problems when you have local  
> > variables declaration inside actions.
> 
> You mean like this code:
> -
> tr15:
> #line 228 "jpf/http/parser.rl"
>  {
>  if(start != p)
>  {
>  key = line[(start - line.ptr) .. (p - line.ptr)];
>  }
>  }
> -
> should become: ?
> -
> tr15:
> #line 228 "jpf/http/parser.rl"
>  {{
>  if(start != p)
>  {
>  key = line[(start - line.ptr) .. (p - line.ptr)];
>  }
>  }}
> -

Yes. This way it becomes a scope which is kind of what one would expect from it.

 
> > One is fixed size array and other is dynamic. Honestly I doubt that it  
> > matters for code generated by Ragel, since this is constant and won't be  
> > passed around. If it's harder to make it fixed-size then don't bother.
> >
> Could a dynamic array cause heap allocations, even if it's data is never  
> changed? If not, dynamic arrays would work fine.

Sorry, I can't provide reliable information on what can happen in general, but 
right now there is no difference in produced code accessing elements of enum 
ubyte[] and enum ubyte[30]. In both cases constants are directly embedded in 
code. 

In fact as long as you only access its elements (no passing array as an 
argument, no assignment to another variable and no accessing .ptr) there is no 
array object at all. If you do -- new object is created every time you do. I 
believe Ragel doesn't generate code which passes tables around, so it doesn't 
matter. 

-- 
Nick Voronin 


Re: Classes or stucts :: Newbie

2010-12-20 Thread Nick Voronin
On Mon, 20 Dec 2010 05:43:08 -0500
bearophile  wrote:

> Nick Voronin:
> 
> > Here is where we diverge. Choosing struct vs class on criteria of their 
> > placement makes no sense to me. 
> 
> In D you use a class if you want inheritance or when you (often) need 
> reference semantics, and you use a struct when you need a little value passed 
> around by value or when you want a simple form of RAII or when you want to 
> implement something manually (like using PIMPL), or when you want max 
> performance (and you manage structs by pointer, you may even put a tag inside 
> the stuct or the pointer and implement manually some kind of inheritance). 
> With structs you have a literal syntax, postblits, in-place allocation, and 
> you are free to use align() too.

Well said. Plenty of differences there more important than stack/heap 
allocation.

-- 
Nick Voronin 


Re: string comparison

2010-12-20 Thread doubleagent
Good & I agree.


is expression for template structs/classes instances?

2010-12-20 Thread d coder
Greetings

I want to find if a given struct type is instantiated from a
particular template struct type. For example:

struct S (T)  {
  alias T Type;
  T t;
}

And later I want to find out if a given type is of type S(*)
(basically any type instantiated from template struct S). In fact I do
not know the type value T used at the time of instantiating S!(T).

I was looking at "is ( Type Identifier : TypeSpecialization ,
TemplateParameterList )" expression at
http://www.digitalmars.com/d/2.0/expression.html#IsExpression .
Thought there would be some way using that, but I could not find any.

Regards
Cherry


Re: is expression for template structs/classes instances?

2010-12-20 Thread Jonathan M Davis
On Monday 20 December 2010 20:23:49 d coder wrote:
> Greetings
> 
> I want to find if a given struct type is instantiated from a
> particular template struct type. For example:
> 
> struct S (T)  {
>   alias T Type;
>   T t;
> }
> 
> And later I want to find out if a given type is of type S(*)
> (basically any type instantiated from template struct S). In fact I do
> not know the type value T used at the time of instantiating S!(T).
> 
> I was looking at "is ( Type Identifier : TypeSpecialization ,
> TemplateParameterList )" expression at
> http://www.digitalmars.com/d/2.0/expression.html#IsExpression .
> Thought there would be some way using that, but I could not find any.
> 
> Regards
> Cherry

Well, from the compiler's perspective S!int would have no relation to S!float, 
S!bool, or any other S!T. The template is instantiated with whatever types and 
values that it's given and then it's its own beast. So, really, there is no 
relation between the various instantiations of any particular template. I'm not 
sure that it would be impossible to have something in __traits or std.traits 
which tested whether a particular type was an instantiation of a particular 
template, but I'm not at all certain that it _is_ possible. Templates are used 
to generate code, but once generated, that code is essentially the same as it 
would have been had you typed it all yourself. So, my guess would be that you 
can't do what you're trying to do. I agree that it could be useful to be able 
to 
do it, but unfortunately, I don't think that it's possible.

If you knew enough about the type, you might be able to do some template voodoo 
to do it in a round-about manner, but it would be specific to the type in 
question. For instance, given your definiton of S, you could use 
_traits/std.traits to check that the type that you're testing has a member 
variable t. You could then check that S!(typeof(t)) was the same as the type 
that you were testing. So, if you get particularly cunning about it, I believe 
that it can be tested for in specific cases, but I don't believe that it can be 
done in any general way.

- Jonathan M Davis


Re: is expression for template structs/classes instances?

2010-12-20 Thread d coder
> For instance, given your definiton of S, you could use
> _traits/std.traits to check that the type that you're testing has a member
> variable t. You could then check that S!(typeof(t)) was the same as the type
> that you were testing. So, if you get particularly cunning about it, I believe
> that it can be tested for in specific cases, but I don't believe that it can 
> be
> done in any general way.
>

Thanks Jonathan

That is exactly what I had thought of doing. I was conscious that it
may not be the cleanest way.
Now that you are saying a cleaner way may not exist, I will go ahead
and write the code.

Regards
- Cherry