Re: Minimize GC memory footprint

2021-02-05 Thread Bastiaan Veelo via Digitalmars-d-learn

On Wednesday, 3 February 2021 at 13:37:42 UTC, frame wrote:
I have to deal with GC as long I want to use other libraries 
that are relying on it or even just phobos.


Conclusion so far (for Windows):

32bit:
- GC just doesn't work at all


?? Do you mean no collections happen? 32bit GC should just work.


64bit:
- Collections are rare. It can be necessary to call 
GC.collect() manually.
- Scope guards to explicit clean up / free memory at function 
exit have no deep impact on most cases.
- If your application should save memory call GC.minimize() 
when it's appropriate.



It seems that calling GC.enable() if it's already enabled just 
disables the automatic GC again? Is this a bug? I cannot 
reproduce it outside my application yet since it's not clear 
when the GC starts collecting, but it always shows the same 
behaviour:



// GC.enable();

Case A: The app is very kind in memory usage (~20 MB)


GC.enable();

Case B: The app is consuming huge amount of memory (~900 MB)


GC.disable();
GC.enable();

Case A again


GC.disable();
GC.enable();
GC.enable();

Case B again


That looks like a bug indeed.


I also have to struggle what the specs' text actually mean:

This function is reentrant, and must be called once for every 
call to disable before automatic collections are enabled.


I think it means that you need to make sure that enable() is 
called as many times as disable() is called before collection can 
happen automatically.


— Bastiaan.


Re: Using the Standard Library with C++ Interop

2021-02-05 Thread Bastiaan Veelo via Digitalmars-d-learn

On Friday, 5 February 2021 at 21:40:29 UTC, wolfiesnotfine wrote:
In any case, I'm unsure how I would runtime init from C++. Is 
there a specific function I should call?


https://dlang.org/phobos/core_runtime.html#.rt_init

Could this be done at compile time in a consteval or constexpr 
function?


This being the runtime, I presume it should be called at run time 
:-) I haven’t used it, but searching for rt_init should give you 
some pointers.


—Bastiaan



Re: writeln and write at CTFE

2021-01-13 Thread Bastiaan Veelo via Digitalmars-d-learn
On Wednesday, 13 January 2021 at 09:11:53 UTC, Guillaume Piolat 
wrote:

On Wednesday, 13 January 2021 at 08:35:09 UTC, Andrey wrote:

Hello all,
Tell me please how can I "writeln" and "write" in function 
that is used in CTFE?

At the moment I get this:
import\std\stdio.d(4952,5): Error: variable impl cannot be 
modified at compile time


Or may be exist some other ways to do it?


pragma(msg, );


This may however not do what you wish it to do: 
https://forum.dlang.org/post/mailman.4526.1499573493.31550.digitalmars-d-le...@puremagic.com


— Bastiaan.


Re: Using a betterC dub package in ordinary D

2021-01-08 Thread Bastiaan Veelo via Digitalmars-d-learn

On Friday, 8 January 2021 at 18:28:36 UTC, Ferhat Kurtulmuş wrote:

On Friday, 8 January 2021 at 15:40:12 UTC, Bastiaan Veelo wrote:

Hi,

When I use earcutd [1] in an ordinary D project, I get a link 
error for the __D7earcutd12__ModuleInfoZ symbol.

[...]


Dear Bastiaan,

I am not an expert in dub system, but I have just pushed a 
modification in dub.json. I am not sure if it solves your 
problem. My modification is


"configurations": [
{
"name": "default",
"targetType": "library"
},
{
"name": "betterC",
"targetType": "library",
"dflags": ["-betterC"]
}
]

now client projects must explicitly pass the subConfiguration 
parameter to compile it with betterC.


Much appreciated Ferhat! This works like a charm. I am kind of 
surprised that it does, as I expected dvector to need the same 
treatment. Excellent support by the way, thanks!


Off topick, the original js implementation is documented to not 
generate results that are guaranteed to be correct. I could not 
find information on what the conditions are that cause 
deviations, and how large these then can be. Do you have an idea 
about this or experience with accuracy of the algorithm? I am 
looking into whether earcutd can replace GLU tesselation. We use 
the result for engineering purposes (not only visualisation) and 
correctness is important to us.


Thanks!
Bastiaan.


Using a betterC dub package in ordinary D

2021-01-08 Thread Bastiaan Veelo via Digitalmars-d-learn

Hi,

When I use earcutd [1] in an ordinary D project, I get a link 
error for the __D7earcutd12__ModuleInfoZ symbol. This is because 
the earcutd dub.json has `"dflags": ["-betterC"]`. I think this 
is in error, my understanding of betterC code is that it can be 
compiled with "-betterC", but does not need to (and must not when 
used in D context).


Am I right? What are the best practices for betterC dub packages?

Thanks,
Bastiaan.


[1] https://code.dlang.org/packages/earcutd


Re: Writing a really fast lexer

2020-12-12 Thread Bastiaan Veelo via Digitalmars-d-learn

On Saturday, 12 December 2020 at 18:15:11 UTC, vnr wrote:
On Saturday, 12 December 2020 at 16:43:43 UTC, Bastiaan Veelo 
wrote:
Have you looked at Pegged [1]? It will give you the lexer and 
parser in one go. I'd be very interested to see how it 
performs on that kind of input.


-- Bastiaan.

[1] https://code.dlang.org/packages/pegged


Yes, I know Pegged, it's a really interesting parser generator 
engine, nevertheless, the grammar of what I would like to 
analyse is not a PEG. But I am also curious to know the 
performances of this tool for very large inputs.


Are you able to share the grammar? Since you plan to parse using 
recursive descent, I think there is a good chance that the 
language can be defined as a PEG. I am using it to parse Pascal, 
whose grammar was defined long before PEG was a thing.


— Bastiaan.


Re: Writing a really fast lexer

2020-12-12 Thread Bastiaan Veelo via Digitalmars-d-learn

On Friday, 11 December 2020 at 19:49:12 UTC, vnr wrote:
For a project with good performance, I would need to be able to 
analyse text. To do so, I would write a parser by hand using 
the recursive descent algorithm, based on a stream of tokens. I 
started writing a lexer with the d-lex package 
(https://code.dlang.org/packages/d-lex), it works really well, 
unfortunately, it's quite slow for the number of lines I'm 
aiming to analyse (I did a test, for a million lines, it lasted 
about 3 minutes). As the parser will only have to manipulate 
tokens, I think that the performance of the lexer will be more 
important to consider. Therefore, I wonder what resources there 
are, in D, for writing an efficient lexer.


Have you looked at Pegged [1]? It will give you the lexer and 
parser in one go. I'd be very interested to see how it performs 
on that kind of input.


-- Bastiaan.

[1] https://code.dlang.org/packages/pegged



Re: Pass enum variable as const ref arg

2020-12-04 Thread Bastiaan Veelo via Digitalmars-d-learn

On Friday, 4 December 2020 at 12:54:25 UTC, Andrey wrote:

Hello,


void test(const ref string[3] qazzz) { qazzz.writeln; }

void main()
{
enum string[3] value = ["qwer", "ggg", "v"];
test(value);
}


Gives errors:


It works if you pass `-preview=rvaluerefparam` to the compiler.

But the other suggestions are better IMO.

—Bastiaan.


Re: Is garbage detection a thing?

2020-11-29 Thread Bastiaan Veelo via Digitalmars-d-learn

On Sunday, 29 November 2020 at 16:05:04 UTC, Mark wrote:

Hi,

can I ask you something in general? I don't know anyone whom I 
could ask. I'm a hobbyist with no science degree or job in 
computing, and also know no other programmers.


I have no good understanding why "garbage collection" is a big 
thing and why "garbage detection" is no thing (I think so).


In order to detect garbage, you need extensive run-time 
instrumentation, the difficulties of which you have indicated 
yourself. In addition comes that detection depends on 
circumstance, which is an argument against the debug/release 
strategy you proposed. There is no guarantee that you’ll find all 
problems in the debug build. Garbage collection also comes at a 
runtime cost, but strategies exist to minimise those, and in 
addition a GC enables valuable language features. One such 
strategy is to minimise allocations, which improves performance 
in any memory management scheme.


[...]
What I don't understand is, when today there exist tools for 
C++ (allocator APIs for debugging purposes, or 
Address-Sanitizer or maybe also MPX) to just detect that your 
program tried to use a memory address that was actually freed 
and invalidated,


why did Java and other languages not stop there but also made a 
system that keeps every address alive as long as it is used?


Elimination of memory problems is much more valuable than 
detection. Recovering from memory errors at run time is 
unreliable.


One very minor criticism that I have is: With GC there can be 
"semantically old data" (a problematic term, sorry) which is 
still alive and valid, and the language gives me the feeling 
that it is a nice system that way. But the overall behavior 
isn't necessarily very correct, it's just that it is much 
better than a corrupted heap which could lead to everything 
possibly crashing soon.


At least in D, you can avoid old data to hang around for too 
long. See core.memory.


Or maybe I could use the safe-c subset in D? But I believe it 
uses garbage collection. I know nothing about it, sorry.


@safe D is not a sub-set, indeed it uses garbage collection. Fact 
is that there are very few domains where this is a problem. Not 
all garbage collectors are equal either, so if you think garbage 
collection is bad in one language, this may not directly apply in 
another. In D the garbage collector is even pluggable, various 
implantations exist. Have you seen the GC category on the 
blog?https://dlang.org/blog/2017/03/20/dont-fear-the-reaper/


BetterC is a subset of D, it does not use garbage collection.

You may be interested in current work being done in static 
analysis of manual memory management in D: 
https://youtu.be/XQHAIglE9CU


The advantage of D is that all options are open. This allows the 
following approach:
1) Start development without worrying about memory. Should 
collection cycles be noticeable:
2) Profile your program and make strategic optimisations 
https://youtu.be/dRORNQIB2wA. If this is not enough:
3) Force explicit collection in idle moments. If you need to go 
further:
4) Completely eliminate collection in hot loops using @nogc 
and/or GC.disable. When even this is not enough:

5) Try another GC implementation. And if you really need to:
6) Switch to manual memory management where it matters.

This makes starting a project in D a safe choice, in multiple 
meanings of the word.


— Bastiaan.


Re: Can't pass [] to extern function object method

2020-11-18 Thread Bastiaan Veelo via Digitalmars-d-learn

On Wednesday, 18 November 2020 at 10:50:12 UTC, frame wrote:
I found the "bug". It was caused by a debug {} statement within 
a struct method. I assume that the debug symbol is just 
incompatible called from the DLL context.


Were the DLL and main program built in different modes 
(debug/release)? Then this problem is understandable. Otherwise I 
find this surprising, and probably worth a bug report?


— Bastiaan.


Re: How can execute method in new Thread?

2020-11-15 Thread Bastiaan Veelo via Digitalmars-d-learn

On Saturday, 14 November 2020 at 17:21:15 UTC, Marcone wrote:
Error: 
D:\dmd2\windows\bin\..\..\src\phobos\std\parallelism.d(516): 
Error: struct `Fruit` does not overload ()


I think you need to pass the this pointer somehow. This works:


import std;

struct Fruit {
string name;

static void printmyname(Fruit thisFruit)
{
writeln(thisFruit.name);
}

void showname()
{
 task!printmyname(this).executeInNewThread;
}
}


void main()
{
Fruit f = Fruit("Banana");
f.showname();
}


This does too:


import std;

struct Fruit
{
string name;

void printmyname()
{
writeln(name);
}

void showname()
{
task!((Fruit 
me){me.printmyname;})(this).executeInNewThread;

}
}


void main()
{
Fruit f = Fruit("Banana");
f.showname();
}


—Bastiaan.


Re: App hangs, GC.collect() fixet it. Why?

2020-09-29 Thread Bastiaan Veelo via Digitalmars-d-learn
On Monday, 28 September 2020 at 21:58:31 UTC, Steven 
Schveighoffer wrote:

On 9/28/20 3:28 PM, Bastiaan Veelo wrote:
I’m leaning towards ditching the memory mapped I/O on the D 
end, and replace it by regular serialisation/deserialisation. 
That will be a manual rewrite though, which is a bit of bummer 
as memory mapped files are widely used in our Pascal code. But 
this will probably give the best end result.


2 things:

1. I agree this is the answer. If you ever ditch the old Pascal 
code, then you can reactivate the memory-mapped code.
2. You can possibly do the translation outside of your 
programs. That is, it wouldn't be entirely impossible to simply 
have a process running that ensures the "D view" and the 
"Pascal view" of the same file is kept in sync. Then you can 
keep the memory mapped code the same, and just define sane 
structures in your D code.


If you aren't required to have both Pascal and D programs 
reading and writing the file at the same time, this shouldn't 
be a problem.


There is no need to run both versions concurrently. The issue is 
that design offices typically maintain a library of past designs 
for as long as they are in existence, to build new designs off 
of. So being able to read or import the files that were written 
with an ancient version of our software is very valuable. Our old 
compiler offered two alternatives for file i/o: one where all 
elements are of the same type, the other one (memory mapped 
files) being the "only" option for files of mixed type. Ideally, 
the structs that are used for i/o do not have any pointers in 
them, and certainly in the more recent file versions that would 
be the case. In older versions that might not be the case; then 
the pointers obviously would be given meaningful values after the 
structs would have been read back in. These cases we would be 
able to work around, though, by converting the old structs to new 
ones upon import.


