Re: DlangUI Layout Justification

2023-04-10 Thread ShadoLight via Digitalmars-d-learn

On Friday, 7 April 2023 at 17:13:58 UTC, Adam D Ruppe wrote:

On Friday, 7 April 2023 at 15:52:02 UTC, Ali Çehreli wrote:
I don't know how relevant it is but there is also Hipreme 
Engine that supports Android:


[...]

One library can help with both games and guis but it is 
unlikely to be a complete solution for either, certainly not 
both.


Wow, what a great comparison, Adam! I've worked on GUIs, but 
never on games... and often wondered about this.


Maybe you can copy+paste the whole thing as a topic on your blog 
...? This comparison deserves *not* to fade into oblivion as is 
the typical fate of most forum discussions.




Re: My vibe-d test app is crashing on Windows

2023-02-13 Thread ShadoLight via Digitalmars-d-learn

On Monday, 13 February 2023 at 13:12:23 UTC, Steve wrote:
The app is just a test echo server. JSON sent in the body of a 
POST request is echoed back to the client. On Pop!_OS it works 
fine but on Windows it responds, there's a delay of about 10 
seconds and then it crashes with the error:


```
Error Program exited with code -1073741819
```

Here's the code:
```d
import vibe.vibe;
import std.json, std.stdio;

void main() {
auto settings = new HTTPServerSettings;
settings.port = 8080;
settings.bindAddresses = ["::1", "127.0.0.1"];

auto router = new URLRouter;
router.get("*", serveStaticFiles("public/"));
router.post("/", &onPost);

auto listener = listenHTTP(settings, router);
scope (exit) { listener.stopListening(); }

logInfo("App listening at http://127.0.0.1:8080/";);
runApplication();
}

static string handlePost(string req) {
return req;
}

void onPost(HTTPServerRequest req, HTTPServerResponse res) {
try {
auto jsr = async(&handlePost, 
req.json.toString()).getResult();

res.contentType("application/json; charset=utf-8");
res.writeBody(jsr);
} catch (Exception e) {
res.contentType("text/plain; charset=utf-8");
res.writeBody(e.msg);
}
}
```

Also when you launch/build the app with dub there's a shed load 
of deprecation warnings, e.g.:

```
\Local\dub\packages\vibe-d-0.9.5\vibe-d\stream\vibe\stream\wrapper.d(334,23): 
Deprecation: reference to local variable `this` assigned to non-scope parameter 
`bytes` calling `writeToStream`
```

I'm a D newbie so it's quite possibly something I'm doing wrong 
...


The -1073741819 error is OxC005 in hex.

And C005 on Windows is a access violation exception, 
indicating that you are trying to access memory that doesn't 
belong to your process. Possibly a 'buffer overrun' access 
exception - but I'm not sure in this case.


Unfortunately I'm not experienced with vibe at all - so I can't 
help with your code.


Just google 'Windows error C005' for more info.


Re: pointer escaping return scope bug?

2022-11-25 Thread ShadoLight via Digitalmars-d-learn

On Friday, 25 November 2022 at 14:07:28 UTC, ShadoLight wrote:

On Saturday, 19 November 2022 at 14:07:59 UTC, Nick Treleaven

```d
@safe:

struct LockedFile
{
private int* fps;

auto fp() return scope => fps;
}

void main()
{
int* p;
{
auto lf = LockedFile(new int);
p = lf.fp;
}
assert(p != null); // address escaped
}
```

[snip]


I don't grok how `lf` can survive the local scope. Or am I 
missing something?


Perhaps because the local scope is not pushed as a separate 
(anonymous) function on the stack... if true then, yes, then `lf` 
will indeed have the same physical lifetime as main (and `p`)...?


On the other hand, if you add a destructor to `LockedFile`, it 
will be invoked at the end of the local scope, not the end of 
main.


I find it a bit confusing what the term "lifetime" should pertain 
to in the case of variables declared inside a local scope inside 
a function - destructor invocation or physical existence of the 
variable on the stack?


But this has no bearing on the heap allocation and the lifetime 
of `p` in the example.




Re: pointer escaping return scope bug?

2022-11-25 Thread ShadoLight via Digitalmars-d-learn

On Saturday, 19 November 2022 at 15:00:16 UTC, Paul Backus wrote:
On Saturday, 19 November 2022 at 14:07:59 UTC, Nick Treleaven 
wrote:

Hi,
The following seems like a bug to me (reduced code, FILE* 
changed to int*):

```d
@safe:

struct LockedFile
{
private int* fps;

auto fp() return scope => fps;
}

void main()
{
int* p;
{
auto lf = LockedFile(new int);
p = lf.fp;
}
assert(p != null); // address escaped
}
```
There's no error with -dip1000.
I'll file this unless I overlooked something.


I think this is intended behavior, because you *do* get an 
error if you replace `new int` with a pointer to a stack 
variable; e.g.,


int local;
auto lf = LockedFile(&local);

The `return scope` qualifier on the method does *not* mean "the 
return value of this method is `scope`". It means "this method 
may return one of this object's pointers, but does not allow 
them to escape anywhere else." In other words, it lets the 
compiler determine that the return value of `lf.fp` has *the 
same* lifetime as `lf` itself.


Since, in your example, `lf` has global lifetime, the compiler 
deduces that `lf.fp` also has global lifetime, and therefore 
there is nothing wrong with assigning it to `p`.


I follow your rationale, but for the life of me I cannot see how 
`lf` _"has global lifetime"_.


Looks to me like `lf` is a value instance of the `LockedFile` 
struct (so on the stack) in a local scope inside main. I fully 
agree that the above code is not problematic, but isn't that 
because `p` is declared outside this local scope, and the 
allocation that happens inside the local scope (in the `lf` 
constructor) is on the heap, so the allocation (now assigned to 
`p`) survives the end of the local scope (and the end of the life 
of `lf`) since it is `p` that has global lifetime?


I don't grok how `lf` can survive the local scope. Or am I 
missing something?






Re: How to link a msvcr120.dll in an inverse recursive way after a Windows .exe binary deployment

2022-09-05 Thread ShadoLight via Digitalmars-d-learn

On Tuesday, 6 September 2022 at 04:59:49 UTC, Mike Parker wrote:

On Tuesday, 6 September 2022 at 04:36:55 UTC, ShadoLight wrote:



True. In that case just distribute the DLL (taken from the DMD 
bin folder) alongside the HelloWorld EXE so that both reside 
in the same folder on the target computer.


The proper way to do this is to ship the correct version of the 
Visual C++ redistributable installer and run it as part of the 
application install process:


https://docs.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170


Sure. But the OP seems to indicate that he doesn't have 
administrative privileges on the machines they wish to distribute 
and test his HelloWorld example.


I don't know if you can run an installer without administrative 
privileges - at least not if you want to write to Program Files / 
Program Files (x86), modify the Registry, environment variables, 
etc.  I'm not even sure if you can create a folder on Windows 10 
without administrative rights without resorting to some tricks. 
I've never required that - and would think that the IT department 
(that handles installs and updates on their organization's 
computers) should have an admin account on all of them.


My take was that he can simply copy the EXE and associated DLLs 
to an existing folder on the target machine if he just want to 
test it running on a non-developer machine.


Making an installer is another mini-project by itself .. not sure 
if he wants to be burdened with such a step simply to resolve his 
DMD issue.


But your redistributable installer link is indeed the proper way.


