format with floating points GC allocating in DMD 2.090

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

char[4096] buf;
writeln(GC.stats.usedSize);
foreach (i; 0 .. 10) {
sformat(buf, "%f", 1.234f);
writeln(GC.stats.usedSize);
}

Output with DMD32 D Compiler v2.089.1-dirty (Win10 x64):
16
16
16
...

Output with DMD32 D Compiler v2.090.0-dirty:
16
848
1664
2480
3296
4112
4944
5760
6576
7392
8208


Re: Constant GC allocations when sending large messages to threads?

2020-01-30 Thread cc via Digitalmars-d-learn
On Wednesday, 29 January 2020 at 21:10:53 UTC, Steven 
Schveighoffer wrote:
I'm pretty sure std.concurrency uses Variant to pass message 
data, which boxes when it gets over a certain size. You are 
probably crossing that threshold.


The allocations should level out eventually when the GC starts 
collecting them.


-Steve


Is there a way to pre-allocate a buffer or something to be used?  
Ideally I'd like to avoid too many garbage collections happening, 
in my application these thread messages happen almost every frame 
and are quickly adding up to 100s of kilobytes in allocations 
every few seconds.


Re: Unexpected result of IsInstanceOf

2020-01-30 Thread Ali Çehreli via Digitalmars-d-learn

On 1/30/20 4:51 PM, Ben Jones wrote:
The following result doesn't make sense to me... how does isInstanceOf 
return false?


```
import std.traits;
import std.stdio;
import std.typecons;
auto f(T)(T t){
 return Nullable!T(t);
}
void main(){
     auto f3 = f(3);
     writeln(typeof(f3).stringof);
     writeln(isInstanceOf!(Nullable, f3));
}
```

outputs

```
Nullable!int
false
```


In this case it's an instance of a type template, which only types would 
be. So, you want to check whether typeof(f3) is an instance of Nullable.


Ali




Re: Unexpected result of IsInstanceOf

2020-01-30 Thread Adam D. Ruppe via Digitalmars-d-learn

On Friday, 31 January 2020 at 00:51:45 UTC, Ben Jones wrote:

writeln(typeof(f3).stringof);
writeln(isInstanceOf!(Nullable, f3));


In the first one, you check typeof, but not in the second one.

writeln(isInstanceOf!(Nullable, typeof(f3))); // true

The template argument there was T above - the type, not the value.


Re: wordladder - code improvement

2020-01-30 Thread dwdv via Digitalmars-d-learn
From one noob to another: Not much of a difference, but levenshteinDistance seems to be a good fit 
here. About as fast as your solution, slightly lower memory usage. byCodeUnit/byChar might shave off 
a few more ms.


For small scripts like these I'm usually not even bothering with const correctness and selective 
imports. There's also import std; but that might lead to ambiguous imports.


---

import std.algorithm, std.array, std.conv, std.datetime.stopwatch,
   std.functional, std.random, std.range, std.stdio, std.uni;

enum WORDFILE = "/usr/share/hunspell/en_GB.dic";
enum WORDSIZE = 4;
enum STEPS = WORDSIZE;

// could be verified at compile-time
static assert(WORDSIZE % 2 == 0, "WORDSIZE should be even");

alias WordList = string[];
alias WordSet = bool[string];

void main() {
auto sw = StopWatch(AutoStart.yes);
auto words = getWords(WORDFILE, WORDSIZE);
// would be slicker with proper destructuring support
auto res = generate!(() => genLadder(words.dup, STEPS))
.enumerate(1)
.find!(a => !a[1].empty)
.front;
writeln("tries: ", res[0]);
res[1].each!writeln;
writeln(sw.peek); // or sw.peek.total!"msecs"
}

WordSet getWords(string filename, uint wordsize) {
return File(filename).byLine
.map!(line => line.until!(not!isAlpha))
.filter!(word => word.count == wordsize)
.map!(word => word.to!string.toUpper)
.assocArray(true.repeat);
}

WordList genLadder(WordSet words, uint steps) {
WordList ladder;

string update(WordList comps) {
ladder ~= comps.choice;
words.remove(ladder.back);
return ladder.back;
}
WordList compWords(string prev) {
return words.byKey.filter!(word => levenshteinDistance(word, prev) == 
1).array;
}

auto prev = update(words.byKey.array);
foreach (comps; generate!(() => compWords(prev)).take(steps + 1)) {
if (comps.empty) return comps;
prev = update(comps);
}

if (levenshteinDistance(ladder.front, ladder.back) < WORDSIZE)
return [];
return ladder;
}


