Re: odd use of preprocessor

2011-11-06 Thread Michel Fortin
On 2011-11-06 19:43:15 +, Ellery Newcomer 
 said:



/* Error values.  */
enum
  {
DW_TAG_invalid = 0
#define DW_TAG_invalid  DW_TAG_invalid
  };


It's strange all right. The only reason I can come with is that they 
want to prevent someone else from defining DW_TAG_invalid as a 
preprocessor value that would shadow the enum value.


Just ignore it, D has no preprocessor. :-)

--
Michel Fortin
michel.for...@michelf.com
http://michelf.com/



Re: Segmentation fault on closing file in destructor

2010-09-26 Thread Michel Fortin

On 2010-09-26 10:06:33 -0400, "Simen kjaeraas"  said:


Tom Kazimiers <2voo...@gmx.de> wrote:


Hi,

a file reading class of mine can be constructed with a filename as
parameter. It instantiates a new std.stream.File (without the passed
file name and closes it when opened within the destructor. The last part
is where things are getting unclear for me. On the "file.isOpen()" call
in the destructor a segmentation fault occurs. What is the problem with
that?


Likely, it is this[1]:

"[T]he order in which the garbage collector calls destructors for
unreference objects is not specified. This means that when the garbage
collector calls a destructor for an object of a class that has members
that are references to garbage collected objects, those references may
no longer be valid. This means that destructors cannot reference sub
objects."

[1]: http://digitalmars.com/d/2.0/class.html#destructors


That's it indeed, but I'll add that it's the File struct that is at 
fault. See this bug:

<http://d.puremagic.com/issues/show_bug.cgi?id=4624>

To make it short: when the File struct is located somewhere in the GC 
heap (like inside a class), File's destructor is buggy when a file is 
open. The only workaround I can think of is to call close() or detach() 
on the file struct before the garbage collectors kicks in (doing it in 
the destructor of your class is already too late, it must be done 
before the destructor gets called).


In fact, it's generally a good idea to not wait for the GC to collect 
your objects before closing files, because waiting for the GC could 
take an indeterminate amount of time and leave files open for a long 
time (the GC only runs when needed).



--
Michel Fortin
michel.for...@michelf.com
http://michelf.com/



Re: Linking D and Obj-C code into a Cocoa app proper? (Mac)

2010-10-05 Thread Michel Fortin

On 2010-10-05 10:02:45 -0400, Heywood Floyd  said:

But, sometimes I get reeeaally weird bugs. I had one bug where if I 
added an empty function to a class in D I got EXC_BAD_ACCES (segfault). 
An empty function! Ie "void f(){}". Remove the function--it works. In 
the debugger, I got the impression maybe the stack has got messed up, 
but I don't know, the debugger just shows assembler code, and I don't 
have the proper skills.


It's hard to say without further details, but it could be that you're 
not recompiling everything that uses the class where you add a 
function. Unlike in Objective-C, adding a function to a D class breaks 
most compiled code that uses that class (because you're adding an 
offset to the virtual function table), so you need to recompile every D 
module that uses that class (or a derived class).


Note that this is totally unrelated to having Objective-C code in the 
same program.



This got really frustrating, needless to say, so I started playing 
around with the build settings. I switched from using LLVM 1.5 (for the 
obj-c code) to gcc 4.2. And now it magically seems to work!


Are you using D for Xcode? By doing that you basically force everything 
to be recompiled, which solves problem described above.




[...]

== Question ==
How do you make D code and Obj-C code coexist? That is, I want to write 
a Cocoa-app that is mostly written in D, and with a little "glue"-code 
in Objective-C. How do you set that up? Is it even supposed to be 
possible?


It is totally possible, and not that hard. Communicating via `extern 
(C)` functions should work well.



(And what could the bug above be? I know LLVM does link-time 
optimizations, and even run-time optimizations. Could it be that it 
messes things up?)


I doubt LLVM optimizations have anything to do with your problem. 
Things to keep in mind when mixing Objective-C:


1. Apple's Objective-C GC isn't supported by D, so you it's probably 
safer to use manual memory management (retain/release) on the 
Objective-C site.


2. Exceptions are not compatible between the two runtimes. Throwing can 
cause unexpected results when it unwinds stack frames in the other 
language.



--
Michel Fortin
michel.for...@michelf.com
http://michelf.com/



Re: Operator precedence of "new"

2010-10-15 Thread Michel Fortin

On 2010-10-15 08:12:24 -0400, bearophile  said:


Currently to call a method to a newly build object/struct you need:

(new Foo).bar();

But isn't it better to change the D operator precedence rules a bit and 
allow new to bind more closely than the method call, to allow a syntax 
like:


new Foo.bar();

Do you see bad side effects in this D2 change?


But then, how does that work?

new Foo.SubType.bar();

Could work like this:

new (Foo.Subtype).bar();

which doesn't look too bad as long as .bar() is at the end. Remove it 
and you'll get this:


new (Foo.Subtype);

Hardly interesting, and somewhat counter-intuitive. That's especially 
bad considering that all types are in reality enclosed module name 
which can be made explicit:


new (std.stdio.File);

I much prefer that this works:

new std.stdio.File;
new Foo.Subtype;

Even if it means I have to do:

(new Foo).bar();

--
Michel Fortin
michel.for...@michelf.com
http://michelf.com/



Re: common types + type modifiers

2011-01-30 Thread Michel Fortin
On 2011-01-29 20:09:11 -0500, Ellery Newcomer 
 said:


trying to wrap my head around shared,const,immutable (not inout yet, 
though someday I'll need to figure out what it's supposed to do)


Currently, dmd doesn't exhibit a lot of consistency wrt the above, so 
bear with me as I question every ing thing it does.


my [erroneous?] understanding of the modifiers:
shared - many threads can see
lack of shared - one thread can see plus some difference or other in 
physical layout (of which I am mostly ignorant)

immutable - nobody can mutate
lack of immutable - anybody can mutate
const - either immutable or mutable - you can't mutate because you 
don't know which, but you also can't rely on it not mutating


shared(immutable(T)) == immutable(T) because who care who can see it if 
nobody can mutate it


otherwise, shared(T) != T where T is not shared or immutable because T 
might be mutable and then it matters who can see it and when



What is the common type of two types with the same base T but different 
modifiers?


My [erroneous?] [generic] reasoning:
(notation - i under T1 means T1 == immutable(T), etc)
T1   :T2  ->   ResultT
i  c  cfollows from my defs above
i  m  cditto
c  m  cditto

I think this is what dmd does. seems obvious.


Everything is correct up to here.



what about shared?

shared(U) : U -> ?? where U is not shared or immutable

the result is some sort of a 'maybe shared' - it definitely can't be U. 
Can it be shared(U) ? I'm not sure about the semantics of tls, but it 
seems like that would violate U's contract that only one thread can see 
[and mutate] it.  So it seems to me that there is no common type of 
shared(U) and U.


Indeed, U and shared(U) have no common type.



unless it's acceptable to just make the mutability const. which would give:

csm   cs
csc   cs
msm   cs
msc   cs


No, that doesn't work. There is no common type between shared and non-shared.


otherwise, its a shared/shared or immutable/shared pair, so the result 
type is shared, and the mutability is the same as for 
unshared/unshared. which, come to think of it, will always be const. So 
the result type will be const shared(T)


So that's my generic reasoning, which doesn't take the semantics of 
subtypes, ease of use, etc, into account. here are some cases which I 
suspect are wrong:


const(int)  :  int  ->  int
const(int)  :  shared(int)  ->  int

and

shared(const(int*))  :  const(int*)  ->  const(int)*

1) why can we do away with the constness of the pointer?
2) I think we should not do away with the sharedness of the pointer, 
let alone of the element (shared is transitive too, isn't it?  it has 
to be..)


