Re: Reducing Pegged ASTs

2014-11-25 Thread Philippe Sigaud via Digitalmars-d-learn
On Tue, Nov 25, 2014 at 4:12 PM, Nordlöw
digitalmars-d-learn@puremagic.com wrote:
 Is there a way to (on the fly) reduce Pegged parse results such as

 C [0, 6][int, x, ;]
  +-C.TranslationUnit [0, 6][int, x, ;]
 +-C.ExternalDeclaration [0, 6][int, x, ;]
+-C.Declaration [0, 6][int, x, ;]
   +-C.DeclarationSpecifiers [0, 4][int]
   |  +-C.TypeSpecifier [0, 4][int]
   +-C.InitDeclaratorList [4, 5][x]
  +-C.InitDeclarator [4, 5][x]
 +-C.Declarator [4, 5][x]
+-C.DirectDeclarator [4, 5][x]
   +-C.Identifier [4, 5][x]

 to

 C [0, 6][int, x, ;]
  +-C.TranslationUnit [0, 6][int, x, ;]
 +-C.ExternalDeclaration [0, 6][int, x, ;]
+-C.Declaration [0, 6][int, x, ;]
   +-C.TypeSpecifier [0, 4][int]
   +-C.Identifier [4, 5][x]

 and still, when needed, be able query that C.Identifier is an instance of
 C.DirectDeclarator etc?

The reducing can be done, either with operators or semantic actions.
IIRC there is a free function in Pegged that does it.
I did not automate it, because every time I cut down severely a parse
tree, I later regret it because I lost information that way.

Cutting while still retaining original info (who is this node's
ancestor) is more difficult: you would have to store it somewhere
anyhow. You cannot create node classes to represent the hierarchy,
because of loops in the grammar: an Identifier can have many different
ancestors.

Note also that Pegged produces parse trees (complete parsing
information), not ASTs. ASTs would indeed be much smaller, but we
would have to define what are the master nodes in the D grammar.

 If not this seems like a cool feature to have ;)

 I guess it would reduce memory requirements by about a magnitude right?

If you want to remember the intermediate nodes you cut down, not
really, since you still need to store them somehow.

I think what's consuming memory right now is that I duplicate the
matched strings at each level, even concatenating them at the higher
levels. I should let them only in the 'leaves' of the tree (heck, like
an AST).

Halas, I've no free time to code anything in D these days... but of
course, feel free to push any pull request you might have!



Re: accessing numeric template parameters

2014-11-03 Thread Philippe Sigaud via Digitalmars-d-learn
On Mon, Nov 3, 2014 at 3:27 PM, Dominikus Dittes Scherkl via
Digitalmars-d-learn digitalmars-d-learn@puremagic.com wrote:
 If I have a struct with numeric template parameter, how can I access it
 within member functions? Like normal member variables? And how about the
 constructor?

 struct polynomial(uint base)
 {
 private:
uint[] N;
 public:
this(uint x) { base = x; }

base is part of the type. polynomial is just a 'recipe' for a type,
the real struct would be Polynomial!(0), Polynomial!(1), etc. Note
that Polynomial!0, Polynomial!1, ... are all different types.

Being part of the type means it's defined only at compile-time, you
cannot use a runtime value (like 'x') to initialize it.

Note that with your current code, `base' is not visible outside
Polynomial. You can alias it to a field to make it visible:

struct Polynomial(uint base)
{
alias b = base; // b is visible outside (but set at compile-time !)
...
}

You can create one like this:

Polynomial!2 poly;
poly.N = [0,1,0,0,1,1];

assert(poly.b == 2);

Of course, you cannot change b: `poly.b = 3;' is forbidden.


Re: how to expand tuple?

2014-11-02 Thread Philippe Sigaud via Digitalmars-d-learn
Any time you want to return or store a group of values of different types.

In a way, tuples are just structs without a name (anonymous structs,
if you will).

Say you have function `foo' and want it to return an int and a string.
In D, you cannot do:

(int, string) foo() { ...  return (3, abc);}

But you can do:

import std.typecons: tuple;
auto foo() { return tuple(3, abc);}

Which is more or less equivalent to:

struct FooReturn { int i; string s;}
FooReturn foo() { return FooReturn(3, abc);}


`Tuple' and its associated factory function `tuple' is just the
standard way to group values together in Phobos. You'll see some
functions returning Tuples, for example. Some D constructs also
recognize std.typecons.Tuple and deal with it elegantly. By defining
you own struct (like `FooReturn' in the previous example), you gain
some control on your code (you can define how people can interact with
FooReturn, you can test for it, etc), but you also lose the
possibility of easy interaction with some parts of Phobos.


Re: how to expand tuple?

2014-11-01 Thread Philippe Sigaud via Digitalmars-d-learn
On Sat, Nov 1, 2014 at 9:34 PM, Suliman via Digitalmars-d-learn
digitalmars-d-learn@puremagic.com wrote:
 Few questions.

 1. In examples tuples are created with keyword auto. Can I create them with
 another keyword. Or auto mean structure of data, that have not standard type
 like (int or string)?

`tuple' is a function defined in the std.typecons module. It's a
helper function to create Tuple!(T...), a templated struct acting as a
tuple.

Don't forget the type will depend on the types of the arguments, so:

auto tup = tuple(1.0, abc, [2,3]);

contains a float, a string and an array of int's, so it's type is
Tuple!(float, string, int[]):

Tuple!(float, string, int[]) tup = tuple(1.0, abc, [2,3]);

It's a bit long to type, so most people prefer using `auto' for such
declarations.




 2. How ti expend tuple? I tried to do:

auto imglist = tuple(aaa);
imglist.expand[sss];
writeln(imglist);

 but got very strange error:
 app.d(30): Error: cannot implicitly convert expression (sss) of type
 string to  uint

Expand, you mean, as in appending to a tuple? It can be done, but it
will create a new type.

First, tup.expand gives you access to the 'raw' tuple ( a template
parameter list, to be precise) underneath Tuple!(T...). The returned
value can be indexed, sliced and its length is known at compile time.

Continuing with my example:

auto first = tup.expand[0]; // 1.0
auto slice = tup.expand[1..$]; // (abc, [2,3])
auto len = tup.expand.length; // 3, since tup has three elements.

That explains the error you get: imglist.expand is a bit like a
vector: it can be indexed, but with uint, not with a string. I thought
you were expanding it, but to the compiler you were trying to index
using a string.


If you really want to append to a tuple, you must create a new
variable, since the augmented tuple will have a different type:

auto tup2 = tuple(tup.expand, 'd'); // tup2 == (1.0, abc, [2,3], 'd')

The type of tup2 is then Tuple!(float, string, int[], char)


Note that, in your case, as you're using only strings, an array of
strings would probably be easier to use.


Re: how to expand tuple?

2014-11-01 Thread Philippe Sigaud via Digitalmars-d-learn
 I thought you were expanding it

Drat. *You* thought you were expanding it.


Re: How to pack types with variables in one message to send it to another thread? [tuple]

2014-09-07 Thread Philippe Sigaud via Digitalmars-d-learn
You can also create new types:

struct UseSprite { string s;}
struct UseAnimation { string s;}


 It's not a class instance, it's a class type. Something like
 `cast(Sprite) null` in parameters. It can be replaced by string
 Sprite, but in this case I can't use receive() as it is. E.g.

 send(tid,gameobjectId,Sprite,reload);
 //must call sprite.reload();

You could use:

sent(tid, gameobjectId, UseSprite(reload));

 send(tid,gameobjectId,Animation,reload);
 //must call animation.reload();

sent(tid, gameobjectId, UseAnimation(reload));

Another way, if you have way to determine that gameobjectId points to
an animation or a sprite, would be to define a struct name Reload {}
and then:

sent(tid, gameobjectId, Reload());



Third way: if Animation.reload() and Sprite.reload() are static methods:

send(tid, gameobjectId, Sprite.reload);



 But both messages are (int, string, string) so they can't be separate by
 different receiving functions. It will be better if messages was (int,
 Sprite, string) / (int, Animation, string). And it solves my problem. :)
 But I don't know how to achieve this.

See my proposal: define your message as types, directly, and load them
for any data necessary for the call.
UseAnimation(reload), or whatever.


Re: literate programming in D

2014-09-04 Thread Philippe Sigaud via Digitalmars-d-learn
 Ah that sounds interesting too! Immediately I start thinking in terms like
 tidlywiki http://tiddlywiki.com/ or something similar, I guess the emacs way
 described earlier also would support this. I personally always enjoy reading
 the readthedocs stuff http://docs.readthedocs.org/en/latest/ is that the
 sort of stuff you mean?

Tiddlywiki is interesting, but I'm really talking about the way LP was
used by Knuth WEB/CWEB in his explanation of TeX and METAFONT.
The Wikipedia article explains it pretty well
(http://en.wikipedia.org/wiki/Literate_programming)

You write a document combining documentation and code. Then two
different programs (weave and ? for WEB) create the resulting
documentation for one (HTML, pdf, whatever) and the code (a .d file)
for another.


I discovered LP through the incredible book Physically-based
Ray-Tracing. The book is one program, explained and documented using
literate progamming. It's an incredible achievement (1000+ pages of
explanations!).
See:

www.pbrt.org

and more precisely:

http://www.pbrt.org/chapters/pbrt_chapter7.pdf

The code begins at page 18 of the pdf.

For example, at page 22:

Sample Method Definitions ≡
Sample::Sample(SurfaceIntegrator *surf, VolumeIntegrator *vol,
const Scene *scene) {
surf-RequestSamples(this, scene);
vol-RequestSamples(this, scene);
Allocate storage for sample pointers 301
Compute total number of sample values needed 302
Allocate storage for sample values 302
}

The snippet Sample Method Definitions introduces three new snippets,
that will be explained elsewhere. Other snippets might also use the
same references, if needed.

It's not complicated to write a D tool for that, I did that some time
ago. Once you define your begin/end token for snippet definitions, you
can parse them to extract the way they are linked.



Re: How to build dlang.org dd files

2014-08-31 Thread Philippe Sigaud via Digitalmars-d-learn
 dmd -c -o- macros.ddoc doc.ddoc -Df{ddoc_filename}.html {ddoc_filename}.dd

 If someone knows of a more official syntax, please let me know.

I don't know of another syntax, but could you please put this
somewhere on the wiki?
Maybe in the cookbook section:

http://wiki.dlang.org/Cookbook


Re: alias and mixin

2014-08-31 Thread Philippe Sigaud via Digitalmars-d-learn
 It is basically just an annoying grammar limitation that does not allow to
 use mixin / __traits as an identifier.

The usual helper template:

```
alias helper(alias a) = a;
```

helps for aliasing __traits and anonymous function templates (x =
x+1), but I don't see an easy solution for mixin inside the current
language, apart from pushing the mixin outside.


Re: alias and mixin

2014-08-31 Thread Philippe Sigaud via Digitalmars-d-learn
 I recommend slightly more generic form:

 template Alias(T...)
 if (T.length == 1)
 {
 alias Alias = T[0];
 }

 it is quite helpful in templated code to be able to alias _anything_

That's what I use also, but didn't want another thread on the (T...)
if (T.length ==1) trick :)



 But yeah, no fun for mixins :(

Mainly, I slap them in my code, then slowly migrate them outwards (in
'head' position) until that compiles...


Re: literate programming in D

2014-08-30 Thread Philippe Sigaud via Digitalmars-d-learn

On Sat, Aug 30, 2014 at 1:37 AM, nikki wrote:
I wasn't too happy about it and I wrote my own little parse 
thingie and have

a literate version nice and meta and small and sloppy ;)