BTW, one further thing I don't understand -- if this is memory 
mapped data, how come it has issues with the GC? And what do 
the "pointers" mean in the memory mapped data? I'm sure there's 
good answers, and your actual code is more complex than the 
simple example, but I'm just curious.


The main problem is that the transpiler doesn't know which 
structs are used for i/o and would need 1-byte alignment, and 
which structs have pointers into GC memory and must not be 1-byte 
aligned. The alternative to switching to 
serialisation/deserialisation is to stay with the automated 
translation of the memory mapped file implementation, not 
automatically 1-byte align every struct but manually align the 
ones that are used in i/o. This is however sensitive to mistakes, 
and the translated mmfile implementation has a bit of a smell to 
it. It is also not portable, as it uses the WinAPI directly. 
Still, it may be the quickest route to get us back on track.


I am very glad to have identified the problem, and there being 
ways to deal with it. I just hope this will be the last big 
hurdle :-)


-Bastiaan.


Re: App hangs, GC.collect() fixet it. Why?

2020-09-28 Thread Bastiaan Veelo via Digitalmars-d-learn
On Monday, 28 September 2020 at 15:44:44 UTC, Steven 
Schveighoffer wrote:

On 9/28/20 8:57 AM, Bastiaan Veelo wrote:

I am glad to have found the cause of the breakage finally, but 
it won't be easy to find a generic solution...


Obviously, this isn't a real piece of code, but there is no way 
around this. You have to align your pointers. The other option 
is to not use the GC and use manual memory management.


If this is a compatibility thing between D and Pascal, and you 
absolutely have to have the same layout, is there a way to 
adjust the structure in Pascal? Like put the elements that 
misalign the pointers at the end of the structure?


Another totally drastic approach would be to supply your own 
even-more-conservative GC which will scan misaligned pointers. 
Probably going to hurt performance quite a bit. You might be 
able to get away with marking only certain blocks as having 
misaligned pointers, but you will have to scan all the stacks 
with this assumption.


