writeln wipes contents of variables ?

2016-01-21 Thread W.J. via Digitalmars-d-learn

Hi everybody!

I'm new to D and trying to wrap my head around ranges.

For a start I'm trying to take a input string and transform it, 
group it, etc.

After each step I inspect the result.
It works fine until step 3 where all of a sudden, after 
write(ln)ing the result, "step3" holds an array of empty arrays.

What gives? Program and output are attached below.

My question is why are "step3"'s contents before and after the 
writeln (1) different?
If I remove this line at (1) the foreach loops print the contents 
as I'd expect and the following writeln (2) prints the contents 
as expected, too.

However the writeln (3) prints empty arrays again.
I don't understand this behavior and I'd really like to know 
what's going on.


Your help and time is much appreciated!

I'm using an unmodified local build of dmd, druntime, and phobos 
from github updated and recompiled today.


[code]
import std.range;
import std.stdio;
import std.algorithm;

void main() {
  string test = "@\r  node1\nnodea\r\nkey:val\n\n  
node2\nnodea\n";

  writeln(test);
  writeln("---");

  auto step1 = test.replace("\r\n", "\n")
.replace("  ", "\t")
.splitter!"a == 10 || a == 13"()
;
  writeln("Step 1:", step1);
  writeln("---");
  writeln("  type: ", typeid(step1));
  writeln("---");

  import std.typecons: Tuple;
  string[][] step2;
  foreach(a; step1) {
auto e = findSplitAfter(a, "\t").array;
step2 ~= e;
  }
  writeln("Step 2:", step2);
  writeln("---");
  writeln("  type: ", typeid(step2));
  writeln("---");

  auto step3 = step2.chunkBy!((a,b) => a[0]==b[0]).array;
  writeln("Step 3:", step3); // (1)
  writeln("---");
  writeln("  type: ", typeid(step3));
  writeln("-+-");

  foreach(x; step3) {
writeln("x:",typeid(x),x);
foreach(y; x)
  writeln("  y:",typeid(y),y);
  }
  writeln("--",step3); // (2)
  writeln("--",step3); // (3)
  writeln("the end");
}
[/code]

Output:
[code]
  node1
nodea
key:val

  node2
nodea

---
Step 1:["@", "\tnode1", "\t\tnodea", "\t\tkey:val", "", 
"\tnode2", "\t\tnodea", ""]

---
  type: std.algorithm.iteration.SplitterResult!(unaryFun, 
string).SplitterResult

---
Step 2:[["", "@"], ["\t", "node1"], ["\t", "\tnodea"], ["\t", 
"\tkey:val"], ["", ""], ["\t", "node2"], ["\t", "\tnodea"], ["", 
""]]

---
  type: immutable(char)[][][]
---
Step 3:[[["", "@"]], [["\t", "node1"], ["\t", "\tnodea"], ["\t", 
"\tkey:val"]], [["", ""]], [["\t", "node2"], ["\t", "\tnodea"]], 
[["", ""]]]

---
  type: app.main.ChunkByImpl!(__lambda1, 
string[][]).ChunkByImpl.Group[]

-+-
x:app.main.ChunkByImpl!(__lambda1, string[][]).ChunkByImpl.Group[]
x:app.main.ChunkByImpl!(__lambda1, string[][]).ChunkByImpl.Group[]
x:app.main.ChunkByImpl!(__lambda1, string[][]).ChunkByImpl.Group[]
x:app.main.ChunkByImpl!(__lambda1, string[][]).ChunkByImpl.Group[]
x:app.main.ChunkByImpl!(__lambda1, string[][]).ChunkByImpl.Group[]
--[[], [], [], [], []]
the end
[/code]


Re: Distribution of D apps

2016-01-21 Thread W.J. via Digitalmars-d-learn
On Wednesday, 20 January 2016 at 16:01:11 UTC, Dibyendu Majumdar 
wrote:

Hi,

I am trying to understand the options for distributing a D app 
to users. My assumption is that only the shared libraries and 
binaries need to be distributed, and I need to include the D 
libraries. Is this correct?


Thanks and Regards
Dibyendu


Hi,

