Re: linking trouble

2018-09-06 Thread Mike Parker via Digitalmars-d-learn
On Friday, 7 September 2018 at 02:44:24 UTC, hridyansh thakur 
wrote:
On Thursday, 6 September 2018 at 16:59:43 UTC, rikki cattermole 
wrote:

On 07/09/2018 4:03 AM, hridyansh thakur wrote:

[...]


That definition isn't complete. Missing at the very least 
``();`` to make it a function declaration.



[...]


So what is the errors you're getting?
And what are the commands you're executing?


compiler is failing to rercognise the .o file


A .o file? Are you using MinGW to compile your C++? You're not 
going to get very far if you are. You have two options that are 
guaranteed to work.


Use the Digital Mars C++ compiler to compile your C++ file to an 
OMF object then use the default OPTLINK linker when building. 
This only supports 32-bit builds.


dmd foo.d bar.obj

The other option is to use the Microsoft linker, which requires 
the MS build tools be installed, either via the build tools 
distribution or Visual Studio. Then you can compile your C++ file 
to a COFF object with the MS compiler for 32- or 64-bit and build 
your executable with one of the following:


dmd -m32mscoff foo.d bar.obj
dmd -m64 foo.d bar.obj


Re: Alias this and opDispatch override

2018-09-06 Thread Domain via Digitalmars-d-learn

On Friday, 7 September 2018 at 02:22:58 UTC, Domain wrote:

The following code fail to compile:

enum KeyMod : int
{
LCtrl  = 1 << 0,
RCtrl  = 1 << 1,
Ctrl   = LCtrl | RCtrl,
}

struct Flags(E)
{
public:
BitFlags!(E, Yes.unsafe) flags;
alias flags this;

bool opDispatch(string name)() const
if (__traits(hasMember, E, name))
{
enum e = __traits(getMember, E, name);
return (mValue & e) != 0;
}
}

Flags!KeyMod keys;
keys.LCtrl = true;
assert(keys.Ctrl);

Error: no property LCtrl for type Flags!(KeyMod)
Error: no property Ctrl for type Flags!(KeyMod)


Sorry. This works:

struct Flags(E)
{
public:
BitFlags!(E, Yes.unsafe) flags;
alias flags this;

bool opDispatch(string name)() const
if (__traits(hasMember, E, name))
{
enum e = __traits(getMember, E, name);
return cast(int)(flags & e) != 0;
}

void opDispatch(string name)(bool set)
if (__traits(hasMember, E, name))
{
enum e = __traits(getMember, E, name);
if (set)
flags |= e;
else
flags &= ~e;
}
}


Re: linking trouble

2018-09-06 Thread hridyansh thakur via Digitalmars-d-learn
On Thursday, 6 September 2018 at 16:59:43 UTC, rikki cattermole 
wrote:

On 07/09/2018 4:03 AM, hridyansh thakur wrote:

[...]


That definition isn't complete. Missing at the very least 
``();`` to make it a function declaration.



[...]


So what is the errors you're getting?
And what are the commands you're executing?


compiler is failing to rercognise the .o file


Alias this and opDispatch override

2018-09-06 Thread Domain via Digitalmars-d-learn

The following code fail to compile:

enum KeyMod : int
{
LCtrl  = 1 << 0,
RCtrl  = 1 << 1,
Ctrl   = LCtrl | RCtrl,
}

struct Flags(E)
{
public:
BitFlags!(E, Yes.unsafe) flags;
alias flags this;

bool opDispatch(string name)() const
if (__traits(hasMember, E, name))
{
enum e = __traits(getMember, E, name);
return (mValue & e) != 0;
}
}

Flags!KeyMod keys;
keys.LCtrl = true;
assert(keys.Ctrl);

Error: no property LCtrl for type Flags!(KeyMod)
Error: no property Ctrl for type Flags!(KeyMod)


Re: Bug with writeln?

