Re: foreach statement: Are there no Iterators in D?

2015-11-08 Thread J.Frank via Digitalmars-d-learn
On Sunday, 8 November 2015 at 11:47:41 UTC, Rikki Cattermole 
wrote:
opApply if you want 0 .. N iterations during for a foreach 
statement and having it reset each time.


No, that won't help. I want to be able to iterate over a data set 
of infinite size.



Otherwise you want ranges :)

An input range is more or less an iterator as you would think 
of it.

You only need popFront, front and empty.


Ah yes, that's what I missed. Looks good. Thank you. :)



foreach statement: Are there no Iterators in D?

2015-11-08 Thread J.Frank via Digitalmars-d-learn

Hello,

I am looking for something like the "Iterator" Interface in Java 
or PHP.

Is there something comparable in D that can be used with foreach?

Thanks,

J.Frank



Re: std.variant.Algebraic, self referential types and delegate members

2015-11-08 Thread Panke via Digitalmars-d-learn
On Sunday, 8 November 2015 at 11:28:05 UTC, Jonathan M Davis 
wrote:
On Sunday, November 08, 2015 10:31:11 Panke via 
Digitalmars-d-learn wrote:

import std.variant, std.stdio;

---
struct NodeTypeA(T) { T[] children; }
struct NodeTypeB(T) { Tree children; }
struct Leaf(T) { T delegate() dg; }

alias Tree = Algebraic!(Leaf, NodeTypeA!This, NodeTypeB!This);

void main()
{
   Tree t;
}
---

yields

tmp.d(6): Error: functions cannot return opaque type This by 
value

tmp.d(8): Error: template instance tmp.Leaf!(This) error
instantiating

This limitation seems arbitrary to me. What's the reason here?


Okay. Several things here. For starters, NodeTypeA, NodeTypeB, 
and Leaf are not actually types. They're templates for types. 
If you want a type, you have to instantiate them. So, something 
like Algebraic!Leaf doesn't make any sense. You need an 
instantiation of Leaf - e.g. Algebraic!(Leaf!int) - rather than 
just Leaf.


My failure, I've played with the code while crafting the post. 
I've used

---
alias Tree = Algebraic!(Leaf!This, NoteTypeA!This, NoteTypeB!This)
---

So no templates, just types.

Next, you have a recursive template instantiation going on 
here. Tree depends on knowing what a NodeTypeB looks like, 
because it's using it in its instantiation of Algebraic. 
Algebraic!(Foo, Bar) is told to hold either a Foo or a Bar, 
which means that it needs to know their definitions - not just 
their names. You need to be using pointers if you want to be 
able to avoid having to know the actual definition of the type. 
So, when you tell NodeTypeB to hold a Tree when a Tree holds a 
NodeTypeB, it's impossible to figure out what the actual layout 
of those types. You have a recursive expansion.


If you want to have a recursive type definition, you _must_ use 
pointers so that the actual definition of the type is not 
required.


Thing is that delegate is nothing more than a glorified pair of 
pointers.


Also, I have no idea what the deal with the This in your code 
is. IIRC, there's a feature involving This with template 
definitions, but you're just using it outside of a template 
definition, so I don't know if that's legal.


It's a recent feature of Algebraic to allow recursive 
definitions. I'd assume that it uses pointers under the hood.


Older compiler but same error message: http://goo.gl/P0wmqe


Re: std.variant.Algebraic, self referential types and delegate members

2015-11-08 Thread Jonathan M Davis via Digitalmars-d-learn
On Sunday, November 08, 2015 10:31:11 Panke via Digitalmars-d-learn wrote:
> import std.variant, std.stdio;
>
> ---
> struct NodeTypeA(T) { T[] children; }
> struct NodeTypeB(T) { Tree children; }
> struct Leaf(T) { T delegate() dg; }
>
> alias Tree = Algebraic!(Leaf, NodeTypeA!This, NodeTypeB!This);
>
> void main()
> {
>Tree t;
> }
> ---
>
> yields
>
> tmp.d(6): Error: functions cannot return opaque type This by value
> tmp.d(8): Error: template instance tmp.Leaf!(This) error
> instantiating
>
> This limitation seems arbitrary to me. What's the reason here?

Okay. Several things here. For starters, NodeTypeA, NodeTypeB, and Leaf are
not actually types. They're templates for types. If you want a type, you
have to instantiate them. So, something like Algebraic!Leaf doesn't make any
sense. You need an instantiation of Leaf - e.g. Algebraic!(Leaf!int) -
rather than just Leaf.