http://nikkikoole.github.io/docs/dokidokDOC.html

I use it to change my d sourcefile slightly (into valid 
markdown)
then I use a node module (ghmd) to make sortof sexy html from 
that.


Nice. Maybe you could strip the initial whitespaces in the code 
parts: due to blocks, your code lines are shifting to the right. 
If you document something that's inside a method inside a class, 
you're bound to have problems :)



Right now, you're documenting your code in a linear way. That's 
good, but for me, most of LP is based around the idea of naming 
snippets and referring to them in code, to be explained elsewhere:


```
Here is the main loop:

Main=
void main() {
Initialize Variables
Precompute State
foreach(i; 0..max) {
Do Computation
}
}

Before doing all this, we need to initialize the variables:

Initialize Variables= ...
```

Of course, snippets can refer to other snippets, recursively.

Do you have any plan to go there?


Re: literate programming in D

2014-08-30 Thread Philippe Sigaud via Digitalmars-d-learn

On Friday, 29 August 2014 at 23:58:19 UTC, Chris Cain wrote:
I used https://www.npmjs.org/package/literate-programming (+ 
pandoc) to do this when writing 
https://dl.dropboxusercontent.com/u/2206555/uniformUpgrade.pdf 
in markdown.


Do you remember if some snippets can be hidden in the final 
documented output (I don't find that in this package)?
I know the goal of LP is to explain your code, but I remember 
using that with other systems: that's useful when you don't want 
to show some plumbing (for a tutorial for example, where you want 
to concentrate on the main suject).




Re: getting the adress of a function by its name in string format

2014-08-30 Thread Philippe Sigaud via Digitalmars-d-learn
 instead I would like to use EAT_FOOD_DECISION and EAT_FOOD_BEHAVIOUR and
 get the functions?

 Is that possible somehow?

If all your functions had the same signature, you could use an
associative array  FunctionType[string] and initialize it:

FunctionType[string] myFuncs;
myFuncs[EAT_FOOD_DECISION] = EAT_FOOD_DECISION;

But it seems they have different types?


Re: Variadic parameter of length 1

2014-08-20 Thread Philippe Sigaud via Digitalmars-d-learn
On Wed, Aug 20, 2014 at 5:34 PM, Dominikus Dittes Scherkl via
Digitalmars-d-learn digitalmars-d-learn@puremagic.com wrote:
 On Wednesday, 20 August 2014 at 15:26:14 UTC, monarch_dodra wrote:

 AFAIK, it's a historical workaround to accept T as either alias or not
 alias, as varargs have auto alias. EG:

 foo!int //OK
 foo!hello //OK too


 Ah, ok.
 And why historical? Is that not necessary anymore? What better solution is
 there today?

No better solution that I know of.

alias template parameters (alias a) match symbols (names, user-defined
types) whereas type parameter (T) match only pure types.

So when we need to match anything, we use (T...) if (T.length == 1)


Re: No Output with shebang.

2014-08-20 Thread Philippe Sigaud via Digitalmars-d-learn
 gdc just compiles the program to a.out. It doesn't run the
 resulting executable. You need to use something like rdmd instead
 of gdc. rdmd compiles to some temporary location and then runs
 the executable.


 Wow, that was fast. Thanks a lot!

Can compiler switches be used with the shebang notation? If yes, there
is certainly a GDC flag (-run?) that tells it to run the generated
executable.


Re: iterate traits ?

2014-08-19 Thread Philippe Sigaud via Digitalmars-d-learn
 A foreach becomes compile-time whenever the aggregate is a purely compile-
 time construct such as a tuple.

Yeah, I think you transformed it into a runtime array by using [ ...
]. Tuples with compatible types can be 'downgraded' to arrays that
way. But there is no need to: tuples are iterable, indexable and
slice-able in D.

import std.stdio;

struct Vertex {float[3] position; float[3] normal;}

void main() {
foreach(e; __traits(allMembers, Vertex)) {
alias tt = typeof(__traits(getMember, Vertex, e)); // worksforme
writeln(tt.sizeof);

}
}


Re: @safe, pure and nothrow at the beginning of a module

2014-08-16 Thread Philippe Sigaud via Digitalmars-d-learn
 If I understand correctly Adam Ruppe's Cookbook, by putting

 @safe:
 pure:
 nothrow:

 at the beginning of a module, I distribute it on all definitions, right?
 Even methods, inner classes, and so on?

I read Adam's book again and I was wrong:

Chapter 7, p. 173:

You may add @safe: to the top of your module and aggregate
definitions to apply the annotation to all function that follows,
instead of writing it on each individual function.

So, first, he's talking only about @safe (though I suppose it works
the same for all annotations) and he says: *and aggregate
definitions*. We indeed need to put annotations inside aggregates to
affect their innards.

If that's true, I have a lot of annotation sprinkling to do.


Re: @safe, pure and nothrow at the beginning of a module

2014-08-16 Thread Philippe Sigaud via Digitalmars-d-learn
On Sat, Aug 16, 2014 at 1:30 PM, Artur Skawina via Digitalmars-d-learn
digitalmars-d-learn@puremagic.com wrote:
 On 08/16/14 13:18, Philippe Sigaud via Digitalmars-d-learn wrote:
 We indeed need to put annotations inside aggregates to
 affect their innards.

 If that's true, I have a lot of annotation sprinkling to do.

 It's not true for @safe, but true for some other attributes.

 http://forum.dlang.org/post/mailman.125.1397731134.2763.digitalmar...@puremagic.com

Okay...

So @safe includes child scopes. I suppose @trusted and @system work in
the same way.

*but*

nothrow, @nogc and UDA's do not include child scopes. Putting them at
the beginning of a module will not affect methods in aggregates...

What's the situation for pure? (I don't have a D compiler handy right
now, or I would test it myself).


Re: @safe, pure and nothrow at the beginning of a module

2014-08-16 Thread Philippe Sigaud via Digitalmars-d-learn
Artur:
 @safe, @trusted, @system, shared, immutable, const, inout and `extern (...)`
 affect child scopes. `synchronized` does too, but in a rather unintuitive
 way; hopefully nobody uses this. ;)

Well, I also hope no one uses inout: at the module level?

 Other attributes, including 'pure' and 'nothrow' only affect symbols
 in the current scope.

There we are. Good to know, thanks.


Re: Appender is ... slow

2014-08-15 Thread Philippe Sigaud via Digitalmars-d-learn
 Quick test...

Ah, thanks a lot Jonathan. I kept telling me I should probably test it
on a simple case.
OK, the good news is, Appender works in these cases (I mean, that's
good news for Phobos).
Now, I just have to find out why it's slower in my case :)



 
 import std.array;
 import std.datetime;
 import std.stdio;

 enum size = 1000;

 void test1()
 {
 auto arr = appender!(int[])();
 foreach(n; 0 .. size)
 arr.put(n);
 }


I used ~= to append to an Appender. The examples use .put, but ~= is
documented so I considered the operator was just syntax sugar. I
didn't have a look at its implementation.


 void test2()
 {
 int[] arr;
 foreach(n; 0 .. size)
 arr ~= n;
 }

 void test3()
 {
 auto arr = new int[](size);
 foreach(n; 0 .. size)
 arr[n] = n;
 }

This one is simple and interesting. In my case I don't know the length
in advance (I'm doing some parsing and predicting the size of the
parse forest based on the input length is somewhat tricky), but I can
pre-allocate some, based on a simple heuristics.

 void test4()
 {
 auto arr = uninitializedArray!(int[])(size);
 foreach(n; 0 .. size)
 arr[n] = n;
 }

Oh, I didn't know this one.


 With size being 1000, I get

 178 ms, 229 μs, and 4 hnsecs
 321 ms, 272 μs, and 8 hnsecs
 27 ms, 138 μs, and 7 hnsecs
 24 ms, 970 μs, and 9 hnsecs

