Re: Digger 2.3 verstr.h problem

2015-08-23 Thread John Colvin via Digitalmars-d-learn

On Sunday, 23 August 2015 at 11:27:32 UTC, Robert M. Münch wrote:
Hi, just trying to build the latest DMD with Digger 2.3 and get 
this:


uffer.d root/port.d root/response.d root/rmem.d 
root/rootobject.d root/speller.d root/stringtable.d newdelete.o 
glue.a backend.a
globals.d(293): Error: file verstr.h cannot be found or not 
in a path specified with -J

make: *** [dmd] Error 1
digger: Saving to cache.
digger: Clearing temporary cache
Fatal error: Command [make, -f, posix.mak, MODEL=64, 
HOST_DC=/Volumes/Daten/Windows/d/develop/d-language/Digger/dl/dmd-2.067.1/dmd2/osx/bin/dmd, dmd] failed with status 2

mac-pro:Digger robby$ find . -name verstr.h
./repo/dmd/src/verstr.h
mac-pro:Digger robby$ find . -name globals.d
./repo/dmd/src/globals.d
mac-pro:Digger robby$

I'm wondering why the verstr.h file can't be found... it's in 
the same dir as from where the import happens. Any ideas?


almost certainly a consequence of the recent switchover to the 
dmd frontend being written in D. Have you tried building the 
latest Digger git HEAD first? If that doesn't work I suggest 
reporting it here for Vladimir (CyberShadow) to look at: 
https://github.com/CyberShadow/Digger/issues/new


Re: Trying to compile weather program

2015-08-23 Thread Gerald Jansen via Digitalmars-d-learn

On Sunday, 23 August 2015 at 16:00:19 UTC, Tony wrote:

/usr/bin/ld: cannot find -lcurl


Just the other day I had a similar problem (compiling vibenews, 
ld complained of missing -levent and -lssl), which I managed to 
solve simply by installing the development versions of the 
libraries (i.e. libevent-dev and libssl-dev). Maybe if you 
install libcurl-dev you will have the same luck I had. (But 
hopefully someone will give a more enlightened reply.)


Re: How to use ranges?

2015-08-23 Thread Gary Willoughby via Digitalmars-d-learn

On Sunday, 23 August 2015 at 17:58:44 UTC, Doolan wrote:

...


Read this for a nice introduction: 
http://ddili.org/ders/d.en/ranges.html

Then watch this: https://www.youtube.com/watch?v=A8Btr8TPJ8c


Re: How to use ranges?

2015-08-23 Thread John Colvin via Digitalmars-d-learn
Generally, dynamic arrays / slices are random-access ranges. 
Narrow strings (string/wstring/char[]/wchar[]/...) are a 
notable exception to this. They are dynamic arrays of 
UTF-8/UTF-16 code units. But they're not random-access ranges 
of Unicode code units. Instead, they're _forward_ ranges of 
Unicode code _points_ (dchar). They have special range 
primitives that to the decoding.
So slices are random-access ranges... I understand the 
random-access part... but are they inheriting from Range, do 
they just include a Range? Why is int[] an array when I 
declare, but variable[] a Range?? Or isn't it a Range?


A range is just any type that satisfies certain properties (e.g. 
has front, empty, popFront in the most basic case). int[] is a 
range because front, empty and popFront are defined for it in 
std.range, which can be called with uniform function call 
syntax (UFCS) as if they were members of the type int[] itself.


Re: Trying to compile weather program

2015-08-23 Thread Tony via Digitalmars-d-learn

On Sunday, 23 August 2015 at 16:00:19 UTC, Tony wrote:
Thanks for the replies. It compiles OK with just. However, it 
isn't linking:


/usr/bin/ld: cannot find -lcurl


I do have some versions of libcurl on my system:

/usr/lib/x86_64-linux-gnu/libcurl.so.3
/usr/lib/x86_64-linux-gnu/libcurl.so.4.3.0
/usr/lib/x86_64-linux-gnu/libcurl.so.4

I see there is a -L option to pass things to the linker

-Llinkerflag   pass linkerflag to link

but I am not sure how to use it.


I tried

ld weather_report.o -lcurl -L/usr/lib/x86_64-linux-gnu

and

ld weather_report.o -lcurl -L /usr/lib/x86_64-linux-gnu

but it also says it can't find libcurl:

ld: cannot find -lcurl



Re: post on using go 1.5 and GC latency

2015-08-23 Thread Atila Neves via Digitalmars-d-learn
On Saturday, 22 August 2015 at 06:54:43 UTC, Ola Fosheim Grøstad 
wrote:
On Saturday, 22 August 2015 at 06:48:48 UTC, Russel Winder 
wrote:

But one that Google are entirely happy to fully fund.


Yes, they have made Go fully supported on Google Cloud now, so 
I think it is safe to say that Google management is backing Go 
fully.


I'm kinda hoping for Go++...


The other day I thought it'd be hilarious if I did a Bjarne and 
wrote a preprocessor to generate Go code that would accept a 
superset of Go syntax but added generics, function overloading, 
etc. And, of course, called it Go++.


Alas, 'tis too much work for just the lulz. I'd rather spend the 
time making D better.


Atila


Re: How to use ranges?

2015-08-23 Thread anonymous via Digitalmars-d-learn
On Sunday 23 August 2015 19:58, Doolan wrote:

 You can use typeof to get the type of a range expression when
 typing it out is impractical/impossible.
 What if I want to save a range in a struct? Or is a range more of
 a verb than a noun..?

Can still use typeof then:

struct S
{
import std.range: tee;
import std.stdio: writeln;

typeof((int[]).init.tee!writeln) teeing;

this(int[] a)
{
teeing = a.tee!writeln;
}
}

void main()
{
auto s = S([1, 2, 3, 4]);
foreach(x; s.teeing) {}
}


Alternatively you can get classy and use std.range.interfaces:


struct S
{
import std.range: tee;
import std.range.interfaces: InputRange, inputRangeObject;
import std.stdio: writeln;

InputRange!int teeing;

this(int[] a)
{
teeing = inputRangeObject(a.tee!writeln);
}
}

void main()
{
auto s = S([1, 2, 3, 4]);
foreach(x; s.teeing) {}
}


 I need to compress some data, and luckily it's very suited for
 Running Length Encoding, so I've gone with doing that.
 Occasionally changes need to be made to this data and so rather
 than extracting the data, changing it, and then recompressing it,
 I can just do the equivalent of leaving a post-it note reminding
 the decompression function to sprinkle these changes in after
 decompression. Occasionally, I also need to grab some values out
 of this data without decompressing it, but for every additional
 value I look for I have to search the post-it notes and it gets a
 little fiddly.

