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

2010-12-20 Thread Nick Voronin
On Mon, 20 Dec 2010 10:26:16 +0100
Johannes Pfau s...@example.com 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 elfy...@gmail.com


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

2010-12-20 Thread Nick Voronin
On Mon, 20 Dec 2010 17:17:05 +0100
Johannes Pfau s...@example.com 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 elfy...@gmail.com


Re: Classes or stucts :: Newbie

2010-12-20 Thread Nick Voronin
On Mon, 20 Dec 2010 05:43:08 -0500
bearophile bearophileh...@lycos.com 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 elfy...@gmail.com


Re: sleepy receiveTimeout?

2010-12-19 Thread Nick Voronin
On Sat, 18 Dec 2010 23:19:47 +0100
Joost 't Hart joost.t.h...@planet.nl wrote:

 Quoting the documentation:
 
 /Suspends the calling thread for at least the supplied period./
 
 What does at least mean here? Is there also an at most? I do not 
 want my friend to end up in cyberspace. :-)

Nope, there isn't :) In ordinary multitasking environment there is no guarantee 
on upper bound.

-- 
Nick Voronin elfy...@gmail.com


Re: sleepy receiveTimeout?

2010-12-19 Thread Nick Voronin
On Sun, 19 Dec 2010 10:50:08 +0100
Joost 't Hart joost.t.h...@planet.nl wrote:

  Quoting the documentation:
 
  /Suspends the calling thread for at least the supplied period./
 
  What does at least mean here? Is there also an at most? I do not
  want my friend to end up in cyberspace. :-)
 
  Nope, there isn't :) In ordinary multitasking environment there is no 
  guarantee on upper bound.
 
 
 Surely got that bit, but I guess it makes sense to refer a bit more to 
 some good old thread state names: After (exactly!) the given period of 
 suspension the thread returns into ready state.
 When (if ever) it will become the running thread again depends ...

