Re: Fluent APIs

2017-05-20 Thread Nicholas Wilson via Digitalmars-d-learn

On Sunday, 21 May 2017 at 05:18:33 UTC, Russel Winder wrote:
I am having a crisis of confidence. In two places I have 
structurally:


datum.action()
  .map!(…)

and then the fun starts as I need to actually do a flatMap. In 
one of the two places I have to:


.array
.joiner;

but in the other place I have to:

.joiner
.array;

in order to stop the compiler spewing out a mass of (to me 
anyway) incomprehensible messages with types I have no 
knowledge of. So why does the fluent API chain break in 
different ways in the two cases. A Priori this seems like a 
breakage of the abstraction.


Full code is at
https://github.com/russel/ApproxGC/blob/master/source/main.d
The comparison is between the functions 
createGenerationsDeleteList and

createListOfPlaces.

Any help rebuilding my knowledge would be good.

Also error message comprehensible to programmers rather than 
compiler writers  might help.


For this kind of errors I find that it helps to break the 
pipeline into individual stages and reason about the type 
separately.


Function createGenerationsDeleteList returns auto.
{
groups.byPair() // This gives a range of Tuple!(string, string[])
.map!(func) // this gives a sorted range of string[]
.array // this gives a string[][]
.joiner; // this gives a range of string[]
}

all is good. If we swap the array and joiner we get
{
.map!(func) // this gives a sorted range of string[]
.joiner // range of range of string(?)
.array; // array of range of string
}

return type is auto, no problems.

Function createListOfPlaces return string[]  <--
{
path.dirEntries(SpanMode.shallow) // range of DirEntries
.map!(p => p.name) // range of strings
.map!(p =>  // range of
   p.dirEntries("*.deb", SpanMode.depth). // range of dir 
entires
   map!(a => a.dirName).uniq) // goes to a 
range of strings

// have a range of range of strings here
.joiner  // range of string
.array  // string[]
}

all is good.

swap the array and joiner and we have
{
// have a range of range of strings here
.array  // array of range of string
.joiner // range of string
}
range of string is NOT string[], hence you get an error.

TL;DR you specified the return type in the second case, changing 
the order of the operations yields a different type -> type error.


Fluent APIs

2017-05-20 Thread Russel Winder via Digitalmars-d-learn
I am having a crisis of confidence. In two places I have structurally:

datum.action()
  .map!(…)

and then the fun starts as I need to actually do a flatMap. In one of
the two places I have to:

.array
.joiner;

but in the other place I have to:

.joiner
.array;

in order to stop the compiler spewing out a mass of (to me anyway)
incomprehensible messages with types I have no knowledge of. So why
does the fluent API chain break in different ways in the two cases. A
Priori this seems like a breakage of the abstraction.

Full code is at
https://github.com/russel/ApproxGC/blob/master/source/main.d
The comparison is between the functions createGenerationsDeleteList and
createListOfPlaces.

Any help rebuilding my knowledge would be good.

Also error message comprehensible to programmers rather than compiler
writers  might help.

-- 
Russel.
=
Dr Russel Winder  t: +44 20 7585 2200   voip: sip:russel.win...@ekiga.net
41 Buckmaster Roadm: +44 7770 465 077   xmpp: rus...@winder.org.uk
London SW11 1EN, UK   w: www.russel.org.uk  skype: russel_winder

signature.asc
Description: This is a digitally signed message part


Re: Code improvement for DNA reverse complement?

2017-05-20 Thread Laeeth Isharc via Digitalmars-d-learn

On Friday, 19 May 2017 at 07:29:44 UTC, biocyberman wrote:
I am solving this problem http://rosalind.info/problems/revc/ 
as an exercise to learn D. This is my solution:


https://dpaste.dzfl.pl/8aa667f962b7

Is there some D tricks I can use to make the 
`reverseComplement` function more concise and speedy? Any other 
comments for improvement of the whole solution are also much 
appreciated.


You might try using ldc in release mode.  With dmd, cost of 
ranges and so on might be higher than doing it in a more direct 
low-level way.  With ldc that difference often seems to shrink to 
insignificance as its optimisation is more powerful.  If you care 
about performance then use ldc or gdc.  (I have less experience 
with gdc, but probably similar).  But then it's best to compare 
results under ldc because the ratios of different options will be 
different vs dmd.





