Re: version(StdDoc)

2018-11-24 Thread Stanislav Blinov via Digitalmars-d-learn
On Sunday, 25 November 2018 at 07:19:50 UTC, Stanislav Blinov 
wrote:



Granted, it may require some special syntax, i.e.

enum E {
a,
b if version(Windows),
c if version(Windows),
d if version(Posix),
}

or something to that effect.


Come to think of it, since UDAs are now allowed, the compiler 
could potentially be taught this:


enum E {
a,
@version(Windows) b,
@version(Windows) c,
@version(Posix)   d,
}


Re: version(StdDoc)

2018-11-24 Thread Stanislav Blinov via Digitalmars-d-learn

On Sunday, 25 November 2018 at 05:41:56 UTC, H. S. Teoh wrote:
On Sat, Nov 24, 2018 at 05:48:16PM +, Stanislav Blinov via 
Digitalmars-d-learn wrote:



Yup. UDAs did get in there eventually, and version should too.


I think this would be a trivial DIP, by making it such that a 
version block inside an enum would lower to the above code. Of 
course, it could be taken further: the above trick doesn't 
quite handle this case:


enum E {
a,
version(Windows) {
b, c
}
version(Posix) {
d
}
}


That is what Jonathan (and I concur) is talking about.

But this looks like such an antipattern that it probably should 
be written differently anyway, or just generated via a string 
mixin.


Why is it an antipattern? Having to version the whole enum just 
because some stupid C API has two out of a hundred items 
versioned per platform is an antipattern :)


Granted, it may require some special syntax, i.e.

enum E {
a,
b if version(Windows),
c if version(Windows),
d if version(Posix),
}

or something to that effect. But there has to be a better way 
than just versioning the whole enum or resorting to clumsy mixins.


Re: version(StdDoc)

2018-11-24 Thread H. S. Teoh via Digitalmars-d-learn
On Sat, Nov 24, 2018 at 05:48:16PM +, Stanislav Blinov via 
Digitalmars-d-learn wrote:
> On Saturday, 24 November 2018 at 17:43:35 UTC, Jonathan M Davis wrote:
> > On Saturday, November 24, 2018 9:28:47 AM MST Stanislav Blinov via
> > Digitalmars-d-learn wrote:
[...]
> > > enum Foo
> > > {
> > >  a,
> > >  b,
> > >  c = {
> > > version(linux) return 42;
> > > else version(Windows) return 54;
> > >  } ()
> > > }
> > > 
> > > /pedantry
> > 
> > LOL. That's an interesting trick. It's ugly and hacky, but it does
> > work around the problem.
> 
> :)

That's an awesome trick! Genius.


> > I'm still inclined to think though that it should be legal to just
> > use version directly in the member list.
> 
> Yup. UDAs did get in there eventually, and version should too.

I think this would be a trivial DIP, by making it such that a version
block inside an enum would lower to the above code. Of course, it could
be taken further: the above trick doesn't quite handle this case:

enum E {
a,
version(Windows) {
b, c
}
version(Posix) {
d
}
}

But this looks like such an antipattern that it probably should be
written differently anyway, or just generated via a string mixin.


T

-- 
Knowledge is that area of ignorance that we arrange and classify. -- Ambrose 
Bierce


Re: version(StdDoc)