Some more information about the setup you are using might help 
(I'm assuming D and Pascal are using the same memory in the 
same process, otherwise this wouldn't be a problem). In 
particular, where does the data come from, and how malleable is 
it in your system? Are there times where references to the D 
data only exist in Pascal?


-Steve


Thanks a lot for thinking with me. I’m not linking any Pascal 
objects, so I don’t need to maintain binary compatibility in 
memory; Only compatibility of data files. The problem arises when 
those files are read using memory mapped files, from which 
structs are memcpy’d over. This is of course the result of 
machine translation of the current Pascal implementation.


Manual memory management is an option and would be 
straightforward in principle, as we’ve done that for ages. The 
only thing is that this memory cannot contain other allocations 
on the GC heap, such as strings or other slices, unless they are 
both aligned and their root is registered.


Fixing the alignment in Pascal is possible in principle, but any 
old files would then need to first be processed by the last 
Pascal version of the programs, which we then would need to keep 
around indefinitely. There would also be issues when we port from 
32 bit to 64 bit.


Another option could be to use 1-byte aligned structs for I/O, 
and copy the members over in default aligned versions. But this 
cannot be part of the automated transcompilation.


Thanks for suggesting a custom gc, which I had not thought of.

I’m leaning towards ditching the memory mapped I/O on the D end, 
and replace it by regular serialisation/deserialisation. That 
will be a manual rewrite though, which is a bit of bummer as 
memory mapped files are widely used in our Pascal code. But this 
will probably give the best end result.


-Bastiaan.


Re: App hangs, GC.collect() fixet it. Why?

2020-09-28 Thread Bastiaan Veelo via Digitalmars-d-learn
On Friday, 5 June 2020 at 21:20:09 UTC, Steven Schveighoffer 
wrote:
This kind of sounds like a codegen bug, a race condition, or 
(worst case) memory corruption.


I think it must have been memory corruption: I had not realized 
that our old Pascal compiler aligns struct members on one byte 
boundaries, and also uses ubyte as the base type for enumerations 
(or ushort if required) instead of uint. When using memory mapped 
files this binary incompatibility likely caused the corruption.


But, after correcting that mistake, suddenly things broke that 
had been working for a long time. Having no idea what could be 
wrong this time, I spent quite some time dustmiting (thanks 
Vladimir!) and manually reducing the code. Voilà:



import std.stdio;
import core.memory;

struct Nothing
{
}

struct Info
{
align(1):
  ubyte u;
  Nothing*[2] arr;
}

Info* info;

void main()
{
  info = new Info;
  writeln("1");
  GC.collect();
  info.arr[0] = new Nothing;
  writeln("2");
  GC.collect();
  info.arr[1] = new Nothing;
  writeln("info.arr[0]  = ", info.arr[0]);
  writeln("info.arr[1]  = ", info.arr[1]);
  assert(info.arr[0] != info.arr[1], "Live object was 
collected!");

}


(The assert triggers on Windows, not on run.dlang.org.) 
Unfortunately for me, I cannot blame this on the compiler. It 
violates the requirements from the spec:


  "Do not misalign pointers if those pointers may point into the 
GC heap" (https://dlang.org/spec/garbage.html)


I am glad to have found the cause of the breakage finally, but it 
won't be easy to find a generic solution...


-Bastiaan.


Re: Why Pegged action dont not work in this case ?

2020-06-11 Thread Bastiaan Veelo via Digitalmars-d-learn

On Sunday, 19 April 2020 at 16:47:06 UTC, Basile B. wrote:
I 've started experimenting Pegged action. Quickly i got 
blocked by this problem. The start action works where I use the 
rule but not directly in the rule.


I don't understand the difference between how you use "where" and 
"directly in".


Note that semantic actions are executed during the parsing 
process, even in branches that eventually fail, before the parser 
back tracks. They are not a substitute for traversing the final 
parse tree, rather, they are a method for manipulating the 
parsing process as it happens.


That's why `endResultRecord` is executed directly after `(',' 
Result)*` succeeds, and `beginResultRecord` is executed directly 
after `ResultRecord` succeeds (even if `'(gdb)'` would not match).



Test program:

[...]
ResultRecord< {beginResultRecord} Token? '^' 
ResultClass (',' Result)* {endResultRecord}


Remove the space between "<" and "{", then it works.

Also I'd like to report that actions dont work with partially 
specialized templates:


---
T handleResultRecord(bool end,  T)(T t);
// then you use handleResultRecord!true and 
handleResultRecord!false in the PEG.

---


That fails for the same reason as `handleResultRecord!true(1)` 
fails to instantiate.


-- Bastiaan.


App hangs, GC.collect() fixet it. Why?

2020-06-05 Thread Bastiaan Veelo via Digitalmars-d-learn
I've been tracking down a hang in our pilot app. Using writeln, 
it appears to hang at newing a slice. After many hours of trying 
things, I discovered that program flow would continue past that 
point when I inserted a call to `GC.collect()` just before. Then 
it stalled again at a call to Win32 `SetMenu()`. Again, inserting 
`GC.collect()` before that made the problem go away.


This band-aid isn't going to scale in the long run. I feel I'm 
treating symptoms, and wonder what the cause is. Any ideas?


I know the GC is not disabled somehow because if I print 
`GC.profileStats()`, I see that there are collections even 
without my explicit calls to `GC.collect()`.


Thanks,

Bastiaan.


Re: Postblit segfault.

2020-06-01 Thread Bastiaan Veelo via Digitalmars-d-learn

On Monday, 1 June 2020 at 09:42:44 UTC, Boris Carvajal wrote:

On Monday, 1 June 2020 at 06:35:36 UTC, MaoKo wrote:

Hello, I don't understand why this code segfault on


Reduced to:

import std.stdio;

struct S {}

void main() {
  S[1] s;
  writeln(s);
}


This used to work up to dmd 2.084.1. It fails since 2.085.1. 
Please file a regression report at 
https://issues.dlang.org/enter_bug.cgi?product=D


— Bastiaan.


Re: CT BitArray

2020-04-02 Thread Bastiaan Veelo via Digitalmars-d-learn
On Thursday, 1 November 2018 at 08:50:38 UTC, Bastiaan Veelo 
wrote:

On Thursday, 1 November 2018 at 00:01:04 UTC, Stefan Koch wrote:
On Wednesday, 31 October 2018 at 23:14:08 UTC, Bastiaan Veelo 
wrote:
Currently, BitArray is not usable at compile time, so you 
cannot do

```
enum e = BitArray([1, 1, 1, 0]);
```
This gives

/dlang/dmd/linux/bin64/../../src/phobos/std/bitmanip.d(1190): Error: `bts` 
cannot be interpreted at compile time, because it has no available source code


[]


meanwhile use module level BitArrays like
```
immutable BitArray e;
static this()
{
e = BitArray([1, 1, 1, 0]);
}
```


Note to self: when this occurs, the above error message does not 
offer a trace to the place where this originates. To get that, 
temporarily insert the following at the indicated line in 
bitmanip.d:

```
if(__ctfe) assert(false, "trap");
```

--Bastiaan.


Re: New with alias

2020-03-10 Thread Bastiaan Veelo via Digitalmars-d-learn

On Tuesday, 10 March 2020 at 06:09:23 UTC, tcak wrote:

I write a code as below:

auto result = new char[4];

It allocates memory as expected.


This is a slice of four chars, which can be used as a dynamic 
array.



Later I define an alias and do the above step:

alias Pattern = char[4];


This is an alias for a static array with a fixed length of four 
chars.



auto result = new Pattern;

But compiler says:
Error: new can only create structs, dynamic arrays or class 
objects, not `char[4]`'s


Is this a bug, or `alias` doesn't work how I was thinking?


It is not a bug. You cannot new static arrays. You can do this, 
though:


Pattern pattern; // One static array of four chars.
auto patterns = new Pattern[3]; // A slice with three static 
arrays of four chars.



--Bastiaan.



Re: Specify dmd or ldc compiler and version in a json dub file?

2020-01-20 Thread Bastiaan Veelo via Digitalmars-d-learn

On Tuesday, 8 August 2017 at 09:17:02 UTC, data pulverizer wrote:
I would like to know how to specify dmd or ldc compiler and 
version in a json dub file.


Update: you can at least specify these in the toolchain 
requirements section: 
https://dub.pm/package-format-json.html#toolchain-requirements


I myself am looking for ways to satisfy these automatically, 
using a tool like dvm (https://code.dlang.org/packages/dvm) in 
preBuildCommands.


Bastiaan.


Re: Slice/Substr [0..?lastIndexOf(".")] How refer itself without create a variable?

2019-12-05 Thread Bastiaan Veelo via Digitalmars-d-learn

On Thursday, 5 December 2019 at 11:28:51 UTC, Marcone wrote:

Simple example:

writeln("Hi\nHow are 
you?\nGood".splitLines()[0][0..?lastIndexOf(r"\")]);


How to refer to this string in lastIndexOf() without create a 
variable?


Thank you.


.splitLines[0] already just produces "Hi", containing no "\", so 
this example is a bit broken.


  writeln("#", "Hi\nHow are you?\nGood".splitLines()[0], "#"); // 
#Hi#


You could write a function to work around having to declare a 
variable:


  string upto(string input, string delim)
  {
  return input[0 .. input.countUntil(delim)];
  }

  void main()
  {
  writeln(upto("Up to colon: skip this", ":")); // Up to colon
  writeln("Up to colon: skip this".upto(":")); // Up to colon
  }

You can use a function literal or lambda, but it isn't pretty:

  writeln((string s){return s[0..s.countUntil(":")];}("Up to 
colon: skip this")); // Up to colon
  writeln((s => s[0..s.countUntil(":")])("Up to colon: skip 
this")); // Up to colon


Bastiaan.


Re: const and immutable values, D vs C++?

2019-12-04 Thread Bastiaan Veelo via Digitalmars-d-learn
On Wednesday, 4 December 2019 at 14:44:43 UTC, Ola Fosheim 
Grøstad wrote:
When is there a noticable difference when using const values 
instead of immutable values in a function body? And when should 
immutable be used instead of const?


f(){
  const x = g();
  immutable y = g();
  ... do stuff with x and y …
}


There is a difference I guess if g() returns a reference type and 
is an inout function. immutable y will only work if the reference 
returned is immutable.


Const is a promise to the rest of the code that you will never 
mutate it. Immutable is a promise by the rest of the code that it 
will never mutate.


Immutable is more powerful, allowing data sharing in overlapping 
slices and between threads without locks. Const is more 
versatile, allowing references to data regardless of its 
mutability.


So if g() always returns immutable, it’s best to receive it as 
such, not const. If it can be either, it must be received as 
const.



I'm comparing D to C++ and I get the following mapping:


Does that make sense at all? D’s const is transitive, C++’s is 
not.


Bastiaan.



Re: Unexpected aliasing

2019-11-12 Thread Bastiaan Veelo via Digitalmars-d-learn

On Tuesday, 12 November 2019 at 08:15:20 UTC, Basile B. wrote:


I'm curious to know what is the equivalent in Pascal that your 
transpiler fails to translate since Pascal records don't have 
constructors at all. Maybe you used an old school 'Object' ?


Note that Extended Pascal is not exactly Pascal. An example:

  TYPE Ints(upperBound) = ARRAY [1 .. upperBound] of Integer;
   MyRecord = RECORD
  integers : Ints(5);
  END;
   SchematicRecord(num) = RECORD
  integers : Ints(num);
  END;
   IntsPtr = ^Ints;

  PROCEDURE myProcedure(PROTECTED VAR someArr : Ints);
  BEGIN
  writeln(someArr.upperBound);
  END;

  PROCEDURE proc;
  VAR dynamicInts : IntsPtr;
  rec : MyRecord;
  BEGIN
  dynamicInts = new(10);
  myProcedure(dynamicInts^);
  myProcedure(rec.integers);
  END;

In this case, only the upper bound of Ints is parameterized, but 
the lower bound could be parameterized as well. Records can also 
be schematized. Procedure arguments can take schemas that are 
undiscriminated, they carry their schemaparameters as properties.


Bastiaan.


Re: Unexpected aliasing

2019-11-12 Thread Bastiaan Veelo via Digitalmars-d-learn
On Monday, 11 November 2019 at 21:52:12 UTC, Jonathan M Davis 
wrote:
On Monday, November 11, 2019 12:17:37 PM MST Bastiaan Veelo via 
Digitalmars- d-learn wrote:


[...]

I could use some help in rewriting the code below so that arr1 
and arr2 each have their own data; ideally with minimal 
changes so that I can make the transcompiler do the right 
thing.


Thanks!
Bastiaan.

void main()
{
  import std.stdio;

  WrapIntegerArray arr1;
  arr1[0] = 42;

  WrapIntegerArray arr2;

  writeln(arr2[0]); // 42, not 0.
  writeln("arr1.wrap.arr.ptr = ", arr1.wrap.arr.ptr);
  writeln("arr2.wrap.arr.ptr = ", arr2.wrap.arr.ptr); // 
identical

  assert(arr2[0] == 0); // fails
}

struct IntegerArray
{
  int[] arr;
  alias arr this;
  this(int l)
  {
  arr = new int[l];
  }
}

struct WrapIntegerArray
{
  auto wrap = IntegerArray(5); // This is CTFE! :-(
  alias wrap this;
}


All struct and class members which are directly initialized 
must have their values known at compile-time. For structs, 
that's what goes in the init value for the type. A side effect 
of this is that it's usually a bad idea to directly initialize 
dynamic arrays which are member variables. You need to do the 
initialization in a constructor. And for structs, if you need a 
no-arg constructor, then you'll need to use a factory function 
(since structs can't have no-arg constructors). e.g.


struct WrapIntegerArray
{
IntegerArray wrap;
alias wrap this;

this(int len)
{
wrap = IntegerArray(len);
}
}

or

struct WrapIntegerArray
{
IntegerArray wrap;
alias wrap this;

static make()
{
WrapIntegerArray retval;
retval.wrap = IntegerArray(5);
return retval;
}
}

So, you could then have something like

auto arr1 = WrapIntegerArray(5);
arr1[0] = 42;

or

auto arr1 = WrapIntegerArray.make();
arr1[0] = 42;

but if you use the init value (which is what you get if you let 
the type be default-initialized), then you'll have to first do 
something to allocate the dynamic array if you want to be able 
to index it, since if you don't give it a value at 
compile-time, it's null (and you don't want to give it a value 
at compile-time, because then every default-initialized struct 
of that type will refer to the same dynamic array). Of course, 
you could always just append values, and the dynamic array will 
be allocated and grow accordingly, but that's obviously not the 
same as allocating it up front to have a specific length.


- Jonathan M Davis


Thank you Jonathan. A factory function seems to be what I need, 
then. It'll be an interesting challenge to have my transpiler 
detect when a factory function is needed, and making sure that 
they are called at the right places. But this might escalate 
since structs can have members that are structs that have a 
factory function. So the enclosing struct also needs a factory 
function. And so forth.


My problem is the translation of so called schematic arrays, a 
type that I have only seen in Extended Pascal. A schematic array 
is a type in which the length of the array is a parameter of the 
type. Extended Pascal does not have dynamic arrays, so schematic 
arrays are its attempt at improving a bit on just plain static 
arrays. The length parameter can be constant, in which it behaves 
akin to templates (which it doesn't have either), but it can also 
be set at run time during initialization (so I can't translate it 
to a template).


Maybe I can omit the translation of schematic arrays 
(IntegerArray in this case) altogether and instead detect where 
and how they are instantiated. Then replace them with a static 
array whenever the length is known at compile time, and a dynamic 
array otherwise. A static array is not nice, but at least they 
can be members of structs without a factory function. Either way, 
my transpiler needs to smarten up...


Bastiaan.


Re: Unexpected aliasing

2019-11-12 Thread Bastiaan Veelo via Digitalmars-d-learn

On Monday, 11 November 2019 at 20:05:11 UTC, Antonio Corbi wrote:
Defining and using a constructor for WrapIntegerArray seems to 
work:


void main()
{
import std.stdio;

WrapIntegerArray arr1 = WrapIntegerArray(5);
arr1[0] = 42;

WrapIntegerArray arr2 = WrapIntegerArray(5);

writeln(arr2[0]); // 42, not 0.
writeln("arr1.wrap.arr.ptr = ", arr1.wrap.arr.ptr);
	writeln("arr2.wrap.arr.ptr = ", arr2.wrap.arr.ptr); // 
identical

assert(arr2[0] == 0); // fails
}

struct IntegerArray
{
int[] arr;
alias arr this;
this(int l)
{
arr = new int[l];
}
}

struct WrapIntegerArray
{
this (int v) {
  wrap = IntegerArray(5);
}

IntegerArray wrap;
alias wrap this;
}

Hope this helps.
Antonio


Thanks, Antonio. My problem is that the length of the array 
should be a built-in property of WrapIntegerArray (immutable in 
this case); what I'd actually want is a constructor without 
arguments. Jonathan's suggestion of using a factory function 
comes closest to that.


Bastiaan.


Unexpected aliasing

2019-11-11 Thread Bastiaan Veelo via Digitalmars-d-learn
Recently I got my first surprise with our use of D. The symptom 
was that two local variables in two different functions appeared 
to be sharing data.


A simplified example is shown below (the original was machine 
translated from Pascal and involved templates and various levels 
of indirection). What I did not know is that the initial value of 
struct members is a compile time feature, apparently. What I 
suspect is happening is that the array lives in the static data 
segment (or is created in the module constructor?) and that the 
slices inside arr1 and arr2 get initialised to point to that same 
array.


I could use some help in rewriting the code below so that arr1 
and arr2 each have their own data; ideally with minimal changes 
so that I can make the transcompiler do the right thing.


Thanks!
Bastiaan.

void main()
{
import std.stdio;

WrapIntegerArray arr1;
arr1[0] = 42;

WrapIntegerArray arr2;

writeln(arr2[0]); // 42, not 0.
writeln("arr1.wrap.arr.ptr = ", arr1.wrap.arr.ptr);
writeln("arr2.wrap.arr.ptr = ", arr2.wrap.arr.ptr); // identical
assert(arr2[0] == 0); // fails
}

struct IntegerArray
{
int[] arr;
alias arr this;
this(int l)
{
arr = new int[l];
}
}

struct WrapIntegerArray
{
auto wrap = IntegerArray(5); // This is CTFE! :-(
alias wrap this;
}



Re: Saving and loading large data sets easily and efficiently

2019-10-03 Thread Bastiaan Veelo via Digitalmars-d-learn

On Monday, 30 September 2019 at 20:10:21 UTC, Brett wrote:
[...]
The way the data is structured is that I have a master array of 
non-ptr structs.


E.g.,

S[] Data;
S*[] OtherStuff;

then every pointer points to an element in to Data. I did not 
use int's as "pointers" for a specific non-relevant reason [...]


I would seriously consider turning that around and work with 
indices primarily, then take the address of an indexed element 
whenever you do need a pointer for that specific non-relevant 
reason. It makes I/O trivial, and it is safer too.


size_t[] OtherStuff;
size_t[int] MoreStuff;

Bastiaan.


Re: How to use #pragma omp parallel for collapse(n) in dlang?

2019-08-15 Thread Bastiaan Veelo via Digitalmars-d-learn

On Tuesday, 13 August 2019 at 08:41:07 UTC, ijet wrote:

How to use #pragma omp parallel for collapse(n) in dlang?


I don’t understand the question.

Bastiaan.


Re: 1 new

2019-08-03 Thread Bastiaan Veelo via Digitalmars-d-learn

On Friday, 2 August 2019 at 18:25:28 UTC, jmh530 wrote:
When I navigate to https://forum.dlang.org/ I have a message 
that says "1 new reply" to "your posts." Normally, I click on 
that "1 new reply" and find the post that's new, go to it, and 
the message disappears. However, it doesn't seem to go away 
anymore. I tried looking at many different old posts without 
luck. At one point it was up to "2 new replies," but I viewed 
that other post and it went back down to "1 new reply." Does 
anyone else have this?


I always have “2 new replies” on that page, no matter how often I 
take a look. The feature seems a bit broken to me.


Bastiaan.


Re: How to get name of my application (project)

2019-08-03 Thread Bastiaan Veelo via Digitalmars-d-learn

On Saturday, 3 August 2019 at 09:26:03 UTC, Andrey wrote:
Hello, how to get name of my application (project) that we 
write in dub.json? Is there any compile-time constant like 
__MODULE__?


The name of an application is not a compile time constant: you 
can rename the executable at any time. Like Rémy said, 
thisExePath.baseName will get you the name at run time.


Bastiaan.


Re: Help me decide D or C

2019-08-02 Thread Bastiaan Veelo via Digitalmars-d-learn

On Friday, 2 August 2019 at 13:45:17 UTC, Alexandre wrote:

On Friday, 2 August 2019 at 12:30:44 UTC, berni wrote:

On Wednesday, 31 July 2019 at 18:38:02 UTC, Alexandre wrote:

[...]


In my oppinion C should have been deprecated about 50 years 
ago and it's not worth while to learn it if you are not 
interested in the history of programming or you have to learn 
it, because you need to maintain software which is allready 
written in C. But that's my oppinion; others may have a 
different sight.


[...]


Could you elaborate more about C being a burden? I have read so 
many people saying C gives a great foundation and should be 
everyone's first language. Now I am confused.


One example is this recent post: 
https://forum.dlang.org/post/yjgkatpbkdyyksldg...@forum.dlang.org


“[...] recently all the problems I am having with D are because D 
is actually superior to C and some assumptions I still have 
because of C should be uninstalled from my brain.”


If you plan on ending up with D anyway, I think that learning C 
first is an unnecessary detour and can be counter productive in 
some ways. And if your objective is to have fun, I would 
recommend against C (except for a masochistic kind of fun).


Don’t take the detour, take the D tour! :-)

Bastiaan.


Re: Help me decide D or C

2019-08-02 Thread Bastiaan Veelo via Digitalmars-d-learn
On Thursday, 1 August 2019 at 20:02:08 UTC, Aurélien Plazzotta 
wrote:

[...]
But don't fool yourself, D is not for beginners. Ali Çehreli is 
a very skilled programmer, ergo, he can't reason like a 
new/starting programmer anymore, regardless of his patience and 
kindness.


I am sorry, but this is very strange reasoning. Would you 
recommend a book on programming written by someone who is not a 
skilled programmer himself in any language? I certainly would not.


Besides, the OP has already expressed his appreciation for Ali’s 
writing.


Bastiaan.



Re: 1 - 17 ms, 553 ╬╝s, and 1 hnsec

2019-05-17 Thread Bastiaan Veelo via Digitalmars-d-learn

On Friday, 17 May 2019 at 18:36:00 UTC, ag0aep6g wrote:
I'd suggest "17 ms, and 553.1µs" for a better default (1 hns is 
0.1 µs, right?). No weird "hnsecs", no false precision, still 
all the data that is there.


I was going to propose the same. Hns is weird.

Bastiaan.


Re: Windows / redirect STDERR to see assert messages

2019-05-14 Thread Bastiaan Veelo via Digitalmars-d-learn

On Sunday, 12 May 2019 at 13:39:15 UTC, Robert M. Münch wrote:

When developing Windows GUI applications I use:

 // detach from console and attach to a new one, works for 
x86 and x86_64

 FreeConsole();
 AllocConsole();

 freopen("CONIN$", "r", stdin);
 freopen("CONOUT$", "w", stdout);
 freopen("CONOUT$", "w", stderr);

so that the GUI app opens a console for writeln() output etc. I 
assumed this should work for assert() messages as well. But it 
seems it doesn't. If an assert fails, I don't see any output. 
Is assert using something else? What's wrong about this 
approach?


Are you sure the last call to freopen doesn't return NULL? You 
are opening the same file twice and I'm not sure that works. Test 
with `stderr.writeln("test")`.


Bastiaan.


Re: CTFE in imported static initializers

2019-05-14 Thread Bastiaan Veelo via Digitalmars-d-learn
On Monday, 13 May 2019 at 20:39:57 UTC, Steven Schveighoffer 
wrote:

Why? I can't even use it at compile time...

pragma(msg, moddata.length);


Is that a good test or "usable at compile time", though? Isn't 
pragma(msg) done at an earlier stage than CTFE? I think that was 
the argument for ctfeWriteln.


(We both know that I'm out of my league here, but anyway :))

Bastiaan.


Re: Compile time mapping

2019-05-12 Thread Bastiaan Veelo via Digitalmars-d-learn

On Sunday, 12 May 2019 at 18:47:20 UTC, Bogdan wrote:

On Sunday, 12 May 2019 at 17:53:56 UTC, Bastiaan Veelo wrote:
If I understand your question correctly, you have two enums of 
equal length, and you want to convert members across enums 
according to their position, right?


My question was very vague, sorry about that.

In my use case I'd like to map SDL2 keyboard scan codes to my 
own game input keyboard codes. The two enums would look 
something like this:


```
enum SDL_Scancode
{
SDL_SCANCODE_UNKNOWN = 0,
SDL_SCANCODE_A = 4,
SDL_SCANCODE_B = 5,
SDL_SCANCODE_C = 6,
SDL_SCANCODE_D = 7,
}

enum MY_Scancode
{
  KEY_A,
  KEY_B,
  KEY_C,
  KEY_D,
}
```

The two enums are not of equal length, so in the end I just 
decided to create an immutable array of type My_Scancode[] 
where the index is an SDL_Scancode and the value is the 
corresponding MY_Scancode enum member. I'm ok with using some 
memory for this, as long as it's as fast as possible.


If the only difference is the extra _UNKNOWN member, you can 
still use the static foreach approach. Just make it a 
non-template function and rip out the checks, and add a +1 in the 
right place.


Re: Compile time mapping

2019-05-12 Thread Bastiaan Veelo via Digitalmars-d-learn

On Sunday, 12 May 2019 at 17:53:56 UTC, Bastiaan Veelo wrote:

On Saturday, 11 May 2019 at 15:48:44 UTC, Bogdan wrote:
What would be the most straight-forward way of mapping the 
members of an enum to the members of another enum (one-to-one 
mapping) at compile time?


If I understand your question correctly, you have two enums of 
equal length, and you want to convert members across enums 
according to their position, right? You can do that with a 
little bit of template programming and static foreach. The 
following works irrespective of underlying value and type, the 
only requirement is that there are no duplicate values:


https://run.dlang.io/is/dNssel


There was an error in the error reporting. That should teach me 
to never copy+paste if you can static foreach :-) This one is 
better:


https://run.dlang.io/is/TVl9db


Re: Compile time mapping

2019-05-12 Thread Bastiaan Veelo via Digitalmars-d-learn

On Saturday, 11 May 2019 at 15:48:44 UTC, Bogdan wrote:
What would be the most straight-forward way of mapping the 
members of an enum to the members of another enum (one-to-one 
mapping) at compile time?


If I understand your question correctly, you have two enums of 
equal length, and you want to convert members across enums 
according to their position, right? You can do that with a little 
bit of template programming and static foreach. The following 
works irrespective of underlying value and type, the only 
requirement is that there are no duplicate values:


https://run.dlang.io/is/dNssel
```
void main()
{
enum FromEnum {F1 = 10, F2, F3}
enum ToEnum   {T1 = 20, T2, T3}
enum CharEnum : char {C1 = 'c', C2, C3}

static assert(to!ToEnum(FromEnum.F2) == ToEnum.T2);
static assert(to!ToEnum(FromEnum.F2) == 21);
static assert(to!CharEnum(FromEnum.F2) == CharEnum.C2);
static assert(to!CharEnum(FromEnum.F2) == 'd');
}

// Converts enumerations by position.
T to(T, F)(F f) if (is(F==enum) && is(T == enum))
{
import std.traits;
import std.meta;
static assert(NoDuplicates!(EnumMembers!F).length == 
EnumMembers!F.length,

  F.stringof ~ " has duplicates.");
static assert(NoDuplicates!(EnumMembers!T).length == 
EnumMembers!T.length,

  F.stringof ~ " has duplicates.");
static assert(EnumMembers!F.length == EnumMembers!T.length,
  F.stringof ~ " and " ~ T.stringof ~ " differ in 
length.");

static foreach(i, t; EnumMembers!T)
if (rank(f) == i)
return t;
assert(0, "Not an enum member");
}

// Returns i if e is the i-th enumerator of E.
static size_t rank(E)(E e) if (is(E == enum))
{
import std.traits;
static foreach (i, member; EnumMembers!E)
if (e == member)
return i;
assert(0, "Not an enum member");
}
```


Re: OT - Git training Lon/HK and book recommendation on taste in programming

2019-05-02 Thread Bastiaan Veelo via Digitalmars-d-learn

On Wednesday, 1 May 2019 at 09:51:01 UTC, Laeeth Isharc wrote:

Hi.

First question - can anyone recommend git / Gitlab training 
providers in HK and London?  Two distinct audiences - highly 
intelligent people that may or may not really program, and 
experienced developers with a finance background that could 
benefit from knowing how to use git properly (finance is often 
in the dark ages).


On the former we are even getting HR, legal and compliance to 
start to use git for documents.  So some handholding will be 
required.


I would like a combination of classroom, small group on-premise 
training and somebody being in the office a few hours a week to 
help show people.


No experience is necessarily required for the latter provided 
you know git well and can patiently explain things in a way 
less advanced people will understand.  It could even be a nice 
part-time job for a student and we could pay well.  Not that we 
wouldn't look at a professional either - I just mean that I am 
open minded.


I know this is not what you're asking for, but it may come in 
handy as supporting material: I just watched this introduction 
[1] to git using my favourite git GUI: SourceTree. The GUI has 
evolved a bit since the videos were made, but it takes the viewer 
through the basics at a pace that everybody should be able to 
follow. Sadly some planned videos in the series were never added.


Bastiaan.

[1] 
https://www.youtube.com/playlist?list=PLpL2ONl1hMLtlY1Y7YJNcA5zumvaITLYs


Re: Any full feature xml library available?

2019-05-02 Thread Bastiaan Veelo via Digitalmars-d-learn

On Thursday, 2 May 2019 at 15:50:53 UTC, rikki cattermole wrote:

On 03/05/2019 3:36 AM, Russel Winder wrote:
On Thu, 2019-05-02 at 02:11 +1200, rikki cattermole via 
Digitalmars-d-

learn wrote:
[…]


It does not. Those features come under the big bad guys 
feature list.


Gonna have to go to C for it.


Surely that means you can use Python, Rust, C++, or D rather 
than

having to descend to using C?

libxml2 is definitely usable from Python, it must be usable 
from D. Of

course, I am assuming libxml2 has the facilities required.


libxml2 is precisely what I meant.

We just don't have the libraries written in D at this point.


Apparently, bindings to libxml2 existed back in 2008. 
http://www.dsource.org/projects/bcd/


Bastiaan


Re: druntime giving wrong line for copy assert?

2019-04-30 Thread Bastiaan Veelo via Digitalmars-d-learn

On Tuesday, 30 April 2019 at 13:59:52 UTC, Rudy Raab wrote:
The error was on line 36, which is the format, not my bad 
slice. Is there a reason for this, or is it a bug


The message is correct when not using dub:
https://run.dlang.io/is/chFTOY

I suspect that if you remove the dub related lines and put it in 
an empty dub project, it will produce a correct message. So it 
looks like a bug in dub from where I am sitting. Maybe dub adds 
lines behind the scene?


Bastiaan.


Re: Does D have a tool like pySnooper?

2019-04-26 Thread Bastiaan Veelo via Digitalmars-d-learn

On Friday, 26 April 2019 at 16:59:15 UTC, H. S. Teoh wrote:
On Fri, Apr 26, 2019 at 02:33:16PM +, Taylor Hillegeist via 
Digitalmars-d-learn wrote:

On Friday, 26 April 2019 at 10:22:49 UTC, Bastiaan Veelo wrote:

[...]

> Proofing the concept:
> ---
> mixin(snoop(q{
> int fun(int a, int b)
> {
> int c = 3;
> foreach (i; 1 .. 5)
> {
> a += i;
> }
> int d = a + b + c;
> return d;
> }
> }));
> ---
> 
> Output:
> 2019-Apr-26 10:33:46.0935135 executed line 7:	int c 
> = 3;
> 2019-Apr-26 10:33:46.0936716 executed line 10:	a 
> += i;
> 2019-Apr-26 10:33:46.0937348 executed line 10:	a 
> += i;
> 2019-Apr-26 10:33:46.0937963 executed line 10:	a 
> += i;
> 2019-Apr-26 10:33:46.0938583 executed line 10:	a 
> += i;
> 2019-Apr-26 10:33:46.0939622 executed line 12:	int d 
> = a + b +

> c;


Now *this* is some seriously cool stuff.


Thanks!

A limitation is that snoop() needs to be pure. At one time I had 
a byLine in there, but for some reason byLine is not pure so that 
didn't work. I was almost about to see if I could use libdparse 
in it (run.dlang.io supports it) but I should spend my time on 
preparing for DConf instead... Feel free to play with it, this 
stuff is fun!


Bastiaan.


Re: Does D have a tool like pySnooper?

2019-04-26 Thread Bastiaan Veelo via Digitalmars-d-learn

On Friday, 26 April 2019 at 08:35:57 UTC, Bastiaan Veelo wrote:

On Thursday, 25 April 2019 at 08:44:14 UTC, Dennis wrote:
On Monday, 22 April 2019 at 16:24:53 UTC, Taylor Hillegeist 
wrote:

Or would this not be easy at all with D?


I don't think so. While there are lots of traits for 
introspection of declarations, there is no way to introspect 
lines of code. The whole function
would need to be wrapped into a mixin, and the D code would 
need to be parsed

at compile time for this to work.


Yes, but I think that might be doable. You wouldn't need a full 
blown D parser, just one that can identify statements (`;` 
being an important clue). Not sure whether __LINE__ will be 
meaningful inside a mixin, though, but that might also be 
fixable. It would be an interesting challenge.


Bastiaan.


Proofing the concept:
---
mixin(snoop(q{
int fun(int a, int b)
{
int c = 3;
foreach (i; 1 .. 5)
{
a += i;
}
int d = a + b + c;
return d;
}
}));
---

Output:
2019-Apr-26 10:33:46.0935135 executed line 7:   int c = 3;
2019-Apr-26 10:33:46.0936716 executed line 10:  a += i;
2019-Apr-26 10:33:46.0937348 executed line 10:  a += i;
2019-Apr-26 10:33:46.0937963 executed line 10:  a += i;
2019-Apr-26 10:33:46.0938583 executed line 10:  a += i;
2019-Apr-26 10:33:46.0939622 executed line 12:	int d = a 
+ b + c;


https://run.dlang.io/is/Go97hQ

Bastiaan.


Re: Does D have a tool like pySnooper?

2019-04-26 Thread Bastiaan Veelo via Digitalmars-d-learn

On Thursday, 25 April 2019 at 08:44:14 UTC, Dennis wrote:
On Monday, 22 April 2019 at 16:24:53 UTC, Taylor Hillegeist 
wrote:

Or would this not be easy at all with D?


I don't think so. While there are lots of traits for 
introspection of declarations, there is no way to introspect 
lines of code. The whole function
would need to be wrapped into a mixin, and the D code would 
need to be parsed

at compile time for this to work.


Yes, but I think that might be doable. You wouldn't need a full 
blown D parser, just one that can identify statements (`;` being 
an important clue). Not sure whether __LINE__ will be meaningful 
inside a mixin, though, but that might also be fixable. It would 
be an interesting challenge.


Bastiaan.


Re: Logging best practices

2019-04-26 Thread Bastiaan Veelo via Digitalmars-d-learn
On Thursday, 25 April 2019 at 10:33:00 UTC, Vladimirs Nordholm 
wrote:

Hello.

Is there a current "Best Practices" for logging in D?

For the actual logging, I know of `std.experimental.logger`. 
However, the `experimental` has kept me away from it.


Is it good, or are there any better alternatives?


Apart from an open issue I have, 
https://issues.dlang.org/show_bug.cgi?id=15536, I have used 
std.experimental.logger successfully here: 
https://github.com/PhilippeSigaud/Pegged/wiki/Grammar-Debugging


Bastiaan.


Re: Logging best practices

2019-04-26 Thread Bastiaan Veelo via Digitalmars-d-learn

On Thursday, 25 April 2019 at 15:51:43 UTC, dangbinghoo wrote:
On Thursday, 25 April 2019 at 10:33:00 UTC, Vladimirs Nordholm 
wrote:

Hello.

Is there a current "Best Practices" for logging in D?

For the actual logging, I know of `std.experimental.logger`. 
However, the `experimental` has kept me away from it.


Is it good, or are there any better alternatives?


for the latest alpha version of D release, all std.experimental 
has been already moved to std.


Are you sure about that? 
https://github.com/dlang/phobos/tree/master/std
I think you are confusing the package std.experimental.all that 
moved to std. It means you can now import all of Phobos by doing 
`import std;` instead of `import std.experimental.all;`. It does 
not mean that everything below std.experimental moved to std and 
thereby lost its experimental status.


Bastiaan.


Re: CTFE & code generators based on PEG grammars?

2019-04-06 Thread Bastiaan Veelo via Digitalmars-d-learn

On Saturday, 6 April 2019 at 12:06:22 UTC, Robert M. Münch wrote:
The idea is, that I can write a string (or maybe even a scope 
block?) in my DSL and use a CTFE grammer to transpile the code.


Are you aware of Pegged[1]? It’s for exactly that.

[1] http://code.dlang.org/packages/pegged


Re: Duplicate class/interface/struct completely

2019-03-26 Thread Bastiaan Veelo via Digitalmars-d-learn

On Tuesday, 26 March 2019 at 05:29:08 UTC, Michelle Long wrote:
The idea is to be able to make sure one can modify a class and 
drop it in for the original and it work in all cases. With 
alias this, it can fail unless we can alias it too.


This sounds like mocking, this answer might be of help: 
https://forum.dlang.org/post/gdfvbrknbnbfunycb...@forum.dlang.org


I don’t know the capabilities of these libraries, but you may 
want to have a look.


Bastiaan.


Re: Why this eponymous template does not compile?

2019-03-25 Thread Bastiaan Veelo via Digitalmars-d-learn

On Monday, 25 March 2019 at 09:27:03 UTC, Victor Porton wrote:
/tmp/temp_7F3C101460D0.d(9,5): Error: template instance 
`synchronizedMemoize!f` template `synchronizedMemoize` is not 
defined, did you mean sychronizedMemoize(alias fun)()?


Why the error?


Sometimes, template error messages are hard to get. But this one 
is pretty clear, to the point that it is difficult for a human to 
point out clearer. :o)




Re: Compile-time associative array

2019-03-20 Thread Bastiaan Veelo via Digitalmars-d-learn

On Wednesday, 20 March 2019 at 08:11:27 UTC, boolangery wrote:

Got it ! Thank you, so I need to write:

enum string[string] CtfeFoo = ["foo" : "bar"];
static immutable string[string] Foo;

static this()
{
Foo = CtfeFoo;
}

string ctfeableFunction()
{
if (__ctfe)
return CtfeFoo["foo"];
else
return Foo["foo"];
}

void main()
{
enum a = ctfeableFunction();
auto b = ctfeableFunction();
}


Yes, that looks correct to me.


Re: PyD - accessing D class fields in Python

2019-03-19 Thread Bastiaan Veelo via Digitalmars-d-learn

On Monday, 18 March 2019 at 22:25:10 UTC, clothlen wrote:

Howdy;

I'm trying to extend my Python program with D, but I'm having 
trouble accessing a D class's 
field/attribute/property/something.


My D file looks like this:

```
module simpletest;
import pyd.pyd;
import std.stdio;

class ExampleTest{
int _a = 3;
int a(){
return _a;
}
void a(int a){
this._a = a;
}
int b = 4;
}

extern(C) void PydMain() {
module_init();
wrap_class!(
ExampleTest,
Property!(ExampleTest.a),
Property!(ExampleTest.b)
// Member!("b")


Maybe you need `Member!(“b”, “rw”)`?


);
}


If that doesn’t work, maybe you find help by filing an issue on 
PyD.




Re: Compile-time associative array

2019-03-19 Thread Bastiaan Veelo via Digitalmars-d-learn

On Tuesday, 19 March 2019 at 08:50:15 UTC, boolangery wrote:

Hi,

I want to use a constant associative array in a ctfe-able 
function.


Example:

string ctfeableFunction()
{
return Foo["foo"];
}

Then I force ctfe with:

enum res = ctfeableFunction();

When I use an enum like:

enum Foo = ["foo" : "bar"];

It works fine.

D-Scanner keep saying to me: This enum may lead to unnecessary 
allocation at run-time. Use 'static immutable [...] instead'


But it lead to: Error: static variable Foo cannot be read at 
compile time.


So is the only way to make ctfe-able associative array is to 
use enum instead of static immutable ?


Yes, I think so. If you would use the enum AA multiple times, it 
would allocate a new AA each time, that is wat D-Scanner warns 
against. I am not sure how the CTFE interpreter is implemented, 
it could be that a new AA is allocated each time you call 
ctfeableFunction, at compile time. But unless you also call it at 
runtime, there should be no extra run time allocations.


If you need the AA at run time as well, I would create a static 
immutable version for that, initialised with the enum.


Beware that a CT AA stores its elements in a different order than 
a RT AA, which you would notice in a foreach, for example.


Re: why is ifThrown un@safe?

2019-03-15 Thread Bastiaan Veelo via Digitalmars-d-learn

On Friday, 15 March 2019 at 19:24:17 UTC, Bastiaan Veelo wrote:

Will do the filing and maybe experiment a bit.

Bastiaan.


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


Re: why is ifThrown un@safe?

2019-03-15 Thread Bastiaan Veelo via Digitalmars-d-learn

On Friday, 15 March 2019 at 19:19:41 UTC, H. S. Teoh wrote:
On Fri, Mar 15, 2019 at 06:46:25PM +, bauss via 
Digitalmars-d-learn wrote:

On Friday, 15 March 2019 at 18:04:05 UTC, Bastiaan Veelo wrote:
> In the code below (https://run.dlang.io/is/d0oTNi), ifThrown 
> is inferred as un@safe. If instead I write the 
> implementation of ifThrown out (after res2) then it is 
> @safe. As far as I can see, there is no real difference. So 
> why doesn't ifThrown work in this case, and can it be made 
> to work?

[...]

Because the handlers may be unsafe.

There is no safe overload of ifThrown.

However you can work around this using @trusted.


I wasn't satisfied with this answer, because in theory the 
@safe-ness of ifThrown ought to be inferred from the @safe-ness 
of its arguments, and ifThrown itself shouldn't do anything 
un-@safe. So I investigated a little further, and found that 
the problem lies in how ifThrown is declared:


	CommonType!(T1, T2) ifThrown(T1, T2)(lazy scope T1 expression, 
scope T2 delegate(Exception) errorHandler) { ... }


The problem is that the second parameter is declared to be a 
delegate with no further qualifications, which means it 
defaults to @system. Therefore, even if `expression` and 
`errorHandler` are both @safe, the compiler will still infer 
the call to `errorHandler` as @system, and therefore ifThrown 
will also be inferred as @system.


The obvious fix of adding @safe to the second parameter won't 
work, because that would preclude ifThrown from being used with 
@system error handlers.


So it appears to me that in order to make this work as it 
should, we need to templatize not only on the return type of 
the delegate, but on the delegate type itself.  Perhaps 
something along the lines of:


	CommonType!(T1, ErrorHandler) ifThrown(T1, T2)(lazy scope T1 
expression, scope ErrorHandler errorHandler)

if (... && is(ErrorHandler == delegate) &&
is(ReturnType!ErrorHandler : T1))
{
...
}

This should probably be filed as an enhancement request in 
bugzilla.



T


Excellent, thank you. Will do the filing and maybe experiment a 
bit.


Bastiaan.


Re: why is ifThrown un@safe?

2019-03-15 Thread Bastiaan Veelo via Digitalmars-d-learn

On Friday, 15 March 2019 at 18:46:25 UTC, bauss wrote:

On Friday, 15 March 2019 at 18:04:05 UTC, Bastiaan Veelo wrote:
In the code below (https://run.dlang.io/is/d0oTNi), ifThrown 
is inferred as un@safe. If instead I write the implementation 
of ifThrown out (after res2) then it is @safe. As far as I can 
see, there is no real difference. So why doesn't ifThrown work 
in this case, and can it be made to work?


Thanks!

void main() @safe
{
import std.process;
import std.exception;

 const res1 = execute(["clang", "-v", "-xc++", 
"/dev/null", "-fsyntax-only"], ["LANG": "C"])

.ifThrown((e) @safe {
import std.typecons : Tuple;
return Tuple!(int, "status", string, "output")(-1, 
e.msg);

}); // Fails

const res2 = () {
try
{
return execute(["clang", "-v", "-xc++", 
"/dev/null", "-fsyntax-only"], ["LANG": "C"]);

}
catch (Exception e)
{
import std.typecons : Tuple;
return Tuple!(int, "status", string, "output")(-1, 
e.msg);

}
}();
}


Because the handlers may be unsafe.


But this handler is explicitly marked @safe, and ifThrown is a 
template, which should infer its attributes, right?



There is no safe overload of ifThrown.


Could it be added?


However you can work around this using @trusted.


I know, but since everything really is safe, I'd rather not imply 
that it might not be. Besides, I failed to use @trusted without 
introducing a new scope, so I'd have to mark the whole block 
where `res1` is used as @trusted. Maybe I did that wrong though.




why is ifThrown un@safe?

2019-03-15 Thread Bastiaan Veelo via Digitalmars-d-learn
In the code below (https://run.dlang.io/is/d0oTNi), ifThrown is 
inferred as un@safe. If instead I write the implementation of 
ifThrown out (after res2) then it is @safe. As far as I can see, 
there is no real difference. So why doesn't ifThrown work in this 
case, and can it be made to work?


Thanks!

void main() @safe
{
import std.process;
import std.exception;

 const res1 = execute(["clang", "-v", "-xc++", "/dev/null", 
"-fsyntax-only"], ["LANG": "C"])

.ifThrown((e) @safe {
import std.typecons : Tuple;
return Tuple!(int, "status", string, "output")(-1, 
e.msg);

}); // Fails

const res2 = () {
try
{
return execute(["clang", "-v", "-xc++", "/dev/null", 
"-fsyntax-only"], ["LANG": "C"]);

}
catch (Exception e)
{
import std.typecons : Tuple;
return Tuple!(int, "status", string, "output")(-1, 
e.msg);

}
}();
}



Re: Phobos in BetterC

2019-03-09 Thread Bastiaan Veelo via Digitalmars-d-learn

On Friday, 8 March 2019 at 09:24:25 UTC, Vasyl Teliman wrote:
I've tried to use Mallocator in BetterC but it seems it's not 
available there:


https://run.dlang.io/is/pp3HDq

This produces a linker error.

I'm wondering why Mallocator is not available in this mode (it 
would be intuitive to assume that it's working). Also I would 
like to know what parts of Phobos are available there (e.g. 
std.traits, std.typecons...).


Thanks in advance.


I can’t answer that but you can use C’s malloc directly: 
https://run.dlang.io/is/fnRFIr


Bastiaan.


Re: How to call other variadic function with the same arguments?

2019-02-24 Thread Bastiaan Veelo via Digitalmars-d-learn

On Sunday, 24 February 2019 at 13:09:15 UTC, Victor Porton wrote:

Let f be a variadic function:

Result f(...);

How to implement variadic function g which calls f with the 
same arguments as one it receives?


Result g(...) {
  // ...
}


I don’t know if you can, but if at least g is a variadic template 
function, you can:

https://run.dlang.io/is/fhxZuV

Bastiaan.


Re: Odd behavior of darray.dup

2019-02-24 Thread Bastiaan Veelo via Digitalmars-d-learn

On Sunday, 24 February 2019 at 12:10:22 UTC, Bastiaan Veelo wrote:
1) You get "immutable(Color)(#{overlap raw, colors})" on 
immutable Color because the `Color.toString()` method is not 
const (corrected in the Gist). This is a bug in 
pixelperfectengine. Likewise, getters like `green()` should be 
const.


Reported. 
https://github.com/ZILtoid1991/pixelperfectengine/issues/8


Re: Odd behavior of darray.dup

2019-02-24 Thread Bastiaan Veelo via Digitalmars-d-learn
On Saturday, 23 February 2019 at 23:35:14 UTC, solidstate1991 
wrote:
On Saturday, 23 February 2019 at 19:21:10 UTC, Bastiaan Veelo 
wrote:


It works for me:
https://run.dlang.io/gist/473b0021487275751accaebeb00be05c

-- Bastiaan


Still no luck, not even with memcpy.

There's even more mystery as I printed out the original static 
immutable array's content, which is different from the 
non-immutable one. Instead of the 32bit hex value of the given 
color in the format of "0x", I get 
"immutable(Color)(#{overlap raw, colors})". This might be a bug.


Sorry, I didn't realize that my link didn't work (due to issue 
https://github.com/dlang-tour/core/issues/714).


I have instead exported a Gist 
https://gist.github.com/run-dlang/965a2fb793bda7b1a82b0512d78973f3 that you should be able to use with the "Import Gist" button on https://run.dlang.io/. I have included the relevant bits from pixelperfectengine (slightly modified, see below). If you have further questions, you can do the same so it will be easier to see what is going on.


Several things here:

1) You get "immutable(Color)(#{overlap raw, colors})" on 
immutable Color because the `Color.toString()` method is not 
const (corrected in the Gist). This is a bug in 
pixelperfectengine. Likewise, getters like `green()` should be 
const.


2) Also note that `intToHex()` could simply be implemented using 
std.format, as row 127 illustrates.


3) You get all zeros because static data needs a static module 
constructor, added on line 111.


4) As an alternative to static data you could use compile time 
data (line 118) which does not need a constructor nor `.dup`. 
Beware that each time you use it though, its value gets 
copy-pasted into the code like a C #define.


Hope this helps,
Bastiaan.


Re: Odd behavior of darray.dup

2019-02-23 Thread Bastiaan Veelo via Digitalmars-d-learn

On Friday, 22 February 2019 at 11:36:35 UTC, solidstate1991 wrote:
If I want to copy an array of structs with .dup (cannot post 
the link in question here at the moment due to non-working 
clipboard, it's Color from pixelperfectengine.graphics.common) 
I get all zeroes instead of the values from the original array. 
I haven't disabled post-blit to my knowledge.


Is it some kind of a bug, or the .dup function has some 
behavior that's not currently documented on the site (such as 
needing a copy constructor)?


It works for me:
https://run.dlang.io/gist/473b0021487275751accaebeb00be05c

-- Bastiaan


Re: Generalizing over function pointers and delegates

2019-02-15 Thread Bastiaan Veelo via Digitalmars-d-learn

On Friday, 15 February 2019 at 17:28:45 UTC, H. S. Teoh wrote:
On Fri, Feb 15, 2019 at 05:40:39PM +0100, ag0aep6g via 
Digitalmars-d-learn wrote:

Your fun_to_dlg fails when the function has parameters.


Yes. Delegates are basically syntactic sugar for a function 
pointer with an implicit first parameter. I.e., a delegate like:


int delegate(string) dg;

is under the hood implemented as the equivalent of:

struct _delegate {
int function(T* context, string) funcptr;
T* context;
int opCall(string s) { return funcptr(context, s); }
}

where T is an appropriate context type, whether an aggregate 
(struct / class) or an anonymous struct that closes over 
whatever variables the delegate accesses in its containing 
scope.


For this reason, casting a function pointer to a delegate will 
not work properly, because the first arguments and number of 
parameters would not match.



T


I love this forum!


Re: Generalizing over function pointers and delegates

2019-02-15 Thread Bastiaan Veelo via Digitalmars-d-learn

On Friday, 15 February 2019 at 16:40:39 UTC, ag0aep6g wrote:

Your fun_to_dlg fails when the function has parameters.


Hah ok. std.functional.toDelegate() does work in its place though.

As far as I see, it would be possible make the conversion would 
work by changing how a delegate's context is passed [1]. But I 
didn't pursue that idea further, and no one else picked it up 
either.


[1] https://forum.dlang.org/post/ofc0lj$2u4h$1...@digitalmars.com


Interesting. Thanks for the link.


Re: Generalizing over function pointers and delegates

2019-02-15 Thread Bastiaan Veelo via Digitalmars-d-learn

On Friday, 15 February 2019 at 14:30:45 UTC, Alex wrote:


There is
https://dlang.org/library/std/functional/to_delegate.html


Ah, there it is :-) Thanks.