Here's a quick implementation of a run-length decoder range, and some 
example usage.

I'm not sure how to go about the post-it note concept, or how practical it 
is. The decoder is not a random-access range, so when you want to edit the 
data and access individual items, then decode-edit-encode may work better. 
You don't have to shoehorn something into ranges just because ranges are 
cool.

But if you want to apply a bunch of transformations to the whole thing, then 
ranges shine.


import std.range: empty, front, popFront, save;
import std.stdio;

struct RunLengthItem(T)
{
T value;
size_t length;
}

struct RunLengthDecoder(T)
{
RunLengthItem!T[] items;
size_t currentRun = 0;

@property bool empty() const {return items.empty;}
@property T front() {return items.front.value;}
void popFront()
{
++currentRun;
if(currentRun = items.front.length)
{
items.popFront();
currentRun = 0;
}
}
@property RunLengthDecoder save() {return this;}
}

void main()
{
/* two 'f's, three 'o's, five 'b's, seven 'a's, eleven 'r's */
RunLengthItem!dchar[] data = [
RunLengthItem!dchar('f', 2),
RunLengthItem!dchar('o', 3),
RunLengthItem!dchar('b', 5),
RunLengthItem!dchar('a', 7),
RunLengthItem!dchar('r', 11)
];

auto decoder = RunLengthDecoder!dchar(data);

/* Just print the elements (writeln is aware of ranges): */
writeln(decoder.save); /* ffooobaaarrr */

/* Uppercase when printing: */
import std.uni: asUpperCase;
writeln(decoder.save.asUpperCase); /* FFOOOBAAARRR */

/* Filter out the 'b's, uppercase, and put an underscore every five 
characters: */
import std.algorithm: filter, joiner;
import std.range: chunks;
auto r = decoder.save
.filter!(c = c != 'b')
.asUpperCase
.chunks(5).joiner(_);
writeln(r); /* FFOOO_A_AARRR_R_RRR */
}



 So, I vaguely know what ranges are, and I've heard you can chain
 them together, and my code would be much more readable if I could
 cut up access to the data and splice in changes... but I don't
 even know how to define a range of the right type...

Sounds like you may have some specific code you could use help with. If so, 
don't be afraid to post that code and ask how it can be range-ified.

 So slices are random-access ranges... I understand the
 random-access part... but are they inheriting from Range, do they
 just include a Range?

There's no inheritance going on. Inheritance is a class thing. Arrays/slices 
are not classes.

std.range defines the necessary range operations for slices: empty, front, 
popFront, etc. That's how slices are ranges.

 Why is int[] an array when I declare, but
 variable[] a Range?? Or isn't it a Range?

Every int[] is a dynamic array, a slice, and a range. Doesn't matter where 
that int[] comes from.



Re: post on using go 1.5 and GC latency

2015-08-23 Thread via Digitalmars-d-learn

On Sunday, 23 August 2015 at 12:49:35 UTC, Russel Winder wrote:
You are mixing too many factors here. General purpose has 
nothing to do with performance, it is to do with can the 
language describe most if not all forms of computation. Go is a 
general purpose programming language just like C, C++, D, Rust, 
Haskell, OCaml.


Yes, of course it is, but given it's typical use context I find 
it odd that they didn't go more towards higher level constructs. 
For me Go displaces Python where more speed is required, though I 
wish it was more pythonic… (neither C++, Rust or D are really 
eligible)




Re: Trying to compile weather program

2015-08-23 Thread anonymous via Digitalmars-d-learn
On Sunday 23 August 2015 11:54, Tony wrote:

 weather_report.d(32): Error: undefined identifier centerJustifier

`centerJustifier` is new in 2.068. You're probably using an older version of 
D. You can replace `centerJustifier` with `center` here.


Re: Trying to compile weather program

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

On Sunday, 23 August 2015 at 09:54:37 UTC, Tony wrote:
I found this weather program on the main page (it seems to 
rotate what it here):


[...]


try with `center()` or update the compiler. centerJustifier() was 
added on 25 Apr 2015 so after 2.066.1 release:


https://github.com/D-Programming-Language/phobos/commit/f85101eea1b875311e5716143cd6346fe4655f02


Re: Trying to compile weather program

2015-08-23 Thread Tony via Digitalmars-d-learn
Thanks for the replies. It compiles OK with just. However, it 
isn't linking:


/usr/bin/ld: cannot find -lcurl


I do have some versions of libcurl on my system:

/usr/lib/x86_64-linux-gnu/libcurl.so.3
/usr/lib/x86_64-linux-gnu/libcurl.so.4.3.0
/usr/lib/x86_64-linux-gnu/libcurl.so.4

I see there is a -L option to pass things to the linker

-Llinkerflag   pass linkerflag to link

but I am not sure how to use it.





Re: How to use ranges?

2015-08-23 Thread Doolan via Digitalmars-d-learn

On Sunday, 23 August 2015 at 13:46:30 UTC, anonymous wrote:

On Sunday 23 August 2015 12:17, Doolan wrote:

And the use of auto everywhere makes it really hard to tell 
what types I should be using for anything. My compiler talks 
about RangeT!(whatever) but you try to use RangeT!(whatever) 
and you find out RangeT is private...


You can use typeof to get the type of a range expression when 
typing it out is impractical/impossible.
What if I want to save a range in a struct? Or is a range more of 
a verb than a noun..?

Can someone give me a short summary of how to use ranges?


I'm not sure what exactly you're looking for. The documentation 
for tee has some example code. How about you show something 
you're having trouble with?
The possibility of using ranges comes up a lot, but here's 
today's example:


I need to compress some data, and luckily it's very suited for 
Running Length Encoding, so I've gone with doing that. 
Occasionally changes need to be made to this data and so rather 
than extracting the data, changing it, and then recompressing it, 
I can just do the equivalent of leaving a post-it note reminding 
the decompression function to sprinkle these changes in after 
decompression. Occasionally, I also need to grab some values out 
of this data without decompressing it, but for every additional 
value I look for I have to search the post-it notes and it gets a 
little fiddly.


So, I vaguely know what ranges are, and I've heard you can chain 
them together, and my code would be much more readable if I could 
cut up access to the data and splice in changes... but I don't 
even know how to define a range of the right type...



And how do they relate to slices? That line is really blurry...


Slice is a synonym for what the spec calls a dynamic array, 
i.e. a structure containing a pointer and a length.


