Re: CTFE write message to console

2024-04-05 Thread Carl Sturtivant via Digitalmars-d-learn

On Friday, 5 April 2024 at 07:37:20 UTC, Paolo Invernizzi wrote:

pragma(msg, x) ?


No.

`__ctfeWrite(x)` is executed inside an executing function like 
any other statement in it, and can have an argument `x` computed 
during that execution.


It is defined to output the computed text `x` to stderr when the 
function it is a part of is called as CTFE by the compiler and to 
be a no-op if that function is called at run time in the compiled 
executable.


So it is a replacement for `std.stdio.write` in a CTFE function, 
handy among other things for reporting what's going on during the 
execution of that function by the compiler.


`pragma(msg, x)` works during its *compilation*, so putting it as 
a line in a CTFE-called function would not execute it when the 
function is called by the compiler. That being the case, `x` may 
not be a value computed when that function executes. Such a value 
is "not available at compile time", only at CTFE run time. The 
CTFE function is not running when it is being compiled.


It is possible that `x` in `pragma(msg, x)` be computed with a 
call to a function as its return value, i.e. computed by CTFE, 
but that call will be made when `pragma(msg, x)` is compiled, and 
is a part of compiling it. Only when the function has returned 
producing `x` does the `pragma(msg, x)` do its work.


Re: CTFE write message to console

2024-04-04 Thread Carl Sturtivant via Digitalmars-d-learn
On Thursday, 4 April 2024 at 15:47:53 UTC, Richard (Rikki) Andrew 
Cattermole wrote:

Oh hey!

https://github.com/dlang/dmd/pull/16250

It was implemented literally 2 weeks ago!

Nightly should have it 
https://github.com/dlang/dmd/releases/tag/nightly


Wow! Happy that's in. It was a bit mysterious, but now that 
request says it was never implemented. Until now. Just what I 
want!


Re: CTFE write message to console

2024-04-04 Thread Carl Sturtivant via Digitalmars-d-learn
On Thursday, 4 April 2024 at 15:07:21 UTC, Richard (Rikki) Andrew 
Cattermole wrote:


Ah yes, I forgot about that particular thing, doesn't see much 
use as far as I'm aware.


It should be working though.


```D
enum X = computeX("A message");

string computeX(string msg) {
auto s = "CTFE msg: ";
auto x = imported!"std.format".format("%s%s\n", s, msg);
__ctfeWrite(x);
return x;
}

void main() {
import std.stdio;
writeln(X);
}
```
Produces no output on compilation, and writes out `CTFE msg: A 
message` when run.




Re: CTFE write message to console

2024-04-04 Thread Carl Sturtivant via Digitalmars-d-learn
On Thursday, 4 April 2024 at 14:06:19 UTC, Richard (Rikki) Andrew 
Cattermole wrote:


```d
static assert(0, "message");
```

Or if it is known to be CTFE'd

```d
assert(0, "message");
```

Just a warning, its a one time use only for both.

No other way to do it.


That's ... unfortunate.