2018-09-06 Thread Jonathan M Davis via Digitalmars-d-learn
On Thursday, September 6, 2018 1:05:03 PM MDT Steven Schveighoffer via 
Digitalmars-d-learn wrote:
> On 9/6/18 2:52 PM, Jonathan M Davis wrote:
> > On Thursday, September 6, 2018 12:21:24 PM MDT Steven Schveighoffer via
> >
> > Digitalmars-d-learn wrote:
> >> On 9/6/18 12:55 PM, Jonathan M Davis wrote:
> >>> It's not a bug in writeln. Any time that a range is copied, you must
> >>> not
> >>> do _anything_ else with the original unless copying it is equivalent
> >>> to
> >>> calling save on it, because the semantics of copying a range are
> >>> unspecified. They vary wildly depending on the range type (e.g.
> >>> copying
> >>> a dynamic array is equivalent to calling save, but copying a class
> >>> reference is not). When you pass the range to writeln, you must
> >>> assumed
> >>> that it may have been consumed. And since you have range of ranges,
> >>> you
> >>> must assume that the ranges that are contained may have been consumed.
> >>> If you want to pass them to writeln and then do anything else with
> >>> them, then you'll need to call save on every range involved (which is
> >>> a
> >>> bit of a pain with a range of ranges, but it's necessary all the
> >>> same).
> >>
> >> This is not necessarily true. It depends how the sub-ranges are
> >> returned.
> >>
> >> The bug is that formattedWrite takes ranges sometimes by ref, sometimes
> >> not.
> >>
> >> formattedWrite should call save on a forward range whenever it makes a
> >> copy, and it doesn't.
> >>
> >> Case in point, it doesn't matter if you call writeln(b.save), the same
> >> thing happens.
> >
> > That's still not a bug in formattedWrite. save only duplicates the
> > outer-most range. And since writeln will ultimately iterate through the
> > inner ranges - which weren't saved - you end up with them being
> > consumed.
>
> That is the bug -- formattedWrite should save all the inner ranges
> (writeln calls formattedWrite, and lets it do all the work). To not do
> so leaves it open to problems such as consuming the sub ranges.
>
> I can't imagine that anyone would expect or desire the current behavior.

It's exactly what you're going to get in all cases if the ranges aren't
forward ranges, and it's what you have to do in general when passing ranges
of ranges to functions if you want to be able to continue to use any of the
ranges involved after passing them to the function. Changing formattedWrite
to work around it is only a workaround for this paricular case. It's still
a bug in general - though given that this would be one of the more common
cases, working around it in this particular case may be worth it. It's still
a workaround though and not something that can be relied on in with
range-based code in general - especially when most range-based code isn't
written to care about what the element types are and copies elements around
all the time.

> Ironically, when that bug is fixed, you *don't* have to call save on the
> outer range!

Except you do, because it's passed by value. If it's a dynamic array, then
you're fine, since copying saves, but in the general case, you still do.

> > When you're passing a range of ranges to a function, you need to
> > recursively save them if you don't want the inner ranges in the
> > original range to be consumed. Regardless of what formattedWrite does,
> > it's a general issue with any function that you pass a range of ranges.
> > It comes right back to the same issue of the semantics of copying
> > ranges being unspecified and that you therefore must always use save on
> > any ranges involved if you want to then use those ranges after having
> > passed them to a function or copy them doing anything else. It's that
> > much more annoying when you're dealing with a range of ranges rather
> > than a range of something else, but the issue is the same.
> It's only a problem if the subranges are returned by reference. If they
> aren't, then no save is required (because they are already copies). The
> fix in this case is to make a copy if possible (using save as expected).
>
> I think the save semantics have to be one of the worst designs in D.

On that we can definitely agree. I'm strongly of the opinion that it should
have been required that forward ranges be dynamic arrays or structs (no
classes allowed) and that it be required that they have a postblit / copy
constructor if the default copy wasn't equivalent to save. If you wanted a
class that was a forward range, you would then have to wrap it in a struct
with the appropriate postblit / copy constructor. That way, copying a
forward range would _always_ be saving it.

The harder question is what to then do with basic input ranges. Having them
share code with forward ranges is often useful but also frequently a
disaster, and to really be correct, they would need to either be full-on
reference types or always passed around by reference. Allowing partial
reference types is a total disaster when you're allowed to copy the range.
Requiring that they be classes would 

Re: Bug with writeln?

2018-09-06 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/6/18 2:52 PM, Jonathan M Davis wrote:

On Thursday, September 6, 2018 12:21:24 PM MDT Steven Schveighoffer via
Digitalmars-d-learn wrote:

On 9/6/18 12:55 PM, Jonathan M Davis wrote:

It's not a bug in writeln. Any time that a range is copied, you must not
do _anything_ else with the original unless copying it is equivalent to
calling save on it, because the semantics of copying a range are
unspecified. They vary wildly depending on the range type (e.g. copying
a dynamic array is equivalent to calling save, but copying a class
reference is not). When you pass the range to writeln, you must assumed
that it may have been consumed. And since you have range of ranges, you
must assume that the ranges that are contained may have been consumed.
If you want to pass them to writeln and then do anything else with
them, then you'll need to call save on every range involved (which is a
bit of a pain with a range of ranges, but it's necessary all the same).


This is not necessarily true. It depends how the sub-ranges are returned.

The bug is that formattedWrite takes ranges sometimes by ref, sometimes
not.

formattedWrite should call save on a forward range whenever it makes a
copy, and it doesn't.

Case in point, it doesn't matter if you call writeln(b.save), the same
thing happens.


That's still not a bug in formattedWrite. save only duplicates the
outer-most range. And since writeln will ultimately iterate through the
inner ranges - which weren't saved - you end up with them being consumed.


That is the bug -- formattedWrite should save all the inner ranges 
(writeln calls formattedWrite, and lets it do all the work). To not do 
so leaves it open to problems such as consuming the sub ranges.