Slicing a dynamic array, static array, or pointer produces a 
dynamic array, referencing (not copying) the sliced elements:



int[] d = [1, 2, 3, 4]; /* dynamic array */
int[] slice = d[1 .. 3];
assert(slice == [2, 3]);

d[1] = 20;
assert(slice[0] == 20);

int[4] s = [1, 2, 3, 4]; /* static array */
slice = s[];
assert(slice == [1, 2, 3, 4]);

int* p = [1, 2, 3, 4].ptr; /* pointer */
slice = p[1 .. 3];
assert(slice == [2, 3]);


Note that the source types are different, but slicing them 
yields the same type every time: int[].


Generally, dynamic arrays / slices are random-access ranges. 
Narrow strings (string/wstring/char[]/wchar[]/...) are a 
notable exception to this. They are dynamic arrays of 
UTF-8/UTF-16 code units. But they're not random-access ranges 
of Unicode code units. Instead, they're _forward_ ranges of 
Unicode code _points_ (dchar). They have special range 
primitives that to the decoding.
So slices are random-access ranges... I understand the 
random-access part... but are they inheriting from Range, do they 
just include a Range? Why is int[] an array when I declare, but 
variable[] a Range?? Or isn't it a Range?


Re: How to use ranges?

2015-08-23 Thread ZombineDev via Digitalmars-d-learn

On Sunday, 23 August 2015 at 17:58:44 UTC, Doolan wrote:

...


Ali's book has a very nice chapter about ranges:
http://ddili.org/ders/d.en/ranges.html


Re: Digger 2.3 verstr.h problem

2015-08-23 Thread Vladimir Panteleev via Digitalmars-d-learn

On Sunday, 23 August 2015 at 20:07:39 UTC, Robert M. Münch wrote:

On 2015-08-23 17:01:07 +, Vladimir Panteleev said:


[...]


Ok, good. So it should be fixable on my side.

[...]


Not really sure what's going on there... If I could reproduce it, 
I'd try building DMD manually - if it still occurred, build DMD 
2.067.1 from source and add debugging printfs to see why it's not 
finding verstr.h.


Re: Digger 2.3 verstr.h problem

2015-08-23 Thread Vladimir Panteleev via Digitalmars-d-learn

On Sunday, 23 August 2015 at 11:27:32 UTC, Robert M. Münch wrote:
Hi, just trying to build the latest DMD with Digger 2.3 and get 
this:


uffer.d root/port.d root/response.d root/rmem.d 
root/rootobject.d root/speller.d root/stringtable.d newdelete.o 
glue.a backend.a
globals.d(293): Error: file verstr.h cannot be found or not 
in a path specified with -J

make: *** [dmd] Error 1
digger: Saving to cache.
digger: Clearing temporary cache
Fatal error: Command [make, -f, posix.mak, MODEL=64, 
HOST_DC=/Volumes/Daten/Windows/d/develop/d-language/Digger/dl/dmd-2.067.1/dmd2/osx/bin/dmd, dmd] failed with status 2

mac-pro:Digger robby$ find . -name verstr.h
./repo/dmd/src/verstr.h
mac-pro:Digger robby$ find . -name globals.d
./repo/dmd/src/globals.d
mac-pro:Digger robby$

I'm wondering why the verstr.h file can't be found... it's in 
the same dir as from where the import happens. Any ideas?


Can't reproduce this on Windows, Linux or OS X 10.10.3.

Can you include more of the build log (specifically, the entire 
failing command line)? It should have a -J. in it.


Re: Digger 2.3 verstr.h problem

2015-08-23 Thread Robert M. Münch via Digitalmars-d-learn

On 2015-08-23 17:01:07 +, Vladimir Panteleev said:


Can't reproduce this on Windows, Linux or OS X 10.10.3.


Ok, good. So it should be fixable on my side.

Can you include more of the build log (specifically, the entire failing 
command line)? It should have a -J. in it.


CC=g++ 
/Volumes/Daten/Windows/d/develop/d-language/Digger/dl/dmd-2.067.1/dmd2/osx/bin/dmd 
-ofdmd -m64 -vtls -J. -d  access.d aggregate.d aliasthis.d apply.d 
argtypes.d arrayop.d arraytypes.d attrib.d backend.d builtin.d 
canthrow.d clone.d complex.d cond.d constfold.d cppmangle.d ctfeexpr.d 
dcast.d dclass.d declaration.d delegatize.d denum.d dimport.d 
dinifile.d dinterpret.d dmacro.d dmangle.d dmodule.d doc.d dscope.d 
dstruct.d dsymbol.d dtemplate.d dunittest.d dversion.d entity.d 
errors.d escape.d expression.d func.d globals.d hdrgen.d id.d 
identifier.d impcnvtab.d imphint.d init.d inline.d intrange.d json.d 
lexer.d lib.d link.d mars.d mtype.d nogc.d nspace.d opover.d optimize.d 
parse.d sapply.d sideeffect.d statement.d staticassert.d target.d 
tokens.d traits.d utf.d visitor.d objc.d root/aav.d root/array.d 
root/file.d root/filename.d root/longdouble.d root/man.d 
root/outbuffer.d root/port.d root/response.d root/rmem.d 
root/rootobject.d root/speller.d root/stringtable.d newdelete.o glue.a 
backend.a
globals.d(293): Error: file verstr.h cannot be found or not in a path 
specified with -J

make: *** [dmd] Error 1
digger: Saving to cache.
digger: Clearing temporary cache
Fatal error: Command [make, -f, posix.mak, MODEL=64, 
HOST_DC=/Volumes/Daten/Windows/d/develop/d-language/Digger/dl/dmd-2.067.1/dmd2/osx/bin/dmd, 
dmd] failed with status 2



AFAIU it does has the -J. included.

--
Robert M. Münch
http://www.saphirion.com
smarter | better | faster



Re: (De)Serializing interfaces

2015-08-23 Thread nims via Digitalmars-d-learn

On Sunday, 23 August 2015 at 03:09:03 UTC, Rikki Cattermole wrote:
Anyway to summise why D doesn't yet have something akin to Java 
or C#. Simply put, we generally work with the actual type not 
an interface. So libraries like Orange can 
serialize/deserialize with great certainty that it got 
everything.


However if you need any help with making such a library, please 
let me know!


Actually I'm coming from C++ but I know a little bit about C# so 
your explanation was helpful anyway! Thanks!


As I really need a working serialization library I'll try making 
one myself now. However I'm not very experienced with D in 
general and its reflection in particular so I could use some help.