This all nice in theory, but are you sure that every sleep() causes setting of 
hardware timer? In every OS? In every minor version of OS even? If not (and I'm 
pretty sure it's not so), then you need to add more details. All about how 
scheduler works. Or this precise talk on what happen after time is up would 
just mislead people. Aside from the fact that sometime after time is up thread 
would become runnable again (which is really obvious, no?) there is nothing to 
say.

-- 
Nick Voronin elfy...@gmail.com


Re: Classes or stucts :: Newbie

2010-12-19 Thread Nick Voronin
On Mon, 20 Dec 2010 07:00:31 -0800
David Currie curri...@iinet.net.au wrote:

 Can a class be instantiated on the stack ?

Yes, check std.conv.emplace 
http://www.digitalmars.com/d/2.0/phobos/std_conv.html#emplace and alloca()
I don't know details about interaction of such objects with GC though.

Also there is scarcely documented storage class scope, which for class objects 
means that they will be destroyed upon scope exit, but also currently results 
in that object itself will be placed on the stack, no memory in heap is 
allocated.

C myC(3);  // C++ syntax BUT is there a d equivalent
 It appears that D ASSUMES myC is really a myC*(in C++)

Not exactly. All class objects have reference semantic, so when you declare 
variable of type C you really declare a reference. The reference is what you 
get from new, pass as parameters, etc.

 Will a struct do?

structs on the contrary have value semantic, so when you declare struct 
variable you get the memory for struct allocated on stack or in data segment. 
When you pass or return structs -- you return or pass value, that is a copy of 
data.

You may be also interested in the way dynamic arrays are handled, as arrays are 
value type, yet they hold a pointer to memory. This means that passing them as 
parameter or returning them does copy pointer and length, but actual data is 
stil shared until you do something which will force D to relocate it. All kind 
of not obvious implications here.

 Does a struct have a constructor (as opposed to an opcall?)

Yes, and more. http://www.digitalmars.com/d/2.0/struct.html

-- 
Nick Voronin elfy...@gmail.com


Re: Classes or stucts :: Newbie

2010-12-19 Thread Nick Voronin
On Sun, 19 Dec 2010 14:38:17 -0800
Jonathan M Davis jmdavisp...@gmx.com 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.

How do you define a need for scoped classes? 

I see two aspects there: first is having destructor called at known point 
rather than arbitrarily, second is performance.

It looks perfectly reasonable for me to want to have first. Do you know why 
things which makes program act more deterministic are shunned from D? Does it 
really add so much to safety that it is worth reducing programmer's control?

Second is irrelevant to types, if I want to speed up some code and can do it by 
placing things on stack rather than in heap -- what does it matter if it is 
class or struct or integer? We have alloca() anyway, so removing modifier won't 
save me from myself, just push me to more C-like code. Which kind of defeats 
the purpose of using D.

 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.

Absolutely. 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 _some_ circumstances, it can catch escaping pointers 
 and references, but in the general case, it can't.

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.

-- 
Nick Voronin elfy...@gmail.com


Re: rdmd bug?

2010-12-19 Thread Nick Voronin
On Mon, 20 Dec 2010 01:24:02 +0100
CrypticMetaphor crypticmetapho...@gmail.com 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:
 ...\projectfolderrdmd 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.


-- 
Nick Voronin elfy...@gmail.com


Re: Classes or stucts :: Newbie

2010-12-19 Thread Nick Voronin
On Sun, 19 Dec 2010 17:26:20 -0800
Jonathan M Davis jmdavisp...@gmx.com wrote:

 On Sunday 19 December 2010 16:50:34 Nick Voronin wrote:
  On Sun, 19 Dec 2010 14:38:17 -0800
  
  Jonathan M Davis jmdavisp...@gmx.com 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.
  
  How do you define a need for scoped classes?
  
  I see two aspects there: first is having destructor called at known point
  rather than arbitrarily, second is performance.
  
  It looks perfectly reasonable for me to want to have first. Do you know why
  things which makes program act more deterministic are shunned from D? Does
  it really add so much to safety that it is worth reducing programmer's
  control?
 
 Then use a struct.

Here is where we diverge. Choosing struct vs class on criteria of their 
placement makes no sense to me. Difference in default placement hardly matters 
at all, you can perfectly put structs in heap or in static segment yet still 
maintain same properties. It's those properties which matter when I choose one 
or another, not where it will reside in particular part of program.

 That's one of the reasons that they exist. And if you 
 _really_ want to make sure that a class' destructor gets run, you can always 
 use 
 clear() (which is arguably an abomination in its own right).

This is what I don't understand. Fine. structs are meant for stack, class for 
heap. Conceptually, anyway. Still there will be ways to put class on stack and 
struct in heap. And there is(will be) clear(). Now I do see benefit of scope 
storage. It looks clean, it is supported by compiler meaning reasonable level 
of protection against misuse, it is extremely effective. What are benefits of 
_not having_ it?

-- 
Nick Voronin elfy...@gmail.com


Re: helpful runtime error messages

2010-12-15 Thread Nick Voronin

On Wed, 15 Dec 2010 13:28:56 +0300, spir denis.s...@gmail.com wrote:

s...@o:~/prog/d$ dmd -ofprog -w -debug -unittest -L--export-dynamic  
prog.d

s...@o:~/prog/d$ ./prog
core.exception.rangeer...@prog(20): Range violation

./prog(_d_array_bounds+0x16) [0x807cad6]
./prog(_D4prog7__arrayZ+0x12) [0x807a54a]
./prog(_Dmain+0x38) [0x807a524]
./prog(extern (C) int rt.dmain2.main(int, char**)) [0x807cc76]
./prog(extern (C) int rt.dmain2.main(int, char**)) [0x807cbd0]
./prog(extern (C) int rt.dmain2.main(int, char**)) [0x807ccba]
./prog(extern (C) int rt.dmain2.main(int, char**)) [0x807cbd0]
./prog(main+0x96) [0x807cb76]
/lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe6) [0x1ddbd6]
./prog() [0x807a401]

