Re: 'version'-based code selection

2019-06-02 Thread Jonathan M Davis via Digitalmars-d-learn
On Sunday, June 2, 2019 11:43:09 AM MDT Anonymouse via Digitalmars-d-learn 
wrote:
> On Saturday, 1 June 2019 at 07:46:40 UTC, Jonathan M Davis wrote:
> > For the most part though, you don't declare your own version
> > identifiers. It sometimes makes sense, but usually, version
> > identifiers are used for versioning code based on the platform
> > or architecture that it's compiled on. They're really only
> > intended to be a saner version of #ifdefs, and if you're doing
> > anything fancy with them, you're really not using them as
> > intended and are probably going to have problems.
>
> I use versioning pervasively to make features opt-in/opt-out at
> compile-time.
>
> Like so, from dub.json:
>
>  "versions":
>  [
>  "AsAnApplication",
>  "WithAdminPlugin",
>  "WithAutomodePlugin",
>  "WithBashQuotesPlugin",
>  "WithChanQueriesService",
>  "WithChatbotPlugin",
>  "WithConnectService",
>  "WithCTCPService",
>  "WithHelpPlugin",
>  "WithNotesPlugin",
>  "WithPersistenceService",
>  "WithPipelinePlugin",
>  "WithPrinterPlugin",
>  "WithQuotesPlugin",
>  "WithSedReplacePlugin",
>  "WithSeenPlugin",
>  "WithWebtitlesPlugin"
>  ],
>
> ---
>
> module foo;
>
> version(WithFoo):
>
> // ...
>
> Is this recommended against? It's a very convenient way of
> enabling and disabling modules outright, since (by default) dub
> eagerly compiles everything it sees. I haven't had any problems
> with it as of yet, at the very least.

Personally, I wouldn't be in favor of doing much in the way of enabling or
disabling features in a library or application in such a manner, but if
you're going to do it, then version identifiers would be appropriate.