Next, you have a recursive template instantiation going on here. Tree
depends on knowing what a NodeTypeB looks like, because it's using it in its
instantiation of Algebraic. Algebraic!(Foo, Bar) is told to hold either a
Foo or a Bar, which means that it needs to know their definitions - not just
their names. You need to be using pointers if you want to be able to avoid
having to know the actual definition of the type. So, when you tell
NodeTypeB to hold a Tree when a Tree holds a NodeTypeB, it's impossible to
figure out what the actual layout of those types. You have a recursive
expansion.

If you want to have a recursive type definition, you _must_ use pointers so
that the actual definition of the type is not required.

Also, I have no idea what the deal with the This in your code is. IIRC,
there's a feature involving This with template definitions, but you're just
using it outside of a template definition, so I don't know if that's legal.
But I'm also not at all familiar with what This actually does even if it's
used in the right place. So, maybe what you're doing with it is valid. I
question it, but I don't know enough to know for sure one way or the other.

Now, mucking around with your code, trying to see if I could get it to
compile, I suspect that Algebraic has something in its implementation that
doesn't play nicely with what you're trying to do (which may or may not
be a bug), but I don't know exactly what's going on. The error message I'm
getting (which does not match the one that you're getting) involves a
complaint about recursive template expansion, which implies that Algebraic
may need to know the definition of Foo even if you instantiate it with Foo*
- e.g. Algebraic!(Foo*), though I don't know why that would be the case.

The error that you're seeing implies that the code is trying to return a
type by value when it does not know the definition of the type, and that's
not going to work. To return a type by value, the compiler needs to know
what its layout is. So, that probably relates to trying to the recursive
expansion problem where the code ends up trying to use a NodeTypeB!This when
it doesn't know the layout of NodeTypeB!This yet, because it's trying to
define Tree, which requires that it know the definition of NodeTypeB!This...
So, it's likely that with whatever version of the compiler you're using,
you're just triggering a slightly different error than the version I'm using
hits, though the root cause is the same.

So, you need to change your types so that they're not actually recursively
defined (which almost certainly means using pointers), and Algebraic may or
may not actually be able to do what you want due to some aspect of its
current implementation.

- Jonathan M Davis



Re: foreach statement: Are there no Iterators in D?

2015-11-08 Thread Rikki Cattermole via Digitalmars-d-learn

On 09/11/15 12:40 AM, J.Frank wrote:

Hello,

I am looking for something like the "Iterator" Interface in Java or PHP.
Is there something comparable in D that can be used with foreach?

Thanks,

J.Frank


opApply if you want 0 .. N iterations during for a foreach statement and 
having it reset each time.


Otherwise you want ranges :)

An input range is more or less an iterator as you would think of it.
You only need popFront, front and empty. But here is the "official" 
interface. http://dlang.org/phobos/std_range_interfaces.html#InputRange
You can have structs an an input range, it is quite common since it 
doesn't allocate.


Re: Deprecation: module std.stream is deprecated

2015-11-08 Thread Spacen Jasset via Digitalmars-d-learn

On Sunday, 8 November 2015 at 08:29:30 UTC, BBaz wrote:

On Sunday, 8 November 2015 at 08:21:38 UTC, BBaz wrote:
On Saturday, 7 November 2015 at 13:52:29 UTC, Spacen Jasset 
wrote:

[...]
I have a used a template, because I cannot directly use the 
InputRange(char) interface as a type, and auto won't work 
either, so is there another parameter type I can use, such 
that I can have the concept of an abstract stream of bytes.


With the help of a template constraint you can abstract this. 
It looks like your problem is more getting the whole range 
since .byLine or .byChunk don't return the full stuff. Maybe 
use std.alsorithm.joiner. As you noted you can carry the 
iterator without knowing the type with auto, example:


---
import std.stdio;
import std.range, std.algorithm;

void main(string[] args)
{
auto inputRange = File(__FILE__).byChunk(1024).joiner;
Foo foo = Foo(inputRange);
}

struct Foo
{
this(T)(T t)
if (isInputRange!T && is(ElementType!T == ubyte))
{
foreach(byte b; t)
{
writef("0x%.2X ", b);
if (b == 0xA) writeln;
}
}
}
---


or even using an auto function:

---
import std.stdio;
import std.range, std.algorithm;

void main(string[] args)
{
auto inputRange0 = inputByteRange(File(__FILE__));
Foo foo0 = Foo(inputRange0);
ubyte[] arr = [1,2,3,4,5];
auto inputRange1 = inputByteRange(arr);
Foo foo1 = Foo(inputRange1);
}