Re: How to link a msvcr120.dll in an inverse recursive way after a Windows .exe binary deployment

2022-09-05 Thread ShadoLight via Digitalmars-d-learn

On Monday, 5 September 2022 at 07:02:53 UTC, BoQsc wrote:


The problem is, D Language Compiler is not included along the 
Windows Operating System.


No compiler is included natively with the Windows OS. Not even 
Microsoft's.


Neither msvcr120.dll is included along the Windows Operating 
System.

You have to download it. No other way.


Or... you download the DMD installer which conveniently include 
it for you.




How can you download it, if your .exe binary that has the 
functionality to download it, cannot even be started due to 
msvcr120.dll not existing on the operating system.


I don't understand this. You need DMD to build your EXE. I 
suppose you have this since your question is specifically about 
DMD. If that is the case you have the DLL you need.





Copy the DLL to C:\Windows\System32\


It required administrator privilegies and this is only a 
HelloWorld example
of the D language deployed on computers, where the D language 
is yet to be installed.


True. In that case just distribute the DLL (taken from the DMD 
bin folder) alongside the HelloWorld EXE so that both reside in 
the same folder on the target computer. If you don't have 
administrative priveleges you cannot modify the PATH on the 
target computer either, so this is the only way. That is anyway 
quite standard under Windows - if you search for msvcr*.dll on 
any Windows machine you'll find lots of copies co-located with 
the EXEs that use them (using the version that came with the 
specific version of Visual Studio they were using to build the 
EXE - for example msvcr90.dll). These DLLs are simply the Visual 
Studio C/C++ Runtime distributed with Visual Studio.


Re: How to link a msvcr120.dll in an inverse recursive way after a Windows .exe binary deployment

2022-09-04 Thread ShadoLight via Digitalmars-d-learn

On Sunday, 4 September 2022 at 15:16:47 UTC, BoQsc wrote:


**Folder structure**

.\msvcr120.dll
.\folder1\HelloWorld.exe
.\folder2\HelloWorld.exe



You don't need to do this. msvcr120.dll is already shipped with 
the DMD compiler at 
[DMD-install-folder]\windows\bin64\msvcr120.dll. (It is also in 
[DMD-install-folder]\windows\bin). You can access it directly 
from there.


When you run your EXE... the OS looks for the DLL in the same 
folder of the EXE- if it cannot find it it looks in the folders 
specified in your PATH.


You can test if this is the case by executing 'where 
msvcr120.dll' at a DOS console command prompt. If the DLL is 
reachable in any folder in your PATH environment variable these 
specific path(s) will be displayed. In this case you don't need 
to do anything - the EXE should be able to run and load the DLL.


The fact that you get this error indicate this is not the case. 
You can do 1 of the following 2 things:
- add your DMD bin64 (or bin) path to the PATH environment 
variable.

--or--
- Copy the DLL to C:\Windows\System32\ - that will for sure 
already be in your PATH so you don't need to modify your PATH 
environment variable.


Re: What are virtual functions?

2021-04-18 Thread ShadoLight via Digitalmars-d-learn
On Wednesday, 14 April 2021 at 14:06:18 UTC, FeepingCreature 
wrote:

On Wednesday, 14 April 2021 at 13:43:20 UTC, Berni44 wrote:

[..]

Covariance is related ...

[..]


The opposite (contravariance) happens ...

[..]




Nice answer but, just to be clear - D only supports covariance on 
return types at the moment, and doesn't support contravariance on 
parameters, right?


I remember contravariance being periodically requested in the 
past but, AFAICR, it has not been implemented, right? A quick 
search through the forums didn't turn anything up either... and 
this does not compile:


```
class A {}
class B : A {}

class Y {
public void bar (B b) {}
}
class X : Y {
public override void bar (A a){}
}
```



Re: F*cked by memory corruption after assiging value to associative array

2021-01-29 Thread ShadoLight via Digitalmars-d-learn

On Monday, 25 January 2021 at 17:11:37 UTC, frame wrote:

On Monday, 25 January 2021 at 16:54:42 UTC, vitamin wrote:

On Monday, 25 January 2021 at 16:44:40 UTC, frame wrote:

On Monday, 25 January 2021 at 16:14:05 UTC, vitamin wrote:




Yes, I directly calling on every function that returns an 
object:


T fun(T)(T object) {
  GC.addRoot(cast(void*) object);
}
...
extern (C) export SomeObject bar() {
return fun(new SomeObject);
}



Just to confirm... I assume you just neglected to show the line 
in fun template function that returns the object, right?


Like...

T fun(T)(T object) {
  GC.addRoot(cast(void*) object);
  return object;
}


Re: Range of dub package versions

2020-12-29 Thread ShadoLight via Digitalmars-d-learn
On Monday, 28 December 2020 at 23:49:02 UTC, rikki cattermole 
wrote:

$ dub upgrade


[..]
Unless you change the version invalidating it, it most likely 
won't upgrade by itself.


Thanks Rikki - that explains it and, indeed, worked perfectly. 
Thanks!


Range of dub package versions

2020-12-28 Thread ShadoLight via Digitalmars-d-learn
I can build my app using dub, which has a dependency on the 
particular version of dlangui that was available when I 
originally created the project:


"dependencies": {
"dlangui": "~>0.9.182",
...etc..
},

I've recently noticed that the dlangui package is now on v0.9.186.

According to [1] this means:

"Restrict to a certain minor version: "~>2.2.13", equivalent to 
">=2.2.13 <2.3.0""


which I understood means that a 'dub build' would automatically 
download and use this latest version (well, up to v0.10.0 anyway).


But I probably misunderstood this - since this does not happen 
and a 'dub build' still reports:


dlangui 0.9.182: target for configuration "default" is up to date.

Is this behaviour correct?

If it is, then does this not imply that one still have to 
manually track and update the json file each time a dependency 
package is updated (if you want to stick with the latest 
version)? Note that I do understand that, if I had v0.9.186 
package on my machine, the same json file (that specifies 
"~>0.9.182") will still work and actually use this version of the 
package.


But the thing is, how would I get v0.9.186 on my machine except 
by doing a explicit 'dub fetch/add' step?  What then is the 
advantage to the "~>0.9.182" syntax compared with simply 
specifying the actual version (as in "dlangui": "==0.9.182" if it 
anyway boils down to a tracking dependency versions manually?


What am I missing?

[1] https://dub.pm/package-format-json.html#version-specs


Re: Why private methods cant be virtual?

2020-09-23 Thread ShadoLight via Digitalmars-d-learn

On Tuesday, 22 September 2020 at 11:39:31 UTC, Daniel Kozak wrote:
On Tue, Sep 22, 2020 at 1:30 PM ShadoLight via 
Digitalmars-d-learn < digitalmars-d-learn@puremagic.com> wrote:





This is not really "overriding", it is more akin to 
"overloading"




No it is not  overloading, overloading is when you have more 
methods with same name and differents params. It is overriding




Which is why I said it is "is more akin to "overloading"" i.e. 
what I meant is that the behaviour is kind-of "similar" to 
overloading in your example.  I did not mean it was classical 
overloading.


The thing is that, if the base class method is non-virtual, 
calling it "overriding" is confusing and somewhat misleading - 
all the derived class does is hide (or "shadow" if you like) the 
base class method.



It is also not polymorphic


I did not say otherwise :-)


Granted, but your example is confusing in the light that the OP 
specially asked about virtual and polymorphic behaviour.





Re: Why private methods cant be virtual?

