Re: Primary Ranges of Containers

2012-06-18 Thread Matthias Walter
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

On 06/18/2012 01:08 PM, Jonathan M Davis wrote:
> On Monday, June 18, 2012 10:06:44 Matthias Walter wrote:
>> Hi,
>> 
>> last week I realized that a const version of 
>> std.container.Array.opSlice() is missing. Now I looked at the
>> code and I think that it is a general design problem.
>> 
>> The docs state that "c.Range" is "The primary range type
>> associated with the container.". I think we really always need
>> two Range types (one for const view and one for non-const view)
>> by design.
>> 
>> I'd propose to always add a bool template parameter (maybe
>> isConst?) to the range since most of the write-functionality can
>> be "removed" by a static if statement in order to make the range
>> read-only.
>> 
>> Any suggestions?
> 
> Yeah, it'll probably have to be templated. C++ already has to do
> something similar with iterators and const_iterators. But since you
> don't normally use the type of a range explicitly, it shouldn't be
> a big deal. The one downside that might pose a problem though is
> that if someone _does_ use the type explicitly, their code will
> break if the type gets templated. We could make a second type
> (ConstRange?) for the iterating over a const Array, but I'd be 
> tempted to just templatize the thing and let it break any code that
> it breaks. std.container is already likely to break stuff to at
> least some extent when the custom allocators get added anyway. I
> suppose that we could just rename the type and then create an alias
> for the current type
> 
> struct ArrayRange(bool isConst) {...} alias ArrayRange!false
> Range; alias ArrayRange!true ConstRange;
> 
> but that might be overkill. I don't know. Regardless, it _is_
> likely that the range type will have to be templatized to fix the
> problem. Ranges and range- based functions in general need to be
> cleaned up a bit to deal with const, since the way that they're
> designed doesn't work with const very well, and we need to make it
> work. I think that it _can_ work, but it takes more effort to do
> so.

I fully agree with all that. In order to migrate older code we may
make isConst have a default value of false.

Best regards,

Matthias

-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iQEcBAEBAgAGBQJP4B8OAAoJEPdcuJbq5/sR7h0H/jeJ+KPUMoiP9SqiamE0qv4V
IantID2fzML8b55CWGQ2ZU7YbhQqOPIIEVtRriNAUIA4sHqWXQA03YgFrDk7XZZy
jrhx9VCUkiMeIuHhSdXQIwAWH+dkfnQoOS9EwbbiwZjBG+zU5iH/s9tduRzKadTr
Bb4QLAx7hEjlsvgRArj0O5z88YeGWbLhUzTz70utoE+1VgROuVF4WzJL9S803ZWX
ZZR1HOx0ktE60jvBTMoK2TzSfB5/JjiDQSWjK8ikEQGSw8QR3M3DWD3WkFucOAaL
3K6xH/yoDTBMOT+IVjkfVOsnv0iBB7ARpJKxOD2r+bJOoGWCQ1YQAoyY8rwrez0=
=yhaM
-END PGP SIGNATURE-


Clang-based service architecture

2012-06-18 Thread Guillaume Chatelet
Google by the voice of Chandler Carruth made this proposal a few days ago

https://plus.google.com/u/0/108216155797501293389/posts/WDheftEoxMT

It aims at building a clang daemon to parse, compile, and generate
informations about source code. Basically
+ multithreaded, distributed compilation
+ coherent support of the language (C/C++/ObjC) throughout IDEs or text
editors ( formatting, syntax highlight, realtime report of compilation
errors/warning, maybe static analysis )