I think in order to keep it simple I'll just have the user to 
write a function called Serialize() which calls the serializer 
which then just writes the values one after the other in a binary 
file (and, of course, for arrays and strings the length too). As 
all classes implement an interface called Serializable (with the 
function Serialize()), finding the right class to serialize won't 
be too hard (at least I think so). However then we have to make 
sure that we deserialize (instantiate) the right class.


Does the runtime have a function which give you something like a 
unique type id and another one which instantiates the type with 
the given id?


Something like:
int id = _magic_runtime_functions.getUniqueTypeId(typeid(T))
Serializable t = _magic_runtime_functions.createTypeOfId(...)

In order to make this clear I wrote some (untested and 
unfinished) code and pushed it into GitHub: 
https://github.com/nims1/interface-serialization-d/blob/master/Serializer.d
I know it still has a lot of problems (hopefully, D has a better 
way of writing binary files into memory...). It's just a quick 
draft.


How to use ranges?

2015-08-23 Thread Doolan via Digitalmars-d-learn
I keep running into areas of my code where it looks like I'd 
benefit from using ranges, and then I try to do some range stuff 
and my compiler tells me I'm using the wrong types, or there's 
this problem, or that problem... so I'm scared off and I just 
figure ways to work around using ranges.


I've tried reading the documentation, but for a language priding 
itself on being readable and nice to look at, it really should 
have less complicated docs:


auto tee(Flag!pipeOnPop pipeOnPop = Yes.pipeOnPop, R1, R2)(R1 
inputRange, R2 outputRange) if (isInputRange!R1  
isOutputRange!(R2, ElementType!R1));
auto tee(alias fun, Flag!pipeOnPop pipeOnPop = Yes.pipeOnPop, 
R1)(R1 inputRange) if (is(typeof(fun) == void) || 
isSomeFunction!fun);


(That's fine as secondary information, but this is the heading 
for this function...)


And the use of auto everywhere makes it really hard to tell what 
types I should be using for anything. My compiler talks about 
RangeT!(whatever) but you try to use RangeT!(whatever) and you 
find out RangeT is private...


I don't mean to complain so hard, I obviously like D enough to 
want to use it, just the current amount/layout of documentation 
can be frustrating at times.


Can someone give me a short summary of how to use ranges? And how 
do they relate to slices? That line is really blurry...


Re: (De)Serializing interfaces

2015-08-23 Thread nims via Digitalmars-d-learn

On Sunday, 23 August 2015 at 08:38:14 UTC, Rikki Cattermole wrote:
What I was thinking was having a serialize method take an 
output range which you will just pass in a value.
I'm not really sure what you mean. Replacing the operator by a 
range function or serializing everything automatically?



A hash? Yeah, TypeInfo_Class should. It will take a pointer.
https://github.com/D-Programming-Language/druntime/blob/master/src/object.d#L261

size_t hash = typeid(avalue).getHash(avalue);

But keep in mind avalue must be an rvalue.
Sounds good! How do I then create an instance having the same 
type?


My suggestion would be evaluate the type down aka get 
immutable(char) from immutable(char)[] aka string. So don't try 
to serialize the string straight. Grab the length put that to 
the output range, then try to serialize each of the values of 
the array individually as another function call to itself.


Same sort of deal with other classes, check that they have the 
interface and if so, call it's serialize method with yourself.


A little confusing I must admit.
I'm sorry I didn't get that. Would you have a piece of code for 
illustration?


Re: (De)Serializing interfaces

2015-08-23 Thread nims via Digitalmars-d-learn

On Sunday, 23 August 2015 at 03:25:27 UTC, Kapps wrote:
I've never used Orange, but one thing you could try is casting 
your object from MyInterface to Object, and registering the 
type Foobar like in 
http://dsource.org/projects/orange/wiki/Tutorials/SerializeBase, then serializing/deserializing it as Object rather than MyInterface. I'm not sure if this will work, but it's worth a try if it doesn't handle interfaces. Interfaces are a bit odd in some ways, as they are not necessarily classes



(and thus not implicitly convertible to Object)

I suspect that's what Orange is having trouble with.
/usr/local/include/d/orange/serialization/Serializer.di(254): 
Error: function pointer *serializer (Serializer, const(Object), 
Mode) is not callable using argument types (Serializer, 
MyInterface, Mode)
/usr/local/include/d/orange/serialization/Serializer.di(902): 
Error: template 
orange.serialization.Serializer.Serializer.serializeBaseTypes 
cannot deduce function from argument types !()(MyInterface), 
candidates are:
/usr/local/include/d/orange/serialization/Serializer.di(970): 
   
orange.serialization.Serializer.Serializer.serializeBaseTypes(T : 
Object)(inout T value)
/usr/local/include/d/orange/serialization/Serializer.di(259): 
Error: template instance 
orange.serialization.Serializer.Serializer.objectStructSerializeHelper!(MyInterface) error instantiating
/usr/local/include/d/orange/serialization/Serializer.di(157): 
   instantiated from here: serializeObject!(MyInterface)
/usr/local/include/d/orange/serialization/Serializer.di(386): 
   instantiated from here: serializeInternal!(MyInterface)
/usr/local/include/d/orange/serialization/Serializer.di(892): 
   instantiated from here: serializePointer!(MyInterface*)
/usr/local/include/d/orange/serialization/Serializer.di(259): 
   ... (2 instantiations, -v to show) ...
/usr/local/include/d/orange/serialization/Serializer.di(129): 
   instantiated from here: serializeInternal!(Foobar)

test.d(27):instantiated from here: serialize!(Foobar)

I also can't cast MyInterface to Foo because at compile time I 
have no idea whether Foo or another type implementing MyInterface 
is behind it. Registering doesn't change that.


Re: post on using go 1.5 and GC latency

2015-08-23 Thread Russel Winder via Digitalmars-d-learn
On Sun, 2015-08-23 at 11:26 +, rsw0x via Digitalmars-d-learn wrote:
 […]
 
 https://groups.google.com/forum/#!msg/golang
 -dev/pIuOcqAlvKU/C0wooVzXLZwJ
 25-50% performance decrease across the board in 1.4 with the 
 addition of write barriers, to an already slow language.