Do you have (even) nicer error reports on some OS's or using some  
switches?


Trass3r pointed this http://3d.benjamin-thaut.de/?p=15 recently. It prints  
line numbers on windows. It doesn't go as deep as stacktrace above though.  
Just


core.exception.rangeer...@strace2(5): Range violation

00 strace2.d::5(16) _Dmain
01 extern (C) int rt.dmain2.main(int, char**) . void runMain() .
02 extern (C) int rt.dmain2.main(int, char**) . void runAll() .
03 main
04 mainCRTStartup
05 RegisterWaitForInputIdle




--
Using Opera's revolutionary email client: http://www.opera.com/mail/


Re: rdmd executable location

2010-12-15 Thread Nick Voronin

try -of option.

On Wed, 15 Dec 2010 21:59:32 +0300, CrypticMetaphor  
crypticmetapho...@gmail.com wrote:


Hello, I'm having a bit of trouble with rdmd. rdmd puts the executable  
in a temp folder, even with the --build-only option. Maybe this is a  
silly question but, how can I compile with rdmd so I get the executable  
in the folder I am  currently at?


other info: I'm programming in Windows XP with dmd version 2.50



--
Using Opera's revolutionary email client: http://www.opera.com/mail/



Re: funny bug with input range interface and toString

2010-12-13 Thread Nick Voronin

On Mon, 13 Dec 2010 11:24:48 +0300, spir denis.s...@gmail.com wrote:

I have a strange bug with an input range interface. Initially, I had a  
(rather big) struct called Text with loads of working unittests. When  
adding a range interface, noting worked anymore, any test ran into an  
infinite loop (the terminal writes pages of '[') ending with segfault.


@property Text front () {
return Text(this.stacks[this.rangeIndex]);
}

Um. There is recursion. front() of Text returns Text. formatValue iterates  
through Range, trying to format every element of it... but goes nowhere  
because Range.front never yields anything but itself typewise.


After shrinking the bug's scope,I finally found it happens on simple  
writeln(text).


Not so simple, with all underlying mess of templates :-D I suppose it's a  
bug that instantiation of formatValue for Range types there always tries  
to iterate manually, ignoring existing toString.


void formatValue(Writer, T, Char)(Writer w, T val,
ref FormatSpec!Char f)
if ( ( is(T == struct) || is(T == union) )  !isInputRange!T)

As you can see it even explicitly mention that default formatting for  
struct (which can use toString) not to be used for Ranges. I think it's  
wrong.


https://bitbucket.org/denispir/denispir-d/changeset/39200b499fb9#chg-textbug.d.  
Note that the range interface itself works fine.


btw, I wonder, how do you build it? I ended up with very long command line  
for dmd, as there was no makefile and jake/rdmd failed to produce anything  
ether.


So, it seems that, in my case for any reason, introducing an input range  
lets D shortcut toString (and try to use what instead?). Look like a bug?


Yup! Still, stack overflow is due to unconventional Range interface.

--
Using Opera's revolutionary email client: http://www.opera.com/mail/


Re: funny bug with input range interface and toString

2010-12-13 Thread Nick Voronin

On Mon, 13 Dec 2010 21:43:33 +0300, spir denis.s...@gmail.com wrote:


I use rdmd for quick testing (because it links automagically).
compile: dmd -w -c filename.d
build: rdmd -w -offilename -debug -unittest --build-only filename.d


Thanks. I missed -of option.

--
Using Opera's revolutionary email client: http://www.opera.com/mail/


overzealous pointsTo()

2010-12-12 Thread Nick Voronin


pointsTo() tries to check every member of anonymous union inside struct.

import std.exception;

union U
{
int i;
string s;
}

struct S1
{
int type;
U u;
}
struct S2
{
int type;
union {
int i;
string s;
}
}

void main()
{
S1 s1;
s1.u.i = 0x7FFF_;
S2 s2;
s2.i = 0x7FFF_;
assert(!pointsTo(s1, s1)); // pass, pointsTo does not look into union
	assert(!pointsTo(s2, s2)); // fails because pointsTo tries to check every  
member of anonymous union

}