About the constness of the pointer, you should only be able to do this 
when you make a copy of the pointer, as in:


const(int*) a;
const(int)* b = a;

There is no const violation here because pointer 'b' is a new variable, 
distinct of 'a'. The data it points to however is the same, so the 
'int' must stay const.


That said, shared(const(int*)) and const(int*) do not have a common 
type since one is shared and the other is not.


--
Michel Fortin
michel.for...@michelf.com
http://michelf.com/



Re: common types + type modifiers

2011-01-30 Thread Michel Fortin
On 2011-01-30 13:23:16 -0500, Ellery Newcomer 
 said:


Ah, thank you. That clears things up a bit. how do you safely convert 
from a shared type to a non shared type or vice versa? a deep copy 
inside a critical section?


A copy? Yes. A critical section? Not really.

Shared is about atomic operations, things that the processor can do 
atomically without locking. They're used mostly to provide sequential 
consistency in our multi-core world where multiple cores can see a 
different value for the same memory address at one given time due to 
out-of-sync caches. Atomic ops forces the caches to synchronize but are 
slower.


You can't mix atomic operations with OS-level locking because they 
don't respect each other (a lock won't prevent an atomic read from 
occurring). Also, atomic ops are generally limited to word-sized data 
structures, sometime double-word. So on a 32-bit processor that's a 
32-bit or 64-bit value (assuming the value is properly aligned).