On Linux you can use 'ldd' to print shared library dependencies.
On Windows you can use Dependency Walker.
On Mac there's likely a similar program.
Mind also that license terms for distributing libraries apply.




Re: writeln wipes contents of variables ?

2016-01-21 Thread W.J. via Digitalmars-d-learn
On Thursday, 21 January 2016 at 13:15:46 UTC, Rikki Cattermole 
wrote:


Ok so input ranges.
An input range is a little bit like an iterator (if you know 
what that is).


When an input range has been read fully, it is empty aka no 
longer has any values associated with it.


writeln, reads an input range fully (since you can't ask for 
what is next without removing the current item) and outputs 
each entry.


So yes, writeln will remove all entries from an input range.
Note however it will not do this for arrays since you can read 
anywhere within them.



Thanks for your reply.

So writeln consumes the values in an InputRange. That leads me to 
believe that if I feed an InputRange to foreach, it will consume 
the values, too.

Did I get that right ?

If that's the case, why I can iterate and write the values just 
fine using nested foreach loops *and* writeln them afterwards ?
I would expect the foreach loops leaves "step3" in the same state 
as writeln does.


So I'm still a little confused as to how foreach goes about it. I 
thought foreach would be iterating an InputRange the same way 
writeln does.


By attaching ".array" to the result of I was under the impression 
the result was actually converted to an array.
That seems not to be the case. What I probably got was something 
like an array of arrays of groups - which are apparently 
InputRanges ?


So, yes, writeln... InputRange... makes perfect sense except for 
the foreach case.


Thanks again for the help :)




Re: Distribution of D apps

2016-01-21 Thread W.J. via Digitalmars-d-learn

On Thursday, 21 January 2016 at 14:03:03 UTC, FreeSlave wrote:

On Thursday, 21 January 2016 at 13:26:15 UTC, W.J. wrote:
On Wednesday, 20 January 2016 at 16:01:11 UTC, Dibyendu 
Majumdar wrote:

[...]


Hi,

On Linux you can use 'ldd' to print shared library 
dependencies.

On Windows you can use Dependency Walker.
On Mac there's likely a similar program.
Mind also that license terms for distributing libraries apply.


OS X has otool -L

Note that these tools don't show runtime dependencies. Many 
libraries can be loaded at runtime, especially when you use 
derelict-like modules. These libraries in their turn may depend 
on others, etc.


Yes, except for Dependency Walker, which, if I recall, inspects 
the executable and can recognize runtime dependencies via 
LoadLibrary calls.


Re: writeln wipes contents of variables ?

2016-01-21 Thread W.J. via Digitalmars-d-learn
On Thursday, 21 January 2016 at 14:36:36 UTC, Rikki Cattermole 
wrote:

On 22/01/16 3:07 AM, W.J. wrote:
On Thursday, 21 January 2016 at 13:15:46 UTC, Rikki Cattermole 
wrote:

[...]



Thanks for your reply.

So writeln consumes the values in an InputRange. That leads me 
to
believe that if I feed an InputRange to foreach, it will 
consume the

values, too.
Did I get that right ?


Correct.

If that's the case, why I can iterate and write the values 
just fine

using nested foreach loops *and* writeln them afterwards ?
I would expect the foreach loops leaves "step3" in the same 
state as

writeln does.

So I'm still a little confused as to how foreach goes about 
it. I
thought foreach would be iterating an InputRange the same way 
writeln does.


By attaching ".array" to the result of I was under the 
impression the

result was actually converted to an array.
That seems not to be the case. What I probably got was 
something like an

array of arrays of groups - which are apparently InputRanges ?

So, yes, writeln... InputRange... makes perfect sense except 
for the

foreach case.

Thanks again for the help :)


After playing around some more and apart from requiring much more 
practice I think this topic can be marked as 'solved'. However, I 
can't seem to find the edit button for my initial post.


Anyways, thanks for your contributions :) Very much appreciated!


Re: Linking C libraries with DMD

2016-01-21 Thread W.J. via Digitalmars-d-learn