Garbage collection is a hard problem for performance oriented code. I
am sure someone will come up with a way of improving the Go one.
Across the board though does worry me, my codes never get a sweep.
D's garbage collector could also do with some work.

 random benchmarks of Go performing 3x(+) slower than C/C++/D, 
 some of these predate Go 1.4.
 https://github.com/kostya/benchmarks
 https://benchmarksgame.alioth.debian.org/u64/benchmark.php?test=alll
 ang=golang2=gccdata=u64
 https://togototo.wordpress.com/2013/07/23/benchmarking-level
 -generation-go-rust-haskell-and-d/ (gcc-go performed the _worst_)
 https://togototo.wordpress.com/2013/08/23/benchmarks-round-two
 -parallel-go-rust-d-scala-and-nimrod/ (and again)
 https://github.com/logicchains/LPATHBench/blob/master/writeup.md 
 (once again, Go is nowhere near C/C++/D/Rust. Where is it? 
 Hanging out with C#/Mono.)

Thanks for those pointers, I shall have a look at them. Sadly though
not for a couple of weeks due to various commitments.

 Go is slow. These aren't cherrypicked, just random samples from a 
 quick Googling.

But why use absolutes. Go may be slow for you in your context, but that
doesn't mean the observation applies everywhere (note the interesting
turn of phrase). For my (admittedly small) codes that do not cause a
garbage collect and are basically just a loop, I find things are fine.

So for a π approximation sequential code using 64-bit:

C, gcc -O3: 8.847241
C++, gcc -O3: 8.916043
Fortran, gfortran -O3: 8.893000
D, ldc -O -release: 8.722329
D, dmd -O -release: 8.787744
Rust, cargo --release: 8.715818
Go, gccgo: 8.823525
Go, 6g: 8.824643
 Go is definitely not slow there then. Thus Go is not slow.

 Where is Go performing C-level speeds at? D claims this, and D 
 shows it does. Go falls into the fast enough category, because 
 it is _not_ a general purpose programming language. So unless 
 multiple randomly sampled benchmarks are all wrong, I'm going to 
 stick with 'Go is slow.'

You are mixing too many factors here. General purpose has nothing to
do with performance, it is to do with can the language describe most if
not all forms of computation. Go is a general purpose programming
language just like C, C++, D, Rust, Haskell, OCaml.

If for you Go is not performant enough, that is fine. But for many
people in various contexts, Go is more the comparable with other
languages. This is not just Go is fast enough, but Go is as fast as
any other option.

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


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


Re: (De)Serializing interfaces

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

On 8/23/2015 10:17 PM, nims wrote:

On Sunday, 23 August 2015 at 08:38:14 UTC, Rikki Cattermole wrote:

What I was thinking was having a serialize method take an output range
which you will just pass in a value.

I'm not really sure what you mean. Replacing the operator by a range
function or serializing everything automatically?


Oh not quite. Humm, how to explain this.

import std.traits : isBasicType, isArray;

interface Serializable {
void serialize(OutputRange!ubyte);
void deserialize(InputRange!ubyte);

final void putValue(T)(OutputRange!ubyte output, ref T value) {
static if (isArray!T) {
putValue(output, value.length);
foreach(v; value)
putValue(v);
} else static if (isBasicType!T) {
// convert to ubytes ext. ext. and call put on output.
} else if (Serializable sv = cast(Serializable)value) {
sv.serialize(output);
} else {
static assert(0, I don't know how to handle this);
}
}

final T getValue(T)(InputRange!ubyte input) {
ubyte[T.sizeof] ret;
foreach(i; 0 .. T.sizeof)
ret[i] = input.moveFront;
return to!T(ret);
}
}

class ... : Serializable {
int x, y;
float z;

void serialize(OutputRange!ubyte output) {
output.putValue(x);
output.putValue(y);
output.putValue(z);
}

void deserialize(InputRange!ubyte input) {
x = input.getValue!int;
y = input.getValue!int;
z = input.getValue!float;
}
}


A hash? Yeah, TypeInfo_Class should. It will take a pointer.
https://github.com/D-Programming-Language/druntime/blob/master/src/object.d#L261


size_t hash = typeid(avalue).getHash(avalue);

But keep in mind avalue must be an rvalue.

Sounds good! How do I then create an instance having the same type?


The hash value won't help you much really. It's meant for comparing 
instances.



My suggestion would be evaluate the type down aka get
immutable(char) from immutable(char)[] aka string. So don't try to
serialize the string straight. Grab the length put that to the output
range, then try to serialize each of the values of the array
individually as another function call to itself.

Same sort of deal with other classes, check that they have the
interface and if so, call it's serialize method with yourself.

A little confusing I must admit.

I'm sorry I didn't get that. Would you have a piece of code for
illustration?


Take a look at the top code snippet.
You will probably want a couple of free functions be the function you 
call to serialize and deserialize. That way it can control embedding 
e.g. the class name as the first set of values. Which is trivial to use 
with the help of e.g. Object.factory or with the help of TypeInfo.init.


On that note I'll see about getting you a snippet of code that may 
interest you here.

If you can please come on[0] to make it slightly easier for me.

[0] https://gitter.im/rikkimax/chatWithMe



Re: How to use ranges?

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

On 8/23/2015 10:17 PM, Doolan wrote:

I keep running into areas of my code where it looks like I'd benefit
from using ranges, and then I try to do some range stuff and my compiler
tells me I'm using the wrong types, or there's this problem, or that
problem... so I'm scared off and I just figure ways to work around using
ranges.

I've tried reading the documentation, but for a language priding itself
on being readable and nice to look at, it really should have less
complicated docs:

auto tee(Flag!pipeOnPop pipeOnPop = Yes.pipeOnPop, R1, R2)(R1
inputRange, R2 outputRange) if (isInputRange!R1  isOutputRange!(R2,
ElementType!R1));
auto tee(alias fun, Flag!pipeOnPop pipeOnPop = Yes.pipeOnPop, R1)(R1
inputRange) if (is(typeof(fun) == void) || isSomeFunction!fun);

(That's fine as secondary information, but this is the heading for this
function...)

And the use of auto everywhere makes it really hard to tell what types I
should be using for anything. My compiler talks about RangeT!(whatever)
but you try to use RangeT!(whatever) and you find out RangeT is private...

I don't mean to complain so hard, I obviously like D enough to want to
use it, just the current amount/layout of documentation can be
frustrating at times.

Can someone give me a short summary of how to use ranges? And how do
they relate to slices? That line is really blurry...


Have a read of: 
https://github.com/rikkimax/twp-d/blob/master/manuscript/content/idioms/ranges.md


Let me know what you think :)


Re: (De)Serializing interfaces

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

On 8/23/2015 8:15 PM, nims wrote:

On Sunday, 23 August 2015 at 03:09:03 UTC, Rikki Cattermole wrote:

Anyway to summise why D doesn't yet have something akin to Java or C#.
Simply put, we generally work with the actual type not an interface.
So libraries like Orange can serialize/deserialize with great
certainty that it got everything.

However if you need any help with making such a library, please let me
know!


Actually I'm coming from C++ but I know a little bit about C# so your
explanation was helpful anyway! Thanks!

As I really need a working serialization library I'll try making one
myself now. However I'm not very experienced with D in general and its
reflection in particular so I could use some help.

I think in order to keep it simple I'll just have the user to write a
function called Serialize() which calls the serializer which then just
writes the values one after the other in a binary file (and, of course,
for arrays and strings the length too). As all classes implement an
interface called Serializable (with the function Serialize()), finding
the right class to serialize won't be too hard (at least I think so).
However then we have to make sure that we deserialize (instantiate) the
right class.


What I was thinking was having a serialize method take an output range 
which you will just pass in a value.



Does the runtime have a function which give you something like a unique
type id and another one which instantiates the type with the given id?


A hash? Yeah, TypeInfo_Class should. It will take a pointer.
https://github.com/D-Programming-Language/druntime/blob/master/src/object.d#L261


Something like:
int id = _magic_runtime_functions.getUniqueTypeId(typeid(T))


This should work

size_t hash = typeid(avalue).getHash(avalue);

But keep in mind avalue must be an rvalue.


Serializable t = _magic_runtime_functions.createTypeOfId(...)

In order to make this clear I wrote some (untested and unfinished) code
and pushed it into GitHub:
https://github.com/nims1/interface-serialization-d/blob/master/Serializer.d
I know it still has a lot of problems (hopefully, D has a better way of
writing binary files into memory...). It's just a quick draft.


My suggestion would be evaluate the type down aka get immutable(char) 
from immutable(char)[] aka string. So don't try to serialize the string 
straight. Grab the length put that to the output range, then try to 
serialize each of the values of the array individually as another 
function call to itself.


Same sort of deal with other classes, check that they have the interface 
and if so, call it's serialize method with yourself.


A little confusing I must admit.
Also small tip, std.traits is awesome. Especially isBasicType ;)


Re: post on using go 1.5 and GC latency

2015-08-23 Thread Russel Winder via Digitalmars-d-learn
On Sat, 2015-08-22 at 11:06 +, Laeeth Isharc via Digitalmars-d
-learn wrote:
 […]
 
 Builds in Go 1.5 will be slower by a factor of about two. The 
 automatic translation of the compiler and linker from C to Go 
 resulted in unidiomatic Go code that performs poorly compared to 
 well-written Go. Analysis tools and refactoring helped to improve 
 the code, but much remains to be done. Further profiling and 
 optimization will continue in Go 1.6 and future releases. For 
 more details, see these slides and associated video.
 

This is about compiler performance, not about generated code
performance.

Anyone interested in performance with Go currently uses gccgo: the
standard Go compiler does not generate particularly well optimized
code. This has been a resourcing choice to date, it is not a failing.
gccgo on the other hand makes use of the whole GCC optimization chain. 

On the other hand gc is blindingly fast at compilation compared to
gccgo. This seems reminiscent of dmd vs. ldc and gdc!

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


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


Re: post on using go 1.5 and GC latency

2015-08-23 Thread Russel Winder via Digitalmars-d-learn
On Sat, 2015-08-22 at 09:27 +, rsw0x via Digitalmars-d-learn wrote:
 […]
 
 The performance decrease has been there since 1.4 and there is no 
 way to remove it - write barriers are the cost you pay for 
 concurrent collection. Go was already much slower than other 
 compiled languages, now it probably struggles to keep up with 
 mono.

I know Walter hates it when people mention the word but: benchmarks.

As soon as someone say things like it probably struggles to keep up
with mono further discussion of the topic is probably not worth
entertaining without getting some agreed codes and running them all on
the same machine.

I agree the standard Go compiler generates not well optimized code, but
gccgo generally does, and generally performs at C-level speeds. Of
course Java often performs far better than that, and often fails to.
You have to be careful with benchmarking and performance things
generally.
 
-- 
Russel.
=
Dr Russel Winder  t: +44 20 7585 2200   voip: sip:russel.win...@ekiga.net
41 Buckmaster Roadm: +44 7770 465 077   xmpp: rus...@winder.org.uk
London SW11 1EN, UK   w: www.russel.org.uk  skype: russel_winder


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


Re: (De)Serializing interfaces

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

On Sunday, 23 August 2015 at 10:37:11 UTC, Rikki Cattermole wrote:

On 8/23/2015 10:17 PM, nims wrote:
On Sunday, 23 August 2015 at 08:38:14 UTC, Rikki Cattermole 
wrote:
What I was thinking was having a serialize method take an 
output range

which you will just pass in a value.
I'm not really sure what you mean. Replacing the operator by a 
range

function or serializing everything automatically?


Oh not quite. Humm, how to explain this.

import std.traits : isBasicType, isArray;