IMHO it should ignore unions, anonymous or not, checking every member of  
them just doesn't make sense.


--
Using Opera's revolutionary email client: http://www.opera.com/mail/


Re: overzealous pointsTo()

2010-12-12 Thread Nick Voronin

On Sun, 12 Dec 2010 22:36:03 +0300, Nick Voronin elfy...@gmail.com wrote:



pointsTo() tries to check every member of anonymous union inside struct.


alias this makes a passable workaround though. (I hope) :)


union U
{
int i;
string s;
}

struct S3
{
int type;
U u;
alias u this;
}

void main()
{
S3 s3;
s3.i = 0x7FFF_;
assert(!pointsTo(s3, s3)); // pass
}


--
Using Opera's revolutionary email client: http://www.opera.com/mail/


Re: effect of a label on following block

2010-11-16 Thread Nick Voronin
On Mon, 15 Nov 2010 19:34:46 +0300, Ellery Newcomer  
ellery-newco...@utulsa.edu wrote:


My gut feeling is that the if statement's behavior is wrong and the  
while statement's is correct, but it could go either way.


I agree, I think case with 'when' works as specs say.

No need for a rationale for what can be adequately explained as a  
compiler bug


There is still correct but unexpected behaviour. I found this on bugtracker
http://d.puremagic.com/issues/show_bug.cgi?id=199
The rationale was I don't want to change this because it could break  
existing code,

and there doesn't seem to be a compelling reason to do so. Well. :(


Please to report to bugzilla


I'll report about if/while inconsistency.

--
Using Opera's revolutionary email client: http://www.opera.com/mail/


effect of a label on following block

2010-11-15 Thread Nick Voronin

Hello.

Consider this code

void main()
{
l:
  {
int v;
  }
  v = 5; // ok, v is defined
}

As I understand from D's grammar this behaviour is not a bug as

LabeledStatement:
Identifier : NoScopeStatement

and NoScopeStatement in turn takes BlockStatement without creating new  
scope.


It looks very unnatural for me though. Especially when label goes before  
ThenStatement


if(1)
l1:{
  int v;
}
v = 5;

it works as above, yet label after 'while'

while(1)
l1:{
  int v;
}
v = 5; // error, v is undefined

has no such effect, even if ThenStatement is just another ScopeStatement.  
I don't understand this difference. Any rationale behind this?


--
Using Opera's revolutionary email client: http://www.opera.com/mail/


readf

2010-11-02 Thread Nick Voronin
Hello.

I'm new to D and I stumbled upon something strange about readf while writing 
some test code.

The code:

import std.stream;
import std.stdio;

int main(char[][] args)
{
string input = 2abc;
auto memstream = new TArrayStream!(string)(input);
int x;
memstream.readf(%d, x);
char[] s = memstream.readString(x);
writefln(%d:%s, x, s); // expected 2:ab, writes 2:bc.
return 0;
}

After looking in stream.d I can understand why it is working in unexpected way 
(readf uses ungetc() which has no effect on readString() ), but is it intended 
behavior? I see in documentation that ungetc() affects only what is read 
afterwards with getc(), but no mention that readf() is incompatible with other 
reading methods.

It wouldn't even be the problem if I knew for sure that there is always 
_exactly_ one char offset, or that return value of readf must be number of 
bytes read from stream. Is it so or is it all just the way it happened to be in 
current implementation?

On another topic. Compiled with D 2.050 it won't work at all, printing 
object.Error: Access Violation. Apparently readf in 2.0 requires mutable 
string as a format string. Writing it like this

memstream.readf(%d.dup, x);

works. Is it intended too?

On yet another topic :) Is there alternative to stream.readf? Somehow while 
searching for explanation of unexpected behavior I got the idea that readf and 
streams considered to be second-class citizens in world of D and they are not a 
proper way to do things, so no one really cares about them... Therefore the 
question. What do I use to read numbers from file?