I can't imagine that anyone would expect or desire the current behavior.

Ironically, when that bug is fixed, you *don't* have to call save on the 
outer range!



When you're passing a range of ranges to a function, you need to recursively
save them if you don't want the inner ranges in the original range to be
consumed. Regardless of what formattedWrite does, it's a general issue with
any function that you pass a range of ranges. It comes right back to the
same issue of the semantics of copying ranges being unspecified and that you
therefore must always use save on any ranges involved if you want to then
use those ranges after having passed them to a function or copy them doing
anything else. It's that much more annoying when you're dealing with a range
of ranges rather than a range of something else, but the issue is the same.



It's only a problem if the subranges are returned by reference. If they 
aren't, then no save is required (because they are already copies). The 
fix in this case is to make a copy if possible (using save as expected).


I think the save semantics have to be one of the worst designs in D.

-Steve


Re: Bug with writeln?

2018-09-06 Thread Jonathan M Davis via Digitalmars-d-learn
On Thursday, September 6, 2018 12:21:24 PM MDT Steven Schveighoffer via 
Digitalmars-d-learn wrote:
> On 9/6/18 12:55 PM, Jonathan M Davis wrote:
> > On Thursday, September 6, 2018 2:40:08 AM MDT Saurabh Das via
> > Digitalmars-d->
> > learn wrote:
> >> Is this a bug with writeln?
> >>
> >> void main()
> >> {
> >>
> >>   import std.stdio, std.range, std.algorithm;
> >>
> >>   auto a1 = sort([1,3,5,4,2]);
> >>   auto a2 = sort([9,8,9]);
> >>   auto a3 = sort([5,4,5,4]);
> >>
> >>   pragma(msg, typeof(a1));
> >>   pragma(msg, typeof(a2));
> >>   pragma(msg, typeof(a3));
> >>
> >>   auto b = [a1, a2, a3];
> >>   pragma(msg, typeof(b));
> >>
> >>   writeln("b:");
> >>   writeln(b);
> >>   writeln(b);  // <-- this one prints incorrectly
> >>
> >>   writeln("a:");
> >>   writeln(a1);
> >>   writeln(a2);
> >>   writeln(a3);
> >>
> >> }
> >>
> >> Output
> >> ==
> >>
> >> SortedRange!(int[], "a < b")
> >> SortedRange!(int[], "a < b")
> >> SortedRange!(int[], "a < b")
> >> SortedRange!(int[], "a < b")[]
> >> b:
> >> [[1, 2, 3, 4, 5], [8, 9, 9], [4, 4, 5, 5]]
> >> [[], [], []]
> >> a:
> >> [1, 2, 3, 4, 5]
> >> [8, 9, 9]
> >> [4, 4, 5, 5]
> >>
> >> The issue goes away if I cast 'b' to const before writeln. I
> >> think it is a bug, but maybe I am missing something?
> >
> > It's not a bug in writeln. Any time that a range is copied, you must not
> > do _anything_ else with the original unless copying it is equivalent to
> > calling save on it, because the semantics of copying a range are
> > unspecified. They vary wildly depending on the range type (e.g. copying
> > a dynamic array is equivalent to calling save, but copying a class
> > reference is not). When you pass the range to writeln, you must assumed
> > that it may have been consumed. And since you have range of ranges, you
> > must assume that the ranges that are contained may have been consumed.
> > If you want to pass them to writeln and then do anything else with
> > them, then you'll need to call save on every range involved (which is a
> > bit of a pain with a range of ranges, but it's necessary all the same).
>
> This is not necessarily true. It depends how the sub-ranges are returned.
>
> The bug is that formattedWrite takes ranges sometimes by ref, sometimes
> not.
>
> formattedWrite should call save on a forward range whenever it makes a
> copy, and it doesn't.
>
> Case in point, it doesn't matter if you call writeln(b.save), the same
> thing happens.

That's still not a bug in formattedWrite. save only duplicates the
outer-most range. And since writeln will ultimately iterate through the
inner ranges - which weren't saved - you end up with them being consumed.
When you're passing a range of ranges to a function, you need to recursively
save them if you don't want the inner ranges in the original range to be
consumed. Regardless of what formattedWrite does, it's a general issue with
any function that you pass a range of ranges. It comes right back to the
same issue of the semantics of copying ranges being unspecified and that you
therefore must always use save on any ranges involved if you want to then
use those ranges after having passed them to a function or copy them doing
anything else. It's that much more annoying when you're dealing with a range
of ranges rather than a range of something else, but the issue is the same.

- Jonathan M Davis





Re: file io

2018-09-06 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/6/18 2:30 PM, Steven Schveighoffer wrote:

On 9/6/18 1:07 PM, rikki cattermole wrote:

On 07/09/2018 4:17 AM, Arun Chandrasekaran wrote:

On Thursday, 6 September 2018 at 16:13:42 UTC, hridyansh thakur wrote:

how to read a file line by line in D


std.stdio.File.byLine()

Refer the doc here: 
https://dlang.org/library/std/stdio/file.by_line.html


An example from the doc:

```
import std.algorithm, std.stdio, std.string;
// Count words in a file using ranges.
void main()
{
 auto file = File("file.txt"); // Open for reading
 const wordCount = file.byLine()    // Read lines
   .map!split   // Split into words
   .map!(a => a.length) // Count words per line
   .sum();  // Total word count
 writeln(wordCount);
}
```


Ranges will be far too advanced of a topic to bring up at this stage.

So something a little more conventional might be a better option:

---
import std.file : readText;
import std.array : split;
import std.string : strip;

string text = readText("file.txt");
string[] onlyWords = text.split(" ");

uint countWords;
foreach(ref word; onlyWords) {
 word = word.strip();
 if (word.length > 0)
 countWords++;
}
---


Ugh, don't do that, it will read the unknown-length file into RAM all at 
once.


foreach(word; File("file.txt").byLine)
{
    word = word.strip();
    if(word.length > 0) countWords++;
}

That will buffer one line at a time and achieve the same results.


ugh, I didn't think this through. This works:

foreach(line; File("file.txt").byLine)
{
   foreach(word; line.split(" "))
   {
word = word.strip();
if(word.length > 0) countWords++;
   }
}

-Steve


Re: file io

2018-09-06 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/6/18 1:07 PM, rikki cattermole wrote:

On 07/09/2018 4:17 AM, Arun Chandrasekaran wrote:

On Thursday, 6 September 2018 at 16:13:42 UTC, hridyansh thakur wrote:

how to read a file line by line in D


std.stdio.File.byLine()

Refer the doc here: https://dlang.org/library/std/stdio/file.by_line.html

An example from the doc:

```
import std.algorithm, std.stdio, std.string;
// Count words in a file using ranges.
void main()
{
 auto file = File("file.txt"); // Open for reading
 const wordCount = file.byLine()    // Read lines
   .map!split   // Split into words
   .map!(a => a.length) // Count words per line
   .sum();  // Total word count
 writeln(wordCount);
}
```


Ranges will be far too advanced of a topic to bring up at this stage.

So something a little more conventional might be a better option:

---
import std.file : readText;
import std.array : split;
import std.string : strip;

string text = readText("file.txt");
string[] onlyWords = text.split(" ");

uint countWords;
foreach(ref word; onlyWords) {
 word = word.strip();
 if (word.length > 0)
     countWords++;
}
---


Ugh, don't do that, it will read the unknown-length file into RAM all at 
once.


foreach(word; File("file.txt").byLine)
{
   word = word.strip();
   if(word.length > 0) countWords++;
}

That will buffer one line at a time and achieve the same results.

-Steve


Re: Bug with writeln?

2018-09-06 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/6/18 12:55 PM, Jonathan M Davis wrote:

On Thursday, September 6, 2018 2:40:08 AM MDT Saurabh Das via Digitalmars-d-
learn wrote:

Is this a bug with writeln?

void main()
{
  import std.stdio, std.range, std.algorithm;

  auto a1 = sort([1,3,5,4,2]);
  auto a2 = sort([9,8,9]);
  auto a3 = sort([5,4,5,4]);

  pragma(msg, typeof(a1));
  pragma(msg, typeof(a2));
  pragma(msg, typeof(a3));

  auto b = [a1, a2, a3];
  pragma(msg, typeof(b));

  writeln("b:");
  writeln(b);
  writeln(b);  // <-- this one prints incorrectly

  writeln("a:");
  writeln(a1);
  writeln(a2);
  writeln(a3);

}

Output
==

SortedRange!(int[], "a < b")
SortedRange!(int[], "a < b")
SortedRange!(int[], "a < b")
SortedRange!(int[], "a < b")[]
b:
[[1, 2, 3, 4, 5], [8, 9, 9], [4, 4, 5, 5]]
[[], [], []]
a:
[1, 2, 3, 4, 5]
[8, 9, 9]
[4, 4, 5, 5]

The issue goes away if I cast 'b' to const before writeln. I
think it is a bug, but maybe I am missing something?


It's not a bug in writeln. Any time that a range is copied, you must not do
_anything_ else with the original unless copying it is equivalent to calling
save on it, because the semantics of copying a range are unspecified. They
vary wildly depending on the range type (e.g. copying a dynamic array is
equivalent to calling save, but copying a class reference is not). When you
pass the range to writeln, you must assumed that it may have been consumed.
And since you have range of ranges, you must assume that the ranges that are
contained may have been consumed. If you want to pass them to writeln and
then do anything else with them, then you'll need to call save on every
range involved (which is a bit of a pain with a range of ranges, but it's
necessary all the same).


This is not necessarily true. It depends how the sub-ranges are returned.