2018-11-24 Thread H. S. Teoh via Digitalmars-d-learn
On Sat, Nov 24, 2018 at 10:27:07PM +, Adam D. Ruppe via Digitalmars-d-learn 
wrote:
[...]
> (Though a parsing thing: /// version(linux) void foo(); - is that doc
> on version linux or on void foo or on both? I guess it could only
> apply it in if there are {}... but eh I still don't love it.)

Yeah that's a tricky case.


[...]
> > It's a bad thing to separate the docs from the actual code, because
> > then the two are liable to go out-of-sync with each other.
> 
> that depends on what kind of docs. for api reference, sure, but other
> docs prolly should be separate because they are bigger picture, and
> thus don't naturally fit well in with the code.

That's what module docs are for. Or docs on aggregates as opposed to
docs on individual members.


> But of course, version(D_Ddoc) is the worst of both worlds.

Agreed.


T

-- 
Customer support: the art of getting your clients to pay for your own 
incompetence.


Re: How to iterate getSymbolsByUDA

2018-11-24 Thread bauss via Digitalmars-d-learn

On Saturday, 24 November 2018 at 08:50:59 UTC, Eko Wahyudin wrote:
On Saturday, 24 November 2018 at 08:09:38 UTC, Stanislav Blinov 
wrote:
On Saturday, 24 November 2018 at 03:48:12 UTC, Eko Wahyudin 
wrote:

Hi all,
anyone know how to iterate getSymbolsByUDA ?


enum Attr;
struct A
{
@Attr int a;
int b;

@Attr void foo() {}
@Attr void foo(int) {}
}

void main() {
import std.traits;
import std.stdio;

alias symbols = getSymbolsByUDA!(A, Attr);

A a;

static foreach (i; 0 .. symbols.length) {
writeln("identifier: ", __traits(identifier, 
symbols[i]));

static if (is(typeof(symbols[i]) == int)) {
__traits(getMember, a, __traits(identifier, 
symbols[i])) = 42;

}
}

assert(a.a == 42);
}


aah ya,, this statement is work

static foreach (i; 0 .. symbols.length)

thank you.


It should work with just:

static foreach(sym; getSymbolsByUDA!(A, Attr)){
  ...
}

or

alias symbols = getSymbolsByUDA!(A, Attr);

static foreach(sym; symbols){
  ...
}


---

What you were missing was just making it a static foreach.


Reading XDR data from a file

2018-11-24 Thread Chris Bare via Digitalmars-d-learn
I have a file in xdr format and I'm trying to use the xdr module 
from dub.

After a lot of failures, I got this to work:

ubyte[] b2 = cast (ubyte[]) read(fname);
string n = cast (string) b2.get!string();
tracef("<%s>", n);

I feel like there should be a way for the xdr get to read 
directly from the file rather than reading it all into a buffer 
first, but no combination of File f = File(fname, "r"); and get  
that I tried would compile.


Also is using cast like this good practice?

--
Chris


Re: version(StdDoc)

2018-11-24 Thread Adam D. Ruppe via Digitalmars-d-learn

On Saturday, 24 November 2018 at 16:16:08 UTC, H. S. Teoh wrote:
Actually, what would be ideal is if each platform-specific 
version of the symbol can have its own associated 
platform-specific docs, in addition to the one common across 
all platforms, and the doc system would automatically compile 
these docs into a single block in the output, possibly by 
introducing platform specific sections, e.g.:


Well, I probably could do that, but I'm not so sure it would make 
since since it separates stuff quite a bit and may have weird 
cases. Like what if the arguments are different? Should it merge 
the params sections? (That is doable btw)


But also from the user side, when they are looking for 
differences, it is a pain if most the stuff is shared and there 
is just a different sentence at the bottom or something. I'd 
prolly insist that it be called out. Of course, the doc gen could 
automatically merge the docs with headers too... but that brings 
us to something we already have:


I just use...

/++
Does whatever.

Note on Windows it does something a bit different.
+/
version(linux)
void foo();

/// ditto
version(Windows)
void foo();


So the ditto covers the case and tells the doc gen they share the 
same stuff, and the header is written however we want in the 
comment.


I don't *hate* having shared docs on version blocks, I am just 
being lazy and avoiding implementation by pushing back :P



(Though a parsing thing: /// version(linux) void foo(); - is that 
doc on version linux or on void foo or on both? I guess it could 
only apply it in if there are {}... but eh I still don't love it.)




It's a bad thing to separate the docs from the actual code, 
because then the two are liable to go out-of-sync with each 
other.


that depends on what kind of docs. for api reference, sure, but 
other docs prolly should be separate because they are bigger 
picture, and thus don't naturally fit well in with the code.



But of course, version(D_Ddoc) is the worst of both worlds.


Re: D is supposed to compile fast.

2018-11-24 Thread welkam via Digitalmars-d-learn

On Friday, 23 November 2018 at 08:57:57 UTC, Chris Katko wrote:

D is supposed to compile fast.


You didnt read the fine print. It compiles simple code fast. Also 
compilation is separate step from linking and your program might 
spend half of "compilation" time in link phase.




Re: version(StdDoc)

2018-11-24 Thread Stanislav Blinov via Digitalmars-d-learn
On Saturday, 24 November 2018 at 17:43:35 UTC, Jonathan M Davis 
wrote:
On Saturday, November 24, 2018 9:28:47 AM MST Stanislav Blinov 
via Digitalmars-d-learn wrote:

On Saturday, 24 November 2018 at 07:00:31 UTC, Jonathan M Davis

wrote:
> [not legal]
>
> enum Foo
> {
>
> a,
> b,
> version(linux) c = 42,
> else version(Windows) c = 54,
>
> }
>
> You're forced to version the entire enum.

Not in this case, no:

enum Foo
{
 a,
 b,
 c = {
version(linux) return 42;
else version(Windows) return 54;
 } ()
}

/pedantry


LOL. That's an interesting trick. It's ugly and hacky, but it 
does work around the problem.


:)

I'm still inclined to think though that it should be legal to 
just use version directly in the member list.


Yup. UDAs did get in there eventually, and version should too.


Re: version(StdDoc)

2018-11-24 Thread Jonathan M Davis via Digitalmars-d-learn
On Saturday, November 24, 2018 9:28:47 AM MST Stanislav Blinov via 
Digitalmars-d-learn wrote:
> On Saturday, 24 November 2018 at 07:00:31 UTC, Jonathan M Davis
>
> wrote:
> > [not legal]
> >
> > enum Foo
> > {
> >
> > a,
> > b,
> > version(linux) c = 42,
> > else version(Windows) c = 54,
> >
> > }
> >
> > You're forced to version the entire enum.
>
> Not in this case, no:
>
> enum Foo
> {
>  a,
>  b,
>  c = {
> version(linux) return 42;
> else version(Windows) return 54;
>  } ()
> }
>
> /pedantry

LOL. That's an interesting trick. It's ugly and hacky, but it does work
around the problem. I'm still inclined to think though that it should be
legal to just use version directly in the member list.

- Jonathan M Davis





Re: D is supposed to compile fast.

2018-11-24 Thread H. S. Teoh via Digitalmars-d-learn
On Sat, Nov 24, 2018 at 09:20:08AM +, Chris Katko via Digitalmars-d-learn 
wrote:
> On Friday, 23 November 2018 at 10:00:17 UTC, Nicholas Wilson wrote:
> > 
> > If you pass all the files on the command line then they all get
> > (re)compiled.
> 
> How are you supposed include files if not passing them to the
> compiler?
> 
> I'm only using std.regex in one file, IIRC, so whatever the "proper"
> way to only compile changed files should improve it drastically.
[...]

Use separate compilation:

dmd -c module1.d
dmd -c module2.d
...
dmd module1.o module2.o ... -of/usr/bin/myprogram

Put this in a makefile or your build system of choice, and let it do
incremental builds.


T

-- 
Государство делает вид, что платит нам зарплату, а мы делаем вид, что работаем.


Re: version(StdDoc)

2018-11-24 Thread Stanislav Blinov via Digitalmars-d-learn
On Saturday, 24 November 2018 at 07:00:31 UTC, Jonathan M Davis 
wrote:



[not legal]

enum Foo
{
a,
b,
version(linux) c = 42,
else version(Windows) c = 54,
}

You're forced to version the entire enum.


Not in this case, no:

enum Foo
{
a,
b,
c = {
   version(linux) return 42;
   else version(Windows) return 54;
} ()
}

/pedantry


Re: How to get all modules in a package at CT?

2018-11-24 Thread Neia Neutuladh via Digitalmars-d-learn
Easiest way is to put this in your build script:

find path/to/package -name '*.d' | \
   xargs grep '^module ' | \
   sed 's,^module,import,' \
   > data/modules.d

Add `-J data` to your DMD command line, or add `"stringImportPaths":
["data"]` to dub.json.

Then in your file:

mixin(import("modules.d"));


Re: version(StdDoc)

2018-11-24 Thread H. S. Teoh via Digitalmars-d-learn
On Fri, Nov 23, 2018 at 09:43:01PM -0700, Jonathan M Davis via 
Digitalmars-d-learn wrote:
[...]
> Honestly, I would argue that if you have multiple versions of the
> documentation, then there's a serious problem. The documentation
> shouldn't be platform-dependent even if the symbols are. Even if the
> documentation needs some extra notes for a specific platform, it
> should all be in one documentation block that anyone using the symbol
> can read. Providing different documentation for different platforms
> just leads to folks not understanding how the symbol differs across
> platforms, leading to code that is even more platform-dependent when
> it really should be as platform independent as possible.

Actually, what would be ideal is if each platform-specific version of
the symbol can have its own associated platform-specific docs, in
addition to the one common across all platforms, and the doc system
would automatically compile these docs into a single block in the
output, possibly by introducing platform specific sections, e.g.:

Code:
/**
 * Does something really fun that applied across platforms!
 */
version(Windows)
{
/**
 * On Windows, this function displays a really funny
 * icon!
 */
int fun(int a) { ... }
}
version(Linux)
{
/**
 * On Linux, this function displays a funny penguin!
 */
int fun(int a) { ... }
}

Doc output:
int fun(int a)

Does something really fun that applied across platforms!

Windows notes: On Windows, this function displays a really funny
icon!

Linux notes: On Linux, this function displays a funny penguin!


If the function signatures are different, then it should be displayed as
"overloads", as Adam suggested. Maybe something like this:

Code:
/**
 * This function takes a different parameter depending on the
 * OS.
 */
version(Windows)
int fun(int x) { ... }
version(Linux)
int fun(long x) { ... }

Output:
int fun(int x)  // on Windows
int fun(long x) // on Linux

This function takes a different parameter depending on the OS.


[...]
> As such, I'm not sure that the fact that ddoc forces you to have a
> separate set of declarations just for the documentation is really a
> bad thing. It puts all of the documentation in one place.

It's a bad thing to separate the docs from the actual code, because then
the two are liable to go out-of-sync with each other. It's even worse
when the docs document a fake declaration that isn't actually part of
the real code. Then the docs won't even show the right declaration when
the code changes, and users won't even realize what has happened.


> The bigger problem IMHO is how -D affects the build. Both it and
> -unittest have the fundamental problem that because they create their
> own version identifiers, they really shouldn't be part of the normal
> build, and yet the way that they're set up to be used, it's as if
> they're expected to be part of the normal build - with -D just causing
> the compiler to generate the documentation in addition to the binary,
> and -unittest making the unit tests run before main rather than
> replacing main.
[...]

You can argue for it both ways.  Having the compiler generate docs per
compilation isn't necessarily a bad thing -- it ensures the docs are
up-to-date.  Running unittests also isn't necessarily a bad thing,
though I agree it's sorta weird that unittests are setup to run before
the main program. Technically, you want to run unittests first,
independently of main(), which should be put in a separate executable.
But you can argue for it both ways.

For larger projects, it does make more sense for unittests to be put in
a separate executable and run separately.  But for small programs,
especially when you're coding-compiling-testing, it's handy to have
unittests automatically run before main(), so that any regressions are
quickly noticed and fixed.  This doesn't make sense for larger programs,
e.g., in my Android project, I really want unittests to run on the host
system where possible, not as part of the APK installed to the device,
because it's much easier to debug on the host system than to deal with
crashlogs and remote debugging on the target machine.

(Of course, deploying unittests to the final execution environment also
has its value. But not as part of the main executable, since tests
should be run only once, not every time you invoke the executable, which
depending on your application could be multiple times during a typical
usage session.)


> As for the issue of versioning the documentation, I don't really see a
> clean one. Having the documentation build affected by version and
> static if and the like causes some problems

Re: How to get all modules in a package at CT?

2018-11-24 Thread Anonymouse via Digitalmars-d-learn

On Saturday, 24 November 2018 at 08:44:19 UTC, Domain wrote:
I have a package named command, and many modules inside it, 
such as command.build, command.pack, command.help...
I want to get all these modules at compile time so that I know 
what command is available.


If you just want static if expressions of whether *known* modules 
are available or not, then test if __traits(identifier, 
package.module) compiles.


---

// Two-step workaround for 
https://issues.dlang.org/show_bug.cgi?id=19409
enum hasBuild = __traits(compiles, __traits(identifier, 
command.build));
enum hasPack = __traits(compiles, __traits(identifier, 
command.pack));
enum hasHelp = __traits(compiles, __traits(identifier, 
command.help));


static if (hasBuild) { /* ... */ }
static if (hasPack) { /* ... */ }
static if (hasHelp) { /* ... */ }

---

__traits(compiles, { import package.module; }) mostly works, but 
I ran into problems when the module was available and merely did 
not compile.


If you want to iterate the package for modules imported in it, 
I'm not sure. __traits(allMembers, package) will list names of 
imported packages but not which modules.


Re: Making external types available to mixins

2018-11-24 Thread John Chapman via Digitalmars-d-learn

On Friday, 23 November 2018 at 21:49:55 UTC, Kagamin wrote:
Well, just have all factories in one module and import it, then 
they will be visible.


They're part of another library over which I have no control, but 
yes, I could still import them all and make life easier.



import allfactories;
auto makeWith(string className, Args…)(auto ref Args args) {
  mixin("return makeWith!(I", className, "Factory)(args);"); // 
Fowarded to implementation of makeWith below

}

Or predeclare make functions in factory modules

interface ICalendarFactory
{
  ...
}

alias makeCalendar=makeWith!ICalendarFactory;





Re: D is supposed to compile fast.

2018-11-24 Thread Chris Katko via Digitalmars-d-learn
On Friday, 23 November 2018 at 10:00:17 UTC, Nicholas Wilson 
wrote:


If you pass all the files on the command line then they all get 
(re)compiled.


How are you supposed include files if not passing them to the 
compiler?


I'm only using std.regex in one file, IIRC, so whatever the 
"proper" way to only compile changed files should improve it 
drastically.


Almost all of my templates are incredibly simple like using 
generic arguments for taking float and doubles, instead of 
hardcoded float.


I am using both Allegro and DAllegro (a D binding for Allegro5). 
But until recently, the compile times have been very fast. So 
it's definitely been D features cutting things down.


And as for "compile-time doesn't matter" arguments, that's plain 
silly. I'm not a junior programmer. I've had builds that took 
over 30 minutes to compile and as we all (should!) know, the 
longer the build time (especially over 10 seconds), the quicker 
the mind loses its train-of-thought and the more difficulty the 
brain has with establishing cause-and-effect relationships 
between code and bugs. When our builds hit 30 minutes, we ended 
up so disconnected from the project we'd end up playing a short 
game of Duke Nukem 3-D inbetween builds. (Ha! Builds. Build 
engine = the Duke Nukem 3D engine. A super-niche pun.) We were 
incredibly unproductive until I re-wrote the entire thing in a 
different language. It ran in less than 10 seconds and suddenly 
we were powering through new problem after new problem. (A huge 
data conversion project between a discontinued, no-documentation 
product and a new product by a different company.)


Anyhow, if you REALLY want to look at some very WIP code with 
poor documentation and possibly lots of random swearing (hobby 
project for trying out D in a game), I'll make the repo public 
for now:


https://bitbucket.org/katasticvoyage/ss14/src/master/

 extra.d is a main code unit for this application.

 ini.d has regex. (and no, it's not a proper lexer. I'm probably 
swapping it out with JSON.)


Re: How to iterate getSymbolsByUDA

2018-11-24 Thread Eko Wahyudin via Digitalmars-d-learn
On Saturday, 24 November 2018 at 08:09:38 UTC, Stanislav Blinov 
wrote:
On Saturday, 24 November 2018 at 03:48:12 UTC, Eko Wahyudin 
wrote:

Hi all,
anyone know how to iterate getSymbolsByUDA ?


enum Attr;
struct A
{
@Attr int a;
int b;

@Attr void foo() {}
@Attr void foo(int) {}
}

void main() {
import std.traits;
import std.stdio;

alias symbols = getSymbolsByUDA!(A, Attr);

A a;

static foreach (i; 0 .. symbols.length) {
writeln("identifier: ", __traits(identifier, 
symbols[i]));

static if (is(typeof(symbols[i]) == int)) {
__traits(getMember, a, __traits(identifier, 
symbols[i])) = 42;

}
}

assert(a.a == 42);
}


aah ya,, this statement is work

static foreach (i; 0 .. symbols.length)

thank you.


How to get all modules in a package at CT?

2018-11-24 Thread Domain via Digitalmars-d-learn
I have a package named command, and many modules inside it, such 
as command.build, command.pack, command.help...
I want to get all these modules at compile time so that I know 
what command is available.


Re: How to iterate getSymbolsByUDA

2018-11-24 Thread Stanislav Blinov via Digitalmars-d-learn

On Saturday, 24 November 2018 at 03:48:12 UTC, Eko Wahyudin wrote:

Hi all,
anyone know how to iterate getSymbolsByUDA ?


enum Attr;
struct A
{
@Attr int a;
int b;

@Attr void foo() {}
@Attr void foo(int) {}
}

void main() {
import std.traits;
import std.stdio;

alias symbols = getSymbolsByUDA!(A, Attr);

A a;

static foreach (i; 0 .. symbols.length) {
writeln("identifier: ", __traits(identifier, symbols[i]));
static if (is(typeof(symbols[i]) == int)) {
__traits(getMember, a, __traits(identifier, 
symbols[i])) = 42;

}
}

assert(a.a == 42);
}