The D community already is moving toward this direction as I can see (
Roman D. Boiko's proposal or Robert Schadek "Distributed Multithreaded
Caching D Compiler" ) and that's awesome news !

Also the idea of getting compiler error/warning, formatting, syntax
highlight as a service looks very sweet to me. A wonderful way to unite
and keep everything in sync from text editor to more powerful IDEs.


Re: DMD + msvc

2012-06-18 Thread Jacob Carlborg

On 2012-06-19 01:22, Walter Bright wrote:

On 6/18/2012 11:10 AM, Adam Wilson wrote:

Object generation is an unholy disaster of
IFDEF's and my brain has melted every time I try to venture into it;
but if we
have a clean interface for interacting with them it would make it
significantly
easier to add things like custom sections, which in turn will open up
a plethora
of new options, including source embedding.


Yeah, me too. But fixing that is not so easy.


A start is to have a rigorous set of tests for this part of the 
compiler. I know the compiler has a test suite but I don't know how much 
of this particular code is covered.


With a rigorous set of tests one will feel more comfortable in 
refactoring the code.


Then it just some hard work that will probably take some time. The first 
thing would probably be to try to put everything platform specific in 
one place. Ideally there would only be one set of if-def's.
If possible this can happen iteratively in several steps. When a 
function needs to be changed refactor it as well to make it more clean.


Ideally we don't want to the new COFF backend to become a part of this mess.

--
/Jacob Carlborg


Re: AST files instead of DI interface files for faster compilation and easier distribution

2012-06-18 Thread Timon Gehr

On 06/19/2012 02:47 AM, Chris Cain wrote:

On Monday, 18 June 2012 at 18:05:59 UTC, Daniel wrote:

Same here, I wish there were a standardized pre-lexed-token "binary"
file-format, would benefit all text editors also, as they need to lex
it anyway to perform color syntax highlighting.


If I were to make my own language, I'd forego a human-readable format
and just have the "language" be defined as a big machine-readable AST.


http://de.wikipedia.org/wiki/Lisp ?


You'd have to have an IDE, but it could display the code in just about
any way the person wants (syntax, style, etc).



This could be done even if the language's source code storage format is 
human-readable.



Syntax highlighting would be instantaneous and there would be fewer
errors made by programmers (maybe ...). Plus it'd be unbelievably easy
to implement things like auto-completion.


Parsing is not a huge issue. Depending on how powerful the language is, 
auto-completion may depend on full code analysis.


Re: AST files instead of DI interface files for faster compilation and easier distribution

2012-06-18 Thread Chris Cain

On Monday, 18 June 2012 at 18:05:59 UTC, Daniel wrote:
Same here, I wish there were a standardized pre-lexed-token 
"binary" file-format, would benefit all text editors also, as 
they need to lex it anyway to perform color syntax highlighting.


If I were to make my own language, I'd forego a human-readable 
format and just have the "language" be defined as a big 
machine-readable AST. You'd have to have an IDE, but it could 
display the code in just about any way the person wants (syntax, 
style, etc).


Syntax highlighting would be instantaneous and there would be 
fewer errors made by programmers (maybe ...). Plus it'd be 
unbelievably easy to implement things like auto-completion.


Re: DMD + msvc

2012-06-18 Thread Trass3r
Does this somewhat vague statement meant that we are getting COFF  
support in the near term?


Yes, because that is necessary for MSVC linker compatibility.


Hooray!


Re: DMD + msvc

2012-06-18 Thread Walter Bright

On 6/18/2012 11:10 AM, Adam Wilson wrote:

On Mon, 18 Jun 2012 10:50:44 -0700, Walter Bright 
wrote:


On 6/17/2012 3:34 AM, Jacob Carlborg wrote:

1. DMD can only output OMF binaries
2. DMD cannot output 64bit code for Windows
3. DMD is not compatible with the MSVC linker or runtime



I intend to fix all of those, at least for 64 bit Windows, in the near term.



Does this somewhat vague statement meant that we are getting COFF support in the
near term?


Yes, because that is necessary for MSVC linker compatibility.


Because if so, I have some serious plans for source embedding in
custom sections. The only thing blocking it is the fact that OMF doesn't support
custom sections. Once the source is embedded in libraries, we can finally
jettison DI files once and for all! Also would it be possible at this point to
clean up the backend such that we have a clean interface for interacting with
object files during their construction, given that with COFF, all object format
wills be roughly feature equal?


Probably not, though it will be better.


Object generation is an unholy disaster of
IFDEF's and my brain has melted every time I try to venture into it; but if we
have a clean interface for interacting with them it would make it significantly
easier to add things like custom sections, which in turn will open up a plethora
of new options, including source embedding.


Yeah, me too. But fixing that is not so easy.



Re: getcwd behaves inconsistent?

2012-06-18 Thread Stephen Jones

On Monday, 18 June 2012 at 20:53:27 UTC, Nick Sabalausky wrote:

"Kapps"  wrote in message
news:jikemjmapclwcufpw...@forum.dlang.org...

On Sunday, 17 June 2012 at 22:39:00 UTC, Stephen Jones wrote:
I recently switched from Eclipse to monoD and found that all 
my code to images etc was invalid because getcwd returns the 
directory that contains the main entry code in Eclipse, but 
returns the directory that contains the executable in 
MonoDevelop. Is there a universally consistent way of 
accessing files?


As mentioned, it is not reliable to use the current working 
directory for making a relative path absolute.




Right. "Current Working Directory" and "Directory of 
Executable" should

never be confused:

- The working directory should be assumed to always be 
different, as it's
whatever directory the user just happens to be in when they run 
your

program.

- If you want to load files that are relative to the exe's 
path, then you
need the directory of the executble. The working directory 
won't help at
all. Note that args[0] is *not* good for this either, as that 
gets screwed
up by symlinks and all sorts of other stuff. args[0] is 
unreliable.


The approach I use is GetModuleFileNameA on Windows 
(GetModuleFileNameA(null, Buffer.ptr, MAX_PATH)) and 
readLinkPosix for /proc/self/exe on Linux 
(readLinkPosix("/proc/self/exe", Buffer.ptr, Buffer.length)).


Yea, that's definitely the way to go. Here are ready-to-go 
functions that
should handle that on Windows, Linux and OSX (untested on OSX 
as I don't

have a working Mac, but theoretically *should* work):

https://bitbucket.org/Abscissa/semitwistdtools/src/8123e04b593c/src/semitwist/util/io.d#cl-168

(Ignore the commented out function - that's just a remenant 
from the

D1/Tango days, I should probably just delete that.)

Use those functions like this:

// Assuming the exe is "C:\Foo\Bar\App.exe"
assert(getExec() == `C:\Foo\Bar\App.exe`);
assert(getExecName() == `App.exe`);
assert(getExecPath() == `C:\Foo\Bar\`);

You should be able to rip those functions right out of that 
file and plop
them into any util module you have, just make sure you also 
include these

import lines:

version(Win32)
import std.c.windows.windows;
else version(OSX)
private extern(C) int _NSGetExecutablePath(char* buf, uint* 
bufsize);

else
import std.c.linux.linux;


That was what I was after. Thanks.


Re: How to break const

2012-06-18 Thread Artur Skawina
On 06/18/12 23:08, deadalnix wrote:
> Le 18/06/2012 09:14, Mehrdad a écrit :
>> Okay, how about this? http://ideone.com/VMlzS
>>
>> Does this break const?
>>
>>
>> import std.stdio;
>> class S
>> {
>> this(int a)
>> {
>> this.a = a;
>> this.increment = { this.a++; };
>> }
>> int a;
>> void delegate() increment;
>> void oops() const { this.increment(); }
>> }
>> void main()
>> {
>> auto c = new const(S)(0);
>> writeln(c.a);
>> c.oops();
>> writeln(c.a);
>> }
> 
> Depending on how it is specified, I think you should either :
>  - get an error when constructing c, because S isn't « constable ». (delegate 
> type cannot be consted, but can be unconsted safely).
>  - get an error when you try to call increment in oops, because the delegate 
> type can't ensure the constness of the operation.
> 

I'm afraid that:

- Banning implicit mutable->const conversions would do far more harm,
  so this would not be a good solution to the problem.
- Requiring that the type of the delegate "ensure the constness" would
  be far too restrictive. (the question would be: "Is any data reachable
  via 'this' also reachable through the delegates context pointer?" and
  every such delegate would of course need to be "pure" [1].

[This isn't *just* about the above example, you get the same problems
 when a const object isn't created but received from somewhere.]

artur

[1] which is a misnomer.


Re: How to break const

2012-06-18 Thread deadalnix

Le 18/06/2012 09:14, Mehrdad a écrit :

Okay, how about this? http://ideone.com/VMlzS

Does this break const?


import std.stdio;
class S
{
this(int a)
{
this.a = a;
this.increment = { this.a++; };
}
int a;
void delegate() increment;
void oops() const { this.increment(); }
}
void main()
{
auto c = new const(S)(0);
writeln(c.a);
c.oops();
writeln(c.a);
}


Depending on how it is specified, I think you should either :
 - get an error when constructing c, because S isn't « constable ». 
(delegate type cannot be consted, but can be unconsted safely).
 - get an error when you try to call increment in oops, because the 
delegate type can't ensure the constness of the operation.


Re: How to break const

2012-06-18 Thread deadalnix

Le 18/06/2012 17:29, Timon Gehr a écrit :

On 06/18/2012 05:14 PM, Christophe Travert wrote:

Matthias Walter , dans le message (digitalmars.D:170036), a écrit :

On 06/18/2012 07:36 AM, Mehrdad wrote:

Is it just me, or did I subvert the type system here?


import std.stdio;

struct Const
{
this(void delegate() increment)
{ this.increment = increment; }
int a;
void delegate() increment;
void oops() const { this.increment(); }
}

void main()
{
Const c;
c = Const({ c.a++; });
writeln(c.a);
c.oops();
writeln(c.a);
}



I don't think so. When calling oops you have two references to the
object c:

- The this-pointer of the object itself which is not allowed to change
the object in the const-call.
- The reference from within main which is allowed to change it and can
be reached via the frame pointer of the delegate.

I see this as perfectly valid code. Of course, opinions may differ here.


But here, the frame pointer of the delegate is part of the const
structure. By transitivity, the frame pointer should be const, ...


'By transitivity' is not a sufficient reason. What you really mean is
'For the guarantee that a const pure method does not change its mutable
parameters'.


Transitivity by itself is required to solve a wide range of problem. The 
most obvious one is controlling what is shared and what isn't using the 
type system.


Re: How to break const

2012-06-18 Thread Era Scarecrow

On Monday, 18 June 2012 at 15:24:31 UTC, Mehrdad wrote:

On Monday, 18 June 2012 at 15:21:36 UTC, Timon Gehr wrote:
So (**IMHO**) if that's really the case, we should really 
spend some time fixing the /design/ of const before the 
implementation...


This is mostly about the design of object initialisation.


good idea or no?


Certainly.



My initial instinct would be to require a "const constructor" 
in order for an object to be const-able, but I'm not sure if 
that would work correctly or not..


 Hmmm... Reminds me of an issue that ended up coming up regarding 
code I was transforming to use immutable rather than mutable 
data. I kept coming up with the same issues. Without a const 
specific constructor, the immutable data I was basing the 
information off refused to go to a mutable temporary (since I 
needed it to be mutable), even if the end object was immutable 
and the data was untouched.


 I ended up with having to make a separate function that acted as 
a constructor, copying immutable elements and data as needed as 
mutable, then passing it back as immutable afterwards. A little 
ugly but it got the job done.


 I also came across an interesting problem.

struct X {
immutable int i_i = 10;
const int c_i = 10;   //same with immutable

immutable int i_i2;
const int c_i2;

this (int n) {
i_i = n; //ct error
c_i = n; //ct error

i_i2 = n;
c_i2 = n;
}
}

void main(){
X x = X(15);
}

 In this case it refuses to modify i_i & c_i during the 
constructor, the value of i_i & c_i specify is basically a 
replacement default(init) and should remain mutable until the 
constructor is finished (Or at least allowed to set once). If I 
wanted a strictly unchanged value I probably would have used an 
enum, and not used the space.


 Is this a bug or intentional?


Re: getcwd behaves inconsistent?

2012-06-18 Thread Nick Sabalausky
"Kapps"  wrote in message 
news:jikemjmapclwcufpw...@forum.dlang.org...
> On Sunday, 17 June 2012 at 22:39:00 UTC, Stephen Jones wrote:
>> I recently switched from Eclipse to monoD and found that all my code to 
>> images etc was invalid because getcwd returns the directory that contains 
>> the main entry code in Eclipse, but returns the directory that contains 
>> the executable in MonoDevelop. Is there a universally consistent way of 
>> accessing files?
>
> As mentioned, it is not reliable to use the current working directory for 
> making a relative path absolute.
>

Right. "Current Working Directory" and "Directory of Executable" should 
never be confused:

- The working directory should be assumed to always be different, as it's 
whatever directory the user just happens to be in when they run your 
program.

- If you want to load files that are relative to the exe's path, then you 
need the directory of the executble. The working directory won't help at 
all. Note that args[0] is *not* good for this either, as that gets screwed 
up by symlinks and all sorts of other stuff. args[0] is unreliable.

> The approach I use is GetModuleFileNameA on Windows 
> (GetModuleFileNameA(null, Buffer.ptr, MAX_PATH)) and readLinkPosix for 
> /proc/self/exe on Linux (readLinkPosix("/proc/self/exe", Buffer.ptr, 
> Buffer.length)).

Yea, that's definitely the way to go. Here are ready-to-go functions that 
should handle that on Windows, Linux and OSX (untested on OSX as I don't 
have a working Mac, but theoretically *should* work):

https://bitbucket.org/Abscissa/semitwistdtools/src/8123e04b593c/src/semitwist/util/io.d#cl-168

(Ignore the commented out function - that's just a remenant from the 
D1/Tango days, I should probably just delete that.)

Use those functions like this:

// Assuming the exe is "C:\Foo\Bar\App.exe"
assert(getExec() == `C:\Foo\Bar\App.exe`);
assert(getExecName() == `App.exe`);
assert(getExecPath() == `C:\Foo\Bar\`);

You should be able to rip those functions right out of that file and plop 
them into any util module you have, just make sure you also include these 
import lines:

version(Win32)
import std.c.windows.windows;
else version(OSX)
private extern(C) int _NSGetExecutablePath(char* buf, uint* bufsize);
else
import std.c.linux.linux;




A currying function

2012-06-18 Thread bearophile
I think std.functional.curry is badly named because I think it's 
a "partial application" (I suggest to rename it).



In Haskell and Scala currying is built-in, this is Haskell, shell 
(ghci):


Prelude> let foo x y z = x * 2 + y * 3 + y * 5
Prelude> let foo1 = foo 5
Prelude> let foo2 = foo1 4
Prelude> foo2 3
42


Through Reddit I've found a curry() in C++11:
https://github.com/LeszekSwirski/cpp-curry


So I've written a D version of it below, not tested much. I have 
not translated the C++11 version. This was quite easy to write, 
and much simpler and shorter than the C++11 version (but maybe 
this misses something, this is just a first draft). This kind of 
stuff was quite longer to do in D1, but now with CTFE on strings 
ops, defining one or more inner static functions that build a 
string at compile-time, it's quite easy. Now I don't need lot of 
templates to do this.


There are two alternative designs, curry1 seems a bit more 
elegant, but if you want to use it in-place it forces you to add 
a () at the beginning, that's not nice and intuitive. So probably 
curry2 is better.



import std.traits: isCallable, ParameterTypeTuple;
import std.string: join;
import std.conv: xformat;

@property curry1(alias F)() if (isCallable!F) {
static string genChain() {
string[] chain;
string[] args;
foreach (i, T; ParameterTypeTuple!F) {
chain ~= xformat("(%s x%d)", T.stringof, i);
args ~= xformat("x%d", i);
}
return chain.join(" => ") ~ " => F(" ~ args.join(", ") ~ 
");";

}
mixin("return " ~ genChain());
}

auto curry2(F)(F f) if (isCallable!F) {
static string genChain() {
string[] chain;
string[] args;
foreach (i, T; ParameterTypeTuple!F) {
chain ~= xformat("(%s x%d)", T.stringof, i);
args ~= xformat("x%d", i);
}
return chain.join(" => ") ~ " => f(" ~ args.join(", ") ~ 
");";

}
mixin("return " ~ genChain());
}

// default arguments are ignored
double foo(immutable int x, in float y, short z=5) pure nothrow {
return x * 2 + y * 3 + y * 5;
}

void main() {
import std.stdio;

writeln(foo(5, 4, 3));

auto cf = curry1!foo;
auto c2 = cf(5)(4);
writeln(c2(3));

writeln(curry1!foo()(5)(4)(3));
writeln(curry2(&foo)(5)(4)(3));
}



This is the code string generated by genChain() for the foo() 
function:


(immutable(int) x0) => (const(float) x1) => (short x2) => f(x0, 
x1, x2);



I think this code induces the creation of heap allocated 
closures, so probably a more efficient version is needed:


_D4test24__T5curryTPFNaNbyixfs...
L0: push EAX
push EAX
push EBX
push 8
call near ptr __d_allocmemory
mov  EBX,EAX
mov  EAX,0Ch[ESP]
mov  [EBX],EAX
fld  float ptr 014h[ESP]
mov  EAX,EBX
mov  EDX,offset FLAT:_D4test24__T5curryTPFNaNbyixf...
fstp float ptr 4[EBX]
add  ESP,4
pop  EBX
add  ESP,8
ret  4


If the function is:

double bar(ref int x, ref double y) pure nothrow {
x++;
return x * 2 + y * 3;
}


it generates:

(int x0) => (double x1) => f(x0, x1);

So this version doesn't handle ref arguments.

Bye,
bearophile


Re: DMD + msvc

2012-06-18 Thread Jonathan M Davis
On Monday, June 18, 2012 23:23:02 Manu wrote:
> It really is. I suspect we will see a gigantic boots to the D community on
> the back of this change! :)

Well, we could all use a good pair of shoes. ;)

- Jonathan M Davis


Re: DMD + msvc

2012-06-18 Thread Manu
On 18 June 2012 22:07, "@puremagic.com <
"\"Michaël".Larouche"> wrote:

> On Monday, 18 June 2012 at 17:51:39 UTC, Walter Bright wrote:
>
>> On 6/17/2012 3:34 AM, Jacob Carlborg wrote:
>>
>>> 1. DMD can only output OMF binaries
>>> 2. DMD cannot output 64bit code for Windows
>>> 3. DMD is not compatible with the MSVC linker or runtime
>>>
>>
>>
>> I intend to fix all of those, at least for 64 bit Windows, in the near
>> term.
>>
>
> This is great news !
>

It really is. I suspect we will see a gigantic boots to the D community on
the back of this change! :)


Re: Shared objects?

2012-06-18 Thread Jacob Carlborg

On Monday, 18 June 2012 at 15:22:19 UTC, Wouter Verhelst wrote:


Ah, too bad.

Do you have a pointer to some more detailed information on 
this? Just so
I can get a feel for how fast things are moving, and/or whether 
it's
worth for me to wait for that -- I can get started on the other 
parts;
while the plugin architecture would be crucial eventually, it's 
not

something I'll need from the very beginning.

Thanks,


Martin Nowak is working on this: 
https://github.com/dawgfoto/druntime/tree/SharedRuntime


--
/Jacob Carlborg


Re: DMD + msvc

2012-06-18 Thread Michaël.Larouche

On Monday, 18 June 2012 at 17:51:39 UTC, Walter Bright wrote:

On 6/17/2012 3:34 AM, Jacob Carlborg wrote:

1. DMD can only output OMF binaries
2. DMD cannot output 64bit code for Windows
3. DMD is not compatible with the MSVC linker or runtime



I intend to fix all of those, at least for 64 bit Windows, in 
the near term.


This is great news !

For one of my personal projects I wanted to use LLVM with D, 
after trying to convert the MSVC .lib to OMF format, linking with 
Win64GDC and MinGW LLVM (but I didn't include all LLVM libs), I 
gave up and I booted to my Mac partition where the object and the 
linker are the same for all.


Re: DMD + msvc

2012-06-18 Thread Adam Wilson
On Mon, 18 Jun 2012 10:50:44 -0700, Walter Bright  
 wrote:



On 6/17/2012 3:34 AM, Jacob Carlborg wrote:

1. DMD can only output OMF binaries
2. DMD cannot output 64bit code for Windows
3. DMD is not compatible with the MSVC linker or runtime



I intend to fix all of those, at least for 64 bit Windows, in the near  
term.




Does this somewhat vague statement meant that we are getting COFF support  
in the near term? Because if so, I have some serious plans for source  
embedding in custom sections. The only thing blocking it is the fact that  
OMF doesn't support custom sections. Once the source is embedded in  
libraries, we can finally jettison DI files once and for all! Also would  
it be possible at this point to clean up the backend such that we have a  
clean interface for interacting with object files during their  
construction, given that with COFF, all object format wills be roughly  
feature equal? Object generation is an unholy disaster of IFDEF's and my  
brain has melted every time I try to venture into it; but if we have a  
clean interface for interacting with them it would make it significantly  
easier to add things like custom sections, which in turn will open up a  
plethora of new options, including source embedding.


--
Adam Wilson
IRC: LightBender
Project Coordinator
The Horizon Project
http://www.thehorizonproject.org/


Re: AST files instead of DI interface files for faster compilation and easier distribution

2012-06-18 Thread Daniel

On Monday, 18 June 2012 at 17:54:40 UTC, Walter Bright wrote:

On 6/18/2012 6:07 AM, Don Clugston wrote:

On 17/06/12 00:37, Walter Bright wrote:

On 6/14/2012 1:03 AM, Don Clugston wrote:

It is for debug builds.
Iain's data indicates that it's only a few % of the time 
taken on

semantic1().
Do you have data that shows otherwise?


Nothing recent, it's mostly from my C++ compiler testing.


But you argued in your blog that C++ parsing is inherently 
slow, and you've

fixed those problems in the design of D.
And as far as I can tell, you were extremely successful!
Parsing in D is very, very fast.


Yeah, but I can't escape that lingering feeling that lexing is 
slow.


I was fairly disappointed that asynchronously reading the 
source files didn't have a measurable effect most of the time.


Same here, I wish there were a standardized pre-lexed-token 
"binary" file-format, would benefit all text editors also, as 
they need to lex it anyway to perform color syntax highlighting.




Re: AST files instead of DI interface files for faster compilation and easier distribution

2012-06-18 Thread Walter Bright

On 6/18/2012 6:07 AM, Don Clugston wrote:

On 17/06/12 00:37, Walter Bright wrote:

On 6/14/2012 1:03 AM, Don Clugston wrote:

It is for debug builds.

Iain's data indicates that it's only a few % of the time taken on
semantic1().
Do you have data that shows otherwise?


Nothing recent, it's mostly from my C++ compiler testing.


But you argued in your blog that C++ parsing is inherently slow, and you've
fixed those problems in the design of D.
And as far as I can tell, you were extremely successful!
Parsing in D is very, very fast.


Yeah, but I can't escape that lingering feeling that lexing is slow.

I was fairly disappointed that asynchronously reading the source files didn't 
have a measurable effect most of the time.


Re: DMD + msvc

2012-06-18 Thread Walter Bright

On 6/17/2012 3:34 AM, Jacob Carlborg wrote:

1. DMD can only output OMF binaries
2. DMD cannot output 64bit code for Windows
3. DMD is not compatible with the MSVC linker or runtime



I intend to fix all of those, at least for 64 bit Windows, in the near term.



Just because it's not dmd, don't mean you have to shy away from contribution.

2012-06-18 Thread Iain Buclaw
Just thought I might say that it's ok to send pull requests for 
any important/critical changes in upstream dmd, phobos and 
druntime down to gdc if you feel it is the correct thing to do.  
It has been done in the past for any showstopping bugs in the 
library (various multithread related issues), and also for cool 
new features (__vector support) - and afterall that is one of the 
reasons why I felt moving to github was important - if there is 
an issue that you can resolve yourself, then get it done! Rather 
than wait for the ever persistant development bottleneck that is 
myself to find time to get round to it.  We don't bite, and only 
ask that anything gdc-specific is wrapped in version(GNU) so that 
it won't be forgotten upon the next big merge.



PS:  Sorry Alexrp, but I thought I might contribute my view to 
the community. :~)


Regards
Iain


Re: How to break const

2012-06-18 Thread Timon Gehr

On 06/18/2012 06:30 PM, Mehrdad wrote:

On Monday, 18 June 2012 at 16:23:39 UTC, Timon Gehr wrote:

I agree. Some of the keywords are poorly chosen, but this does not
have any actual _practical_ implications for coding. Changing them,
however, does.



Not sure if this was intended to be referring to my post or not, but
just to clarify:



It was not. ;)



The real problem is _not_ the fact that there is a technical issue with
const/pure/immutable/whatever.
Like you said, that might not have any practical consequences.


The problem is that when the compiler _uses_ const/pure/immutable to
make decisions regarding optimizations.



It is important that the type system is sound.


When that's the case, then IMHO they **MUST** be foolproof, no matter
how rare/common they are (assuming no casts and such, to subvert the
system).



This must be the case even if the compiler does not optimize.



Otherwise the compiler generates wrong binaries for correct code.


Then the compiler is wrong.


Re: How to break const

2012-06-18 Thread Andrei Alexandrescu

On 6/18/12 10:24 AM, Mehrdad wrote:

On Monday, 18 June 2012 at 15:21:36 UTC, Timon Gehr wrote:

So (**IMHO**) if that's really the case, we should really spend some
time fixing the /design/ of const before the implementation...


This is mostly about the design of object initialisation.


good idea or no?


Certainly.



My initial instinct would be to require a "const constructor" in order
for an object to be const-able, but I'm not sure if that would work
correctly or not..


The constructor of a const or immutable object progressively evolves the 
object from a raw state to a fixed, constructed state. During the 
process the object has not discernable type. This is what needs to be fixed.


Andrei


Re: How to break const

2012-06-18 Thread Andrei Alexandrescu

On 6/18/12 10:15 AM, Mehrdad wrote:

So (**IMHO**) if that's really the case, we should really spend some
time fixing the /design/ of const before the implementation... good idea
or no?


It's the implementation (not design) of constructors typechecking that's 
the problem.


Andrei


Re: How to break const

2012-06-18 Thread Mehrdad

On Monday, 18 June 2012 at 16:23:39 UTC, Timon Gehr wrote:
I agree. Some of the keywords are poorly chosen, but this does 
not have any actual _practical_ implications for coding. 
Changing them, however, does.



Not sure if this was intended to be referring to my post or not, 
but just to clarify:



The real problem is _not_ the fact that there is a technical 
issue with const/pure/immutable/whatever.

Like you said, that might not have any practical consequences.


The problem is that when the compiler _uses_ const/pure/immutable 
to make decisions regarding optimizations.


When that's the case, then IMHO they **MUST** be foolproof, no 
matter how rare/common they are (assuming no casts and such, to 
subvert the system).



Otherwise the compiler generates wrong binaries for correct code.


Re: How to break const

2012-06-18 Thread Timon Gehr

On 06/18/2012 06:12 PM, deadalnix wrote:

Le 18/06/2012 18:04, Timon Gehr a écrit :

It would be better to have 'nostatic' as the keyword for the
current 'pure' and 'pure' as a shortcut for 'immutable nostatic'.

This would also silence the 'pure is a misnomer' crowd.



I don't really have an opinion on that subject.  I understand the keywork
choice can be confusing, but the overall design is really nice.


I agree. Some of the keywords are poorly chosen, but this does not have
any actual _practical_ implications for coding. Changing them, however,
does.

It is just frustrating to always be stopped mid-sentence when
explaining the design to someone unfamiliar with it, or even have them
lose interest because they think to have found a 'problem' with it.

There is also a group of one or two guys who cannot mention 'pure'
without also mentioning that they disagree with the keyword choice.

Interestingly, few oppose to 'const'. This is probably because C++ has
paved the way for it.

TL;DR: poorly chosen keywords create needless communication overhead


Re: How to break const

2012-06-18 Thread deadalnix

Le 18/06/2012 18:04, Timon Gehr a écrit :

To explain my proposal, I have to make several thing clear first. You
have here 2 things to qualify : the delegate itself, and the hidden
parameter. As type qualifier are transitive in D, qualify the delegate
also transitively qualify the hidden parameter.

The proposal was to use postfix qualifier notation to qualify the hidden
parameter, and qualifier between return type and delegate keyword to
qualify the delegate itself.


Why would the second part of the proposal be necessary?



What do you qualify as the second part ?


My original proposal stated that the type
qualifier before the return type qualify the return type, but this is
another topic.

To make is clearer, some examples :

void delegate() const; // A mutable delegate that use const frame
pointer (all variable accessed throw the frame pointer are made const).
void const delegate(); // A const delegate that use a const frame
pointer (transitivity).
void const delegate() immutable; // A const delegate that use an
immutable frame pointer (delegate can only access immutable data from
the frame pointer).
void immutable delegate() const; // Error, immutable data cannot refers
to const data.

Note that the implicit cast goes the other way around than usual. void
delegate() const can be safely casted to void delegate(), but not the
other way around, as you are allowed to not mutate mutable data, but not
the other way around.


Comments:

1.

struct S{
int x;
void foo()pure{x++;} // ok
}

void main(){
int x;
void foo()pure{x++;} // currently an error
}

The second part should be allowed. It is qualifying foo as 'immutable'
which should fail.



Yes.


2.

int y;
struct S{
int x;
void foo()immutable{y++;} // ok
}

void main(){
void foo()immutable{y++;} // should be allowed
}

The problem is the unfortunate annotation overhead.


And yes. This is another topic, but I think the way to go is inference.


It would be better to have 'nostatic' as the keyword for the
current 'pure' and 'pure' as a shortcut for 'immutable nostatic'.

This would also silence the 'pure is a misnomer' crowd.



I don't really have an opinion on that subject. I understand the keywork 
choice can be confusing, but the overall design is really nice.


Re: How to break const

2012-06-18 Thread Timon Gehr

On 06/18/2012 05:12 PM, deadalnix wrote:

Le 18/06/2012 16:51, Andrei Alexandrescu a écrit :

Mehrdad posted a code sample and you replied to it with what I could
only assume was an explanation of the code's behavior. I hope you'd
agree it was a reasonable assumption, whether or not it was correct.

The problem at work here is that "this" is typed incorrectly during the
construction of a qualified object. It should go progressively from a
"raw" to a "cooked" state, and cannot be passed to any function while
raw.


I've however made other posts to explain why
transitivity is broken when it comes to delegate.


I looked at your posts through June and couldn't find such, so a couple
of links would be great. Of course, bug reports would be even better!



I'm not sure you are talking about the proposal or the transitivity
issue here. I'll explain the proposal below, for the explaination of why
the transitivity is broken, see :
http://forum.dlang.org/thread/ywispsasaylqscyua...@forum.dlang.org?page=2#post-jrn7sv:24jjj:241:40digitalmars.com



To explain my proposal, I have to make several thing clear first. You
have here 2 things to qualify : the delegate itself, and the hidden
parameter. As type qualifier are transitive in D, qualify the delegate
also transitively qualify the hidden parameter.

The proposal was to use postfix qualifier notation to qualify the hidden
parameter, and qualifier between return type and delegate keyword to
qualify the delegate itself.


Why would the second part of the proposal be necessary?


My original proposal stated that the type
qualifier before the return type qualify the return type, but this is
another topic.

To make is clearer, some examples :

void delegate() const; // A mutable delegate that use const frame
pointer (all variable accessed throw the frame pointer are made const).
void const delegate(); // A const delegate that use a const frame
pointer (transitivity).
void const delegate() immutable; // A const delegate that use an
immutable frame pointer (delegate can only access immutable data from
the frame pointer).
void immutable delegate() const; // Error, immutable data cannot refers
to const data.

Note that the implicit cast goes the other way around than usual. void
delegate() const can be safely casted to void delegate(), but not the
other way around, as you are allowed to not mutate mutable data, but not
the other way around.


Comments:

1.

struct S{
int x;
void foo()pure{x++;} // ok
}

void main(){
int x;
void foo()pure{x++;} // currently an error
}

The second part should be allowed. It is qualifying foo as 'immutable' 
which should fail.


2.

int y;
struct S{
int x;
void foo()immutable{y++;} // ok
}

void main(){
void foo()immutable{y++;} // should be allowed
}

The problem is the unfortunate annotation overhead.
It would be better to have 'nostatic' as the keyword for the
current 'pure' and 'pure' as a shortcut for 'immutable nostatic'.

This would also silence the 'pure is a misnomer' crowd.




Re: How to break const

2012-06-18 Thread deadalnix

Le 18/06/2012 17:50, Timon Gehr a écrit :

On 06/18/2012 05:28 PM, Mehrdad wrote:

On Monday, 18 June 2012 at 15:24:31 UTC, Mehrdad wrote:

On Monday, 18 June 2012 at 15:21:36 UTC, Timon Gehr wrote:

So (**IMHO**) if that's really the case, we should really spend some
time fixing the /design/ of const before the implementation...


This is mostly about the design of object initialisation.


good idea or no?


Certainly.



My initial instinct would be to require a "const constructor" in order
for an object to be const-able, but I'm not sure if that would work
correctly or not..


Come to think of it, that would play REALLY nicely with 'scope' -- a
reference to a non-const object can be escaped from a 'const
constructor' if and only if the reference is scope!

Bingo! Does that work??


Yes, but it requires proper enforcement of 'scope'.

- which is undecidable/must be done conservatively
- code would have to become 'scope correct'



Come on, what can't we infers qualifiers ?


Re: How to break const

2012-06-18 Thread Timon Gehr

On 06/18/2012 05:28 PM, Mehrdad wrote:

On Monday, 18 June 2012 at 15:24:31 UTC, Mehrdad wrote:

On Monday, 18 June 2012 at 15:21:36 UTC, Timon Gehr wrote:

So (**IMHO**) if that's really the case, we should really spend some
time fixing the /design/ of const before the implementation...


This is mostly about the design of object initialisation.


good idea or no?


Certainly.



My initial instinct would be to require a "const constructor" in order
for an object to be const-able, but I'm not sure if that would work
correctly or not..


Come to think of it, that would play REALLY nicely with 'scope' -- a
reference to a non-const object can be escaped from a 'const
constructor' if and only if the reference is scope!

Bingo! Does that work??


Yes, but it requires proper enforcement of 'scope'.

 - which is undecidable/must be done conservatively
 - code would have to become 'scope correct'



Re: How to break const

2012-06-18 Thread Mehrdad

On Monday, 18 June 2012 at 15:36:23 UTC, deadalnix wrote:

Le 18/06/2012 17:28, Mehrdad a écrit :

On Monday, 18 June 2012 at 15:24:31 UTC, Mehrdad wrote:

On Monday, 18 June 2012 at 15:21:36 UTC, Timon Gehr wrote:
So (**IMHO**) if that's really the case, we should really 
spend some
time fixing the /design/ of const before the 
implementation...


This is mostly about the design of object initialisation.


good idea or no?


Certainly.



My initial instinct would be to require a "const constructor" 
in order
for an object to be const-able, but I'm not sure if that 
would work

correctly or not..


Come to think of it, that would play REALLY nicely with 
'scope' -- a

reference to a non-const object can be escaped from a 'const
constructor' if and only if the reference is scope!

Bingo! Does that work??


Indeed, this should be scope for ctor (avoid partially 
initialized object in 3rd party code) /dtor (avoid 
resurrection, which is a real pain for any GC, and a very good 
way to ends up with alive object in invalid state).


note: "for a CONST ctor", not just any ctor



Re: How to break const

2012-06-18 Thread deadalnix

Le 18/06/2012 17:28, Mehrdad a écrit :

On Monday, 18 June 2012 at 15:24:31 UTC, Mehrdad wrote:

On Monday, 18 June 2012 at 15:21:36 UTC, Timon Gehr wrote:

So (**IMHO**) if that's really the case, we should really spend some
time fixing the /design/ of const before the implementation...


This is mostly about the design of object initialisation.


good idea or no?


Certainly.



My initial instinct would be to require a "const constructor" in order
for an object to be const-able, but I'm not sure if that would work
correctly or not..


Come to think of it, that would play REALLY nicely with 'scope' -- a
reference to a non-const object can be escaped from a 'const
constructor' if and only if the reference is scope!

Bingo! Does that work??


Indeed, this should be scope for ctor (avoid partially initialized 
object in 3rd party code) /dtor (avoid resurrection, which is a real 
pain for any GC, and a very good way to ends up with alive object in 
invalid state).


Re: How to break const

2012-06-18 Thread deadalnix

Le 18/06/2012 17:23, Timon Gehr a écrit :

On 06/18/2012 05:13 PM, deadalnix wrote:

Le 18/06/2012 16:55, Mehrdad a écrit :

On Monday, 18 June 2012 at 14:48:37 UTC, deadalnix wrote:

Le 18/06/2012 16:44, Mehrdad a écrit :

Interesting, making the delegate `pure' doesn't change anything
either.

So 'pure' doesn't let you "infer something just by looking at the code
either", right?


It does ! It tell you that the function have no side effect, and that
the function called with identical arguments will return identical
results.

pure will not ensure constness or immutability. const and immutable
are made for that.

The fact that D decouple purity and immutability is a very nice design
decision and is explained nicely here :
http://klickverbot.at/blog/2012/05/purity-in-d/




Identical calls giving identical results? What?


import std.stdio;
struct S
{
this(int a)
{
this.a = a;
this.increment = { return this.a++; };
}
int a;
int delegate() pure increment;
auto oops() const { return this.increment(); }
}
void main()
{
auto c = immutable(S)(0);
writeln(c.oops()); // 0
writeln(c.oops()); // 1
writeln(c.oops()); // 2
writeln(c.oops()); // 3
writeln(c.oops()); // 4
writeln(c.oops()); // 5
}


They are not call with the same parameters. The hidden parameter have
changed (I know this is tricky).


The whole problem is that the hidden parameter has changed. It is
immutable!


As said, this is effectively a const/immutable issue. Not a purity issue.

I'm not claiming that this code is fine, just explaining that the code 
is fine in regard to purity.


Re: How to break const

2012-06-18 Thread Timon Gehr

On 06/18/2012 05:14 PM, Christophe Travert wrote:

Matthias Walter , dans le message (digitalmars.D:170036), a écrit :

On 06/18/2012 07:36 AM, Mehrdad wrote:

Is it just me, or did I subvert the type system here?


import std.stdio;

struct Const
{
 this(void delegate() increment)
 { this.increment = increment; }
 int a;
 void delegate() increment;
 void oops() const { this.increment(); }
}

void main()
{
 Const c;
 c = Const({ c.a++; });
 writeln(c.a);
 c.oops();
 writeln(c.a);
}



I don't think so. When calling oops you have two references to the object c:

- The this-pointer of the object itself which is not allowed to change
the object in the const-call.
- The reference from within main which is allowed to change it and can
be reached via the frame pointer of the delegate.

I see this as perfectly valid code. Of course, opinions may differ here.


But here, the frame pointer of the delegate is part of the const
structure. By transitivity, the frame pointer should be const, ...


'By transitivity' is not a sufficient reason. What you really mean is
'For the guarantee that a const pure method does not change its mutable
parameters'.


Re: How to break const

2012-06-18 Thread Mehrdad

On Monday, 18 June 2012 at 15:24:31 UTC, Mehrdad wrote:

On Monday, 18 June 2012 at 15:21:36 UTC, Timon Gehr wrote:
So (**IMHO**) if that's really the case, we should really 
spend some

time fixing the /design/ of const before the implementation...


This is mostly about the design of object initialisation.


good idea or no?


Certainly.



My initial instinct would be to require a "const constructor" 
in order for an object to be const-able, but I'm not sure if 
that would work correctly or not..


Come to think of it, that would play REALLY nicely with 'scope' 
-- a reference to a non-const object can be escaped from a 'const 
constructor' if and only if the reference is scope!


Bingo! Does that work??


Re: How to break const

2012-06-18 Thread Timon Gehr

On 06/18/2012 05:13 PM, deadalnix wrote:

Le 18/06/2012 16:55, Mehrdad a écrit :

On Monday, 18 June 2012 at 14:48:37 UTC, deadalnix wrote:

Le 18/06/2012 16:44, Mehrdad a écrit :

Interesting, making the delegate `pure' doesn't change anything either.

So 'pure' doesn't let you "infer something just by looking at the code
either", right?


It does ! It tell you that the function have no side effect, and that
the function called with identical arguments will return identical
results.

pure will not ensure constness or immutability. const and immutable
are made for that.

The fact that D decouple purity and immutability is a very nice design
decision and is explained nicely here :
http://klickverbot.at/blog/2012/05/purity-in-d/




Identical calls giving identical results? What?


import std.stdio;
struct S
{
this(int a)
{
this.a = a;
this.increment = { return this.a++; };
}
int a;
int delegate() pure increment;
auto oops() const { return this.increment(); }
}
void main()
{
auto c = immutable(S)(0);
writeln(c.oops()); // 0
writeln(c.oops()); // 1
writeln(c.oops()); // 2
writeln(c.oops()); // 3
writeln(c.oops()); // 4
writeln(c.oops()); // 5
}


They are not call with the same parameters. The hidden parameter have
changed (I know this is tricky).


The whole problem is that the hidden parameter has changed. It is immutable!


Re: How to break const

2012-06-18 Thread Mehrdad

On Monday, 18 June 2012 at 15:21:36 UTC, Timon Gehr wrote:
So (**IMHO**) if that's really the case, we should really 
spend some

time fixing the /design/ of const before the implementation...


This is mostly about the design of object initialisation.


good idea or no?


Certainly.



My initial instinct would be to require a "const constructor" in 
order for an object to be const-able, but I'm not sure if that 
would work correctly or not..


Re: How to break const

2012-06-18 Thread deadalnix

Le 18/06/2012 17:20, Mehrdad a écrit :

On Monday, 18 June 2012 at 15:19:26 UTC, deadalnix wrote:


Yes, but this isn't a problem with pure here, this is a problem with
const.


Hence the title...


The sample code should not compile.


What should the error be? Is it correct in the language spec?


The specification lack on that point, because we are here facing a 
specification bug. Depending on how we choose to fix that, the error can 
be different.


Fix the initializer to dissalow the way you initialize c is probably the 
way to go on that specific case. Andrei says that work have been done in 
that direction, but I'm not aware of where it is now. It also require a 
way to qualify the frame pointer; which isn't possible ATM.


Re: How to break const

2012-06-18 Thread Timon Gehr

On 06/18/2012 05:15 PM, Mehrdad wrote:

On Monday, 18 June 2012 at 15:11:00 UTC, Timon Gehr wrote:

On 06/18/2012 04:55 PM, Mehrdad wrote:


Identical calls giving identical results? What?


import std.stdio;
struct S
{
 this(int a)
 {
 this.a = a;
 this.increment = { return this.a++; };
 }
 int a;
 int delegate() pure increment;
 auto oops() const { return this.increment(); }
}
void main()
{
 auto c = immutable(S)(0);
 writeln(c.oops()); // 0
 writeln(c.oops()); // 1
 writeln(c.oops()); // 2
 writeln(c.oops()); // 3
 writeln(c.oops()); // 4
 writeln(c.oops()); // 5
}


Now you have managed to break the type system.
The underlying issue is unrelated to delegates though.




Yeah, I didn't mean to say it's a delegate issue either. That's why the
title was saying "how to break _const_".  Delegates were just a means to
an end. :)


So (**IMHO**) if that's really the case, we should really spend some
time fixing the /design/ of const before the implementation...


This is mostly about the design of object initialisation.


good idea or no?


Certainly.


Re: How to break const

2012-06-18 Thread Mehrdad

On Monday, 18 June 2012 at 15:19:26 UTC, deadalnix wrote:


Yes, but this isn't a problem with pure here, this is a problem 
with const.


Hence the title...


The sample code should not compile.


What should the error be? Is it correct in the language spec?


Re: How to break const

2012-06-18 Thread Mehrdad

On Monday, 18 June 2012 at 15:16:58 UTC, Mehrdad wrote:

Explain it however you want.

The bottom line I'm getting at is, you can't re-order the 
calls, EVEN IF by "looking at them" you can tell they're pure 
@safe nothrow const...


(Sorry wasn't intending to make a mean comment -- my bad if it 
came across that way.)



And not just re-ordering for that matter.

I can't see /any/ optimizations happening even though these are 
const/pure/@safe/nothrow/whatever...


Re: D in your browser? possible?

2012-06-18 Thread nazriel

On Monday, 18 June 2012 at 14:59:53 UTC, Timon Gehr wrote:

On 06/18/2012 03:47 PM, nazriel wrote:

On Sunday, 17 June 2012 at 16:38:25 UTC, Damian wrote:

I've noticed a few languages are adopting this, for example
Haskell: http://tryhaskell.org
Go: http://play.golang.org

Will D get something like this? I find it to be of great use
with Go specifically and I'm sure it would benefit D just as 
much.


Hey.

We are working on something like that.
http://dpaste.dzfl.pl/

At the end we want also to share an API to allow users to use 
service on
their own like in the GO Lang website etc, where you can click 
Try it
now (actually its already done via "Compile" button, where 
request is

sent via AJAX).

(Warning: Compiler section is actually dummy-filled, at the 
moment only

dmd2.059 is avaible).



Very nice.

Why do you use radio buttons in the 'Libraries' section though?
Those are not mutually exclusive.


The thing is, we want also provide support for D1, where Tango 
excludes Phobos and vice-versa.


I am not sure yet how we should handle it, maybe some JS-magic, 
which would replace checkbox for radiobox when using D1, or just 
ignoring 2nd choice when using D1.


This is cosmetic change though, can be done anytime (backend 
supports both libraries in same time)


Re: Shared objects?

2012-06-18 Thread Wouter Verhelst
Jacob Carlborg  writes:

> On 2012-06-18 16:56, Wouter Verhelst wrote:
>> However, what
>> I don't find is the answer to the two following questions:
>>
>> - Does D support dlopen(), or some similar mechanism, to allow me to
>>load plugins at runtime?
>
> Yes. You can compile D code to a standard dynamic library, just as you
> would using C.

Cool.

>> - If it does, does Object.factory() still work for new classes loaded in
>>through dlopen() (or its functional equivalence)?
>
> No.
>
> Dynamic libraries are currently not working properly in D. The runtime
> needs to be updated to handle it. There are some problem with module
> info, exception handling tables and TLS. There might be some problem
> left with PIC as well.
>
> This is worked on and hopefully we will have a solution not too far in
> the future.

Ah, too bad.

Do you have a pointer to some more detailed information on this? Just so
I can get a feel for how fast things are moving, and/or whether it's
worth for me to wait for that -- I can get started on the other parts;
while the plugin architecture would be crucial eventually, it's not
something I'll need from the very beginning.

Thanks,

-- 
The volume of a pizza of thickness a and radius z can be described by
the following formula:

pi zz a


Re: How to break const

2012-06-18 Thread deadalnix

Le 18/06/2012 17:16, Mehrdad a écrit :

On Monday, 18 June 2012 at 15:13:33 UTC, deadalnix wrote:

Identical calls giving identical results? What?


import std.stdio;
struct S
{
this(int a)
{
this.a = a;
this.increment = { return this.a++; };
}
int a;
int delegate() pure increment;
auto oops() const { return this.increment(); }
}
void main()
{
auto c = immutable(S)(0);
writeln(c.oops()); // 0
writeln(c.oops()); // 1
writeln(c.oops()); // 2
writeln(c.oops()); // 3
writeln(c.oops()); // 4
writeln(c.oops()); // 5
}


They are not call with the same parameters. The hidden parameter have
changed (I know this is tricky).



Explain it however you want.

The bottom line I'm getting at is, you can't re-order the calls, EVEN IF
by "looking at them" you can tell they're pure @safe nothrow const...


Yes, but this isn't a problem with pure here, this is a problem with const.

The sample code should not compile.


Re: How to break const

2012-06-18 Thread Mehrdad

On Monday, 18 June 2012 at 15:13:33 UTC, deadalnix wrote:

Identical calls giving identical results? What?


import std.stdio;
struct S
{
this(int a)
{
this.a = a;
this.increment = { return this.a++; };
}
int a;
int delegate() pure increment;
auto oops() const { return this.increment(); }
}
void main()
{
auto c = immutable(S)(0);
writeln(c.oops()); // 0
writeln(c.oops()); // 1
writeln(c.oops()); // 2
writeln(c.oops()); // 3
writeln(c.oops()); // 4
writeln(c.oops()); // 5
}


They are not call with the same parameters. The hidden 
parameter have changed (I know this is tricky).



Explain it however you want.

The bottom line I'm getting at is, you can't re-order the calls, 
EVEN IF by "looking at them" you can tell they're pure @safe 
nothrow const...


Re: How to break const

2012-06-18 Thread deadalnix

Le 18/06/2012 16:55, Mehrdad a écrit :

On Monday, 18 June 2012 at 14:48:37 UTC, deadalnix wrote:

Le 18/06/2012 16:44, Mehrdad a écrit :

Interesting, making the delegate `pure' doesn't change anything either.

So 'pure' doesn't let you "infer something just by looking at the code
either", right?


It does ! It tell you that the function have no side effect, and that
the function called with identical arguments will return identical
results.

pure will not ensure constness or immutability. const and immutable
are made for that.

The fact that D decouple purity and immutability is a very nice design
decision and is explained nicely here :
http://klickverbot.at/blog/2012/05/purity-in-d/




Identical calls giving identical results? What?


import std.stdio;
struct S
{
this(int a)
{
this.a = a;
this.increment = { return this.a++; };
}
int a;
int delegate() pure increment;
auto oops() const { return this.increment(); }
}
void main()
{
auto c = immutable(S)(0);
writeln(c.oops()); // 0
writeln(c.oops()); // 1
writeln(c.oops()); // 2
writeln(c.oops()); // 3
writeln(c.oops()); // 4
writeln(c.oops()); // 5
}


They are not call with the same parameters. The hidden parameter have 
changed (I know this is tricky).


Re: How to break const

2012-06-18 Thread Mehrdad

On Monday, 18 June 2012 at 15:11:00 UTC, Timon Gehr wrote:

On 06/18/2012 04:55 PM, Mehrdad wrote:


Identical calls giving identical results? What?


import std.stdio;
struct S
{
 this(int a)
 {
 this.a = a;
 this.increment = { return this.a++; };
 }
 int a;
 int delegate() pure increment;
 auto oops() const { return this.increment(); }
}
void main()
{
 auto c = immutable(S)(0);
 writeln(c.oops()); // 0
 writeln(c.oops()); // 1
 writeln(c.oops()); // 2
 writeln(c.oops()); // 3
 writeln(c.oops()); // 4
 writeln(c.oops()); // 5
}


Now you have managed to break the type system.
The underlying issue is unrelated to delegates though.




Yeah, I didn't mean to say it's a delegate issue either. That's 
why the title was saying "how to break _const_". Delegates were 
just a means to an end. :)



So (**IMHO**) if that's really the case, we should really spend 
some time fixing the /design/ of const before the 
implementation... good idea or no?


Re: How to break const

2012-06-18 Thread Christophe Travert
Matthias Walter , dans le message (digitalmars.D:170036), a écrit :
> On 06/18/2012 07:36 AM, Mehrdad wrote:
>> Is it just me, or did I subvert the type system here?
>> 
>> 
>> import std.stdio;
>> 
>> struct Const
>> {
>> this(void delegate() increment)
>> { this.increment = increment; }
>> int a;
>> void delegate() increment;
>> void oops() const { this.increment(); }
>> }
>> 
>> void main()
>> {
>> Const c;
>> c = Const({ c.a++; });
>> writeln(c.a);
>> c.oops();
>> writeln(c.a);
>> }
>> 
> 
> I don't think so. When calling oops you have two references to the object c:
> 
> - The this-pointer of the object itself which is not allowed to change
> the object in the const-call.
> - The reference from within main which is allowed to change it and can
> be reached via the frame pointer of the delegate.
> 
> I see this as perfectly valid code. Of course, opinions may differ here.

But here, the frame pointer of the delegate is part of the const 
structure. By transitivity, the frame pointer should be const, and 
therefore, calling the delegate (which modifies the frame pointer) 
should not be legal.

To be callable from a const method (oops), the member delegate 
(increment) should be of type "void delegate() const". This type exists, 
but is not easy to get[1]. Because constness of frame pointers is not 
implemented as it should be[2], there is a hole in the const system.

[1] AFAIK, it can only be got by making an explicit delegate like 
&struct.const_method
[2] Just like pure and no_throw attributes are complicated to work with 
delegates, the const attribute would be a mess to use at the moment.

-- 
Christophe


Re: How to break const

2012-06-18 Thread Timon Gehr

On 06/18/2012 04:33 PM, deadalnix wrote:

Le 18/06/2012 15:03, Timon Gehr a écrit :

On 06/18/2012 02:45 PM, deadalnix wrote:

Le 18/06/2012 07:59, Matthias Walter a écrit :

On 06/18/2012 07:36 AM, Mehrdad wrote:

Is it just me, or did I subvert the type system here?


import std.stdio;

struct Const
{
this(void delegate() increment)
{ this.increment = increment; }
int a;
void delegate() increment;
void oops() const { this.increment(); }
}

void main()
{
Const c;
c = Const({ c.a++; });
writeln(c.a);
c.oops();
writeln(c.a);
}



I don't think so. When calling oops you have two references to the
object c:

- The this-pointer of the object itself which is not allowed to change
the object in the const-call.
- The reference from within main which is allowed to change it and can
be reached via the frame pointer of the delegate.

I see this as perfectly valid code. Of course, opinions may differ
here.

Matthias


The hidden parameter of the delegate is stored in c. This hidden
parameter must be qualified with const when c is made const, for
transitivity. However, it isn't.

In short :
- c is made const
- the frame pointer is stored in c
- the frame pointer must be made const for transitivity.

=> The type system is broken. You'll find many examples of this behavior
with delegates.


The type system is not broken. You cannot modify an immutable object
using this behaviour. Delegates are type checked once and for all when
they are declared. Transitive const does not necessarily need to
apply to their context pointers. I think it is useful to reason about
delegates at a higher abstraction level than function pointer and
context pointer.



You cannot use this to modify immutable data, granted.

But you can use that to break transitivity (ie, make immutable data
refers mutable datas). It have many hidden traps. For instance, data
that isn't shared or immutable can be shared anyway between thread throw
delegates.

Not being able to ensure transitivity with delegate break all benefit of
transitivity.

However, delegate is a special beast, because it cannot be safely «
constified », but can be safely « unconstified ».



The issue is that immutable objects can contain impure delegates as 
fields. This should probably be banned.





Re: DMD + msvc

2012-06-18 Thread Iain Buclaw
On 18 June 2012 16:08, Manu  wrote:
> On 18 June 2012 11:38, Kagamin  wrote:
>>
>> On Sunday, 17 June 2012 at 10:49:30 UTC, Gor Gyolchanyan wrote:
>>>
>>> Thanks for the reply.
>>> This is so ridiculous and frustrating.
>>
>>
>> Use GDC?
>
>
> I use GDC now. It produces COFF objects, and is technically capable of
> linking against MSVC code, except the 2 compilers expect different runtimes.
> You have to be REALLY careful with your GDC code to make sure it doesn't
> produce implicit calls into the GNU runtime, otherwise you'll get link
> conflicts.
> You can afford some really standard runtime calls that are also present in
> the mscrt, and it'll just link to those instead of the gnu ones.
>
> I have successfully build small scale projects with GDC linking against MSVC
> code, but there's a long list of problems and gotchas...
> My current approach is to build D code into DLL's and dynamically link
> against my MSVC code, or vice-versa.
>
> Hopefully the new 64bit dmd comes soon :)