The bug is that formattedWrite takes ranges sometimes by ref, sometimes not.

formattedWrite should call save on a forward range whenever it makes a 
copy, and it doesn't.


Case in point, it doesn't matter if you call writeln(b.save), the same 
thing happens.


-Steve


Re: Slicing betterC

2018-09-06 Thread Jonathan M Davis via Digitalmars-d-learn
On Thursday, September 6, 2018 11:34:18 AM MDT Adam D. Ruppe via 
Digitalmars-d-learn wrote:
> On Thursday, 6 September 2018 at 17:10:49 UTC, Oleksii wrote:
> > struct Slice(T) {
> >
> >   size_t capacity;
> >   size_t size;
> >   T* memory;
> >
> > }
>
> There's no capacity in the slice, that is stored as part of the
> GC block, which it looks up with the help of RTTI, thus the
> TypeInfo reference.
>
> Slices *just* know their size and their memory pointer. They
> don't know how they were allocated and don't know what's beyond
> their bounds or how to grow their bounds. This needs to be
> managed elsewhere.
>
> If you malloc a slice in regular D, the capacity will be returned
> as 0 - the GC doesn't know anything about it. Any attempt to
> append to it will allocate a whole new block.
>
> In -betterC, there is no GC to look up at all, and thus it has
> nowhere to look. You'll have to make your own struct that stores
> capacity if you need it.
>
> I like to do something like
>
> struct MyArray {
>T* rawPointer;
>int capacity;
>int currentLength;
>
>// most user interaction will occur through this
>T[] opSlice() { return rawPointer[0 .. currentLength]; }
>
>// fill in other operators as needed
> }

To try to make this even clearer, a dynamic array looks basically like this
underneath the hood

struct DynamicArray(T)
{
size_t length;
T* ptr;
}

IIRC, it actually uses void* unfortunately, but that struct is basically
what you get. Notice that _all_ of the information that's there is the
pointer and the length. That's it. If you understand the semantics of what
happens when passing that struct around, you'll understand the semantics of
passing around dynamic arrays. And all of the operations that would have
anything to do with memory management involve the GC - capacity, ~, ~=, etc.
all require the GC. If you're not using -betterC, the fact that the dynamic
array was allocated with malloc is pretty irrelevant, since all of those
operations will function exactly the same as if the dynamic array were
allocated by the GC. It's just that because the dynamic array is not
GC-allocated, it's guaranteed that the capacity is 0, and therefore any
operations that would increase the arrays length then require reallocating
the dynamic array with the GC, whereas if it were already GC-allocated, then
its capacity might have been greater than its length, in which case,
reallocation would not be required.

If you haven't read it already, I would suggest reading this article:

https://dlang.org/articles/d-array-article.html

It does not use the official terminology, but in spite of that, it should
really help clarify things for you. The article refers to T[] as being a
slice (which is accurate, since it is a slice of memory), but it incorrectly
refers to the memory buffer itself as being the dynamic array, whereas the
language spec considers the T[] (the struct shown above) to be the dynamic
array. The language does not have a specific name for that memory buffer,
and it considers a T[] to be dynamic array regardless of what memory it
refers to. So, you should keep that in mind when reading the article, but
the concepts that it teaches are very much correct and should help a great
deal in understanding how dynamic arrays work in D.

- Jonathan M Davis





Re: Slicing betterC

2018-09-06 Thread Adam D. Ruppe via Digitalmars-d-learn

On Thursday, 6 September 2018 at 17:10:49 UTC, Oleksii wrote:

struct Slice(T) {
  size_t capacity;
  size_t size;
  T* memory;
}


There's no capacity in the slice, that is stored as part of the 
GC block, which it looks up with the help of RTTI, thus the 
TypeInfo reference.


Slices *just* know their size and their memory pointer. They 
don't know how they were allocated and don't know what's beyond 
their bounds or how to grow their bounds. This needs to be 
managed elsewhere.


If you malloc a slice in regular D, the capacity will be returned 
as 0 - the GC doesn't know anything about it. Any attempt to 
append to it will allocate a whole new block.


In -betterC, there is no GC to look up at all, and thus it has 
nowhere to look. You'll have to make your own struct that stores 
capacity if you need it.


I like to do something like

struct MyArray {
  T* rawPointer;
  int capacity;
  int currentLength;

  // most user interaction will occur through this
  T[] opSlice() { return rawPointer[0 .. currentLength]; }

  // fill in other operators as needed
}



Re: Slicing betterC

2018-09-06 Thread Oleksii via Digitalmars-d-learn

On Thursday, 6 September 2018 at 17:10:49 UTC, Oleksii wrote:


  allocatedFoo = foos[0 .. $ + 1];// <= Error: TypeInfo


This line meant to be `allocatedFoo = foos[$]`. Sorry about that.


Slicing betterC

2018-09-06 Thread Oleksii via Digitalmars-d-learn