Unexpected result of IsInstanceOf

2020-01-30 Thread Ben Jones via Digitalmars-d-learn
The following result doesn't make sense to me... how does 
isInstanceOf return false?


```
import std.traits;
import std.stdio;
import std.typecons;
auto f(T)(T t){
return Nullable!T(t);   
}
void main(){
auto f3 = f(3);
writeln(typeof(f3).stringof);
writeln(isInstanceOf!(Nullable, f3));
}
```

outputs

```
Nullable!int
false
```


Re: Template Usage with Eponymous Trick

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

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

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



[..]

would make the language grammatically ambiguous...


OK, understood. Thank you.




Re: Template Usage with Eponymous Trick

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

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

[..]

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


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




Re: books for learning D

2020-01-30 Thread p.shkadzko via Digitalmars-d-learn

On Wednesday, 29 January 2020 at 08:56:26 UTC, rumbu wrote:

On Wednesday, 29 January 2020 at 08:40:48 UTC, p.shkadzko wrote:
Has anyone read "d programming language tutorial: A Step By 
Step Appoach: Learn d programming language Fast"?


https://www.goodreads.com/book/show/38328553-d-programming-language-tutorial?from_search=true=G9QIeXioOJ=3


Beware, this is a scam.
This guy has hundreds of "books". These books are promoted on 
various forums for download. Of course, you must enter your CC 
to "prove your identity".


Uh, ok, thanks for information.


Re: auto keyword

2020-01-30 Thread H. S. Teoh via Digitalmars-d-learn
On Thu, Jan 30, 2020 at 09:37:40AM +, Michael via Digitalmars-d-learn wrote:
[...]
> auto elements = buf.to!string.strip.split(" ").filter!(a => a != "");
> 
> That line strips white space from buf, splits it, removes empty
> elements and returns an array of strings. At least I thought so.

If you want an array of strings, just add .array to the end, and you
will get string[] back.