Same here, good.
Using ~= n instead of .put(n) gives me results consistently slightly
slower for Appender (170 ms - 190 ms, repeatedly, even going back and
forth between the two possibilities.
I created a test1prime to test that.


 With size being 100,000, I get

 15 secs, 731 ms, 499 μs, and 1 hnsec
 29 secs, 339 ms, 553 μs, and 8 hnsecs
 2 secs, 602 ms, 385 μs, and 2 hnsecs
 2 secs, 409 ms, 448 μs, and 9 hnsecs

Ditto. OK, that's good. Also, it's still slower with using Appender ~=
n instead of Appender.put. (18s instead of 15, 20% slower)
So, kids: don't do that.

 So, it looks like using Appender to create an array of ints is about twice
 as fast as appending to the array directly, and unsurprisingly, creating the
 array at the correct size up front and filling in the values is far faster
 than either, whether the array's elements are default-initialized or not.
 And the numbers are about the same if it's an array of char rather than an
 array of int.

Perfect. That also means my go-to method will still be using standard
arrays, but with pre-allocation.
I just feel stupid writing that, because it's obvious that reserving
things should give it better speed.


 Also, curiously, if I add a test which is the same as test2 (so it's just
 appending to the array) except that it calls reserve on the array with size,
 the result is almost the same as not reserving. It's a smidgeon faster but
 probably not enough to matter. So, it looks like reserve doesn't buy you
 much for some reason. Maybe the extra work for checking whether it needs to
 reallocate or whatever fancy logic it has to do in ~= dwarfs the extra cost
 of the reallocations? That certainly seems odd to me, but bizarrely, the
 evidence does seem to say that reserving doesn't help much. That should
 probably be looked into.

Yeah, I get a small boost of 5% compared to not reserving at size
1000, which completely disappears for longer arrays.
(No different for size 100_000).


 In any case, from what I can see, if all you're doing is creating an array
 and then throwing away the Appender, it's faster to use Appender than to
 directly append to the array.

Indeed.

 Maybe that changes with structs? I don't know.

I'm using classes, because what I'm pushing into the Appender are
graph nodes and I got fed up with tracing pointer to strucs
everywhere. Maybe I should change back to structs and see what it
does.


 It would be interesting to know what's different about your code that's
 causing Appender to be slower, but from what I can see, it's definitely
 faster to use Appender unless you know the target size of the array up
 front.

Good conclusion. Thanks for your help. My takeaway idea is that I'll
use arrays, but 'new T[](size)' them before. If that makes heavy
concatenation 10 times faster, it should have a positive effect (I'm
not of course waiting for anything near a 10x boost in my computation
time).



Re: Appender is ... slow

2014-08-15 Thread Philippe Sigaud via Digitalmars-d-learn
 I wonder if using plain `Array` instead may be result in better performance
 where immutability is not needed.

Hmm, no:

module appendertest;

import std.array;
import std.datetime;
import std.stdio;
import std.container;

enum size = 1_000;

void test1()
{
auto arr = appender!(int[])();
foreach(n; 0 .. size)
arr.put(n);
}

void test1prime()
{
auto arr = appender!(int[])();
foreach(n; 0 .. size)
arr ~= n;
}

void test2()
{
int[] arr;
foreach(n; 0 .. size)
arr ~= n;
}

void test2prime()
{
int[] arr;
arr.reserve(size);
foreach(n; 0 .. size)
arr ~= n;
}

void test3()
{
Array!int arr;
foreach(n; 0 .. size)
arr ~= n;
}

void test3prime()
{
Array!int arr;
arr.reserve(size);
foreach(n; 0 .. size)
arr ~= n;
}

void test4()
{
auto arr = new int[](size);
foreach(n; 0 .. size)
arr[n] = n;
}

void test5()
{
auto arr = uninitializedArray!(int[])(size);
foreach(n; 0 .. size)
arr[n] = n;
}

void main()
{
auto result = benchmark!(test1, test1prime,
 test2, test2prime,
 test3, test3prime,
 test4,
 test5
)(10_000);

writeln(Appender.put   :, cast(Duration)result[0]);
writeln(Appender ~=:, cast(Duration)result[1]);
writeln(Std array  :, cast(Duration)result[2]);
writeln(Std array.reserve  :, cast(Duration)result[3]);
writeln(Array  :, cast(Duration)result[4]);
writeln(Array.reserve  :, cast(Duration)result[5]);
writeln(new T[]()  :, cast(Duration)result[6]);
writeln(uninitializedArray :, cast(Duration)result[7]);
}

Times:

Appender.put   :157 ms, 602 μs, and 3 hnsecs
Appender ~=:182 ms, 807 μs, and 1 hnsec
Std array  :256 ms, 210 μs, and 7 hnsecs
Std array.reserve  :244 ms, 770 μs, and 4 hnsecs
Array  :336 ms, 207 μs, and 3 hnsecs
Array.reserve  :321 ms, 500 μs, and 6 hnsecs
new T[]()  :28 ms, 496 μs, and 6 hnsecs
uninitializedArray :26 ms and 620 μs



Re: Appender is ... slow

2014-08-15 Thread Philippe Sigaud via Digitalmars-d-learn
On Thu, Aug 14, 2014 at 11:33 PM, Joseph Rushton Wakeling via
Digitalmars-d-learn digitalmars-d-learn@puremagic.com wrote:
 On 14/08/14 19:16, Philippe Sigaud via Digitalmars-d-learn wrote:

 Do people here get good results from Appender? And if yes, how are you
 using it?


 An example where it worked for me:
 http://braingam.es/2013/09/betweenness-centrality-in-dgraph/

 (You will have to scroll down a bit to get to the point where appenders get
 introduced.)

I remember reading this and loving it! Any news on this? Do you have
new algorithms?


Re: Appender is ... slow

2014-08-15 Thread Philippe Sigaud via Digitalmars-d-learn
 It is very different with better compiler though :

 $ ldmd2 -release -O a.d
 $ ./appendertest
 Appender.put   :378 ms, 794 μs, and 9 hnsecs
 Appender ~=:378 ms, 416 μs, and 3 hnsecs
 Std array  :2 secs, 222 ms, 256 μs, and 2 hnsecs
 Std array.reserve  :2 secs, 199 ms, 64 μs, and 5 hnsecs
 Array  :349 ms and 250 μs
 Array.reserve  :347 ms, 694 μs, and 1 hnsec
 new T[]()  :37 ms, 989 μs, and 8 hnsecs
 uninitializedArray :39 ms, 333 μs, and 3 hnsecs

 (size 10_000)

OK, same here, except std array gives me only 1.4 s, while the other
timings are about the same. (0.14 alpha2 : ldmd2 -O -inline).
Drat, that means testing on many different compilers. Oh well, let's
start small: pre-allocating, better algorithms, then I'll do real
speed instrumentation.



Re: Appender is ... slow

2014-08-15 Thread Philippe Sigaud via Digitalmars-d-learn
On Fri, Aug 15, 2014 at 1:57 PM, Messenger via Digitalmars-d-learn
digitalmars-d-learn@puremagic.com wrote:

 T[size] beats all of those on dmd head, though it is inarguably a
 bit limiting.

I confirm (even with 2.065). With ldc2 it's optimized out of the way,
so it gives 0 hnsecs :-)
Hmm, what about a sort of linked list of static arrays, that allocates
a new one when necessary?


Re: Appender is ... slow

2014-08-15 Thread Philippe Sigaud via Digitalmars-d-learn
Well, I created a wrapper around a std.array.uninitializedArray 
call, to manage the interface I need (queue behavior: pushing at 
the end, popping at the beginning). When hitting the end of the 
current array, it either reuse the current buffer or create a new 
one, depending of the remaining capacity.


On the 'synthetic' benchmarks, it performs quite reasonably: half 
the time of  Array or Appender (twice faster), 5x faster than 
standard array, and 3-4x slower than uninitializedArray.


And... It does not change the timings in my code, it even makes 
things slower when pre-allocating to much. Only by pre-allocating 
only a few elements do I get back the original timings.


So, I guess I'm suffering from a bad case of premature 
optimization :)


I thought that, having lots of concatenation in my code, that'd 
be a bottleneck. But it appears than pre-allocation does not give 
me any speed-up.


Well, at least it got me thinking, testing LDC a bit more and 
learning things on Array and Appender ;)


Thank for your help guys, it's now time for the -profile switch 
again...




@safe, pure and nothrow at the beginning of a module

2014-08-15 Thread Philippe Sigaud via Digitalmars-d-learn

So I'm trying to use @safe, pure and nothrow.

If I understand correctly Adam Ruppe's Cookbook, by putting

@safe:
pure:
nothrow:

at the beginning of a module, I distribute it on all definitions, 
right? Even methods, inner classes, and so on?


Because I did just that on half a dozen of modules and the 
compiler did not complain. Does that mean my code is clean(?) or 
that what I did has no effect?




Re: Appender is ... slow

2014-08-15 Thread Philippe Sigaud via Digitalmars-d-learn

On Friday, 15 August 2014 at 16:48:10 UTC, monarch_dodra wrote:
On Friday, 15 August 2014 at 14:40:36 UTC, Philippe Sigaud 
wrote:
Well, I created a wrapper around a 
std.array.uninitializedArray call, to manage the interface I 
need


Make sure you don't use that if your type has elaborate 
construction, or assumes a certain initial state (unless you 
are actually emplacing your objects of course).


Hmm, what's elaborate construction? They are classes and have 
constructors, of course. I assumed that this produced only null's 
in the array.



I thought that, having lots of concatenation in my code, 
that'd be a bottleneck. But it appears than pre-allocation 
does not give me any speed-up.


If you are using raw GC arrays, then the raw append 
operation will, outweigh the relocation cost on extension. So 
pre-allocation wouldn't really help in this situation (though 
the use of Appender *should*)



OK.


Re: @safe, pure and nothrow at the beginning of a module

2014-08-15 Thread Philippe Sigaud via Digitalmars-d-learn
In another module I marked as '@safe:' at the top, the compiler told
me that a class opEquals could not be @safe (because Object.opEquals
is @system).

So it seems that indeed a module-level '@safe:' affects everything,
since a class method was found lacking.

(I put a @trusted attribute on it).


Re: Appender is ... slow

2014-08-15 Thread Philippe Sigaud via Digitalmars-d-learn
On Fri, Aug 15, 2014 at 10:04 PM, John Colvin via Digitalmars-d-learn
digitalmars-d-learn@puremagic.com wrote:

 compiler, version, OS, architecture, flags?

Compiler: DMD 2.065 and LDC 0.14
OS: Linux 64bits (8 cores, but there is no parallelism here)
flags: -O -release -inline (and -noboundscheck for DMD)


 Have you looked at the assembly to check that all the Appender method calls
 are being inlined?

I do not know how to look at the assembly, neither do I know how to
see if Appender method calls are being inlined.

I did spend some time with -profile and gained a nice 10% increase in
speed with that, fighting bottlenecks in my code.


Re: Appender is ... slow

2014-08-14 Thread Philippe Sigaud via Digitalmars-d-learn
 I don't know much about Phobos appender implementation details but the key
 thing with reusable buffer is avoid freeing them. AFAIR Appender.clear frees
 the allocated memory but `Appender.length = 0` does not, making it possible
 to just overwrite stuff again and again.

I call .clear() only at the beginning of the computation, to avoid any
strange effects with std.datetime.benchmark (using benchmark with
memoizing functions can lead to strange results if one does not take
care to flush any result between to calls.)
After that initial call to clear, I just append.

The thing is, it's not the first time it happens. For years, I tried
to use Appender to get faster code, to no avail.


btw, I saw your Dconf talk yesterday, nice content! And thanks for
talking about Pegged!
It might interest you to know that the code I'm trying to use Appender
on is a new engine for Pegged, based on GLL parsing, that should be
able to produce a parser for any grammar, even ambiguous ones.


Re: Appender is ... slow

2014-08-14 Thread Philippe Sigaud via Digitalmars-d-learn
 I've never really tried to benchmark it, but it was my understanding that
 the idea behind Appender was to use it to create the array when you do that
 via a lot of appending, and then you use it as a normal array and stop using
 Appender.

That's how I use it, yes.

 It sounds like you're trying to use it as a way to manage reusing
 the array, and I have no idea how it works for that.

There is a misunderstanding there: I'm using clear only to flush the
state at the beginning of the computation. The Appender is a class
field, used by the class methods to calculate. If I do not clear it at
the beginning of the methods, I keep appending new results to old
computations, which is not what I want. But really, calling clear is a
minor point: I'm interested in Appender's effect on *one* (long,
concatenation-intensive) computation.

 I've
 never actually benchmarked it for just creating arrays via appending. I'd
 just assumed that it was faster than just using ~=, because that's what it's
 supposedly for. But maybe I just completely misunderstood what the point of
 Appender was.

I don't know. People here keep telling newcomers to use it, but I'm
not convinced by its results. Maybe I'm seeing worse results because
my arrays are do not have millions of elements and Appender shines for
long arrays?


Re: Appender is ... slow

