Re: On attribute inference...

2016-04-19 Thread Walter Bright via Digitalmars-d

On 4/18/2016 8:20 PM, Jonathan M Davis via Digitalmars-d wrote:

Except that unfortunately, the compiler _does_ do attribute inference for
auto return functions now, because the body is guaranteed to be available.
Relying on that inference in a public API that's part of a library will
easily lead to code breakage when the function implementation is changed (or
even when a function that it calls is changed, if that affects its
attributes).

Personally, I think that adding attribute inference for auto return
functions was a mistake and just encourages bad practices, but unless Walter
can be convinced that it was such a bad idea that it needs to be reverted
(and break whatever code thatt that would break), we're stuck with it.
Regardless, I think that it's clear that if you want a stable API, you need
to infer attributes as little as possible.


Auto function attribute inference is a good idea. They really aren't 
conceptually different from templates. Note that the mangling of an auto 
function will change if its attributes change, thus meaning you should get a 
link failure.


Attribute inference is a huge win for D, it makes the mass of attributes 
manageable.



Re: On attribute inference...

2016-04-19 Thread Jacob Carlborg via Digitalmars-d

On 2016-04-19 10:57, Jonathan M Davis via Digitalmars-d wrote:


However, there are some good arguments for not just exporting everything -
particularly with regards to compilation efficiency. It's not that uncommon
for a library to have a public API that everyone should see and use while
having a bunch of functions that are used only internally and really
shouldn't be exposed to users of the library. To some extent, package can be
used to hide those, but the larger the library, the harder that gets. And if
a library is very deep (i.e. its functions do a lot for you), then you're
fairly quickly going to end up with functionality that ideally would be
hidden, and putting everything in one module or package isn't always
reasonable.


Can't the new package(name) syntax be used to solve this? Although this 
doesn't work for virtual methods.


--
/Jacob Carlborg


Re: On attribute inference...

2016-04-19 Thread Johannes Pfau via Digitalmars-d
Am Tue, 19 Apr 2016 01:57:21 -0700
schrieb Jonathan M Davis via Digitalmars-d
:

> I expect that hiding symbols which aren't public would certainly help
> a great deal in avoiding having a lot of unnecessary symbols in a
> compiled library, but it doesn't completely solve the problem. And
> when discussions on export have come up, some of the folks who are
> particularly knowledgeable on the subject have been _very_ much in
> favor of using export to restrict what is and isn't visible in the
> generated library rather than relying on public. They'll have to
> chime in to provide good details though. The main issue that I recall
> is the desire/need to reduce the number of symbols in order to make
> compiling/linking more efficient.
> 
> - Jonathan M Davis
> 

Not only compiling / linking: https://gcc.gnu.org/wiki/Visibility

* It very substantially improves load times of your DSO (Dynamic Shared
  Object). For example, a huge C++ template-based library which was
  tested (the TnFOX Boost.Python bindings library) now loads in eight
  seconds rather than over six minutes!

* It lets the optimiser produce better code. PLT indirections (when a
  function call or variable access must be looked up via the Global
  Offset Table such as in PIC code) can be completely avoided, thus
  substantially avoiding pipeline stalls on modern processors and thus
  much faster code. Furthermore when most of the symbols are bound
  locally, they can be safely elided (removed) completely through the
  entire DSO. This gives greater latitude especially to the inliner
  which no longer needs to keep an entry point around "just in case".

* It reduces the size of your DSO by 5-20%. ELF's exported symbol table
  format is quite a space hog, giving the complete mangled symbol name
  which with heavy template usage can average around 1000 bytes. C++
  templates spew out a huge amount of symbols and a typical C++ library
  can easily surpass 30,000 symbols which is around 5-6Mb! Therefore if
  you cut out the 60-80% of unnecessary symbols, your DSO can be
  megabytes smaller!

* Much lower chance of symbol collision. The old woe of two libraries
  internally using the same symbol for different things is finally
  behind us with this patch. Hallelujah! 


Re: On attribute inference...

2016-04-19 Thread Satoshi via Digitalmars-d

On Tuesday, 19 April 2016 at 08:57:21 UTC, Jonathan M Davis wrote:
On Tuesday, April 19, 2016 07:58:19 Satoshi via Digitalmars-d 
wrote:
Why cannot be exported every public/protected method by 
default? When I am creating so/dll I want to export almost 
everything. Methods what I dont want to export I should mark 
as private or package or package(nameOfRootPackage).


From the standpoint of simplicity, that's definitely nicer. 
With C/C++ and
Linux, the default is that all symbols in a shared library are 
visible, whereas on Windows, on those which are explicitly 
exported are visible, and I always found having to deal with 
building on a Windows a royal pain - especially when what I had 
done just worked on Linux.