> Indeed elements can be treated as a string slice, but if i replace
> auto by string[] the compiler complains:
> Error: cannot implicitly convert expression filter(split(strip(to(buf)), "
> ")) of type FilterResult!(__lambda1, string[]) to string[]

That's because the actual type is a lazily-evaluated range.


> In order to use an explicit type I wonder what kind of type I might
> use instead of auto?

In this case, you actually can't spell out the type, because it's a
Voldemort type (it's only defined inside the function that constructs
it, and is not directly nameable outside).  Usually, a Voldemort type is
returned when you *shouldn't* be referring to it with an explicit type.
For example, in this case, if what you really want is an array of
strings then you should add .array at the end to get a string[].

If you wish to store the lazy range, for whatever reason, you can use
the typeof() operator to extract a type from it (without actually
spelling it out -- because you can't):

auto elements = buf.to!string.strip.split(" ").filter!(a => a != "");
alias E = typeof(elements);
E x;
x = elements;

Usually this is only useful if you wish the store the lazy range inside
some kind of aggregate type while retaining its lazy evaluation
semantics.  But if you expect it to be eagerly evaluated anyway, there's
no need to jump through hoops to get at the type of `elements`; just
stick .array to the end of it and get a string[] back.


T

-- 
"The whole problem with the world is that fools and fanatics are always so 
certain of themselves, but wiser people so full of doubts." -- Bertrand 
Russell. "How come he didn't put 'I think' at the end of it?" -- Anonymous


Re: DMD won't compile re-init of variable

2020-01-30 Thread Adam D. Ruppe via Digitalmars-d-learn

On Thursday, 30 January 2020 at 21:09:41 UTC, Simon wrote:

How do I revert my variable to the init state?


null is the initial state for those.


Re: DMD won't compile re-init of variable

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

On Thursday, 30 January 2020 at 21:09:41 UTC, Simon wrote:

Hi dlang community,

I'm trying to implement a "reset" functionality which should 
revert all variables to the program start initial state.


Example:

import Graph;
protected Edge[string] m_string2edge;

int main()
{
// adding some elements
// not important how it works
// m_string2edge[name] = e;

// resetting it
m_string2edge = null;
m_string2edge = new Edge[string]; // <- won't compile

return 0;
}

How do I revert my variable to the init state?

Thanks in advance,
Simon


You can use m_string2edge.clear() if you want to remove all 
entries from m_string2edge.


See https://dlang.org/spec/hash-map.html#properties


DMD won't compile re-init of variable

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

Hi dlang community,

I'm trying to implement a "reset" functionality which should 
revert all variables to the program start initial state.


Example:

import Graph;
protected Edge[string] m_string2edge;

int main()
{
// adding some elements
// not important how it works
// m_string2edge[name] = e;

// resetting it
m_string2edge = null;
m_string2edge = new Edge[string]; // <- won't compile

return 0;
}

How do I revert my variable to the init state?

Thanks in advance,
Simon



Re: Question about alias and getOverloads

2020-01-30 Thread Paul Backus via Digitalmars-d-learn

On Thursday, 30 January 2020 at 18:20:47 UTC, uranuz wrote:
2. Where in the documentation is mentioned that when I create 
alias to name that is a function or method that has overloads 
then this alias is actually an alias not only for the first or 
second or randomly selected overload in overload set, but an 
alias for all of overloads in set at the same time?


Thanks. Have a good day!


It is directly implied (although not outright stated) by the 
paragraph I quoted in my previous reply, which says that aliases 
may be used to merge overload sets. This feature would not work 
if the alias referred only to a single member of the overload set.


The documentation here could definitely use some improvement, but 
I think it is at least sufficient to reassure you that the 
behavior is intentional and can be safely relied upon.


Re: Template Usage with Eponymous Trick

2020-01-30 Thread Paul Backus via Digitalmars-d-learn

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


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


The 'classical' invocation style is not allowed because it would 
make the language grammatically ambiguous. Without semantic 
analysis, the compiler would have no way of knowing whether 
`foo!(int, int)` was intended to refer to the template instance 
foo!(int, int), or the eponymous member foo!(int, int).foo.


Re: Template Usage with Eponymous Trick

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

On Thursday, 30 January 2020 at 17:00:08 UTC, ShadoLight wrote:
Agreed. My question though is should the 'shorthand' notation 
_replace_ the 'longhand' notation, or be available _in 
addition_ to the 'longhand' notation in the eponymous case (so 
the eponymous notation is just 'syntax sugar' if you will).




Consider the following example:

T foo(T = int)(T val = T.init)
{
   return val + 1;
}

void main()
{
auto i = foo!().foo();
writeln(i);
}

What should be the value of i?
1: foo!() is the template instantiation, foo() the method call
2: foo!() and foo() are method calls.

The answer is 2 (because empty braces are optional) but with your 
proposed change it would be ambigous (unless one interpreation 
was prioritized which would probably be more confusing).


Maybe we should rather ask what benefit results from allowing 
this explicit notation? IMHO the entire purpose of epynemous 
templates is to make templates containing one public* symbol less 
verbose which is a common use case.


*public ~ useful outside of the templated symbol

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


Agreed, the documentation could use some polishing.


Re: Question about alias and getOverloads

2020-01-30 Thread H. S. Teoh via Digitalmars-d-learn
On Thu, Jan 30, 2020 at 06:20:47PM +, uranuz via Digitalmars-d-learn wrote:
[...]
> 1. Why API for __traits(getOverloads) is so strange. Why I need to
> find parent for symbol myself and pass actual symbol name as string,
> but not actually pass a symbol itself? It is very strange to me...

Actually, __traits was not intended to be used by end user code.  It's
supposed to be a raw, low-level interface into compiler internals, that
the standard library uses to implement a nicer user-facing API, i.e.,
std.traits.

Unfortunately, std.traits hasn't kept up with the proliferation of
__traits, and now we have pretty widespread use of __traits in user code
for doing things std.traits can't do, or can't do very well.

If you think __traits(getOverloads) is strange, wait till you see the
weird function parameter tuples that behave like tuples but actually
have extra information associated with them, but this information
"disappears" when you index the tuple or otherwise manipulate it like a
"normal" tuple.  Instead, to extract this information you must take
1-element slices of it.  Thankfully, this ugly mess is hidden behind
nicely-clothed citizens of std.traits, so user code rarely has to deal
with this craziness.

Arguably, any weird behaviours of __traits ought to be reason to file a
bug to add a nicer-behaving API to std.traits.  In fact, any __traits
that doesn't have a std.traits analogue arguably should be a bug.


> 2. Where in the documentation is mentioned that when I create alias to
> name that is a function or method that has overloads then this alias
> is actually an alias not only for the first or second or randomly
> selected overload in overload set, but an alias for all of overloads
> in set at the same time?
[...]

It's probably missing/incomplete documentation.  File a bug.


T

-- 
Change is inevitable, except from a vending machine.


Re: Question about alias and getOverloads

2020-01-30 Thread uranuz via Digitalmars-d-learn
I apologise that I need to revive this discussion again. But 
still I got answer to only one of my questions. I know that it is 
a common practice in programmers society that when someone asks 
more than 1 question. Then people who answer them usually choose 
only one of these questions that is the most easiest to answer. 
But the rest of the questions are just ignored. But the topic is 
still considered resolved. Person who answered `increased his 
carma`. All are happy. Except for the man who asked the question, 
but only got answer that is trivial, easy-to-answer or 
easy-to-find by himself. And actually got the answer to only one 
of the questions. And it is the less important.


At my job in this case I usually ask questions only one by one. 
It gives to person that shall try to answer no options and to 
answer only to this question. So only when I got answer that 
satisfies me I start to ask the next question.
I didn't want to use this technique there, because I believe that 
D community is better...


Sorry for this disgression, but I still don't understand several 
main points:
1. Why API for __traits(getOverloads) is so strange. Why I need 
to find parent for symbol myself and pass actual symbol name as 
string, but not actually pass a symbol itself? It is very strange 
to me...
2. Where in the documentation is mentioned that when I create 
alias to name that is a function or method that has overloads 
then this alias is actually an alias not only for the first or 
second or randomly selected overload in overload set, but an 
alias for all of overloads in set at the same time?


Thanks. Have a good day!


Re: Template Usage with Eponymous Trick

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

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


[...]


From my POV is

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

just a shorthand notation for...



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


If you had...

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

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


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

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


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


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




Re: Unused imports

2020-01-30 Thread Francesco Mecca via Digitalmars-d-learn

On Thursday, 30 January 2020 at 16:23:54 UTC, Michael wrote:

Is there a way to detect unused imports?

It happened to me that I used imports which I did not need in 
the end. So, I'd like to remove them easily.


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

TL;DR
This has come up in the past and the typical answer was: "This 
should be implemented as a third party tool using dmd as a 
library".


It is a problem that there are no currently available tools to do 
that (maybe visual-d greys out unused imports) but I do agree 
that it should be provided as a third party.


Such a functionality could end up in:
https://github.com/dlang-community/D-Scanner

and it is also a good first time project for a beginner in the D 
ecosystem.


Unused imports

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

Is there a way to detect unused imports?

It happened to me that I used imports which I did not need in the 
end. So, I'd like to remove them easily.





Re: Template Usage with Eponymous Trick

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

On Thursday, 30 January 2020 at 15:14:43 UTC, ShadoLight wrote:
Is there a technical reason for this limitation? Why are the 
'classical' invocation style not allowed for eponymous 
templates as well?


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


I guess the intention is to e.g. allow UFCS on the return values 
of templated functions without ambiguities, e.g.:


void main()
{
import std.algorithm, std.stdio;
int[] values = [ 1, 2, 3, 4 ];

values.filter!(i => i % 2 == 0)
  .map!(i => i / 2) // Does not refer to any hidden 
member of template filter

  .each!writeln;
}

From my POV is

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

just a shorthand notation for

template foo(T)
{
void foo() {}
}

allthough it could probably use some improvements to the 
documentation.


Re: Template Usage with Eponymous Trick

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

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

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


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



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


Eponymous templates are documented here:

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

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


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


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


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


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

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

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


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

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

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

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


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

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


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


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


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


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



Re: Template Usage with Eponymous Trick

2020-01-30 Thread Paul Backus via Digitalmars-d-learn

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


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



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


Eponymous templates are documented here:

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

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


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


Re: Template Usage with Eponymous Trick

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

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


[...]


Tested on https://run.dlang.io


Template Usage with Eponymous Trick

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


import std.stdio;

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

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

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

}

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

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


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


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


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


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


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

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


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



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


Re: Deprecation message from phobos compiling a vibe.d app.

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

On Thursday, 30 January 2020 at 13:05:05 UTC, drug wrote:
That's probably triggered by some constraints. I had the issue 
like this with Nullable: 
https://github.com/dlang/phobos/pull/7324


The core problem here stems from the fact that templates are 
always instantiated in the scope of the template declaration [1]. 
Hence dmd instantiates some template using a deprecated symbol in 
a non-deprecated scope and issues these warnings.


I'm currently working on a PR [2] to resolve this issue but still 
have to fix some issues when dealing with overloaded symbols as 
template alias parameters.


[1] https://dlang.org/spec/template.html#instantiation_scope
[2] https://github.com/dlang/dmd/pull/10677


Re: readline / Gnu readline

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

On Thursday, 30 January 2020 at 13:23:17 UTC, Adam D. Ruppe wrote:

On Thursday, 30 January 2020 at 06:12:32 UTC, Michael wrote:

I did exactly just what you proposed.


yeah i often just leave my random filenames in there, in this 
case rl was one of them. (if you don't put `.d` at the end of a 
filename, dmd will add it automatically). Generally a "module X 
is in file X which cannot be read" error means you should:


1) double-check any filenames on the command line. Make sure no 
typos etc and the files all exist. With my samples that 
frequently means changing the filename from whatever nonsense I 
left in my lazy copy/paste :P


2) If all the files are in place, this error can also be caused 
by a mismatch between the `module` name in an imported file and 
the `import` statement that is trying to use it. Those should 
always match.