Some search of the forum led me to some [decade plus old 
discussion](https://forum.dlang.org/post/j1n1m2$24p0$1...@digitalmars.com) of a possible CTFE writeln function that would be a no-op at runtime, which to my surprise led me to find [core_builtins.__ctfeWrite](https://dlang.org/phobos/core_builtins.html#.__ctfeWrite) but when I tried it out, it compiled yet output no text to the console. Given your remarks I suppose I should have expected this.


Re: std.traits.ParameterIdentifierTuple problem

2024-04-02 Thread Carl Sturtivant via Digitalmars-d-learn

On Monday, 1 April 2024 at 18:28:16 UTC, Nick Treleaven wrote:

On Sunday, 31 March 2024 at 23:05:44 UTC, Carl Sturtivant wrote:

Yes, it's not possible to instantiate a function type.


But with extern it seems the semantics is fine as a function 
is not being instantiated. It is merely associating a name 
with a type: in what sense is this instantiation in any 
reasonable way?


Yes there is no instantiation for extern. But what would be the 
use of allowing an extern function type instance, when there's 
no way to instantiate it?


1. For compile time work that uses the name but not the function 
it nominally refers to. That's what I wanted it for: 
`ParameterIdentifierTuple` might actually work on that.


2. In fact the definition might refer to a function defined in 
another module, for example brought in by ImportC. It's an 
alternative way of writing the signature of an external function. 
Why rule it out when it is reasonable?


The first could also work with an explicitly uninstantiated 
function, as in `enum FUNCTYPE f = void;` hence my second attempt 
above.


As long as there are compile-time actions that work on functions 
but not their types, this would be a way to work around that.





Re: std.traits.ParameterIdentifierTuple problem

2024-03-31 Thread Carl Sturtivant via Digitalmars-d-learn

On Sunday, 31 March 2024 at 11:35:39 UTC, Nick Treleaven wrote:
If a function type does include identifiers, then would two 
function types with the same argument types but different 
identifiers compare equal using `is`?


Yes. That is the idea. Define `is` to work this way.


Yes, it's not possible to instantiate a function type.


But with extern it seems the semantics is fine as a function is 
not being instantiated. It is merely associating a name with a 
type: in what sense is this instantiation in any reasonable way?





Re: std.traits.ParameterIdentifierTuple problem

2024-03-30 Thread Carl Sturtivant via Digitalmars-d-learn

On Saturday, 30 March 2024 at 22:37:53 UTC, Carl Sturtivant wrote:

Incidentally, I tried
```D
extern typeof(foo) func;
```
to say that func was an actual function (`extern` so defined 
elsewhere) whose type was the type of the function `int foo(int 
num, string name, int);` so I can then use 
`ParameterIdentifierTuple` on a function, not a type, but the 
compiler said `bug1.d(5): Error: variable ``bug1.func`` cannot 
be declared to be a function`. Seems unreasonable given the 
implied semantics.


The word *variable* in that error message caught my eye and it 
struck me that in some sense a function is a constant, not a 
variable, we have function pointers for the last. So I tried

```D
enum typeof(foo) func = void;
```
to see if I could escape this difficulty. Sadly got exactly the 
same error message, even though no variable was involved.


Re: std.traits.ParameterIdentifierTuple problem

2024-03-30 Thread Carl Sturtivant via Digitalmars-d-learn

On Saturday, 30 March 2024 at 21:07:35 UTC, Nick Treleaven wrote:
Although `.stringof` on a function type does include the 
parameter names, the names are not really part of the type - 
see:

https://github.com/dlang/phobos/pull/3620#issuecomment-288469685

Perhaps `ParameterIdentifierTuple` should give a compile error 
when given a function type.


I'm inclined to a view that keeps more "it just works" options 
open. Regard the parameter names as a part of the type (which I 
am very grateful for them being currently) and just regard part 
of the definition of "type equality" as being to ignore parameter 
names when comparing types.


With this viewpoint, ParameterIdentifierTuple should be repaired 
to work with function types just as it works with functions, and 
the current behavior is a bug.


Incidentally, I tried
```D
extern typeof(foo) func;
```
to say that func was an actual function (`extern` so defined 
elsewhere) whose type was the type of the function `int foo(int 
num, string name, int);` so I can then use 
`ParameterIdentifierTuple` on a function, not a type, but the 
compiler said `bug1.d(5): Error: variable ``bug1.func`` cannot be 
declared to be a function`. Seems unreasonable given the implied 
semantics.




Re: std.traits.ParameterIdentifierTuple problem

2024-03-30 Thread Carl Sturtivant via Digitalmars-d-learn

On Saturday, 30 March 2024 at 21:51:34 UTC, Nick Treleaven wrote:
On Saturday, 30 March 2024 at 21:45:34 UTC, Nick Treleaven 
wrote:
On Saturday, 30 March 2024 at 21:25:45 UTC, Carl Sturtivant 
wrote:
OK, so how can I get them? Am I forced to take that string 
and parse it with CTFE?


Lookup the source of ParameterIdentifierTuple and change 
`FunctionTypeOf!func` to just `func` inside the first `static 
if`.


Sorry, that actually doesn't work.


I appreciate you actually having a shot at this! No apology 
necessary!




Re: std.traits.ParameterIdentifierTuple problem

2024-03-30 Thread Carl Sturtivant via Digitalmars-d-learn

On Saturday, 30 March 2024 at 21:07:35 UTC, Nick Treleaven wrote:
On Saturday, 30 March 2024 at 19:23:07 UTC, Carl Sturtivant 
wrote:

$ dmd -c bug1.d
int(int num, string name, int)
["", "", ""]
bug1.d(9): Error: static assert:  "wrong!"
```
Please explain. How do I get the names of the identifiers out 
of a parameter list at compile time reliably?


Although `.stringof` on a function type does include the 
parameter names, the names are not really part of the type - 
see:

https://github.com/dlang/phobos/pull/3620#issuecomment-288469685

Perhaps `ParameterIdentifierTuple` should give a compile error 
when given a function type.


OK, so how can I get them? Am I forced to take that string and 
parse it with CTFE?


std.traits.ParameterIdentifierTuple problem

2024-03-30 Thread Carl Sturtivant via Digitalmars-d-learn
Using the 
[ParameterIdentifierTuple](https://dlang.org/phobos/std_traits.html#ParameterIdentifierTuple) example just there, with one more step stops working. Details:

```D
import std.traits;
int foo(int num, string name, int);
static assert([ParameterIdentifierTuple!foo] == ["num", "name", 
""]);


alias signature = typeof(foo);
pragma(msg, signature.stringof);
enum names = [ParameterIdentifierTuple!signature];
pragma(msg, names.stringof);
static assert(names==["num","name",""], "wrong!");
```
Output on compilation:
```
$ dmd --version
DMD64 D Compiler v2.107.0
Copyright (C) 1999-2024 by The D Language Foundation, All Rights 
Reserved written by Walter Bright


$ dmd -c bug1.d
int(int num, string name, int)
["", "", ""]
bug1.d(9): Error: static assert:  "wrong!"
```
Please explain. How do I get the names of the identifiers out of 
a parameter list at compile time reliably?




Re: Hidden members of Class objects

2024-03-26 Thread Carl Sturtivant via Digitalmars-d-learn
On Thursday, 7 March 2024 at 00:38:30 UTC, Richard (Rikki) Andrew 
Cattermole wrote:
Yes its opt-in. 
https://dlang.org/spec/statement.html#synchronized-statement


As you mentioned in another thread there's handy ABI 
documentation for classes and interfaces just here 
[https://dlang.org/spec/abi.html#classes](https://dlang.org/spec/abi.html#classes) that spells out the story.


Re: DFLAGS and DMD Windows

2024-03-21 Thread Carl Sturtivant via Digitalmars-d-learn

On Thursday, 21 March 2024 at 18:17:00 UTC, Carl Sturtivant wrote:
On Wednesday, 20 March 2024 at 22:53:13 UTC, Carl Sturtivant 
wrote:
Is it me, or does the [DFLAGS environment 
variable](https://dlang.org/dmd-windows.html#environment) have 
no effect on DMD.

```
dmd --version
DMD64 D Compiler v2.107.0
```


Anyone?


Well, the docs are bogus.
https://issues.dlang.org/show_bug.cgi?id=1660
Would have been nice if they'd mentioned this.



Re: ImportC GUID compilation problem with some Windows headers

2024-03-21 Thread Carl Sturtivant via Digitalmars-d-learn

On Thursday, 21 March 2024 at 22:33:17 UTC, Dave P. wrote:
I filed a bug for this: 
https://issues.dlang.org/show_bug.cgi?id=24447


I haven’t tried on  a windows box and this is just from me 
grepping through header files, but maybe try to `#define 
EXTERN_C` as nothing in the meantime?


I'll give it a shot. Thanks for the bug report.



Re: DFLAGS and DMD Windows

2024-03-21 Thread Carl Sturtivant via Digitalmars-d-learn
On Wednesday, 20 March 2024 at 22:53:13 UTC, Carl Sturtivant 
wrote:
Is it me, or does the [DFLAGS environment 
variable](https://dlang.org/dmd-windows.html#environment) have 
no effect on DMD.

```
dmd --version
DMD64 D Compiler v2.107.0
```


Anyone?


Re: ImportC GUID compilation problem with some Windows headers

2024-03-21 Thread Carl Sturtivant via Digitalmars-d-learn

On Thursday, 21 March 2024 at 00:06:56 UTC, Carl Sturtivant wrote:

```C
EXTERN_GUID(IID_IBlahBlahBlah, 0xabcdef12, 0x11d2, 0xab3a, 
0xc0, 0x4f, [...] );

```


Has anyone successfully compiled an EXTERN_GUID declaration like 
this in a Windows header with ImportC using some C macro trickery 
for example?





ImportC GUID compilation problem with some Windows headers

2024-03-20 Thread Carl Sturtivant via Digitalmars-d-learn
I'm running into this COM related issue with some Windows 
headers, in the case when each GUID is declared in such a file as 
follows.

```C
EXTERN_GUID(IID_IBlahBlahBlah, 0xabcdef12, 0x11d2, 0xab3a, 0xc0, 
0x4f, [...] );

```
and ImportC which is compiling `blah.c` containing only a few 
macro definitions and a single include of a header file say 
 encounters these and responds with

```
[...] waffle.h(123): Error: variable `waffle.IID_IBlahBlahBlah` 
extern symbols cannot have initializers

```
Presumably MSVC simply compiles such files, but DMD's ImportC is 
too strict to do so. I've worked around this in some very dirty 
and inconvenient ways, but am hoping for a real solution of some 
kind. I want to use some of these IIDs and CLSIDs so I need to 
make these declarations work in some fashion. Inclusions are 
nested so these may be far from the header file I am including in 
`blah.c`. Any help appreciated.


Re: Need help with Windows linkage ( DMD using ImportC)

2024-03-20 Thread Carl Sturtivant via Digitalmars-d-learn
I found a way to make a solution for 64 bit Windows mechanically 
with many MSVC intrinsics, using only mingw64.

Here's an [MSYS2](https://www.msys2.org/) bash script.
```bash
gcc -E -P intrin.c -o vcintrinsics.c

sed -i 's/extern __inline__ 
__attribute__((__always_inline__,__gnu_inline__))//g' 
vcintrinsics.c


gcc -fPIC -shared -o vcintrinsics.dll vcintrinsics.c 
-Wl,--export-all-symbols -Wl,--output-def=vcintrinsics.def


#lib -nologo -machine:x64 -def:vcintrinsics.def 
-out:vcintrinsics.lib


dlltool -D vcintrinsics.dll -d vcintrinsics.def -l 
vcintrinsics.lib -m i386:x86-64


cp vcintrinsics.dll /c/D/dmd2/windows/bin64/
cp vcintrinsics.lib /c/D/dmd2/windows/lib64/
```
The commented out line is using the MS librarian to do the same 
job as the mingw64 libtool. This script builds a dll containing 
100+ intrinsics defined in mingw64 and makes an import library 
for DMD to use it from a developer command prompt.


`intrin.c` contains only `#include ` and is 
preprocessed in the first line into `vcintrinsics.c` which if 
examined contains working definitions of many intrinsics but with 
`extern __inline__ 
__attribute__((__always_inline__,__gnu_inline__))` prefixing 
them, so they will not compile to actual library functions. The 
sed command strips those prefixes out, and the compilation makes 
a DLL containing the the intrinsics and a DEF file listing their 
names for linkage, ready for dlltool to assemble an import 
library suitable for DMD to link to so as to be able to 
dynamically link the DLL.


And that's it; so far the result has just worked and I've had no 
linkage issues due to missing MSVC intrinsics since. I just put 
vcintrinsics.lib on the end of the dmd command line whenever I'm 
using real Windows headers in ImportC and the linker has always 
been satisfied so far. When I'm done, I can remove vcintrinsics 
from the dmd command line, and find out which intrinsics are 
actually needed for linking, and using the technique earlier in 
the thread above, satisfy those directly, so the result doesn't 
need vcintrinsics.dll.


Hopefully DMD will soon know about these MSVC intrinsics but 
until then this is an effective way to more-or-less permanently 
work around the inevitable linkage problems.


DFLAGS and DMD Windows

2024-03-20 Thread Carl Sturtivant via Digitalmars-d-learn
Is it me, or does the [DFLAGS environment 
variable](https://dlang.org/dmd-windows.html#environment) have no 
effect on DMD.

```
dmd --version
DMD64 D Compiler v2.107.0
```



Re: Need help with Windows linkage ( DMD using ImportC)

2024-03-10 Thread Carl Sturtivant via Digitalmars-d-learn

On Thursday, 7 March 2024 at 18:14:32 UTC, Gregor Mückl wrote:
2. C code referring to MSVC-specific compiler intrinsics. At 
least InterlockedExchangeAdd, InterlockedExchangeAdd64 and 
_stosb are such intrinsics. This is harder to resolve. There 
are two ways forward here: either implement a shim function 
that replicates the intrinsic's functionality if possible or 
add support for these intrinsics to DMD.


Thanks for the explanation, on the strength of which I found a 
way to deal with this correctly.


I made `intrinsics1.c` that has `#include ` and 
contains an actual function for each missing intrinsic; e.g. for 
the missing __shiftright128 it has

```C
unsigned __int64 D__shiftright128(
   unsigned __int64 LowPart,
   unsigned __int64 HighPart,
   unsigned char Shift
)
{ return __shiftright128(LowPart, HighPart, Shift); }

```
where I got the prototypes from this [list of 
intrinsics](https://learn.microsoft.com/en-us/cpp/intrinsics/alphabetical-listing-of-intrinsic-functions?view=msvc-170).


Compiling this with MSVC `cl -c intrinsics1.c` produces a COFF 
object `intrinsics1.obj` containing an actual function to link to 
for each intrinsic. So this stage writes the code so we don't 
have to.


As a matter of necessity, the names of the functions in 
`intrinsics1.c` representing the MSVC intrinsics are not the same 
as their actual names. By my convention above they are prefixed 
with "D". Now we could simply write an extern(C) D function in a 
module say `vcintrinsics.d`, that has exactly the intrinsic's 
name, and calls the "D" prefixed function linked from 
`intrinsics1.obj`, e.g. for the above example `vcintrinsics.d` 
could contain

```D
extern(C):

extern ulong D__shiftright128(ulong LowPart, ulong HighPart, 
ubyte Shift);


ulong __shiftright128(ulong LowPart, ulong HighPart, ubyte Shift){
return D__shiftright128(LowPart, HighPart, Shift);
}
```
As DMD doesn't know of these intrinsics, it won't complain about 
defining a function with exactly the same name as an intrinsic so 
as to implement that intrinsic as an actual function, solving the 
problem. `dmd -lib vcintrinsics.d intrinsics1.obj` then produces 
a library that resolves the linkage issue.


An alternative not involving having two function calls to 
implement an intrinsic is to compile `intrinsics1.c` with MSVC 
into a DLL, and using a DEF file that renames the exports just 
like part of the solution 
[here](https://forum.dlang.org/post/ruupyklfkrvnjtker...@forum.dlang.org) make those functions available under their original names when linking to its import library.


A lot of both of the above is boilerplate and can be automated. 
It would be even nicer if the MSVC tools could be persuaded to 
proceed in a similar way with DEF file renaming when building a 
static library, but I have not succeeded in making this happen. 
Anyone?


Re: DMD windows and Clang's llvm-link.exe

2024-03-09 Thread Carl Sturtivant via Digitalmars-d-learn
On Sunday, 10 March 2024 at 04:22:20 UTC, Richard (Rikki) Andrew 
Cattermole wrote:

On 10/03/2024 4:46 PM, Carl Sturtivant wrote:
suggesting that there's a reason version 9 instead of 17 of 
lld is being used in the latest DMD installation, that may be 
relevant what I'd like to try. Any idea what that might be?


Yes, nobody has updated it.

https://github.com/dlang/installer/blob/50f5825e9d9bf44afb9108f0c1a01a8038d2f156/.github/workflows/build_windows.yml#L22

The ldc one should match whatever LLVM is which is newer.


No technical reason then, I assume you mean.


Re: DMD windows and Clang's llvm-link.exe

2024-03-09 Thread Carl Sturtivant via Digitalmars-d-learn
On Saturday, 9 March 2024 at 22:07:05 UTC, Richard (Rikki) Andrew 
Cattermole wrote:

lld is used and distributed with dmd and ldc.

That is known to work.

If you have MSVC, it'll prefer that however.


Interesting, perhaps I should have known that, though I have not 
used DMD on Windows for many years until now.


I have this from a 64-bit "Developer Command Prompt":
```

lld-link --version
LLD 9.0.0 (https://github.com/dlang/installer 
d4266cf3dccfd7a7d361d28143f86e98b2da8db8)

dmd --version

DMD64 D Compiler v2.107.0
Copyright (C) 1999-2024 by The D Language Foundation, All Rights 
Reserved written by Walter Bright

```
Whereas from an MSYS2 Clang64 terminal I have this:
```
$ lld-link --version
LLD 17.0.6$ clang --version
clang version 17.0.6
```
suggesting that there's a reason version 9 instead of 17 of lld 
is being used in the latest DMD installation, that may be 
relevant what I'd like to try. Any idea what that might be?




DMD windows and Clang's llvm-link.exe

2024-03-09 Thread Carl Sturtivant via Digitalmars-d-learn
I'd like to see if I can get dmd to work correctly with Clang 
rather than MS tools. Can anyone share any experience they've had 
with this or any understanding of the situation?




Re: Need help with Windows linkage ( DMD using ImportC)

2024-03-09 Thread Carl Sturtivant via Digitalmars-d-learn

On Thursday, 7 March 2024 at 18:14:32 UTC, Gregor Mückl wrote:
1. Missing import libraries for Win32 API functions. Anything 
starting with `__imp_` is a symbol that should be provided by a 
DLL import library. MapViewOfFileNuma2 for example is provided  
by onecore.lib in the Windows SDK, according to Microsoft 
documentation.


Onecore: not sure what I did to add that dependency. Two symbols 
there. Thanks for the __imp_ clue.


2. C code referring to MSVC-specific compiler intrinsics. At 
least InterlockedExchangeAdd, InterlockedExchangeAdd64 and 
_stosb are such intrinsics. This is harder to resolve. There 
are two ways forward here: either implement a shim function 
that replicates the intrinsic's functionality if possible or 
add support for these intrinsics to DMD.


Yes, not sure what the potential consequences are for my dirty 
replacement. Presumably DMD itself won't generate code using 
these, but ...




Re: Hidden members of Class objects

2024-03-06 Thread Carl Sturtivant via Digitalmars-d-learn

On Wednesday, 6 March 2024 at 23:45:00 UTC, H. S. Teoh wrote:
In D, there's a pointer to the vtable and another pointer to a 
Monitor object (used for synchronized methods).  There was talk 
about getting rid of the Monitor field years ago, but nothing 
has happened yet.


Very interesting: is the monitor field ever touched by compiled D 
code at any point nowadays? Or is it just vestigial?




Hidden members of Class objects

2024-03-06 Thread Carl Sturtivant via Digitalmars-d-learn
I notice that a class with no data members has a size of two 
words (at 64 bits). Presumably there's a pointer to a table of 
virtual functions, and one more. Is the Vtable first?


A COM class that inherits from IUnknown and has no data members 
has a size of three words, presumably as before plus something 
that ordinarily is in the Vtable but can't be for a COM object as 
it has its own layout of that.


What is actually in these objects using that space?


Re: Need help with Windows linkage ( DMD using ImportC)

2024-03-04 Thread Carl Sturtivant via Digitalmars-d-learn

On Monday, 4 March 2024 at 21:21:20 UTC, Carl Sturtivant wrote:

```
blah.obj: error LNK2019: unresolved external symbol _mul128 
referenced in function MultiplyExtract128
blah.obj: error LNK2019: unresolved external symbol 
__shiftright128 referenced in function MultiplyExtract128
blah.obj: error LNK2019: unresolved external symbol _umul128 
referenced in function UnsignedMultiplyExtract128
blah.obj: error LNK2019: unresolved external symbol __stosb 
referenced in function RtlSecureZeroMemory
blah.obj: error LNK2019: unresolved external symbol 
__readgsqword referenced in function NtCurrentTeb
blah.obj: error LNK2019: unresolved external symbol 
__imp_MapViewOfFileNuma2 referenced in function MapViewOfFile2
blah.obj: error LNK2019: unresolved external symbol 
__imp_CharUpperW referenced in function ua_CharUpperW

```


I forced linkage of these unused symbols as follows, but it would 
be nice to have a clean way to proceed.

```D
extern(C) {
int _InterlockedExchangeAdd(int* Addend, int Value) { return 
0; };
long _InterlockedExchangeAdd64(long* Addend, long Value) { 
return 0; }

void _mul128() {};
void __shiftright128() {};
void _umul128() {};
void __stosb() {};
void __readgsqword() {};
void __imp_MapViewOfFileNuma2() {};
void __imp_CharUpperW() {};
}
```
I got the D signatures of the first two so as to generate the 
correct linkage by using ImportC to translate the inclusion of 
`Windows.h` into a .di file, and searching.


Re: Using ImportC to augment a big C project with D

2024-02-21 Thread Carl Sturtivant via Digitalmars-d-learn
On Tuesday, 20 February 2024 at 18:33:42 UTC, Carl Sturtivant 
wrote:

1.
When the resulting executable runs it will have D call C which 
in turn calls D. In that last D (the D files replacing some C 
files), if I throw an exception and don't catch it in the D 
files that replace some C files, will it propagate correctly to 
the D main function where I can catch it?


My understanding is that [this 
reply](https://forum.dlang.org/post/ur5g46$fmb$1...@digitalmars.com) 
indicates that this works. Exceptions thrown by D can be caught 
by D in general in the presence of ImportC.



2.
The C source calls exit() from C's stdlib, and D needs to 
terminate properly. Throwing an exception and catching it in 
D's main function seems to be a way to achieve this. What is 
the best way to deal with exit() ?


So I can simulate C's exit() by throwing an exception and 
catching it in main() as [suggested 
here](https://forum.dlang.org/post/mailman.5856.1600355565.31109.digitalmars-d-le...@puremagic.com).



3.
I want to use D's remarkable Fiber class to reimplement a 
deterministic stack changing context switch that in the 
original project is achieved with assembly code on a 
per-platform basis. This will mean that D's main function will 
call C which will call D which will effect a context switch. Is 
there any reason to believe this will work as naively hoped?


I'll have to proceed experimentally, but I'd like to know in 
advance if this is doomed. Anyone?


Re: Using ImportC to augment a big C project with D

2024-02-21 Thread Carl Sturtivant via Digitalmars-d-learn
On Wednesday, 21 February 2024 at 12:45:50 UTC, Bastiaan Veelo 
wrote:
What do you mean by "need"? You can call 
https://dlang.org/phobos/core_stdc_stdlib.html#.exit from D:


Of course, but does it respect D shutdown?


Output:
```
onlineapp._sharedStaticDtor_L11_C1
```

So it does run module destructors, but not `scope(exit)` 
statements (which probably makes sense).


So it doesn't respect D shutdown, i.e. what happens when 
returning from main with an error code.


I would expect `exit()` called from the C source to have 
similar results.


Why is that?

I just found this.
[Proper way to exit with specific exit 
code?](https://forum.dlang.org/thread/bavfkowjjcijeshrt...@forum.dlang.org)








Using ImportC to augment a big C project with D

2024-02-20 Thread Carl Sturtivant via Digitalmars-d-learn
I just saw the announcement that macros with parameters are now 
translated into D by ImportC. Incredible! Congratulations to all 
involved.


As an occasional D user, I have long wanted a fast route to using 
D with an existing large C project (100K lines approximately).


I want to replace the C main program with a D main function that 
calls the old C main function (suitably renamed) to change the 
command line arguments that can be supplied, and with the helpful 
side effect that druntime is properly initialized. I want to 
replace some C files with D ones. (I am cognizant of GC issues 
here, this is not what I am asking about.)


Now I can use ImportC with all of the header files to make the D 
replacement files easy to write correctly. Perhaps I can use 
ImportC for all of the C source.


1.
When the resulting executable runs it will have D call C which in 
turn calls D. In that last D (the D files replacing some C 
files), if I throw an exception and don't catch it in the D files 
that replace some C files, will it propagate correctly to the D 
main function where I can catch it?


2.
The C source calls exit() from C's stdlib, and D needs to 
terminate properly. Throwing an exception and catching it in D's 
main function seems to be a way to achieve this. What is the best 
way to deal with exit() ?


3.
I want to use D's remarkable Fiber class to reimplement a 
deterministic stack changing context switch that in the original 
project is achieved with assembly code on a per-platform basis. 
This will mean that D's main function will call C which will call 
D which will effect a context switch. Is there any reason to 
believe this will work as naively hoped?





Re: std.uni.CodepointSet from range of pairs of integers

2024-02-19 Thread Carl Sturtivant via Digitalmars-d-learn
On Monday, 19 February 2024 at 04:47:07 UTC, Richard (Rikki) 
Andrew Cattermole wrote:

On 19/02/2024 5:33 PM, Carl Sturtivant wrote:
On Monday, 19 February 2024 at 01:42:03 UTC, Richard (Rikki) 
Andrew Cattermole wrote:


Indeed, nothing in that function body would suggest it needs to 
be a forward range.


Ah yup, the body was changed but never updated its template 
conditional.


https://github.com/dlang/phobos/commit/c9f1c42ed3a8bb92e48bf400ce2f31f434a99905


Thank you for looking into this.


Re: std.uni.CodepointSet from range of pairs of integers

2024-02-19 Thread Carl Sturtivant via Digitalmars-d-learn
On Monday, 19 February 2024 at 01:42:03 UTC, Richard (Rikki) 
Andrew Cattermole wrote:

I can understand ``pure``.

https://github.com/dlang/phobos/blob/master/std/uni/package.d#L2075

It is literally on the constructor.


I should have noticed this!



Re: std.uni.CodepointSet from range of pairs of integers

2024-02-18 Thread Carl Sturtivant via Digitalmars-d-learn
On Monday, 19 February 2024 at 01:42:03 UTC, Richard (Rikki) 
Andrew Cattermole wrote:

I can understand ``pure``.

https://github.com/dlang/phobos/blob/master/std/uni/package.d#L2075

It is literally on the constructor.

Now @safe I don't know. My best guess would be for some reason 
the constructor is getting inferred as it (templates get 
inferred).


What about needing a forward range, not just an input range? It 
would seem it just needs to iterate through a sequence of pairs 
of integers.


std.uni.CodepointSet from range of pairs of integers

2024-02-18 Thread Carl Sturtivant via Digitalmars-d-learn
I wanted to construct a CodepointSet from a string, so I used the 
constructor here.

https://dlang.org/phobos/std_uni.html#.InversionList.this.2

I wrote a range of pairs (CodepointIntervals) of integers 
consisting of each codepoint in the string paired with that plus 
one. This did solve the problem, but only after I overcame some 
peculiarities of the situation.


Specifically, this required a forward range, not just an input 
range, so I wrote a save method.


Once I fixed that problem, it needed empty() and popFront() to be 
pure. So I added the word pure to each in my range.


Once I fixed that problem, it required those to be @safe, so I 
added that to my struct declaration of my range.


Then everything worked.

Could I have anticipated any of this, and what is the reason for 
each of these?





Re: std.uni CodepointSet toString

2024-02-08 Thread Carl Sturtivant via Digitalmars-d-learn

On Wednesday, 7 February 2024 at 17:11:30 UTC, H. S. Teoh wrote:
Do we know why the compiler isn't getting it right?  Shouldn't 
we be fixing it instead of just turning off elision completely?


This matter seems to have been an issue for some time.
https://forum.dlang.org/post/l5e5hm$1177$1...@digitalmars.com



Re: std.uni CodepointSet toString

2024-02-07 Thread Carl Sturtivant via Digitalmars-d-learn
On Wednesday, 7 February 2024 at 11:49:20 UTC, Richard (Rikki) 
Andrew Cattermole wrote:

```
undefined reference to 
`_D4core9exception__T15__switch_errorTZQsFNaNbNiNeAyamZv'

collect2: error: ld returned 1 exit status
Error: linker exited with status 1
```


Use ``-allinst``, that is a template emission bug.


!
Thanks, at least I can continue now, though presumably the cure 
has its own problems.


```
$ dmd --help | grep allinst
  -allinst  generate code for all template instantiations
```
Unclear exactly how -allinst does this, given type parameters, 
and it will affect all of the many templates I use in source with 
CodepointSet.


Can you shed any light?



std.uni CodepointSet toString

2024-02-06 Thread Carl Sturtivant via Digitalmars-d-learn

Need help working around a linkage problem.
```d
import std.uni, std.conv, std.stdio, std.format;

void main() {
//auto c1 = unicode.InBasic_latin;
auto c1 = CodepointSet('a','z'+1);
writeln(c1.to!string);
writeln(format("%d", c1));
writeln(format("%#x", c1));
writeln(format("%#X", c1));
writefln("%s", c1);
}
```
doesn't link, but does link with the commented out CodepointSet 
instead. Combines code from these examples at the following URLs.

https://dlang.org/phobos/std_uni.html#InversionList
https://dlang.org/phobos/std_uni.html#.InversionList.toString
```
$ dmd --version
DMD64 D Compiler v2.107.0
Copyright (C) 1999-2024 by The D Language Foundation, All Rights 
Reserved written by Walter Bright

$ dmd cset2.d
/usr/bin/ld: cset2.o: in function 
`_D4core8internal7switch___T14__switch_errorZQrFNaNbNiNfAyamZv':

cset2.d:(.text._D4core8internal7switch___T14__switch_errorZQrFNaNbNiNfAyamZv[_D4core8internal7switch___T14__switch_errorZQrFNaNbNiNfAyamZv]+0x19):
 undefined reference to 
`_D4core9exception__T15__switch_errorTZQsFNaNbNiNeAyamZv'
collect2: error: ld returned 1 exit status
Error: linker exited with status 1
```




Re: Scripting with Variant from std.variant: parameter passing

2024-02-03 Thread Carl Sturtivant via Digitalmars-d-learn

On Friday, 2 February 2024 at 20:58:12 UTC, Paul Backus wrote:

Another variation on the same theme:
```d
/// map over a variadic argument list
template mapArgs(alias fun)
{
auto mapArgs(Args...)(auto ref Args args)
{
import std.typecons: tuple;
import core.lifetime: forward;
import std.meta: Map = staticMap;

auto ref mapArg(alias arg)()
{
return fun(forward!arg);
}

return tuple(Map!(mapArg, args));
}
}

import std.variant: Variant;
import std.meta: allSatisfy;

enum isVariant(T) = is(T == Variant);

auto foo(Args...)(Args args)
if (!allSatisfy!(isVariant, Args))
{
return .foo(mapArgs!Variant(args).expand);
}
```


Thanks, will study the library machinery you used here.


Re: Scripting with Variant from std.variant: parameter passing

2024-02-02 Thread Carl Sturtivant via Digitalmars-d-learn
On Friday, 2 February 2024 at 19:22:22 UTC, Steven Schveighoffer 
wrote:

```d
void foo(Variant x, Variant y) { ... }

import std.meta : allSatisfy;

enum isVariant(T) = is(T == Variant);

// this is going to suck at CTFE but...
string argsAsVariants(size_t count)
{
   import std.format;
   import std.range;
   import std.alglorithm;
   import std.array;
   return iota(count).map!(i => format("Variant(args[%s])", 
i).join(",");

}

// shim
auto foo(Args...)(Args args) if (!allSatisfy!(isVariant, Args))
{
mixin("return foo(", argsAsVariants(args.length), ");");
}
```


Thanks for this idea. I'll work on it.


-Steve





Scripting with Variant from std.variant: parameter passing

2024-02-02 Thread Carl Sturtivant via Digitalmars-d-learn
It seems I cannot pass e.g. an int argument to a Variant function 
parameter. What's the simplest way to work around this 
restriction?


Re: import locality with function parameters

2024-02-01 Thread Carl Sturtivant via Digitalmars-d-learn
On Friday, 2 February 2024 at 01:23:11 UTC, Steven Schveighoffer 
wrote:

Are you thinking of this?

https://dlang.org/phobos/object.html#.imported

-Steve


Yes! Glad it's now part of D.
Thank you.




import locality with function parameters

2024-02-01 Thread Carl Sturtivant via Digitalmars-d-learn

Hello,

I seem to recall that there is surprising template to import a 
module and get a type from it inside the declaration of the type 
of a parameter to a function, so that the module need not be 
imported outside of the function definition. I think there was a 
blog article some years ago about this where there was some 
indication that this or something with equivalent effect would be 
incorporated into D in some way.


How do I define a function with a parameter that is a type in an 
outside module while keeping module import local to that 
definition?




Re: compute from a string the text of a string literal

2024-01-17 Thread Carl Sturtivant via Digitalmars-d-learn

On Wednesday, 17 January 2024 at 18:53:48 UTC, Paul Backus wrote:
There's a function that does this in Phobos, but it's 
`private`. Currently, the only way to access it is by calling 
`to!string` or `format` on a range that contains the string you 
want to convert as an element:


```d
void main()
{
import std.range, std.conv, std.stdio;

string s = `"foo"\bar`;
string escaped = only(s).to!string[1 .. $-1]; // slice off 
[ and ]

writeln(escaped); // "\"foo\"\\bar"
}
```


Great! I'll use that!



compute from a string the text of a string literal

2024-01-17 Thread Carl Sturtivant via Digitalmars-d-learn

Hello,
I'd like a function like this,
```
string image(string s)
```
that maps any string s into the doubly quoted backslash escaped 
text that would be a string literal for s were it pasted into a 
program. Perhaps with a second parameter with detailed options.


Is there something out there I could use?



Re: Bison 3.8.1 released with D backend

2021-09-15 Thread Carl Sturtivant via Digitalmars-d-announce

On Wednesday, 15 September 2021 at 14:48:06 UTC, Tejas wrote:
I'm sorry for being ignorant, but what does it mean to have a 
\ back-end in Bison?


Does it mean that the parser program that `Bison` will output 
will be a `.d` file?


Assuming I'm correct:

What does it matter whether the parser is a `.c .cpp .d .pl` or 
whatever file?


I'm really sorry I'm coming off as abrasive/ungrateful. I have 
no intention to belittle the author or the work she has done.


But I'm really curious: What changes if `Bison` outputs it's 
parser in some language other than the one it originally 
targeted(perhaps that was C?)


I'm really sorry if this appears dismissive, I just don't know 
how to phrase it any better.


A question asking for its author to be educated would be more 
suitably posted in the Learn forum.





Re: Bison 3.8.1 released with D backend

2021-09-15 Thread Carl Sturtivant via Digitalmars-d-announce

Quote:

*** A skeleton for the D programming language

  The "lalr1.d" skeleton is now officially part of Bison.

  It was originally contributed by Oliver Mangold, based on Paolo 
Bonzini's
  lalr1.java, and was improved by H. S. Teoh.  Adela Vais then 
took over
  maintenance and invested a lot of efforts to complete, test and 
document

  it.

  It now supports all the bells and whistles of the other 
deterministic
  parsers, which include: pull/push interfaces, verbose and 
custom error
  messages, lookahead correction, token constructors, 
internationalization,

  locations, printers, token and symbol prefixes, etc.

  Two examples demonstrate the D parsers: a basic one 
(examples/d/simple),

  and an advanced one (examples/d/calc).


Bison 3.8.1 released with D backend

2021-09-15 Thread Carl Sturtivant via Digitalmars-d-announce



The D back-end for deterministic parsers contributed by Adela 
Vais is now available with the release of Bison 3.8.1 !


https://github.com/adelavais

See https://savannah.gnu.org/forum/forum.php?forum_id=10047 for 
details.





Re: Anyway to achieve the following

2021-08-15 Thread Carl Sturtivant via Digitalmars-d-learn

On Sunday, 15 August 2021 at 07:10:17 UTC, JG wrote:

Hi,

This is exactly the behaviour I was trying to obtain.

It however comes with a fair amount of overhead, as can be seen 
in the following llvm ir:


[...]


What you are asking for are reference variables. C++ has them: 
the example here illustrates the behavior you want.

https://www.geeksforgeeks.org/references-in-c/

D does not have them, as mentioned above:
https://forum.dlang.org/post/mailman.2714.1628875187.3446.digitalmars-d-le...@puremagic.com

So to get the behavior you want, they have to be simulated, which 
is what this does:

https://forum.dlang.org/post/lcrrnszslpyazoziy...@forum.dlang.org

Next version: no `toString` and storage passed in by reference 
rather than by pointer.


```
struct S {
  int x = 1234;
}

void main() {
  import std.stdio;
   S s;
   auto p = 
   //construction of a using &(s.x)
   auto a = Ref!(int)(*p);
   //auto a = Ref!(int)(s.x);
   writeln(a); //displays 1234
   s.x += 1;
   writeln(a); //displays 1235
   a += 1;
   writeln(s.x); //displays 1236
}

struct Ref(T)
{
  T* ptr;
  this(ref T x) { ptr =  }
  @property ref T var() { return *ptr; }
  alias var this;
}
```

I see no way to avoid overhead, as I see no simpler simulation.



Re: Anyway to achieve the following

2021-08-14 Thread Carl Sturtivant via Digitalmars-d-learn

```
struct S {
  int x = 1234;
}

void main() {
  import std.stdio;
   S s;
   //construction of a using &(s.x)
   auto a = Ref!(int)();
   writeln(a); //displays 1234
   s.x += 1;
   writeln(a); //displays 1235
   a += 1;
   writeln(s.x); //displays 1236
}

struct Ref(T) {
  T* ptr;
  this(T* p) { ptr = p; }
  string toString() { import std.conv; return to!string(*ptr); }
  ref T var() { return *ptr; }
  alias var this;
}
```


Re: Reading IDX Files in D, an introduction to compile time programming

2020-08-23 Thread Carl Sturtivant via Digitalmars-d-announce
On Saturday, 22 August 2020 at 07:04:19 UTC, Petar Kirov 
[ZombineDev] wrote:


I feel like limiting CTFE just gives a false sense of security 
and destroys many interesting use cases. If a part of my build 
system will do directory traversal to build the list of files 
to import, what difference would it make to not have this as a 
single build step. The argument that somehow


dmd -run gen_code.d | dmd -

Is more secure than just:

dmd file.d # file.d is allowed to access the FS at CT

makes no sense to me.

See Jai for example. You can run absolutely *any* code at 
compile time. 5 years ago Jai's creator made a demo of running 
an OpenGL game at CT [1]. In the same demo he also used CTFE to 
validate calls to printf. He made the case that while many 
compilers go the route of hard-coding checks for printf style 
functions in the compiler, he thinks that users should be able 
to implement arbitrary checks in their code. And 5 years later, 
instead of D expanding the frontiers of what's possible via 
CTFE, printf checking was hard coded in the compiler [2].


[1]: https://www.youtube.com/watch?v=UTqZNujQOlA
[2]: https://github.com/dlang/dmd/pull/10812/files

I don't need say that unlimited CTFE has been a huge success 
for Jai. What I wish is that we can learn from this stop 
bringing arguments that C people would bring for D's CTFE ("My 
Makefile calls a Python script to generate C code and it's 
doing just fine, so I don't think one should be allowed to run 
code at compile time, as it will make the code just harder to 
follow").


As another example, types in Zig are first class citizens [3] 
and can be manipulated with CTFE just like any other value. 
"Type functions" in D should just be regular D functions taking 
types as parameters and returning types.


[3]: 
https://ziglang.org/documentation/master/#Introducing-the-Compile-Time-Concept


Strongly Agreed!



Re: alias restriction??!

2020-07-20 Thread Carl Sturtivant via Digitalmars-d-learn

On Monday, 20 July 2020 at 17:24:56 UTC, Carl Sturtivant wrote:
Well perhaps you do parse a "constant-offset expression" i.e. 
syntactically dotted with constant indexes, like 
name1.name2[constant].name3 and then later there's a semantic 
check that the "constant-offset expression" involves no 
indirections when an offset into the top level object is 
computed. Then it's treated like any other attribute of a 
struct with a known offset.


Perhaps this could also work for a class at the top with 
recursively embedded structs and value arrays.


Re: alias restriction??!

2020-07-20 Thread Carl Sturtivant via Digitalmars-d-learn
On Sunday, 19 July 2020 at 20:46:19 UTC, Steven Schveighoffer 
wrote:

On 7/19/20 4:21 PM, Carl Sturtivant wrote:


Perhaps what's needed is something more that is less than 
allowing aliases for expressions in the wide sense you suggest 
here.


I agree. Something not yet mentioned is that aliases provide 
direct access to the symbols for the purposes of looking at 
attributes -- something that a wrapper function doesn't provide.


The question is: how do you restrict it to explicit data items 
within a specific aggregate without parsing arbitrary 
expressions?


Well perhaps you do parse a "constant-offset expression" i.e. 
syntactically dotted with constant indexes, like 
name1.name2[constant].name3 and then later there's a semantic 
check that the "constant-offset expression" involves no 
indirections when an offset into the top level object is 
computed. Then it's treated like any other attribute of a struct 
with a known offset.


Re: alias restriction??!

2020-07-19 Thread Carl Sturtivant via Digitalmars-d-learn

On Sunday, 19 July 2020 at 17:06:14 UTC, Paul Backus wrote:
Also, letting aliases refer to expressions essentially allows 
AST macros in through the back door. Consider the following 
example:


[...]


Perhaps what's needed is something more that is less than 
allowing aliases for expressions in the wide sense you suggest 
here.


Re: alias restriction??!

2020-07-19 Thread Carl Sturtivant via Digitalmars-d-learn

On Sunday, 19 July 2020 at 12:08:07 UTC, Paul Backus wrote:
On Saturday, 18 July 2020 at 18:46:16 UTC, Carl Sturtivant 
wrote:

Here's a toy version of a problem in the wild.

struct S {
long first;
union T {
long one;
double two;
}
T second;
alias First = first;
alias Second = second.one;
}

void main() {
S x;
x.First = 4;
x.Second = 5; // compilation error: "Error: need this for 
one of type long"

}


Easiest workaround:

ref inout(long) Second() inout { return second.one; }


Was trying to avoid this for performance reasons. In fact what 
are the performance implications of this sort of thing with 
current implementations? --- relative to using a simple offset.




alias restriction??!

2020-07-18 Thread Carl Sturtivant via Digitalmars-d-learn

Here's a toy version of a problem in the wild.

struct S {
long first;
union T {
long one;
double two;
}
T second;
alias First = first;
alias Second = second.one;
}

void main() {
S x;
x.First = 4;
x.Second = 5; // compilation error: "Error: need this for one 
of type long"

}

Second is a fixed offset into an S and it would be nice to have a 
name for it. Why doesn't alias know it's OK?


I can work around this with some duplication as follows.

struct S {
long first;
union {
long one;
double two;
union T {
long one;
double two;
}
T second;
}
alias First = first;
alias Second = one;
}

void main() {
S x;
x.First = 4;
x.Second = 5;
x.second.one = 6;
import std.stdio;
writeln(x);
writeln(x.one);
writeln(x.Second);
}

Is there any way to avoid the duplication of the entries in the 
anonymous union, aside from using a mixin template?


Is there some other way (not involving writing a function) to 
work around this?




Re: GCC 10.1 Released

2020-05-15 Thread Carl Sturtivant via Digitalmars-d-announce

On Saturday, 16 May 2020 at 00:26:31 UTC, Carl Sturtivant wrote:

On Thursday, 14 May 2020 at 16:57:20 UTC, Iain Buclaw wrote:

[[GCC 11 Development]]

Now the development cycle has started again, I have ambitions 
for a number disruptive changes to land during the next 
release cycle.


Superb! --- gdc is perhaps the most important strategically and 
I am so glad to see this playing out.


In fact I would like to characterize compiler progress for D as 
follows.


dmd --- logistical progress
ldc --- tactical progress
gdc --- strategic progress

:)


Re: GCC 10.1 Released

2020-05-15 Thread Carl Sturtivant via Digitalmars-d-announce

On Thursday, 14 May 2020 at 16:57:20 UTC, Iain Buclaw wrote:

[[GCC 11 Development]]

Now the development cycle has started again, I have ambitions 
for a number disruptive changes to land during the next release 
cycle.


Superb! --- gdc is perhaps the most important strategically and I 
am so glad to see this playing out.


Re: How do I display unicode characters in D on standard (english) Windows 10 console window?

2019-07-31 Thread Carl Sturtivant via Digitalmars-d-learn

On Monday, 29 July 2019 at 22:17:55 UTC, WhatMeWorry wrote:
This is a very stupid question but from Ali's book, I took this 
segment:



writeln("Résumé preparation: 10.25€");
writeln("\x52\sum\u00e9 preparation: 10.25\");


and after running it all I get is the following:


Résumé preparation: 10.25€
Résumé preparation: 10.25€


I was expecting the symbol "£" or something like that.  What am 
I missing?


In my Windows 10 build 1803 I was able to find a box to check to 
globally use the UTF-8 code page. Checking it requires a restart 
as it says the locale has changed.


Settings>Time>Region>Administrative_Language_Settings
brings up a Region dialog, and clicking on "Change system 
locale..." brought up a dialog where this box can be checked.


After doing this the console acted sensibly right away with the 
code you wrote.


Re: Top Five World’s Most Underrated Programming Languages

2019-01-17 Thread Carl Sturtivant via Digitalmars-d-announce
On Monday, 14 January 2019 at 20:21:25 UTC, Andrei Alexandrescu 
wrote:

Of possible interest:

https://www.technotification.com/2019/01/most-underrated-programming-languages.html


What's interesting here is the language nim, which perhaps has 
some lessons for D.

https://nim-lang.org/




Re: opDispatch doesn't play nice with inheritance

2018-11-17 Thread Carl Sturtivant via Digitalmars-d-learn

On Thursday, 15 November 2018 at 19:01:45 UTC, Ali Çehreli wrote:

On 11/15/2018 09:14 AM, Carl Sturtivant wrote:

> opDispatch is special in that it allows for functions to be
added to a
> class or struct when undefined overtly but used elsewhere but
it seems
> those functions sadly are final.
>
> Can anything useful be done to remedy the situation?

For the compiler to be able to make all opDispatch 
instantiations virtual, it would have to first see all calls 
that generate opDispatch instantiations. (Impossible in the 
presence of separate compilation.)


Only then the compiler would know how large the vtbl of the 
base class should be and what member functions of the derived 
class are overrides of those virtual functions.


I suppose it's such administrative difficulties that led to D 
defining anything that might conceivably be overridden to be 
virtual, whether or not actually overridden.




Re: opDispatch doesn't play nice with inheritance

2018-11-15 Thread Carl Sturtivant via Digitalmars-d-learn
On Thursday, 15 November 2018 at 18:04:42 UTC, Adam D. Ruppe 
wrote:

Right, all templates are final, including opDispatch.

What I've done in the past is to forward them to a virtual 
function with runtime arguments instead of compile time 
arguments.


Kinda like:

void opDispatch(string name)() {
 callMethod(name);
}

/* virtual */ void callMethod(string name) {
 // do a reflection loop or associate array or switch or 
whatever to dispatch it here, reimplemented (or at least 
re-mixed-in) in the child classes to account for their new 
methods

}



What exactly do you need to do with it? Maybe you can do an 
alternative design.


Well, I found an alternative design not using opDispatch, not 
fundamentally dissimilar to what you suggested above, thanks for 
that, and it's not too uneconomical in its textual organization. 
I was hoping to avoid doing any of my own dispatching when 
inheritance would do it for me.






opDispatch doesn't play nice with inheritance

2018-11-15 Thread Carl Sturtivant via Digitalmars-d-learn

//Consider this:
import std.stdio;

void main() {
X obj = new Y;
writeln( obj._f() );
}

class Proxy {
X x;
this(X x) { this.x = x; }
string _f() { return "Proxy._f called"; }
}

class X {
auto opDispatch(string f, Args...)(Args args) {
Proxy p = new Proxy(this);
return mixin("p."~f~"(args)");
}
}

class Y : X {
string _f() { return "Y._f called"; }
}
//

Presumably the presence of obj._f()in main causes the compilation 
of a function _f() in the class X, yet the function _f() in Y 
that inherits it merely shadows it; the keyword override cannot 
be used for this function.


opDispatch is special in that it allows for functions to be added 
to a class or struct when undefined overtly but used elsewhere 
but it seems those functions sadly are final.


Can anything useful be done to remedy the situation?




Re: DIP 1015--Deprecation of Implicit Conversion of Int. & Char. Literals to bool--Formal Assement

2018-11-14 Thread Carl Sturtivant via Digitalmars-d-announce
On Monday, 12 November 2018 at 10:05:09 UTC, Jonathan M Davis 
wrote:
*sigh* Well, I guess that's the core issue right there. A lot 
of us would strongly disagree with the idea that bool is an 
integral type and consider code that treats it as such as 
inviting bugs. We _want_ bool to be considered as being 
completely distinct from integer types. The fact that you can 
ever pass 0 or 1 to a function that accepts bool without a cast 
is a problem in and of itself. But it doesn't really surprise 
me that Walter doesn't agree on that point, since he's never 
agreed on that point, though I was hoping that this DIP was 
convincing enough, and its failure is certainly disappointing.


I'm at a loss to see any significant advantage to having bool as 
a part of the language itself if it isn't deliberately isolated 
from `integral types`.


Re: custom sorting of lists ?

2018-10-19 Thread Carl Sturtivant via Digitalmars-d-learn
On Friday, 19 October 2018 at 17:53:58 UTC, Stanislav Blinov 
wrote:
On Friday, 19 October 2018 at 17:40:59 UTC, Carl Sturtivant 
wrote:


If we imagine an Ordered Range being a finite Range of some 
kind with the additional property that its values are ordered 
(--- exact definition needed ---)...


There's already a SortedRange: 
https://dlang.org/phobos/std_range.html#.SortedRange


That's nice. So perhaps all this can be done in using the 
existing machinery in Phobos.




Re: custom sorting of lists ?

2018-10-19 Thread Carl Sturtivant via Digitalmars-d-learn
On Wednesday, 17 October 2018 at 19:02:00 UTC, Steven 
Schveighoffer wrote:

On 10/17/18 2:03 PM, Carl Sturtivant wrote:
On Monday, 15 October 2018 at 13:39:59 UTC, Steven 
Schveighoffer wrote:


But that's just the thing -- merge sort *does* depend on the 
container type. It requires the ability to rearrange the 
elements structurally, since you merge the sets of items 
together. This requires making another list from the original 
list, and ranges don't lend themselves to that.


One thing you *can* do is allocate an array beside the 
original container, and move things back and forth. But this 
is not required if you have a linked-list type which can 
simply be restructured without moving.


Doesn't this just mean a new special kind of range is needed 
to be defined?




I don't think it fits into range primitives. Basically, I need 
to rearrange one element from one place to another in O(1) time 
(and without actually moving/copying the data).


This really just is a linked-list special feature. One thing to 
note is that in a range of T, this move has nothing to do with 
the T.


-Steve


If we imagine an Ordered Range being a finite Range of some kind 
with the additional property that its values are ordered (--- 
exact definition needed ---). And work with Ranges of Ordered 
Ranges, can't we then sort by starting with a Range of single 
element Ranges (which are automatically ordered), and then 
pairwise merge repeatedly, i.e. get the next two elements (which 
are ordered ranges) and merge them & repeat, producing a Range of 
Ordered Ranges with half as many elements --- this is what I 
meant by pairwise merging --- and apply that pairwise merge 
repeatedly to the original range. I'm speculating intuitively, 
but it does look like there exists a possible extension of the 
notion of Range that would do the job.






Re: custom sorting of lists ?

2018-10-17 Thread Carl Sturtivant via Digitalmars-d-learn
On Monday, 15 October 2018 at 13:39:59 UTC, Steven Schveighoffer 
wrote:


But that's just the thing -- merge sort *does* depend on the 
container type. It requires the ability to rearrange the 
elements structurally, since you merge the sets of items 
together. This requires making another list from the original 
list, and ranges don't lend themselves to that.


One thing you *can* do is allocate an array beside the original 
container, and move things back and forth. But this is not 
required if you have a linked-list type which can simply be 
restructured without moving.


Doesn't this just mean a new special kind of range is needed to 
be defined?




Re: A Friendly Challenge for D

2018-10-11 Thread Carl Sturtivant via Digitalmars-d
On Thursday, 11 October 2018 at 13:26:19 UTC, Jabari Zakiyth 
wrote:

On Thursday, 11 October 2018 at 05:11:20 UTC, Ali Çehreli wrote:

[...]


What country are you trying to get access from, because I know 
people in the US have gotten the papers from those link, for 
free and without an account. It may also have something to do 
with your browser. They work for me in various modern browsers, 
including the Tor Browser.


Not credible --- I cannot get either without an account browsing 
from the US using Firefox with no unusual arrangements.


Re: extern(C++, ns) is wrong

2018-09-10 Thread Carl Sturtivant via Digitalmars-d
On Wednesday, 5 September 2018 at 13:53:15 UTC, Jonathan M Davis 
wrote:
On Wednesday, September 5, 2018 7:03:26 AM MDT Nicholas Wilson 
via Digitalmars-d wrote:

[...]


Based on everything Walter said in the previous thread, it 
honestly seems to me to be primarily like he just can't give up 
on the idea that D has to worry about modeling C++ namespaces. 
Pretty much all of the extra complications that come from the 
current approach stem from insisting on modeling namespaces in 
D instead of just treating the namespace as part of the 
information that you give to the compiler to indicate what the 
symbol in D is supposed to correspond to in C++ when the 
compiler goes to mangle it.


[...]


I wholeheartedly agree. C++ namespaces are a C++ language idea 
that D has discarded in favor of much simpler facilities. 
Injecting that  back into D when linking to 
C++ is polluting D with needless complexity at odds with that 
gain in simplicity. The name collision problem with two 
namespaces containing the same name can be resolved with much 
simpler facilities. For example, at the point of the extern 
declaration, the name of the linked entity could be provided as 
an optional third parameter so that the name in D could be 
different. I'm sure many other simple schemes could be invented, 
more consistent with D's approach.




std.process.pipeProcess stalls (linux)

2018-06-01 Thread Carl Sturtivant via Digitalmars-d-learn
A computationally intensive process run from the command line 
works fine, runs to completion after several minutes, writing a 
few hundred lines of text to standard output and creating, 
writing to and closing around 200 files of size around 20KB.


Now run from std.process.pipeProcess and periodically tested for 
completion with tryWait interleaved with sleep everything seems 
fine for a while. htop reveals that one core is running this at 
100% CPU, and the first 76 files appear one after another, but 
the 77th file is opened and nothing is written to it, and htop 
reveals that the CPU usage has dropped to zero, and yet the 
process is still running according to ps, and this continues 
indefinitely, no error message, no indication from tryWait that 
it is done. htop does not reveal at any point that memory use is 
even half of what is available.


Previously with similar processes that are a somewhat scaled back 
version of the one that fails as above, there's been no 
difference between what happened at the command line and what's 
happening here.


Any ideas or suggestions?



Re: Initialization of struct containing anonymous union

2017-08-14 Thread Carl Sturtivant via Digitalmars-d-learn
On Monday, 14 August 2017 at 15:11:35 UTC, Steven Schveighoffer 
wrote:

On 8/14/17 10:57 AM, Carl Sturtivant wrote:
On Monday, 14 August 2017 at 14:49:57 UTC, Steven 
Schveighoffer wrote:

On 8/14/17 10:36 AM, Carl Sturtivant wrote:
On Monday, 14 August 2017 at 14:24:40 UTC, Steven 
Schveighoffer wrote:


I think what the docs mean is that as soon as an anonymous 
union is present, you can't initialize anything further 
than the first union field.


I understood that, hence my remark that "this is not 
helpful".


OK. I thought you meant that the documentation is not helpful 
enough to understand what it means.




So it seems I am forced to assign explicitly to each 
member of the struct, an ugly process.


What is a nice way to solve this problem?


I think the only way to solve it is with a constructor:

this(int ival, double xval) { i = ival; x = xval; }


As I though I made clear, I don't want write assignments to 
each variable in a 50 or 100 member struct from a library 
when D could supply a better solution.


Sorry, I thought you meant to assign the fields manually 
outside an initializer function.


I can print out such a struct using writeln, but can find no 
way to use that text cleaned up in source code to create 
such a struct. Is D completely deficient here?


Hm... have you tried named field initializers?

mess m = { i: 99, x: 3.14};



I could do that, but again it would involve finding the 50 or 
100 names and writing text that looks quite like the text of 
an assignment except using colon instead of equals. So just as 
long and ugly.


Well, you only have to initialize the ones that aren't 
defaulted. So in some use cases, this is hugely beneficial.


But it seems in your case, you want to intialize everything 
explicitly (but only one member from each union).


Tried this, also works. Looks like you just have to name items 
after the unions (i.e. when you are skipping members). Ugly, 
but passable:


struct mess
{
union
{
int i;
string s;
}
double x;
int z;
}

mess s = {99, x: 3.14, 5};

-Steve


!
Agreed!


Re: Initialization of struct containing anonymous union

2017-08-14 Thread Carl Sturtivant via Digitalmars-d-learn
On Monday, 14 August 2017 at 14:49:57 UTC, Steven Schveighoffer 
wrote:

On 8/14/17 10:36 AM, Carl Sturtivant wrote:
On Monday, 14 August 2017 at 14:24:40 UTC, Steven 
Schveighoffer wrote:


I think what the docs mean is that as soon as an anonymous 
union is present, you can't initialize anything further than 
the first union field.


I understood that, hence my remark that "this is not helpful".


OK. I thought you meant that the documentation is not helpful 
enough to understand what it means.




So it seems I am forced to assign explicitly to each member 
of the struct, an ugly process.


What is a nice way to solve this problem?


I think the only way to solve it is with a constructor:

this(int ival, double xval) { i = ival; x = xval; }


As I though I made clear, I don't want write assignments to 
each variable in a 50 or 100 member struct from a library when 
D could supply a better solution.


Sorry, I thought you meant to assign the fields manually 
outside an initializer function.


I can print out such a struct using writeln, but can find no 
way to use that text cleaned up in source code to create such 
a struct. Is D completely deficient here?


Hm... have you tried named field initializers?

mess m = { i: 99, x: 3.14};



I could do that, but again it would involve finding the 50 or 100 
names and writing text that looks quite like the text of an 
assignment except using colon instead of equals. So just as long 
and ugly.




I believe you could generate a constructor given the 
introspection of the fields themselves. Probably would be messy 
though.


Probably worth investigating, though not handy when quickly 
writing a short one-off tool. Was hoping D would have a better 
way.





Re: Initialization of struct containing anonymous union

2017-08-14 Thread Carl Sturtivant via Digitalmars-d-learn
On Monday, 14 August 2017 at 14:24:40 UTC, Steven Schveighoffer 
wrote:


I think what the docs mean is that as soon as an anonymous 
union is present, you can't initialize anything further than 
the first union field.


I understood that, hence my remark that "this is not helpful".

So it seems I am forced to assign explicitly to each member of 
the struct, an ugly process.


What is a nice way to solve this problem?


I think the only way to solve it is with a constructor:

this(int ival, double xval) { i = ival; x = xval; }


As I though I made clear, I don't want write assignments to each 
variable in a 50 or 100 member struct from a library when D could 
supply a better solution. I can print out such a struct using 
writeln, but can find no way to use that text cleaned up in 
source code to create such a struct. Is D completely deficient 
here?




Initialization of struct containing anonymous union

2017-08-14 Thread Carl Sturtivant via Digitalmars-d-learn

  struct mess
  {
union
{
int i;
string s;
}
double x;
  }

How do I cleanly initialize this, assuming it's i that I want to 
give an overt value to?


The docs say "If there are anonymous unions in the struct, only 
the first member of the anonymous union can be initialized with a 
struct literal, and all subsequent non-overlapping fields are 
default initialized". This is not helpful.

https://dlang.org/spec/struct.html#struct-literal

The above is a toy example distilled from a real problem. The 
struct comes from a C library and is very long and contains 
several anonymous unions. The D declaration of the struct was 
made by someone else who made the library available to D.


I printed out such a struct returned by a call to the library, 
and wanted to create my own from scratch. But it seems that I 
can't just copy what writeln printed and edit it into an 
initialization analogous to


  mess m = { 99, 3.14 };

with the above, because I just get the analog of

Error: overlapping initialization for field i and s
Error: cannot implicitly convert expression (3.14) of type double 
to string


and the alternative more like what is printed by writeln,

  auto m = mess(99, 3.14);

produces a similar error message.

So it seems I am forced to assign explicitly to each member of 
the struct, an ugly process.


What is a nice way to solve this problem?




Re: Simulating reference variables using `alias this`

2017-05-10 Thread Carl Sturtivant via Digitalmars-d

On Wednesday, 10 May 2017 at 17:48:53 UTC, MrSmith wrote:
On Wednesday, 10 May 2017 at 17:12:11 UTC, Carl Sturtivant 
wrote:
Here's the beginning of an interesting little experiment to 
simulate reference variables using `alias this` to disguise a 
pointer as a reference. Could add a destructor to set the 
pointer to null when a reference goes out of scope.

...


I've used this code for similar purpose:

alias TextEditorSettingsRef = TextEditorSettings*;
alias TextEditorSettingsConstRef = const(TextEditorSettings)*;
struct TextEditorSettings
{}

But you need to have two aliases (templates) for const and 
non-const refs, since using:

const TextEditorSettingsRef editor;
does:
const(TextEditorSettings*)
not
const(TextEditorSettings)*

What do you think?


Works if you use new to get struct pointers. And . knows it's a 
pointer so you get the right effect. But I want to see if D can 
simulate general reference variables safely.




Re: Simulating reference variables using `alias this`

2017-05-10 Thread Carl Sturtivant via Digitalmars-d

On Wednesday, 10 May 2017 at 17:12:11 UTC, Carl Sturtivant wrote:
Here's the beginning of an interesting little experiment to 
simulate reference variables using `alias this` to disguise a 
pointer as a reference. Could add a destructor to set the 
pointer to null when a reference goes out of scope.


Here's a better version. Improvements? This can still behave as 
badly as a pointer, e.g. if returned from a function.


```
struct reference(T)
{
T* ptr;
this(ref T x)
{
ptr = 
}
~this()
{
ptr = null;
}
import std.exception : enforce;

ref T cnvrt() @property
{
enforce( ptr !is null);
return *ptr;
}
ref T cnvrt(T x) @property
{
enforce( ptr !is null);
return *ptr = x;
}
ref reference!T opAssign(T t)
{
enforce( ptr !is null);
*ptr = t;
return this;
}
ref reference!T opAssign(ref reference!T r)
{
enforce( ptr !is null && r.ptr !is null);
*ptr = *r.ptr;
return this;
}
alias cnvrt this;
}

void main()
{
int i;
auto ri = reference!int(i);
auto ri2 = reference!int(ri);

assert(ri.ptr==ri2.ptr);

i = 99;
assert(i==ri && i==ri2 && ri==ri2);

ri = 100;
assert(i==ri && i==ri2 && ri==ri2);

ri2 = 101;
assert(i==ri && i==ri2 && ri==ri2);

int j = -1;
auto rj = reference!int(j);

ri = rj;

assert(ri==rj);
assert(ri.ptr!=rj.ptr);
}
```



Re: subtlety or bug?

2017-05-10 Thread Carl Sturtivant via Digitalmars-d-learn
Aha, https://dlang.org/spec/struct.html#struct-destructor says 
that


An identity assignment overload is required for a struct if one 
or more of these conditions hold:


* it has a destructor

so this is the above condition coming into play.




subtlety or bug?

2017-05-10 Thread Carl Sturtivant via Digitalmars-d-learn

The following compiles and runs correctly.
https://forum.dlang.org/post/tzwsohkcqrkqotbwn...@forum.dlang.org

But if I add a destructor to the reference struct template as 
follows, it no longer compiles, and the complaints are not about 
the destructor.

```
~this()
{
ptr = null;
}
```
refsim.d(39): Error: generated function 
refsim.reference!int.reference.opAssign (reference!int p) is not 
callable using argument types (int)
refsim.d(42): Error: generated function 
refsim.reference!int.reference.opAssign (reference!int p) is not 
callable using argument types (int)


These are complaining about lines where reference!int variables 
are assigned integers.


What's going on?

Here's the code linked to above without the destructor that works.
```
struct reference(T)
{
T* ptr;
this(ref T x)
{
ptr = 
}
import std.exception : enforce;

ref T cnvrt() @property
{
enforce( ptr !is null);
return *ptr;
}
ref T cnvrt(T x) @property
{
enforce( ptr !is null);
return *ptr = x;
}
alias cnvrt this;
}

void main()
{
int i;
auto ri = reference!int(i);
auto ri2 = reference!int(ri);

assert(ri.ptr==ri2.ptr);

i = 99;
assert(i==ri && i==ri2 && ri==ri2);

ri = 100;
assert(i==ri && i==ri2 && ri==ri2);

ri2 = 101;
assert(i==ri && i==ri2 && ri==ri2);
}
```



Simulating reference variables using `alias this`

2017-05-10 Thread Carl Sturtivant via Digitalmars-d
Here's the beginning of an interesting little experiment to 
simulate reference variables using `alias this` to disguise a 
pointer as a reference. Could add a destructor to set the pointer 
to null when a reference goes out of scope.


```
struct reference(T)
{
T* ptr;
this(ref T x)
{
ptr = 
}
import std.exception : enforce;

ref T cnvrt() @property
{
enforce( ptr !is null);
return *ptr;
}
ref T cnvrt(T x) @property
{
enforce( ptr !is null);
return *ptr = x;
}
alias cnvrt this;
}

void main()
{
int i;
auto ri = reference!int(i);
auto ri2 = reference!int(ri);

assert(ri.ptr==ri2.ptr);

i = 99;
assert(i==ri && i==ri2 && ri==ri2);

ri = 100;
assert(i==ri && i==ri2 && ri==ri2);

ri2 = 101;
assert(i==ri && i==ri2 && ri==ri2);
}
```


Re: multiple `alias this` suggestion

2017-05-06 Thread Carl Sturtivant via Digitalmars-d

On Saturday, 6 May 2017 at 10:18:24 UTC, Seb wrote:
As no one pointed it out before, FYI there has been a previous 
DIP (https://wiki.dlang.org/DIP66) on which the old dmd PR was 
based on.


Glad you mentioned that!



Re: alias can't find symbol or can't use symbol

2017-05-06 Thread Carl Sturtivant via Digitalmars-d-learn

On Wednesday, 3 May 2017 at 09:04:07 UTC, Jonathan M Davis wrote:
I believe that the core problem is that an alias declaration 
just aliases a symbol - i.e. it just creates a new name for the 
symbol. And as far as I can tell,


alias n2 = x2.n;

is actually equivalent to

alias n2 = member.n;

You get exactly the same error message if that change is made. 
It's a bit like how you can call a static function with an 
object rather than the struct/class(e.g. s.foo() instead of 
S.foo()). Similarly, if you turn n into a member function, then 
you get an error like


q.d(20): Error: this for n needs to be type member not type 
outer


It's just aliasing the function, not creating a delegate or 
doing a syntactic conversion. If it _were_ doing a syntactic 
conversion and just making it so that everywhere you see n2, it 
got changed to x.n, then I could see code like


outer o;
o.n2 = 5;

working. But that's not how alias declarations work. They just 
create a new name for the symbol in the scope that they're 
declared. So, the symbol isn't tied to a particular instance, 
and you get the problem that you're having.


The following works with
outer2 o;
o.n2 = 5;
so it's not static, i.e. n2 is tied to the instance here.

struct outer2
{
int n;
alias n2 = n;
}

So it seems reasonable to have better semantics for an embedded 
struct with alias_this.





Re: multiple `alias this` suggestion

2017-05-04 Thread Carl Sturtivant via Digitalmars-d

On Wednesday, 3 May 2017 at 19:52:46 UTC, Daniel N wrote:

On Wednesday, 3 May 2017 at 19:41:58 UTC, Daniel N wrote:
On Saturday, 29 April 2017 at 23:57:07 UTC, Carl Sturtivant 
wrote:

On Thursday, 27 April 2017 at 05:41:43 UTC, Daniel N wrote:

Even better, with alias for embedded aliased-to-this structs 
made working usefully, name management can be done before 
embedding the features, by having another layer of embedding 
as in my earlier example here.

https://forum.dlang.org/post/hvdmtvjvccbkmkjzu...@forum.dlang.org



OK, you have a point.

I realise syntax is the least important part of this proposal, 
but "alias this" is the only alias that still is backwards...


If you do write a DIP at least consider this:
alias this : entity, render;


PS One could of course eat the cake and keep it still, at the 
cost of additional complexity.


Distributed and prioritized:
alias this : a_prio1, a_prio2, a_prio3;
alias this : b_prio1, b_prio2;

any a* could clash with any b* but a:s wont clash with their 
own kind since they are internally prioritised the same goes 
for b:s.


Reasonable. I may eventually resort to this possibility, but 
right now I am trying to force out the consequences of avoiding 
this extra complexity. (And syntax, yes, noted.)


Not finished posting to this thread yet.



Re: alias can't find symbol or can't use symbol

2017-05-04 Thread Carl Sturtivant via Digitalmars-d-learn

On Wednesday, 3 May 2017 at 09:04:07 UTC, Jonathan M Davis wrote:


I believe that the core problem is that an alias declaration 
just aliases a symbol - i.e. it just creates a new name for the 
symbol. And as far as I can tell,


alias n2 = x2.n;

is actually equivalent to

alias n2 = member.n;

You get exactly the same error message if that change is made. 
It's a bit like how you can call a static function with an 
object rather than the struct/class(e.g. s.foo() instead of 
S.foo()). Similarly, if you turn n into a member function, then 
you get an error like


q.d(20): Error: this for n needs to be type member not type 
outer


It's just aliasing the function, not creating a delegate or 
doing a syntactic conversion. If it _were_ doing a syntactic 
conversion and just making it so that everywhere you see n2, it 
got changed to x.n, then I could see code like


outer o;
o.n2 = 5;

working. But that's not how alias declarations work. They just 
create a new name for the symbol in the scope that they're 
declared. So, the symbol isn't tied to a particular instance, 
and you get the problem that you're having.


alias this is a bit different, because it isn't really aliasing 
the symbol - rather it's telling the compiler about an implicit 
conversion. So, that arguably confuses things a  bit, but for 
your example to work, normal alias declarations would need to 
do more than create a new name for a symbol, and as I 
understand it, they don't.


Now, I totally agree that it would be nice if your example 
would work, and I think that I've run into this problem before 
in my own code, but aliases would have to work a bit 
differently than they curently do for it to work. It seems like 
a reasonable enhancement request to me, but I'm not sure what 
Walter's take on it would be. He has a tendancy to see things 
how the compiler would in cases like this and not necessarily 
how a typical programmer would, so it wouldn't surprise me if 
he's reaction were that of course it wouldn't work, but I don't 
know. It's often the case that what the programmer thinks is 
intuitive doesn't really jive with how the language actually 
works.


Thanks, that was enlightening. That said, if alias this really 
did bring n into the outer scope in the specific case when it's a 
variable in an embedded struct then `alias n2 = n` in the outer 
scope would work in the ordinary way. After all,


struct fakeOuter
{
  int n;
  alias n2 = n;
}

void main()
{
  fakeOuter o;
  o.n2 = 5;
}

compiles and runs fine. And presumably as it's a struct being 
embedded here


struct member
{
int n;
}

struct outer
{
member x;
alias x this;
//alias n2 = n;
}

the binary layouts of fakeOuter and outer are the same, so the 
rename is harmless because it has a simple interpretation in 
regular D without `alias this`.






Re: alias can't find symbol or can't use symbol

2017-04-30 Thread Carl Sturtivant via Digitalmars-d-learn

On Sunday, 30 April 2017 at 02:19:29 UTC, bauss wrote:

What exactly did you expect here?

'n' is not in the scope of 'outer'.

'n' is in the scope of 'member'.

Of course it works with 'x.n' since 'x' points to the 'member' 
declared inside 'outer'.


I mean it would have worked with classes, but structs are 
different does not have any type of actual inheritance, which 
is what you're trying to achieve.


```
class member {
int n;
}

class outer : member {
alias n2 = n; // Ok ...
}
```


It did NOT work with x.n as I asserted. And `alias x this` brings 
n into the scope of outer. So your reply makes no sense.




alias can't find symbol or can't use symbol

2017-04-29 Thread Carl Sturtivant via Digitalmars-d-learn

Consider the following.

struct member
{
int n;
}

struct outer
{
member x;
alias x this;
alias n2 = n;
}

This does not compile: alias n2 = n;
Error: undefined identifier 'n'

On the other hand if change that into
alias n2 = x.n;
then it does compile.

void main()
{
outer o;
o.n2 = 5;
}

Now this code doesn't compile: o.n2 = 5;
Error: need 'this' for 'n' of type 'int'

Given that one struct inside another is a static situation, this 
seems unnecessarily strict. It's getting in the way of some name 
management with `alias this`. What's the rationale here?






Re: multiple `alias this` suggestion

2017-04-29 Thread Carl Sturtivant via Digitalmars-d

On Thursday, 27 April 2017 at 05:41:43 UTC, Daniel N wrote:
On Wednesday, 26 April 2017 at 18:34:48 UTC, Carl Sturtivant 
wrote:

On Wednesday, 26 April 2017 at 15:00:30 UTC, Steven
Image using frameworks which conveniently allow adding features 
to a struct...


struct Beholder
{
  mixin Entity!Movable;
  mixin Render!"Beholder.png";
}


Why distribute features as mixin templates when with AliasThis 
fully implemented they can be distributed as structs and are 
therefore encapsulated?


struct Beholder
{
//now Entity(T) is a struct template, not a mixin template
  Entity!Movable entity;
//ditto
  Render!"Beholder.png" render;
//in my hierarchical form
  alias entity, render this;
}

Even better, with alias for embedded aliased-to-this structs made 
working usefully, name management can be done before embedding 
the features, by having another layer of embedding as in my 
earlier example here.

https://forum.dlang.org/post/hvdmtvjvccbkmkjzu...@forum.dlang.org

Broadly speaking, a mixin template is just "a bunch of 
unencapsulated declarations". And AliasThis is a way to remove a 
layer of encapsulation from "a bunch of declarations". (Though it 
cannot be used currently outside of a struct or class.) This just 
screams for simplification.




Re: multiple `alias this` suggestion

2017-04-29 Thread Carl Sturtivant via Digitalmars-d
On Friday, 21 April 2017 at 14:55:31 UTC, Steven Schveighoffer 
wrote:
One thing we can do also is just use declaration order to 
prioritize which alias this to use.


Presumably using declaration order as a means of prioritizing 
which name wins was rejected as a design possibility in the case 
of mixin templates which don't do this.


There is a strong parallel between name collisions between 
multiple mixin template instantions in the same scope, and 
muliple AliasThis declarations in the same scope: both bring an 
arbitrary collection of names and their concomitant collisions 
into that scope.


So presumably using declaration order as a means of prioritizing 
which name wins in the case of AliasThis would be rejected for 
the same reasons as for mixin templates.




Re: multiple `alias this` suggestion

2017-04-29 Thread Carl Sturtivant via Digitalmars-d

On Friday, 28 April 2017 at 07:07:44 UTC, Daniel N wrote:

On Friday, 28 April 2017 at 05:32:36 UTC, Carl Sturtivant wrote:
On Friday, 28 April 2017 at 04:44:44 UTC, Carl Sturtivant 
wrote:

On Thursday, 27 April 2017 at 05:41:43 UTC, Daniel N wrote:
On Wednesday, 26 April 2017 at 18:34:48 UTC, Carl Sturtivant 
wrote:
On Wednesday, 26 April 2017 at 15:00:30 UTC, Steven 
Schveighoffer wrote:
I think you can appreciate that this doesn't scale. 
Imagine a case which has 2 or 3 optional alias this items.


-Steve


Agreed, not manually, as it is exponential in the number of 
conditions.


Image using frameworks which conveniently allow adding 
features to a struct...


struct Beholder
{
  mixin Entity!Movable;
  mixin Render!"Beholder.png";
}

... then you couldn't even solve it manually without 
rewriting the framework.


With distributed 'alias this' you could seamlessly combine 
any number of frameworks from different vendors.


Please explain "seamlessly" with the prospect of name 
collisions.


:) Disclosure: I have a negative view of mixin templates. 
Entanglement with names at the landing site is unhappy.




You don't have to fear mixin collisions since there is an 
awesomely designed builtin feature to solve this issue.


mixin template fun() { int a; }

struct A
{
mixin fun f1;
mixin fun f2;
}

void main()
{
auto a = A();

a.f1.a = 1;
a.f2.a = 2;
}


If having templates with dynamic bindings (set at the landing 
site) of some kind is obligatory, then this is about as good as 
it can get. I wouldn't call it awesome except in the sense that 
it cleverly makes the best of an awkward situation. It's not a 
clean abstraction: subsequently mixing in more "features of a 
struct" into your struct can make a formerly usable name in the 
outside world unusable.


However I am trying to arrive at a mechanism whereby this is 
unnecessary.


AliasThis has the same issues as led to the definition of mixin 
templates if there are multiple such. So there are two broad 
paths that could be followed. The first is to just swallow a 
similar mechanism as mixin templates, and try to allow arbitrary 
interaction among many distributed AliasThis declarations with 
fallback to fully qualified names in the event of ambiguity as in 
your example.


The second path is to endeavor to create a different mechanism 
that does not suffer from that approach, so an additional entity 
can be added to the list of things being aliased-to-this without 
making existing names unusable outside of the definition being 
made, exactly the way mixin templates don't.


I am trying to explore this second path.




Re: multiple `alias this` suggestion

2017-04-29 Thread Carl Sturtivant via Digitalmars-d

On Thursday, 27 April 2017 at 05:41:43 UTC, Daniel N wrote:
On Wednesday, 26 April 2017 at 18:34:48 UTC, Carl Sturtivant 
wrote:
On Wednesday, 26 April 2017 at 15:00:30 UTC, Steven 
Schveighoffer wrote:
I think you can appreciate that this doesn't scale. Imagine a 
case which has 2 or 3 optional alias this items.


-Steve


Agreed, not manually, as it is exponential in the number of 
conditions.


Image using frameworks which conveniently allow adding features 
to a struct...


struct Beholder
{
  mixin Entity!Movable;
  mixin Render!"Beholder.png";
}

... then you couldn't even solve it manually without rewriting 
the framework.


Here's a way to use single hierarchical AliasThis as per this 
thread without editing vendor code. No special mechanism for name 
collisions is needed.


// contain arbitrary names from vendors, & do some renaming if 
desired

struct EntityWrapper(T)
{
//one hierarchical AliasThis in here (or none)
  mixin Entity!T;
}
struct RenderWrapper(string s)
{
//one hierarchical AliasThis in here (or none)
  mixin Render!s;
  alias t2 = t; //e.g.
}

struct Beholder
{
  EntityWrapper!Movable entity;
  RenderWrapper!"Beholder.png" render;
//one hierarchical AliasThis in here
  alias entity, render this; //if render.t is shadowed, it gets 
out as t2

}




Re: multiple `alias this` suggestion

2017-04-27 Thread Carl Sturtivant via Digitalmars-d

On Friday, 28 April 2017 at 04:44:44 UTC, Carl Sturtivant wrote:

On Thursday, 27 April 2017 at 05:41:43 UTC, Daniel N wrote:
On Wednesday, 26 April 2017 at 18:34:48 UTC, Carl Sturtivant 
wrote:
On Wednesday, 26 April 2017 at 15:00:30 UTC, Steven 
Schveighoffer wrote:
I think you can appreciate that this doesn't scale. Imagine 
a case which has 2 or 3 optional alias this items.


-Steve


Agreed, not manually, as it is exponential in the number of 
conditions.


Image using frameworks which conveniently allow adding 
features to a struct...


struct Beholder
{
  mixin Entity!Movable;
  mixin Render!"Beholder.png";
}

... then you couldn't even solve it manually without rewriting 
the framework.


With distributed 'alias this' you could seamlessly combine any 
number of frameworks from different vendors.


Please explain "seamlessly" with the prospect of name 
collisions.


:) Disclosure: I have a negative view of mixin templates. 
Entanglement with names at the landing site is unhappy.


The idea of mixin template instantations bringing in AliasThis 
declarations is amplifying my negative view. Still, I suppose 
this could be made to work following analogous rules. Yuck.


Do we even need mixin templates when some form of multiple 
AliasThis is available? And if that form is really clean, haven't 
we then gained something?









Re: multiple `alias this` suggestion

2017-04-27 Thread Carl Sturtivant via Digitalmars-d

On Thursday, 27 April 2017 at 05:41:43 UTC, Daniel N wrote:
On Wednesday, 26 April 2017 at 18:34:48 UTC, Carl Sturtivant 
wrote:
On Wednesday, 26 April 2017 at 15:00:30 UTC, Steven 
Schveighoffer wrote:
I think you can appreciate that this doesn't scale. Imagine a 
case which has 2 or 3 optional alias this items.


-Steve


Agreed, not manually, as it is exponential in the number of 
conditions.


Image using frameworks which conveniently allow adding features 
to a struct...


struct Beholder
{
  mixin Entity!Movable;
  mixin Render!"Beholder.png";
}

... then you couldn't even solve it manually without rewriting 
the framework.


With distributed 'alias this' you could seamlessly combine any 
number of frameworks from different vendors.


Please explain "seamlessly" with the prospect of name collisions.



Re: multiple `alias this` suggestion

2017-04-26 Thread Carl Sturtivant via Digitalmars-d

On Wednesday, 26 April 2017 at 20:19:19 UTC, Walter Bright wrote:

On 4/21/2017 5:17 AM, Andrei Alexandrescu wrote:
This is interesting, and would be timely to discuss before an 
implementation of

multiple alias this gets started. -- Andrei


mixin templates already have an established method for 
resolving overloads and such with the names they introduce. Any 
multiple alias this solution should investigate any parallels 
with that.


The suggestion for multiple alias this I postulate in the 
original post in this thread is a clean way to avoid that 
complexity. Here's a summary.

https://forum.dlang.org/post/vkqriubvydntloptg...@forum.dlang.org

I am leaning toward the view that with some template support from 
a small library, to help use it effectively inside templates, 
that it provides a simple and effective solution to the problem. 
Here's one postulated template.

https://forum.dlang.org/post/irjupadpohusatrzo...@forum.dlang.org



Re: multiple `alias this` suggestion

2017-04-26 Thread Carl Sturtivant via Digitalmars-d
On Wednesday, 26 April 2017 at 15:00:30 UTC, Steven Schveighoffer 
wrote:
I think you can appreciate that this doesn't scale. Imagine a 
case which has 2 or 3 optional alias this items.


-Steve


Agreed, not manually, as it is exponential in the number of 
conditions. But I think some template machinery could mixin the 
right stuff in one place avoiding that problem, implanting the 
existing names in an `alias this`. So

  AliasThis!(x,y,z)
which could detect if each name exists in an instantiation and 
only use that name if so, and would be placed outside of any 
`static if` to do the job.


I'm leaning toward the notion that a single AliasThis of the kind 
I suggested  with a suitable template library to help out with 
matters such as the one you raised is enough.


(Some name management for shadowed names could be in that library 
too --- different topic, will discuss elsewhere.)





Re: multiple `alias this` suggestion

2017-04-26 Thread Carl Sturtivant via Digitalmars-d

On Monday, 24 April 2017 at 16:52:49 UTC, Carl Sturtivant wrote:
On Friday, 21 April 2017 at 14:55:31 UTC, Steven Schveighoffer 
wrote:
I agree, I like how this solves the ambiguity problem nicely. 
However, this disallows using introspection to declare 
multiple alias this piecemeal. e.g.:


struct S(bool foo)
{
  int x;
  alias x this;
  static if(foo)
  {
 string y;
 alias y this;
  }
}

One thing we can do also is just use declaration order to 
prioritize which alias this to use.


Not necessary in this case:

struct S(bool foo)
{
  int x;
  static if(!foo)
  {
 alias x this;
  }
  else
  {
 string y;
 alias x, y this;
  }
}

It's easier to analyze if  isn't distributed, i.e. if only one 
location applies.


It's easier to analyze if AliasThis isn't distributed, i.e. if 
only one location appears in a given instantiation.






Re: multiple `alias this` suggestion

2017-04-24 Thread Carl Sturtivant via Digitalmars-d

On Friday, 21 April 2017 at 14:51:42 UTC, Meta wrote:

auto x = top(1,2,3);

void takesMember1(member1) {}
void takesMember2(member2) {}
void takesMember3(member3) {}

static assert(__traits(compiles, { takesMember1(x); }));  
//Passes
static assert(__traits(compiles, { takesMember2(x); })); 
//Passes
static assert(__traits(compiles, { takesMember3(x); })); 
//Passes


This is a little bit surprising until you think about it a bit. 
It's also how we would want multiple alias this to behave were 
it implemented, which is a plus.


Nice!



Re: multiple `alias this` suggestion

2017-04-24 Thread Carl Sturtivant via Digitalmars-d
On Friday, 21 April 2017 at 14:55:31 UTC, Steven Schveighoffer 
wrote:
I agree, I like how this solves the ambiguity problem nicely. 
However, this disallows using introspection to declare multiple 
alias this piecemeal. e.g.:


struct S(bool foo)
{
  int x;
  alias x this;
  static if(foo)
  {
 string y;
 alias y this;
  }
}

One thing we can do also is just use declaration order to 
prioritize which alias this to use.


Not necessary in this case:

struct S(bool foo)
{
  int x;
  static if(!foo)
  {
 alias x this;
  }
  else
  {
 string y;
 alias x, y this;
  }
}

It's easier to analyze if  isn't distributed, i.e. if only one 
location applies.




Re: multiple `alias this` suggestion

2017-04-20 Thread Carl Sturtivant via Digitalmars-d
On Wednesday, 19 April 2017 at 18:32:43 UTC, Carl Sturtivant 
wrote:
Imagine the existing single `alias this` is extended to provide 
such a heierarchy of lookups. For example,


struct top
{
mem3 m3;
mem2 m2;
mem1 m1;
alias m3, m2, m1 this;
// ...
}

could be interpreted to mean search for a name in m3 if not 
found in top, and in m2 if not found in m3 and in m1 if not 
found in m2. I don't back the syntax, just the notion.


Maybe that's not all that's expected from "multiple alias this" 
but it would be a clean step forward. Issues?


No issues then!
Time for a D I P perhaps.
Comment?



multiple `alias this` suggestion

2017-04-19 Thread Carl Sturtivant via Digitalmars-d
Currently only one `alias this` declaration is permitted, and the 
documentation https://dlang.org/spec/class.html#AliasThis says 
the following.


"Multiple AliasThis are allowed. For implicit conversions and 
forwarded lookups, all AliasThis declarations are attempted; if 
more than one AliasThis is eligible, the ambiguity is disallowed 
by raising an error. Note: Multiple AliasThis is currently 
unimplemented."


However the effect of multiple `alias this` declarations can be 
approximated in existing D using only single `alias this`, e.g. 
in the following three members each with `alias this` are 
simulated.


//
struct member1
{
int n1, n2, n3;
}

struct member2
{
int n2, n3;
member1 member;
alias member this;
}

struct member3
{
int n3;
member2 member;
alias member this;
}

struct top
{
member3 member;
alias member this;

this(int i, int j, int k)
{
n1 = i; n2 = j; n3 = k;
}
}


void main()
{
auto x = top(1,2,3);
member3 m3 = x.member;
member2 m2 = m3.member;
member1 m1 = m2.member;

import std.stdio;
writefln("%s %s %s", m1.n1, m1.n2, m1.n3);
writefln("%s %s %s", m2.n1, m2.n2, m2.n3);
writefln("%s %s %s", m3.n1, m3.n2, m3.n3);
writefln("%s %s %s", x.n1, x.n2, x.n3);
}
//

Which outputs the following as expected from chaining the effects 
of `alias this`.


1 0 0
1 2 0
1 2 3
1 2 3

Note that this construction provides a natural hierarchy for name 
lookup, unlike the statement above taken from the documentation.


Imagine the existing single `alias this` is extended to provide 
such a heierarchy of lookups. For example,


struct top
{
mem3 m3;
mem2 m2;
mem1 m1;
alias m3, m2, m1 this;
// ...
}

could be interpreted to mean search for a name in m3 if not found 
in top, and in m2 if not found in m3 and in m1 if not found in 
m2. I don't back the syntax, just the notion.


Maybe that's not all that's expected from "multiple alias this" 
but it would be a clean step forward. Issues?





Re: std.digest toHexString

2017-03-16 Thread Carl Sturtivant via Digitalmars-d-learn

On Thursday, 16 March 2017 at 18:51:45 UTC, Adam D. Ruppe wrote:
Phobos could have been written to avoid this problem too, 
there's a few solutions that work, but right now, using the 
standard library in a way people expect to work will be 
silently disastrous.


Yes, and as an outsider I find this, well, disconcerting. No 
complaint from the compiler about assignment to string of the 
result of a library function call should have produced a string 
with the obvious semantics.


Having read this thread I have formed a conclusion.

Implicitly slicing rvalue arrays is too much like implicitly 
taking the address of an rvalue.


There's an explicit postfix operator [] to do that, and if there 
was no implicit slicing, I'd at least know where slicing is 
occurring and I wouldn't use the slice of a temporary beyond its 
lifetime.


Now a function with a slice parameter could not be called with an 
rvalue array parameter without putting an explicit slice operator 
in at the point of call.


But writing a function like that is just a way to regard rvalue 
arrays of different sizes based upon the same type as being the 
same type, when they are not. They are distinct types. And so a 
template could take care of that minor syntactic problem if so 
desired, with one instantiation for each rvalue array type (i.e. 
size), with a ref parameter to avoid copying.


I see every reason to remove implicit slicing of rvalue arrays.

Trying to keep it available sometimes is a complex endeavor, and 
the rules will be lengthy, and consequently have more 
complications to explain to people joining use of D, and for 
what? There's almost nothing to gain. This would be a mistake. D 
is already very large.


If I didn't know what my general confidence level in D was for 
other reasons, this incident could well have driven me away. The 
standard library compiled completely unexpectedly insane and 
unsafe semantics when I just called a simple-looking function. 
This sort of thing is undoubtedly bringing D into disrepute with 
some people here and there, people just trying it out to solve a 
problem.






Re: std.digest toHexString

2017-03-16 Thread Carl Sturtivant via Digitalmars-d-learn

On Thursday, 16 March 2017 at 17:20:45 UTC, H. S. Teoh wrote:
I'm not convinced casting static array to immutable is OK. 
Check this out:


import std.stdio;

char[32] func() {
char[32] staticArr = "A123456789abcdefB123456789abcdef";
return staticArr; // OK, by-value return
}

string gunk() {
	string x = func(); // implicit conversion char[32] -> 
string

writeln(x.ptr);
writeln(x); // prints "A123456789abcdefB123456789abcdef"
return x;
}

void main() {
auto s = gunk();
writeln(s.ptr); // prints same address as in gunk()
writeln(s); // prints corrupted string
}

Run this code and you'll see that s.ptr has the same address as 
x.ptr, and that x.ptr is the address of a local variable. This 
is blatantly wrong.


Filed a new issue for this:

https://issues.dlang.org/show_bug.cgi?id=17261


Exactly, if there was a variable of type char[32] on the right 
hand side of

string x = func();
instead of the call of func, then the compiler would complain. So 
this is a bug.






Re: std.digest toHexString

2017-03-16 Thread Carl Sturtivant via Digitalmars-d-learn

On Thursday, 16 March 2017 at 17:18:30 UTC, Adam D. Ruppe wrote:
On Thursday, 16 March 2017 at 17:12:08 UTC, Carl Sturtivant 
wrote:

I did that, and it made no difference. :(


wait a minute i just realized:

toHexString.d(11) in the error message

You named the file toHexString which means the *module* will be 
named toHexString by default...


OK, right!




  1   2   >