auto inputByteRange(T)(auto ref T t)
{
static if (is(T == File))
return t.byChunk(1024).joiner;
else static if (is(T == ubyte[]))
return t;
else assert(0, "unsupported inputByteRange arg");
}

struct Foo
{
this(T)(T t)
if (isInputRange!T && is(ElementType!T == ubyte)){}
}
---


Thank you for your detailed replies, I shall try them out when I 
get a moment.


I would like to *winge* and say that it doesn't appear to be 
straight forward, or at least not obvious and clean to get the 
concept of an abstract steam working, which is to my mind a basic 
thing.


This looks the simplest solution at the moment:


auto inputRange = File(__FILE__).byChunk(1024).joiner;
Foo foo = Foo(inputRange);


But it doesn't seem efficient and strays off the conceptual path. 
In other words, why chunk things up, join them back, to get a 
stream? Perhaps the problem is that File is missing a .range() 
function?










Re: Deprecation: module std.stream is deprecated

2015-11-08 Thread BBasile via Digitalmars-d-learn

On Sunday, 8 November 2015 at 14:41:11 UTC, Spacen Jasset wrote:
But it doesn't seem efficient and strays off the conceptual 
path. In other words, why chunk things up, join them back, to 
get a stream?


`.byChunk` caches and `.joiner` hides this caching mechanism. 
Both operations happen under the hood "incrementally" while using 
the final input range because of lazy evaluation, so if your file 
is big, you are assured that only slices of N bytes (1024 in my 
example) will be loaded at once in the DRAM (unless you 
accumulate the whole thing later). This matches well to a "file 
stream concept", at least to read.


But as said in Jonathan M Davis's answer you can also read the 
whole file in a string or a ubyte[].



Perhaps the problem is that File is missing a .range() function?


Yes but this is a bit like this that phobos ranges and algorithms 
work. You have many independant low-level blocks with which you 
can compose rather than big classes that wrap everything. The 
whole standard library is organized around this.


std.stream was not compliant with this system and this is why 
"they" deprecated it (at least this is how I understood this).


Re: Error not callable with argument types but types matches

2015-11-08 Thread anonymous via Digitalmars-d-learn

On 08.11.2015 08:17, Sliya wrote:

I am on Mac OS, but I still don't get it. If the import was not
case-sensitive, I would not have any error since the good file would
have been loaded... Here I have no error saying file not found yet the
file is not loaded. I'd love to know what really happens.


The file system is case insensitive. That means when dmd opens noise.d 
or Noise.d it gets the same contents both times. So both `import noise;` 
and `import Noise;` succeed.


But the module name is case sensitive. `import noise;` results in a 
module `noise`, while `import Noise;` results in a module `Noise`. And 
they're not the same. They're different modules.


So when cell.d does `import Noise;` and perlin.d does `import noise;`, 
then they're using two different, incompatible Noise interfaces.


Re: foreach statement: Are there no Iterators in D?

2015-11-08 Thread rsw0x via Digitalmars-d-learn

On Sunday, 8 November 2015 at 11:57:16 UTC, J.Frank wrote:
On Sunday, 8 November 2015 at 11:47:41 UTC, Rikki Cattermole 
wrote:
opApply if you want 0 .. N iterations during for a foreach 
statement and having it reset each time.


No, that won't help. I want to be able to iterate over a data 
set of infinite size.



Otherwise you want ranges :)

An input range is more or less an iterator as you would think 
of it.

You only need popFront, front and empty.


Ah yes, that's what I missed. Looks good. Thank you. :)


FWIW since you mentioned Java, if you're accustomed to Java 8 
streams they're very similar to D's ranges.


Re: std.variant.Algebraic, self referential types and delegate members

2015-11-08 Thread Meta via Digitalmars-d-learn

On Sunday, 8 November 2015 at 10:31:13 UTC, Panke wrote:

import std.variant, std.stdio;

---
struct NodeTypeA(T) { T[] children; }
struct NodeTypeB(T) { Tree children; }
struct Leaf(T) { T delegate() dg; }

alias Tree = Algebraic!(Leaf, NodeTypeA!This, NodeTypeB!This);

void main()
{
  Tree t;
}
---

yields

tmp.d(6): Error: functions cannot return opaque type This by 
value
tmp.d(8): Error: template instance tmp.Leaf!(This) error 
instantiating


This limitation seems arbitrary to me. What's the reason here?


The issue is because your delegate inside Leaf returns a T by 
value, and T in this case is
the type std.variant.This; it's an opaque struct type to allow 
for recursive structures. If it sees This* or This[] in the 
template argument list to Algebraic, it'll do some magic to 
replace this with another Variant. That magic is 
std.typecons.ReplaceType[1]. However, note the warning on 
ReplaceType:


"However, member types in `struct`s or `class`es are not replaced 
because there

are no ways to express the types resulting after replacement."

And thus it can't replace the T return type of your delegate with 
the proper type. The compiler sees that you're trying to return 
the opaque struct This by value and violently disagrees with that 
notion, refusing to compile. To make that particular compiler 
error go away you can change the return type of the delegate to 
T* or T[], but that's not particularly useful as you're still 
just returning a pointer to This, not the recursive type. I'm not 
completely sure what you're trying to do is possible in D, and 
definitely not without enhancements to ReplaceType.



1. 
https://github.com/D-Programming-Language/phobos/blob/245c7ab0b591cb48b3dbb239640dd54e0717110a/std/typecons.d#L6643


Re: Cannot use local 'i' as parameter to non-global template

2015-11-08 Thread Nicholas Wilson via Digitalmars-d-learn

On Saturday, 7 November 2015 at 15:04:41 UTC, maik klein wrote:

template IsSame(T){
  template As(alias t){
enum As = is(T : typeof(t));
  }
}
void main()
{
  int i;
  enum b = IsSame!int.As!(i);
}

Err:

Error: template instance As!(i) cannot use local 'i' as 
parameter to non-global template As(alias t) dmd failed with 
exit code 1

I don't understand the error message.

I also tried

template IsSame(T){
  enum As(alias t) = is(T : typeof(t));
}

Which results in

Error: template app.IsSame!int.As cannot deduce function from 
argument types !()(int), candidates are: source/app.d(50,8):

app.IsSame!int.As(alias t)

What am I doing wrong?

Ps: Also posted on SO 
https://stackoverflow.com/questions/33584130/cannot-use-local-i-as-parameter-to-non-global-template not sure where people usually ask questions about D.


Two ways to go about doing this

template IsSame(T,U)
{
 enum IsSame = is(T : U)
}

or make i a "global" by using a template
alias Identity(T) = T;

 template IsSame(T){
   enum As(alias t) = is(T : typeof(t));
}

enum b = IsSame!int.As!Identity!(i);


std.variant.Algebraic, self referential types and delegate members

2015-11-08 Thread Panke via Digitalmars-d-learn

import std.variant, std.stdio;

---
struct NodeTypeA(T) { T[] children; }
struct NodeTypeB(T) { Tree children; }
struct Leaf(T) { T delegate() dg; }

alias Tree = Algebraic!(Leaf, NodeTypeA!This, NodeTypeB!This);

void main()
{
  Tree t;
}
---

yields

tmp.d(6): Error: functions cannot return opaque type This by value
tmp.d(8): Error: template instance tmp.Leaf!(This) error 
instantiating


This limitation seems arbitrary to me. What's the reason here?


Re: Why my app require MSVCR120.dll?

2015-11-08 Thread thedeemon via Digitalmars-d-learn

On Sunday, 8 November 2015 at 05:11:50 UTC, suliman wrote:

On Sunday, 8 November 2015 at 04:50:49 UTC, thedeemon wrote:

On Saturday, 7 November 2015 at 10:03:58 UTC, Suliman wrote:


I am using DMD.


-m64 or -m32mscoff ?


Without any keys. I use dub for building


I suspect your issue is caused by botan library on which vibe-d 
depends:

http://code.dlang.org/packages/botan
It says it needs MS linker on Windows and so most probably 
depends on MSVC runtime.
Usually when you build something with DMD without -m64 or 
-m32mscoff it makes a binary without such dependencies, it uses 
its own C library (snn.lib) statically linked.


phobos: What type to use instead of File when doing I/O on streams?

2015-11-08 Thread J.Frank via Digitalmars-d-learn

Hello again,

I'm a bit puzzled by the "File" type. Looking at the 
implementation, it seems that all I/O functions were stuffed into 
a single class^H^H^H^H^Hstruct.
What I expected to find is some kind of "Stream" class (with 
read(), write(), eof()), which is extended by a "File" class 
(with seek(), mmap(), etc.).


So, assuming my program reads from stdin and is supposed to work 
on a file as well as on a pipe (which is not seekable) - how can 
I make the compiler bark when I accidently use stdin.seek()?


Am I missing something here, too?



Re: std.range.only with different range types

2015-11-08 Thread Jakob Ovrum via Digitalmars-d-learn

On Sunday, 8 November 2015 at 19:57:34 UTC, Freddy wrote:

---
import std.algorithm;
import std.range;
import std.stdio;

void main(){
only(iota(0,4),[1,4,5]).writeln;
}
---
How can I call std.range.only with different range types?


