gtkDcoding Blog Post #0025 - LinkButtons

2019-04-09 Thread Ron Tarrant via Digitalmars-d-learn
Good morning! A new post is up on the gtkDcoding blog. It's all 
about the LinkButton and you can find it here:


http://gtkdcoding.com/2019/04/09/0025-creating-and-using-a-linkButton.html


Re: D threading and shared variables

2019-04-09 Thread Archie Allison via Digitalmars-d-learn

On Sunday, 7 April 2019 at 22:18:56 UTC, Johan Engelen wrote:

On Sunday, 7 April 2019 at 14:08:07 UTC, Archie Allison wrote:


This generally works OK when tied to a Console but when link 
options are changed to be SUBSYSTEM:WINDOWS and 
ENTRY:mainCRTStartup it rarely does.


Manually setting the entry point sounds problematic if no other 
precautions are taken. Are you sure that druntime is 
initialized? See [1].


- Johan

[1] https://wiki.dlang.org/D_for_Win32


I changed the main code as described in the article but the 
effect seems to be the same as just using the link options. Is 
there anything obviously wrong with the variable declarations in 
the code sample? It looks like having a console output window in 
addition to just the GUI is having some sort of effect on 
threading, sharing or timing.




Re: Templates - What's Up with the template keyword?

2019-04-09 Thread Ron Tarrant via Digitalmars-d-learn

On Monday, 8 April 2019 at 14:56:46 UTC, Mike Parker wrote:

In the subsequent sections, I show both long and short 
(eponymous) forms of enum and function templates.


In your book, Mike, you stated:

Remember, a template is only instantiated once for each set of 
arguments and
the same instantiation can be repeated in multiple modules 
throughout a
program. If each instantiation were scoped locally, the 
template would no

longer work as expected.


That leads me to speculate that it should be possible to use a 
class template as a sort of singleton. But, because a class 
template (from what I understand currently) needs to be 
instantiated using 'new,' I'm thinking maybe it isn't possible.


Can you (or someone else) clear this up for me, please?

What I have in mind is a template wrapped around a GTK AccelGroup 
that could then be instantiated in the MainWindow as well as 
inside any MenuItem needing a keyboard shortcut assignment.


Re: Templates - What's Up with the template keyword?

2019-04-09 Thread Mike Parker via Digitalmars-d-learn

On Tuesday, 9 April 2019 at 10:53:49 UTC, Ron Tarrant wrote:

On Monday, 8 April 2019 at 14:56:46 UTC, Mike Parker wrote:

In the subsequent sections, I show both long and short 
(eponymous) forms of enum and function templates.


In your book, Mike, you stated:

Remember, a template is only instantiated once for each set of 
arguments and
the same instantiation can be repeated in multiple modules 
throughout a
program. If each instantiation were scoped locally, the 
template would no

longer work as expected.


That leads me to speculate that it should be possible to use a 
class template as a sort of singleton. But, because a class 
template (from what I understand currently) needs to be 
instantiated using 'new,' I'm thinking maybe it isn't possible.


Can you (or someone else) clear this up for me, please?


Instantiating a class template is not like instantiating a single 
instance of an object. What it does is create an implementation 
of the class, not an instance. So given this:


class Foo(T) {
   T item;
}

Then this instantiation (which, byt the way, does not need new -- 
an alias will do the trick):


alias IntFoo = Foo!int;

Essentially does this:

class FooWithInt {
int item;
}

Of course, the symbol will be different than 'FooWithInt', but 
the point is for every T there has to be a uniquely named 
implementation of Foo.




What I have in mind is a template wrapped around a GTK 
AccelGroup that could then be instantiated in the MainWindow as 
well as inside any MenuItem needing a keyboard shortcut 
assignment.


Off the top of my head, to get a Singleton template, you could 
implement all of your singleton plumbing (thread safety if you 
need it, etc) in the template and add a `static _instance` member 
just as you would for any non-templated singleton:


class Singleton(T) {
private static Singleton!T _instance;
static Singleton!T instance() {
if(_instance is null) {
_instance = new Singleton!T;
}
...
}

private T _thing;
...
}

And you can then instantiate directly or, more conveniently, use 
an alias:


alias Accelerators = Singleton!AccelGroup;

Then:

Accelerators.instance.doSomething();







Re: Templates - What's Up with the template keyword?

2019-04-09 Thread Alex via Digitalmars-d-learn

