www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Shared with no type in Druntime.

reply "Adam Wilson" <flyboynw gmail.com> writes:
Ok. So i've been trying to build Phobos with my new DI generation code  
(available here: https://github.com/LightBender/dmd.git) and i've run into  
an interesting usage of shared in the D Runtime. Namely, it has no type.  
I've been told that this is not correct and it should have a type. Is that  
correct?

Currently the source file (stdio.d in the DRT) has this in it and it  
compiles successfully:

     private extern shared FILE[_NFILE] _iob;

     shared stdin  = &_iob[0];
     shared stdout = &_iob[1];
     shared stderr = &_iob[2];
     shared stdaux = &_iob[3];
     shared stdprn = &_iob[4];

With the new DI generation code stdio.di contains this:

     private extern shared FILE[_NFILE] _iob;

     shared stdin; (Errors here and all subsequent lines in this snippet)
     shared stdout;
     shared stderr;
     shared stdaux;
     shared stdprn;

Is D doing some kind of type inference based on the type of the _iob  
variable in the first example that causes DMD to throw an error with the  
"= &_iob[0];" part removed?

-- 
Adam Wilson
IRC: LightBender
Project Coordinator
The Horizon Project
http://www.thehorizonproject.org/
Apr 28 2012
parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 04/28/2012 06:08 PM, Adam Wilson wrote:
 Ok. So i've been trying to build Phobos with my new DI generation code
 (available here: https://github.com/LightBender/dmd.git) and i've run
 into an interesting usage of shared in the D Runtime. Namely, it has no
 type. I've been told that this is not correct and it should have a type.
 Is that correct?

 Currently the source file (stdio.d in the DRT) has this in it and it
 compiles successfully:

 private extern shared FILE[_NFILE] _iob;

 shared stdin = &_iob[0];
 shared stdout = &_iob[1];
 shared stderr = &_iob[2];
 shared stdaux = &_iob[3];
 shared stdprn = &_iob[4];

 With the new DI generation code stdio.di contains this:

 private extern shared FILE[_NFILE] _iob;

 shared stdin; (Errors here and all subsequent lines in this snippet)
 shared stdout;
 shared stderr;
 shared stdaux;
 shared stdprn;

 Is D doing some kind of type inference based on the type of the _iob
 variable in the first example that causes DMD to throw an error with the
 "= &_iob[0];" part removed?
Yes. D does type inference all the time. Most of the time 'auto' is used because most variables have automatic storage class. The following are all legal: void main() { auto a = 42; // int const c = "hello"; // string immutable i = 1.5; // double struct S {} shared s = new shared(S); // S* enum e = [ 0, 1 ]; // int[] } All of the standard streams are of type File: assert(typeid(stdin) == typeid(std.stdio.File)); Ali
Apr 28 2012
parent reply "Adam Wilson" <flyboynw gmail.com> writes:
On Sat, 28 Apr 2012 18:23:30 -0700, Ali =C7ehreli <acehreli yahoo.com> w=
rote:

 On 04/28/2012 06:08 PM, Adam Wilson wrote:
 Ok. So i've been trying to build Phobos with my new DI generation cod=
e
 (available here: https://github.com/LightBender/dmd.git) and i've run=
 into an interesting usage of shared in the D Runtime. Namely, it has =
no
 type. I've been told that this is not correct and it should have a ty=
pe.
 Is that correct?

 Currently the source file (stdio.d in the DRT) has this in it and it
 compiles successfully:

 private extern shared FILE[_NFILE] _iob;

 shared stdin =3D &_iob[0];
 shared stdout =3D &_iob[1];
 shared stderr =3D &_iob[2];
 shared stdaux =3D &_iob[3];
 shared stdprn =3D &_iob[4];

 With the new DI generation code stdio.di contains this:

 private extern shared FILE[_NFILE] _iob;

 shared stdin; (Errors here and all subsequent lines in this snippet)
 shared stdout;
 shared stderr;
 shared stdaux;
 shared stdprn;

 Is D doing some kind of type inference based on the type of the _iob
 variable in the first example that causes DMD to throw an error with =
the
 "=3D &_iob[0];" part removed?
Yes. D does type inference all the time. Most of the time 'auto' is us=
ed =
 because most variables have automatic storage class. The following are=
=
 all legal:

 void main()
 {
      auto a =3D 42;               // int
      const c =3D "hello";         // string
      immutable i =3D 1.5;         // double

      struct S
      {}

      shared s =3D new shared(S);  // S*
      enum e =3D [ 0, 1 ];         // int[]
 }

 All of the standard streams are of type File:

      assert(typeid(stdin) =3D=3D typeid(std.stdio.File));

 Ali
Ok, so that answers the legality of the issue, but it smacks of sloppy = coding. We cannot ship the DRT as a dynamic library, as has been discuss= ed = and agreed to as a good idea, if their are variable declarations that re= ly = on type inference from an assignment operation because those assignments= = will get stripped out of the DI. So what should I do then? Because share= d = stdin; by itself with no assignment to infer from IS illegal and there i= s = not (that I can see) a way to separate an instantiation from an = implementation and the whole point of DI files is too remove = implementations. -- = Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/
Apr 28 2012
parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Saturday, April 28, 2012 18:32:00 Adam Wilson wrote:
 Ok, so that answers the legality of the issue, but it smacks of sloppy
 coding. We cannot ship the DRT as a dynamic library, as has been discussed
 and agreed to as a good idea, if their are variable declarations that rely
 on type inference from an assignment operation because those assignments
 will get stripped out of the DI. So what should I do then? Because shared
 stdin; by itself with no assignment to infer from IS illegal and there is
 not (that I can see) a way to separate an instantiation from an
 implementation and the whole point of DI files is too remove
 implementations.
There's nothing sloppy about it whatsoever. If you think that that's sloppy coding, then you're going to think that auto is sloppy coding, and you're going to be very unhappy with a lot of D code. Taking advantage of such type inference is considered _good_ style in D. For the most part, you shouldn't use the type explicitly unless you actually need to. If you need to put a variable in a .di file without its initializer, then that's a case where you're going to need to use the type explicitly. That means that either the .di generator is going to leave the initializer in (which I expect is what it currently does) - in which case you'd need to change it by hand - or it's going to need to take the type of the initializer and use that in the variable's declaration in the .di file rather than using shared by itself or auto or whatever it was using that involved type inference. - Jonathan M Davis
Apr 28 2012
parent reply "Adam Wilson" <flyboynw gmail.com> writes:
On Sat, 28 Apr 2012 19:23:28 -0700, Jonathan M Davis <jmdavisProg gmx.com>  
wrote:

 On Saturday, April 28, 2012 18:32:00 Adam Wilson wrote:
 Ok, so that answers the legality of the issue, but it smacks of sloppy
 coding. We cannot ship the DRT as a dynamic library, as has been  
 discussed
 and agreed to as a good idea, if their are variable declarations that  
 rely
 on type inference from an assignment operation because those assignments
 will get stripped out of the DI. So what should I do then? Because  
 shared
 stdin; by itself with no assignment to infer from IS illegal and there  
 is
 not (that I can see) a way to separate an instantiation from an
 implementation and the whole point of DI files is too remove
 implementations.
There's nothing sloppy about it whatsoever. If you think that that's sloppy coding, then you're going to think that auto is sloppy coding, and you're going to be very unhappy with a lot of D code. Taking advantage of such type inference is considered _good_ style in D. For the most part, you shouldn't use the type explicitly unless you actually need to. If you need to put a variable in a .di file without its initializer, then that's a case where you're going to need to use the type explicitly. That means that either the .di generator is going to leave the initializer in (which I expect is what it currently does) - in which case you'd need to change it by hand - or it's going to need to take the type of the initializer and use that in the variable's declaration in the .di file rather than using shared by itself or auto or whatever it was using that involved type inference. - Jonathan M Davis
Ok, I can accept that. Explicit typing is lots of extra pointless typing when the compiler can just figure it out for me. But that leaves us with an interesting design question. Right now, DI gen is destructive, which means any changes I make to the DI file will get destroyed on the next build if I forget to remove the -H flags. Unfortunately that means that the DI generator is going to have to somewhat dictate coding style and we need to make sure that DI gen covers the broadest possible range of potential uses. Personally, I have no problem leaving in initializers for module level variables. Is that an acceptable solution to the community? -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/
Apr 28 2012
next sibling parent Paulo Pinto <pjmlp progtools.org> writes:
Am 29.04.2012 05:03, schrieb Adam Wilson:
 On Sat, 28 Apr 2012 19:23:28 -0700, Jonathan M Davis
 <jmdavisProg gmx.com> wrote:

 On Saturday, April 28, 2012 18:32:00 Adam Wilson wrote:
 Ok, so that answers the legality of the issue, but it smacks of sloppy
 coding. We cannot ship the DRT as a dynamic library, as has been
 discussed
 and agreed to as a good idea, if their are variable declarations that
 rely
 on type inference from an assignment operation because those assignments
 will get stripped out of the DI. So what should I do then? Because
 shared
 stdin; by itself with no assignment to infer from IS illegal and
 there is
 not (that I can see) a way to separate an instantiation from an
 implementation and the whole point of DI files is too remove
 implementations.
There's nothing sloppy about it whatsoever. If you think that that's sloppy coding, then you're going to think that auto is sloppy coding, and you're going to be very unhappy with a lot of D code. Taking advantage of such type inference is considered _good_ style in D. For the most part, you shouldn't use the type explicitly unless you actually need to. If you need to put a variable in a .di file without its initializer, then that's a case where you're going to need to use the type explicitly. That means that either the .di generator is going to leave the initializer in (which I expect is what it currently does) - in which case you'd need to change it by hand - or it's going to need to take the type of the initializer and use that in the variable's declaration in the .di file rather than using shared by itself or auto or whatever it was using that involved type inference. - Jonathan M Davis
Ok, I can accept that. Explicit typing is lots of extra pointless typing when the compiler can just figure it out for me. But that leaves us with an interesting design question. Right now, DI gen is destructive, which means any changes I make to the DI file will get destroyed on the next build if I forget to remove the -H flags. Unfortunately that means that the DI generator is going to have to somewhat dictate coding style and we need to make sure that DI gen covers the broadest possible range of potential uses. Personally, I have no problem leaving in initializers for module level variables. Is that an acceptable solution to the community?
Maybe I have been spoiled by doing too much programming in languages that have module systems, but why is the initialization shown in the .di file? This is an implementation issue on the module. -- Paulo
Apr 29 2012
prev sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2012-04-29 05:03, Adam Wilson wrote:

 Ok, I can accept that. Explicit typing is lots of extra pointless typing
 when the compiler can just figure it out for me. But that leaves us with
 an interesting design question. Right now, DI gen is destructive, which
 means any changes I make to the DI file will get destroyed on the next
 build if I forget to remove the -H flags. Unfortunately that means that
 the DI generator is going to have to somewhat dictate coding style and
 we need to make sure that DI gen covers the broadest possible range of
 potential uses.

 Personally, I have no problem leaving in initializers for module level
 variables. Is that an acceptable solution to the community?
No, I think it's way better that the DI generator outputs the actually type instead of just "shared/auto" and the assignment. In this case: shared stdin = &_iob[0]; Should be generated as: shared File stdin; Anything to the right of the assignment operator is just an implementation detail. -- /Jacob Carlborg
Apr 29 2012
next sibling parent "Jakob Ovrum" <jakobovrum gmail.com> writes:
On Sunday, 29 April 2012 at 15:21:10 UTC, Jacob Carlborg wrote:
 No, I think it's way better that the DI generator outputs the 
 actually type instead of just "shared/auto" and the assignment.

 In this case:

 shared stdin = &_iob[0];

 Should be generated as:

 shared File stdin;

 Anything to the right of the assignment operator is just an 
 implementation detail.
I agree, except to get the right behaviour, I think that must be: extern shared File stdin;
Apr 29 2012
prev sibling parent reply "Adam Wilson" <flyboynw gmail.com> writes:
On Sun, 29 Apr 2012 08:21:10 -0700, Jacob Carlborg <doob me.com> wrote:

 On 2012-04-29 05:03, Adam Wilson wrote:

 Ok, I can accept that. Explicit typing is lots of extra pointless typing
 when the compiler can just figure it out for me. But that leaves us with
 an interesting design question. Right now, DI gen is destructive, which
 means any changes I make to the DI file will get destroyed on the next
 build if I forget to remove the -H flags. Unfortunately that means that
 the DI generator is going to have to somewhat dictate coding style and
 we need to make sure that DI gen covers the broadest possible range of
 potential uses.

 Personally, I have no problem leaving in initializers for module level
 variables. Is that an acceptable solution to the community?
No, I think it's way better that the DI generator outputs the actually type instead of just "shared/auto" and the assignment. In this case: shared stdin = &_iob[0]; Should be generated as: shared File stdin; Anything to the right of the assignment operator is just an implementation detail.
I agree, however, DMD has not yet performed it's semantic analysis at the time of DI generation so I have no clue what the type is when the files are generated. Theoretically that could be changed but such a decision is WAY above my paygrade and would probably require significant rewrites of the DI generation code, as in tearing it down and starting over. My understanding is that the reason for this is that the semantic analysis does significant rewriting of the AST and would probably drastically alter the look and even function of the output code... Also, there is this comment in the code to start the DI generation: /* Generate 'header' import files. * Since 'header' import files must be independent of command * line switches and what else is imported, they are generated * before any semantic analysis. */ My guess is that that has to do with the way the command-line switches impact the semantic analysis. -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/
Apr 30 2012
parent Jacob Carlborg <doob me.com> writes:
On 2012-04-30 20:21, Adam Wilson wrote:

 I agree, however, DMD has not yet performed it's semantic analysis at
 the time of DI generation so I have no clue what the type is when the
 files are generated. Theoretically that could be changed but such a
 decision is WAY above my paygrade and would probably require significant
 rewrites of the DI generation code, as in tearing it down and starting
 over. My understanding is that the reason for this is that the semantic
 analysis does significant rewriting of the AST and would probably
 drastically alter the look and even function of the output code...

 Also, there is this comment in the code to start the DI generation:
 /* Generate 'header' import files.
 * Since 'header' import files must be independent of command
 * line switches and what else is imported, they are generated
 * before any semantic analysis.
 */
 My guess is that that has to do with the way the command-line switches
 impact the semantic analysis.
Ok, I didn't know about this. Regardless I think this needs to be solved in the end. Perhaps a new semantic analysis phase that is only run when generating DI files. But that would probably be quite hard. -- /Jacob Carlborg
May 01 2012