2014-08-14 Thread Philippe Sigaud via Digitalmars-d-learn
 There is a misunderstanding there: I'm using clear only to flush the
 state at the beginning of the computation. The Appender is a class
 field, used by the class methods to calculate. If I do not clear it at
 the beginning of the methods, I keep appending new results to old
 computations, which is not what I want. But really, calling clear is a
 minor point: I'm interested in Appender's effect on *one* (long,


 This is exactly what I propose to change - set `length` to 0 instead of
 calling `clear`. That way you will keep using same memory chunk simply
 abandoning its old state at the beginning of each computation.

You mean by using the shrinkTo method? (Appender does not have a
length, that's a bit of a bother btw).
I just did, it does not change anything. Too bad.

Heck, my code is simpler to read and use *and* faster by using a
bog-standard D array. I'll keep my array for now :)


Re: Appender is ... slow

2014-08-14 Thread Philippe Sigaud via Digitalmars-d-learn
 Thanks! Repeating what I have mentioned during DConf talk - have you ever
 considered proposing Pegged for Phobos inclusion? It feels like important
 bit of infrastructure to me.

At the time, it was considered (rightfully) far too slow and
memory-hogging. I think having a generic lexer and a standard D parser
in Phobos would already be a great step forward.


Re: Are Delimited strings and HereDoc strings just here to suck ?

2014-08-11 Thread Philippe Sigaud via Digitalmars-d-learn
On Mon, Aug 11, 2014 at 10:09 PM, H. S. Teoh via Digitalmars-d-learn
digitalmars-d-learn@puremagic.com wrote:
 On Mon, Aug 11, 2014 at 07:47:44PM +, Klaus via Digitalmars-d-learn wrote:
 I mean when writing a D lexer, you necessarly reach the moment when
 you think:

 Oh no! is this feature just here to suck ?


 The crazy variety of ways to write string literals in D, OTOH, *is* a
 bit over the top, as I found out myself when I also tried writing a D
 lexer.  :-P

Out of curiosity, how does a lexer deal with heredocs? It's a sort
of... user-defined token, right?


Re: Are Delimited strings and HereDoc strings just here to suck ?

2014-08-11 Thread Philippe Sigaud via Digitalmars-d-learn
On Mon, Aug 11, 2014 at 10:58 PM, H. S. Teoh via Digitalmars-d-learn
digitalmars-d-learn@puremagic.com wrote:

 In Flex, one way you can implement heredocs is to have a separate mode
 where the lexer is scanning for the ending string.  So basically you
 have a sub-lexer that treats the heredoc as three tokens, one that
 defines the ending string for the heredoc (which is never returned to
 the caller), one that contains the content of the heredoc, and the
 terminating token (also never returned to the caller).

Ah, a small, specialized sub-lexer. OK, I get it.


Re: How to easily construct objects with multi-param constructors from lazy ranges?

2014-08-06 Thread Philippe Sigaud via Digitalmars-d-learn
 Yea, but that won't work for forward ranges. It only provides opIndex if the
 underlying range provides it. Since the chunk size is a runtime parameter it
 can't implement opIndex efficiently for non-random access ranges.

But in your case, your range is random-access, no?

Or else, you can always map array on the chunks...


 staticChunks was a bit of a misnomer. staticTake would be a better name. The
 range would contains a static array and pops that number of elements from
 the input range. Then, opIndex can easily be defined.

What about takeExactly?


Re: Help with porting grammar from PEGjs to D for dustjs project!

2014-08-06 Thread Philippe Sigaud via Digitalmars-d-learn
On Wed, Aug 6, 2014 at 9:09 AM, Uranuz via Digitalmars-d-learn
digitalmars-d-learn@puremagic.com wrote:
 What I was thinking about is possibility to change ParseTree struct with
 user-defined version of it. And I was thinking about setting tree type as
 template parameter to grammar:

 grammar!(MyParseTree)(
 Arithmetic:
...
 );



That's already the case, look at

https://github.com/PhilippeSigaud/Pegged/blob/master/pegged/parser.d

on line 134, for example.

struct GenericPegged(TParseTree)
{
...
}

And then, the library alias a standard version (line 1531):

alias GenericPegged!(ParseTree).Pegged Pegged;

Which means the customer-facing Pegged parser is in fact a generic
parser specialized on ParseTree. But you can substitute your own parse
tree.

That's of course the same for all parsers: GenericXXX(TParseTree)
{...} and then alias XXX = GenericXXX!(ParseTree);


But you're right, it's not really documented and I don't have a
template checking whether TParseTree respect some static inferface.
This parameterization was asked by someone on github, but I don't
think they used it finally.

ParseTree is described here:

https://github.com/PhilippeSigaud/Pegged/wiki/Parse-Trees


Maybe we can continue this thread by private mail? I'm not sure people
on the D list are that interested by the internals of a library.


Re: Inner struct accessing host member

2014-08-06 Thread Philippe Sigaud via Digitalmars-d-learn
 hmmm static and private... other keywords to
 try, but offhand it's been a while i don't know if either would change the
 behavior. Could just be inner scope limitations. Might be other
 tags/modifiers...

  I feel helpless :(

No need to ;-) Thanks for your help, don't sweat it too much.

  I'm not sure if it would help, but sometimes if you reverse the logic you
 might get what you want by putting the data in B instead of A.

I have a lot of Bs (nodes in a graph). They compute some things and
when they get a result, they update A's field. Each A holds the entry
point to their inner graph of Bs and waits for the results.
So I don't see how I could invert it, really.

What  *could* do it to have the graph of Bs in thread and sending
results as messages to another thread, where A is waiting for them.

It's just... I'm so used to being able to mix and compose 'concepts'
in D: structs in functions, classes in classes in structs, functions
returning functions returning structs, etc. I'm used to begin able to
organise my code as I see the problem space.
But here, with a struct-in-a-struct, I hit a wall. Not fun, but not
problematic too...


Re: Help with porting grammar from PEGjs to D for dustjs project!

2014-08-05 Thread Philippe Sigaud via Digitalmars-d-learn
 Is there multiline comments available inside PEGGED template?
 As far as I understand inline comments are set via # sign.

No, no multiline comment. That's based on the original PEG grammar,
which allows only #-comments.


Re: How to easily construct objects with multi-param constructors from lazy ranges?

2014-08-05 Thread Philippe Sigaud via Digitalmars-d-learn
 Some range which takes an at compile time known number of elements from an
 input range and provides opIndex seems perfect to me, but as far as I know
 there's no such thing in Phobos.

There is chunks:

http://dlang.org/phobos/std_range.html#chunks


Re: static array in templated struct/class

2014-08-05 Thread Philippe Sigaud via Digitalmars-d-learn
 http://pastebin.com/34sbffSa

Your problem comes from lengthSquared:

public auto lengthSquared = function () = val.reduce!((a,b) = a + b*b);

That's an unusual way to define a method. Any reason why you are using
a pointer to a function as a member? Do you need to be able to
redefine it at runtime?

I guess that in this case, the compiler cannot determine its return
type and/or its size?
I'd use:

public auto lengthSquared () { return val.reduce!((a,b) = a + b*b);}


Inner struct accessing host member

2014-08-05 Thread Philippe Sigaud via Digitalmars-d-learn

I'd have thought that this would work:

struct A
{
int[] i;
B b;

struct B
{
void foo() { i ~= 1;}
}
}

void main()
{
A a;
a.b.foo();
}

But the compiler tells me 'need this for i of type int[]'.
Is there any way I can gain access on i inside B?


Re: Inner struct accessing host member

2014-08-05 Thread Philippe Sigaud via Digitalmars-d-learn
On Tue, Aug 5, 2014 at 11:37 PM, Martijn Pot via Digitalmars-d-learn
digitalmars-d-learn@puremagic.com wrote:

 Does this help :
 http://www.digitalmars.com/d/archives/digitalmars/D/learn/Nested_struct_member_has_no_access_to_the_enclosing_class_data_38294.html

Yes, that helps: that explains why it does not wor :).
I changed my code to use classes. It's a bit less handy, but it works.


Re: Inner struct accessing host member

2014-08-05 Thread Philippe Sigaud via Digitalmars-d-learn
 why it does not wor :).

why it does not *work*, of course. Sigh.


Re: Inner struct accessing host member

2014-08-05 Thread Philippe Sigaud via Digitalmars-d-learn

On Tuesday, 5 August 2014 at 22:14:23 UTC, abanstadya wrote:

programming Q, either youra newb or not, should rather be 
posted to 'http://forum.dlang.org/group/digitalmars.D.learn'. 
Your post appears on 
'http://forum.dlang.org/group/digitalmars.D' which is more 
related to the lang. design rather to programming Q. Take care 
next time bro.


This *is* D.learn, bro.


Re: Inner struct accessing host member

2014-08-05 Thread Philippe Sigaud via Digitalmars-d-learn
On Tuesday, 5 August 2014 at 23:47:00 UTC, Artur Skawina via 
Digitalmars-d-learn wrote:



Is there any way I can gain access on i inside B?


Not directly, but as you ask for /any/ way -- yes:

   struct B
   {
 void foo() { outer.i ~= 1; }
 ref A outer() inout @property { return 
*cast(A*)(cast(void*)this-A.b.offsetof); }

   }

Note this will work only as long as you have just one B
instance in A and B is never created or copied outside of A.


OK. I have en entire graph, whose nodes are Bs inside A. So that 
might not be totally appropriate for me. Thanks anyway, I always 
forget about offsetof


Re: Inner struct accessing host member

2014-08-05 Thread Philippe Sigaud via Digitalmars-d-learn

Era:
 broken_b.foo(); //i_a is accessible invisibly because 
overridden or transformed assuming it would be converted or 
copied/moved as appropriate.


 return b; //if a is a local variable then b becomes invalid 
even though it's a struct.

 return i_b; //same as return b
 return broken_b; //same as above two cases.


I see. I didn't know one could create an A.B 'outside'. I saw 
inner types as Voldemort types, but that is true only for inner 
structs in functions.




 Now a current way to make it safe while still leaving it 
structs could be passing a reference to either the outer struct 
or the variable in question. For simplicity it would probably 
be the struct.

(...)
 Or less safe is to use a pointer and assign it when b 
instantiates to point back to A.. But if you pass B around 
without A and A goes out of scope... same problem...


 Maybe i'm over-thinking it.


I already tried to propagate a ref through A's methods, but that 
made a mess: I have lots of methods, which have all to transmit 
this ref, only for *one* of them being able to update it.


Thanks for you explanations :)
I'm now using classes and inner classes. I'm not fond of classes, 
but that's working correctly.


Re: Threadpools, difference between DMD and LDC

2014-08-04 Thread Philippe Sigaud via Digitalmars-d-learn
 Without going into much detail: Threads are heavy, and creating a thread is
 an expensive operation (which is partially why virtually every standard
 library includes a ThreadPool).

 I haven't looked into detail your code, but consider using the TaskPool if
 you just want to schedule some tasks to run amongst a few threads, or
 potentially using Fibers (which are fairly light-weight) instead of Threads.

OK, I get it. Just to be sure, there is no ThreadPool in Phobos or in
core, right?
IIRC, there are fibers somewhere in core, I'll have a look. I also
heard the vibe.d has them.


Re: Threadpools, difference between DMD and LDC

2014-08-04 Thread Philippe Sigaud via Digitalmars-d-learn
On Mon, Aug 4, 2014 at 2:13 PM, Chris Cain via Digitalmars-d-learn
digitalmars-d-learn@puremagic.com wrote:

 OK, I get it. Just to be sure, there is no ThreadPool in Phobos or in
 core, right?

 There is. It's called taskPool, though:

 http://dlang.org/phobos/std_parallelism.html#.taskPool