I'm getting a bit more familiar with D. Really nice. Just wrote a 
program consisting of several files. Importing works fine now and 
also GNU readline.

Thanks for your help


Re: D Cookbook range save question

2020-01-30 Thread Adam D. Ruppe via Digitalmars-d-learn
(I'll answer here anyway just in case someone lands here via a 
web search.)


On Thursday, 30 January 2020 at 10:31:08 UTC, mark wrote:
Why is this a *copy*? (For a copy (in C++) I'd have expected 
return *this.)


In C++, `this` is a pointer, but in D, it is a reference. So 
assignment follows those semantics instead; `Foo a = this` does a 
copy assignment and if you want a pointer, you need to explicitly 
ask for one with the & operator: `Foo* a = `


fun fact, old versions of D, ~11ish years ago, actually worked 
the same way as C++. But the reference one was generally nicer 
and you can turn it back to the pointer as needed so it got 
changed.


Re: readline / Gnu readline

2020-01-30 Thread Adam D. Ruppe via Digitalmars-d-learn

On Thursday, 30 January 2020 at 06:12:32 UTC, Michael wrote:

I did exactly just what you proposed.


yeah i often just leave my random filenames in there, in this 
case rl was one of them. (if you don't put `.d` at the end of a 
filename, dmd will add it automatically). Generally a "module X 
is in file X which cannot be read" error means you should:


1) double-check any filenames on the command line. Make sure no 
typos etc and the files all exist. With my samples that 
frequently means changing the filename from whatever nonsense I 
left in my lazy copy/paste :P


2) If all the files are in place, this error can also be caused 
by a mismatch between the `module` name in an imported file and 
the `import` statement that is trying to use it. Those should 
always match.


Re: Deprecation message from phobos compiling a vibe.d app.

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

On 1/30/20 2:50 PM, Martin Tschierschke wrote:

When building my small vibe.d app I am getting this messages twice:

/usr/include/dmd/phobos/std/range/primitives.d(174,38): Deprecation: 
alias byKeyValue this is deprecated - Iterate over .byKeyValue instead.
/usr/include/dmd/phobos/std/range/primitives.d(176,27): Deprecation: 
alias byKeyValue this is deprecated - Iterate over .byKeyValue instead.
/usr/include/dmd/phobos/std/range/primitives.d(174,38): Deprecation: 
alias byKeyValue this is deprecated - Iterate over .byKeyValue instead.
/usr/include/dmd/phobos/std/range/primitives.d(176,27): Deprecation: 
alias byKeyValue this is deprecated - Iterate over .byKeyValue instead.


Unfortunately I don't know what is triggering this and what to do about.
The build is working, so it is more a question of elegance.


That's probably triggered by some constraints. I had the issue like this 
with Nullable: https://github.com/dlang/phobos/pull/7324


wordladder - code improvement

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

Below is a program that produces a wordladder.

The algorithm is probably suboptimal, but I don't care since I've 
implemented the same one in Python, Rust, Go, Java, and Nim, so I 
find it useful for language comparison purposes.


What I'd like some feedback on is how to improve the code 
(keeping the algorithm the same) to make it into more idiomatic D 
and to take the most advantage of D's features (while keeping it 
as understandable as possible).