A templated function also works.

```
int genfun(F)(F dg) {return dg();}
​
int top_level() {return -1;}
​
void main()
{
int nested() {return -2;}
assert(genfun(_level) == -1);
assert(genfun() == -2);
}
​```


Generalizing over function pointers and delegates

2019-02-15 Thread Bastiaan Veelo via Digitalmars-d-learn

Given a function taking a delegate, for example

```
int fun(int delegate() dg) {return dg();}
```

Sometimes we need to call `fun` with a pointer to a nested 
function and other times with a pointer to a top level function. 
As function pointers do not implicitly convert to delegates, this 
does not work without jumping through hoops.


One option is to define an overload:

```
int fun(int function() fn)
{
int nested_fn()
{
return fn();
}
return fun(_fn);
}
```

This is clunky and rather a lot of extra lines to work around a 
language limitation. The limitation seems somewhat artificial, 
because a delegate /can/ be initialized referencing a top level 
function (the spec [1] limits that to delegate declarations at 
module scope, but this limit does not seem to apply [2]). But you 
cannot /assign/ it a top level function. You can however 
explicitly assign the `.funcptr` referencing the top level 
function, leaving the stack frame pointer null.


Exploiting this, it is possible to explicitly convert a function 
pointer into a delegate [2]:

```
Ret delegate(Args args) fun_to_dlg(Ret, Args...)(Ret 
function(Args args) fun)

{
Ret delegate(Args) dlg;
dlg.funcptr = fun;
return dlg;
}
```