Ah, std.parallelism. I stoopidly searched in std.concurrency and core.*
Thanks!


Re: Threadpools, difference between DMD and LDC

2014-08-04 Thread Philippe Sigaud via Digitalmars-d-learn
On Mon, Aug 4, 2014 at 3:36 PM, Dicebot via Digitalmars-d-learn
digitalmars-d-learn@puremagic.com wrote:

 Most likely those threads either do nothing or are short living so you don't
 get actually 10 000 threads running simultaneously. In general you should
 expect your operating system to start stalling at few thousands of
 concurrent threads competing for context switches and system resources.
 Creating new thread is rather costly operation though you may not spot it in
 synthetic snippets, only under actual load.

 Modern default approach is to have amount of worker threads identical or
 close to amount of CPU cores and handle internal scheduling manually via
 fibers or some similar solution.

That's what I guessed. It's juste that I have task that will generate
other (linked) tasks, in a DAG. I can use a thread pool of 2-8
threads, but that means storing tasks and their relationships (which
is waiting on which, etc). I rather liked the idea of spawning new
threads when I needed them ;)




 If you are totally new to the topic of concurrent services, getting familiar
 with http://en.wikipedia.org/wiki/C10k_problem may be useful :)

I'll have a look. I'm quite new, my only knowledge comes from reading
the concurrency threads here, std.concurrency, std.parallelism and
TDPL :)


Re: Threadpools, difference between DMD and LDC

2014-08-04 Thread Philippe Sigaud via Digitalmars-d-learn
On Mon, Aug 4, 2014 at 6:21 PM, Dicebot via Digitalmars-d-learn
digitalmars-d-learn@puremagic.com wrote:

 vibe.d additions may help here:

 http://vibed.org/api/vibe.core.core/runTask
 http://vibed.org/api/vibe.core.core/runWorkerTask
 http://vibed.org/api/vibe.core.core/workerThreadCount

 task abstraction allows exactly that - spawning new execution context and
 have it scheduled automatically via underlying fiber/thread pool. However, I
 am not aware of any good tutorials about using those so jump in at your own
 risk.

Has anyone used (the fiber/taks of) vibe.d for something other than
powering websites?


Re: Threadpools, difference between DMD and LDC

2014-08-04 Thread Philippe Sigaud via Digitalmars-d-learn
On Mon, Aug 4, 2014 at 6:38 PM, Russel Winder via Digitalmars-d-learn
digitalmars-d-learn@puremagic.com wrote:

 Are these std.concurrent threads or std.parallelism tasks?

 A std.parallelism task is not a thread. Like Erlang or Java Fork/Join
 framework, the program specifies units of work and then there is a
 thread pool underneath that works on tasks as required. So you can have
 zillions of tasks but there will only be a few actual threads working on
 them.

That's it. Many tasks, a few working threads. That's what I'm
converging to. They are not particularly 'concurrent', but they can
depend on one another.

My only gripes with std.parallelism is that I cannot understand
whether it's interesting to use the module if tasks can create other
tasks and depend on them in a deeply interconnected graph. I mean, if
I have to write lots of scaffolding just to manage dependencies
between task, I might as well built it on core.thread and message
passing directly. I'm becoming quite enamored of message passing,
maybe because it's a new shiny toy for me :)

That's for parsing, btw. I'm trying to write a n-core engine for my
Pegged parser generator project.



 Most likely those threads either do nothing or are short living
 so you don't get actually 10 000 threads running simultaneously.

 I suspect it is actually impossible to start this number of kernel
 threads on any current kernel

So, what happens when I do

void doWork() { ... }

Tid[] children;
foreach(_; 0 .. 10_000)
children ~= spawn(doWork);

?

I mean, it compiles and runs happily.
In my current tests, I end the application by sending all thread a
CloseDown message and waiting for an answer from each of them. That
takes about 1s on my machine.

 I have no current data, but it used to be that for a single system it
 was best to have one or two more threads than the number of cores.
 Processor architectures and caching changes so new data is required. I
 am sure someone somewhere has it though.

I can add that, depending on the tasks I'm using, it's sometime better
to use 4, 6, 8 or 10 threads, repeatedly for a given task. I'm using a
Core i7, Linux sees it as an 8-core.
So, well, I'll try and see.


Re: Threadpools, difference between DMD and LDC

2014-08-04 Thread Philippe Sigaud via Digitalmars-d-learn
 https://github.com/D-Programming-Language/phobos/pull/1910

Very interesting discussion, thanks. I'm impressed by the amount of
work you guys do on github.


Threadpools, difference between DMD and LDC

2014-08-03 Thread Philippe Sigaud via Digitalmars-d-learn

I'm trying to grok message passing. That's my very first foray
into this, so I'm probably making every mistake in the book :-)

I wrote a small threadpool test, it's there:

http://dpaste.dzfl.pl/3d3a65a00425

I'm playing with the number of threads and the number of tasks,
and getting a feel about how message passing works. I must say I
quite like it: it's a bit like suddenly being able to safely
return different types from a function.

What I don't get is the difference between DMD (I'm using 2.065)
and LDC (0.14-alpha1).

For DMD, I compile with -O -inline -noboundscheck
For LDC, I use -03 -inline

LDC gives me smaller executables than DMD (also, 3 to 5 times
smaller than 0.13, good job!) but above all else incredibly,
astoundingly faster. I'm used to LDC producing 20-30% faster
programs, but here it's 1000 times faster!

8 threads, 1000 tasks: DMD:  4000 ms, LDC: 3 ms (!)

So my current hypothesis is a) I'm doing something wrong or b)
the tasks are optimized away or something.

Can someone confirm the results and tell me what I'm doing wrong?


Threadpools, difference between DMD and LDC

2014-08-03 Thread Philippe Sigaud via Digitalmars-d-learn
I'm trying to grok message passing. That's my very first foray 
into this, so I'm probably making every mistake in the book :-)


I wrote a small threadpool test, it's there:

http://dpaste.dzfl.pl/3d3a65a00425

I'm playing with the number of threads and the number of tasks, 
and getting a feel about how message passing works. I must say I 
quite like it: it's a bit like suddenly being able to safely 
return different types from a function.


What I don't get is the difference between DMD (I'm using 2.065) 
and LDC (0.14-alpha1).


For DMD, I compile with -O -inline -noboundscheck
For LDC, I use -03 -inline

LDC gives me smaller executables than DMD (also, 3 to 5 times 
smaller than 0.13, good job!) but above all else incredibly, 
astoundingly faster. I'm used to LDC producing 20-30% faster 
programs, but here it's 1000 times faster!


8 threads, 1000 tasks: DMD:  4000 ms, LDC: 3 ms (!)

So my current hypothesis is a) I'm doing something wrong or b) 
the tasks are optimized away or something.


Can someone confirm the results and tell me what I'm doing wrong?



Re: Help with porting grammar from PEGjs to D for dustjs project!

2014-08-03 Thread Philippe Sigaud via Digitalmars-d-learn
Uranuz:
 http://akdubya.github.io/dustjs/

 So I need some help with rewriting grammar from PEGjs into PEGGED.

Is this the grammar?

https://github.com/akdubya/dustjs/blob/master/src/dust.pegjs

If so, then I think I can provide some help. But I don't get what
output you want (see below).

 Also I don't understand in PEGGED (I have not tried to use it yet) how to
 generate some logic from AST. Where should I describe it or should I walk
 around all nodes for somehow and generate code for them.

You can put semantic actions in the grammar (code between curly
brackets). dust.pegjs seems
to have that in their grammar definition also (all these { return
something } blocks)

Or you can walk the parse tree afterwards.

See the Pegged tutorial here:

https://github.com/PhilippeSigaud/Pegged/wiki/Pegged-Tutorial

More particularly:

https://github.com/PhilippeSigaud/Pegged/wiki/Using-the-Parse-Tree

The example explains (I hope) how to use a wiki grammar to parse wiki
text and output LaTeX code.


 Goal of this is to use dust template system as template engine at server
 side.

More concretely, what's the goal? A template as input and... what
should be output? If I understand correctly, dustjs produces
Javascript code. Is that what you want? Or do you want D code?

Also, did you have a look at vide.d and its Diet templates?


Re: Threadpools, difference between DMD and LDC

2014-08-03 Thread Philippe Sigaud via Digitalmars-d-learn
 This is correct – the LLVM optimizer indeed gets rid of the loop completely.

OK,that's clever. But I get this even when put a writeln(some msg)
inside the task. I thought a write couldn't be optimized away that way
and that it's a slow operation?

Anyway, I discovered Thread.wait() in core in the meantime, I'll use
that. I just wanted to have tasks taking a different amount of time
each time.

I have another question: it seems I can spawn hundreds of threads
(Heck, even 10_000 is accepted), even when I have 4-8 cores. Is there:
is there a limit to the number of threads? I tried a threadpool
because in my application I feared having to spawn ~100-200 threads
but if that's not the case, I can drastically simplify my code.
Is spawning a thread a slow operation in general?



Re: Help with porting grammar from PEGjs to D for dustjs project!

2014-08-03 Thread Philippe Sigaud via Digitalmars-d-learn
On Mon, Aug 4, 2014 at 7:13 AM, Uranuz via Digitalmars-d-learn
digitalmars-d-learn@puremagic.com wrote:
 I am real noob about grammar description languages so I need some
 explanation about it. As far as I understand expressions in curly bracers
 are used to modify syntax tree just in process of parsing instead of
 modifying it after?

Yes, that's it. Or at least that's the way Pegged does it. I'm not
such a specialist myself, I just dabbled in it to write Pegged.
As I understand it, many parsers do not produce a parse tree, they
only 'return' what their embedded action tell them to.

Personally, I have a slight preference to using the parse tree once
it's complete. a) Because that way I have access to all the
information (parent nodes, sibling nodes, even far way) whereas when
doing it with an action means you only have the local, current node
context and b) because it decouples steps that are in my mind
separated anyway: parsing, then producing a value out of the parse
tree. A bit like ranges in D, and Walter and his components
programming speech.


 How I could use PEGGED to map some code to these parsed expressions to
 generate code that will perform operations defined by this grammar? Should I
 walk around all the syntax tree and just append code to some string and mix
 it in then or are there some features for code generation?

You can insert semantic actions inside the grammar definition, as is
done by Dustjs, or you can have a function walking the tree
afterwards.
For D, since Pegged works at compile time, you can have your parse
tree at compile time. Use the walking function to generate D code (a
string) and mix it in.

enum parseTree = Grammar(input); // CT parsing
string codeMaker(ParseTree pt) { ... } // recursive walker

mixin(codeMaker(parseTree));

See https://github.com/PhilippeSigaud/Pegged/wiki/Using-the-Parse-Tree