2020-09-22 Thread ShadoLight via Digitalmars-d-learn

On Tuesday, 22 September 2020 at 10:23:08 UTC, Daniel Kozak wrote:
On Tue, Sep 22, 2020 at 11:06 AM claptrap via 
Digitalmars-d-learn < digitalmars-d-learn@puremagic.com> wrote:




"Functions marked as final may not be overridden in a derived 
class, unless they are also private"


So final private functions can be overriden? It seems not, but 
the sentence is definitely confusing if not just plain wrong.


Yes they can, if you have class A in one module and class B in 
another

module this will work:

//a.d
class A
{
private final void overrideFun()
{
import std.stdio : writeln;
writeln("A::overrideFun");
}
}

//b.d
import a;
class B : A
{
void overrideFun()
{
import std.stdio : writeln;
writeln("B::overrideFun");
}
}

// main.d
import b;

void main(string[] args)
{
B b = new B;
b.overrideFun;
}


This is not really "overriding", it is more akin to 
"overloading". It is also not polymorphic i.e. this will call  
A::overrideFun.


A b = new B;
b.overrideFun;



Re: Alternative to friend functions?

2020-02-20 Thread ShadoLight via Digitalmars-d-learn

On Thursday, 20 February 2020 at 08:02:48 UTC, Bienlein wrote:

On Tuesday, 18 February 2020 at 12:43:22 UTC, Adnan wrote:

What is the alternative to C++'s friend functions in D?

module stable_matching;

alias FemaleID = int;
alias MaleID = int;

class Person {
string name;
int id;
}

class Male : Person {
this(string name = "Unnamed Male") {
static int nextID = 0;
this.id = nextID++;
this.name = name;
}
}

class Female : Person {
this(string name = "Unnamed Female") {
static int nextID = 0;
this.id = nextID++;
this.name = name;
}
}

class Husband(uint N) : Male {
FemaleID engagedTo = -1;
const FemaleID[N] preferences;

this(FemaleID[N] preferences) {
this.preferences = preferences;
}
}

class Wife(uint N) : Female {
FemaleID engagedTo = -1;
const MaleID[N] preferences;

this(MaleID[N] preferences) {
this.preferences = preferences;
}
}

void engage(N)(ref Wife!N, wife, ref Husband!N husband) {
// Here, I want to access both husband and wife's 
engaged_to

}

class MatchPool(uint N) {
Husband!N[N] husbands;
Wife!N[N] wives;
}


I would make Husband and Wife subclasses of a common abstract 
superclass Spouse that declares the engagedTo var. The Spouse 
superclass would also be the place where to put the engage 
method. What is different for males and females you can 
redefine in the respective subclass.


But where in that inheritance hierarchy will you slot the Spouse 
class in? You don't have multiple inheritance in D, so are you 
thinking along these lines?:


class Person {..}
class Spouse : Person {..}
class Male : Spouse {..}
class Female : Spouse {..}

That implies every Male and Female 'is a' Spouse which, feels a 
bit clunky to me.


Maybe a better design for your idea is to make Spouse an 
interface; something along these lines:

class Person {..}
interface Spouse {void engage(..);}
class Male : Person, Spouse {..}
class Female : Person, Spouse {..}

Then, as you say, the respective engage(..) implementations are 
done in the Male/Female subclass.


Maybe you can even declare a winArgument(..) method returning a 
bool in the Spouse interface.  For the Male class the 
implementation will be real easy: just return false!


[Disclaimer]: Last paragraph not to be taken seriously!


Re: Template Usage with Eponymous Trick

2020-02-02 Thread ShadoLight via Digitalmars-d-learn

On Sunday, 2 February 2020 at 23:48:45 UTC, Paul Backus wrote:

On Sunday, 2 February 2020 at 23:39:10 UTC, ShadoLight wrote:
But, my question was if this was avoidable if braces were not 
optional. Paul's answer was that non-optional braces will not 
make...

alias a = S!(int);
... non-ambiguous, but I still don't get that based on the 
above results.


[..]

If the behavior were changed as you have previously proposed, 
so that `S!(int)` could refer *either* to the eponymous struct 
*or* the template instance, then the alias declaration would 
become ambiguous. Again, this would be true whether or not you 
used braces.


Ok, I get it. Thanks.



Re: Template Usage with Eponymous Trick

2020-02-02 Thread ShadoLight via Digitalmars-d-learn
On Sunday, 2 February 2020 at 18:30:17 UTC, Steven Schveighoffer 
wrote:


Thanks for taking the time to explain. However, when I tested my 
results does not seem to match your explanation.




First, note that:

struct S(T) {}

is *exactly* equivalent to (in fact, you can write it this way, 
and it works exactly the same):


template S(T) { struct S {} }


Yes, agreed.



So does S!int refer to the template instantiation (which is not 
a type) or the eponymous S struct inside the template (which is 
a type)? This was Paul's point.


I get what you are trying to say, but testing actually shows 
S!int is already a type in the eponymous case (but not in the 
classical case). If I do as in Paul's example...


template S(T) {
struct S {T x;}
}

// Should this assertion pass or fail?
static assert(is(S!(int)));   //PASS

void main()
{
auto a = S!(int)(3);
writeln(typeof(a).stringof);
}

... it actually compiles and the assertion passes (and prints 
S!int as the type), so it seems the eponymous template 
instantiation already created its eponymous struct as well, no?


But I guess that in terms of 'short-hand' syntax it actually 
makes sense since it is an eponymous template and, as you/Paul 
explained previously, it should only be invoked in this way.


In contrast, for the  non-eponymous case

template R(T) {
struct Q {T x;}
}

// Should this assertion pass or fail?
//static assert(is(R!(int)));  //FAIL

void main()
{
auto b = R!(int).Q(3);
writeln(typeof(b).stringof);
}

... now the assertion fails as expected, but the type printed is 
simply Q.


So we actually have this:

template S(T) {
struct S {}
}

template R(T) {
struct Q {}
}

static assert(is(S!(int)) == true);   //PASS
static assert(is(R!(int)) == false);  //PASS

I can understand (as @MoonlightSentinel's example showed), that 
optional braces can make this ambiguous and that is the current 
situation.


But, my question was if this was avoidable if braces were not 
optional. Paul's answer was that non-optional braces will not 
make...

alias a = S!(int);
... non-ambiguous, but I still don't get that based on the above 
results.




Re: Template Usage with Eponymous Trick

2020-02-02 Thread ShadoLight via Digitalmars-d-learn

On Sunday, 2 February 2020 at 16:23:42 UTC, Paul Backus wrote:

[..]


No, it would still be ambiguous:

struct S(T) {}

alias a = S!(int);

// Should this assertion pass or fail?
static assert(is(a));


Sorry, I don't get it. AFAICS 'is(a)' should return true (since a 
is an alias for a full type here) - and braces being compulsory 
or optional does not affect this.


AFAICS:

struct S(T) {}

alias a = S!(int);
alias b = S;

// Should this assertion pass or fail?
static assert(is(a));  //PASS
static assert(is(b));  //FAIL

But I don't see how braces will affect this. Can you explain?


Re: Template Usage with Eponymous Trick

2020-02-02 Thread ShadoLight via Digitalmars-d-learn
On Friday, 31 January 2020 at 15:37:06 UTC, Steven Schveighoffer 
wrote:

On 1/30/20 9:10 AM, ShadoLight wrote:




but to give you some historical perspective...


[..]