allowing
```
int top_level() {return -1;}
void main()
{
assert(fun(fun_to_dlg(_level)) == -1);
}
```

This may be preferable to the overload, depending on the number 
of calls like this. But since this is allowed and working, why 
can't it be done automatically? Or, when implicit conversion is 
dangerous, why doesn't a cast exist to the effect of my template? 
Have I overlooked an easier way of doing this?


Thanks for any input!
Bastiaan.

P.S. For the record, the spec also says this: "Future directions: 
Function pointers and delegates may merge into a common syntax 
and be interchangeable with each other." I wish that was the case 
already.


[1] Point 9 in https://dlang.org/spec/function.html#closures
[2] https://run.dlang.io/is/x8HJaW


Re: Determination of thread status.

2018-12-26 Thread Bastiaan Veelo via Digitalmars-d-learn

On Wednesday, 26 December 2018 at 05:43:47 UTC, Vitaly wrote:
On Tuesday, 25 December 2018 at 17:08:00 UTC, Neia Neutuladh 
wrote:

1. Find the Thread object:
  Tid threadId = spawn();
  auto thread = Thread.getAll.filter!(x => x.id == 
threadId).front;

2. Check the `isRunning` property.

The indirection with spawn() is awkward.


Thanks for the answer.
I checked.
Thread.getAll [x] .id is of type ulong, and spawn is of type 
Tid, moreover, they do not intersect in value either. But even 
if the program spawns a single thread, Thread.getAll [x] 
.isRunning returns true after the function terminates. Perhaps 
you need to wait some time.
You may have to send a message before exiting the function. 
Just look at the possibilities of std.parallelism.
I will gladly try other solutions. I would be grateful for your 
suggestions.