Re: Why is DUB not passing dll.def file to linker

2017-05-20 Thread Mike Parker via Digitalmars-d-learn

On Saturday, 20 May 2017 at 20:26:29 UTC, Igor wrote:

So my question is if the fix is so simple what are the reasons 
it isn't implemented? Am I missing something?


I don't know, but you could always submit a PR or an enhancement 
request.


Re: Why is DUB not passing dll.def file to linker

2017-05-20 Thread Igor via Digitalmars-d-learn

On Saturday, 20 May 2017 at 20:04:27 UTC, Mike Parker wrote:

On Saturday, 20 May 2017 at 19:53:16 UTC, Igor wrote:


There is no mention of dll.def file.


Add a "sourceFiles" directive:

"sourceFiles-windows" : ["dll.def"]

See the comments at the following:

https://github.com/dlang/dub/issues/575
https://github.com/dlang/dub/pull/399


Thanks Mike. Google wasn't this helpful :). In the meantime I 
tried debugging dub to see what is happening and with this simple 
change in packagerecipe.d it seems to work:


// collect source files (instead of just "*.d" i put the 
following at line 206)

dst.addSourceFiles(collectFiles(sourcePaths, "*.{d,def}"));

This is the output I got:

Performing "debug" build using dmd for x86_64.
handmade ~master: building configuration "internal"...
FILES IN BUILDSETTINGS: ["dll.def", "handmade.d", "handmade_h.d", 
"windll.d"]
dmd -m64 -c 
-of.dub\build\internal-debug-windows-x86_64-dmd_2074-C56D6B49201C03F44B01E754688EACEE\handmade.obj -debug -g -w -version=HANDMADE_INTERNAL -version=Have_handmade handmade.d handmade_h.d windll.d -vcolumns

Linking...
dmd 
-of.dub\build\internal-debug-windows-x86_64-dmd_2074-C56D6B49201C03F44B01E754688EACEE\handmade.dll .dub\build\internal-debug-windows-x86_64-dmd_2074-C56D6B49201C03F44B01E754688EACEE\handmade.obj dll.def -m64 -shared -g


As you can see def file just got added to link command.

So my question is if the fix is so simple what are the reasons it 
isn't implemented? Am I missing something?


Re: Why is DUB not passing dll.def file to linker

2017-05-20 Thread Mike Parker via Digitalmars-d-learn

On Saturday, 20 May 2017 at 19:53:16 UTC, Igor wrote:


There is no mention of dll.def file.


Add a "sourceFiles" directive:

"sourceFiles-windows" : ["dll.def"]

See the comments at the following:

https://github.com/dlang/dub/issues/575
https://github.com/dlang/dub/pull/399



Why is DUB not passing dll.def file to linker

2017-05-20 Thread Igor via Digitalmars-d-learn

I am using DUB 1.3.0. My folder structure is:
project
  dub.json
  source
windll.d
handmade.d
dll.def

dub.json looks like this:

{
"name": "handmade",
"targetType": "dynamicLibrary",
"targetPath": "build",
"configurations": [
{
"name": "internal",
"versions": ["HANDMADE_INTERNAL"]
}
]
}

But when I run: dub -v build -ax86_64 --force
I get:

Generating using build
Generate target handmade (dynamicLibrary D:\git\temp\build 
handmade)

Performing "debug" build using dmd for x86_64.
handmade ~master: building configuration "internal"...
dmd -m64 -c 
-of.dub\build\internal-debug-windows-x86_64-dmd_2074-C56D6B49201C03F44B01E754688EACEE\handmade.obj -debug -g -w -version=HANDMADE_INTERNAL -version=Have_handmade -Isource source\handmade.d source\windll.d -vcolumns

Linking...
dmd 
-of.dub\build\internal-debug-windows-x86_64-dmd_2074-C56D6B49201C03F44B01E754688EACEE\handmade.dll .dub\build\internal-debug-windows-x86_64-dmd_2074-C56D6B49201C03F44B01E754688EACEE\handmade.obj -m64 -shared -g
Copying target from 
D:\git\temp\.dub\build\internal-debug-windows-x86_64-dmd_2074-C56D6B49201C03F44B01E754688EACEE\handmade.dll to D:\git\temp\build