For example, in the last function, compatibleWords(), I can't 
help thinking that I could avoid the foreach loop.


Also I'm still not really clear on the appropriateness of 
const/immutable/in in function arguments. The docs seem to 
discourage in, and other things I've read seem to favour const. 
Similarly, the appropriateness of const/immutable inside 
functions.


// wordladder.d
import core.time: MonoTime;
import std.algorithm: any, count, filter, map, sum, until;
import std.array: array, join;
import std.conv: dtext, to;
import std.functional: not;
import std.range: assocArray, repeat, zip;
import std.random: choice;
import std.stdio: File, write, writeln;
import std.uni: isAlpha, toUpper;

enum WORDFILE = "/usr/share/hunspell/en_GB.dic";
enum WORDSIZE = 4; // Should be even
enum STEPS = WORDSIZE;

alias WordList = string[];
alias WordSet = int[string]; // key = word; value = 0

void main() {
immutable start = MonoTime.currTime;
auto words = getWords(WORDFILE, WORDSIZE);
int count = 1;
WordList ladder;
write("Try ");
while (true) {
write('.');
ladder = generate(words, STEPS);
if (ladder.length != 0)
break;
++count;
}
writeln(' ', count);
writeln(join(ladder, '\n'));
writeln(MonoTime.currTime - start);
}

WordSet getWords(const string filename, const int wordsize) {
return File(filename).byLine
.map!(line => line.until!(not!isAlpha))
.filter!(word => word.count == wordsize)
.map!(word => word.to!string.toUpper)
.assocArray(0.repeat);
}

WordList generate(WordSet allWords, const int steps) {
WordList ladder;
auto words = allWords.dup;
auto compatibles = allWords.dup;
auto prev = update(ladder, words, compatibles);
for (int i = 0; i <= steps; ++i) {
compatibles = compatibleWords(prev, words);
if (compatibles.length == 0)
return [];
prev = update(ladder, words, compatibles);
}
immutable first = dtext(ladder[0]);
immutable last = dtext(ladder[$ - 1]);
if (any!(t => t[0] == t[1])(zip(first, last)))
return []; // Don't accept any vertical letters in common
return ladder;
}

string update(ref WordList ladder, ref WordSet words,
  const WordSet compatibles) {
immutable word = compatibles.byKey.array.choice;
ladder ~= word;
words.remove(word);
return word;
}