Maybe use spawnLinked()? https://run.dlang.io/is/9xbyAF


Re: Determination of thread status.

2018-12-25 Thread Bastiaan Veelo via Digitalmars-d-learn

On Tuesday, 25 December 2018 at 14:44:43 UTC, Vitaly wrote:

Hi all.
I can not understand how to track me that the thread has 
finished work.

eg:

import std.concurrency;
void myThread ()
{
// Do the work
}

void main ()
{
Tid thread = spawn (& myThread);
// It is necessary to check whether the thread has finished its 
work or is active.

}

Could you tell me how to do this?


std.concurrency is a low-level API. You may be looking for a 
higher level API: std.parallelism. See Task.done(), 
https://dlang.org/phobos/std_parallelism.html#.Task.done


Bastiaan.


Re: CT BitArray

2018-11-01 Thread Bastiaan Veelo via Digitalmars-d-learn

On Thursday, 1 November 2018 at 00:01:04 UTC, Stefan Koch wrote:

Tell me which version are you using and I'll make it for you.


By the way this is a really generous offer, thanks for being like 
that!


Re: CT BitArray

2018-11-01 Thread Bastiaan Veelo via Digitalmars-d-learn

On Thursday, 1 November 2018 at 00:01:04 UTC, Stefan Koch wrote:
On Wednesday, 31 October 2018 at 23:14:08 UTC, Bastiaan Veelo 
wrote:
Currently, BitArray is not usable at compile time, so you 
cannot do

```
enum e = BitArray([1, 1, 1, 0]);
```
This gives
/dlang/dmd/linux/bin64/../../src/phobos/std/bitmanip.d(1190): 
Error: `bts` cannot be interpreted at compile time, because 
it has no available source code


IIUC, that is because `bts` comes from core.bitop but no 
source code is there. I am guessing these are filled in by 
compiler intrinsics or the like, and they are unavailable at 
CT, correct?


I suppose that alternative implementations of `btc`, `bts`, 
`btr`, `bsf` and `bt` could exist that do not use the runtime 
that could be used if(__ctfe) in the implementation of 
BitArray, that would make the above code work. Is this 
feasible? Is there precedent in phobos? Are there 
complications?


Thanks!


Oh that ... actually I can fix that with a small patch to dmd.

Tell me which version are you using and I'll make it for you.

Cheers,

Stefan


Thank you, Stefan. At the moment we are using latest stable dmd, 
v2.082.1. I expect to switch to ldc or gdc at a later time. I 
don't think we'll be patching the compiler, support in the 
mainline compilers would be much preferable. It is not a blocker 
either, we can wait as long as it takes and meanwhile use module 
level BitArrays like

```
immutable BitArray e;
static this()
{
e = BitArray([1, 1, 1, 0]);
}
```

It just seemed like a fixable limitation to me, hence my question 
here. Shall we start with a feature request?


Bastiaan.


CT BitArray

2018-10-31 Thread Bastiaan Veelo via Digitalmars-d-learn
Currently, BitArray is not usable at compile time, so you cannot 
do

```
enum e = BitArray([1, 1, 1, 0]);
```
This gives
/dlang/dmd/linux/bin64/../../src/phobos/std/bitmanip.d(1190): 
Error: `bts` cannot be interpreted at compile time, because it 
has no available source code


IIUC, that is because `bts` comes from core.bitop but no source 
code is there. I am guessing these are filled in by compiler 
intrinsics or the like, and they are unavailable at CT, correct?


I suppose that alternative implementations of `btc`, `bts`, 
`btr`, `bsf` and `bt` could exist that do not use the runtime 
that could be used if(__ctfe) in the implementation of BitArray, 
that would make the above code work. Is this feasible? Is there 
precedent in phobos? Are there complications?


Thanks!



Re: Dub project has both .sdl and .json files. Is this normal or did I do something wrong?

2018-08-05 Thread Bastiaan Veelo via Digitalmars-d-learn

On Saturday, 4 August 2018 at 17:53:45 UTC, Neia Neutuladh wrote:

On Friday, 3 August 2018 at 19:41:32 UTC, Bastiaan Veelo wrote:
But if you commit it, and a compiler deprecation causes a 
dependency in that pinned version to fail to compile, then 
your app won't compile either, even though your code itself 
does not suffer from the deprecation and even though a newer 
release of the dependency is available that solves the 
deprecations. This means that, if your app is on 
code.dlang.org, people won't be able to dub fetch && dub run.


This is also true if the dependency gets a major version bump 
and then gets updated for a breaking compiler change.


If the dependency range is broad enough, you can `dub upgrade 
&& dub run`.


You mean the dependency range in dub.selections.json of an app on 
code.dlang.org? I would be in favour of it being a range, but I 
think that is unusual. Usually people just commit the generated 
file unedited, which seems to always be pinned to the patch level?


Anyway, dub documentation could be a lot more verbose on 
dub.selections.json :-)


What advantages does committing dub.selections.json have that 
outweigh this disadvantage?


Dependencies don't always follow semantic versioning. For 
instance, a binding for a C library that is actively developed 
might reasonably follow the bound library's versioning. Or the 
maintainer might make a mistake and commit a breaking change 
without bumping to a new major version.


This is why my top-level projects these days have specific 
versions of dependencies rather than the more commonly used 
ranges. I'm only going to test against those specific versions, 
so why should I claim that my application can use future 
versions?


I know that failing to build is better than potential erroneous 
execution, so I understand the rationale. It’s just that I get 
build failures after updating to the newest compiler often enough 
that it's frustrating. Build failures in tools that I use in my 
build that is, like dfmt, ddox, scod.


It would be OK if dub.selections.json would also pin the 
compiler version and there were a standard way to select that 
version (like dvm, but without its shortcomings).


That would be good. If I were less lazy, I could add that to 
dub. It already manages packages; the compiler is just a 
slightly different dependency.


Apart from solving this problem, there are other advantages:
1. It would make it possible to check out an older version of 
your software and compile it without problems, and be sure that 
it results in the same binary as when that version was committed.
2. You can easily work with different compilers in different 
branches. Like using ldc in the release branch of your CI and dmd 
in your feature branch, or work on porting to a different 
compiler outside the master branch.


But since dub is distributed with the compiler, handling the 
compiler as a dependency might not be straightforward. How would 
you prevent getting trapped in an old version when dub downgrades 
itself? Which of the installed dub versions du you use to do dub 
upgrade? How would dub appear in dub.selections.json?


If you have ideas on this, I am genuinely interested.

-Bastiaan


Re: Dub project has both .sdl and .json files. Is this normal or did I do something wrong?

2018-08-03 Thread Bastiaan Veelo via Digitalmars-d-learn
On Tuesday, 19 December 2017 at 10:15:18 UTC, Jacob Carlborg 
wrote:

On 2017-12-18 23:36, WhatMeWorry wrote:

[...]