DMD would be linking against it's own runtime on windows too, rather
than msvc runtime, iirc. So you may have similar problems there too.


-- 
Iain Buclaw

*(p < e ? p++ : p) = (c & 0x0f) + '0';


Re: How to break const

2012-06-18 Thread deadalnix

Le 18/06/2012 16:51, Andrei Alexandrescu a écrit :

Mehrdad posted a code sample and you replied to it with what I could
only assume was an explanation of the code's behavior. I hope you'd
agree it was a reasonable assumption, whether or not it was correct.

The problem at work here is that "this" is typed incorrectly during the
construction of a qualified object. It should go progressively from a
"raw" to a "cooked" state, and cannot be passed to any function while raw.


I've however made other posts to explain why
transitivity is broken when it comes to delegate.


I looked at your posts through June and couldn't find such, so a couple
of links would be great. Of course, bug reports would be even better!



I'm not sure you are talking about the proposal or the transitivity 
issue here. I'll explain the proposal below, for the explaination of why 
the transitivity is broken, see : 
http://forum.dlang.org/thread/ywispsasaylqscyua...@forum.dlang.org?page=2#post-jrn7sv:24jjj:241:40digitalmars.com



To explain my proposal, I have to make several thing clear first. You 
have here 2 things to qualify : the delegate itself, and the hidden 
parameter. As type qualifier are transitive in D, qualify the delegate 
also transitively qualify the hidden parameter.