If what you need is generating Javascript code, no need to do that at
compile-time: you can assemble the JS code as a string at runtime and
then write it to a file somewhere, I guess.

 Something that I was thinking about is comparision of resulting syntax tree
 to check if it was correctly implemented. It would be great if different
 gramar parsers will output result in common format (JSON or XML for example)
 and it will be possiple to compare them for equality. But different parsers
 have different internal format of tree so maybe creating some transformation
 is possible. With this feature it could be possible to say if parser is
 working correctly.

Different formats and also different languages. I don't see how you
can compare a parse tree that's a D object and another tree made by
dustjs: you never see the AST produced by dust, you only see the
resulting JS code.


Re: Type deduction on templated constructor.

2014-07-30 Thread Philippe Sigaud via Digitalmars-d-learn
 I expected such an answer and I do understand the decisions behind it. Yet,
 you gave me a really GOOD news! Having to write cast(ubyte) 1 was way too
 much verbose for my liking, while the new ubyte(1) is reasonable enough.

Why not use `1u`?


Re: Type deduction on templated constructor.

2014-07-30 Thread Philippe Sigaud via Digitalmars-d-learn
On Wed, Jul 30, 2014 at 11:46 AM, Philippe Sigaud
philippe.sig...@gmail.com wrote:
 I expected such an answer and I do understand the decisions behind it. Yet,
 you gave me a really GOOD news! Having to write cast(ubyte) 1 was way too
 much verbose for my liking, while the new ubyte(1) is reasonable enough.

 Why not use `1u`?

Ow! Ignore that. 1u is an uint, not an ubyte.


Re: Compile time regex matching

2014-07-15 Thread Philippe Sigaud via Digitalmars-d-learn
 I did, and I got it to work. Unfortunately, the code used to in the CTFE is
 left in the final executable even though it is not used at runtime. So now
 the question is, is there away to get rid of the excess baggage?

Not that I know of. Once code is injected, it's compiled into the executable.

   auto result = MyRegex(import(config-file.txt)); // compile-time parsing
   return writeln(\~result.matches[0]~\);;


   mixin(get_match());

I never tried that, I'm happy that works.

Another solution would be to push these actions at runtime, by using a
small script instead of your compilation command. This script can be
in D.

- The script takes a file name as input
- Open the file
- Use regex to parse it
- Extract the values you want and write them to a temporary file.
- Invoke the compiler (with std.process) on your main file with -Jpath
flag to the temporary file. Inside your real code, you can thus use
mixin(import(temp file)) happily.
- Delete the temporary file once the previous step is finished.

Compile the script once and for all, it should execute quite rapidly.
It's a unusual pre-processor, in a way.


Re: new properties for basic types

2014-07-14 Thread Philippe Sigaud via Digitalmars-d-learn
Halas, that's not what the OP wants. He needs properties on the *type*
itself: int.foo instead of foo!int.

So no, this is not possible.


Re: Compile time regex matching

2014-07-14 Thread Philippe Sigaud via Digitalmars-d-learn
 I am trying to write some code that uses and matches to regular expressions
 at compile time, but the compiler won't let me because matchFirst and
 matchAll make use of malloc().

 Is there an alternative that I can use that can be run at compile time?

You can try Pegged, a parser generator that works at compile-time
(both the generator and the generated parser).

https://github.com/PhilippeSigaud/Pegged

docs:

https://github.com/PhilippeSigaud/Pegged/wiki/Pegged-Tutorial

It's also on dub:

http://code.dlang.org/packages/pegged

It takes a grammar as input, not a single regular expression, but the
syntax is not too different.


  import pegged.grammar;

  mixin(grammar(`
  MyRegex:
  foo - abc* def?
  `));

  void main()
  {
  enum result = MyRegex(abcabcdefFOOBAR); // compile-time parsing

  // everything can be queried and tested at compile-time, if need be.
  static assert(result.matches == [abc, abc, def]);
  static assert(result.begin == 0);
  static assert(result.end == 9);

  pragma(msg, result.toString()); // parse tree
  }


It probably does not implement all those regex nifty features, but it
has all the usual Parsing Expression Grammars powers. It gives you an
entire parse result, though: matches, children, subchildren, etc. As
you can see, matches are accessible at the top level.

One thing to keep in mind, that comes from the language and not this
library: in the previous code, since 'result' is an enum, it'll be
'pasted' in place everytime it's used in code: all those static
asserts get an entire copy of the parse tree. It's a bit wasteful, but
using 'immutable' directly does not work here, but this is OK:

enum res = MyRegex(abcabcdefFOOBAR); // compile-time parsing
immutable result = res; // to avoid copying the enum value everywhere

The static asserts then works (not the toString, though). Maybe
someone more knowledgeable than me on DMD internals could certify it
indeed avoid re-allocating those parse results.


Re: Compile time regex matching

2014-07-14 Thread Philippe Sigaud via Digitalmars-d-learn
On Mon, Jul 14, 2014 at 3:19 PM, Artur Skawina via Digitalmars-d-learn
digitalmars-d-learn@puremagic.com wrote:
 On 07/14/14 13:42, Philippe Sigaud via Digitalmars-d-learn wrote:
 asserts get an entire copy of the parse tree. It's a bit wasteful, but
 using 'immutable' directly does not work here, but this is OK:

 enum res = MyRegex(abcabcdefFOOBAR); // compile-time parsing
 immutable result = res; // to avoid copying the enum value everywhere

static immutable result = MyRegex(abcabcdefFOOBAR); // compile-time 
 parsing

Ah, static!



 The static asserts then works (not the toString, though). Maybe
(snip diff)

I'll push that to the repo, thanks! I should sprinkle some const and
pure everywhere...

 [completely untested; just did a git clone and fixed the two
  errors the compiler was whining about. Hmm, did pegged get
  faster? Last time i tried (years ago) it was unusably slow;
  right now, compiling your example, i didn't notice the extra
  multi-second delay that was there then.]

It's still slower than some handcrafted parsers. At some time, I could
get it on par with std.regex (between 1.3 and 1.8 times slower), but
that meant losing some other properties. I have other parsing engines
partially implemented, with either a larger specter of grammars or
better speed (but not both!). I hope the coming holidays will let me
go back to it.


Re: new properties for basic types

2014-07-14 Thread Philippe Sigaud via Digitalmars-d-learn
 Hmm.
 So how do I use stuff like this:

 template defaultInit(T)
 {
 static if (!is(typeof({ T v = void; })))// inout(U)
 @property T defaultInit(T v = T.init);
 else
 @property T defaultInit();
 }

 (this is from std.traits - ok, it's private, but anyway)

It should be invoked as `defaultInit!SomeType`


 Because I have seen nowhere anything like defaultInit!T (or T.defaultInit)
 and don't understand why here the attribute @property is used.
 Why does it make a difference, and how?

@property allows you to call a function without the parenthesis (), to
imitate a field in a struct or class.
In this particular case, I don't know what defaultInit is used for. It
seems to compile to a forward declaration of a function, but I don't
know what for.

I cannot find it on my copy of std.traits. What DMD version are you using?


Re: Opinions: The Best and Worst of D (for a lecture/talk I intend to give)

2014-07-08 Thread Philippe Sigaud via Digitalmars-d-learn
On Tue, Jul 8, 2014 at 7:50 AM, H. S. Teoh via Digitalmars-d-learn
digitalmars-d-learn@puremagic.com wrote quite a wall of text

Wow, what to add to that? Maybe you scared other from participating ;-)

* I'll second metaprogramming: the alliance between templates, CTFE
and mixins is really nice. It's *the* feature (or triplet of features)
I think of when Walter says that many D parts are kind of what for?
in isolation but really grow into something awesome by using one
another.

* I'd add static introspection to the mix: using static if,
__traits(...) and is(...), clunky as the syntax is (there, one 'ugly'
thing for you), is easy and very powerful: the idea to have code
selecting its flow or extracting information (is that a static array?
Does this aggregate have an '.empty' method?). This is the basis for
std.algorithm idiom of 'static interface' which allows us compile-time
duck typing, which I find very pleasing.

* unittests are nice of course, H. S. Teoh already said it
expressively enough :-)

* I'd add arrays and slice. They are wonderfully simple to use,
efficient, etc. I remember learning D by translating the Euler Project
problems from C++ to D and it was a joy.

Which brings me to another feature I like: ranges. The idea is nothing
new, but I find it quite well-realized in D, far easier than other
compiled languages alternatives and since they are pervasive in the
library, you can really plug components into one another nicely.

For example:
http://wiki.dlang.org/Component_programming_with_ranges#Case_Study:_Formatting_a_Calendar

* dub is good, and you can show code.dlang.org in your presentation.

* Bonus point: different compilers. I like that. I regularly use at
least two in parallel while developping (comparing results, speed,
etc). Kudos to all the guys involved!



As for the bad and ugly:

* it's frustrating not to have a big collection module in Phobos, but
then I didn't propose one, so I'll shut up.
* there are still some not so nice interaction between
const/shared/inout/ auto ref, though I rarely hit them these days
* The compiler still has some quirks: I find it strange you can put
unused qualifiers in many places.

But very honestly, it was already a joy to use a few years ago, and
it's becoming better and better.


Re: dependency graph

2014-07-06 Thread Philippe Sigaud via Digitalmars-d-learn
If you compile your project with the -deps flag, the compiler will
output import dependencies. With -deps=filename, the output will go
into filename.

From there, you'll have to parse and create the graph, though. Maybe
have a look into rdmd source, to see how the dependency extraction is
done there?


Re: What exactly module in D means?

2014-07-06 Thread Philippe Sigaud via Digitalmars-d-learn
On Sat, Jul 5, 2014 at 6:35 PM, Andre Tampubolon via
Digitalmars-d-learn digitalmars-d-learn@puremagic.com wrote:
 I've been reading the newsgroup for a while, and it seems that one of the
 reason folks like D is because it supports module.

 My question is: what does module mean?
 A quick google pointed my this page: http://dlang.org/module.html.
 Still cannot understand it, though :)

 How does it differ from the old C's #include?

Well, module are 'more first-class' in D than in C. By this, I mean
that they have an identity: a name, members, symbols. You can see them
as a enormous struct/class. You can use introspection to obtain the
symbols defined in a module, query their types, etc. Heck, in some
cases, module names can even by used as arguments for templates.

As others said, a D module is a unit of encapsulation: inside a
module, functions, structs and classes can freely call one other and
access their internal fields. Outside the module, only what's not
private is visible. Thus, you can create complex, interdependent
structures inside your module, but export only some parts for public
access. This way, you control a module 'interface', its external
frontier.

Importing a module in D means the public symbols defined in the module
become accessible in the importer. There is no need to import all
visible symbols in your current scope: you can restrict your import to
only one or two symbols, rename them, etc. That's much more powerful
than C when it comes to name clashes.

Different 'downstream' modules can import the same 'upstream' module,
and choose to import different symbols. No need to do a big 'import
everything in the current scope'.

symbols names are also defined on a per-module basis: two different
modules can have members with a similar name, without clash: just
prefix the names with the module name to differentiate them (or rename
one while importing).