`only` is for creating a range from a list of values. iota(0, 4) 
and [1, 4, 5] are already ranges. Maybe you want to use 
std.range.chain?


assert(iota(1, 3).chain([3, 4]).equal([1, 2, 3, 4]));


Re: phobos: What type to use instead of File when doing I/O on streams?

2015-11-08 Thread J.Frank via Digitalmars-d-learn

On Sunday, 8 November 2015 at 21:57:55 UTC, Alex Parrill wrote:

Post what you're trying to do if you want an example.


$ cat test.d
import std.stdio;

//void foo(Stream in_stream, Stream out_stream) // I want 
something like this

void foo(File in_stream, File out_stream)
{
in_stream.seek(3); // BUG

string line;
while ((line = in_stream.readln()) !is null)
out_stream.write(line);
}

void main(string[] args)
{
foo(stdin, stdout);
}
$ cat test.txt
Line 0
Line 1
Line 2
$ gdc -o test test.d
$ ./test 

std.range.only with different range types

2015-11-08 Thread Freddy via Digitalmars-d-learn

---
import std.algorithm;
import std.range;
import std.stdio;

void main(){
only(iota(0,4),[1,4,5]).writeln;
}
---
How can I call std.range.only with different range types?


Re: phobos: What type to use instead of File when doing I/O on streams?

2015-11-08 Thread Alex Parrill via Digitalmars-d-learn

On Sunday, 8 November 2015 at 20:47:08 UTC, J.Frank wrote:

Hello again,

I'm a bit puzzled by the "File" type. Looking at the 
implementation, it seems that all I/O functions were stuffed 
into a single class^H^H^H^H^Hstruct.
What I expected to find is some kind of "Stream" class (with 
read(), write(), eof()), which is extended by a "File" class 
(with seek(), mmap(), etc.).


So, assuming my program reads from stdin and is supposed to 
work on a file as well as on a pipe (which is not seekable) - 
how can I make the compiler bark when I accidently use 
stdin.seek()?


Am I missing something here, too?


Use ubyte/char input ranges. Post what you're trying to do if you 
want an example.


Re: Preferred behavior of take() with ranges (value vs reference range)

2015-11-08 Thread TheFlyingFiddle via Digitalmars-d-learn

On Monday, 9 November 2015 at 02:14:58 UTC, Jon D wrote:
Here's an example of the behavior differences below. It uses 
refRange, but same behavior occurs if the range is created as a 
class rather than a struct.

--Jon


This is an artifact of struct based ranges being value types. 
When you use take the range get's copied into another structure 
that is also a range but limits the number of elements you take 
from that range.


Basically: take looks something like this: (simplified)

struct Take(Range)
{
   size_t count;
   Range  range;

   @property ElementType!Range front() { return range.front; }
   @property bool empty() { return count == 0 || range.empty; }
   void popFront() { count--; range.popFront; }
}

Code like this:

auto fib1 = ...

//Here fib1 get's copied into first5.
auto first5 = Take(5, fib);

So later when you perform actions on first5 you no longer take 
any action on fib1 but instead take action on the copied range 
inside of first5. Hence you don't see any consumption of fib1's 
elements.


However when you use a refRange / a class the Take range will 
take a reference / pointer to the actual range. So now your no 
longer working a copy of the range but on the range itself. As 
you reuse the same range you will see that consumption has 
occured.