Hi the folks,

Could you please share your wisdom with me? I wonder why the 
following code:

```
import core.stdc.stdlib;

Foo[] pool;
Foo[] foos;

auto buff = (Foo*)malloc(Foo.sizeof * 10);
pool = buff[0 .. 10];
foos = pool[0 .. 0 ];

// Now let's allocate a Foo:
Foo* allocatedFoo;
if (foos.length < foos.capacity) {// <= Error: TypeInfo 
cannot be used with -betterC
  allocatedFoo = foos[0 .. $ + 1];// <= Error: TypeInfo 
cannot be used with -betterC

}
```
fails to compile because of `foos.capacity` and `foos[0 .. $ + 
1]`. Why do these two innocent looking expressions require 
TypeInfo? Aren't slices basically fat pointers with internal 
structure that looks like this:

```
struct Slice(T) {
  size_t capacity;
  size_t size;
  T* memory;
}
```
?

It's weird that `TypeInfo` (being a run-time and reflection 
specific thing) is required in this particular case. Shouldn't 
static type checking be enough for all that?


Thanks in advance,
--
Oleksii


Re: file io

2018-09-06 Thread rikki cattermole via Digitalmars-d-learn

On 07/09/2018 4:17 AM, Arun Chandrasekaran wrote:

On Thursday, 6 September 2018 at 16:13:42 UTC, hridyansh thakur wrote:

how to read a file line by line in D


std.stdio.File.byLine()

Refer the doc here: https://dlang.org/library/std/stdio/file.by_line.html

An example from the doc:

```
import std.algorithm, std.stdio, std.string;
// Count words in a file using ranges.
void main()
{
     auto file = File("file.txt"); // Open for reading
     const wordCount = file.byLine()    // Read lines
   .map!split   // Split into words
   .map!(a => a.length) // Count words per line
   .sum();  // Total word count
     writeln(wordCount);
}
```


Ranges will be far too advanced of a topic to bring up at this stage.

So something a little more conventional might be a better option:

---
import std.file : readText;
import std.array : split;
import std.string : strip;

string text = readText("file.txt");
string[] onlyWords = text.split(" ");

uint countWords;
foreach(ref word; onlyWords) {
word = word.strip();
if (word.length > 0)
countWords++;
}
---


Re: linking trouble

2018-09-06 Thread rikki cattermole via Digitalmars-d-learn

On 07/09/2018 4:03 AM, hridyansh thakur wrote:

i am on windows i have tried
DMD
LDC

and i am getting same linking error with linking my c++ object

i am doing by the official tutorial (dlang spec book)

here is my app.d code

import std.stdio;