If you want to use locking (a critical section in Windows parlance), 
you should put your data in a synchronized class, then share that class 
with other threads. If you don't use locking, you have at best 
double-word granularity.



--
Michel Fortin
michel.for...@michelf.com
http://michelf.com/



Re: std.concurrency & immutable classes...

2011-02-06 Thread Michel Fortin

On 2011-02-06 16:55:36 -0500, Tomek Sowiński  said:


... doesn't work.

class C {}
thisTid.send(new immutable(C)());
receive((immutable C) { writeln("got it!"); });

This throws: 
core.exception.AssertError@/usr/include/d/dmd/phobos/std/variant.d(285): 
immutable(C)


And when I go for Rebindable, I get "Aliases to mutable thread-local 
data not allowed.".


Is there anything I can do?

Overall, I think that's another reason D needs native tail const badly. 
Polymorphic classes are close to being second class citizens just as 
soon const enters. :(


I just made this pull request today:
<https://github.com/D-Programming-Language/dmd/pull/>

If you want to test it, you're very welcome. Here is my development 
branch for this feature:

<https://github.com/michelf/dmd/tree/const-object-ref>

--
Michel Fortin
michel.for...@michelf.com
http://michelf.com/



Re: std.concurrency & immutable classes...

2011-02-06 Thread Michel Fortin

On 2011-02-06 20:09:56 -0500, Michel Fortin  said:


I just made this pull request today:
<https://github.com/D-Programming-Language/dmd/pull/>


That should have been:
<https://github.com/D-Programming-Language/dmd/pull/3>

--
Michel Fortin
michel.for...@michelf.com
http://michelf.com/



Re: std.concurrency & immutable classes...

2011-02-07 Thread Michel Fortin

On 2011-02-07 17:11:08 -0500, Tomek Sowiński  said:


Michel Fortin napisał:


I just made this pull request today:
<https://github.com/D-Programming-Language/dmd/pull/>

If you want to test it, you're very welcome. Here is my development
branch for this feature:
<https://github.com/michelf/dmd/tree/const-object-ref>


Thanks for doing this. Is it approved by Walter?


Depends on what you mean by "approved".

He commented once on the newsgroup after I posted an earlier version of 
the patch, saying I should add tests for type deduction and some other 
stuff. This change his something he attempted to do in the past and 
failed, I expect him to be skeptical. I guess he'll review it when he 
has the time and I hope he'll merge these changes in the mainline. 
He'll probably want to take his time however, since it can break 
existing code in some cases; it's basically a change to the language.


If you want to show your support, I guess you can vote up the 
enhancement request in the bugzilla.

<http://d.puremagic.com/issues/show_bug.cgi?id=5325>

Also feel free to compile it, test it, and share your experience. The 
more tested it is, the more used and appreciated it is, the more 
exposure it gets, the sooner it gets approved, or so I guess.


--
Michel Fortin
michel.for...@michelf.com
http://michelf.com/



Re: std.concurrency & immutable classes...

2011-02-11 Thread Michel Fortin

On 2011-02-10 14:45:14 -0500, Tomek Sowiński  said:


Michel Fortin napisał:


Thanks for doing this. Is it approved by Walter?


Depends on what you mean by "approved".

He commented once on the newsgroup after I posted an earlier version of
the patch, saying I should add tests for type deduction and some other
stuff. This change his something he attempted to do in the past and
failed, I expect him to be skeptical.


It would be much easier if he provided the specific case(s) which broke 
his teeth. Then we'll all know where's the problem.


I don't think he had much time to look at the patch. His last remark 
were more of like "I'm skeptical it can work, please make sure you have 
tests to cover those specific cases..." followed with a list of things 
to test. I'll surely get some feedback on my patch someday, hopefully 
right after the next release (which should be imminent now).


The architecture of the DMD front end makes it very difficult to 
approach the tail-const problem for classes the same way it works for 
pointers. If this is what Walter tried, I have no difficulty 
understanding why it didn't go very far. My approach was to make the 
optional 'ref' a modifier that changes the attributes of a new head 
type attached to classes. This may look a little of a hack, but it 
works.




If it's soluble, it'll ope
n the door to tail type modifiers in general, not just in classes. It's a b
urning issue e.g. with ranges (mostly struct).

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

Look at the attachment to get a feel of what hoops we'll have to jump throu
gh to side-step lack of tail X.


Passing 'this' by reference in struct member functions makes it pretty 
much impossible to support tail const. The reason it works for classes 
is that class member functions receive a *copy* of the 'this' object 
reference, in other words the constness of the original reference does 
not matter.



--
Michel Fortin
michel.for...@michelf.com
http://michelf.com/



Re: assert(expression, error)

2011-02-12 Thread Michel Fortin
On 2011-02-12 10:05:34 -0500, Andrej Mitrovic 
 said:



Btw, is the inline problem just a DMD implementation problem, or does
enforce have to be fixed for that?


DMD implementation problem. The inliner doesn't support ref, out, lazy, 
and delegate arguments at this time. Enforce uses a lazy second 
argument so it doesn't get inlined.


--
Michel Fortin
michel.for...@michelf.com
http://michelf.com/



Re: Struct reference returning function and const members

2011-03-03 Thread Michel Fortin

On 2011-03-03 01:42:18 -0500, Tom  said:


I have...

int main(string[] args) {
auto s1 = f(); // MH MH
auto s2 = g(); // OK
s2.c = null; // OK
return 0;
}


I think the compiler complains because the s1.c member is not 
assignable (since it is const), so you can't assign to s1 as a whole. 
That said, it should probably be allowed for an initialization 
assignment like this one. I suggest you add it to the bug tracker.

<http://d.puremagic.com/issues/>


--
Michel Fortin
michel.for...@michelf.com
http://michelf.com/



Re: Deducing types for function templates

2011-03-15 Thread Michel Fortin

On 2011-03-15 10:42:46 -0400, Magnus Lie Hetland  said:


I've got a function template along these lines:

  Foo!T foo(T)(T[] bar, real function(T,T) baz) { ... }

The main reason I'm using this is that it seems necessary to use a 
function, rather than a type (such as Foo), if you want the compiler to 
deduce the compile-time parameters. (Right?)


Now ... this works just fine. However, if I try to add "const" before 
"T[]", DMD no longer groks it. Is that how it shold be? Seems awkward 
to me... (Or maybe I'm just doing it wrong?)


I'd say add it to bugzilla. It's probably related to this bug:
<http://d.puremagic.com/issues/show_bug.cgi?id=5531>


And a followup question: Writing out the type of baz like this (in 
several places) is also a bit awkward. I'd like to have a template so I 
could just do


  Foo!T foo(T)(T[] bar, baz_t!T baz) { ... }

However, I haven't been able to define such a template without running 
into the same problem (i.e., that DMD no longer can deduce what T 
should be from my arguments).


My feeling is that it should work. Feel free to file a bug or 
enhancement request in the bug tracker.



--
Michel Fortin
michel.for...@michelf.com
http://michelf.com/



Re: Deducing types for function templates

2011-03-15 Thread Michel Fortin

On 2011-03-15 13:20:30 -0400, "Simen kjaeraas"  said:

On Tue, 15 Mar 2011 17:36:04 +0100, Michel Fortin  
 wrote:



On 2011-03-15 10:42:46 -0400, Magnus Lie Hetland   said:


I've got a function template along these lines:
   Foo!T foo(T)(T[] bar, real function(T,T) baz) { ... }
 The main reason I'm using this is that it seems necessary to use a  
function, rather than a type (such as Foo), if you want the compiler to 
 deduce the compile-time parameters. (Right?)
 Now ... this works just fine. However, if I try to add "const" before  
"T[]", DMD no longer groks it. Is that how it shold be? Seems awkward  
to me... (Or maybe I'm just doing it wrong?)


I'd say add it to bugzilla. It's probably related to this bug:
<http://d.puremagic.com/issues/show_bug.cgi?id=5531>


Oh, it's much older than that:

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


I'm not sure it's the same thing, but I realize it's hard to say given 
Magnus in his original post didn't mention how he attempts to 
instantiate the template.


--
Michel Fortin
michel.for...@michelf.com
http://michelf.com/



Re: Want to help DMD bugfixing? Write a simple utility.

2011-03-19 Thread Michel Fortin

On 2011-03-19 20:41:09 -0400, Jonathan M Davis  said:


On Saturday 19 March 2011 17:11:56 Don wrote:

Here's the task:
Given a .d source file, strip out all of the unittest {} blocks,
including everything inside them.
Strip out all comments as well.
Print out the resulting file.

Motivation: Bug reports frequently come with very large test cases.
Even ones which look small often import from Phobos.
Reducing the test case is the first step in fixing the bug, and it's
frequently ~30% of the total time required. Stripping out the unit tests
is the most time-consuming and error-prone part of reducing the test case.

This should be a good task if you're relatively new to D but would like
to do something really useful.


Unfortunately, to do that 100% correctly, you need to actually have a working D
lexer (and possibly parser). You might be able to get something close enough to
work in most cases, but it doesn't take all that much to throw off a basic
implementation of this sort of thing if you don't lex/parse it with something
which properly understands D.


Well, I made simple lexer for D strings, comments, identifiers and a 
few other tokens which should be up to that task. It's what I use to 
parse files and detect dependencies in D for Xcode. Unfortunately, it's 
written in Objective-C++ (but half of it is plain C)...


<https://github.com/michelf/d-for-xcode/blob/master/Sources/DXBaseLexer.h>
<https://github.com/michelf/d-for-xcode/blob/master/Sources/DXBaseLexer.mm>
<https://github.com/michelf/d-for-xcode/blob/master/Sources/DXScannerTools.h>
<https://github.com/michelf/d-for-xcode/blob/master/Sources/DXScannerTools.m>

Very short unit test:
<https://github.com/michelf/d-for-xcode/blob/master/Unit%20Tests/DXBaseLexerTest.mm>

--


Michel Fortin
michel.for...@michelf.com
http://michelf.com/



Re: File, line and message for assert(0)?

2011-05-28 Thread Michel Fortin

On 2011-05-28 12:32:59 -0400, simendsjo  said:

I don't think I understand the use case for assert(0) then.. I thought 
it was just a way getting assert in release mode.


The use case for assert(0) is the same as any assert(whatever): 
checking for things that shouldn't happen. Normally compiling in 
release mode would strip all the asserts to make things slimmer and 
faster. But given there is no cost in checking for assert(0), those are 
not stripped, they are just replaced with a halt instruction. So the 
assert's still there, but you don't have a message for it nor the line 
number.


If you want to see where the assertion happens, you can either compile 
in non-release mode or you can hook a debugger to your release 
executable and wait for the assert to happen.


--
Michel Fortin
michel.for...@michelf.com
http://michelf.com/



Re: Pure not acting pure.

2011-06-16 Thread Michel Fortin

On 2011-06-15 23:29:46 -0400, Charles McAnany  said:

Ah, so does the compiler figure out which ones are strongly and weakly 
pure and then optimize as
appropriate? Is there a way to indicate that a function is strongly 
pure? Because it would seem odd

to call a function you thought was pure and wind up with a mutated argument.


Just make sure all the parameters are either const or immutable or 
passed by copy and do not contain any pointer or reference. That'll 
make the function strongly pure, and the compiler will be able optimize.


--
Michel Fortin
michel.for...@michelf.com
http://michelf.com/



Re: is this a poly Polymorphism?

2011-08-29 Thread Michel Fortin

On 2011-08-29 01:58:30 +, Jonathan M Davis  said:


On Monday, August 29, 2011 04:50:09 hhaammaadd wrote:

import std.stdio;
class employee {
void work() {
writeln("I am employee");
}
}

class manager: employee {
void work() {
writeln("I am manager");
}
}


void main() {
employee e1 = new manager;//here
e1.work();

manager m3 = new manager;//--|here
employee *e2 = &m3;//|
e2.work();


}


Pointers are not polymorphic in D. Class references are, but if you have a
pointer to a class, it assumes that the type is exactly that type and
determines its function calls at compile time rather than at runtime.


Actually, a pointer to a class is really a pointer to a reference to an 
object, since the reference is always with a class type. So "employee 
*" is in reality a pointer to a reference to an employee object.


--
Michel Fortin
michel.for...@michelf.com
http://michelf.com/



Re: integer cast in object_.d

2011-09-04 Thread Michel Fortin
On 2011-09-05 02:57:33 +, Andrej Mitrovic 
 said:



I'm looking at compare() in class TypeInfo_Array and it's defined as:

override int compare(in void* p1, in void* p2)
{
void[] a1 = *cast(void[]*)p1;
void[] a2 = *cast(void[]*)p2;
size_t sz = value.tsize();
size_t len = a1.length;

if (a2.length < len)
len = a2.length;
for (size_t u = 0; u < len; u++)
{
int result = value.compare(a1.ptr + u * sz, a2.ptr + u * sz);
if (result)
return result;
}
return cast(int)a1.length - cast(int)a2.length;
}

Shouldn't that return line be:
return cast(int)(a1.length - a2.length);

To make it 64-bit safe?


Per the rules of modular arithmetic substraction, both will give you 
the same result actually. And no it isn't 64-bit safe.



--
Michel Fortin
michel.for...@michelf.com
http://michelf.com/



Re: WinRT

2011-09-30 Thread Michel Fortin

On 2011-09-29 21:23:48 +, RenatoL  said:


Hi all. What do you about WinRT? I think this new APIs could be a
very interesting point for D... they are open to any language and
i think that D is perfect to work with them. What's your opinion?
Best regards


From what I understand, WinRT is based on COM. D already supports COM, 
so it might already be doable by declaring the right interfaces as 
derivatives of IUnknown.


I suggest you give it a try.

That said, the automatic reference counting they added to WinRT types 
in Visual C++ won't be available without compiler support (but you can 
do it manually), and neither will the compiler-generated reflection 
data (you'll have to generate it yourself).


--
Michel Fortin
michel.for...@michelf.com
http://michelf.com/



Re: WinRT

2011-10-01 Thread Michel Fortin

On 2011-09-30 14:05:28 +, Jacob Carlborg  said:


On 2011-09-30 12:58, Michel Fortin wrote:

On 2011-09-29 21:23:48 +, RenatoL  said:


Hi all. What do you about WinRT? I think this new APIs could be a
very interesting point for D... they are open to any language and
i think that D is perfect to work with them. What's your opinion?
Best regards


 From what I understand, WinRT is based on COM. D already supports COM,
so it might already be doable by declaring the right interfaces as
derivatives of IUnknown.

I suggest you give it a try.

That said, the automatic reference counting they added to WinRT types in
Visual C++ won't be available without compiler support (but you can do
it manually), and neither will the compiler-generated reflection data
(you'll have to generate it yourself).


Doesn't the garbage collector implement reference counting or similar 
when implementing from IUnknown?


Would be great, but it's not mentioned in the language spec so I 
somewhat doubt it.

<http://www.d-programming-language.org/interface.html#COM-Interfaces>

--
Michel Fortin
michel.for...@michelf.com
http://michelf.com/