If you want a more indepth explanation there were two talks at 
Dconf this year that (in part) discussed this topic. 
(https://www.youtube.com/watch?v=A8Btr8TPJ8c, 
https://www.youtube.com/watch?v=QdMdH7WX2ew=PLEDeq48KhndP-mlE-0Bfb_qPIMA4RrrKo=14)


Re: phobos: What type to use instead of File when doing I/O on streams?

2015-11-08 Thread Adam D. Ruppe via Digitalmars-d-learn

On Sunday, 8 November 2015 at 20:47:08 UTC, J.Frank wrote:
So, assuming my program reads from stdin and is supposed to 
work on a file as well as on a pipe (which is not seekable) - 
how can I make the compiler bark when I accidently use 
stdin.seek()?


You don't, in general. stdin is sometimes seekable and the 
compiler doesn't know if it is or not until you try at runtime.


You could write a wrapper struct for File though that @disables 
the seek function. It would have a File member, alias file this;, 
a constructor that forwards to it (optionally, you could also 
construct it as a File and assign it), and then a @disabled 
function with the same signature as the seek call in File. Then, 
it will no longer compile as long as you use your wrapper.


Preferred behavior of take() with ranges (value vs reference range)

2015-11-08 Thread Jon D via Digitalmars-d-learn

Just started looking at D, very promising!

One of the first programs I constructed involved infinite 
sequences. A design question  that showed up is whether to 
construct the range as a struct/value, or class/reference. It 
appears that structs/values are more the norm, but there are 
exceptions, notably refRange. I'm wondering if there are any 
community best practices or guidelines in this area.


One key difference is the behavior of take(). If the range is a 
value/struct, take() does not consume elements. If it's a 
ref/class, it does consume elements. From a consistency 
perspective, it'd seem useful if the behavior was consistent as 
much as possible.


Here's an example of the behavior differences below. It uses 
refRange, but same behavior occurs if the range is created as a 
class rather than a struct.


import std.range;
import std.algorithm;

void main() {
auto fib1 = recurrence!((a,n) => a[n-1] + a[n-2])(1, 1);
auto fib2 = recurrence!((a,n) => a[n-1] + a[n-2])(1, 1);
auto fib3 = refRange();

// Struct/value based range - take() does not consume elements
assert(fib1.take(7).equal([1, 1, 2, 3, 5, 8, 13]));
assert(fib1.take(7).equal([1, 1, 2, 3, 5, 8, 13]));
fib1.popFrontN(7);
assert(fib1.take(7).equal([21, 34, 55, 89, 144, 233, 377]));

// Reference range (fib3) - take() consumes elements
assert(fib2.take(7).equal([1, 1, 2, 3, 5, 8, 13]));
assert(fib3.take(7).equal([1, 1, 2, 3, 5, 8, 13]));
assert(fib3.take(7).equal([21, 34, 55, 89, 144, 233, 377]));
assert(fib2.take(7).equal([610, 987, 1597, 2584, 4181, 6765, 
10946]));
assert(fib2.take(7).equal([610, 987, 1597, 2584, 4181, 6765, 
10946]));

}

--Jon


Associative arrays

2015-11-08 Thread TheFlyingFiddle via Digitalmars-d-learn
I have a few questions about the pseudo built in associative 
arrays.


1. Is it possible to have the built in associative array use a 
custom allocator from std.experimental.allocator to service it's 
allocation needs?


2. A while ago I read on the newsgroup a while back that there 
was a plan to make it possible for a user to swap out the 
standard associative array implementation by modifying druntime 
and or implementing some linker functions. Have this been done 
yet? And if so what must I do to swap the implementation?


Re: Confusion about dynamically and lexically scoped closures

2015-11-08 Thread ParticlePeter via Digitalmars-d-learn

On Sunday, 8 November 2015 at 23:17:06 UTC, Jakob Ovrum wrote:
The closures for delegates in D1 are never automatically copied 
to the heap, while in D2 this is done when it's determined that 
the delegate might outlive one of its upvalues.


So, I think it's safe to say we have lexical closures in D2 but 
only dynamic closures in D1 and the language specification is 
out of date.


Thanks, makes sens, I assumed a typo in the docs.


Confusion about dynamically and lexically scoped closures

2015-11-08 Thread ParticlePeter via Digitalmars-d-learn

Hi,
the confusion starts here: http://dlang.org/function.html#closures
End of paragraph bellow the last delegate example:
"This combining of the environment and the function is called a 
dynamic closure."


While according to 
https://en.wikipedia.org/wiki/Scope_%28computer_science%29
"Lexical scope vs. dynamic scope" I would call D delegates 
lexical closures, as the scope of the callee (scope where callee 
is defined) is used for free variable lookup, isn't that right?


Confusion is enhanced with this Dlang wiki: 
http://wiki.dlang.org/Function_literals
"This has brought up the specter of Dynamic Closures. The nested 
and/or anonymous functions can only access dynamic scope, which 
means scope that exists on the stack at the time of execution. 
This differs from lexical scope, which refers to the scope as 
indicated by the program text structure."


So what's what now?

Cheers, ParticlePeter


Parse d source file by using compiler

2015-11-08 Thread tcak via Digitalmars-d-learn
I checked for a flag in this page http://dlang.org/dmd-linux.html 
, but couldn't have found any for this purpose.


Is there a way to parse a d source file so it generates a tree in 
JSON, XML, or something-that-can-be-processed-easily file format?


---

My real purpose:

I need to generate hash code (e.g. MD5) for a part of source code 
(let's say a class, struct, or a function). So whether the codes 
are changed or not can be detected. As you will guess, comments, 
text formatting etc. shouldn't affect the hash result.



Use-Case:

I am writing a code generator/back up system. It will check the 
last available code file. If important changes are done in a 
specific part of code, it will increase version number by 1.


Re: Associative arrays

2015-11-08 Thread Rikki Cattermole via Digitalmars-d-learn

On 09/11/15 4:57 PM, TheFlyingFiddle wrote:

I have a few questions about the pseudo built in associative arrays.

1. Is it possible to have the built in associative array use a custom
allocator from std.experimental.allocator to service it's allocation needs?


Nope.


2. A while ago I read on the newsgroup a while back that there was a
plan to make it possible for a user to swap out the standard associative
array implementation by modifying druntime and or implementing some
linker functions. Have this been done yet? And if so what must I do to
swap the implementation?


As far as I'm aware, you are stuck using e.g. structs to emulate AA 
behavior.
I have a VERY basic implementation here: 
https://github.com/rikkimax/alphaPhobos/blob/master/source/std/experimental/internal/containers/map.d

Feel free to steal.


Re: Preferred behavior of take() with ranges (value vs reference range)

2015-11-08 Thread Jon D via Digitalmars-d-learn

On Monday, 9 November 2015 at 02:44:48 UTC, TheFlyingFiddle wrote:

On Monday, 9 November 2015 at 02:14:58 UTC, Jon D wrote:
Here's an example of the behavior differences below. It uses 
refRange, but same behavior occurs if the range is created as 
a class rather than a struct.

--Jon


This is an artifact of struct based ranges being value types. 
When you use take the range get's copied into another structure 
that is also a range but limits the number of elements you take 
from that range.


...

If you want a more indepth explanation there were two talks at 
Dconf this year that (in part) discussed this topic. 
(https://www.youtube.com/watch?v=A8Btr8TPJ8c, 
https://www.youtube.com/watch?v=QdMdH7WX2ew=PLEDeq48KhndP-mlE-0Bfb_qPIMA4RrrKo=14)


Thanks for the quick reply. The two videos were very helpful. I 
understood what was happening underneath (mostly), but the videos 
made it clear there are a number of open questions regarding 
reference and value ranges and how best to use them.


Re: Parse d source file by using compiler

2015-11-08 Thread Rikki Cattermole via Digitalmars-d-learn

On 09/11/15 6:49 PM, tcak wrote:

I checked for a flag in this page http://dlang.org/dmd-linux.html , but
couldn't have found any for this purpose.

Is there a way to parse a d source file so it generates a tree in JSON,
XML, or something-that-can-be-processed-easily file format?

---

My real purpose:

I need to generate hash code (e.g. MD5) for a part of source code (let's
say a class, struct, or a function). So whether the codes are changed or
not can be detected. As you will guess, comments, text formatting etc.
shouldn't affect the hash result.


Use-Case:

I am writing a code generator/back up system. It will check the last
available code file. If important changes are done in a specific part of
code, it will increase version number by 1.


There is a json output, but it hasn't been all that maintained.
Use something like DScanner, instead.


Re: Parse d source file by using compiler

2015-11-08 Thread BBasile via Digitalmars-d-learn

On Monday, 9 November 2015 at 05:49:25 UTC, tcak wrote:
I checked for a flag in this page 
http://dlang.org/dmd-linux.html , but couldn't have found any 
for this purpose.


Is there a way to parse a d source file so it generates a tree 
in JSON, XML, or something-that-can-be-processed-easily file 
format?


---

My real purpose:

I need to generate hash code (e.g. MD5) for a part of source 
code (let's say a class, struct, or a function). So whether the 
codes are changed or not can be detected. As you will guess, 
comments, text formatting etc. shouldn't affect the hash result.



Use-Case:

I am writing a code generator/back up system. It will check the 
last available code file. If important changes are done in a 
specific part of code, it will increase version number by 1.


You could write your own tool using libdparse[1]: parse, visit 
the AST, create a signature for the declarations that are 
interesting.


---
https://github.com/Hackerpilot/libdparse


Re: Associative arrays

2015-11-08 Thread rsw0x via Digitalmars-d-learn
On Monday, 9 November 2015 at 04:29:30 UTC, Rikki Cattermole 
wrote:

On 09/11/15 4:57 PM, TheFlyingFiddle wrote:

[...]


Nope.


[...]


As far as I'm aware, you are stuck using e.g. structs to 
emulate AA behavior.
I have a VERY basic implementation here: 
https://github.com/rikkimax/alphaPhobos/blob/master/source/std/experimental/internal/containers/map.d

Feel free to steal.


Fwiw, EMSI provides high quality containers backed by 
std.experimental.allocator.

https://github.com/economicmodeling/containers




dbgVerifySorted is not nothrow

2015-11-08 Thread Panke via Digitalmars-d-learn

I've updated my compiler and ran into this regression:

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

Code:

---
import std.algorithm, std.container;

void main()
{
static bool compare(P a, P b)
{
return a.curColumn < b.curColumn;
}
Array!P a = make!(Array!P);
sort!compare(a[]);
}

struct P
{
int curColumn = 0;
}
---

Result:
/usr/include/dlang/dmd/std/algorithm/sorting.d(982): Error: 
template instance std.range.assumeSorted!(compare, 
RangeT!(Array!(P))) error instantiating
tmp.d(10):instantiated from here: sort!(compare, 
cast(SwapStrategy)0, RangeT!(Array!(P)))

1 tobias@akela ~ [i] % dmd -debug tmp.d
/usr/include/dlang/dmd/std/range/package.d(7189): Error: 
'std.range.SortedRange!(RangeT!(Array!(P)), 
compare).SortedRange.dbgVerifySorted' is not nothrow
/usr/include/dlang/dmd/std/algorithm/sorting.d(982): Error: 
template instance std.range.assumeSorted!(compare, 
RangeT!(Array!(P))) error instantiating
tmp.d(10):instantiated from here: sort!(compare, 
cast(SwapStrategy)0, RangeT!(Array!(P)))


What I don't understand is, why dbgVerifySorted has to be nothrow 
in the first place. Is that an new requirement for contracts? I 
couldn't find any hint in the language spec.





Re: Deprecation: module std.stream is deprecated

2015-11-08 Thread BBaz via Digitalmars-d-learn

On Saturday, 7 November 2015 at 13:52:29 UTC, Spacen Jasset wrote:

[...]
I have a used a template, because I cannot directly use the 
InputRange(char) interface as a type, and auto won't work 
either, so is there another parameter type I can use, such that 
I can have the concept of an abstract stream of bytes.


With the help of a template constraint you can abstract this. It 
looks like your problem is more getting the whole range since 
.byLine or .byChunk don't return the full stuff. Maybe use 
std.alsorithm.joiner. As you noted you can carry the iterator 
without knowing the type with auto, example:


---
import std.stdio;
import std.range, std.algorithm;

void main(string[] args)
{
auto inputRange = File(__FILE__).byChunk(1024).joiner;
Foo foo = Foo(inputRange);
}

struct Foo
{
this(T)(T t)
if (isInputRange!T && is(ElementType!T == ubyte))
{
foreach(byte b; t)
{
writef("0x%.2X ", b);
if (b == 0xA) writeln;
}
}
}
---




Re: Deprecation: module std.stream is deprecated

2015-11-08 Thread BBaz via Digitalmars-d-learn

On Sunday, 8 November 2015 at 08:21:38 UTC, BBaz wrote:
On Saturday, 7 November 2015 at 13:52:29 UTC, Spacen Jasset 
wrote:

[...]
I have a used a template, because I cannot directly use the 
InputRange(char) interface as a type, and auto won't work 
either, so is there another parameter type I can use, such 
that I can have the concept of an abstract stream of bytes.


With the help of a template constraint you can abstract this. 
It looks like your problem is more getting the whole range 
since .byLine or .byChunk don't return the full stuff. Maybe 
use std.alsorithm.joiner. As you noted you can carry the 
iterator without knowing the type with auto, example:


---
import std.stdio;
import std.range, std.algorithm;

void main(string[] args)
{
auto inputRange = File(__FILE__).byChunk(1024).joiner;
Foo foo = Foo(inputRange);
}

struct Foo
{
this(T)(T t)
if (isInputRange!T && is(ElementType!T == ubyte))
{
foreach(byte b; t)
{
writef("0x%.2X ", b);
if (b == 0xA) writeln;
}
}
}
---


or even using an auto function:

---
import std.stdio;
import std.range, std.algorithm;

void main(string[] args)
{
auto inputRange0 = inputByteRange(File(__FILE__));
Foo foo0 = Foo(inputRange0);
ubyte[] arr = [1,2,3,4,5];
auto inputRange1 = inputByteRange(arr);
Foo foo1 = Foo(inputRange1);
}

auto inputByteRange(T)(auto ref T t)
{
static if (is(T == File))
return t.byChunk(1024).joiner;
else static if (is(T == ubyte[]))
return t;
else assert(0, "unsupported inputByteRange arg");
}

struct Foo
{
this(T)(T t)
if (isInputRange!T && is(ElementType!T == ubyte)){}
}
---


Re: dbgVerifySorted is not nothrow

2015-11-08 Thread BBaz via Digitalmars-d-learn

On Sunday, 8 November 2015 at 08:05:41 UTC, Panke wrote:

I've updated my compiler and ran into this regression:

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

[...]


reopened.