interface Serializable {
void serialize(OutputRange!ubyte);
void deserialize(InputRange!ubyte);

final void putValue(T)(OutputRange!ubyte output, ref T value) {
static if (isArray!T) {
putValue(output, value.length);
foreach(v; value)
putValue(v);
} else static if (isBasicType!T) {
// convert to ubytes ext. ext. and call put on output.
} else if (Serializable sv = cast(Serializable)value) {
sv.serialize(output);
} else {
static assert(0, I don't know how to handle this);
}
}

final T getValue(T)(InputRange!ubyte input) {
ubyte[T.sizeof] ret;
foreach(i; 0 .. T.sizeof)
ret[i] = input.moveFront;
return to!T(ret);
}
}

class ... : Serializable {
int x, y;
float z;

void serialize(OutputRange!ubyte output) {
output.putValue(x);
output.putValue(y);
output.putValue(z);
}

void deserialize(InputRange!ubyte input) {
x = input.getValue!int;
y = input.getValue!int;
z = input.getValue!float;
}
}


A hash? Yeah, TypeInfo_Class should. It will take a pointer.
https://github.com/D-Programming-Language/druntime/blob/master/src/object.d#L261


size_t hash = typeid(avalue).getHash(avalue);

But keep in mind avalue must be an rvalue.
Sounds good! How do I then create an instance having the same 
type?


The hash value won't help you much really. It's meant for 
comparing instances.



My suggestion would be evaluate the type down aka get
immutable(char) from immutable(char)[] aka string. So don't 
try to
serialize the string straight. Grab the length put that to 
the output

range, then try to serialize each of the values of the array
individually as another function call to itself.

Same sort of deal with other classes, check that they have the
interface and if so, call it's serialize method with yourself.

A little confusing I must admit.

I'm sorry I didn't get that. Would you have a piece of code for
illustration?


Take a look at the top code snippet.
You will probably want a couple of free functions be the 
function you call to serialize and deserialize. That way it can 
control embedding e.g. the class name as the first set of 
values. Which is trivial to use with the help of e.g. 
Object.factory or with the help of TypeInfo.init.


On that note I'll see about getting you a snippet of code that 
may interest you here.

If you can please come on[0] to make it slightly easier for me.

[0] https://gitter.im/rikkimax/chatWithMe


Short summary of code snippets:

~~~
module dnetdev.webserver.common.classfinder;

Interface findAndCreateClass(Interface)(string name) if 
(is(Interface == class) || is(Interface == interface)) {

import std.experimental.allocator;
auto alloc = theAllocator();

auto classinfo = TypeInfo_Class.find(name);
if (classinfo is null)
return null;

size_t issize = classinfo.init.length;
void[] dataallocated = alloc.allocate(issize);

Object obj;
dataallocated[] = cast(void[])classinfo.init[];
if (dataallocated is null)
return null;

obj = cast(Object)dataallocated.ptr;

if (obj !is null) {
if (classinfo.defaultConstructor !is null)
(cast(void 
function(Object))classinfo.defaultConstructor)(obj);


if (Interface obj2 = cast(Interface)obj) {
return obj2;
} else {
alloc.dispose(obj);
return null;
}
} else {
alloc.dispose(dataallocated);
return null;
}
}
~~~

~~~
void main() {
int x;
foo!x(x);
}

void foo(alias T)(typeof(T) v) {
pragma(msg, T.stringof);
}



import std.stdio;

interface Foo {
final void func(this T)(/* output */) {
writeln(T.stringof);
foreach(v; __traits(allMembers, T))
writeln(v);
}
}

class Bar : Foo {
int x;
}

void main() {
Bar b = new Bar;
b.func();
}
~


Re: How to use ranges?

2015-08-23 Thread anonymous via Digitalmars-d-learn
On Sunday 23 August 2015 12:17, Doolan wrote:

 And the use of auto everywhere makes it really hard to tell what
 types I should be using for anything. My compiler talks about
 RangeT!(whatever) but you try to use RangeT!(whatever) and you
 find out RangeT is private...

You can use typeof to get the type of a range expression when typing it out 
is impractical/impossible.

 Can someone give me a short summary of how to use ranges?

I'm not sure what exactly you're looking for. The documentation for tee has 
some example code. How about you show something you're having trouble with?

 And how do they relate to slices? That line is really blurry...

Slice is a synonym for what the spec calls a dynamic array, i.e. a 
structure containing a pointer and a length.

Slicing a dynamic array, static array, or pointer produces a dynamic 
array, referencing (not copying) the sliced elements:


int[] d = [1, 2, 3, 4]; /* dynamic array */
int[] slice = d[1 .. 3];
assert(slice == [2, 3]);

d[1] = 20;
assert(slice[0] == 20);

int[4] s = [1, 2, 3, 4]; /* static array */
slice = s[];
assert(slice == [1, 2, 3, 4]);

int* p = [1, 2, 3, 4].ptr; /* pointer */
slice = p[1 .. 3];
assert(slice == [2, 3]);


Note that the source types are different, but slicing them yields the same 
type every time: int[].

Generally, dynamic arrays / slices are random-access ranges. Narrow strings 
(string/wstring/char[]/wchar[]/...) are a notable exception to this. They 
are dynamic arrays of UTF-8/UTF-16 code units. But they're not random-access 
ranges of Unicode code units. Instead, they're _forward_ ranges of Unicode 
code _points_ (dchar). They have special range primitives that to the 
decoding.



Re: How to use ranges?

2015-08-23 Thread welkam via Digitalmars-d-learn

There was a talk on ranges in Dconf 2015
https://www.youtube.com/watch?v=A8Btr8TPJ8clist=PLEDeq48KhndP-mlE-0Bfb_qPIMA4RrrKoindex=10


Re: post on using go 1.5 and GC latency

2015-08-23 Thread via Digitalmars-d-learn

On Saturday, 22 August 2015 at 12:48:31 UTC, rsw0x wrote:
The problem with D's GC is that there's no scaffolding there 
for it, so you can't really improve it.

At best you could make the collector parallel.

If I had the runtime hooks and language guarantees I needed I'd 
begin work on a per-thread GC immediately.


If you had a fiber local reference type and some guarantees 
related to that, you probably could do a per-fiber GC and collect 
when fibers are waiting.




Trying to compile weather program

2015-08-23 Thread Tony via Digitalmars-d-learn
I found this weather program on the main page (it seems to rotate 
what it here):


// Get your local weather report
pragma(lib, curl);
import std.functional, std.json, std.net.curl,
std.stdio, std.string;

alias getJSON = pipe!(get, parseJSON);
auto K2C = (float f) = f - 273.15;
auto K2F = (float f) = f / 5 * 9 - 459.67;

void main()
{
auto loc = getJSON(ipinfo.io/)[loc]
.str.split(,);
auto resp = getJSON(
api.openweathermap.org/data/2.5/weather ~
?lat= ~ loc[0] ~ lon= ~ loc[1]);

auto city = resp[name].str;
auto country = resp[sys][country].str;
auto desc = resp[weather][0][description].str;
auto temp = resp[main][temp].floating;

writefln(`
+-+
|%s|
+-+
|  weather  |  %-23s|
+-+
|  temperature  |  %.2f°C (%.2f°F)  |
+-+
`.outdent,
centerJustifier(city ~ ,  ~ country, 41),
desc, temp.K2C, temp.K2F);
}

I am compiling on Ubuntu 14.02 with DMD v2.066.1

I get this compile error:

weather_report.d(32): Error: undefined identifier centerJustifier


Digger 2.3 verstr.h problem

2015-08-23 Thread Robert M. Münch via Digitalmars-d-learn

Hi, just trying to build the latest DMD with Digger 2.3 and get this:

uffer.d root/port.d root/response.d root/rmem.d root/rootobject.d 
root/speller.d root/stringtable.d newdelete.o glue.a backend.a
globals.d(293): Error: file verstr.h cannot be found or not in a path 
specified with -J

make: *** [dmd] Error 1
digger: Saving to cache.
digger: Clearing temporary cache
Fatal error: Command [make, -f, posix.mak, MODEL=64, 
HOST_DC=/Volumes/Daten/Windows/d/develop/d-language/Digger/dl/dmd-2.067.1/dmd2/osx/bin/dmd, 
dmd] failed with status 2

mac-pro:Digger robby$ find . -name verstr.h
./repo/dmd/src/verstr.h
mac-pro:Digger robby$ find . -name globals.d
./repo/dmd/src/globals.d
mac-pro:Digger robby$

I'm wondering why the verstr.h file can't be found... it's in the 
same dir as from where the import happens. Any ideas?


--
Robert M. Münch
http://www.saphirion.com
smarter | better | faster



Re: post on using go 1.5 and GC latency

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

On Sunday, 23 August 2015 at 11:06:20 UTC, Russel Winder wrote:
On Sat, 2015-08-22 at 09:27 +, rsw0x via 
Digitalmars-d-learn wrote:

[…]

The performance decrease has been there since 1.4 and there is 
no way to remove it - write barriers are the cost you pay for 
concurrent collection. Go was already much slower than other 
compiled languages, now it probably struggles to keep up with 
mono.


I know Walter hates it when people mention the word but: 
benchmarks.


As soon as someone say things like it probably struggles to 
keep up with mono further discussion of the topic is probably 
not worth entertaining without getting some agreed codes and 
running them all on the same machine.


I agree the standard Go compiler generates not well optimized 
code, but
gccgo generally does, and generally performs at C-level speeds. 
Of
course Java often performs far better than that, and often 
fails to.

You have to be careful with benchmarking and performance things
generally.


https://groups.google.com/forum/#!msg/golang-dev/pIuOcqAlvKU/C0wooVzXLZwJ
25-50% performance decrease across the board in 1.4 with the 
addition of write barriers, to an already slow language.


random benchmarks of Go performing 3x(+) slower than C/C++/D, 
some of these predate Go 1.4.

https://github.com/kostya/benchmarks
https://benchmarksgame.alioth.debian.org/u64/benchmark.php?test=alllang=golang2=gccdata=u64
https://togototo.wordpress.com/2013/07/23/benchmarking-level-generation-go-rust-haskell-and-d/
 (gcc-go performed the _worst_)
https://togototo.wordpress.com/2013/08/23/benchmarks-round-two-parallel-go-rust-d-scala-and-nimrod/
 (and again)
https://github.com/logicchains/LPATHBench/blob/master/writeup.md 
(once again, Go is nowhere near C/C++/D/Rust. Where is it? 
Hanging out with C#/Mono.)


Go is slow. These aren't cherrypicked, just random samples from a 
quick Googling.
Where is Go performing C-level speeds at? D claims this, and D 
shows it does. Go falls into the fast enough category, because 
it is _not_ a general purpose programming language. So unless 
multiple randomly sampled benchmarks are all wrong, I'm going to 
stick with 'Go is slow.'


Re: How to use ranges?

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

On 8/24/2015 12:52 AM, Doolan wrote:

On Sunday, 23 August 2015 at 10:38:53 UTC, Rikki Cattermole wrote:

On 8/23/2015 10:17 PM, Doolan wrote:
Have a read of:
https://github.com/rikkimax/twp-d/blob/master/manuscript/content/idioms/ranges.md


Let me know what you think :)


I think I'm a little more confused than before... this says there are
two kinds of ranges and I thought there were five??


There are more, but input/output ranges are the core two.
They underpin all the others.

Generally speaking these are the two that you will be using. The others 
such as ForwardRange are really just optional extras.


Re: How to use ranges?

2015-08-23 Thread Doolan via Digitalmars-d-learn

On Sunday, 23 August 2015 at 10:38:53 UTC, Rikki Cattermole wrote:

On 8/23/2015 10:17 PM, Doolan wrote:
Have a read of: 
https://github.com/rikkimax/twp-d/blob/master/manuscript/content/idioms/ranges.md


Let me know what you think :)