On Thursday, 21 January 2016 at 16:14:40 UTC, jmh530 wrote:
I'm trying to understand calling C libraries from D on Windows 
with DMD. I made a simple example and compiled it with a static 
library fine (so I've converted the .h file correctly). Then, I 
compiled with gcc to a shared library (because I cannot for the 
life of me figure out how to do this with DMC). I then used 
implib to generate a .lib file (the fact that this is necessary 
is not described nearly well enough in the documentation).


The next step is getting this to compile with dmd. I'm getting 
an error that the function isn't getting called, which is 
suggesting that I'm not linking the .lib file with DMD properly.


The dmd page
https://dlang.org/dmd-windows.html
explains that -L is used to pass stuff to the linker. It seems 
to indicate that this should be the folder that the library is 
in. The dll and lib files are in the same folder as the .d file 
I'm trying to compile. So presumably, this should be -L. or 
-L\. or like -LC:\folder\. But nothing like that works. There's 
a link on the dmd page to optlink, which doesn't really help me 
figure this out either. There's also some stuff about set LIB 
in the sci.ini. Not sure I'm supposed to mess with that.


The LearningD book has some examples as well. I don't have it 
in front of me right now, but I think I tried what they 
recommend also. Nevertheless, I feel like the documentation 
should be clear enough so that this isn't so frustrating.


You need to port the header file to d. i believe there's the htod 
utility, however I haven't used that yet.
Then, basically all you have to do is to tell the linker to link 
against your C .lib.
Remember that -LC:\folder (for dmd) passes "C:\folder" on to the 
linker. Assuming the library folder flag for your linker is -L, 
you'd want to use -L-LC:\folder.


Re: Linking C libraries with DMD

2016-01-21 Thread W.J. via Digitalmars-d-learn
On Thursday, 21 January 2016 at 17:00:14 UTC, Andrea Fontana 
wrote:

On Thursday, 21 January 2016 at 16:57:26 UTC, W.J. wrote:
You need to port the header file to d. i believe there's the 
htod utility, however I haven't used that yet.


You should try with dstep too.

More info here:
http://wiki.dlang.org/List_of_Bindings

And here:
http://wiki.dlang.org/D_binding_for_C


Interesting read. Thanks for sharing!



Re: Linking C libraries with DMD

2016-01-21 Thread W.J. via Digitalmars-d-learn

On Thursday, 21 January 2016 at 23:07:06 UTC, jmh530 wrote:
On Thursday, 21 January 2016 at 22:54:26 UTC, Dibyendu Majumdar 
wrote:

On Thursday, 21 January 2016 at 22:49:06 UTC, jmh530 wrote:


I'm not trying to created a shared library in D. My goal is 
to use a shared library from C in D. Right now, I'm working 
with a simple test case to make sure I could understand it 
before working with the actual shared library I want to use.


I recall some discussion in LearningD (don't have it in front 
of me now) that different types of shared libraries are 
needed on 32bit vs. 64bit because there is a different 
linker. This is what I did to created the shared library:


gcc -Wall -fPIC -c .c -I.
gcc -shared -o .dll .o -I.
implib .lib .dll


Okay then you don't need the /IMPLIB option. But you do need 
to specify the library via -L as I mentioned before.


i.e. use:

dmd -m64 -L/LIBPATH: -L prog.d

Where  is yourlib.lib and this is present along 
with the DLL in the path you gave.


Plus your prog.d needs to have appropriate code. Example:

module app;

extern (C) void testing();

void main()
{
testing();
}

Here testing() is provided in the DLL.


I ran

dmd -m64 .d -L/LIBPATH: -L

and got

 : fatal error LNK1136: invalid or corrupt file
--- errorlevel 1136

At least that's progress.


The linker will most certainly get confused by  this "-Lname>" - as it will take it for an object file. The difference is 
that a library is a collection of object files.


The GNU linker ld, for instance, uses the -l switch for 
adding libraries to link against and -L to add a search 
path to look for the libraries passed in with -l.


If you leave it to the compiler to invoke the linker you need to 
remember the -L compiler switch is passing what follows to the 
linker (minus the -L compiler switch).
I.e. -L-LC:\lib\path will be passed on as "-LC:\lib\path", 
-L-lsomelib => "-lsomelib", etc.


You won't find help about linker options on any compiler manual. 
You have to refer to your linker manual.


Also make sure to adhere to naming conventions. It could very 
well be your linker quits with an error message if you pass it 
-lsomelib for a file somelib.lib when it expects to find the file 
libsomelib.lib instead.


LNK1136 is for a corrupt or abnormally small file. I did notice 
that the original dll was 82kb and the lib file was 2kb.


The lib for a 'DLL' is small because it just tells the linker 
where to find the code in the 'DLL' - the actual code is in the 
'DLL'.


Hope the helps


Re: writeln wipes contents of variables ?

2016-01-21 Thread W.J. via Digitalmars-d-learn

On Thursday, 21 January 2016 at 21:59:10 UTC, Chris Wright wrote:

On Thu, 21 Jan 2016 14:07:16 +, W.J. wrote:
So writeln consumes the values in an InputRange. That leads me 
to
believe that if I feed an InputRange to foreach, it will 
consume the

values, too.
Did I get that right ?


In general, yes.



Thanks for your reply.

Some ranges have value semantics and can be saved simply by 
assigning them to a new variable, or passing them to a function.


How can I identify those ranges, or, how can I tell if any 
particular range has value semantics ? I didn't read any of this 
in the manual - not that I could remember anyways.


Thanks for your help!


Re: htod question

2016-01-21 Thread W.J. via Digitalmars-d-learn
On Friday, 22 January 2016 at 00:31:01 UTC, Dibyendu Majumdar 
wrote:
I tried using htod but got errors as it could not handle the 
std C header files (Visual C++).


And probably never will. D doesn't have a preprocessor so it's 
kind of hard to automate the process.



How do people work around this?

Thanks and Regards
Dibyendu


They don't.

Counter question: What's so bad about the D std library ?


Re: htod question

2016-01-21 Thread W.J. via Digitalmars-d-learn
On Friday, 22 January 2016 at 01:04:50 UTC, Dibyendu Majumdar 
wrote:
On Friday, 22 January 2016 at 01:03:09 UTC, Dibyendu Majumdar 
wrote:

On Friday, 22 January 2016 at 00:52:59 UTC, W.J. wrote:

Counter question: What's so bad about the D std library ?


I am trying to create bindings for existing C library so I was 
trying to use htod for that.


The library includes various C header files ... causing htod to 
fail


I see. I didn't quite understand your question correctly. I 
thought you were trying to port over the std c library.


Maybe you can give an example ?


Re: writeln wipes contents of variables ?

2016-01-22 Thread W.J. via Digitalmars-d-learn
On Friday, 22 January 2016 at 01:47:19 UTC, Rikki Cattermole 
wrote:


Contrary to what it is called in the links, this is a 
NewsGroup/Mailing list and not a forum. So no editing ability :)