There is no mention of dll.def file.


Re: Getopt default int init and zero

2017-05-20 Thread Jon Degenhardt via Digitalmars-d-learn

On Friday, 19 May 2017 at 12:09:38 UTC, Suliman wrote:
I would like to check if user specified `0` as getopt 
parameter. But the problem that `int`'s are default in `0`. So 
if user did not specified nothing `int x` will be zero, and all 
other code will work as if it's zero.


One way to do this is the use a callback function or delegate. 
Have the callback set both the main variable and a boolean 
tracking whether the option was entered.


--Jon


Re: Why would an initialised struct pointer field be null in the struct's destructor?

2017-05-20 Thread Gary Willoughby via Digitalmars-d-learn

On Saturday, 20 May 2017 at 12:25:39 UTC, Stanislav Blinov wrote:

Oof. Dangerous stuff.


:)

Thanks for the heads up but I think I'm covering all cases in my 
main code.


Re: Why would an initialised struct pointer field be null in the struct's destructor?

2017-05-20 Thread Gary Willoughby via Digitalmars-d-learn

On Saturday, 20 May 2017 at 11:15:57 UTC, Moritz Maxeiner wrote:
Because `element = tmp` destroys `element`, which you allocated 
filled with zeroes.

The destructor will run for each `element`.


Right, I get it because the destructors running on the struct 
that is being replaced. Doh!


Re: Why would an initialised struct pointer field be null in the struct's destructor?

2017-05-20 Thread Stanislav Blinov via Digitalmars-d-learn

On Saturday, 20 May 2017 at 10:48:54 UTC, Gary Willoughby wrote:
In the following code, the `_foo` pointer (of the Foo struct) 
is null in the first call to the destructor. Why is this? I 
think it's got something to do with the foreach loop but I'm 
not sure. Any ideas?


Oof. Dangerous stuff. As Moritz pointed out, default opAssign 
will call the destructor on Foo. I should, however, elaborate 
further. You're dealing with uninitialized data. calloc() gives 
you zero-initialized block, which is not necessarily how Foo.init 
would look (it does in this case, but that's not true in general 
case).
malloc() gives you a potentially garbage-filled block, which is 
even more dangerous.


When filling an array of uninitialized values, use 
std.algorithm.moveEmplace(src, dst) instead of assignment. And, 
if you have destructors, you have to call the destructors 
manually when you free the array.
Furthermore, since Bar._data is an array of Foos, and Foo has a 
pointer in it, you might want to register the Bar._data array 
with the GC (GC.addRange, GC.removeRange). Unless you're willing 
to manually make sure that GC *never* sees those pointers.


Re: Why would an initialised struct pointer field be null in the struct's destructor?

2017-05-20 Thread Moritz Maxeiner via Digitalmars-d-learn

On Saturday, 20 May 2017 at 10:48:54 UTC, Gary Willoughby wrote:
In the following code, the `_foo` pointer (of the Foo struct) 
is null in the first call to the destructor. Why is this? I 
think it's got something to do with the foreach loop but I'm 
not sure. Any ideas?


struct Bar
{
private Foo[] _data;

public this(int n)
{
this._data = (cast(Foo*) calloc(n, Foo.sizeof))[0 .. n];

foreach(ref element; this._data)
{
auto tmp = Foo(1);
element = tmp;
}
}
}


Because `element = tmp` destroys `element`, which you allocated 
filled with zeroes.

The destructor will run for each `element`.


Why would an initialised struct pointer field be null in the struct's destructor?

2017-05-20 Thread Gary Willoughby via Digitalmars-d-learn
In the following code, the `_foo` pointer (of the Foo struct) is 
null in the first call to the destructor. Why is this? I think 
it's got something to do with the foreach loop but I'm not sure. 
Any ideas?



import std.stdio;
import core.stdc.stdlib : malloc, calloc, free;