Also, `import foo;` is a statement, you can put it everywhere a
statement is legit. That's a recent addition (ie, 1-2 year?), that
Andrei likes to call 'Turtles all the way down' and is quickly
becoming a D idiom: import a symbol near its use place: inside a
function, a method, even inside an if branch: that avoid scope
pollution and nicely documents where a symbol is necessary.


Re: How to test templates for equality?

2014-07-06 Thread Philippe Sigaud via Digitalmars-d-learn
Seeing his example, the OP wants a solution that works even for templates:

template Test1(T) {}

pragma(msg, instanceArgsOf!(Test1, Test1!int));

which fails because Test1!int is not a type (std.traits.isInstanceOf
fails also, for the same reason).
And is(symbol == Name!Args, Args...) does not work if Name!Args and
symbol are not types.

In this particular case, the only solution I know of is an awful hack:
using .stringof and __traits(identifier, x) and then parse the
strings:

Name!(int, double[string]) and Name(T, U[V], U, V)

and then the fun begins: in the general case, you must then equate the
arguments lists (recursively).

Philippe


Re: Trying to reproduce Node.js async waterfall pattern.. (Meta-programming)

2014-06-24 Thread Philippe Sigaud via Digitalmars-d-learn
 Yes, the final callback is always called, but if an error is passed to the
 callback by any of the main steps in the sequence ladder, it will
 immediately jump to the final callback and not execute further steps.

OK.


 What do you mean? The compiler does deduce the type of Funcs.


 If you look at where I call Waterfall() in main, you'll see I had to
 manually specify (Callback cb) instead of just (cb); since it didn't know
 that the Funcs... were of type AsyncFunc

you can use std.typetuple.allSatisfy with a helper template:

enum isAsyncFunc(T) = is(T == AsyncFunc);

... (Funcs...)(Funcs funcs) if (allSatisfy!(isAsyncFunc, Funcs))
{ ... }



 (cb) { cb(null, one);} is possible, but that means it's a function
 template, not a function.
 You can get this syntax by making the callbacks template arguments,
 which means they must be known at compile-time. Is that OK with you or
 do you need the possibility to define the callbacks at runtime?


 The goal was to do as much as possible at compile time.  Could you elaborate
 on this a bit.  I guess the answer is, yes, it's okay with me.

I mean, it's possible to get a (cb){ some code } syntax, but as that
define a function template, it has no real type: it cannot be a
runtime argument, only an alias template parameter. That means that
all callbacks must be defined in your code, none can come from user
input or runtime computation.




 I don't get it: none of your callbacks have a return type per se: they
 all return 'void'.
 Do you want callbacks that really return something?


 Yes, the callbacks at step0 should output a type in the result which is
 specific to step0, and then that type should be fed in as a secondary
 parameter to step1.

 I didn't get that far, as I was already stuck.

OK, I get it.



 thanks for your patience!

Well, we are there to explain :-)
I'll have try and code something. If I can get it to work, I'll post it there.


Re: Trying to reproduce Node.js async waterfall pattern.. (Meta-programming)

2014-06-23 Thread Philippe Sigaud via Digitalmars-d-learn
On Mon, Jun 23, 2014 at 9:39 PM, Christian Beaumont via
Digitalmars-d-learn digitalmars-d-learn@puremagic.com wrote:

 Each function is given a callback, that when called, steps the waterfall
 forward on to the next function to process.  If an error is passed to the
 callback (instead of null), then the waterfall stops processing and calls
 the final callback at the end of the chain.

Just to be sure: whether or not an error is passed to a callback, the
final callback is always called?
I mean, the last callback could also be called *only when something
fails*, a bit like a default case in a switch, or an error-handling
routine.


 1) I can't see any way to get the compiler to deduce the type of Funcs

What do you mean? The compiler does deduce the type of Funcs.

 I had an urge to somehow specialize the variadic Funcs... but I couldn't
 figure out any syntax to do that.

What do you mean by 'specialize'?

  Well, because of that, I have to
 repeatedly say (Callback cb) instead of (cb).

(cb) { cb(null, one);} is possible, but that means it's a function
template, not a function.
You can get this syntax by making the callbacks template arguments,
which means they must be known at compile-time. Is that OK with you or
do you need the possibility to define the callbacks at runtime?



 2) I can't see a path to flow the output type of the previous callback to
 the input TLastResult for the next... so it's stuck on string :(