I'll keep that in mind. Thanks :)


Re: writeln wipes contents of variables ?

2016-01-22 Thread W.J. via Digitalmars-d-learn

On Friday, 22 January 2016 at 01:49:58 UTC, anonymous wrote:

On 22.01.2016 01:49, W.J. wrote:
How can I identify those ranges, or, how can I tell if any 
particular
range has value semantics ? I didn't read any of this in the 
manual -

not that I could remember anyways.


Generally you shouldn't. If you care about it either way, use 
.save or std.range.refRange.


If you don't want some range r to be consumed by some 
operation, pass r.save instead of plain r. If you want r to be 
consumed, pass refRange(&r). Only if you don't care if r is 
consumed or not, should you pass simply r.


If you know for a fact that copying r is the same as r.save, 
then you can just pass (and copy) r, of course. We know it's 
that way with dynamic arrays, because of their nature as 
pointer+length structures. But there's nothing wrong with 
calling .save on an array anyway.


Also, when a function takes a range via a ref parameter, then 
you don't need refRange, of course. The ref parameter ensures 
that no copy is made and that the original range is affected by 
the function.


This is even better than trying to figure out whether value 
semantics are supported or not.


So, .safe returns a copy of the range - I suppose a copy of the 
current state - and refRange always consumes the values in the 
range.


Thanks a lot for your reply! Very much appreciated.