The proposal was to use postfix qualifier notation to qualify the hidden 
parameter, and qualifier between return type and delegate keyword to 
qualify the delegate itself. My original proposal stated that the type 
qualifier before the return type qualify the return type, but this is 
another topic.


To make is clearer, some examples :

void delegate() const; // A mutable delegate that use const frame 
pointer (all variable accessed throw the frame pointer are made const).
void const delegate(); // A const delegate that use a const frame 
pointer (transitivity).
void const delegate() immutable; // A const delegate that use an 
immutable frame pointer (delegate can only access immutable data from 
the frame pointer).
void immutable delegate() const; // Error, immutable data cannot refers 
to const data.


Note that the implicit cast goes the other way around than usual. void 
delegate() const can be safely casted to void delegate(), but not the 
other way around, as you are allowed to not mutate mutable data, but not 
the other way around.


Re: How to break const

2012-06-18 Thread Timon Gehr

On 06/18/2012 04:55 PM, Mehrdad wrote:


Identical calls giving identical results? What?


import std.stdio;
struct S
{
  this(int a)
  {
  this.a = a;
  this.increment = { return this.a++; };
  }
  int a;
  int delegate() pure increment;
  auto oops() const { return this.increment(); }
}
void main()
{
  auto c = immutable(S)(0);
  writeln(c.oops()); // 0
  writeln(c.oops()); // 1
  writeln(c.oops()); // 2
  writeln(c.oops()); // 3
  writeln(c.oops()); // 4
  writeln(c.oops()); // 5
}


