Re: mir.algebraic: Visitor cannot be called

2020-12-09 Thread Andre Pany via Digitalmars-d-learn

On Thursday, 10 December 2020 at 05:49:12 UTC, 9il wrote:

On Wednesday, 9 December 2020 at 14:34:18 UTC, Andre Pany wrote:

[...]


For .member access mir.algebraic checks at compile time that 
all underlying types (except typeof(null)) can be called with 
provided arguments. It is kind of API protection.


Alternatives:

With compile-time known type
```
v.get!A.foo(3); // will throw if it isn't A
v.trustedGet!A.foo(3); // will assert if it isn't A
```

Without compile-time known type
```
v.tryGetMember!"foo"(3); // will throw if it isn't A
v.optionalGetMember!"foo"(3); // will return null Nullable!void 
of it isn't A

```

tryGetMember and optionalGetMember are alternative visitor 
handlers in mir.algebraic.


Kind regards,
Ilya


Fantastic, thanks a lot!

Kind regards
André


Re: mir.algebraic: Visitor cannot be called

2020-12-09 Thread 9il via Digitalmars-d-learn

On Wednesday, 9 December 2020 at 14:34:18 UTC, Andre Pany wrote:

Hi,

I want to port some Python coding and try have as much similiar 
coding as

possible.

I thought I can have a mir variant which stores either class A 
or B

and I can call at runtime a method like this:

```
/+ dub.sdl:
name "app"
dependency "mir-core" version="1.1.51"
+/

import std.stdio: writeln;
import mir.algebraic;

class A {
void foo(int i){writeln("A.foo");}
}

class B {
void foo(int i, string s){writeln("B.foo");}
}

void main() {
Variant!(A,B) v = new A();
v.foo(3);
}
```

But it fails with:
Error: static assert:  "Algebraic!(A, B): the visitor cann't be 
caled with arguments (B, int)"


The error message seems strange. Is the behavior I want somehow 
possible?
(At runtime I know whether I have an object of A or B and will 
only call

with the correct method signature).

Kind regards
André


For .member access mir.algebraic checks at compile time that all 
underlying types (except typeof(null)) can be called with 
provided arguments. It is kind of API protection.


Alternatives:

With compile-time known type
```
v.get!A.foo(3); // will throw if it isn't A
v.trustedGet!A.foo(3); // will assert if it isn't A
```

Without compile-time known type
```
v.tryGetMember!"foo"(3); // will throw if it isn't A
v.optionalGetMember!"foo"(3); // will return null Nullable!void 
of it isn't A

```

tryGetMember and optionalGetMember are alternative visitor 
handlers in mir.algebraic.


Kind regards,
Ilya



Re: where is the memory corruption?

2020-12-09 Thread Paul Backus via Digitalmars-d-learn

On Wednesday, 9 December 2020 at 21:21:58 UTC, ag0aep6g wrote:


D's wchar is not C's wchar_t. D's wchar is 16 bits wide. The 
width of C's wchar_t is implementation-defined. In your case 
it's probably 32 bits.


In D, C's wchar_t is available as `core.stdc.stddef.wchar_t`.

http://dpldocs.info/experimental-docs/core.stdc.stddef.wchar_t.1.html


Re: where is the memory corruption?

2020-12-09 Thread ag0aep6g via Digitalmars-d-learn

On 09.12.20 21:35, Jack wrote:
I'm on linux/opensuse, trying to pass a wchar_* from C to D but I'm 
getting only the first letter of that string. Could someone help figure 
out why?


this is the piece of D code:

extern(C) export
void sayHello(const (wchar) *s)

[...]
and below the piece of C code where I call the lib's function, compiled 
with clang -std=c11 -m64 dll.c -ldl

[...]

   const wchar_t *s2 = L"hello!";
   void (*fp)(const wchar_t*) = dlsym(lh, "sayHello");
   char *de = dlerror();
   if(de) {
     fprintf(stderr, "slsym error:%s\n", de);
     return EXIT_FAILURE;
   }
   fp(s2);

the output is "h" rather "hello". What am I missing?


D's wchar is not C's wchar_t. D's wchar is 16 bits wide. The width of 
C's wchar_t is implementation-defined. In your case it's probably 32 bits.


Because of that size mismatch, sayHello sees your L"hello!" string as 
"h\0e\0l\0l\0o\0!\0"w. And the conversion correctly stops at the first 
null character.


My C isn't very good, but I think char_16t is the correct analog to D's 
wchar. https://en.cppreference.com/w/c/string/multibyte/char16_t


Re: where is the memory corruption?

2020-12-09 Thread Dukc via Digitalmars-d-learn

On Wednesday, 9 December 2020 at 20:35:21 UTC, Jack wrote:

the output is "h" rather "hello". What am I missing?


In the sayHello function, you are converting a pointer to utf16 
character into utf8 string, not utf16 string to utf8 string. 
Convert the C wstring to a D `wstring` first 
(std.string.fromStringz).




where is the memory corruption?

2020-12-09 Thread Jack via Digitalmars-d-learn
I'm on linux/opensuse, trying to pass a wchar_* from C to D but 
I'm getting only the first letter of that string. Could someone 
help figure out why?


this is the piece of D code:

extern(C) export
void sayHello(const (wchar) *s)
{
import std.stdio : writeln;
import std.conv : to;

import core.runtime : rt_init, rt_term;
rt_init();
scope(exit) rt_term();

writeln("+sayHello()");
auto s2 = to!string(s);
writeln("s2 = ", s2);
writeln("-sayHello()");
}

build with dub, using "targetType": "dynamicLibrary" in dub.json.

and below the piece of C code where I call the lib's function, 
compiled with clang -std=c11 -m64 dll.c -ldl



  const char *libpath = "path/to/library.so";
  void *lh = dlopen(libpath, RTLD_LAZY);
  if(!lh) {
fprintf(stderr, "dlopen error: %s\n", dlerror());
return EXIT_FAILURE;
  }

  const wchar_t *s2 = L"hello!";
  void (*fp)(const wchar_t*) = dlsym(lh, "sayHello");
  char *de = dlerror();
  if(de) {
fprintf(stderr, "slsym error:%s\n", de);
return EXIT_FAILURE;
  }
  fp(s2);

the output is "h" rather "hello". What am I missing?


Re: How to make Create Window Work?

2020-12-09 Thread Ruby The Roobster via Digitalmars-d-learn
On Wednesday, 9 December 2020 at 17:57:49 UTC, Adam D. Ruppe 
wrote:


C will cast 0 to null implicitly, D will not. If there's ever a 
case where you need to pass a number as a handle (like some 
HBRUSHe among others), you then explicitly cast it like 
`cast(HANDLE) -1`. (HANDLE is an alias to void* too so that 
would also work)


Thank you. Now it works.


Re: How to make Create Window Work?

2020-12-09 Thread Adam D. Ruppe via Digitalmars-d-learn
On Wednesday, 9 December 2020 at 17:45:18 UTC, Ruby The Roobster 
wrote:

 0, // window menu


here, that's the only int you do and I'm pretty sure that's 
supposed a be a HMENU which is a HANDLE, which is a void* rather 
than an int.


C will cast 0 to null implicitly, D will not. If there's ever a 
case where you need to pass a number as a handle (like some 
HBRUSHe among others), you then explicitly cast it like 
`cast(HANDLE) -1`. (HANDLE is an alias to void* too so that would 
also work)


But for 0 you almost certainly just want to get in the habit of 
using the built in `null` instead 0.


re NULL vs null, both are OK here, but since NULL can actually be 
overridden by other libs (it is just a library constant) you're 
better off consistently using `null` for those too.


Re: How to make Create Window Work?

2020-12-09 Thread Ruby The Roobster via Digitalmars-d-learn
Also, here is the error in full: E:\Users\User\Desktop\tet.d|100| 
  cannot pass argument `0` of type `int` to parameter `void* 
i`|


Re: How to make Create Window Work?

2020-12-09 Thread Ruby The Roobster via Digitalmars-d-learn
On Wednesday, 9 December 2020 at 17:42:50 UTC, Adam D. Ruppe 
wrote:
On Wednesday, 9 December 2020 at 17:37:16 UTC, Ruby The 
Roobster wrote:

It's not the 'NULL' that's the error.


I know.


It doesn't compile because of the '0'
. That is what I need to fix, since I want to make a 
WM_COMMAND for that button.


Use lowercase `null` instead.


I did. Still gives an error:

LRESULT WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM 
lParam) nothrow

{
scope (failure) assert(0);

HDC hdc;
PAINTSTRUCT ps;
RECT rect;

switch (message)
{
case WM_CREATE:
 CreateWindow("BUTTON".toUTF16z,  // window class 
name

 "The Hello Program",  // window caption
 WS_CHILD | WS_VISIBLE,  // window style
 CW_USEDEFAULT,// initial x 
position
 CW_USEDEFAULT,// initial y 
position

 250,// initial x size
 250,// initial y size
 hwnd, // parent window 
handle

 0, // window menu handle
 null,// program instance 
handle

 null);
 return 0;
case WM_COMMAND:
case WM_DESTROY:
PostQuitMessage(0);
return 0;

default:
}

return DefWindowProc(hwnd, message, wParam, lParam);
}


Re: How to make Create Window Work?