It was actually much more restrictive before -- e.g.  in order 
to do an eponymous template, you could have no other members in 
the template.


Thanks for the historical perspective Steve. Appreciated.

When you refer to 'other members' in the eponymous template, I 
notice that they are indeed allowed, but are effectively hidden 
(if they have a different name from the template name) inside the 
eponymous template, correct?


For example, this works fine in 'classical' template style - all 
members are 'public' and accessible:


template bar(T) {
T z;  //Allowed...
void b1(T x){z+=x;}   //Allowed...
void b2(T x){z-=x;}   //Allowed...
}
void main()
{

bar!(int).b1(4);//Works..
writeln(bar!int.z); //Works..
bar!(int).b2(5);//Works..
writeln(bar!int.z); //Works..
}


For eponymous templates, only members with the overloaded 
template identifier are accessible 'from the outside'.



template foo(T) {
T z;  //Allowed...
void foo(T x){f1(x);} //Allowed...
T foo(){return z;}//Allowed...
void f1(T x){z+=x;}   //Allowed...
}


void main()
{
foo(3);  //Works..
foo(4);  //Works..
writeln(foo!int.z);  //onlineapp.d(21): Error: no property z 
for type int
foo!int.f1(3);   //onlineapp.d(21): Error: no property f1 
for type int

writeln(foo!int());  //Works..
}

So the eponymous template invocation has to use the eponymous 
'trick' and only overloaded members are accessible.


Not bad and definitely an improvement , but I still find the 
inconsistency jarring... IIUC this 'ambiguity' would have been 
avoidable if template argument braces were not optional, right?


I do know this horse has bolted, but personally I think it D made 
a mistake to make the braces on compile-/run-time arguments on 
template/function invocation optional in the zero/one argument 
case.


It is not even completely symmetric between compile- and 
run-time: in compile time you can leave the braces off in the 
case of zero and one arguments, but for run-time only for zero 
arguments.


For want of the effort to type 2 braces, a fair bit of complexity 
and some inconsistency has been introduced into the language. And 
I remember that it actually made code harder to read when I 
started out in D, not easier.


I support the dropping of the braces in the case of property 
functions, but that use case is quite clear-cut and I think easy 
to handle based on the @property annotation.




Re: Template Usage with Eponymous Trick

2020-01-30 Thread ShadoLight via Digitalmars-d-learn

On Thursday, 30 January 2020 at 20:42:02 UTC, Paul Backus wrote:

On Thursday, 30 January 2020 at 15:14:43 UTC, ShadoLight wrote:



[..]

would make the language grammatically ambiguous...


OK, understood. Thank you.




Re: Template Usage with Eponymous Trick

2020-01-30 Thread ShadoLight via Digitalmars-d-learn
On Thursday, 30 January 2020 at 20:00:05 UTC, MoonlightSentinel 
wrote:

On Thursday, 30 January 2020 at 17:00:08 UTC, ShadoLight wrote:

[..]

...your proposed change it would be ambigous ...


Ok, that makes sense - I did not consider the impact of the 
optional empty braces. Thank you.




Re: Template Usage with Eponymous Trick

2020-01-30 Thread ShadoLight via Digitalmars-d-learn
On Thursday, 30 January 2020 at 16:16:48 UTC, MoonlightSentinel 
wrote:

On Thursday, 30 January 2020 at 15:14:43 UTC, ShadoLight wrote:


[...]


From my POV is

void foo(T)() { ... }

just a shorthand notation for...



Agreed. My question though is should the 'shorthand' notation 
_replace_ the 'longhand' notation, or be available _in addition_ 
to the 'longhand' notation in the eponymous case (so the 
eponymous notation is just 'syntax sugar' if you will).


If you had...

template foo(T) {
   bar(){..}
}

...you have no choice but to use foo!(int).bar()- (where T is 
'int'). So, I'm asking, in the eponymous case, should...


template foo(T) {
   foo(){..}
}

force you to use foo!(int)() instead (as is currently the case), 
or should foo!(int).foo() also still be acceptable/available?


For consistency's sake I think it should be but, if there is some 
reason why this is not technically possible/advisable, I was 
hoping someone would enlighten me.


And, in that case some of the examples in the documentation needs 
fixing.




Re: Template Usage with Eponymous Trick

2020-01-30 Thread ShadoLight via Digitalmars-d-learn

On Thursday, 30 January 2020 at 14:22:11 UTC, Paul Backus wrote:

On Thursday, 30 January 2020 at 14:10:38 UTC, ShadoLight wrote:
...but in the 'classical' default template style, so I would 
have thought the 
template_name!(compile_time_args).function_name(run_time_args) 
style would still work, even if the template and function 
names are identical.


If this is in fact now the intended behavior, then there are 
some places where the documentation are in error.



[1]: https://dlang.org/spec/template.html#variadic-templates


Eponymous templates are documented here:

https://dlang.org/spec/template.html#implicit_template_properties

This specific behavior is documented in the first paragraph 
below that heading, which reads as follows:


If a template contains members whose name is the same as the 
template identifier and if the type or the parameters type of 
these members include at least all the template parameters 
then these members are assumed to be referred to in a template 
instantiation


Yes, the behavior is described but not that it is in fact the 
_only_ way that an eponymous template can in fact be instantiated.


I think this behavior will be surprising for someone new to D. 
For eponymous templates you actually have the short-hand 
declarative style as well...


void foo(S, T)(S s, T t) {}

..ok, needs to call with...
foo!(int, int) (1, 2);
...or even just...
foo(1, 2);
...and your template parameters will be deduced.

This is at least kind-of intuitive. But now if you declare the 
template in the fully standard way:


   template foo(S, T)
   {
   void foo(S s, T t) {}
   }

..and you call it in the completely standard way (as you would 
have in fact been required if template identifier and member were 
differently named)...

   foo!(int, int).foo(1, 2);
..it not only does _not_ compile, but gives you an error:

onlineapp.d(12): Error: function onlineapp.foo!(int, int).foo(int 
s, int t) is not callable using argument types ()


...where foo!(int, int).foo(int s, int t) is clearly a match!

I really like the eponymous template trick and all that, but this 
did catch me by surprise -I did not realize that the eponymous 
template style in fact invalidates the 'classic' template 
invocation style: it is one or the other. I was somehow under the 
mistaken impression that you could still revert to the classic 
style, even if your template identifier and member identifier 
were identical.


Is there a technical reason for this limitation? Why are the 
'classical' invocation style not allowed for eponymous templates 
as well?


It seems somewhat arbitrary - note that inner/outer functions 
does not have this limitation - the fllowing is legal and 
compiles (and does not lead to infinite recursion):


int foo(int a, int b)
{
int foo(int x, int y) {return x+y;}
return foo(a, b);
}


void main()
{
   int z = foo(2, 4);
}



Re: Template Usage with Eponymous Trick

2020-01-30 Thread ShadoLight via Digitalmars-d-learn

On Thursday, 30 January 2020 at 14:10:38 UTC, ShadoLight wrote:
Taking this example from documentation page on 'Template 
Sequence Parameters' [1]:


[...]


Tested on https://run.dlang.io


Template Usage with Eponymous Trick

2020-01-30 Thread ShadoLight via Digitalmars-d-learn
Taking this example from documentation page on 'Template Sequence 
Parameters' [1]:


import std.stdio;

template print(args...)
{
void print()
{
writeln("args are ", args); // args is a ValueSeq
}
}