On Monday, 8 April 2019 at 12:23:28 UTC, Ron Tarrant wrote:
I'm digging into templates in an attempt to understand the 
signals-n-slots replacement for the observer pattern, but I've 
got a question I can't seem to find an answer for and an 
example for which I'm unable to solve the error.


First, the question...



Your confusion arises in your understanding of meta programming 
and templates. Templates are compile time expressions that use 
parameters. They are exactly analogous to parameters in typical 
programming but allow one to pass around CT information that 
doesn't exist at run time.


It is not the statement itself that is a template but the fact 
that it depends on a "template", which is a sort of abstract 
variable.


class C(T)

template C(T)

struct(T)

interface(T)

void foo(T)()

etc...


are all things that depend on a template parameter T. One can say 
that they are all "templated" or are "templates".


One can also say they are parameterized(meaning they take a 
parameter, but the parameters are CT "objects".



Essentially template is the most general and the rest are just 
syntactic sugar.


e.g.,

template CC(T)
{
   class C
   {
  T t;
   }
}


template CC is a "template"(just like a cookie cutter but that 
can configure itself depending on what T is, as this example 
shows that we can create a class with different type of t.



D has all kinda of stuff like this that help reduce the bloat of 
templates. Sometimes you must use one method over another for 
certain effects but usually you can pick and choose.


The idea is not to think of meta programming as something 
different than normal programming. It is still programming and 
there is enough of an overlap that it benefits one to realize 
they are the same thing but are at different levels in the type 
system. Meta programming works on the type hierarchy while 
"runtime programming" works in the type hierarchy. Meta 
programming is a super set of runtime programming.



The way I think of meta programming is that of coding runtime 
code. Run time code codes binary code. If I create a statement 
like


writeln("test");

I know that the code gets translated in to a call instruction, 
pointers are used, "test" exists in some location in memory, 
etc... it all is machine code though when I compile.


When I do something like this

foo!int();

I know that the first part of foo!int is "meta code" and it first 
gets translated in to runtime code and then that code gets 
translated in to machine code.


For example

void foo(T)(T s) { writeln(s); }

in this case, depending on what T is at compile time(which I get 
to decide in some way and so I know exactly what it is at compile 
time, in theory), foo takes on different versions.


if I call foo(3) then it is writeln(3) and T is an int(by 
deduction in the compiler) and the compiler can even optimize out 
certain things here because it also knows that 3 is known.(this 
is CTFE) There is nothing to optimize in that example though.


if I call foo(readln()) then the the compiler cannot optimize out 
but this code get translated in to writeln(readlin()) but T is a 
string(since readln returns a string and the compiler can deduce 
it).


But in general foo acts as all these possibilities(and all the 
possibilities are known by the compiler because they have to be 
known to compile and use).


So, what does templates do? They combine very similar code in to 
meta blocks that can then be easily used. They allow constructing 
very complex meta code such as


void foo(T)(T s) { static if (is(T == string)) writeln(s); }


and now foo is much more complicated because it has two 
completely different behaviors depending on what T is. You can't 
get that with run time code without a lot of work and it will 
never be efficient. But here the compiler will eventually know 
what T is and it can then choose the correct path at compile 
time. The if will disappear and so no extra overhead exists at 
runtime.


So, templates are very powerful things(the above doesn't even 
dent their power) The idea to bear in mind is that anything in D 
is a template if it takes a template parameter. Think of a 
template as a drawing template used to sketch something. It isn't 
the final result but it shapes the final result. It is more like 
a blueprint or a program in and of itself.


I think the hard part for many is that they can't balance the 
meta programming part with the run time part. This is very easy 
though if one always just keeps track of which side one is 
programming in and not to mix them up(mentally).


The meta programming part will always be obvious, it will depend 
on template parameters and use meta programming constructs. There 
are sometimes overlap between the two levels but it because 
natural once one gets enough of an understanding.


The hardest part about D is that it has so much meta programming 
stuff and there are sometimes bugs and special cases to do 
things, but the grammatical de

Re: const of AliasSeq is silently ignored

2019-04-09 Thread Alex via Digitalmars-d-learn

On Monday, 8 April 2019 at 19:56:50 UTC, Yuxuan Shui wrote:


In this example:

const(AliasSeq!(int, int)) a;
pragma(msg, typeof(a)); // (int, int)

This kind of make sense, since AliasSeq is not a "single" type. 
But silently dropping const seems bad, the compiler should 
probably report an error/warning in this case?


kinda makes sense and making sense are two different things. It 
has to make sense to the compiler.


While I see that you want to distribute const over the list, D is 
not designed to do this with anything that I know of. It could, 
without issue, but one must makes sure it does not contradict any 
other uses. If it doesn't then it could be a bonus feature.


Normally though one expects const to work on it's argument and so 
this also suggests having a const AliasSeq. Since we can't have a 
const AliasSeq there may be no issue redefining it to me what you 
want.


I agree that silently dropping things are bad. D does this 
sometimes and it can be a real pain.







Re: Overloads not returning appropriate info. [Field reflunkory]

2019-04-09 Thread Alex via Digitalmars-d-learn

On Monday, 8 April 2019 at 21:52:59 UTC, Adam D. Ruppe wrote:

On Saturday, 6 April 2019 at 12:20:28 UTC, Alex wrote:
 Error: variable 
`std.traits.ParameterDefaults!(foo).Get!1u.Get` only 
parameters or stack based variables can be `inout`


so i think that is a bug in the phobos library

see: 
https://forum.dlang.org/thread/qbqvkcoexxtlvlxob...@forum.dlang.org



I appreciate you looking in to it instead of writing it off. It 
basically proves my point that there are issues with D. These 
issues tend too be subtle and creep in to code and then that 
causes problems. I have been thrown off several times and when 
things don't work out I assume it is my code and when it's not 
I've already trashed my code trying to figure out what was wrong 
with it. These are the real problems with D and they come from 
two things: Not having a uniform and direct interface for 
reflection. Not having proper unit testing done for traits.


D is so heavy in meta programming that maybe it is time for a 
proper solution?


Re: Overloads not returning appropriate info. [Field reflunkory]

2019-04-09 Thread Adam D. Ruppe via Digitalmars-d-learn

On Tuesday, 9 April 2019 at 14:42:38 UTC, Alex wrote:

It basically proves my point that there are issues with D.


The language is fine in this case, it is a bug in the library.

Though, I don't think the library can be fixed because the 
language doesn't have facilities to express these things through 
libraries but I also don't see the point in having a library 
at all. You incur compile time and run time costs for stuff you 
probably don't need and introduce another layer of bugs.


Some of the lower level features are a little weird to see*, but 
they are easy to use once you get to know them.


* for example
   static if(is(typeof(overload) Params == __parameters))

to get the function parameter list (as the Params variable 
there). It is a little weird looking, but it isn't really hard to 
use.


Re: const of AliasSeq is silently ignored

2019-04-09 Thread Paul Backus via Digitalmars-d-learn

On Monday, 8 April 2019 at 19:56:50 UTC, Yuxuan Shui wrote:


In this example:

const(AliasSeq!(int, int)) a;
pragma(msg, typeof(a)); // (int, int)

This kind of make sense, since AliasSeq is not a "single" type. 
But silently dropping const seems bad, the compiler should 
probably report an error/warning in this case?


It works if you use the "storage class" syntax for const:

const AliasSeq!(int, int) a;
pragma(msg, typeof(a)); // (const(int), const(int))


Re: Overloads not returning appropriate info. [Field reflunkory]

2019-04-09 Thread Alex via Digitalmars-d-learn

On Tuesday, 9 April 2019 at 14:59:03 UTC, Adam D. Ruppe wrote:

On Tuesday, 9 April 2019 at 14:42:38 UTC, Alex wrote:

It basically proves my point that there are issues with D.


The language is fine in this case, it is a bug in the library.

I didn't say the language. The point with the language is that it 
could have built in semantics to do reflection in a inform 
way(__traits is somewhat uniform but messy and then one has 
std.traits which then makes it not uniform).


Though, I don't think the library can be fixed because the 
language doesn't have facilities to express these things 
through libraries but I also don't see the point in having 
a library at all. You incur compile time and run time costs for 
stuff you probably don't need and introduce another layer of 
bugs.


There is no runtime costs. The library may not be efficient but 
it is a better design. It abstracts most of the crap away and 
provides a very natural and uniform interface in to reflection.


Ultimately the compiler itself should provide this information 
directly. It has all the information when it compiles and it can 
lazily instantiate whatever information it has to calculate when 
it is requested. It could be very efficient, it is just doing 
what __traits does but more naturally.


Reflection should be a first class semantic in D given D's heavy 
meta programming capabilities.




Some of the lower level features are a little weird to see*, 
but they are easy to use once you get to know them.


* for example
   static if(is(typeof(overload) Params == __parameters))

to get the function parameter list (as the Params variable 
there). It is a little weird looking, but it isn't really hard 
to use.



The problem is that there is a semantic that supposedly exists to 
dot he same but fails. So it is not about weirdness but about 
non-uniformity. Why does it have to be that way? There is no 
reason, it is also a hack in the compiler. WHy not just wrap that 
code with something sane like


Type.Reflect!Parameters

?

This is exactly what my library does and it is a more sane 
looking solution. It's that simple. You can't disagree, you know 
it looks better(we could argue about the precise syntax but it is 
much better and more informative than what you posted).


Also, your snippet is meant to be used, later on, such as in a 
for each loop,


when we could do

static foreach(p; Type.Reflect!Parameters)

vs

static if(is(typeof(overload) Params == __parameters))
static foreach(p; Params)


It's 50% savings in both line space and character space, it's 
much faster to understand, it is uniform and natural while the 
second case is ugly, confusing, and bloated.



My point is that THERE IS NO NEED for such things. It is ALL 
about syntax. It's just wrappers. There is no new functionality. 
I'm just trying to make things "look" better because things that 
"look" better are easier to comprehend. Look better means that 
they are more uniform with common practices and experiences and 
allow for easier navigation in memory space.


You may be ok with having to remember special cases here and 
their... but it is a defect.  Suppose you program in 10 languages 
regularly, those special cases then are an order of magnitude 
more to remember... suppose you do other things with your life. 
If you don't and all you do is program D then you don't feel it 
as bad, if you do lots of other things then these are speed bumps 
that slows one down for no good reason at all(if you have one, 
besides, "some one has to code the new syntax and it takes work 
to make it better" then I'd like to hear it).


What I see if you justifying bad syntax just to justify it 
because it exists. If I'm wrong you just have to give me 
meaningful reasons why that is not the case.


I'm not looking to be confrontational, I'm looking to make things 
better. If you are right about what you claim then you can back 
it up, if not you can't except with fallacious arguments. My mind 
is willing to be changed as long as the change is provably good, 
else there is no point in going backwards.



I think the only argument you have is "It already exists and 
works and is not too bad"... which may be a good enough argument 
for you but isn't for me. That type of argument can be used to 
prevent progress on anything. "The cave is already exists and 
works to keep us sheltered and is not that bad so we don't need 
to build a nice house with AC that takes work to do". If all you 
have ever lived in is a cave then you can't possibly know if the 
house is better. It has to be built first to compare and 
contrast. The secret is that there is always something better 
than something else and it always should be sought after, at 
least theoretically(sure there is the practical issue of time, I 
accept that, but I don't accept denial that their isn't something 
better).



Hell, as much time that we have spent arguing over this shit we 
could have probably created a language feature 

Re: Overloads not returning appropriate info. [Field reflunkory]

2019-04-09 Thread Seb via Digitalmars-d-learn

On Tuesday, 9 April 2019 at 16:30:53 UTC, Alex wrote:

On Tuesday, 9 April 2019 at 14:59:03 UTC, Adam D. Ruppe wrote:

[...]
I didn't say the language. The point with the language is that 
it could have built in semantics to do reflection in a inform 
way(__traits is somewhat uniform but messy and then one has 
std.traits which then makes it not uniform).


[...]


Have you considered writing a DIP?


Re: Overloads not returning appropriate info. [Field reflunkory]

2019-04-09 Thread H. S. Teoh via Digitalmars-d-learn
On Tue, Apr 09, 2019 at 06:33:21PM +, Seb via Digitalmars-d-learn wrote:
> On Tuesday, 9 April 2019 at 16:30:53 UTC, Alex wrote:
> > On Tuesday, 9 April 2019 at 14:59:03 UTC, Adam D. Ruppe wrote:
> > > [...]
> > I didn't say the language. The point with the language is that it
> > could have built in semantics to do reflection in a inform
> > way(__traits is somewhat uniform but messy and then one has
> > std.traits which then makes it not uniform).
> > 
> > [...]
> 
> Have you considered writing a DIP?

I think the original intent was that __traits was supposed to be
low-level, implementation-specific calls into the compiler, while
std.traits is supposed to be the user-friendly syntactic sugar built on
top that user code is supposed to use.

Unfortunately, it turned out that people prefer using __traits directly
instead, and std.traits hasn't quite been keeping up with new __traits
(e.g., AFAIK __traits(compiles) does not have a std.traits equivalent),
and is also less familiar to many people, so now we have a mishmash of
code sometimes using __traits and sometimes std.traits.


T

-- VI = Visual Irritation


Re: Templates - What's Up with the template keyword?

2019-04-09 Thread Ron Tarrant via Digitalmars-d-learn

On Tuesday, 9 April 2019 at 14:25:18 UTC, Mike Parker wrote:

Off the top of my head, to get a Singleton template, you could 
implement all of your singleton plumbing (thread safety if you 
need it, etc) in the template and add a `static _instance` 
member just as you would for any non-templated singleton:


class Singleton(T) {
private static Singleton!T _instance;
static Singleton!T instance() {
if(_instance is null) {
_instance = new Singleton!T;
}
...
}

private T _thing;
...
}

And you can then instantiate directly or, more conveniently, 
use an alias:


alias Accelerators = Singleton!AccelGroup;

Then:

Accelerators.instance.doSomething();


So, I guess the short answer is 'no.' A template can't really 
substitute for a singleton without actually becoming a singleton 
in and of itself.


I'm still struggling to understand templates, but I'll keep at it.

Thanks, Mike.




Re: Templates - What's Up with the template keyword?

2019-04-09 Thread Ron Tarrant via Digitalmars-d-learn

On Tuesday, 9 April 2019 at 14:41:30 UTC, Alex wrote:

Your confusion arises in your understanding of meta programming 
and templates. Templates are compile time expressions that use 
parameters.


This sounds like another 'no.' :)

Thanks for all the info, Alex.


Re: Overloads not returning appropriate info. [Field reflunkory]

2019-04-09 Thread Alex via Digitalmars-d-learn

On Tuesday, 9 April 2019 at 18:33:21 UTC, Seb wrote:

On Tuesday, 9 April 2019 at 16:30:53 UTC, Alex wrote:

On Tuesday, 9 April 2019 at 14:59:03 UTC, Adam D. Ruppe wrote:

[...]
I didn't say the language. The point with the language is that 
it could have built in semantics to do reflection in a inform 
way(__traits is somewhat uniform but messy and then one has 
std.traits which then makes it not uniform).


[...]


Have you considered writing a DIP?


No, because I expect it won't even be considered. The typical 
responses I have seen to this sort of thing is that "we already 
have it". Hence why I decided to write my own lib, and then had a 
few issues.


Andre did look in to some of the ideas and said he would pass it 
off to some GSOC students to look in to making it better, so 
maybe something will come out of that.


I believe that basically the compiler simply needs to present a 
better interface in to reflection. This should have been done 
from the get go but I guess __traits has been patched together 
over time as as things were needed.


Essentially the compiler would need to do what I have done and 
wrap __traits and std.traits in to a more uniform interface. It 
would add an extra layer of indirection though since the wrapper 
needs then to stay consistent with any traits changes.



My library works well but is incomplete and has some bugs to due 
bugs in traits. It is, though, rather slow and I haven't worked 
on fixing it. (actually it doesn't seem to add too much overhead 
after the first call but I imagine that is due to the template 
being instantiated already in the module, might multiply for each 
new module it is used in)



What I'm thinking is that maybe it is better to have some range 
like semantics used for reflection. I have thought about it much 
but I got the idea earlier.


Type.Reflect.Accessor.Accessor.Selector.Selector.Accessor...

The idea is that one can access stuff from the type and then use 
certain keywords to select and filter and then access more.


I say it is range like but I'm not sure if ranges would work or 
not or if it would just be dispatching.


E.g.,

MyClass.Reflect.TemplateParameters.Select!int.Names

Would get the template parameters of MyClass, then select only 
those with int and then get the names of those parameters.


(this could work in general for runtime too)

MyClass.SomeArray.Select("x.value == 4").name;

which is why I say it is sorta like ranges(which I'm thinking 
more of piping).



I just haven't thought about it much and there doesn't seem to be 
much interest in going this route... I think it would be a great 
addition to D but others seem to not care or are more interested 
in arguing to relatively insignificant issues.







Re: Templates - What's Up with the template keyword?

2019-04-09 Thread Steven Schveighoffer via Digitalmars-d-learn

On 4/9/19 4:31 PM, Ron Tarrant wrote:


I'm still struggling to understand templates, but I'll keep at it.


When I first saw C++ templates, I thought "what the hell is this black 
magic", and had no idea how they worked. In fact, this was back before 
STL, and I recall it was a set of templates called "Rogue Wave". None of 
us who were working on the project at the time understood them, so we 
ripped them all out.


The thing that made it click for me is that a template is very akin to a 
macro substitution -- where you just copy and paste the given parameter 
wherever its substitute is found.


For example:

struct S(T)
{
   T member;
}

S!int => put int wherever you see T.

So it's like you typed:

struct S
{
   int member;
}

and that's what the compiler sees. All optimization, layout, etc. works 
exactly like you typed that directly. But instead of creating one type 
for every member type you need, you just write it once and "instantiate" 
the template giving the type you want.


I will say, it's not EXACTLY the same as macro substitution -- there are 
rules. But it's a good way to think about it. I actually am going to go 
over this kind of thinking a bit in my talk this year at dconf.


-Steve


Re: Overloads not returning appropriate info. [Field reflunkory]

2019-04-09 Thread Alex via Digitalmars-d-learn

On Tuesday, 9 April 2019 at 18:56:58 UTC, H. S. Teoh wrote:
On Tue, Apr 09, 2019 at 06:33:21PM +, Seb via 
Digitalmars-d-learn wrote:

On Tuesday, 9 April 2019 at 16:30:53 UTC, Alex wrote:
> On Tuesday, 9 April 2019 at 14:59:03 UTC, Adam D. Ruppe 
> wrote:

> > [...]
> I didn't say the language. The point with the language is 
> that it could have built in semantics to do reflection in a 
> inform way(__traits is somewhat uniform but messy and then 
> one has std.traits which then makes it not uniform).
> 
> [...]


Have you considered writing a DIP?


I think the original intent was that __traits was supposed to 
be low-level, implementation-specific calls into the compiler, 
while std.traits is supposed to be the user-friendly syntactic 
sugar built on top that user code is supposed to use.


Unfortunately, it turned out that people prefer using __traits 
directly instead, and std.traits hasn't quite been keeping up 
with new __traits (e.g., AFAIK __traits(compiles) does not have 
a std.traits equivalent), and is also less familiar to many 
people, so now we have a mishmash of code sometimes using 
__traits and sometimes std.traits.




That may be the case but I recently saw some one here say "All 
the roads to hell are paved with good intentions", which isn't 
hyperbole. The better the initial plan the better things will 
turn out. Planning is the key to success, without it there is 
only luck.


My point has been and is that there is a better way that is more 
natural.  I make no claims about anything else. It may be a cop 
out to say something that is a tautology but I make the claim as 
an emphasis that I believe that it is more true in this case than 
others. i.e., D's traits are PITA. Ok, they are not as bad as 
some things but I know they can be better since I have used other 
languages that have far more logical reflection(such as C#) than 
D.


Because D has such an extensive meta programming language(the 
best I've seen for procedural) it needs a well thought out and 
natural reflection scheme. traits works but the more I use it the 
more I believe it could have been done better. It's one thing to 
use it here and there, but when you use it everywhere the issues 
multiply.


I think the library I through together at least demonstrates a 
much more natural way(and it was just a first attempt without any 
planning). I imagine something much better could be created with 
some proper planning and teamwork. My impression though is few 
people here actually care about such things.









Re: Overloads not returning appropriate info. [Field reflunkory]

2019-04-09 Thread H. S. Teoh via Digitalmars-d-learn
On Tue, Apr 09, 2019 at 08:49:17PM +, Alex via Digitalmars-d-learn wrote:
> On Tuesday, 9 April 2019 at 18:56:58 UTC, H. S. Teoh wrote:
[...]
> My point has been and is that there is a better way that is more
> natural.  I make no claims about anything else. It may be a cop out to
> say something that is a tautology but I make the claim as an emphasis
> that I believe that it is more true in this case than others. i.e.,
> D's traits are PITA. Ok, they are not as bad as some things but I know
> they can be better since I have used other languages that have far
> more logical reflection(such as C#) than D.

As I said, __traits was never designed to be user-friendly, or even
"logical".  It was supposed to be a quick-and-easy way to tap into
compiler internals, and std.traits was supposed to be the proper API to
introspection.  But std.traits, as it stands, is far, far from what it
ought to be, and so we have today's sorry situation.

(And on a side note: don't even get me started on is(...) expressions.)

Anyway, since you seem to be passionate about this, this could be your
chance of making std.traits what it ought to have been all along, or
making a sensible reflection library that can for all practical purposes
replace std.traits.

I, for one thing, would appreciate a nicer API to introspection than
what we currently have.  One of the main things that drew me to D was
its metaprogramming capabilities, and while overall it has been a
positive experience, there *are* flies in the ointment like __traits,
is(...) expressions, etc..  If you or somebody else could come up with a
saner way to do introspection in D, it'd be very much appreciated.


T

-- 
Life would be easier if I had the source code. -- YHL


Re: Templates - What's Up with the template keyword?

2019-04-09 Thread H. S. Teoh via Digitalmars-d-learn
On Tue, Apr 09, 2019 at 04:48:45PM -0400, Steven Schveighoffer via 
Digitalmars-d-learn wrote:
> On 4/9/19 4:31 PM, Ron Tarrant wrote:
> 
> > I'm still struggling to understand templates, but I'll keep at it.
[...]
> The thing that made it click for me is that a template is very akin to
> a macro substitution -- where you just copy and paste the given
> parameter wherever its substitute is found.
[...]

Yes, templates are, functionally speaking, macros with type safety, and
in D's case syntactic sanity, and none of the disadvantages of an actual
macro system.


T

-- 
Heads I win, tails you lose.


Re: Templates - What's Up with the template keyword?

2019-04-09 Thread Ali Çehreli via Digitalmars-d-learn

On 04/08/2019 05:23 AM, Ron Tarrant wrote:

> But in "Programming in D," (self, 2009-2018) by Ali Çehreli, there's no
> mention of the 'template' keyword in any of his examples.

'template' keyword is introduced here:

  http://ddili.org/ders/d.en/templates_more.html#ix_templates_more.template

I found that page by clicking on one of the two 'template' entries under 
T in the book's index:


  http://ddili.org/ders/d.en/ix.html

Ali



Re: Templates - What's Up with the template keyword?

2019-04-09 Thread Ali Çehreli via Digitalmars-d-learn

On 04/08/2019 05:59 AM, Ron Tarrant wrote:

On Monday, 8 April 2019 at 12:40:10 UTC, Adam D. Ruppe wrote:

You don't need template keyword for the majority of cases because the 
compiler lets you do shortcuts.

Thanks, Adam. Good to know.


(maybe I am looking at the wrong part of the book, it is hard to find 
the right section/page number online).


My bad. The edition I'm working from was released 2018-10-17 and can be 
found here:


http://ddili.org/ders/d.en/Programming_in_D.pdf

The page number in online PDF viewer is 421 and the example is about 1/3 
of the way down the page.



That template specialization works along with the general definition of 
the same template. So, you must have the following function template as 
well:


T getResponse(T)(string question) {
writef("%s (%s): ", question, T.stringof);

T response;
readf(" %s", &response);

return response;
}

As Steve said, when you replace all Ts in there e.g. with int, you get 
what the compiler would generate for T being int. However, the readf 
above cannot work with e.g. Point!double because readf does not know 
what Point!double is. For that reason, we may use a specialization for 
Point!T:


Point!T getResponse(T : Point!T)(string question)
{
writefln("%s (Point!%s)", question, T.stringof);

auto x = getResponse!T(" x");
auto y = getResponse!T(" y");

return(Point!T(x, y));

} // getResponse() Point!T

(It may be made to work with Adam's (T : Point!R, R) syntax but I failed 
just now.)


Now you have a specialization that works with any Point!T. T can be 
double, int, etc. However, you must call getResponse with that special 
Point. I'm using an alias for code reduction:


  alias MapLocation = Point!double;
  auto wayPoint1 = getResponse!MapLocation("Where is the first map 
location?");
  auto wayPoint2 = getResponse!MapLocation("Where is the second map 
location?");


Your code did not work because Point is not a type but a type template. 
(On the other hand, Point!double is a type). The whole program:


import std.stdio;
import std.math;
import std.string;

struct Point(T)
{
T x;
T y;

T distanceTo(Point that) const
{
immutable real xDistance = x - that.x;
immutable real yDistance = y - that.y;

immutable distance = sqrt((xDistance * xDistance) + (yDistance 
* yDistance));


return(cast(T)distance);

} // distanceTo()

} // struct Point

T getResponse(T)(string question) {
writef("%s (%s): ", question, T.stringof);

T response;
readf(" %s", &response);

return response;
}

Point!T getResponse(T : Point!T)(string question)
{
writefln("%s (Point!%s)", question, T.stringof);

auto x = getResponse!T(" x");
auto y = getResponse!T(" y");

return(Point!T(x, y));

} // getResponse() Point!T


void main()
{
  alias MapLocation = Point!double;
auto wayPoint1 = getResponse!MapLocation("Where is the first map 
location?");
auto wayPoint2 = getResponse!MapLocation("Where is the second map 
location?");


writeln("Distance: ", wayPoint1.distanceTo(wayPoint2));

} // main()

Ali


Re: Templates - What's Up with the template keyword?

2019-04-09 Thread Adam D. Ruppe via Digitalmars-d-learn

On Wednesday, 10 April 2019 at 00:42:11 UTC, Ali Çehreli wrote:
(It may be made to work with Adam's (T : Point!R, R) syntax but 
I failed just now.)


You know, I didn't think T : Point!T would work, but it does. Huh.

Anyway, the , R one works similarly, observe:

---
T getResponse(T : Point!R, R)(string question) {
writef("%s (%s): ", question, T.stringof);

R response;
readf(" %s", &response);

return T(response);
}
---

In this case, when you pass it a Point!double, T is still the 
full type, Point!double (so the return value there needs to be 
constructed), but R is now just the `double` part, so we can pass 
that independently to readf.


This pattern is also useful for capturing static arrays:


void processStaticArray(A : T[N], T, size_t N)(ref A) {
writeln(T.stringof, " ", N);
}

void main()
{
int[5] arr;
processStaticArray(arr);
}


There, A is our static array type, but then we deconstruct its 
pieces to get the size and inner type too. This lets us pass any 
static array in without losing the compile-time length.


(though usually I'd just slice it and call it T[]!)



These patterns are also used by the `is` expression, and you can 
rename the whole thing there when used inside `static if`. (I 
know most people think this is crazy black magic, but it actually 
isn't that crazy once you know the pattern - write the symbol 
with placeholders, add a comma, define the placeholders. Then the 
other forms like is(T == X) and is(T : X) and even is(T N == X) 
are just optional additions to this - == means is equal to, : 
means can convert to, and the N in the last one renames the value 
extracted to something else, most valuable in is(typeof(func) 
Params == __parameters).


So yeah, there is a bit to it, but it is just a pattern, 
condition, optional placeholders, optional rename.)


Re: Overloads not returning appropriate info. [Field reflunkory]

2019-04-09 Thread Adam D. Ruppe via Digitalmars-d-learn

On Tuesday, 9 April 2019 at 20:45:18 UTC, Alex wrote:

On Tuesday, 9 April 2019 at 18:33:21 UTC, Seb wrote:

Have you considered writing a DIP?


No, because I expect it won't even be considered.


You won't pass review if you don't show knowledge of the existing 
language, but there's a lot of people who are interested in a few 
changes.


A few years ago, there was a proposal for a magical `meta` 
namespace that would call into the compiler for syntax sugar on 
CT reflection. The old idea was to replace `__traits(X, args)` 
with `meta.X(args)` - pure syntax change - but you could perhaps 
revive and expand that as the entry point to your new idea and 
get some people on board.


I'm skeptical of any reflection library, but compiler changes 
might be able to change that. The status quo for D's reflection 
libraries are:


1) weird bugs and/or omissions since the language does not let 
you express all the function parameter details as return values 
or local variables.


2) slow compile times (you said your thing was 10 seconds! that's 
utterly unacceptable)


3) not actually significantly easier to use than language 
built-ins (if they are actually easier to use at all!)



So any library without compiler changes is, as of today, I 
believe *impossible* to get right, and getting as close as you 
can is horribly slow. So, your DIP would necessarily include 
language+compiler changes.


And the compiler is *already* (almost) fully capable, so changing 
that needs to show that the change is worth it. Maybe you can do 
that, even little cosmetic things can indeed be a win, but to 
write a convincing case here, you'll need to compare and contrast 
various cases.


Re: Overloads not returning appropriate info. [Field reflunkory]

2019-04-09 Thread Adam D. Ruppe via Digitalmars-d-learn

On Tuesday, 9 April 2019 at 21:00:55 UTC, H. S. Teoh wrote:
(And on a side note: don't even get me started on is(...) 
expressions.)


is expressions rock. And I betcha if we did do libraries for 
them, it would eventually go full circle, with someone doing a 
pattern-matching DSL that reinvents the original syntax, just 
much slower to compile :P


Re: Overloads not returning appropriate info. [Field reflunkory]

2019-04-09 Thread Adam D. Ruppe via Digitalmars-d-learn
Another couple ideas you might get some traction on are making 
typeid() values be convertible back into typeof types iff CTFE.


That would let you use types as OOP class values in intermediate 
structures while still turning them back into template args later.


Not sure just how realistic that is, but might be fun to explore.


Related would be to use RTInfo in druntime to extend the typeid 
info to runtime data, based on a -version switch. This should be 
possible in today's language fairly easily, though it would not 
be customizable by the end user, you could perhaps just make it 
include it all.