However, you do need to watch out, because such an approach runs the risk of
problems if you end up with a project depending on libraries that depend on
your library, because they may not be compiled with the same set of version
identifiers. I'm not sure how dub handles that (probably by considering it a
conflict), but without any form of conflict resolution (or you have a form
of conflict resolution that doesn't catch this issue), you run the risk of
modules being imported with one set of version identifiers but actually
compiled with another. In some situations, that will result in a linker
error, but in others, it's just going to result in the code not behaving as
expected. It's less of an issue if the version identifiers are for an
application rather than a library. Also, if you're versioning out entire
modules rather than pieces of modules, you're likely to be less at risk of
subtle problems, since then you'll just get large stuff missing, and linking
will fail, whereas if you're using such version identifiers within code
(e.g. changing the body of a function), then you run a high risk of subtle
problems.

Personally, if I were writing a library with optional stuff, I'd make the
optional stuff into sub-modules and try to avoid using version identifiers.
I might do it for an application though, since in that case, you wouldn't be
dealing with sub-modules, and you're not dealing with anything depending on
your code, just controlling what ends up in the executable.

- Jonathan M Davis





Re: 'version'-based code selection

2019-06-02 Thread Anonymouse via Digitalmars-d-learn

On Saturday, 1 June 2019 at 07:46:40 UTC, Jonathan M Davis wrote:
For the most part though, you don't declare your own version 
identifiers. It sometimes makes sense, but usually, version 
identifiers are used for versioning code based on the platform 
or architecture that it's compiled on. They're really only 
intended to be a saner version of #ifdefs, and if you're doing 
anything fancy with them, you're really not using them as 
intended and are probably going to have problems.


I use versioning pervasively to make features opt-in/opt-out at 
compile-time.


Like so, from dub.json:

"versions":
[
"AsAnApplication",
"WithAdminPlugin",
"WithAutomodePlugin",
"WithBashQuotesPlugin",
"WithChanQueriesService",
"WithChatbotPlugin",
"WithConnectService",
"WithCTCPService",
"WithHelpPlugin",
"WithNotesPlugin",
"WithPersistenceService",
"WithPipelinePlugin",
"WithPrinterPlugin",
"WithQuotesPlugin",
"WithSedReplacePlugin",
"WithSeenPlugin",
"WithWebtitlesPlugin"
],

---

module foo;

version(WithFoo):

// ...

Is this recommended against? It's a very convenient way of 
enabling and disabling modules outright, since (by default) dub 
eagerly compiles everything it sees. I haven't had any problems 
with it as of yet, at the very least.




Re: 'version'-based code selection

2019-06-02 Thread Yatheendra via Digitalmars-d-learn

On Saturday, 1 June 2019 at 07:46:40 UTC, Jonathan M Davis wrote:


Like static ifs, version statements are completely a 
compile-time construct and having nothing to do with runtime 
beyond how they affect the code that's generated.

...
- Jonathan M Davis


Thanks for taking the time.

That's it then for selecting between malloc/free implementations 
at runtime (program start-up time, usually) in such a way. There 
might still be hope in the form of a separate dynamic library 
with re-implemented malloc, and equivalent wrapper API's around 
libc in another library (whole program, including Phobos, relying 
on the same malloc library).


Re: 'version'-based code selection

2019-06-01 Thread Jonathan M Davis via Digitalmars-d-learn
On Friday, May 31, 2019 9:59:13 PM MDT Yatheendra via Digitalmars-d-learn 
wrote:
> Hi people.
>
> The 'version' keyword sounds like a fantastic capability, but how
> far does DMD take it (and does GDC take it equally far)? This is
> not a "D Improvement Proposal", I am just asking how it is now.
>
> Can code of multiple versions be compiled into the same
> executable or library, and a particular one selected from
> "later"? I guess not without some name mangling and wrangling.
>
> Can such selection be done at link-time for standard as well as
> user-defined library code? Maybe some library file naming
> conventions are followed to allow the compiler to select the
> corresponding file?
>
> Wishful thinking, but can the selection be at runtime? That would
> be language support for making some things easy, e.g. picking
> from assembly-coded routines based on runtime CPU id (the video
> player MPlayer picks routines that way, and I read that the D
> library, Mir, has CPU id support).
>
> Thanks.
>
> P.S: I am a brand-new C++'y asylum seeker who may have missed
> seeing some documentation, so RTFM is a valid response.
>
> P.P.S: This question was triggered by the D GSoC project for
> independent-of-C implementations of malloc/free/memcpy/memset.
> Could a common malloc be exposed to the D
> runtime/Phobos/programs, with the C or D implementations
> selectable at link-time (using a mechanism available to user code
> too)?

Like static ifs, version statements are completely a compile-time construct
and having nothing to do with runtime beyond how they affect the code that's
generated. They also have nothing to do with linking beyond how they affect
what code is generated.

version statements are basically just static if statements that are compiled
in if the corresponding version identifier has been defined. They're
esentially D's answer to C's #ifdefs. A version statement can only check a
single version identifier (so, no boolean logic like with #ifdefs), but else
can be used like with static ifs. e.g.

version(linux)
{
// compile in this code on Linux
}
else version(Windows)
{
// compile in this code on Windows
}
else
static assert(false, "This platform is not supported.");

Multiple version identifiers exist when compiling. For instance, if
compiling on 64-bit x86 Linux, both the linux and X86_64 version identifiers
would be defined. So, it's not like there's only one version identifier when
compiling. Additional version identifiers can be supplied on the
command-line when compiling, and you can even define a version for just
within the module (version identifers cannot be imported). You don't
technically need to compile each module in a program with the same set of
version identifiers, but it's usually asking for trouble if you don't,
because that can cause problems when a module is imported using one set of
version identifiers but actually compiled with another (e.g. totaly
different symbol definitions could be used depending on what was versioned
in the module, leading to linker errors).

For the most part though, you don't declare your own version identifiers. It
sometimes makes sense, but usually, version identifiers are used for
versioning code based on the platform or architecture that it's compiled on.
They're really only intended to be a saner version of #ifdefs, and if you're
doing anything fancy with them, you're really not using them as intended and
are probably going to have problems.

The list of predefined version identifiers can be found here:

https://dlang.org/spec/version.html#predefined-versions

- Jonathan M Davis





Re: 'version'-based code selection

2019-05-31 Thread rikki cattermole via Digitalmars-d-learn

On 01/06/2019 3:59 PM, Yatheendra wrote:


Hi people.

The 'version' keyword sounds like a fantastic capability, but how far 
does DMD take it (and does GDC take it equally far)? This is not a "D 
Improvement Proposal", I am just asking how it is now.


GDC, LDC and DMD all share the same frontend from DMD.

Can code of multiple versions be compiled into the same executable or 
library, and a particular one selected from "later"? I guess not without 
some name mangling and wrangling.


It is not supported.

Think #ifdef and you should get a basic understanding of its scope.