void main()
{
 //writeln("Edit source/app.d to start your project.");
 int[] m = someFUN(44,55);
 ulong k = m.length;

 for (int i=0;i

That definition isn't complete. Missing at the very least ``();`` to 
make it a function declaration.



here is the C++ code

#include 
#include 
#include 

FILE *fp;

int*file_io(){

char name[20] ;

std::cout << "please enter the file name " << '\n';
std::cin >> name;

   fp = fopen(name,"r+");
  char  a  = 'a';
   int  n  =  0 ;
   while (!feof(fp)) {
     a = fgetc(fp);
     if (a=='\n') {
   n++;
     }
   }

  int *p  = (int*)calloc(n,sizeof(int));
  for (size_t i = 0; i < n ; i++) {
    fscanf(fp,"%d",(p+i));
  }

return p;

}


So what is the errors you're getting?
And what are the commands you're executing?



Re: Bug with writeln?

2018-09-06 Thread Jonathan M Davis via Digitalmars-d-learn
On Thursday, September 6, 2018 2:40:08 AM MDT Saurabh Das via Digitalmars-d-
learn wrote:
> Is this a bug with writeln?
>
> void main()
> {
>  import std.stdio, std.range, std.algorithm;
>
>  auto a1 = sort([1,3,5,4,2]);
>  auto a2 = sort([9,8,9]);
>  auto a3 = sort([5,4,5,4]);
>
>  pragma(msg, typeof(a1));
>  pragma(msg, typeof(a2));
>  pragma(msg, typeof(a3));
>
>  auto b = [a1, a2, a3];
>  pragma(msg, typeof(b));
>
>  writeln("b:");
>  writeln(b);
>  writeln(b);  // <-- this one prints incorrectly
>
>  writeln("a:");
>  writeln(a1);
>  writeln(a2);
>  writeln(a3);
>
> }
>
> Output
> ==
>
> SortedRange!(int[], "a < b")
> SortedRange!(int[], "a < b")
> SortedRange!(int[], "a < b")
> SortedRange!(int[], "a < b")[]
> b:
> [[1, 2, 3, 4, 5], [8, 9, 9], [4, 4, 5, 5]]
> [[], [], []]
> a:
> [1, 2, 3, 4, 5]
> [8, 9, 9]
> [4, 4, 5, 5]
>
> The issue goes away if I cast 'b' to const before writeln. I
> think it is a bug, but maybe I am missing something?

It's not a bug in writeln. Any time that a range is copied, you must not do
_anything_ else with the original unless copying it is equivalent to calling
save on it, because the semantics of copying a range are unspecified. They
vary wildly depending on the range type (e.g. copying a dynamic array is
equivalent to calling save, but copying a class reference is not). When you
pass the range to writeln, you must assumed that it may have been consumed.
And since you have range of ranges, you must assume that the ranges that are
contained may have been consumed. If you want to pass them to writeln and
then do anything else with them, then you'll need to call save on every
range involved (which is a bit of a pain with a range of ranges, but it's
necessary all the same).

In many cases, you can get away with passing a range to a function or use it
with foreach and then continue to use it after that, but that's only because
copying those ranges is equivalent to calling save on them. It doesn't work
if any of the ranges involved aren't saved when they're copied, and it
doesn't work in generic code, because you have no clue whether the ranges
that are going to be used with that code are going to be saved when they're
copied.

- Jonathan M Davis





Re: Example of using C API from D?

2018-09-06 Thread Russel Winder via Digitalmars-d-learn
On Mon, 2018-09-03 at 11:41 +1200, rikki cattermole via Digitalmars-d-learn
wrote:
[…]
> 
> You won't need to actually fill out any c struct's that you don't need 
> either. Make them opaque as long as they are referenced via pointer and 
> not by value.

True. And indeed Fontconfig can mostly meet the "it's an opaque type based
system" but there are a few dark corners – most of which I need! 

[…]
> 
> Ugh, you do know that the linker which does all the hard work doesn't 
> know anything about the signature of the C function? That is the part 
> SharedLib replaces. You will of course define it with a proper signature 
> on D's side with a helpful cast :)

Not good enough to be honest, D is a statically typed language and so all
usage of functions should be checked against something other than a human
guess.

Anyway DStep has given me a Fontconfig D module that works nicely, and I will
check dpp as an alternative as soon as it builds on Debian Sid.
 
-- 
Russel.
===
Dr Russel Winder  t: +44 20 7585 2200
41 Buckmaster Roadm: +44 7770 465 077
London SW11 1EN, UK   w: www.russel.org.uk



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


Re: file io

2018-09-06 Thread Arun Chandrasekaran via Digitalmars-d-learn
On Thursday, 6 September 2018 at 16:13:42 UTC, hridyansh thakur 
wrote:

how to read a file line by line in D


std.stdio.File.byLine()

Refer the doc here: 
https://dlang.org/library/std/stdio/file.by_line.html


An example from the doc:

```
import std.algorithm, std.stdio, std.string;
// Count words in a file using ranges.
void main()
{
auto file = File("file.txt"); // Open for reading
const wordCount = file.byLine()// Read lines
  .map!split   // Split into words
  .map!(a => a.length) // Count words per 
line

  .sum();  // Total word count
writeln(wordCount);
}
```


file io

2018-09-06 Thread hridyansh thakur via Digitalmars-d-learn

how to read a file line by line in D



linking trouble

2018-09-06 Thread hridyansh thakur via Digitalmars-d-learn

i am on windows i have tried
DMD
LDC

and i am getting same linking error with linking my c++ object

i am doing by the official tutorial (dlang spec book)

here is my app.d code

import std.stdio;

void main()
{
//writeln("Edit source/app.d to start your project.");
int[] m = someFUN(44,55);
ulong k = m.length;

for (int i=0;i
#include 
#include 

FILE *fp;

int*file_io(){

char name[20] ;

std::cout << "please enter the file name " << '\n';
std::cin >> name;

  fp = fopen(name,"r+");
 char  a  = 'a';
  int  n  =  0 ;
  while (!feof(fp)) {
a = fgetc(fp);
if (a=='\n') {
  n++;
}
  }

 int *p  = (int*)calloc(n,sizeof(int));
 for (size_t i = 0; i < n ; i++) {
   fscanf(fp,"%d",(p+i));
 }

return p;

}





Re: hasAliasing with nested static array bug ?

2018-09-06 Thread SrMordred via Digitalmars-d-learn

On Thursday, 6 September 2018 at 07:37:11 UTC, Simen Kjærås wrote:

On Wednesday, 5 September 2018 at 22:35:16 UTC, SrMordred wrote:

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


Yup, that's a bug. Reduced example:

struct S {
int*[1] arr;
}
import std.traits : hasAliasing;
static assert(hasAliasing!S);


Issue filed: https://issues.dlang.org/show_bug.cgi?id=19228
Pull request: https://github.com/dlang/phobos/pull/6694

--
  Simen


Nice, thanks :)


Re: Meson issue with -L--export-dynamic flag

2018-09-06 Thread Russel Winder via Digitalmars-d-learn
On Mon, 2018-09-03 at 13:19 +, Gerald via Digitalmars-d-learn
wrote:
> Myself and some others are looking at replacing autotools in 
> Tilix with meson for the various Linux distros to use when 
> building and packaging the binary. However we are running into an 
> issue with meson around the use of the "-L--export-dynamic" flag.
> 

I have been using -L-Wl,--export-dynamic to get C symbols exported at
runtime with ldc2, I am nt sure if this datum helps any.
 
-- 
Russel.
===
Dr Russel Winder  t: +44 20 7585 2200
41 Buckmaster Roadm: +44 7770 465 077
London SW11 1EN, UK   w: www.russel.org.uk



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


Re: C++ GLM(OpenGL Mathematics) D Equivalent.

2018-09-06 Thread Guillaume Piolat via Digitalmars-d-learn

On Tuesday, 4 September 2018 at 19:23:16 UTC, SrMordred wrote:
Most C++ game related projects uses GLM as they default 
math/vector lib (even if not using opengl).


In D we have (that I found):

gfm.math  - https://github.com/d-gamedev-team/gfm
dlib.math - https://github.com/gecko0307/dlib
Gl3n  - https://github.com/Dav1dde/gl3n

But i'm not sure which to pick.

Can someone point me out some reasons to use one over the 
other? (or show some differences)


I´m expecting something of equivalent functions and performance 
as c++ glm.


Thank you!


It appears mine is the only one that is @nogc.


Re: Bug with writeln?

2018-09-06 Thread Simen Kjærås via Digitalmars-d-learn

On Thursday, 6 September 2018 at 09:06:21 UTC, Simen Kjærås wrote:
On Thursday, 6 September 2018 at 08:40:08 UTC, Saurabh Das 
wrote:

Is this a bug with writeln?


Yup. What happens is writeln destructively iterates over b[i]. 
Since b[i] is a forward range, this shouldn't be done 
destructively. Instead, a copy should be made using b[i].save, 
somewhere deep in Phobos' bowels.


For now, here's a workaround:

writeln(b.dup);
writeln(b); // Look ma, it works twice!

.dup creates a copy of the array, and the destructive iteration 
happens on the copy instead.


Issue: https://issues.dlang.org/show_bug.cgi?id=19229
PR: https://github.com/dlang/phobos/pull/6695


Re: Bug with writeln?

2018-09-06 Thread Simen Kjærås via Digitalmars-d-learn

On Thursday, 6 September 2018 at 08:40:08 UTC, Saurabh Das wrote:

Is this a bug with writeln?


Yup. What happens is writeln destructively iterates over b[i]. 
Since b[i] is a forward range, this shouldn't be done 
destructively. Instead, a copy should be made using b[i].save, 
somewhere deep in Phobos' bowels.


For now, here's a workaround:

writeln(b.dup);
writeln(b); // Look ma, it works twice!

.dup creates a copy of the array, and the destructive iteration 
happens on the copy instead.


--
  Simen


Bug with writeln?

2018-09-06 Thread Saurabh Das via Digitalmars-d-learn

Is this a bug with writeln?

void main()
{
import std.stdio, std.range, std.algorithm;

auto a1 = sort([1,3,5,4,2]);
auto a2 = sort([9,8,9]);
auto a3 = sort([5,4,5,4]);

pragma(msg, typeof(a1));
pragma(msg, typeof(a2));
pragma(msg, typeof(a3));

auto b = [a1, a2, a3];
pragma(msg, typeof(b));

writeln("b:");
writeln(b);
writeln(b);  // <-- this one prints incorrectly

writeln("a:");
writeln(a1);
writeln(a2);
writeln(a3);

}

Output
==

SortedRange!(int[], "a < b")
SortedRange!(int[], "a < b")
SortedRange!(int[], "a < b")
SortedRange!(int[], "a < b")[]
b:
[[1, 2, 3, 4, 5], [8, 9, 9], [4, 4, 5, 5]]
[[], [], []]
a:
[1, 2, 3, 4, 5]
[8, 9, 9]
[4, 4, 5, 5]

The issue goes away if I cast 'b' to const before writeln. I 
think it is a bug, but maybe I am missing something?




Re: How to understand context type of a delegate?

2018-09-06 Thread Kagamin via Digitalmars-d-learn
Maybe poke into GC and see if it has ClassInfo associated with 
the allocated block.


Re: hasAliasing with nested static array bug ?

2018-09-06 Thread Simen Kjærås via Digitalmars-d-learn

On Wednesday, 5 September 2018 at 22:35:16 UTC, SrMordred wrote:

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


Yup, that's a bug. Reduced example:

struct S {
int*[1] arr;
}
import std.traits : hasAliasing;
static assert(hasAliasing!S);


Issue filed: https://issues.dlang.org/show_bug.cgi?id=19228
Pull request: https://github.com/dlang/phobos/pull/6694

--
  Simen