struct Foo
{
public int* _foo;

public this(int n)
{
this._foo  = cast(int*) malloc(int.sizeof);
writefln("ctor: %x", this._foo);
}

public this(this)
{
writefln("post blit: %x", this._foo);
}

public ~this()
{
// Why is this._foo null here???
writefln("dtor: %x", this._foo);
}
}

struct Bar
{
private Foo[] _data;

public this(int n)
{
this._data = (cast(Foo*) calloc(n, Foo.sizeof))[0 .. n];

foreach(ref element; this._data)
{
auto tmp = Foo(1);
element = tmp;
}
}
}

void main(string[] args)
{
auto bar = Bar(1);
}



Re: how to disable inlining of ldc2 when 'dub build --build=release'?

2017-05-20 Thread Stanislav Blinov via Digitalmars-d-learn

On Saturday, 20 May 2017 at 08:02:26 UTC, lixiaozi wrote:

so, what should i do to disable inlining of ldc2 in release 
build?


As Stefan mentioned, a test case would be nice. But have you 
tried annotating the offending function with pragma(inline, 
false)?


http://dlang.org/spec/pragma.html#inline


Re: how to disable inlining of ldc2 when 'dub build --build=release'?

2017-05-20 Thread Stefan Koch via Digitalmars-d-learn

On Saturday, 20 May 2017 at 08:08:38 UTC, Johan Engelen wrote:

On Saturday, 20 May 2017 at 08:02:26 UTC, lixiaozi wrote:

[...]
I noticed it's the inline optimization in ldc2 that caused the 
crash.


If you are certain that your code is 100% correct, please file 
a bug report. Inlining is done by LLVM and it is rare to find 
an LLVM bug like that (what architecture are you on, x86?).


While LLVM in general has quite a few bugs, inlining should be 
rather solid.

 Any chance we can get a test-case ?


Re: how to disable inlining of ldc2 when 'dub build --build=release'?

2017-05-20 Thread Johan Engelen via Digitalmars-d-learn

On Saturday, 20 May 2017 at 08:02:26 UTC, lixiaozi wrote:


Now, I try to disable inlining in "dub.json" like
==
"dflags":[
"-disable-inlining"
],
==
 but it doesn't work, because then dub calls ldc2 like this:
'ldc2   -disable-inlining  -release  -enable-inlining 
-Hkeep-all-bodies -O3 -w -oq' and inlining in ldc2 will still 
be enabled.


You could file a bug/feature request with Dub: I think it should 
add user flags at the end of the cmdline. (flags can override 
earlier flags, so then the user can override any flag Dub is 
already passing to LDC).


-Johan


Re: how to disable inlining of ldc2 when 'dub build --build=release'?

2017-05-20 Thread Johan Engelen via Digitalmars-d-learn

On Saturday, 20 May 2017 at 08:02:26 UTC, lixiaozi wrote:

[...]
I noticed it's the inline optimization in ldc2 that caused the 
crash.


If you are certain that your code is 100% correct, please file a 
bug report. Inlining is done by LLVM and it is rare to find an 
LLVM bug like that (what architecture are you on, x86?).


so, what should i do to disable inlining of ldc2 in release 
build?


You can try disabling inlining of a specific function 
(pragma(inline, false)), or disabling optimization inside a 
function (@optStrategy("none")).


-Johan


how to disable inlining of ldc2 when 'dub build --build=release'?

2017-05-20 Thread lixiaozi via Digitalmars-d-learn

Hi,guys!
I recently use ldc2 to compile my project.
When using 'dub build --build=release --compiler=ldc2 ',it 
crashed in a try catch block.
After a few tries, I noticed it's the inline optimization in ldc2 
that caused the crash. So i manually changed the call of ldc2 to 
'ldc2 -release -disable-inlining -Hkeep-all-bodies -O3 -w -oq 
...' and it worked and doesn't crash any more.


Now, I try to disable inlining in "dub.json" like
==
"dflags":[
"-disable-inlining"
],
==
 but it doesn't work, because then dub calls ldc2 like this:
'ldc2   -disable-inlining  -release  -enable-inlining 
-Hkeep-all-bodies -O3 -w -oq' and inlining in ldc2 will still be 
enabled.


so, what should i do to disable inlining of ldc2 in release build?

Thanks in advance.