But when I look the directory that has the dub.sdl file, I 
also see a file called dub.selections.json


{
 "fileVersion": 1,
 "versions": {
     "derelict-al": "1.0.3",
     "derelict-assimp3": "1.3.0",
     "derelict-fi": "2.0.3",
     "derelict-fmod": "2.0.4",
     "derelict-ft": "1.1.3",
     "derelict-gl3": "1.0.23",
     "derelict-glfw3": "3.1.3",
     "derelict-util": "2.0.6",
     "gl3n": "1.3.1"
 }
}


So how did this .json file get created and can I just delete 
it?
You should keep it. If you have developed an application it 
should be committed to git, if it's a library it should not be 
committed.


But if you commit it, and a compiler deprecation causes a 
dependency in that pinned version to fail to compile, then your 
app won't compile either, even though your code itself does not 
suffer from the deprecation and even though a newer release of 
the dependency is available that solves the deprecations. This 
means that, if your app is on code.dlang.org, people won't be 
able to dub fetch && dub run.


What advantages does committing dub.selections.json have that 
outweigh this disadvantage?


It would be OK if dub.selections.json would also pin the compiler 
version and there were a standard way to select that version 
(like dvm, but without its shortcomings).


For example, scod 0.4.4 does not compile with dmd 2.081.1 because 
of this (https://github.com/MartinNowak/scod/issues/14). Its 
latest change to dub.selections.json is only three months old, to 
make it work with dmd 2.080.0. This illustrates that if you're 
unlucky, you may have to bring out frequent new releases with 
updates to dub.selections.json (through "dub upgrade") even 
though your app is stable and doesn't change.


Re: Newbie: out-of-source builds with "dub"?

2018-07-30 Thread Bastiaan Veelo via Digitalmars-d-learn

On Monday, 30 July 2018 at 01:50:23 UTC, CC wrote:
[...]

My usual modus operandi is:
1. check out the project into some directory "foo".
2. create another directory "foo.build", somewhere outside of 
"foo".

3. "cd foo.build"
4. Run some configuration script/file located in "foo", to 
generate "foo.build/Makefile".

5. Run "make".

I've started playing with "dub", and it *seems* to assume that 
you want the files generated during the build process to reside 
directly inside your checked-out source tree.


Is that true?  And if so, am I fighting dub's design by 
attempting out-of-source builds?


I haven’t tried it, but from the docs it seems that 
“--temp-build” does an out-of-source build, although it’s not 
exactly like your modus operandi.




Re: UCFS does not work for nested functions?

2018-06-18 Thread Bastiaan Veelo via Digitalmars-d-learn
On Monday, 18 June 2018 at 19:31:39 UTC, Steven Schveighoffer 
wrote:
In other words, if UFCS meant that module-level symbols took 
precedent over local symbols, then it's backwards in terms of 
which place usually wins. Generally it's the local symbols.


Ah, you mean it would have to be that way to prevent breakage. No 
I would not want it that way.


[...]


But one thing I will note, is that this is valid today:

void bar(int) {writeln("module");}

void main() {
 static void bar(int) {writeln("local");}
 int x;
 x.bar; // "module"
}

Adding UFCS support to locals, which one would be the expected 
call? It's difficult to imagine the local being the lower 
priority, but it would have to be that way to avoid code 
breakage.


Thanks, that clarifies it. No turtles for UFCS.





Re: UCFS does not work for nested functions?

2018-06-18 Thread Bastiaan Veelo via Digitalmars-d-learn
On Monday, 18 June 2018 at 17:58:11 UTC, Steven Schveighoffer 
wrote:

On 6/18/18 1:25 PM, bauss wrote:

On Monday, 18 June 2018 at 17:16:29 UTC, aliak wrote:
On Monday, 18 June 2018 at 14:19:30 UTC, Steven Schveighoffer 
wrote:

On 6/18/18 7:16 AM, Bastiaan Veelo wrote:

On Sunday, 18 May 2014 at 08:15:08 UTC, Steffen Wenz wrote:

Hi,

Just noticed that using UFCS does not work for nested 
functions, and was wondering whether that's intended, and 
what the rationale behind it is:


I just had the same question.

I can imagine that the context pointer of nested functions 
complicates things, but making `bar` `static` does not 
help. Has anything changed in recent years regarding the 
difficulty of implementing UFCS for nested functions? Would 
it be easier to only support static nested functions?


```
void main() {
 static void bar(int x) {}

 int x;
 x.bar(); // Error: no property 'bar' for type 'int'
}
```


It's never been supported, and likely will not be. I think 
the idea is that you can override expected behavior inside 
by accidentally defining some function locally with the same 
name.




Wondering how this is different than with non-nested 
functions? If a global function has the same name as a member 
function then the member function takes precedence. So 
wouldn't the same thing just apply here if it were supported?




I second this.


What then can happen is that your local calls can get hijacked 
from outside the module, if someone happens to define something 
later that you happened to import. D tries to avoid such 
possibilities.


There's not much precedent for local symbols being overridden 
by module-level symbols.


-Steve


I don't understand. What local symbol would be overwritten by 
which module-level symbol?


Whatever the concerns, what is the difference regarding these 
concerns between this:

```
// Valid today
void bar(int) {}
void main() {
int x;
b.bar;
}
```
and this:
```
\\ Invalid today
void main() {
static void bar(int) {}
int x;
x.bar;
}
```


Re: UCFS does not work for nested functions?

2018-06-18 Thread Bastiaan Veelo via Digitalmars-d-learn

On Sunday, 18 May 2014 at 08:15:08 UTC, Steffen Wenz wrote:

Hi,

Just noticed that using UFCS does not work for nested 
functions, and was wondering whether that's intended, and what 
the rationale behind it is:


I just had the same question.

I can imagine that the context pointer of nested functions 
complicates things, but making `bar` `static` does not help. Has 
anything changed in recent years regarding the difficulty of 
implementing UFCS for nested functions? Would it be easier to 
only support static nested functions?


```
void main() {
static void bar(int x) {}

int x;
x.bar(); // Error: no property 'bar' for type 'int'
}
```


File.put()

2018-06-08 Thread Bastiaan Veelo via Digitalmars-d-learn
Writing a single value to binary file can be done in (at least) 
two ways. Let `f` be a `File`:


```
f.rawWrite(()[0 .. 1]);
```

or

```
f.lockingBinaryWriter.put(value);
```

The former way is little talked about, the latter is not even 
documented. As far as I can see, the latter resolves to the 
former [1] if we disregard locking, mode switching and keeping a 
reference count (on Windows).


Shouldn't there be a `File.put()` method for the case where you 
already know that the file is locked and in the right mode? The 
trick to convert a single value to a range so it can be feeded to 
`rawWrite` may not be obvious to everyone.


Or have I just overlooked the obvious way for writing single 
values?


[1] 
https://github.com/dlang/phobos/blob/v2.080.1/std/stdio.d#L3102




Re: Line endings when redirecting output to file on windows.

2018-06-05 Thread Bastiaan Veelo via Digitalmars-d-learn
On Monday, 4 June 2018 at 15:31:04 UTC, Steven Schveighoffer 
wrote:
Windows C library has this bizarro mode for FILE * called 
"text" mode, which is the default. In this mode, it scans all 
output, and anywhere it sees a '\n', it replaces it with "\r\n".


Thanks, Steven.


Re: Line endings when redirecting output to file on windows.

2018-06-03 Thread Bastiaan Veelo via Digitalmars-d-learn

On Sunday, 3 June 2018 at 15:42:48 UTC, rikki cattermole wrote:

On 04/06/2018 3:24 AM, Bastiaan Veelo wrote:
I need some help understanding where extra '\r' come from when 
output is redirected to file on Windows.


First, this works correctly:
  rdmd --eval="(\"hello\" ~ newline).toFile(\"out.txt\");"
As expected, out.txt contains "hello\r\n".

I would expect the following to do the same, but it doesn't:
  rdmd --eval="write(\"hello\" ~ newline);" > out.txt
Now out.txt contains "hello\r\r\n".

Who is doing the extra conversion here, and how do I stop it?

Thanks!
Bastiaan.


That would be cmd. Not sure you can stop it without piping it 
after rdmd to remove the \r.


Thanks. It is starting to dawn on me that I shouldn't use 
`newline` and `toFile` to write text files, but rather always use 
"\n" as line ending and use `write` for both writing to stdout 
and file.

 rdmd --eval="File(\"out.txt\", \"w\").write(\"hello\n\");"
and
 rdmd --eval="write(\"hello\n\");" > out.txt
both produce "hello\r\n" on Windows.

Am I correct, or is there a more idiomatic way of writing strings 
to text files?




Line endings when redirecting output to file on windows.

2018-06-03 Thread Bastiaan Veelo via Digitalmars-d-learn
I need some help understanding where extra '\r' come from when 
output is redirected to file on Windows.


First, this works correctly:
 rdmd --eval="(\"hello\" ~ newline).toFile(\"out.txt\");"
As expected, out.txt contains "hello\r\n".

I would expect the following to do the same, but it doesn't:
 rdmd --eval="write(\"hello\" ~ newline);" > out.txt
Now out.txt contains "hello\r\r\n".

Who is doing the extra conversion here, and how do I stop it?

Thanks!
Bastiaan.


Re: Template instantiation fails on Linux, succeeds on Windows

2018-05-17 Thread Bastiaan Veelo via Digitalmars-d-learn

On Thursday, 17 May 2018 at 23:18:32 UTC, Basile B. wrote:

On Thursday, 17 May 2018 at 22:07:46 UTC, Bastiaan Veelo wrote:

Hi!

The code in [1] compiles and runs flawlessly on Windows, but 
not on Linux (neither run.dlang nor Travis docker image). Any 
idea what can be done?


Hello. Yes, add `import core.stdc.stdarg;` in your module and 
it works.

I don't know why it's not required on windows, this is strange.


Great! Thanks a lot, Basile!

Seems there is room for improvement somewhere, a better error 
message at the least.


Template instantiation fails on Linux, succeeds on Windows

2018-05-17 Thread Bastiaan Veelo via Digitalmars-d-learn

Hi!

The code in [1] compiles and runs flawlessly on Windows, but not 
on Linux (neither run.dlang nor Travis docker image). Any idea 
what can be done?


errors:
Error: undefined identifier __va_list_tag
onlineapp.d(282): Error: template instance 
`onlineapp.SetFactory!byte` error instantiating

Error: undefined identifier __va_list_tag
onlineapp.d(288): Error: template instance 
`onlineapp.SetFactory!(Count)` error instantiating

Error: undefined identifier __va_list_tag
onlineapp.d(290): Error: template instance 
`onlineapp.SetFactory!char` error instantiating


SetFactory is defined on row 233, and it seems that the problem 
relates to the vararg opIndex.


[1] https://run.dlang.io/gist/6dcbe4e82846cbeb3bf478e92a2b6e6f


Re: How to inform dub of generated source files?

2018-05-17 Thread Bastiaan Veelo via Digitalmars-d-learn

On Thursday, 17 May 2018 at 17:42:21 UTC, Bastiaan Veelo wrote:

Isn't preGenerateCommands meant to cover this case?


Appears to be a bug. Filed 
https://github.com/dlang/dub/issues/1474


How to inform dub of generated source files?

2018-05-17 Thread Bastiaan Veelo via Digitalmars-d-learn

Hi,

Context: https://github.com/veelo/Pascal2D

One of my source files is generated by executing `cd source && 
rdmd generate.d`, which creates the file `source/epparser.d`. 
(There is actually one step in between, calling `rdmd make.d`, 
which checks creation times, but that's not relevant here).


I have added this step as preGenerateCommands in dub.json [1].

The problem is that the first time `dub build` is run, it does 
not seem to be aware of `source/epparser.d` and linking fails 
[2]. A second `dub build` succeeds.


Isn't preGenerateCommands meant to cover this case?

I can add `epparser.d` in an extra soureFile line in dub.json, 
which fixes the very first build, but that makes successive 
builds fail because it causes the file name to appear twice in 
the arguments to dmd once the file exists.


Changing preGenerateCommands into preBuildCommands makes no 
difference.



Thanks!
Bastiaan.

[1] https://github.com/veelo/Pascal2D/blob/master/dub.json#L22
[2] https://travis-ci.org/veelo/Pascal2D/builds/379096446#L511


Re: Shouldn't D be added to this list?

2018-02-07 Thread Bastiaan Veelo via Digitalmars-d-learn

On Tuesday, 6 February 2018 at 22:36:09 UTC, WhatMeWorry wrote:

https://www.khronos.org/opengl/wiki/Language_bindings

I was thinking that with derelictGL, D should be on this list?

If so, I'm not sure how one would go about this?


It is a wiki, anybody can add it, me thinks.


Re: BitArray shift left/right confusion.

2018-02-03 Thread Bastiaan Veelo via Digitalmars-d-learn

On Friday, 2 February 2018 at 00:33:03 UTC, Jakub Łabaj wrote:
On the other hand, shifting operators are equally confusing for 
me, as they are for you - they really work in the other way 
around! I thought this is a very weird bug, but I found this 
pull request: https://github.com/dlang/phobos/pull/2844, which 
states this is the intended behaviour.


I don't know if there is anybody that would expect this - it's 
inconsistent with any other bitset implementation I know from 
other languages, as well as with what logic suggests. I'm 
curious if the authors changed their minds in this regard and 
there is any chance for that to be rewritten?


The same confusion existed amongst the authos, that pull was done 
in reaction to 
https://github.com/dlang/phobos/pull/2797#discussion-diff-22456052.


So the shift direction seems to be as intended (by Martin Nowak 
at least) but the docs should be clear in what order the bits are 
printed and indexed. I guess.


Re: `Alias this` to a mixed in property

2018-01-24 Thread Bastiaan Veelo via Digitalmars-d-learn

On Wednesday, 24 January 2018 at 14:21:42 UTC, ag0aep6g wrote:
The spec says that you cannot make an overload set just by 
mixing in multiple functions/methods with the same name. 
Instead, you have to do it like this:



mixin getter g;
mixin setter!int s;

alias p = g.p;
alias p = s.p;


https://dlang.org/spec/template-mixin.html#mixin_scope


Thanks a lot! I didn't know you could do overloads by way of 
multiple aliases with the same name.


I meant to use this for mixing in multiple instantiations 
generated from a static foreach over an AliasSeq of types, but 
generating unique identifiers poses an extra challenge.


I may go for string mixin's instead, which I just discovered do 
work:


```
import std.stdio;

enum getter = `
@property int p()
{
writeln(__LINE__, " mixin getter");
return 3;
}
`;
string setter(string T) pure
{ return `
@property int p(` ~ T ~ ` arg)
{
writeln(__LINE__, " mixin setter ` ~ T ~ `" ,  arg);
return 4;
}
`;
}
struct S
{
mixin(getter);
mixin(setter("int"));
alias p this;
}

void main(string[] args)
{
S s;
s = 7;
int i = s;
}
```


`Alias this` to a mixed in property

2018-01-24 Thread Bastiaan Veelo via Digitalmars-d-learn

Hi,

`Alias this` to mixed in properties does not seem to work, see 
below. If you think it should, I'll file an issue. Otherwise: can 
this be made to work somehow?


Interestingly, if you uncomment either the mixin getter or setter 
(row 36 or 37) and its corresponding use in `main`, then the 
remaining property works. Does the compiler detect identical 
names and then does some additional mangling which messes with my 
`alias this` maybe?


```
import std.stdio;

// version = manual; // Manually written property works, 
obviously.


mixin template getter()
{
@property int p()
{
writeln(__LINE__, " mixin getter");
return 3;
}
}
mixin template setter(T)
{
@property int p(T arg)
{
writeln(__LINE__, " mixin setter ", typeid(T), ' ',  arg);
return 4;
}
}
struct S
{
version (manual) {
@property int p()
{
writeln(__LINE__, " manual getter");
return 3;
}
@property int p(int arg)
{
writeln(__LINE__, " manual setter int ",  arg);
return 4;
}
}
else {
mixin getter;// row 36
mixin setter!int;// row 37
}
alias p this;
}


void main(string[] args)
{
S s;
s = 7;
int i = s;
}
```

Error: cannot implicitly convert expression s of type S to int.


Re: Finding ElementType

2018-01-07 Thread Bastiaan Veelo via Digitalmars-d-learn

On Sunday, 7 January 2018 at 13:50:23 UTC, Adam D. Ruppe wrote:

On Sunday, 7 January 2018 at 12:40:22 UTC, Bastiaan Veelo wrote:
1) Should we have a reference in the docs for std.traits to 
std.range.primitive : ElementType?


wouldn't hurt i guess

2) Should phobos contain a version without the special narrow 
string behavior?