// Add words that are 1 letter different to prev
WordSet compatibleWords(const string prev, const WordSet words) {
WordSet compatibles;
immutable prevChars = dtext(prev);
immutable size = prevChars.length - 1;
foreach (word; words.byKey)
if (sum(map!(t => int(t[0] == t[1]))
 (zip(prevChars, dtext(word == size)
compatibles[word] = 0;
return compatibles;
}


Deprecation message from phobos compiling a vibe.d app.

2020-01-30 Thread Martin Tschierschke via Digitalmars-d-learn
When building my small vibe.d app I am getting this messages 
twice:


/usr/include/dmd/phobos/std/range/primitives.d(174,38): 
Deprecation: alias byKeyValue this is deprecated - Iterate over 
.byKeyValue instead.
/usr/include/dmd/phobos/std/range/primitives.d(176,27): 
Deprecation: alias byKeyValue this is deprecated - Iterate over 
.byKeyValue instead.
/usr/include/dmd/phobos/std/range/primitives.d(174,38): 
Deprecation: alias byKeyValue this is deprecated - Iterate over 
.byKeyValue instead.
/usr/include/dmd/phobos/std/range/primitives.d(176,27): 
Deprecation: alias byKeyValue this is deprecated - Iterate over 
.byKeyValue instead.


Unfortunately I don't know what is triggering this and what to do 
about.

The build is working, so it is more a question of elegance.


D Cookbook range save question

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

In the D Cookbook it has as part of the FibonacciRange example:

@property FibonacciRange save() { return this; }

And in the description it says:

"...save, which returns a new range that is a copy of the current 
range and can be advanced independently..."


Why is this a *copy*? (For a copy (in C++) I'd have expected 
return *this.)


Re: D Cookbook range save question

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

On Thursday, 30 January 2020 at 10:31:08 UTC, mark wrote:

In the D Cookbook it has as part of the FibonacciRange example:

@property FibonacciRange save() { return this; }

And in the description it says:

"...save, which returns a new range that is a copy of the 
current range and can be advanced independently..."


Why is this a *copy*? (For a copy (in C++) I'd have expected 
return *this.)


Oh, I understand now...

Sorry for the noise but I don't know how to delete a premature 
post!


Re: auto keyword

2020-01-30 Thread Jonathan M Davis via Digitalmars-d-learn
On Thursday, January 30, 2020 2:37:40 AM MST Michael via Digitalmars-d-learn 
wrote:
> auto is surely a nice feature. Nonetheless I'd prefer to use
> explicit types. So when reading a code and I see the auto keyword
> I also have to find out what kind of type is meant.
>
> I have a line of code that looks like this:
> auto elements = buf.to!string.strip.split(" ").filter!(a => a !=
> "");
>
> That line strips white space from buf, splits it, removes empty
> elements and returns an array of strings. At least I thought so.
>
> Indeed elements can be treated as a string slice, but if i
> replace auto by string[] the compiler complains:
> Error: cannot implicitly convert expression
> filter(split(strip(to(buf)), " ")) of type
> FilterResult!(__lambda1, string[]) to string[]
>
> In order to use an explicit type I wonder what kind of type I
> might use instead of auto?

For code like that, you don't. A lot of code in D - especially code that
uses ranges - uses what are called Voldemort types. They are declared inside
the function and you have no access to them. They follow a known API, so you
know what to do with them, but you they have no name that you have access
to. Realistically though, even if you had access to the type's name, you
wouldn't want to use it explicitly anyway, because usually, it's a templated
type which is instantiated with another templated type and is likely several
layers deep. Using the explicit names would be hideous. Years ago (before we
had Voldemort types), there was a bug in ddoc that made functions that
returned auto not show up in the documentation. So, all of std.algorithm
returned explicit types, and they were so hideous that it just scared
people. It works _far_ better to just understand how to use these types and
not use their names explicitly. It also makes the code far more resilient to
changes, since as long as the return type retains the same API, it doesn't
matter how the return type is changed. A function like filter could have
its return type changed to something else, and the code calling it wouldn't
care so long as it was the same kind of range.

Since you probably aren't familiar with ranges in D (or you wouldn't be
trying to use them by name), I suggest that you read this:

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

And in addition to the fact that you pretty much have to use auto with
range-based code, you're pretty much going to have to get used to dealing
with D code using auto heavily, because that's what most D code does.
Certainly, sometimes, you can use type names explicitly, but it's common
practice to use auto most of the time. It can take a bit of getting used to,
but ultimately, it actually results in more maintainable code.

- Jonathan M Davis





auto keyword

2020-01-30 Thread Michael via Digitalmars-d-learn
auto is surely a nice feature. Nonetheless I'd prefer to use 
explicit types. So when reading a code and I see the auto keyword 
I also have to find out what kind of type is meant.


I have a line of code that looks like this:
auto elements = buf.to!string.strip.split(" ").filter!(a => a != 
"");


That line strips white space from buf, splits it, removes empty 
elements and returns an array of strings. At least I thought so.


Indeed elements can be treated as a string slice, but if i 
replace auto by string[] the compiler complains:
Error: cannot implicitly convert expression 
filter(split(strip(to(buf)), " ")) of type 
FilterResult!(__lambda1, string[]) to string[]


In order to use an explicit type I wonder what kind of type I 
might use instead of auto?


Re: readline / Gnu readline

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

On Thursday, 30 January 2020 at 08:13:16 UTC, Mike Parker wrote:
That means any arguments you pass on the command line after the 
source file name will be passed to your program. Compiler 
options need to go before the source file name.


rdmd -L-lreadline mysource.d


That works, thanks Mike


Re: readline / Gnu readline

2020-01-30 Thread Mike Parker via Digitalmars-d-learn

On Thursday, 30 January 2020 at 06:27:36 UTC, Michael wrote:

On Thursday, 30 January 2020 at 06:15:54 UTC, Mike Parker wrote:

Is your source file named rl.d? And are you running dmd in the 
source file's directory?


No, I did not. Changed it now and it works with dmd. Great!
Tried the same with rdmd I'm getting a linker error.


Take a look at the rdmd documentation:

https://dlang.org/rdmd.html

There you'll see this:

rdmd [dmd and rdmd options] progfile[.d] [program arguments]

That means any arguments you pass on the command line after the 
source file name will be passed to your program. Compiler options 
need to go before the source file name.


rdmd -L-lreadline mysource.d