Thread overview
Writing closed source programs in D?
May 31, 2013
Shriramana Sharma
May 31, 2013
Regan Heath
May 31, 2013
Jonathan M Davis
Jun 03, 2013
Jesse Phillips
Jun 03, 2013
Maxim Fomin
May 31, 2013
Now I'm *not* going to write closed source programs in D [;-)], but am curious -- in C++ we have header files which a developer can confidently distribute along with the compiled libraries, and the actual source of the libraries (the *.cpp files) remains with the developer. In D, (obviously I'm a noob) it seems that module is the unit of programming, so how does one provide the library user with an API only without distributing the full D sources? Is it perhaps like Python where you can compile stuff into a SO and provide appropriate documentation so the user can just do import fooclosedlib and go ahead?

-- 
Shriramana Sharma ஶ்ரீரமணஶர்மா श्रीरमणशर्मा
May 31, 2013
On Fri, 31 May 2013 12:25:48 +0100, Shriramana Sharma <samjnaa@gmail.com> wrote:

> Now I'm *not* going to write closed source programs in D [;-)], but am
> curious -- in C++ we have header files which a developer can
> confidently distribute along with the compiled libraries, and the
> actual source of the libraries (the *.cpp files) remains with the
> developer. In D, (obviously I'm a noob) it seems that module is the
> unit of programming, so how does one provide the library user with an
> API only without distributing the full D sources? Is it perhaps like
> Python where you can compile stuff into a SO and provide appropriate
> documentation so the user can just do import fooclosedlib and go
> ahead?

You ship the library with .di files created by the compiler.
http://dlang.org/dmd-linux.html#interface_files

.di files are .d files without the function bodies etc.  There are issues with templates and auto, but we will eventually have nice solutions for those.

R

-- 
Using Opera's revolutionary email client: http://www.opera.com/mail/
May 31, 2013
On Friday, May 31, 2013 13:06:13 Regan Heath wrote:
> .di files are .d files without the function bodies etc. There are issues with templates and auto, but we will eventually have nice solutions for those.

The only problem with auto is that the type can't be inferred without the function body. But all of the information is there. So, all you have to do is make it so that the function doesn't return auto (or so that the variable declaration uses the actual type instead of auto). For non-templated functions, that's trivial. .di generation could automate that better, but it's not a big deal.

The situation with templates is basically the same as it is with C++. They have to go in the interface/header file and always will. There's no way around that, because the code importing the header/interface file actually needs the full definition. If the compiler supported some sort of intermediate format, then you could provide partially compiled templates, but pretty much all of the information would still have to be there (just in a less human readable format), and you can't even partially compile much of a template without the arguments to instantiate it with anyway. So, you'd pretty much just be putting the same template definition in a binary format instead of text, which wouldn't stop much of anyone from figuring out what they looked like.

The reality of the matter is that if you want to hide your implementation, you don't use templates. It's impossible to actually hide them due to the fact that they're merely templates for generating code rather than actual code.

- Jonathan M Davis
June 03, 2013
On Friday, 31 May 2013 at 15:35:54 UTC, Jonathan M Davis wrote:
> The only problem with auto is that the type can't be inferred without the
> function body. But all of the information is there. So, all you have to do is
> make it so that the function doesn't return auto (or so that the variable
> declaration uses the actual type instead of auto). For non-templated
> functions, that's trivial. .di generation could automate that better, but it's
> not a big deal.

During the discussion about increasing attribute inference to auto functions, it was being argued that defining the specific return type for an auto function in the di file is incorrect.
June 03, 2013
On Friday, 31 May 2013 at 15:35:54 UTC, Jonathan M Davis wrote:
> The situation with templates is basically the same as it is with C++. They
> have to go in the interface/header file and always will. There's no way around
> that, because the code importing the header/interface file actually needs the
> full definition. If the compiler supported some sort of intermediate format,
> then you could provide partially compiled templates, but pretty much all of
> the information would still have to be there (just in a less human readable
> format), and you can't even partially compile much of a template without the
> arguments to instantiate it with anyway. So, you'd pretty much just be putting
> the same template definition in a binary format instead of text, which wouldn't
> stop much of anyone from figuring out what they looked like.
>
> - Jonathan M Davis

Actually dmd for code importing module doesn't need full definition, it only inserts symbols referring to external object files. This allows to split template declaration and definition with restriction that module with template definition emits referred symbols (which restricts applicability since due to separate compilation model it is impossible to know beforehand template parameters). This also can be viewed as 'linker' template constraint, if you pass not expected parameters you will have link error.

import foo;
import std.stdio;

class Me : BiiA
{
   override void foo()
   {
      writeln("main");
   }
}


void main()
{
   BiiA b = new Me;
   b.foo();
   b.get();
}
--- foo.di-------
template bar(T, U)
{
   U baz();
   class A(T)
   {
      T t;
      T get();
      void foo();
   }
}

alias bar!(int, int) Bii;
alias Bii.A!int BiiA;
---foo.d ----
import std.stdio;

template bar(T, U)
{
   U baz();
   class A(T)
   {
      T t;
      T get()
      {
         writeln("foo");
         return t;
      }
      void foo()
      {
         writeln("foo");
      }
   }
}

alias bar!(int, int) Bii;
alias Bii.A!int BiiA;
-----
dmd main.d // Error undefined reference to ...
dmd main.d foo.o //works
./main
main
foo