However, there are some good arguments for not just exporting 
everything - particularly with regards to compilation 
efficiency. It's not that uncommon for a library to have a 
public API that everyone should see and use while having a 
bunch of functions that are used only internally and really 
shouldn't be exposed to users of the library. To some extent, 
package can be used to hide those, but the larger the library, 
the harder that gets. And if a library is very deep (i.e. its 
functions do a lot for you), then you're fairly quickly going 
to end up with functionality that ideally would be hidden, and 
putting everything in one module or package isn't always 
reasonable. As it is Phobos has std.internal which is 
theoretically not supposed to be used outside of Phobos, but 
it's completely importable and usable by any code using Phobos. 
Having code like that restricted by export could be desirable.


I expect that hiding symbols which aren't public would 
certainly help a great deal in avoiding having a lot of 
unnecessary symbols in a compiled library, but it doesn't 
completely solve the problem. And when discussions on export 
have come up, some of the folks who are particularly 
knowledgeable on the subject have been _very_ much in favor of 
using export to restrict what is and isn't visible in the 
generated library rather than relying on public. They'll have 
to chime in to provide good details though. The main issue that 
I recall is the desire/need to reduce the number of symbols in 
order to make compiling/linking more efficient.


- Jonathan M Davis




But when I create two versions of the same library (shared and 
static one). Public symbols will be accessible through the static 
library but inaccessible through the shared library.


Library is a one big package and marking symbols as 
package(MyLib) is same as mark them as public in shared object.


e.g. I have MyLib and TestApp
MyLib
 - math.d
 - foo.d
 - bar/test.d

TestApp
 - main.d

or subpackages like
rikarin.core;
rikarin.appkit;
rikarin.base;
rikarin.backend;
etc.

I can easily create internal methods through the package(rikarin) 
definition. And package symbols shouldn't be exported.


Re: On attribute inference...

2016-04-19 Thread Jonathan M Davis via Digitalmars-d
On Tuesday, April 19, 2016 07:58:19 Satoshi via Digitalmars-d wrote:
> Why cannot be exported every public/protected method by default?
> When I am creating so/dll I want to export almost everything.
> Methods what I dont want to export I should mark as private or
> package or package(nameOfRootPackage).

>From the standpoint of simplicity, that's definitely nicer. With C/C++ and
Linux, the default is that all symbols in a shared library are visible,
whereas on Windows, on those which are explicitly exported are visible, and
I always found having to deal with building on a Windows a royal pain -
especially when what I had done just worked on Linux.

However, there are some good arguments for not just exporting everything -
particularly with regards to compilation efficiency. It's not that uncommon
for a library to have a public API that everyone should see and use while
having a bunch of functions that are used only internally and really
shouldn't be exposed to users of the library. To some extent, package can be
used to hide those, but the larger the library, the harder that gets. And if
a library is very deep (i.e. its functions do a lot for you), then you're
fairly quickly going to end up with functionality that ideally would be
hidden, and putting everything in one module or package isn't always
reasonable. As it is Phobos has std.internal which is theoretically not
supposed to be used outside of Phobos, but it's completely importable and
usable by any code using Phobos. Having code like that restricted by export
could be desirable.

I expect that hiding symbols which aren't public would certainly help a
great deal in avoiding having a lot of unnecessary symbols in a compiled
library, but it doesn't completely solve the problem. And when discussions
on export have come up, some of the folks who are particularly knowledgeable
on the subject have been _very_ much in favor of using export to restrict
what is and isn't visible in the generated library rather than relying on
public. They'll have to chime in to provide good details though. The main
issue that I recall is the desire/need to reduce the number of symbols in
order to make compiling/linking more efficient.

- Jonathan M Davis



Re: On attribute inference...

2016-04-19 Thread Satoshi via Digitalmars-d

Why cannot be exported every public/protected method by default?
When I am creating so/dll I want to export almost everything. 
Methods what I dont want to export I should mark as private or 
package or package(nameOfRootPackage).


Re: On attribute inference...

2016-04-18 Thread Jonathan M Davis via Digitalmars-d
On Tuesday, April 19, 2016 03:27:46 Marco Leise via Digitalmars-d wrote:
> No case makes the distinction between "function body
> availability" and "API stability" more clear than auto return.
> Even though their source code is copied verbatim into the .di
> files to allow the return of voldemort types (i.e. types that
> are defined inside the function returning it), their
> attributes are *not* inferred, because they may be part of a
> public API!

Except that unfortunately, the compiler _does_ do attribute inference for
auto return functions now, because the body is guaranteed to be available.
Relying on that inference in a public API that's part of a library will
easily lead to code breakage when the function implementation is changed (or
even when a function that it calls is changed, if that affects its
attributes).

Personally, I think that adding attribute inference for auto return
functions was a mistake and just encourages bad practices, but unless Walter
can be convinced that it was such a bad idea that it needs to be reverted
(and break whatever code thatt that would break), we're stuck with it.
Regardless, I think that it's clear that if you want a stable API, you need
to infer attributes as little as possible.

> I'd also propose a visibility level above 'public',
> to tag symbols that are exported from a library. All others
> are not invisible in .dll/.so files and removed during .di
> generation. All functions that are not part of such "exported"
> symbols can then have their attributes inferred.

Isn't that basically what folks like Benjamin and Martin want the export
keyword to do?

- Jonathan M Davis