www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 7417] New: One-definition rule for version specification - allow version expressions

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7417

           Summary: One-definition rule for version specification - allow
                    version expressions
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: enhancement
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: clugdbug yahoo.com.au


--- Comment #0 from Don <clugdbug yahoo.com.au> 2012-02-01 03:51:32 PST ---
This enhancement adds a new syntax for version specifications, which would
allow us to eliminate the bird's nest of version statements that occurs when
code has a complicated version dependency.

The new syntax makes version specifications look like boolean variable
declarations:

version identifier = expression;

It would become illegal to reference a version identifier which hasn't been
declared. The spec already says that version declarations may only occur at
module scope; this new form of version specification would additionally be
disallowed inside version blocks (this enforces the one-definition rule).

version identifier = extern;
means that the identifier is externally specified (either on the command line,
or as a compiler built-in).

version VersionIdentifier = VersionExpression;

extern version VersionIdentifier;
// means this version is set from command line, or is a compiler built-in

VersionExpression:
     VersionExpression && VersionExpression
     VersionExpression || VersionExpression
    !VersionExpression
    ( VersionExpression )
        VersionIdentifier
        true
        false
        extern

version(A)
{
   version = AorNotB;
}
version(B)
{
}
else {
   version = AorNotB;
}

becomes:
version AorNotB = A || !B;

----
Note that this is backwards-compatible, it doesn't collide with the existing
syntax. To get the full benefit from it, though, we would need to eventually
disallow existing version specifications from being inside version blocks.
version = XXX; outside of a version block would be the same as version XXX =
true; so most code would continue to work.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Feb 01 2012
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7417


Martin Nowak <code dawg.eu> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |code dawg.eu


--- Comment #1 from Martin Nowak <code dawg.eu> 2013-01-30 06:18:10 PST ---
Now we've accidentally led the necessary discussion in a pull request.
https://github.com/D-Programming-Language/d-programming-language.org/pull/243

Maybe we should archive this here.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 30 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7417



--- Comment #2 from Martin Nowak <code dawg.eu> 2013-01-30 07:41:11 PST ---
 WalterBright

A far more robust and organized approach is to figure out just what you're
trying to abstract away in these version blocks, and then abstract it away as a
struct, class, function, or import. Then,

version (B)
feature() { return foo(); }
else version (C)
feature() { return foo(); }
else version (D)
feature() { return creature(); }
else
static assert(0, "version not supported");

This is clear, simple, organized, and forces the programmer adding E to check
each one of those, instead of assuming they will work.

I know that D users will continue to try and write C style version blocks, but
I will continue to try and show a better way. I also am painfully aware that
druntime/phobos have turned to C style versioning, despite my exhortations. It
should be fixed, not embraced.

Please do. It's an important design principle, deserves a proper name and getting popularized. It takes some getting used to it because it apparently contradicts other design principles. But we DO use it in druntime/phobos all over the place. I hope you can write an article or give a talk about this at some point. I do not agree though that it's the right approach for all problems. Take ELFOBJ in DMD as an example.
#define ELFOBJ (TARGET_LINUX || TARGET_FREEBSD || TARGET_OPENBSD ||
TARGET_SOLARIS)

It solves the maintenance issue of having to restate it over and over again, therefor I mentioned DRY. Adding a new ELF target could use a compilation/fix/test-cycle approach and testing has become the method of choice for most projects.
The recent attempt to replace in the DMD source code a bunch of the operating
system predefines with POSIX was a failure, and the reason for the failure was
a fine example of why the C approach is inferior and why it isn't supported in
D. 

I didn't follow that but as you said before it would have been naive to think everything would just work. For POSIX to work you need two sides, a fully compliant implementation and POSIX correct client code. This is doomed to fail but it doesn't make POSIX a bad abstraction layer. The problem is that forcing people to use something they feel is a bad match to their problem won't make this popular. This is the reason why "final switch" is a winner, it optionally allows people to improve their code correctness but it doesn't get in the way. It would be more fruitful to warn/error about a missing default case in an if-else ladder. If you thoroughly read through Dons proposal you see that he enforces to declare all used version identifiers before usage. This would open a door for better compile time checks. Maybe we could even check that no value combination of the induced extern version identifiers would lead to taking a branch of an if-else ladder. This would be something I'd call a worthy D implementation. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jan 30 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7417



--- Comment #3 from Martin Nowak <code dawg.eu> 2013-01-30 08:00:22 PST ---
And from a personal experience of a vibe.d app for mips-openwrt.
Having to solve all problems at once was the reason I spend 2 weeks
trying to implement what I wanted in one of the already supported languages.
I then spend 1.5 days on my vibe app and more than 1 week on understanding
glibc's and ulibc's header structure and compiling/fixing/debugging druntime
MIPS. Being faced with tons of compilation issues in a complex OpenWRT/GCC/GDC
build chain is not funny. In the end most of the issues were a missing "static
if(0, "Unsupported platform")" in the default branch of a "static if" or
"version" ladder, easy to fix but unnecessary. Some other issues were outright
bugs like a stat64 redeclaration in phobos's std.file, I think that got fixed
in the meanwhile.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 30 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7417



--- Comment #4 from Martin Nowak <code dawg.eu> 2013-01-30 09:33:31 PST ---
Scratch the version combination idea it's too complex and doesn't yield the
wanted result.
What might work out really well is to detect version-static-if-else ladders as
constructs and warn if no branch was taken.
This depends on the current set of defined version identifiers and static if
conditions and would have been an actual game changer for porting.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 30 2013
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7417



--- Comment #5 from Martin Nowak <code dawg.eu> 2013-01-30 09:39:24 PST ---
IMHO we should support version imports. When an extern identifier is not
specified we could perform an import search and pickup public version
declarations. Hijacking protection included of course.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 30 2013