Now you have managed to break the type system.
The underlying issue is unrelated to delegates though.


Re: D in your browser? possible?

2012-06-18 Thread Manu
On 17 June 2012 19:38, Damian  wrote:

> I've noticed a few languages are adopting this, for example
> Haskell: http://tryhaskell.org
> Go: http://play.golang.org
>
> Will D get something like this? I find it to be of great use
> with Go specifically and I'm sure it would benefit D just as much.
>

A friend of mine started this:
https://bitbucket.org/fearog/gdc-nacl

Chrome NaCl (http://en.wikipedia.org/wiki/Google_Native_Client) target for
GDC, to run realtime client-side D code in your browser! Yeah!

I'm sure he could use some help ;)


Re: DMD + msvc

2012-06-18 Thread Manu
On 18 June 2012 11:38, Kagamin  wrote:

> On Sunday, 17 June 2012 at 10:49:30 UTC, Gor Gyolchanyan wrote:
>
>> Thanks for the reply.
>> This is so ridiculous and frustrating.
>>
>
> Use GDC?
>

I use GDC now. It produces COFF objects, and is technically capable of
linking against MSVC code, except the 2 compilers expect different runtimes.
You have to be REALLY careful with your GDC code to make sure it doesn't
produce implicit calls into the GNU runtime, otherwise you'll get link
conflicts.
You can afford some really standard runtime calls that are also present in
the mscrt, and it'll just link to those instead of the gnu ones.

I have successfully build small scale projects with GDC linking against
MSVC code, but there's a long list of problems and gotchas...
My current approach is to build D code into DLL's and dynamically link
against my MSVC code, or vice-versa.

Hopefully the new 64bit dmd comes soon :)


Re: Shared objects?

2012-06-18 Thread Jacob Carlborg

On 2012-06-18 16:56, Wouter Verhelst wrote:

Hi group,

I've been reading up on D for the past few days--something I'd been
planning to do for quite a while--and find much to like and little to
dislike; as such, I am considering using it for my next project, which
would run on Linux (and possibly some other POSIX systems) and would
need to load plugins.

Now I've done such things in C in the past, and it's not too difficult:
you create a .so file, have it call some initial function right after
the dlopen(), and then have that initial function register the new
functionality available.

After looking at the documentation for a few days, I've come to the
conclusion that with Object.factory and interfaces, I believe I can
abstract things enough so that all a plugin would need to do is register
a new class, which could then be instantiated if needs be.


Yes, in theory.


However, what
I don't find is the answer to the two following questions:

- Does D support dlopen(), or some similar mechanism, to allow me to
   load plugins at runtime?


Yes. You can compile D code to a standard dynamic library, just as you 
would using C.



- If it does, does Object.factory() still work for new classes loaded in
   through dlopen() (or its functional equivalence)?


No.

Dynamic libraries are currently not working properly in D. The runtime 
needs to be updated to handle it. There are some problem with module 
info, exception handling tables and TLS. There might be some problem 
left with PIC as well.


This is worked on and hopefully we will have a solution not too far in 
the future.


--
/Jacob Carlborg


Re: D in your browser? possible?

2012-06-18 Thread Timon Gehr

On 06/18/2012 03:47 PM, nazriel wrote:

On Sunday, 17 June 2012 at 16:38:25 UTC, Damian wrote:

I've noticed a few languages are adopting this, for example
Haskell: http://tryhaskell.org
Go: http://play.golang.org

Will D get something like this? I find it to be of great use
with Go specifically and I'm sure it would benefit D just as much.


Hey.

We are working on something like that.
http://dpaste.dzfl.pl/

At the end we want also to share an API to allow users to use service on
their own like in the GO Lang website etc, where you can click Try it
now (actually its already done via "Compile" button, where request is
sent via AJAX).

(Warning: Compiler section is actually dummy-filled, at the moment only
dmd2.059 is avaible).



Very nice.

Why do you use radio buttons in the 'Libraries' section though?
Those are not mutually exclusive.



Re: DMD + msvc

2012-06-18 Thread Manu
On 17 June 2012 13:49, Gor Gyolchanyan  wrote:

> On Sun, Jun 17, 2012 at 2:34 PM, Jacob Carlborg  wrote:
> > On 2012-06-17 07:15, Gor Gyolchanyan wrote:
> >>
> >> Is it possible to use the VC2010 linker with DMD? That would allow
> >> easily linking with COFF libraries and building 64 bit binaries.
> >
> >
> > No.
> >
> > 1. DMD can only output OMF binaries
> > 2. DMD cannot output 64bit code for Windows
> > 3. DMD is not compatible with the MSVC linker or runtime
> >
> > --
> > /Jacob Carlborg
>
> Thanks for the reply.
> This is so ridiculous and frustrating.
>