see ElementEncodingType
http://dpldocs.info/experimental-docs/std.range.primitives.ElementEncodingType.html

3) Are there other differences between my version and the 
phobos version?


The Phobos one works on any range, not just built-in arrays. It 
also returns an answer (void) if you pass it something that has 
no element type, whereas yours would be a compile error.


Thanks.


Finding ElementType

2018-01-07 Thread Bastiaan Veelo via Digitalmars-d-learn
The learn forum is great not only for asking questions, but also 
for learning from the questions by others: I just learned about 
the existence of std.range.primitives: ElementType, a function 
that I have looked for in phobos before, without finding it. I 
had expected this to be in std.traits or __traits.


So I implemented my own:
```
template arrayElementType(T : T[])
{
alias arrayElementType = T;
}

unittest
{
static assert (is(arrayElementType!(int[]) == int));
}
```

For reference, this is the phobos version:
```
template ElementType(R)
{
static if (is(typeof(R.init.front.init) T))
alias ElementType = T;
else
alias ElementType = void;
}
```

As far as I can see these are largely equivalent, except that the 
phobos version has special behavior for narrow strings [1]. This 
special behavior is actually unwanted in my case.


The following questions pop up:
1) Should we have a reference in the docs for std.traits to 
std.range.primitive : ElementType?
2) Should phobos contain a version without the special narrow 
string behavior?
3) Are there other differences between my version and the phobos 
version?


Thanks,
Bastiaan.

[1] https://dlang.org/phobos/std_range_primitives.html#ElementType


Re: Does dub support generating source files?

2018-01-06 Thread Bastiaan Veelo via Digitalmars-d-learn
On Saturday, 6 January 2018 at 13:40:54 UTC, rikki cattermole 
wrote:

On 06/01/2018 1:23 PM, Bastiaan Veelo wrote:
I could script a custom preBuildCommand that checks 
modification dates and supplies the Pegged include path 
explicitly but that seems hackish and non-portable and 
typically something that the build system should do.


See: https://github.com/Abscissa/gen-package-version


If I read this correctly, it basically takes the script route 
(rdmd) somewhat like the above [1], but taking care to stay 
portable by inquiring dub. I should be able to make this work, 
but I wish dub supported adding simple make rules...


[1] 
https://github.com/Abscissa/gen-package-version/blob/515138077fb78af5c4154f13990cee23e54ed9e7/src/genPackageVersion/genDModule.d#L60


Re: Does dub support generating source files?

2018-01-06 Thread Bastiaan Veelo via Digitalmars-d-learn
On Saturday, 6 January 2018 at 13:40:54 UTC, rikki cattermole 
wrote:

On 06/01/2018 1:23 PM, Bastiaan Veelo wrote:
Can dub do this or is this a thing for reggae? It must work on 
Windows though.


Thanks!


See: https://github.com/Abscissa/gen-package-version


That seems to be a good tip, thanks. I'll need to study what's 
going on there.


Does dub support generating source files?

2018-01-06 Thread Bastiaan Veelo via Digitalmars-d-learn

Hi,

One of my source files (epparser.d) should be generated by 
calling rdmd on another soure file (make.d) and therefore should 
depend on changes in make.d and an additional module 
(epgrammar.d). An include path to Pegged is required for 
compilation. epparser.d should be part of the main project, but 
make.d and epgrammar.d should not. I have tried using a dub 
subpackage for this with preBuildCommands ("cd ./subpackage && 
dub run") in the main project, but that doesn't update epparser.d 
when epgrammar.d changes (oddly enough; is does update when 
subpackage targetType is "library", but it must be "executable"). 
epparser.d should not be generated unnecessarily.


I could script a custom preBuildCommand that checks modification 
dates and supplies the Pegged include path explicitly but that 
seems hackish and non-portable and typically something that the 
build system should do.


Can dub do this or is this a thing for reggae? It must work on 
Windows though.


Thanks!


Re: BitArray shift left/right confusion.

2017-12-28 Thread Bastiaan Veelo via Digitalmars-d-learn

On Wednesday, 27 December 2017 at 20:45:49 UTC, Biotronic wrote:

BitArray is apparently a mess.

Thanks for your confirmation, digging and reporting issues
https://issues.dlang.org/show_bug.cgi?id=18133 and
https://issues.dlang.org/show_bug.cgi?id=18134

(Turns out we both live in the same country).



BitArray shift left/right confusion.

2017-12-27 Thread Bastiaan Veelo via Digitalmars-d-learn

I suppose the following is not a bug, but confusing it is:

```
void main()
{
import std.stdio;
import std.bitmanip;
BitArray ba = [1, 1, 1, 1, 1, 1, 1, 1];
writeln(ba);// [1, 1, 1, 1, 1, 1, 1, 1]
ba >>= 4; // right shift
writeln(ba);// [1, 1, 1, 1, 0, 0, 0, 0] bits shifted left
}```

I suppose this is because the array is printed left-to-right, 
whereas the bits in a byte are typically ordered right-to-left. I 
suppose I should interpret the bits in the array to increase in 
significance with increasing index (little endian) and that 
right-shift means a shift towards less significance (which is to 
the right in big endian).


The documentation of <<= and >>= [1] however just talks about 
left and right, without defining left and right or clarifying 
that the directions are reversed from how the array is printed.


Is there something I have missed?

[1] 
https://dlang.org/phobos/std_bitmanip.html#.BitArray.opOpAssign.2


Re: Ddoc and struct members

2017-12-14 Thread Bastiaan Veelo via Digitalmars-d-learn
On Thursday, 14 December 2017 at 03:17:10 UTC, rikki cattermole 
wrote:

On 14/12/2017 3:16 AM, n00nb wrote:
I don't understand if there is a way to generate documentation 
for all the members without putting a '///' over every member


There isn't.


It doesn’t need to take any vertical space though:

“If the documentation comment appears on the same line to the 
right of a declaration, it applies to that.“ [1]


[1] https://dlang.org/spec/ddoc.html


Re: ddox empty public methods/interfaces etc

2017-11-13 Thread Bastiaan Veelo via Digitalmars-d-learn

On Friday, 10 November 2017 at 10:12:32 UTC, RazvanN wrote:
I don't want to open a new forum thread for this, but if you 
guys have more experience with ddox can you please explain me 
how does it work? I expected you can simply run ddox on a .d 
file and it will output the documentation in some sort of form 
(json, html or whatever), but from what I saw, you need to pass 
it the json if you want to use serve-html/generate-html/filter 
and you have to use dmd to generate the json. Looking on the 
source code only passing serve-test actually parses the .d 
file, but the serve-test doesn't seem to be a public parameter.


Not sure whether this is on topic, but does


dub --build=ddox


do what you want?


Re: ldc D compiler installation on windows 10

2017-08-07 Thread Bastiaan Veelo via Digitalmars-d-learn

On Sunday, 6 August 2017 at 23:44:27 UTC, greatsam4sure wrote:
Good day. I will appreciate it if anybody here can help me with 
the step by step way of installing ldc D compiler on windows. I 
have read online info but i just don't get it. let the process 
be in steps for easy comprehension.thanks in advance


Try this:

1) go to https://github.com/ldc-developers/ldc/releases
2) download the appropriate ldc2-*-msvc.zip
3) unzip it anywhere
4) read the README.txt from that location.

If you encounter a problem, try to explain it here as detailed as 
you can.


Regards,
Bastiaan.


Re: VibeD - REST API and vibed.web.auth framework

2017-08-07 Thread Bastiaan Veelo via Digitalmars-d-learn

On Sunday, 6 August 2017 at 16:47:14 UTC, holo wrote:

Hello

I'm trying to use auth framework with REST api ( 
http://vibed.org/api/vibe.web.auth/ ).


Is it possible to use it with registerRestInterface? According 
to description under: 
http://vibed.org/api/vibe.web.auth/requiresAuth it should be 
available on both Web and REST.


Here is my example code and compilation errors bellow:



[snip]

  AuthInfo authenticate(scope HTTPServerRequest req, scope 
HTTPServerResponse res) @safe


[snip]



And im getting such errors:

ms-frontpage ~master: building configuration "application"...
../../.dub/packages/vibe-d-0.7.31/vibe-d/source/vibe/http/server.d(286,33): 
Deprecation: alias diet.traits.FilterCallback is deprecated - Use 
SafeFilterCallback instead.
source/app.d(14,31): Error: cannot create instance of interface 
IfOAuthAPI
source/service/oauth.d(35,8): Error: @safe function 
'oauth.OAuthAPI.authenticate' cannot call @system function 
'vibe.http.session.Session.opCast'


[snip]

Are you aware what @safe does? If you remove it, it probably 
compiles.


From @safe functions you cannot call functions that are not 
marked @safe or @trusted [1].


Regards,
Bastiaan.

[1] https://dlang.org/spec/function.html#function-safety


Re: trait detecting anonymous union?

2017-05-23 Thread Bastiaan Veelo via Digitalmars-d-learn

On Tuesday, 23 May 2017 at 01:02:59 UTC, Vladimir Panteleev wrote:

On Monday, 22 May 2017 at 21:03:42 UTC, Bastiaan Veelo wrote:
Is there a way to detect at CT that S has overlapping data 
members, when an anonimous union is used as above?


I have an implementation here:

https://github.com/CyberShadow/rclidasm/blob/31bde3347ec1259026b6ab15e2305f2a99e63a30/src/rclidasm/meta.d#L110-L183


Interesting work. Thanks or sharing!

Bastiaan.


  1   2   >