2020-12-09 Thread Adam D. Ruppe via Digitalmars-d-learn
On Wednesday, 9 December 2020 at 17:37:16 UTC, Ruby The Roobster 
wrote:

It's not the 'NULL' that's the error.


I know.


It doesn't compile because of the '0'
. That is what I need to fix, since I want to make a WM_COMMAND 
for that button.


Use lowercase `null` instead.



Re: How to make Create Window Work?

2020-12-09 Thread Ruby The Roobster via Digitalmars-d-learn
On Wednesday, 9 December 2020 at 17:32:57 UTC, Adam D. Ruppe 
wrote:
On Wednesday, 9 December 2020 at 17:25:10 UTC, Ruby The 
Roobster wrote:
 CreateWindow("BUTTON".toUTF16z,  // window 
class name


fyi for a string literal like this you can just do

"BUTTON"w.ptr // note the w

This gives an error saying: Cannot pas argument of type 'int' 
to argument of type 'void*'. How is this fixed?


Use lowercase `null` instead.


It's not the 'NULL' that's the error. It doesn't compile because 
of the '0'
. That is what I need to fix, since I want to make a WM_COMMAND 
for that button.


Re: How to make Create Window Work?

2020-12-09 Thread Adam D. Ruppe via Digitalmars-d-learn
On Wednesday, 9 December 2020 at 17:25:10 UTC, Ruby The Roobster 
wrote:
 CreateWindow("BUTTON".toUTF16z,  // window 
class name


fyi for a string literal like this you can just do

"BUTTON"w.ptr // note the w

This gives an error saying: Cannot pas argument of type 'int' 
to argument of type 'void*'. How is this fixed?


Use lowercase `null` instead.


How to make Create Window Work?

2020-12-09 Thread Ruby The Roobster via Digitalmars-d-learn

Here is the code im using:

extern(Windows)
LRESULT WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM 
lParam) nothrow

{
scope (failure) assert(0);

HDC hdc;
PAINTSTRUCT ps;
RECT rect;

switch (message)
{
case WM_CREATE:
 CreateWindow("BUTTON".toUTF16z,  // window class 
name

 "The Hello Program",  // window caption
 WS_CHILD | WS_VISIBLE,  // window style
 CW_USEDEFAULT,// initial x 
position
 CW_USEDEFAULT,// initial y 
position

 250,// initial x size
 250,// initial y size
 hwnd, // parent window 
handle

 0, // window menu handle
 NULL,// program instance 
handle

 NULL);
 return 0;
case WM_COMMAND:
case WM_DESTROY:
PostQuitMessage(0);
return 0;

default:
}

return DefWindowProc(hwnd, message, wParam, lParam);
}


This gives an error saying: Cannot pas argument of type 'int' to 
argument of type 'void*'. How is this fixed?


Re: To use or not immutable?

2020-12-09 Thread Dukc via Digitalmars-d-learn

On Wednesday, 9 December 2020 at 16:47:43 UTC, Jack wrote:
Do you use it in your code base? are there some design flaws, 
like there's in C++'s const, which I'm not aware of?


There are downsides, Jonathan Davis has written about them: 
http://www.jmdavisprog.com/articles/why-const-sucks.html


But the downside of D's `const` or `immutable` are mainly that 
you can't use them everywhere you might wish to. A good rule of 
thumb is that if you can get it to pass compilation as `const` or 
`immutable` without any hacks, there is no problem going ahead 
with it.


To use or not immutable?

2020-12-09 Thread Jack via Digitalmars-d-learn
I'm coding with visual studio code and now it shows a yellow mark 
on variables that is never modified and that could be marked as 
const or immutable. I think that makes sense, so I think I'll be 
using it. Do you use it in your code base? are there some design 
flaws, like there's in C++'s const, which I'm not aware of?


mir.algebraic: Visitor cannot be called

2020-12-09 Thread Andre Pany via Digitalmars-d-learn

Hi,

I want to port some Python coding and try have as much similiar 
coding as

possible.

I thought I can have a mir variant which stores either class A or 
B

and I can call at runtime a method like this:

```
/+ dub.sdl:
name "app"
dependency "mir-core" version="1.1.51"
+/

import std.stdio: writeln;
import mir.algebraic;

class A {
void foo(int i){writeln("A.foo");}
}

class B {
void foo(int i, string s){writeln("B.foo");}
}

void main() {
Variant!(A,B) v = new A();
v.foo(3);
}
```

But it fails with:
Error: static assert:  "Algebraic!(A, B): the visitor cann't be 
caled with arguments (B, int)"


The error message seems strange. Is the behavior I want somehow 
possible?
(At runtime I know whether I have an object of A or B and will 
only call

with the correct method signature).

Kind regards
André