I've been bugging Walter for this for months, and the word on the street is
that he's working on it now :)
Intention is to support the MS linker and runtimes (which is what I need
too).


Re: How to break const

2012-06-18 Thread Mehrdad

On Monday, 18 June 2012 at 14:55:42 UTC, Mehrdad wrote:

Identical calls giving identical results? What?


import std.stdio;
struct S
{
 this(int a)
 {
 this.a = a;
 this.increment = { return this.a++; };
 }
 int a;
 int delegate() pure increment;
 auto oops() const { return this.increment(); }
}
void main()
{
 auto c = immutable(S)(0);
 writeln(c.oops()); // 0
 writeln(c.oops()); // 1
 writeln(c.oops()); // 2
 writeln(c.oops()); // 3
 writeln(c.oops()); // 4
 writeln(c.oops()); // 5
}




Heck, make that all @safe pure nothrow:

 int delegate() pure @safe nothrow increment;
 auto oops() pure const @safe nothrow { return 
this.increment(); }


Shared objects?

2012-06-18 Thread Wouter Verhelst
Hi group,

I've been reading up on D for the past few days--something I'd been
planning to do for quite a while--and find much to like and little to
dislike; as such, I am considering using it for my next project, which
would run on Linux (and possibly some other POSIX systems) and would
need to load plugins.

Now I've done such things in C in the past, and it's not too difficult:
you create a .so file, have it call some initial function right after
the dlopen(), and then have that initial function register the new
functionality available.

After looking at the documentation for a few days, I've come to the
conclusion that with Object.factory and interfaces, I believe I can
abstract things enough so that all a plugin would need to do is register
a new class, which could then be instantiated if needs be. However, what
I don't find is the answer to the two following questions:

- Does D support dlopen(), or some similar mechanism, to allow me to
  load plugins at runtime?
- If it does, does Object.factory() still work for new classes loaded in
  through dlopen() (or its functional equivalence)?

Thanks,

-- 
The volume of a pizza of thickness a and radius z can be described by
the following formula:

pi zz a


Re: How to break const