template write(Args...)
{
void write(Args args) // Args is a TypeSeq
  // args is a ValueSeq
{
writeln("args are ", args);
}
}

void main()
{
print!(1,'a',6.8).print();// prints: args 
are 1a6.8
write!(int, char, double).write(1, 'a', 6.8); // prints: args 
are 1a6.8

}

This fails to compile with:
onlineapp.d(22): Error: template onlineapp.print cannot deduce 
function from argument types !()(void), candidates are:

onlineapp.d(3):print(args...)()
onlineapp.d(23): Error: function onlineapp.write!(int, char, 
double).write(int _param_0, char _param_1, double _param_2) is 
not callable using argument types ()
onlineapp.d(23):missing argument for parameter #1: int 
_param_0


Fixing the error is simply to use 'simplified' template calling 
convention for templates based on the 'Eponymous Trick':


print!(1,'a',6.8)();// prints: args are 
1a6.8
write!(int, char, double)(1, 'a', 6.8); // prints: args are 
1a6.8


Why does the 'classical' template calling convention not work 
anymore in this case? (if the template name and function name are 
different it obviously still works). Note the templates were not 
defined in the simplified 'Eponymous Trick' style i.e.:


void print(args...)()
{
writeln("args are ", args); // args is a ValueSeq
}


void write(Args...)(Args args) // Args is a TypeSeq
   // args is a ValueSeq
{
writeln("args are ", args);
}

...but in the 'classical' default template style, so I would have 
thought the 
template_name!(compile_time_args).function_name(run_time_args) 
style would still work, even if the template and function names 
are identical.


If this is in fact now the intended behavior, then there are some 
places where the documentation are in error.



[1]: https://dlang.org/spec/template.html#variadic-templates


Re: How load icon from resource using LoadImage?

2020-01-06 Thread ShadoLight via Digitalmars-d-learn

On Sunday, 5 January 2020 at 13:52:27 UTC, JN wrote:

On Sunday, 5 January 2020 at 13:33:35 UTC, Marcone wrote:


[snip]


By the way, have you managed to add the res file into the 
binary? My understanding is that the res file should be added 
into the exe file by the rc command before it can be used.


Sort of correct... but not strictly correct. Typically the 
resource compiler (such as Microsoft's rc.exe) compiles 
xyzfile.rc into xyzfile.res.


xyzfile.res is then added into the exe by the linker during 
linking.




Re: How to use ResizerWidget in Dlangui app..?

2020-01-03 Thread ShadoLight via Digitalmars-d-learn

On Thursday, 2 January 2020 at 05:24:33 UTC, Rémy Mouëza wrote:

On Monday, 30 December 2019 at 23:32:37 UTC, ShadoLight wrote:

Hi,

I suspect I'm missing something obvious, but ResizerWidget is 
not working for me on Windows - it shows the 'dragging'-cursor 
when hovering the mouse on the ResizerWidget, but dragging 
with the left mouse button does nothing.




I ran into the same issue. The resizeEvent callback is not 
implemented yet. Below is my custom implementation.



/** A completed resizer widget.
  As of 2016-12-30, the ResizerWidget does not work out of the 
box.

  This class implement the missing piece.
 */
class Resizer : ResizerWidget {

/// Default initialization.
this () {
super ();
initResizeCb ();
}

/// Create with ID parameter.
this (string ID, Orientation orient = Orientation.Vertical) 
{

super (ID, orient);
initResizeCb ();
}

/// Initialize the resize on drag behaviour callback.
protected void initResizeCb () {
this.resizeEvent
= (ResizerWidget source,
   ResizerEventType event,
   int currentPosition)
{
if (event != ResizerEventType.Dragging) {
return;
}

if (_orientation == Orientation.Horizontal) {
auto delta = _previousWidget.width - 
currentPosition;
auto pw= max (0, _previousWidget.width - 
delta);
auto mw= max (0, _nextWidget.width + 
delta);


_previousWidget
.minWidth (pw)
.maxWidth (pw);

_nextWidget
.minWidth (mw)
.maxWidth (mw);
}
else if (_orientation == Orientation.Vertical) {
auto delta = _previousWidget.height - 
currentPosition;
auto pw= max (0, _previousWidget.height - 
delta);
auto mw= max (0, _nextWidget.height + 
delta);


_previousWidget
.minHeight (pw)
.maxHeight (pw);

_nextWidget
.minHeight (mw)
.maxHeight (mw);
}

parent.requestLayout ();
};
}
}


Remy, just a quick note to say thank you again!

I had to make a small adjustment to make the Resizer class 
completely generic for all cases, but I can only guess you did 
not need this as your use case probably had the ResizerWidget 
parent as the outermost widget.


The issue is that the currentPosition argument in the resizeEvent 
handler is in terms of the application window, and not in terms 
of the ResizerWidget parent. So, if you have another widget above 
the ResizerWidget parent (in the Orientation.Vertical case) or to 
the left of the ResizerWidget parent (in the 
Orientation.Horizontal case), you have a small offset issue. The 
same applies if you have margins or padding on the ResizerWidget 
parent (or any of its parent(s)).


Anyway, the fix is quite trivial:

/// Initialize the resize on drag behaviour callback.
protected void initResizeCb () {
this.resizeEvent
= delegate(ResizerWidget source,
   ResizerEventType event,
   int currentPosition)
{
if (event != ResizerEventType.Dragging) {
return;
}

int delta;
int pw;
int mw;
int localPos;
if (_orientation == Orientation.Horizontal) {
localPos = currentPosition - parent.left;
delta = _previousWidget.width - localPos;
pw= max (0, _previousWidget.width - delta);
mw= max (0, _nextWidget.width + delta);

_previousWidget
.minWidth (pw)
.maxWidth (pw);

_nextWidget
.minWidth (mw)
.maxWidth (mw);
}
else if (_orientation == Orientation.Vertical) {
localPos = currentPosition - parent.top;
delta = _previousWidget.height - localPos;
pw= max (0, _previousWidget.height - delta);
mw= max (0, _nextWidget.height + delta);

_previousWidget
.minHeight (pw)
.maxHeight (pw);

_nextWidget
.minHeight (mw)
.maxHeight (mw);
}

parent.requestLayout ();
};
}
}






Re: How to use ResizerWidget in Dlangui app..?

2020-01-01 Thread ShadoLight via Digitalmars-d-learn

On Thursday, 2 January 2020 at 05:24:33 UTC, Rémy Mouëza wrote:

On Monday, 30 December 2019 at 23:32:37 UTC, ShadoLight wrote:

Hi,

I suspect I'm missing something obvious, but ResizerWidget is 
not working for me on Windows - it shows the 'dragging'-cursor 
when hovering the mouse on the ResizerWidget, but dragging 
with the left mouse button does nothing.




I ran into the same issue. The resizeEvent callback is not 
implemented yet. Below is my custom implementation.



[snip]

OK, I suspected as much. But thanks a lot Rémy! You are saving me 
a lot of work - much appreciated!





Re: How to use ResizerWidget in Dlangui app..?

2020-01-01 Thread ShadoLight via Digitalmars-d-learn

On Wednesday, 1 January 2020 at 10:52:02 UTC, Ron Tarrant wrote:

On Monday, 30 December 2019 at 23:32:37 UTC, ShadoLight wrote:

dragging with the left mouse button does nothing.