I don't get it: none of your callbacks have a return type per se: they
all return 'void'.
Do you want callbacks that really return something?


 3) I had to use a specialization to deal with the head case; (the first
 function doesn't have an input from a previous result). Minor, but niggly.

You can test if func[0] takes one or two arguments:

import std.traits: isCallable, ReturnType;

static if (isCallable!(Func[0])  ReturnType!(Func[0]).length == 1)


Re: What is the correct way to forward method calls to the struct field?

2014-06-22 Thread Philippe Sigaud via Digitalmars-d-learn
On Sun, Jun 22, 2014 at 5:04 PM, monnoroch via Digitalmars-d-learn
digitalmars-d-learn@puremagic.com wrote:
 There is also a problem: when i declare opDispatch to be private,
 i still have access to this forwarding from another package. Is
 it a bug or what?

I don't know. I never used private in conjunction with a template.
Let's hope someone more knowledgeable than me can answer this.


Re: What is the correct way to forward method calls to the struct field?

2014-06-22 Thread Philippe Sigaud via Digitalmars-d-learn
On Sun, Jun 22, 2014 at 5:02 PM, monnoroch via Digitalmars-d-learn
digitalmars-d-learn@puremagic.com wrote:
 Thanks a lot!
 There is a problem though: when i pass incorrect parameters to
 such a method, it says, that S has no such field, which is a
 misleading error message.

You can test the mixin with static if, like this:

struct SomeT {
int foo(double d) { return 0;}
void bar(double d) { return;}
}

struct S {
  auto opDispatch(string name, Args...)(Args args) {
 static if (is(typeof(mixin((*iface). ~ name)(args
   return mixin((*iface). ~ name)(args);
 else
   pragma(msg, S. ~ name ~  cannot be called with arguments of
type  ~ Args.stringof);
}
SomeT** iface;
}

void main()
{
  SomeT st;
  SomeT* st_p = st;
  SomeT** st_p_p = st_p;
  S s = S(st_p_p);

  s.foo(3.14);
  s.foo(abc);
  s.bar(abc, 3.14);
}


Re: template mixins for boilerplate

2014-06-21 Thread Philippe Sigaud via Digitalmars-d-learn
Out of curiosity, why use a mixin template containing a string mixin
instead of, well, directly injecting a string mixin in your struct,
with a function?


Re: template mixins for boilerplate

2014-06-21 Thread Philippe Sigaud via Digitalmars-d-learn
On Sat, Jun 21, 2014 at 4:24 PM, Dicebot via Digitalmars-d-learn
digitalmars-d-learn@puremagic.com wrote:
 On Saturday, 21 June 2014 at 13:45:14 UTC, Philippe Sigaud via
 Digitalmars-d-learn wrote:

 Out of curiosity, why use a mixin template containing a string mixin
 instead of, well, directly injecting a string mixin in your struct,
 with a function?


 Hiding non-hygienic implementation behind a more reliable interface.

In what way is a template more reliable than the equivalent function?
That's an honest question: I'm just looking at the code a few posts
upward:

mixin template Function(string name) {
mixin(public static int  ~ name ~ () { return other.module. ~
name ~; });
}

struct S {
  mixin Function!fctn1;
}

And this double-mixin construction seems needlessly complicated to me,
compared to:

string Function(string name) {
  return public static int  ~ name ~ () { return other.module.
~ name ~; };
}

struct S {
mixin(Function(fctn1));
}


Re: What is the correct way to forward method calls to the struct field?

2014-06-21 Thread Philippe Sigaud via Digitalmars-d-learn
You can use 'auto' to let the compiler deduce the return type. Here I
use 'foo' which returns an int and 'bar', which returns void.

struct SomeT {
int foo(double d) { return 0;}
void bar(double d) { return;}
}

struct S {
auto /* here */
   opDispatch(string name, Args...)(Args args) {
return mixin((*iface). ~ name)(args);
}
SomeT** iface;
}


void main()
{
  SomeT st;
  SomeT* st_p = st;
  SomeT** st_p_p = st_p;

  S s = S(st_p_p);

  import std.stdio : writeln;
  writeln(s.foo(3.14)); // 0
  writeln(typeof(s.bar(3.14)).stringof); // void
}

On Sat, Jun 21, 2014 at 8:21 PM, monnoroch via Digitalmars-d-learn
digitalmars-d-learn@puremagic.com wrote:
 On Saturday, 21 June 2014 at 18:16:17 UTC, monnoroch wrote:

 Actyaly, last variant didn't work either: i was testing it
 inside S like ifc.foo(1), so UFCS kiked in, not alias this.


 Oh, my bad, alias impl this; actually did work. But the first
 argument problem still holds.


Re: template mixins for boilerplate

2014-06-20 Thread Philippe Sigaud via Digitalmars-d-learn
Use a string mixin?

string fun(string name)
{
  return public static int  ~ name ~ () { return 0; };
}

struct S {
mixin (fun(fctn1));
}

void main() {
S s;
import std.stdio;
writeln(s.fctn1());
}


Re: Universal Construction Syntax for Pointers?

2014-06-14 Thread Philippe Sigaud via Digitalmars-d-learn
Would

auto i = (int*)(3);

make sense?

Does it work?


Re: Universal Construction Syntax for Pointers?

2014-06-14 Thread Philippe Sigaud via Digitalmars-d-learn
 And I don't think it should, because the heap allocation that you're
 probably expecting should be explicit IMO. For me it's also unintuitive,
 because I would read it as constructing a pointer that points to the address
 3.

I agree. I'm trying to get a feel on the limits of this new
'type(value)' syntax.


Re: does there exist a dimensional analysis library for D?

2014-06-13 Thread Philippe Sigaud via Digitalmars-d-learn
Hi Vlad,

you can try David Nadlinger's std.units:

http://klickverbot.at/code/units/std_units.html

See the discussion at

http://forum.dlang.org/thread/io1vgo$1fnc$1...@digitalmars.com


From what I deemly remember of Boost/units, it's a bit less complete,
but far easier to use.


Re: one of the weirdest bugs ever - request for testing

2014-06-12 Thread Philippe Sigaud via Digitalmars-d-learn
 // wrong code gen(*) with -release -O -inline -noboundscheck or
 // with -release -inline -noboundscheck but only if std.file is imported:

  auto x = countUntil( names, FOO );
  write(x);
  if( 0 = x ) writeln( found a FOO); // (*) not found!
 }


 I'm running OSX Mavericks with DMD v2.065.0. This behavior cannot be
 reproduced.

Linux, 64bits, DMD v2.065.0

Works OK for me (1 found a FOO), with or without importing std.file
and compiling with -release -inline -noboundscheck


Re: Creating new types from tuples.

2014-06-07 Thread Philippe Sigaud via Digitalmars-d-learn
 Is there any reason you couldn't (or would rather not) use structs rather
 than tuples?


 That would work. What would be the best way to auto-generate the types? I
 have somewhere around 30 already, and the number will grow with this
 project.

 Evan Davis

Maybe you could use a struct template, with UDP as a template
parameter. It'll instantiate a different type for each UDP value. If
you add new possible values to the enum, the rest of the code will
follow.

struct SendReceivePair(UDP udp)
{
/// maybe here some different values, differentiated by static if,
if needed.
}

Then, use these types directly in 'receive':

receive(
  (SendReceivePair!(UDP.ping) value) { },
  (SendReceivePair!(UDP.keep_alive) value) { }
)

If you want to 'retrieve' the UDP template parameter, you can expose
it through an alias:


struct SendReceivePair(UDP udp)
{
alias packetType = udp;
}

So, given SendReceivePair!(xxx) srp, you can get 'xxx' by srp.packetType;


Re: When is a slice not a slice?

2014-06-05 Thread Philippe Sigaud via Digitalmars-d-learn
 enum b = DataAndView(1);
 assert (!sameTail(b.data, b.view));

I suppose it's because enums are manifest constants: the value they
represent is 'copy-pasted' anew everywhere it appears in the code. So
for arrays and associative arrays, it means recreating a new value
each and every time.
In your case, your code is equivalent to:

assert (!sameTail(DataAndView(1).data,DataAndView(1).view));

And the two DataAndView(1), being completely separated, do not have
the same tail.


Re: enums

2014-06-01 Thread Philippe Sigaud via Digitalmars-d-learn
On Sat, May 31, 2014 at 10:14 PM, bearophile via Digitalmars-d-learn
digitalmars-d-learn@puremagic.com wrote:

 In contrast to those two examples where immutable can be used at compile
 time, what are some other cases where it is necessary to use enum instead
 of immutable?


 By default use enum if you define a compile-time-known value (...)

Now that we have immutable's that can be used inside templates, why
use an enum? Because it's 'inlined' in the code?

(I know the reason not to use it for an array or associative array, I
experimented that fully in my own code. Ouch!)


Re: how to detect ctfe

2014-06-01 Thread Philippe Sigaud via Digitalmars-d-learn
But let's keep in mind it's a *runtime* value. You cannot use it at
compile-time as a boolean for a 'static if'.
So:

if (__ctfe) // yes
{
// compile-time path
}
else
{
// runtime path
}

But not:

static if (__ctfe) // no
{
// compile-time path, including new global declarations
}
else
{
// runtime path
}

Why would you want to do that? I needed an associative array for my
code. AA don't work that well at compile-time. So I wanted to replace
them with my own Associative struct, maybe less efficient/generic, but
that works at CT. The idea was:

static if (__ctfe)
alias Type = Associative!(string, string);
else
alias Type = string[string];

// then, use Type, whatever the path.


Re: Casting Structs

2014-06-01 Thread Philippe Sigaud via Digitalmars-d-learn
On Sun, Jun 1, 2014 at 12:34 AM, Timon Gehr via Digitalmars-d-learn
digitalmars-d-learn@puremagic.com wrote:

 This behaviour is independent of templates. Struct values of the same size
 can be reinterpret-cast to each other this way even if their types are
 completely unrelated.

Do you know if this is by design?


Re: DMD fail when using both reflection and UDA

2014-06-01 Thread Philippe Sigaud via Digitalmars-d-learn
In any case, it's an internal compiler error, so it's a bug. Users
should never see ICEs.
Could you please report it, with the entire error message?


Re: Hiding types

2014-05-31 Thread Philippe Sigaud via Digitalmars-d-learn
On Sat, May 31, 2014 at 6:39 AM, Dicebot via Digitalmars-d-learn
digitalmars-d-learn@puremagic.com wrote:
 private in D does not provide any strong guarantees, it only controls direct
 access to the symbol. You effectively want some sort of strict internal
 linkage attribute which does not exist in D.

Indeed. I will learn to use '@disable this', then.


Re: Hiding types

2014-05-31 Thread Philippe Sigaud via Digitalmars-d-learn
 What do you mean? Like this?

 Hidden* foo() { return new Hidden();}

 Yes, this way you can control all aspects of the construction and use. You
 wouldn't need to make it private even, just don't lay out the struct in the
 normal import:

 struct Hidden;

 I think you would need to use a .di file to do this.

OK, I'll try that also. Thank you!


 You can make the struct's methods and data all private, which would prevent
 any useful access to it. But I don't know your use case.

I was trying to imitate some Haskell code in D. The idea was to play
with resources: from a File, create an OpenedFile which cannot be
created except by calling File.open(). And only FileOpened has a
.close() method.
Or something like this, anyway.

But I now realize that I was heading in a wrong direction: private is
not the way to do that: I want the user to know OpenedFile exists. I
just forbid him to create such a value except through File.open(). So
I guess :

struct OpenedFile {
@disable this...
}

is the way to go.

Now I just have to find an explanation on how to use this. I never
touched this part of D.


Re: Forward reference to nested function not allowed?

2014-05-31 Thread Philippe Sigaud via Digitalmars-d-learn
See:  http://dlang.org/function.html#variadicnested

The second example explains that nested functions can be accessed only
if the name is in scope.


Re: enums

2014-05-30 Thread Philippe Sigaud via Digitalmars-d-learn
 In D enum can be used to define manifest constants. This means constants
 known at compile time. In practice for a double there isn't a lot of
 difference. In general you can't take the address of a manifest constant,
 unlike immutables.

Because they do not exist as 'variables' or symbol in the generated
code. They are directly replaced by their computed value.

so :

- enum : manifest constant, can be used as a template argument, as a
static if operand or generally as a compile-time value. Indeed, a way
to force compile-time function evaluation is to ask for an enum:

enum result = foo(...); // foo(...) will be evaluated during compilation.

- immutable : it's a real variable: you can initialize it (once) at
runtime, and take its address.


Re: enums

2014-05-30 Thread Philippe Sigaud via Digitalmars-d-learn
A good use of 'static immutable', sadly not voted into the language.

:-)

But you're right, and I remember being tripped by this.


Re: enums

2014-05-30 Thread Philippe Sigaud via Digitalmars-d-learn
On Fri, May 30, 2014 at 7:28 PM, Ali Çehreli
digitalmars-d-learn@puremagic.com wrote:
 On 05/30/2014 08:30 AM, Russel Winder via Digitalmars-d-learn wrote:

  enum double p0 = 0.0045;

 As others have already said, p0 is a manifest constant. Interestingly, it
 can be thought of like a C macro, being pasted inside source code.

 Avoid enums for arrays and associative arrays as they are hidden performance
 sinks. The constant gets regenerated at runtime every time it is used in an
 expression.

I guess that, in an ideal world, immutable variables could be use at
compile-time (template arguments, etc). We could then ditch
'enums-as-manifest-constants'.The best of both worlds.

But what we have here is already quite good!



Re: enums

2014-05-30 Thread Philippe Sigaud via Digitalmars-d-learn
On Fri, May 30, 2014 at 7:56 PM, Steven Schveighoffer wrote:

 You can as long as the value is known at compile time:

 http://dpaste.dzfl.pl/5a710bd80ab0

Oh wow.

And that works for static if also:

http://dpaste.dzfl.pl/f87321a47834

Man. That opens some new possibilities.


Hiding types

2014-05-30 Thread Philippe Sigaud via Digitalmars-d-learn
I'm trying to 'hide' a type, so as not to see it outside its 
module. I want to control the way it's created and used.


I know of Voldemort types and '@disable this', but for now I'm 
just trying to use 'private'. Halas, it seems it can be 
circumvented:


*

module A;

private struct Hidden {}

Hidden foo() { return Hidden();}

*

module B;

import A;

void main() {
typeof(foo()) h;
}

*

Am I misunderstanding something or is that a bug?


Re: Hiding types

2014-05-30 Thread Philippe Sigaud via Digitalmars-d-learn

On Friday, 30 May 2014 at 19:54:00 UTC, safety0ff wrote:

On Friday, 30 May 2014 at 19:50:43 UTC, Philippe Sigaud wrote:

Am I misunderstanding something or is that a bug?


Try: auto foo() { return Hidden();}


I'm not seeing any difference? I'm still able to create a value 
of type Hidden in an external module.


Re: Hiding types

2014-05-30 Thread Philippe Sigaud via Digitalmars-d-learn
On Friday, 30 May 2014 at 20:02:40 UTC, Steven Schveighoffer 
wrote:



If you want an opaque struct, you need to return it by pointer.


What do you mean? Like this?

Hidden* foo() { return new Hidden();}

?

Otherwise, the user must be able to know what type it is 
(otherwise, how would he use it?)


I just fear that by using internal, public, functions, the user 
might get access to a private type. I guess the D answer to that 
is to make foo private also. That makes sense.


I now realize that I implicitly considered 'private' to be 
transitive (or viral). That is that:


Hidden foo() { return Hidden();}

as foo is returning a value from a private type, it should be 
considered private also. By the compiler, I mean.


Re: How to get struct's members ?

2014-05-23 Thread Philippe Sigaud via Digitalmars-d-learn
On Fri, May 23, 2014 at 8:44 AM, monarch_dodra via Digitalmars-d-learn
digitalmars-d-learn@puremagic.com wrote:
 On Friday, 23 May 2014 at 01:17:18 UTC, bioinfornatics wrote:


 I would like to get struct's members and zip them with an action

 tupleof will do what you need (mostly). However, I don't think there will be
 any way to (generically) run-time zip on the members, due to probably type
 mismatch, and memory layout. In any case, nothing trivial, AFAIK.

You can define a map-like (or zip-like) template to act on tuples as
if they were ranges, but the resulting type will still be a tuple: in
general, the members and the delegates associated with them will all
have a different type.

Bioinfornatics, if you know your struct members are all of the same
type, you can 'cast' the tuple as an array by wrapping it in square
brackets like this:

[ myStruct.tupleof ]

and then use the usual range algorithms.

If that's not the case, you can create another struct, holding both
the original struct and the delegates...

I did some generic range-like work on tuples a few years ago. See for example:

https://github.com/PhilippeSigaud/dranges/blob/master/tuple.d#L620

Could you explain what you want with more details?


Re: Avoiding __traits(getAttributes, ...) on alias

2014-05-10 Thread Philippe Sigaud via Digitalmars-d-learn
Vlad Levenfeld:
 but beware I've noticed that sometimes this is not
 equivalent to the previous version and I'm not sure how or why that happens.
 In particular I notice that

   mixin(const bool value = ~expr~;));
 and
   const bool value = mixin(expr);

 are not the same, for some reason.

What are the differences?


Re: Avoiding __traits(getAttributes, ...) on alias

2014-05-10 Thread Philippe Sigaud via Digitalmars-d-learn
   else // doesn't compile, member is not accessible error
 foreach (type; __traits (getAttributes, mixin(`T.`~member)))
   static if (is (type == attribute))
 return true;
   return false;

 Maybe its trying to use it inside of __traits that is causing it?

Maybe __traits is trying to extract attributes from the mixin
expression, before the mixin injection?
That looks like a bug to me, no?


  1   2   >