2012-06-18 Thread Artur Skawina
On 06/18/12 16:41, deadalnix wrote:
> Le 18/06/2012 16:28, Artur Skawina a écrit :
>> It's fine, if you view a delegate as opaque.
>>
> 
> No it isn't. You cannot ensure transitivity anywhere. This have obvious, and 
> severe drawback for concurrent programing (implicit sharing is back) and GC 
> performances (GC can eb crazy fast when it come to transitive immutable data, 
> see OCaml's GC performances for instance).
> 
>> 'this' being const does not preclude accessing the object that 'this'
>> points to via another, mutable, reference.
>>
>> Consider the alternative - you'd have to forbid storing any delegate
>> with a non-const non-value argument inside any object.

So how would you like to handle this? And, no, allowing only the cases
that /can/ be statically checked is not ok - it would result in black
magic - delegates would be accepted or not depending on the contents
of the object (think templates and composition).

>> And "breaking" const would then _still_ be possible and trivial.
>>
> 
> No, and your example don't demonstrate that in any way. Transitivity is 
> maintained in the example below, because g isn't a member of s, and if it 
> were, then the example would break at compile time.

The word "breaking" is in quotes for a reason. Const is not an immutability
guarantee. If you treat delegates as opaque then there's no practical
difference between using them or accessing the data via another external
reference.

> purity is another beast altogether.

D's "weak pure" can help; I just don't like the redefinition of the term
"purity"; another name for "weak purity" would be better.

artur


Re: How to break const

2012-06-18 Thread Mehrdad

On Monday, 18 June 2012 at 14:48:37 UTC, deadalnix wrote:

Le 18/06/2012 16:44, Mehrdad a écrit :
Interesting, making the delegate `pure' doesn't change 
anything either.


So 'pure' doesn't let you "infer something just by looking at 
the code

either", right?


It does ! It tell you that the function have no side effect, 
and that the function called with identical arguments will 
return identical results.


pure will not ensure constness or immutability. const and 
immutable are made for that.


The fact that D decouple purity and immutability is a very nice 
design decision and is explained nicely here : 
http://klickverbot.at/blog/2012/05/purity-in-d/




Identical calls giving identical results? What?


import std.stdio;
struct S
{
 this(int a)
 {
 this.a = a;
 this.increment = { return this.a++; };
 }
 int a;
 int delegate() pure increment;
 auto oops() const { return this.increment(); }
}
void main()
{
 auto c = immutable(S)(0);
 writeln(c.oops()); // 0
 writeln(c.oops()); // 1
 writeln(c.oops()); // 2
 writeln(c.oops()); // 3
 writeln(c.oops()); // 4
 writeln(c.oops()); // 5
}


Re: How to break const

2012-06-18 Thread Andrei Alexandrescu

On 6/18/12 9:45 AM, deadalnix wrote:

Le 18/06/2012 16:43, Andrei Alexandrescu a écrit :

On 6/18/12 7:43 AM, deadalnix wrote:

Le 18/06/2012 07:36, Mehrdad a écrit :

Is it just me, or did I subvert the type system here?



delegate fail to ensure transitivity of type qualifier. This is no news.
This is however a big error.

I proposed a fix to that by changing the semantic of the type qualifier
depending on its position in the declaration, but didn't received much
feedback at the time.


I don't think that's the correct explanation.

Andrei



I fail to understand what you mean here. This post ins't supposed to
explain anything.


Mehrdad posted a code sample and you replied to it with what I could 
only assume was an explanation of the code's behavior. I hope you'd 
agree it was a reasonable assumption, whether or not it was correct.


The problem at work here is that "this" is typed incorrectly during the 
construction of a qualified object. It should go progressively from a

"raw" to a "cooked" state, and cannot be passed to any function while raw.


I've however made other posts to explain why
transitivity is broken when it comes to delegate.


I looked at your posts through June and couldn't find such, so a couple 
of links would be great. Of course, bug reports would be even better!



Andrei


Re: How to break const

2012-06-18 Thread deadalnix

Le 18/06/2012 16:44, Mehrdad a écrit :

Interesting, making the delegate `pure' doesn't change anything either.

So 'pure' doesn't let you "infer something just by looking at the code
either", right?


It does ! It tell you that the function have no side effect, and that 
the function called with identical arguments will return identical results.


pure will not ensure constness or immutability. const and immutable are 
made for that.


The fact that D decouple purity and immutability is a very nice design 
decision and is explained nicely here : 
http://klickverbot.at/blog/2012/05/purity-in-d/


Re: How to break const

2012-06-18 Thread Mehrdad

On Monday, 18 June 2012 at 14:41:02 UTC, deadalnix wrote:

Le 18/06/2012 16:28, Artur Skawina a écrit :

It's fine, if you view a delegate as opaque.



No it isn't. You cannot ensure transitivity anywhere. This have 
obvious, and severe drawback for concurrent programing 
(implicit sharing is back) and GC performances (GC can eb crazy 
fast when it come to transitive immutable data, see OCaml's GC 
performances for instance).


'this' being const does not preclude accessing the object that 
'this'

points to via another, mutable, reference.

Consider the alternative - you'd have to forbid storing any 
delegate

with a non-const non-value argument inside any object.

And "breaking" const would then _still_ be possible and 
trivial.




No, and your example don't demonstrate that in any way. 
Transitivity is maintained in the example below, because g 
isn't a member of s, and if it were, then the example would 
break at compile time.



   import std.stdio;

   S*[const(S)*] g;

   struct S {
  int i;
  this(int i) { this.i = i; g[&this] =&this; }
  void f() const { g[&this].i=666; }
   }

   void main() {
  const s = S(42);
  writeln(s);
  s.f();
  writeln(s);
   }

Yes, D's "pure" could help here, only it's misnamed (even if in
this particular case that term would be fitting).



purity is another beast altogether.




Interesting, making the delegate `pure' doesn't change anything 
either.


So 'pure' doesn't let you "infer something just by looking at the 
code either", right?


Re: How to break const

2012-06-18 Thread Andrei Alexandrescu

On 6/18/12 7:43 AM, deadalnix wrote:

Le 18/06/2012 07:36, Mehrdad a écrit :

Is it just me, or did I subvert the type system here?



delegate fail to ensure transitivity of type qualifier. This is no news.
This is however a big error.

I proposed a fix to that by changing the semantic of the type qualifier
depending on its position in the declaration, but didn't received much
feedback at the time.


I don't think that's the correct explanation.

Andrei



Re: How to break const

2012-06-18 Thread deadalnix

Le 18/06/2012 16:43, Andrei Alexandrescu a écrit :

On 6/18/12 7:43 AM, deadalnix wrote:

Le 18/06/2012 07:36, Mehrdad a écrit :

Is it just me, or did I subvert the type system here?



delegate fail to ensure transitivity of type qualifier. This is no news.
This is however a big error.

I proposed a fix to that by changing the semantic of the type qualifier
depending on its position in the declaration, but didn't received much
feedback at the time.


I don't think that's the correct explanation.

Andrei



I fail to understand what you mean here. This post ins't supposed to 
explain anything. I've however made other posts to explain why 
transitivity is broken when it comes to delegate.


Re: How to break const

2012-06-18 Thread Mehrdad

On Monday, 18 June 2012 at 12:43:04 UTC, deadalnix wrote:

Le 18/06/2012 07:36, Mehrdad a écrit :

Is it just me, or did I subvert the type system here?



delegate fail to ensure transitivity of type qualifier. This is 
no news. This is however a big error.



Oh lol :( thought I'd discovered something.

Well in that case, shouldn't the system protect itself then?

Otherwise it seems like 'const' in D becomes just like C++ const 
(doesn't let you "prove" anything)...



I proposed a fix to that by changing the semantic of the type 
qualifier depending on its position in the declaration, but 
didn't received much feedback at the time.


Interesting!


Re: How to break const

2012-06-18 Thread deadalnix

Le 18/06/2012 16:28, Artur Skawina a écrit :

It's fine, if you view a delegate as opaque.



No it isn't. You cannot ensure transitivity anywhere. This have obvious, 
and severe drawback for concurrent programing (implicit sharing is back) 
and GC performances (GC can eb crazy fast when it come to transitive 
immutable data, see OCaml's GC performances for instance).



'this' being const does not preclude accessing the object that 'this'
points to via another, mutable, reference.

Consider the alternative - you'd have to forbid storing any delegate
with a non-const non-value argument inside any object.

And "breaking" const would then _still_ be possible and trivial.



No, and your example don't demonstrate that in any way. Transitivity is 
maintained in the example below, because g isn't a member of s, and if 
it were, then the example would break at compile time.



import std.stdio;

S*[const(S)*] g;

struct S {
   int i;
   this(int i) { this.i = i; g[&this] =&this; }
   void f() const { g[&this].i=666; }
}

void main() {
   const s = S(42);
   writeln(s);
   s.f();
   writeln(s);
}

Yes, D's "pure" could help here, only it's misnamed (even if in
this particular case that term would be fitting).



purity is another beast altogether.


Re: How to break const

2012-06-18 Thread Mehrdad
On Monday, 18 June 2012 at 14:37:26 UTC, Andrei Alexandrescu 
wrote:

On 6/18/12 1:35 AM, Matthias Walter wrote:

On 06/18/2012 08:19 AM, Mehrdad wrote:
On Monday, 18 June 2012 at 06:14:22 UTC, Matthias Walter 
wrote:

Its not, that a const method cannot modify an object, it just
ensures that the const method cannot modify the object *by 
using

the this-pointer*.




I see...


So that means you /can't/ tell something just by looking at a 
part

of the code, right?

(Just mentioning this since this idea seemed to be emphasized 
a lot

by D.)


Yes, you are right with that.


Actually things are a fair amount subtler. On the face of it, 
immutable does fulfill the OP's expectation. But even for const 
code, there's still a lot of guarantees that can be inferred 
depending on the types involved.


Andrei


Changing "new const(S)(0);" to "new immutable(S)(0);" still 
doesn't work tho.


Re: How to break const

2012-06-18 Thread Andrei Alexandrescu

On 6/18/12 2:14 AM, Mehrdad wrote:

Okay, how about this? http://ideone.com/VMlzS

Does this break const?


import std.stdio;
class S
{
this(int a)
{
this.a = a;
this.increment = { this.a++; };
}
int a;
void delegate() increment;
void oops() const { this.increment(); }
}
void main()
{
auto c = new const(S)(0);
writeln(c.a);
c.oops();
writeln(c.a);
}


Yes. Currently the constructor is not typechecked properly. Kenji has 
done some work on that and is still blocked by me and Walter with some 
questions.


Andrei


Re: How to break const

2012-06-18 Thread Andrei Alexandrescu

On 6/18/12 1:35 AM, Matthias Walter wrote:

On 06/18/2012 08:19 AM, Mehrdad wrote:

On Monday, 18 June 2012 at 06:14:22 UTC, Matthias Walter wrote:

Its not, that a const method cannot modify an object, it just
ensures that the const method cannot modify the object *by using
the this-pointer*.




I see...


So that means you /can't/ tell something just by looking at a part
of the code, right?

(Just mentioning this since this idea seemed to be emphasized a lot
by D.)


Yes, you are right with that.


Actually things are a fair amount subtler. On the face of it, immutable 
does fulfill the OP's expectation. But even for const code, there's 
still a lot of guarantees that can be inferred depending on the types 
involved.


Andrei



Re: How to break const

2012-06-18 Thread deadalnix

Le 18/06/2012 15:03, Timon Gehr a écrit :

On 06/18/2012 02:45 PM, deadalnix wrote:

Le 18/06/2012 07:59, Matthias Walter a écrit :

On 06/18/2012 07:36 AM, Mehrdad wrote:

Is it just me, or did I subvert the type system here?


import std.stdio;

struct Const
{
this(void delegate() increment)
{ this.increment = increment; }
int a;
void delegate() increment;
void oops() const { this.increment(); }
}

void main()
{
Const c;
c = Const({ c.a++; });
writeln(c.a);
c.oops();
writeln(c.a);
}



I don't think so. When calling oops you have two references to the
object c:

- The this-pointer of the object itself which is not allowed to change
the object in the const-call.
- The reference from within main which is allowed to change it and can
be reached via the frame pointer of the delegate.

I see this as perfectly valid code. Of course, opinions may differ here.

Matthias


The hidden parameter of the delegate is stored in c. This hidden
parameter must be qualified with const when c is made const, for
transitivity. However, it isn't.

In short :
- c is made const
- the frame pointer is stored in c
- the frame pointer must be made const for transitivity.

=> The type system is broken. You'll find many examples of this behavior
with delegates.


The type system is not broken. You cannot modify an immutable object
using this behaviour. Delegates are type checked once and for all when
they are declared. Transitive const does not necessarily need to
apply to their context pointers. I think it is useful to reason about
delegates at a higher abstraction level than function pointer and
context pointer.



You cannot use this to modify immutable data, granted.

But you can use that to break transitivity (ie, make immutable data 
refers mutable datas). It have many hidden traps. For instance, data 
that isn't shared or immutable can be shared anyway between thread throw 
delegates.


Not being able to ensure transitivity with delegate break all benefit of 
transitivity.


However, delegate is a special beast, because it cannot be safely « 
constified », but can be safely « unconstified ».


Re: How to break const

2012-06-18 Thread Artur Skawina
On 06/18/12 14:45, deadalnix wrote:
> Le 18/06/2012 07:59, Matthias Walter a écrit :
>> On 06/18/2012 07:36 AM, Mehrdad wrote:
>>> Is it just me, or did I subvert the type system here?
>>>
>>>
>>> import std.stdio;
>>>
>>> struct Const
>>> {
>>>  this(void delegate() increment)
>>>  { this.increment = increment; }
>>>  int a;
>>>  void delegate() increment;
>>>  void oops() const { this.increment(); }
>>> }
>>>
>>> void main()
>>> {
>>>  Const c;
>>>  c = Const({ c.a++; });
>>>  writeln(c.a);
>>>  c.oops();
>>>  writeln(c.a);
>>> }
>>>
>>
>> I don't think so. When calling oops you have two references to the object c:
>>
>> - The this-pointer of the object itself which is not allowed to change
>> the object in the const-call.
>> - The reference from within main which is allowed to change it and can
>> be reached via the frame pointer of the delegate.
>>
>> I see this as perfectly valid code. Of course, opinions may differ here.
>>
>> Matthias
> 
> The hidden parameter of the delegate is stored in c. This hidden parameter 
> must be qualified with const when c is made const, for transitivity. However, 
> it isn't.
> 
> In short :
> - c is made const
> - the frame pointer is stored in c
> - the frame pointer must be made const for transitivity.
> 
> => The type system is broken. You'll find many examples of this behavior with 
> delegates.

It's fine, if you view a delegate as opaque.

'this' being const does not preclude accessing the object that 'this'
points to via another, mutable, reference.

Consider the alternative - you'd have to forbid storing any delegate
with a non-const non-value argument inside any object.

And "breaking" const would then _still_ be possible and trivial.

   import std.stdio;

   S*[const(S)*] g;

   struct S {
  int i;
  this(int i) { this.i = i; g[&this] = &this; }
  void f() const { g[&this].i=666; }
   }

   void main() {
  const s = S(42);
  writeln(s);
  s.f();
  writeln(s);
   }

Yes, D's "pure" could help here, only it's misnamed (even if in
this particular case that term would be fitting).

artur


Re: D in your browser? possible?

2012-06-18 Thread nazriel

On Sunday, 17 June 2012 at 16:38:25 UTC, Damian wrote:

I've noticed a few languages are adopting this, for example
Haskell: http://tryhaskell.org
Go: http://play.golang.org

Will D get something like this? I find it to be of great use
with Go specifically and I'm sure it would benefit D just as 
much.


Hey.

We are working on something like that.
http://dpaste.dzfl.pl/

At the end we want also to share an API to allow users to use 
service on their own like in the GO Lang website etc, where you 
can click Try it now (actually its already done via "Compile" 
button, where request is sent via AJAX).


(Warning: Compiler section is actually dummy-filled, at the 
moment only dmd2.059 is avaible).




Re: AST files instead of DI interface files for faster compilation and easier distribution

2012-06-18 Thread Don Clugston

On 17/06/12 00:37, Walter Bright wrote:

On 6/14/2012 1:03 AM, Don Clugston wrote:

It is for debug builds.

Iain's data indicates that it's only a few % of the time taken on
semantic1().
Do you have data that shows otherwise?


Nothing recent, it's mostly from my C++ compiler testing.


But you argued in your blog that C++ parsing is inherently slow, and 
you've fixed those problems in the design of D.

And as far as I can tell, you were extremely successful!
Parsing in D is very, very fast.


Yes, it is designed so you could just import a symbol table. It is done
as source code, however, because it's trivial to implement.


It has those nasty side-effects listed under (3) though.


I don't think they're nasty or are side effects.


They are new problems which people ask for solutions for. And they are 
far more difficult to solve than the original problem.


Re: How to break const

2012-06-18 Thread Timon Gehr

On 06/18/2012 02:45 PM, deadalnix wrote:

Le 18/06/2012 07:59, Matthias Walter a écrit :

On 06/18/2012 07:36 AM, Mehrdad wrote:

Is it just me, or did I subvert the type system here?


import std.stdio;

struct Const
{
 this(void delegate() increment)
 { this.increment = increment; }
 int a;
 void delegate() increment;
 void oops() const { this.increment(); }
}

void main()
{
 Const c;
 c = Const({ c.a++; });
 writeln(c.a);
 c.oops();
 writeln(c.a);
}



I don't think so. When calling oops you have two references to the
object c:

- The this-pointer of the object itself which is not allowed to change
the object in the const-call.
- The reference from within main which is allowed to change it and can
be reached via the frame pointer of the delegate.

I see this as perfectly valid code. Of course, opinions may differ here.

Matthias


The hidden parameter of the delegate is stored in c. This hidden
parameter must be qualified with const when c is made const, for
transitivity. However, it isn't.

In short :
- c is made const
- the frame pointer is stored in c
- the frame pointer must be made const for transitivity.

=> The type system is broken. You'll find many examples of this behavior
with delegates.


The type system is not broken. You cannot modify an immutable object
using this behaviour. Delegates are type checked once and for all when
they are declared. Transitive const does not necessarily need to
apply to their context pointers. I think it is useful to reason about
delegates at a higher abstraction level than function pointer and
context pointer.




Re: valid uses of shared

2012-06-18 Thread Christophe Travert
"Steven Schveighoffer" , dans le message (digitalmars.D:169568), a
 écrit :
> On Thu, 07 Jun 2012 22:16:21 -0400, Robert DaSilva   
> wrote:
> 
> 
>> You're forgetting about Global data.
> 
> I wasn't so much forgetting it as I was ignoring it :)
> 
> My thought on that is that the shared keyword in that case is truly a  
> storage class.  It's the one place where having a value-type based shared  
> value makes sense.  If we had some kind of synchronized/shared pairing,  
> the compiler would have to allocate mutex space for that too.
> 
>> I think rather the head shared should be striped as this fits better  
>> with how D treats meaningless specifiers.
> 
> I don't think we can do that with type constructors, but I'm not sure.   
> I'm certainly against it, as I am against the current abuses of that  
> methodology.
> 
>> And trying to put structs that contain shared data on the stack should  
>> be illegal.

The compiler can already heap-allocate function variables that should be 
on the stack. So why disallowing shared for function variables?

void foo()
{
  shared int test; // allocates test on shared memory block.
}

Just like:
int delegate(int) adder(int a)
{
  return b => (a+b); // allocates a on the heap to make a closure.
}

-- 
Christophe


Re: How to break const

2012-06-18 Thread deadalnix

Le 18/06/2012 09:58, Jonathan M Davis a écrit :

On Monday, June 18, 2012 08:19:55 Mehrdad wrote:

On Monday, 18 June 2012 at 06:14:22 UTC, Matthias Walter wrote:

Its not, that a const method cannot modify an object, it just
ensures that the const method cannot modify the object *by
using the this-pointer*.


I see...


So that means you /can't/ tell something just by looking at a
part of the code, right?

(Just mentioning this since this idea seemed to be emphasized a
lot by D.)


You can if the function is pure as well, because then that delegate would not
be legal. For instance, this code

import std.stdio;

struct Const
{
 this(void delegate() pure increment)
 { this.increment = increment; }
 int a;
 void delegate() pure increment;
 void oops() const pure { this.increment(); }
}

void main()
{
 Const c;
 c = Const({ c.a++; });
 writeln(c.a);
 c.oops();
 writeln(c.a);
}


fails to compile, giving this error:

q.d(15): Error: constructor q.Const.this (void delegate() pure increment) is
not callable using argument types (void delegate() nothrow @safe)

All const guarantees is that the object isn't altered through the const
reference/pointer (which in the case of a const function is this). That's
powerful, but it needs pure as well to really be able to just glance at it and
know that it's not altering your object.

If you want an extreme exampl. you could create an object whose entire state
was held in a global variable, then the fact that the this pointer was const
wouldn't mean much. But if the member functions were pure, then you couldn't
access that global variable, and so that externalization of the state wouldn't
work, and you'd be guaranteed that the const function didn't alter your object
(as long as none of the arguments to that const function held a reference or
pointer to that object anyway (though that's a fairly abnormal thing to do) -
only strong purity absolutely guarantees that your object isn't being
altered).

- Jonathan M Davis


It would be true if the delegate wasn't stored in c. For instance, it is 
true if the delegate is passed as oops argument.


But in our case, the type system is broken. See explanations in other 
posts I've made in this thread.


Re: How to break const

2012-06-18 Thread deadalnix

Le 18/06/2012 07:36, Mehrdad a écrit :

Is it just me, or did I subvert the type system here?



delegate fail to ensure transitivity of type qualifier. This is no news. 
This is however a big error.


I proposed a fix to that by changing the semantic of the type qualifier 
depending on its position in the declaration, but didn't received much 
feedback at the time.




import std.stdio;

struct Const
{
this(void delegate() increment)
{ this.increment = increment; }
int a;
void delegate() increment;
void oops() const { this.increment(); }
}

void main()
{
Const c;
c = Const({ c.a++; });
writeln(c.a);
c.oops();
writeln(c.a);
}




Re: How to break const

2012-06-18 Thread deadalnix

Le 18/06/2012 07:59, Matthias Walter a écrit :

On 06/18/2012 07:36 AM, Mehrdad wrote:

Is it just me, or did I subvert the type system here?


import std.stdio;

struct Const
{
 this(void delegate() increment)
 { this.increment = increment; }
 int a;
 void delegate() increment;
 void oops() const { this.increment(); }
}

void main()
{
 Const c;
 c = Const({ c.a++; });
 writeln(c.a);
 c.oops();
 writeln(c.a);
}



I don't think so. When calling oops you have two references to the object c:

- The this-pointer of the object itself which is not allowed to change
the object in the const-call.
- The reference from within main which is allowed to change it and can
be reached via the frame pointer of the delegate.

I see this as perfectly valid code. Of course, opinions may differ here.

Matthias


The hidden parameter of the delegate is stored in c. This hidden 
parameter must be qualified with const when c is made const, for 
transitivity. However, it isn't.


In short :
- c is made const
- the frame pointer is stored in c
- the frame pointer must be made const for transitivity.

=> The type system is broken. You'll find many examples of this behavior 
with delegates.


Re: RandomSample with specified random number generator

2012-06-18 Thread Artur Skawina
On 06/18/12 10:40, Joseph Rushton Wakeling wrote:
> On 17/06/12 19:50, Artur Skawina wrote:
>> I took your random.d and ran with that:
>>
>> [6612, 6650, 6704, 0, 6629, 6834, 6634, 6756, 6590, 6591]
>> [6589, 6587, 6636, 0, 6673, 6704, 6647, 6704, 6643, 6817]
>> [6744, 6552, 6602, 0, 6641, 6722, 6598, 6676, 6749, 6716]
>> [6641, 6583, 6710, 0, 6618, 6684, 6789, 6673, 6683, 6619]
>> [6667, 6692, 6600, 0, 6717, 6588, 6660, 6678, 6673, 6725]
>>
>> so the problem is still there, just a little different.
>>
>> I'm using an old GDC build, in case that makes any difference:
>>
>> gcc version 4.6.3 20120106 (prerelease gdc 0.31 - r748:ab99d67f04c2, using 
>> dmd 2.057)
> 
> Just built my random.d with gdc 4.6.3 together with your test code.  Here's 
> what comes out:
> 
> [5954, 5896, 6018, 6004, 5978, 5963, 5959, 5970, 6151, 6107]
> [6020, 6044, 5914, 5994, 6110, 6064, 5969, 5985, 6002, 5898]
> [5877, 6021, 6022, 6054, 6075, 5967, 5998, 6010, 6023, 5953]
> [6059, 5968, 5972, 5908, 5982, 6034, 6189, 5909, 5982, 5997]
> [6006, 6077, 6011, 6037, 5823, 6062, 6022, 5925, 6065, 5972]
> [5877, 6006, 6005, 6049, 6013, 5971, 6053, 6023, 5902, 6101]
> [5946, 5984, 6006, 6018, 6049, 6097, 5993, 6030, 5922, 5955]
> [5992, 6071, 5974, 5993, 6066, 5974, 5897, 6017, 5951, 6065]
> [5975, 6127, 6103, 5889, 6000, 5949, 6003, 5849, 5974, 6131]
> [6005, 5937, 5920, 5978, 6032, 6003, 6023, 6064, 6086, 5952]
> 
> ... are you sure there's not something wrong in the way you added my random.d 
> to your test code?  I've sent a copy of my code to you privately so you can 
> test.

Your standalone version works fine.

For some reason the test fails as shown above when I replace the
std.random module with your version (same as the working test
program minus the runtime test), compile it and link my test with
the resulting random.o object.

artur


Re: Primary Ranges of Containers

2012-06-18 Thread Jonathan M Davis
On Monday, June 18, 2012 10:06:44 Matthias Walter wrote:
> Hi,
> 
> last week I realized that a const version of
> std.container.Array.opSlice() is missing. Now I looked at the code and I
> think that it is a general design problem.
> 
> The docs state that "c.Range" is "The primary range type associated with
> the container.". I think we really always need two Range types (one for
> const view and one for non-const view) by design.
> 
> I'd propose to always add a bool template parameter (maybe isConst?) to
> the range since most of the write-functionality can be "removed" by a
> static if statement in order to make the range read-only.
> 
> Any suggestions?

Yeah, it'll probably have to be templated. C++ already has to do something 
similar with iterators and const_iterators. But since you don't normally use 
the type of a range explicitly, it shouldn't be a big deal. The one downside 
that might pose a problem though is that if someone _does_ use the type 
explicitly, their code will break if the type gets templated. We could make a 
second type (ConstRange?) for the iterating over a const Array, but I'd be 
tempted to just templatize the thing and let it break any code that it breaks. 
std.container is already likely to break stuff to at least some extent when the 
custom allocators get added anyway. I suppose that we could just rename the 
type and then create an alias for the current type

struct ArrayRange(bool isConst) {...}
alias ArrayRange!false Range;
alias ArrayRange!true ConstRange;

but that might be overkill. I don't know. Regardless, it _is_ likely that the 
range type will have to be templatized to fix the problem. Ranges and range-
based functions in general need to be cleaned up a bit to deal with const, 
since the way that they're designed doesn't work with const very well, and we 
need to make it work. I think that it _can_ work, but it takes more effort to 
do so.

- Jonathan M Davis


Re: Segmented Ranges?

2012-06-18 Thread Christophe Travert
"bearophile" , dans le message (digitalmars.D:169611), a écrit :
> struct BilevelScan(Range) {

This is basically std.algorithm.joiner

> So an idea is to introduce in D the multi-level Ranges:
> SegmentedInputRange
> SegmentedOutputRange
> SegmentedForwardRange
> SegmentedBidirectionalRange
> SegmentedRandomAccessRange
> 
> I think a Segmented Input Range is more complex than an Input 
> Range. Inventing such ranges is like finding the miminal set of 
> axioms that allow to write down a theorem, that is to efficiently 
> implement the normal algorithms. This is not an easy for me, I 
> don't know much about this topic.

I would only use this axiom:
- a SegmentedRange defines a bySegment property, returning a Range of 
Range bearing the same element type as SegmentedRange.

and define BySegment!Range as the type returned by range.bySegment, and 
SegmentType!Range as the type returned by range.bySegment.front.

Then it is up to the implementer of the algorithm to test the type of 
a SegmentedRange (InputRange, OutputRange, etc.), the type of 
BySegment!Range, and the type of SegmentType!Range when needed. There 
are too many combinaisons to make specific range types for all of them.
Moreover SegmentedRandomAccessRange would be ambiguous: is it a 
RandomAccessRange, a Range whose BySegment method returns a 
RandomAccessRange, a Range whose SegmentType is a RandomAccessRange, 
or all of them ?

-- 
Christophe


Re: Proposal to add 'Elements of Programming' Concepts to std.traits

2012-06-18 Thread Denis Shelomovskij

16.06.2012 20:11, Walter Bright пишет:

On 6/16/2012 8:26 AM, Guillaume Chatelet wrote:

And then we wonder why software is
notorious for being delivered late and full of bugs, while other
engineers routinely deliver finished bridges, automobiles, electrical
appliances, etc., on time and with only minor defects.


I have a nit to pick with that statement, as a former mechanical
engineer who has done professional mechanical designs and has taken
apart a lot of others.

Bridges, automobiles, electrical appliances, etc., are full of design
errors.


You all probably know a canonical example, Tacoma Narrows Bridge:
http://www.youtube.com/watch?v=j-zczJXSxnw
Let's forgive its designers because it was the first such accident with 
bridge.


But in Russia we still (2010) have this:
http://www.youtube.com/watch?v=rVzYDIlBQ0w
And this bridge still works without rebuilding, but with attenuator now.


--
Денис В. Шеломовский
Denis V. Shelomovskij




Re: DMD + msvc

2012-06-18 Thread Kagamin

On Sunday, 17 June 2012 at 10:49:30 UTC, Gor Gyolchanyan wrote:

Thanks for the reply.
This is so ridiculous and frustrating.


Use GDC?


Re: RandomSample with specified random number generator

2012-06-18 Thread Joseph Rushton Wakeling

On 17/06/12 19:50, Artur Skawina wrote:

I took your random.d and ran with that:

[6612, 6650, 6704, 0, 6629, 6834, 6634, 6756, 6590, 6591]
[6589, 6587, 6636, 0, 6673, 6704, 6647, 6704, 6643, 6817]
[6744, 6552, 6602, 0, 6641, 6722, 6598, 6676, 6749, 6716]
[6641, 6583, 6710, 0, 6618, 6684, 6789, 6673, 6683, 6619]
[6667, 6692, 6600, 0, 6717, 6588, 6660, 6678, 6673, 6725]

so the problem is still there, just a little different.

I'm using an old GDC build, in case that makes any difference:

gcc version 4.6.3 20120106 (prerelease gdc 0.31 - r748:ab99d67f04c2, using dmd 
2.057)


Just built my random.d with gdc 4.6.3 together with your test code.  Here's what 
comes out:


[5954, 5896, 6018, 6004, 5978, 5963, 5959, 5970, 6151, 6107]
[6020, 6044, 5914, 5994, 6110, 6064, 5969, 5985, 6002, 5898]
[5877, 6021, 6022, 6054, 6075, 5967, 5998, 6010, 6023, 5953]
[6059, 5968, 5972, 5908, 5982, 6034, 6189, 5909, 5982, 5997]
[6006, 6077, 6011, 6037, 5823, 6062, 6022, 5925, 6065, 5972]
[5877, 6006, 6005, 6049, 6013, 5971, 6053, 6023, 5902, 6101]
[5946, 5984, 6006, 6018, 6049, 6097, 5993, 6030, 5922, 5955]
[5992, 6071, 5974, 5993, 6066, 5974, 5897, 6017, 5951, 6065]
[5975, 6127, 6103, 5889, 6000, 5949, 6003, 5849, 5974, 6131]
[6005, 5937, 5920, 5978, 6032, 6003, 6023, 6064, 6086, 5952]

... are you sure there's not something wrong in the way you added my random.d to 
your test code?  I've sent a copy of my code to you privately so you can test.




Re: How to break const

2012-06-18 Thread Jonathan M Davis
On Monday, June 18, 2012 09:14:59 Mehrdad wrote:
> Okay, how about this? http://ideone.com/VMlzS
> 
> Does this break const?
> 
> 
> import std.stdio;
> class S
> {
>  this(int a)
>  {
>  this.a = a;
>  this.increment = { this.a++; };
>  }
>  int a;
>  void delegate() increment;
>  void oops() const { this.increment(); }
> }
> void main()
> {
>  auto c = new const(S)(0);
>  writeln(c.a);
>  c.oops();
>  writeln(c.a);
> }

I'm not sure. I believe that it gets away with it, because none of the member 
variable are actually const until the constructor has completed, in which 
case, you've managed to hide away a non-const reference to what is supposed to 
be a const object. Technically, I don't think that it breaks const, but it 
does seem rather off. However, if the object isn't actually const until the 
constructor is complete, then it _is_ perfectly legimate.

Now, what worries me is that this seems to compile:

import std.stdio;
class S
{
 this(int a) immutable
 {
 this.a = a;
 this.increment = { this.a++; };
 }
 int a;
 void delegate() increment;
 void oops() const { this.increment(); }
}
void main()
{
 auto c = new const(S)(0);
 writeln(c.a);
 c.oops();
 writeln(c.a);
}

As I understand it, that should _not_ compile. An immutable constructor should 
disallow all mutation of member variables after their initial assignment 
within the constructor, but clearly that's not happening. It even allows 
adding

++a;

on its own inside of the constructor, so it's not just an issue with the 
delegate either.

- Jonathan M Davis


Primary Ranges of Containers

2012-06-18 Thread Matthias Walter
Hi,

last week I realized that a const version of
std.container.Array.opSlice() is missing. Now I looked at the code and I
think that it is a general design problem.

The docs state that "c.Range" is "The primary range type associated with
the container.". I think we really always need two Range types (one for
const view and one for non-const view) by design.

I'd propose to always add a bool template parameter (maybe isConst?) to
the range since most of the write-functionality can be "removed" by a
static if statement in order to make the range read-only.

Any suggestions?

Best regards,

Matthias


Re: How to break const

2012-06-18 Thread Mehrdad

On Monday, 18 June 2012 at 07:58:50 UTC, Jonathan M Davis wrote:
That's powerful, but it needs pure as well to really be able to 
just glance at it and know that it's not altering your object.



I see, so I need pure for the first example; thanks.


How about the second one though?


Re: How to break const

2012-06-18 Thread Mehrdad

On Monday, 18 June 2012 at 07:58:50 UTC, Jonathan M Davis wrote:
That's powerful, but it needs pure as well to really be able to 
just glance at it and know that it's not altering your object.



I see, so I need pure for the first example; thanks.


How about the second one though?


Re: How to break const

2012-06-18 Thread Jonathan M Davis
On Monday, June 18, 2012 08:19:55 Mehrdad wrote:
> On Monday, 18 June 2012 at 06:14:22 UTC, Matthias Walter wrote:
> > Its not, that a const method cannot modify an object, it just
> > ensures that the const method cannot modify the object *by
> > using the this-pointer*.
> 
> I see...
> 
> 
> So that means you /can't/ tell something just by looking at a
> part of the code, right?
> 
> (Just mentioning this since this idea seemed to be emphasized a
> lot by D.)

You can if the function is pure as well, because then that delegate would not 
be legal. For instance, this code

import std.stdio;

struct Const
{
this(void delegate() pure increment)
{ this.increment = increment; }
int a;
void delegate() pure increment;
void oops() const pure { this.increment(); }
}

void main()
{
Const c;
c = Const({ c.a++; });
writeln(c.a);
c.oops();
writeln(c.a);
}


fails to compile, giving this error:

q.d(15): Error: constructor q.Const.this (void delegate() pure increment) is 
not callable using argument types (void delegate() nothrow @safe)

All const guarantees is that the object isn't altered through the const 
reference/pointer (which in the case of a const function is this). That's 
powerful, but it needs pure as well to really be able to just glance at it and 
know that it's not altering your object.

If you want an extreme exampl. you could create an object whose entire state 
was held in a global variable, then the fact that the this pointer was const 
wouldn't mean much. But if the member functions were pure, then you couldn't 
access that global variable, and so that externalization of the state wouldn't 
work, and you'd be guaranteed that the const function didn't alter your object 
(as long as none of the arguments to that const function held a reference or 
pointer to that object anyway (though that's a fairly abnormal thing to do) - 
only strong purity absolutely guarantees that your object isn't being 
altered).

- Jonathan M Davis


Re: DMD + msvc

2012-06-18 Thread Mehrdad

On Sunday, 17 June 2012 at 10:49:30 UTC, Gor Gyolchanyan wrote:
On Sun, Jun 17, 2012 at 2:34 PM, Jacob Carlborg  
wrote:

On 2012-06-17 07:15, Gor Gyolchanyan wrote:


Is it possible to use the VC2010 linker with DMD? That would 
allow
easily linking with COFF libraries and building 64 bit 
binaries.



No.

1. DMD can only output OMF binaries
2. DMD cannot output 64bit code for Windows
3. DMD is not compatible with the MSVC linker or runtime

--
/Jacob Carlborg


Thanks for the reply.
This is so ridiculous and frustrating.


Yeah, but do note that even if DMD _was_ compatible with the 
VC2010 linker, then that still wouldn't get you 64-bit code...


Re: How to break const

2012-06-18 Thread Mehrdad

Okay, how about this? http://ideone.com/VMlzS

Does this break const?


import std.stdio;
class S
{
this(int a)
{
this.a = a;
this.increment = { this.a++; };
}
int a;
void delegate() increment;
void oops() const { this.increment(); }
}
void main()
{
auto c = new const(S)(0);
writeln(c.a);
c.oops();
writeln(c.a);
}