Window window = Platform.instance.createWindow("DlangUI 
example", null);


I'm not familiar with this toolkit, but my guess is that you 
didn't pass in a `flags` value and therefore you aren't using 
the appropriate overload of the createWindow() function to 
achieve what you're after.


The following is from the DLangUI GitHub site 
(https://github.com/buggins/dlangui/wiki/Getting-Started). Take 
a look at the third argument:


Window createWindow(
dstring windowCaption, // window caption
Window parent, // parent window, pass null for main 
(first) window.
uint flags = WindowFlag.Resizable, // various flags - bit 
fields from WindowFlag enum values

uint width = 0,// initial window width
uint height = 0// initial window height
);


Thanks for the reply, Ron.

Yes, as you say WindowFlag.Resizable is the default value for the 
'flags' argument in the createWindow call, so that was the 
setting I had.


But the problem is actually not in resizing the full app window 
(that actually works - including keeping the relative proportions 
of the widget children sizes), but rather in resizing 2 widgets 
that are separated by a ResizerWidget inside the app window. The 
app window size should actually not be affected since, as 1 
widget on one side of the ResizerWidget shrinks by N pixels in 
height or width (depending on the orientation of the 
ResizerWidget), the opposite widget should grow by the same N 
pixels in height/width, leaving the parent size unaffected.


I can see that is actually what is coded, but it is not working 
when I run the app.


But I thought you may be on to something and I should check if 
children widgets of the app window inherits some settings from 
the parent, so I checked the WindowFlag flags. According to [1] 
you can have:

- Fullscreen
- Modal
- Resizable

However, checking the code there are additional options:
/// window creation flags
enum WindowFlag : uint {
/// window can be resized
Resizable = 1,
/// window should be shown in fullscreen mode
Fullscreen = 2,
/// modal window - grabs input focus
Modal = 4,
/// measure window size on window.show() - helps if you want 
scrollWindow but on show() you want to set window to mainWidget 
measured size

MeasureSize = 8,
/// window without decorations
Borderless = 16,
/// expand window size if main widget minimal size is greater 
than size defined in window constructor

ExpandSize = 32,
}

So it looks like the documentation isn't completely up to date 
either. Anyway, I also tried to pass WindowFlag.Resizable | 
WindowFlag.MeasureSize as flags argument in the call to 
createWindow, but it did not help.


I was hoping for a quick answer on the forum from someone who has 
run into the same, but I think I'm going to need to dig into 
dlangui code to figure out what is going wrong.


[1]: 
http://buggins.github.io/dlangui/ddox/dlangui/platforms/common/platform/WindowFlag.html





How to use ResizerWidget in Dlangui app..?

2019-12-30 Thread ShadoLight via Digitalmars-d-learn

Hi,

I suspect I'm missing something obvious, but ResizerWidget is not 
working for me on Windows - it shows the 'dragging'-cursor when 
hovering the mouse on the ResizerWidget, but dragging with the 
left mouse button does nothing.


Reduced very simple example:

///app.d
import dlangui;
import gui;

mixin APP_ENTRY_POINT;


/// entry point for dlangui based application
extern (C) int UIAppMain(string[] args) {
// create window
Window window = Platform.instance.createWindow("DlangUI 
example", null);


//Make main layout
auto mainGui = new GuiHandler();
window.mainWidget = mainGui.makeGui(window);
// show window
window.show();

// run message loop
return Platform.instance.enterMessageLoop();
}

/// gui.d
import dlangui;

class GuiHandler : ResizeHandler {

Widget makeGui(Window w) {
//Make main layout
auto vlayout = new VerticalLayout();
vlayout.margins = 20;
vlayout.padding = 10;ets
vlayout.backgroundColor = 0xC0;
vlayout.layoutWidth(FILL_PARENT).layoutHeight(FILL_PARENT);

// Layout for editors
auto editorsLayout = new LinearLayout();
editorsLayout.orientation = Orientation.Vertical;

//Make edit + trace windows
auto editor = new EditBox();
editorsLayout.addChild(editor);

auto resizer = new ResizerWidget();
//		resizer.resizeEvent.connect(this); //Connect for handling 
events in onResize.

editorsLayout.addChild(resizer);

auto tracer = new LogWidget();
editorsLayout.addChild(tracer);


editorsLayout.layoutWidth(FILL_PARENT).layoutHeight(FILL_PARENT);
vlayout.addChild(editorsLayout);

return vlayout;
}

	override void onResize(ResizerWidget source, ResizerEventType 
event, int currentPosition) {

 //Not shown...
}
}

I searched through all the dlangui examples where ResizerWidget 
is used, and none of them provides any onResize event handler as 
shown above. But, since none of them work (symptoms exactly the 
same as mine), I am wondering if this is required?


Also checking in DlanguiIDE - nowhere does it implements the 
onResize event handler for ResizerWidget either. I find this a 
bit odd - in none of the projects where ResizerWidget are used 
does it work, but none of these projects provide the onResize 
event handler either.  Which makes me suspect it is supposed to 
work 'out of the box' and does not require the event handler for 
the basic dragging functionality - similar how resizing the whole 
window works without requiring that you implement it yourself in 
the OnResize event handler for the main Widget. Also - I can 
hardly believe that Vadim would have kept putting it in examples, 
but without it working, so I suspect some regression here if I am 
not doing something stupid myself (which is always possible!).


There are plenty of 'deprecated' warnings when building dlangui 
and, since dlangui has not been updated since 2018, I'm concerned 
it may be breaking with new versions of the compiler.


Alternatively I'm missing something elementary here..? Has anyone 
used ResizerWidget successfully with a recent version of the 
compiler on Windows?


win 7
DMD32 D Compiler v2.089.1
dlangui-0.9.182



Re: How add "version.txt" Version File by Command Line or by resources.res using dmd.exe

2019-12-10 Thread ShadoLight via Digitalmars-d-learn

On Tuesday, 10 December 2019 at 14:33:41 UTC, Marcone wrote:

On Tuesday, 10 December 2019 at 09:48:11 UTC, ShadoLight wrote:

On Tuesday, 10 December 2019 at 07:23:00 UTC, rumbu wrote:

[...]


To add to Rumbo's comment: to compile a *.rc to *.res file you 
will need a resource compiler.


[...]


Hi, I compile resource using windres.exe of MinGW, Can you send 
me the versionfile code mode to Dlang? Thank you.


I'm not a 100% sure what you mean, but note there isn't a 
specific version "file format" (or something) that specifically 
applies for "dlang apps only" - the format of a *.res applies to 
all executables runnable on a specific platform (eg. EXEs, DLLs, 
etc on Windows in this case).


You can use the same resource compiler to compile a *.rc to a 
*.res file and link this with *.objs files produced in any native 
language (C/C++/D/Pascal/etc) to create your EXE/DLL.


Here, for example, is a kind of minimalist *.rc file from an old 
x86 app I did ages ago (edited to hide real names, etc):



101 ICON DISCARDABLE ".\\Resources\\someicon.ico"

205 BITMAP DISCARDABLE ".\\Resources\\somebitmap.bmp"

STRINGTABLE DISCARDABLE
BEGIN
3001 "This string was loaded from the resource!"
END

/
//
// Version
//
VS_VERSION_INFO VERSIONINFO
 FILEVERSION 2,0,1,2
 PRODUCTVERSION 2,0,0,1
 FILEFLAGSMASK 0x3fL
 #ifdef _DEBUG
 FILEFLAGS 0x1L
#else
 FILEFLAGS 0x0L
#endif
FILEOS 0x4L
 FILETYPE 0x1L
 FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "Comments", "\0"
VALUE "CompanyName", "My Super Co\0"
VALUE "FileDescription", "Blah blah\0"
VALUE "FileVersion", "2, 0, 1, 2\0"
VALUE "InternalName", "MyApp\0"
VALUE "LegalCopyright", "Copyright (C) 2011\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "MyApp.exe\0"
VALUE "PrivateBuild", "\0"
VALUE "ProductName", "Blah blah\0"
VALUE "ProductVersion", "2, 0, 0, 1\0"
VALUE "SpecialBuild", "\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END


You can create the *.rc file by hand, but it is probably easier 
just to use a freely available Resource editor. The above *.rc 
file, IIRC, was created with XN Resource editor [1], but this was 
long ago and nowadays I just typically use the one that is 
bundled as part of Visual Studio.


Linking to a *.res file such as the one above will include the 
resources directly in your EXE, and you then load the resources 
during runtime using the listed "resource identifiers" (for 
example 3001 for the string).


Regarding the version info - it will be automatically displayed 
when you right-click the EXE (or DLL!) and select Properties. But 
this is a feature of Windoxs, not your app. To display the 
version info in your app (for example to display "My App 
v1.0.0.2" instead of just "My App" in the Title-bar) you need to 
do a little bit more work - you need to call the Windows API 
GetFileVersionInfo function [2] to extract the version info. Look 
at this [3] page for an example - it is in C but should be easy 
to adapt.


[1] https://stefansundin.github.io/xn_resource_editor/
[2] 
https://docs.microsoft.com/en-us/windows/win32/api/winver/nf-winver-getfileversioninfoa?redirectedfrom=MSDN
[3] 
https://stackoverflow.com/questions/940707/how-do-i-programmatically-get-the-version-of-a-dll-or-exe-file




Re: How add "version.txt" Version File by Command Line or by resources.res using dmd.exe

2019-12-10 Thread ShadoLight via Digitalmars-d-learn

On Tuesday, 10 December 2019 at 07:23:00 UTC, rumbu wrote:

On Sunday, 8 December 2019 at 20:50:05 UTC, Marcone wrote:

I want to add version to my program.
I have configurated my version file "version.txt",  but I dont 
know how link this file to my program. If Need spec file, 
please send the exemple code of spec. Or is is possible add 
version file by dmd command line or resources. Thank you.


Your version.txt file is python specific, it will not work in D.

You have 2 options:
- create a .res file in Visual Studio and edit it by adding a 
VERSIONINFO resource.
- create a .rc file in any text editor adding a VERSIONINFO 
resource; compile it to .res using rc yourfile.rc


Pass the .res file to the dmd compiler in the command line.


To add to Rumbo's comment: to compile a *.rc to *.res file you 
will need a resource compiler.


Digital Mars's C/C++ tools [1] include one, but I suspect only 
for x86.


But, if you are on Windows, all of the recent Windows SDKs bundle 
the resource compiler as well - in both x86 and x64 versions.


On my PC I have rc.exe as part of SDK v7.1...
c:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Bin\RC.Exe
c:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Bin\x64\RC.Exe

..as well as part of SDK v8.1:
c:\Program Files (x86)\Windows Kits\8.1\bin\x64\rc.exe
c:\Program Files (x86)\Windows Kits\8.1\bin\x86\rc.exe

I don't have SDK 10 installed, but that will probably also 
contain it.


You should be able to get the individual SDKs from [2] or as part 
of a Visual Studio download.


[1] http://ftp.digitalmars.com/bup.zip
[2] 
https://developer.microsoft.com/en-us/windows/downloads/sdk-archive


Re: How polymorphism work in D?

2019-11-06 Thread ShadoLight via Digitalmars-d-learn

On Wednesday, 6 November 2019 at 06:27:32 UTC, OiseuKodeur wrote:
On Wednesday, 6 November 2019 at 06:05:25 UTC, rikki cattermole 
wrote:

On 06/11/2019 6:43 PM, OiseuKodeur wrote:

I have this


[snip]

Rikki's answer is the direct answer to your question since you 
already had the if(..) statements coded in your main function, 
but your code does not really exploit the main abstraction 
advantage that polymorphism offers.


The typical use of polymorphism in terms of your example would be 
where you don't want to mess with the interior details of derived 
classes in your main function - you want to code your logic in 
your main function just keeping the 'interface' as defined by Foo 
in your head. Something like this:


abstract class Foo {
void writeProp();
}

class Bar : Foo
{
float value;

this(float t_value) { value = t_value; }

override void writeProp() {value.writeln;}
}

class Baz : Foo
{
string name;

this(string t_name) { name = t_name; }

override void writeProp() {name.writeln;}
}

void main()
{
Foo foo = new Bar(10);

foo.writeProp;
foo.writeln;
}

The idea is that you can separate Baz and Bar "out of sight" (in 
a library for example) and write your main logic i.t.o. only 
Foo's.


The advantage will become apparent if you want to add another 
class, say Boo : Foo. In your case you would need to add another 
else if(..) clause to your main function in addition to adding 
the class itself. In the above case you only need to add the 
class - you don't need to touch the main function.





Re: Is this a bug? +goto

2018-11-09 Thread ShadoLight via Digitalmars-d-learn

On Thursday, 8 November 2018 at 09:34:34 UTC, Michelle Long wrote:

What I am talking about is about an obvious error...


OK, so here are your code slightly modified:

void main(){
int i;
W:
if(i==0)
goto Q;
int x;

Q:
i++;
if(i==1)
goto W;

writeln("a");
}

This code does not even skip the 'int x;' declaration and 
initialization - it happens the 2nd time after the goto to W - 
but still errors with exactly the same error i.e. 'goto skips 
declaration of variable x'. so this is _clearly_ a bug in the 
compiler (right?), even more so than your original case, since 
the declaration + initialization are not in fact skipped here.


The reason for this behavior is what Jonathan and others have 
tried to explain to you numerous times i.e. that the compiler 
does not do flow analysis, and hence cannot detect that the above 
is in fact working code.


You seem to be stuck on your premise that the compiler should be 
able to detect your "trivially obvious case", but would you also 
expect the compiler to detect the above case? You seem unwilling 
to accept that it is a reasonable trade-off that the compiler 
does not detect your "trivially obvious case", since the general 
case can be arbitrarily complex - and D currently simply does not 
do flow analysis. Maybe in the future it will do some form of 
flow analysis (let's hope!), but currently it doesn't.


This isn't some 'conspiracy' or 'mindless' defense of the status 
quo like you seem to claim:


What you will find with some of these guys is they start with 
the assumption that everything D does is correct then they 
try to disprove anything that goes against it by coming up 
with reasons that explain why D does it the way it does. It 
is circular reasoning and invalid. Each step >>> they come up 
with some new explanation when you pick holes in their 
previous >>> ones.


If the above was really the case there wouldn't be over 4000 bugs 
open in D at the moment [1], since they would be (according to 
you) be rationalized as 'features', not 'bugs', right?


But above all ... I really think that you need to calm down a 
notch or 2, you are seeing way too many conspiracies here. Stuff 
like this...


>> Don't let their psychobabble fool you. They are wrong and 
>> you were right from the start.


[snip]

Is it logical that the compiler **should** error out in the 
first case and no in the second?


That is what the discussion is ALL about.


[snip]

THAT IS FACT! It doesn't matter if the examples work above. I 
have simplified what I have done and in my code I simply add 
brackets and it works! That is what people should be thinking 
about...


[snip]


... You can assume that I know how scopes work.


[snip]

You shouldn't assume everyone can't comprehend such 
trivialities.




[snip]

What happens when you do that you just create noise that makes 
it more difficult to have a proper discussion that gets at the 
whole point of the conversation.


You seem to default to assuming that the person you are talking 
to has no clue about the problem at hand.


You really seem just a tad too certain of your facts and that 
everyone else are just being obstructionists and incapable of 
seeing your point. In fact you seem to be the one to block out 
any 'other' factors raised by others (such as flow analysis), and 
just keep seeing the issue in this simplistic "this is my view 
and (I quote) 'what the discussion is ALL about'... ".


Are you really so convinced that only 'you' are seeing the forest 
for the trees..?


I notice you started off the same way in your 'Dustmite + Visual 
D' thread in the IDE category, chastising Valdimir who 'dared' to 
contradict you:


As the error message says, the problem occurs because another 
file is accessing it.


No, have you not learned in your life time that just because 
something or someeone says something doesn't make it true?


And then, in your typical self-assured way, corrected Vladimir 
for his 'foolish idea' that the issue is unlikely to be the 
junction:


Let me enlighten you a little: The reason why this is most 
likely a junction is:

[snip]

Wow, to be so certain of yourself must be really nice... but... 
maybe a bit foolish, since in the end it turned out  ... Vladimir 
was correct. But I guess the words "I was wrong" are not really 
in your vocabulary, is it?


Maybe you need to take a long calm look at yourself in the 
mirror... no-one here is out to "get you", in fact no-one here 
thinks that the "D-way" is perfect! In fact, most of the 
old-timers here are probably, more than most, aware of the warts 
in D. Stick around on these forums for a few years and you will 
see epic debates between the core developers on why feature 'X' 
is broken, and what should be done to fix it!


But most of all... virtually every person that responded on this 
thread tried to help you, or at least debate with you on the 
why's and the how's...  but you seem to take disagreements as 
persona

Re: Data structures and algorithms in D?

2018-10-08 Thread ShadoLight via Digitalmars-d-learn

On Sunday, 7 October 2018 at 20:27:47 UTC, eastanon wrote:
Are there reading resources on Data structures and Algorithms 
in D? There are several such books in the C/C++ and Java world 
and many senior/experienced D users might have come across them 
in C. But for people who join D after reading Ali's book, a 
data structures and algorithms book in D would be a great next 
step. i.e. a book that uses D's idioms and best practices. Any 
such material in development or recommended blog posts?


AFAIK there is no specific book that focuses and delves into Data 
structures and Algorithms specifically, however there are some 
books (besides Ali's) that touches on it - at least in a limited 
sense specific to the topics in each book.


For example, Adam D. Ruppe's 'D Cookbook' has a chapter on 
Ranges, which also covers using ranges when implementing/using 
algorithms.


Likewise Michael Parker's 'Learning D' book has 2 chapters that 
touches on Ranges and Algorithms:

- Chapter 6: Understanding Ranges
- Chapter 7: Composing Functional Pipelines with Algorithms
and Ranges

I'm not sure about Andrei's TDPL book - I read it so long ago I 
cannot remember. (And I don't have my copy with me so I cannot 
check). And Kai Nacke's 'D Web Development' book does not really 
cover these topics either.


Of the above-mentioned 2 books (that do cover it), I think 
Michael's book is the better resource at the moment (that I am 
aware of anyway). But I'm not sure if I will claim that it covers 
these topics better than Ali's book at the moment - so maybe it 
is not going to be good enough for you either.


Ali's book anyway seems to be regularly updated (since he 
self-publishes it) to be up-to-date with the latest in the D 
language/ecosystem, so I think we will see any new info on this 
in Ali's book before any other book manages to bring out a new 
edition (the other books just regularly published - so are in 
effect really snapshots of the language at the time of 
publication).


Of course, this is besides the problem that containers are 
(still!) somewhat lacking in D compared to other languages - you 
just need to look at [1] to see that.


[1] https://dlang.org/phobos/std_container.html



Link to https://run.dlang.io/ ??

2018-02-20 Thread ShadoLight via Digitalmars-d-learn
It would be nice if there was a link to https://run.dlang.io/ on 
the dlang website - preferably under Resources drop-down menu or 
similar.


Or is there somewhere and I am just missing it?

I have bookmarked it for myself, but it would be better for 
newbies if it was also easily accessible from the website.


Re: Error in template instantiation from D-Cookbook example

2018-02-09 Thread ShadoLight via Digitalmars-d-learn

On Friday, 9 February 2018 at 21:39:22 UTC, Adam D. Ruppe wrote:

On Friday, 9 February 2018 at 21:31:29 UTC, ShadoLight wrote:

[1] https://run.dlang.io/is/dyElXg


There's missing quotes in there:

Line 14:
code ~= "push(call!"~piece~"(pop(), pop()));\n";

Should be:

code ~= "push(call!\""~piece~"\"(pop(), pop()));\n";

[snip]

On Friday, 9 February 2018 at 21:58:51 UTC, Meta wrote:

On Friday, 9 February 2018 at 21:31:29 UTC, ShadoLight wrote:

[snip]
The problem becomes apparent once you uncomment one of these 
and paste the offending string ("5 5 + 3 - 2 * 1 + 3 /") in.

[snip]

push(call!+(pop(), pop()));

[snip]
So it takes a string as its sole template argument. The problem 
is that the code in convertToD forgot to add the quotes around 
the operators that are supposed to be passed as strings to call.

[snip]

Indeed, that makes sense! Thanks to you both!

Adam, you are right - it was indeed incorrectly mangled... it is 
shown as...

code ~= "push(call!'"~piece~"'(pop(), pop()));\n";

So the escaped quotes \" were mangled as '. I simply removed them 
since I assumed they were typos in the doc, similar to the other 
ones I had fixed. My bad.


Man, I cannot believe how quickly you guys answered. Thanks again!


Error in template instantiation from D-Cookbook example

2018-02-09 Thread ShadoLight via Digitalmars-d-learn

Hi,

Trying to improve my CT-fu, I looked at a DSL example (chapter 9) 
in Adam's D-Cookbook. Although I am sure Adam's original examples 
would have worked, there were some errors in the example code in 
the book.


The example also contains some code to allow you to test the 
functions at RT, which had an error i.e. I had to change this...


writeln(parse(code));   // to aid with debugging
writeln(convertToD(parse(code)));   // debugging aid
..to..
writeln(parse(code)[]); // to aid with debugging
writeln(convertToD(parse(code))[]); // debugging aid

..to match the actual function arguments. So that worked fine.

However I could not get the CT version to work with the current 
version of DMD i.e. this [1]...


[1] https://run.dlang.io/is/dyElXg

...fails with:
onlineapp.d-mixin-36(38): Error: template argument expected 
following !
onlineapp.d(48): Error: template instance onlineapp.runDslCode!"5 
5 + 3 - 2 * 1 + 3 /" error instantiating.


I find the error message a bit lacking as to the real cause - I 
really cannot see where the "template argument expected following 
!" error is. It all looks correct to me.


In addition the RT version is working correctly (after fixing the 
above bug), so that is not helping in identifying the error - 
particularly since it is failing in the only CT specific function 
not used/called at RT. So I am not sure how to debug this.


Can somebody please put me out of my misery here?

Thx!