I think I'm a little more confused than before... this says there 
are two kinds of ranges and I thought there were five??


order of declaration/definition

2015-08-23 Thread John Colvin via Digitalmars-d-learn

enum A = 1;
enum B = C; //Error
static if(A)
enum C = 0;
enum D = C; //OK

Is order supposed to matter here?


Templates and writing variable number of arguments

2015-08-23 Thread Andre Polykanine via Digitalmars-d-learn
Hi everyone,
It's me again.
Now  I'm  struggling  with  the  `output` member function which should
output  a  string  either  to  stdout  or  to a file, depending on the
parameter.
However,  I would like it to work like `writefln` with variable number
of arguments:
output(Hello %s!, world); // should be OK
output(%s  %s:  %s  %d  times,  I, say, Hello world!, 500); //
Should also be OK

Here is my code:

final void output(T)(string text, T params...) const {
if (this.outFile == ) {
writefln(text, params);
} else { // Output to a file
auto f = File(this.outFile, w);
try {
f.writefln(text, params);
} catch(Exception e) {
writefln(Unable to write to %s: %s, 
this.outFile, e.msg);
}
}
}

And the compiler says it can't deduce the type of arguments.
What am I doing wrong here?
Maybe, I don't need such a function and all and there is a way to make
it more elegant?
Thanks!

-- 
With best regards from Ukraine,
Andre
Skype: Francophile
Twitter: @m_elensule; Facebook: menelion
My blog: http://menelion.oire.org/



Re: Templates and writing variable number of arguments

2015-08-23 Thread ted via Digitalmars-d-learn

try replacing:
final void output(T)(string text, T params...) const {
with
 final void output(T...)(string text, T params) const {


Andre Polykanine via Digitalmars-d-learn wrote:

 Hi everyone,
 It's me again.
 Now  I'm  struggling  with  the  `output` member function which should
 output  a  string  either  to  stdout  or  to a file, depending on the
 parameter.
 However,  I would like it to work like `writefln` with variable number
 of arguments:
 output(Hello %s!, world); // should be OK
 output(%s  %s:  %s  %d  times,  I, say, Hello world!, 500); //
 Should also be OK
 
 Here is my code:
 
 final void output(T)(string text, T params...) const {
 if (this.outFile == ) {
 writefln(text, params);
 } else { // Output to a file
 auto f = File(this.outFile, w);
 try {
 f.writefln(text, params);
 } catch(Exception e) {
 writefln(Unable to write to %s: %s,
 this.outFile, e.msg);
 }
 }
 }
 
 And the compiler says it can't deduce the type of arguments.
 What am I doing wrong here?
 Maybe, I don't need such a function and all and there is a way to make
 it more elegant?
 Thanks!