Re: Error: Undefined identifier when moving import to another module

2014-10-19 Thread monarch_dodra via Digitalmars-d-learn

On Sunday, 19 October 2014 at 09:39:05 UTC, nrgyzer wrote:

Hi guys,

when I do the following:
  static if ( isCallable!(mixing(m) )


mixing ?


void main() { /* do something here */ }


What exactly are you doing here?


... I'm getting many error messages like these:

myMain.d-mixin-11(11): Error: undefined identifier 
_D12TypeInfo_xAa6__initZ
myMain.d-mixin-11(11): Error: undefined identifier 
_D49TypeInfo_xAS3std8typecons16__T5TupleTkTkTkZ5Tuple6__initZ

myMain.d-mixin-11(11): Error: undefined identifier


Sounds like your import was also import std.typecons which 
appears to have been required in your main.


Re: Error: Undefined identifier when moving import to another module

2014-10-19 Thread monarch_dodra via Digitalmars-d-learn

On Sunday, 19 October 2014 at 16:09:41 UTC, nrgyzer wrote:
mixing should be replaced with mixin: static if ( 
isCallable!(mixin(m) )


My main is empty in both cases. So nothing done in my main 
(currently).


Posting full code that actually compiles and reproduces the issue 
helps.


Re: Formatted output of range of tuples

2014-10-13 Thread monarch_dodra via Digitalmars-d-learn

On Wednesday, 8 October 2014 at 23:28:34 UTC, bearophile wrote:

anonymous:


You can turn the tuples into ranges with `only`:

writef(%(%(%s %)\n%), zip(indexes, source).map!(t = 
only(t.expand)));


This is a nice idea. Expand can probably be replaced by a []. I 
presume this works only if the types inside the tuple are the 
same.


Expand creates returns a TypeTuple though, so it's arguably 
free. [] allocates a dynamic array, so is costly.


On the flip side, only is *entirelly* by value, and carries all 
its arguments. If the tuple is big, then the range can become 
quite big.


Re: DList!int.remove(range.takeOne) - workarounds?

2014-10-12 Thread monarch_dodra via Digitalmars-d-learn

On Sunday, 12 October 2014 at 09:45:22 UTC, Algo wrote:

DList seems to have an issue with remove:

void main()
{
import std.container, std.range, std.algorithm;
auto list = DList!int([1, 2, 4, 6]);
auto res = find(list[], 2);
list.remove(res); //ok
/*
list.remove(res.takeOne);
Error: function std.container.dlist.DList!int.DList.remove 
(Range r) is not callable using argument types (Result)

list.remove(res.take(1));
Error: function std.container.dlist.DList!int.DList.remove 
(Range r) is not callable using argument types (Take!(Range))

*/
}

Are there any known workarounds besides linearRemove?


There is (unfortunatly) no support for takeOne in DList.

However, linearRemove is not a workaround or worst than remove. 
It is just that it accepts a wider range of input, when O(1) 
cannot be guaranteed. If you are operating with a range of length 
1, then linearRemove is still O(1).




Re: Splitting Ranges using Lambda Predicates

2014-10-10 Thread monarch_dodra via Digitalmars-d-learn

On Friday, 10 October 2014 at 05:55:00 UTC, Nordlöw wrote:
On Thursday, 9 October 2014 at 22:01:31 UTC, monarch_dodra 
wrote:
My quick guess is you are missing the *global* imports for the 
restraints. The compiler doesn't complain because the 
constraint is in a is(typeof(...)) test. The reason the 
typeof fails is simply cause the compiler has no idea what 
unaryFun is.


I don't understand. The restraints are commented out at

https://github.com/nordlow/justd/blob/master/slicer.d

I made a couple of changes and now it works but I don't quite 
understand why...


Thanks anyway.


Sorry, I read your compile error wrong, and was on my phone.

Anyways, I'm a bit worried, because it looks like an internal 
phobos compile error. May I request you attempt to re-create and 
potentially reduce the issue? I want to make sure you didn't 
uncover a bug...


Re: Splitting Ranges using Lambda Predicates

2014-10-09 Thread monarch_dodra via Digitalmars-d-learn

On Thursday, 9 October 2014 at 21:55:03 UTC, Nordlöw wrote:

On Wednesday, 11 June 2014 at 08:58:58 UTC, monarch_dodra wrote:

auto slicer(alias isTerminator, Range)(Range input)
if (((isRandomAccessRange!Range  hasSlicing!Range) || 
isSomeString!Range)

is(typeof(unaryFun!isTerminator(input.front
{
   return SlicerResult!(unaryFun!isTerminator, Range)(input);
}
...


Your solution copied here

https://github.com/nordlow/justd/blob/master/slicer.d

errors as
/home/per/opt/x86_64-unknown-linux-gnu/dmd/linux/bin64/src/phobos/std/algorithm.d(5752,24): 
Error: template std.functional.not!(isUpper).not cannot deduce 
function from argument types !()(dchar), candidates are:

/home/per/opt/x86_64-unknown-linux-gnu/dmd/linux/bin64/src/phobos/std/functional.d(393,10):
   std.functional.not!(isUpper).not(T...)(T args) if 
(is(typeof(!unaryFun!pred(args))) || 
is(typeof(!binaryFun!pred(args
slicer.d(29,31): Error: template instance 
std.algorithm.find!(not, string) error instantiating
slicer.d(16,12):instantiated from here: 
Slicer!(isUpper, string)
slicer.d(85,30):instantiated from here: 
slicer!(isUpper, string)


What's wrong?


My quick guess is you are missing the *global* imports for the 
restraints. The compiler doesn't complain because the constraint 
is in a is(typeof(...)) test. The reason the typeof fails is 
simply cause the compiler has no idea what unaryFun is.


Re: coding practices: include whole module or only the needed function

2014-10-07 Thread monarch_dodra via Digitalmars-d-learn

On Tuesday, 7 October 2014 at 07:33:24 UTC, Gary Willoughby wrote:

On Monday, 6 October 2014 at 21:24:56 UTC, AsmMan wrote:
Which practice do you use: if you need only one or two 
functions from a module:


import myModule : func, func2;

or (import whole module, assuming no function name conflits of 
course)


import myModule;

any words why one over the other are welcome.

I like the first one why it explicitly show why I'm importing 
such a module and I think (personally) it make code more easy 
to read/understand/maitain. Also it's very useful inside 
functions (local imports) where we can overload the function 
like in:


int f(int arg)
{
  import foo : f;

  return f(somethingElse, arg);
}

I used it recently.


Be mindful of this classic bug: 
https://issues.dlang.org/show_bug.cgi?id=314


Yeah. In the current state of affairs, please NEVER do selective 
imports in global scope. As a general rule, avoid imports in 
global scope anyways.


Re: coding practices: include whole module or only the needed function

2014-10-07 Thread monarch_dodra via Digitalmars-d-learn
On Tuesday, 7 October 2014 at 17:29:45 UTC, ketmar via 
Digitalmars-d-learn wrote:

On Tue, 07 Oct 2014 17:24:40 +
bachmeier via Digitalmars-d-learn 
digitalmars-d-learn@puremagic.com

wrote:

On Tuesday, 7 October 2014 at 08:37:59 UTC, monarch_dodra 
wrote:

 As a general rule, avoid imports in global scope anyways.
Can you expand or provide a link to the issue?

ahem...
https://issues.dlang.org/show_bug.cgi?id=313
https://issues.dlang.org/show_bug.cgi?id=314


That's only relative to having selective imports.

The idea of avoiding global imports is mostly to avoid polluting 
your own namespace, or to keep better track of who needs what.


For example, if 1 function requires std.foo, and then you later 
remove that function. With global imports, chances are you'll 
forget to remove it.


Re: array append result type

2014-10-06 Thread monarch_dodra via Digitalmars-d-learn

On Monday, 6 October 2014 at 11:28:16 UTC, John Colvin wrote:

string a;
char[] b;
pragma(msg, typeof(a ~ b)); // char[]

why not string?

What are the rules that determine this?


*Ideally*, I'd have said it returns char[], so that you can 
chose via purity.


However, it's not pure, so that argument doesn't hold.

That said, casting to immutable is safe provided you never 
actually mutate. The reverse isn't true.


To answer the question directly though, I don't know what the 
rules are. I'd guess they are mostly whatever druntime 
implemented though...


Re: array append result type

2014-10-06 Thread monarch_dodra via Digitalmars-d-learn
On Monday, 6 October 2014 at 16:38:37 UTC, Steven Schveighoffer 
wrote:
I filed this ER ages ago: 
https://issues.dlang.org/show_bug.cgi?id=1654


Not sure if anyone has it on their radar at this point.

-Steve


I didn't read the whole thing, but wouldn't purity be a major 
game changer for 1654?


Re: slidingSplitter + retro

2014-10-06 Thread monarch_dodra via Digitalmars-d-learn

On Monday, 6 October 2014 at 20:06:41 UTC, Nordlöw wrote:

I've almost satisfied with my new range slidingSplitter at

https://github.com/nordlow/justd/blob/master/range_ex.d#L19

All unittest work as expected except my radial test

https://github.com/nordlow/justd/blob/master/range_ex.d#L243

which, I believe, incorrectly prints

Tuple!(int[], int[])([1, 2], [3])
Tuple!(int[], int[])([1, 2], [3])
Tuple!(int[], int[])([1], [2, 3])
Tuple!(int[], int[])([1, 2, 3], [])
Tuple!(int[], int[])([], [1, 2, 3])

I cannot understand why the line

Tuple!(int[], int[])([1, 2], [3])

is printed twice at the beginning.

Have I done something wrong in my implementation of opIndex or 
opSlice?


I don't have time to investigate tonight, and it's probably not 
it, but your save isn't saving _upper.


I don't know how your radial works. Does the first back print 
([1, 2, 3], []) as it should?


Re: How to detect start of Unicode symbol and count amount of graphemes

2014-10-05 Thread monarch_dodra via Digitalmars-d-learn

On Sunday, 5 October 2014 at 08:27:58 UTC, Uranuz wrote:
I have struct StringStream that I use to go through and parse 
input string. String could be of string, wstring or dstring 
type. I implement function popChar that reads codeUnit from 
Stream. I want to have *debug* mode of parser (via CT switch), 
where I could get information about lineIndex, codeUnitIndex, 
graphemeIndex. So I don't want to use *front* primitive because 
it autodecodes everywhere, but I want to get info abot index of 
*user perceived character* in debug mode (so decoding is needed 
here).


Question is how to detect that I go from one Unicode grapheme 
to another when iterating on string, wstring, dstring by code 
unit? Is it simple or is it attempt to reimplement a big piece 
of existing std library code?


You can use std.uni.byGrapheme to iterate by graphemes:
http://dlang.org/phobos/std_uni.html#.byGrapheme

AFAIK, graphemes are not self synchronizing, but codepoints 
are. You can pop code units until you reach the beginning of a 
new codepoint. From there, you can iterate by graphemes, though 
your first grapheme might be off.


Re: RFC on SlidingSplitter Range

2014-10-03 Thread monarch_dodra via Digitalmars-d-learn

On Friday, 3 October 2014 at 15:22:06 UTC, Nordlöw wrote:

Destroy, please!


As a quick comment, your definition of moveFront is not what 
phobos understands with moveFront:

https://github.com/D-Programming-Language/phobos/blob/7914fa31cb3b53f4e50421399f2b99d2012e8031/std/range.d#L8267

Namelly, the idea of moveFront, is simply that it takes the front 
and std.algorithm.move's it.


If anything, I'd have expected you to provide something returns 
the popped element. What you do pops an element, and then returns 
the *next* one. What good is that?


Also, what you want to check is hasSlicing, which is more 
powerful than isRA. Speaking of which, if you don't have 
isRA, it looks like your range errors out (no front).


Your sliding splitter does not handle narrow strings. I'd have 
thought that was the original goal. Well, it is better to not 
support it at all of course, rather than doing it wrong :)


Re: RFC on SlidingSplitter Range

2014-10-03 Thread monarch_dodra via Digitalmars-d-learn

On Friday, 3 October 2014 at 17:06:41 UTC, Nordlöw wrote:

On Friday, 3 October 2014 at 16:32:24 UTC, monarch_dodra wrote:
If anything, I'd have expected you to provide something 
returns the popped element. What you do pops an element, and 
then returns the *next* one. What good is that?


My mistake. It's fixed now.


Well, yes and no. You are still providing a moveFront that does 
not conform to what the range interface expects. EG:


auto app = appender();
auto myRange = slidingSplitter([1, 2, 3]);
for ( ; !myRange.empty ; myRange.popFront() )
  app.put(myRange.moveFront());

As you can see from this code snippet, moveFront is not expected 
to pop. At all. As a matter of fact, this will error out during 
runtime, as the loop will attempt a pop on an empty range.


IMO, you should just leave it out.

Also, what you want to check is hasSlicing, which is more 
powerful than isRA. Speaking of which, if you don't have 
isRA, it looks like your range errors out (no front).


Ok. Fixed know.


There's still the issue that if you don't have slicing, then your 
range doesn't have front at all. You might as well just make it 
a general template restriction.


Your sliding splitter does not handle narrow strings. I'd have 
thought that was the original goal. Well, it is better to not 
support it at all of course, rather than doing it wrong :)


That's part of episode 2, for now ;)


Cool.

More things I saw:
Don't make opIndex const. You have no guarantee R.opindex is 
const.
Also, opSlice() is not a range primitive. You can implement it, 
it's basically just a no-op. The one that's important is 
opSlice(lhs, rhs).


Also, no point in returning an auto ref from slidingSplitter, 
you *know* it's an rvalue.


If your implementation use two ranges that you slice on the 
fly, then you can trivially support strings, thanks to popFront.


I threw this together. I left out checks for infinity in favor of 
brevity:


//
import std.range, std.stdio;
import std.typecons: Tuple, tuple;

struct SlidingSplitter(R)
if (hasSlicing!R || isSomeString!R)
{
this(R)(R data)
{
_original = data;
_right = data.save;
}

auto front() @property
{
return tuple(_original[0 .. $ - _right.length], _right);
}

void popFront()
{
if (_right.empty)
_original = _right;
else
_right.popFront();
}

bool empty() const { return _original.empty; }

static if (hasSlicing!R)
{
auto opIndex(size_t i)
{
return tuple(
_original[0 .. i + $ - _right.length],
_right[i .. $]);
}

size_t length() { return _right.length + 1; }
}

private R _original;
private R _right;
}

auto slidingSplitter(R)(R data)
{
return SlidingSplitter!R(data);
}

void main()
{
{
auto r = slidingSplitter([1, 2, 3]);
writefln(r.length: %s, r.length);
writefln(r[1]: %s, r[1]);
writefln(r[2]: %s, r[2]);
}
{
writefln(%(%s\n%), slidingSplitter(Nordlöw));
}
}
//

Output:

r.length: 4
r[1]: Tuple!(int[], int[])([1], [2, 3])
r[2]: Tuple!(int[], int[])([1, 2], [3])
Tuple!(string, string)(, Nordlöw)
Tuple!(string, string)(N, ordlöw)
Tuple!(string, string)(No, rdlöw)
Tuple!(string, string)(Nor, dlöw)
Tuple!(string, string)(Nord, löw)
Tuple!(string, string)(Nordl, öw)
Tuple!(string, string)(Nordlö, w)
Tuple!(string, string)(Nordlöw, )


Re: RFC on SlidingSplitter Range

2014-10-03 Thread monarch_dodra via Digitalmars-d-learn

On Friday, 3 October 2014 at 19:12:54 UTC, Nordlöw wrote:

On Friday, 3 October 2014 at 17:46:18 UTC, monarch_dodra wrote:
If your implementation use two ranges that you slice on the 
fly, then you can trivially support strings, thanks to 
popFront.


Very clever. That's what I wanted.


I threw this together.


Superb!

It could be motivated to use

static if (isRandomAccessRange!R)
{
// my solution for member functions...
private R _data;
private size_t _index;
else // assumes R is either string or wstring
{
// your solution for member functions...
private R _original;
private R _right;
}

to save space in the RA-case, right?


The idea is to try to keep as much code in common as possible. 
You can keep your version, provided you write this for popFront:


void popFront()
{
if (_index  _data.length)
{
static if (isNarrowString!R)
_index += stride(_data, _index)
else
++_index;
}
}


Is isRandomAccessRange!R the correct way to check for this?


Either that or isNarrowString. given the restrictions, both are 
correct.



Nice unittest ;)


Thanks ;)


I left out checks for infinity in favor of brevity:


Last thing for now:
- What do you mean by this?


I mean that this would not work if you passed in a repeat(5) 
even though repeat verifies RA and hasSlicing. That's because 
there's a point where you check for length.


The correct restrictions should have been:
if (isSomeString || hasSlicing  !isInfinite)

Note that this works regardless of operator precedence.


- Do I have to indicate that this range is not infinite?


You indicate a range is infinite with an enum empty = false;. 
By having a run-time empty, you are implicitly stating you are 
not infinite.


...


That said...
You could perfectly well support infinite ranges, with the 
correct static ifs. You'd produce an infinite sliding splitter.


Re: RFC on SlidingSplitter Range

2014-10-03 Thread monarch_dodra via Digitalmars-d-learn

On Friday, 3 October 2014 at 19:46:10 UTC, Nordlöw wrote:
Is prefix ++ preferred in D because of some specific reason? I 
recall it, for some containers/iterators, gives smaller/faster 
codegen in C++?


Be it C, C++ or D, pre increment is maybe faster, and is never 
slower.


So as a rule of thumb, unless you should *specifically* require 
post increment, pre-increment is to be prefered, though in 95% of 
the cases, it results in the same code.


Re: RFC on SlidingSplitter Range

2014-10-03 Thread monarch_dodra via Digitalmars-d-learn

On Friday, 3 October 2014 at 20:28:24 UTC, Nordlöw wrote:

On Friday, 3 October 2014 at 20:15:33 UTC, Nordlöw wrote:

Could you please take a look again at


I made another update at

https://github.com/nordlow/justd/blob/master/range_ex.d#L15

I had forgotten to move front and popFront out of static if 
hasSlicing!R


Now

auto name = slidingSplitter(Nordlöw);

errors

range_ex.d(41,24): Error: incompatible types for ((this._index) 
+= (stride(this._data, this._index))): 'ulong' and 'Result'
range_ex.d(88,12): Error: template instance 
range_ex.SlidingSplitter!string error instantiating
range_ex.d(131,32):instantiated from here: 
slidingSplitter!string


It must be resolving to std.range.stride. You want std.utf.stride.


Re: RFC on SlidingSplitter Range

2014-10-03 Thread monarch_dodra via Digitalmars-d-learn

On Friday, 3 October 2014 at 20:15:33 UTC, Nordlöw wrote:
Note that I had to tweak empty() a bit. I don't know if I got 
right. Could you check?


Sounds about right, but I didn't really look.


Further I can't get string support to work:

writefln(%(%s\n%), slidingSplitter(Nordlöw));

errors as

std.format.FormatException@/home/per/opt/x86_64-unknown-linux-gnu/dmd/linux/bin64/src/phobos/std/format.d(2591): 
Expected '%s' format specifier for type 'SlidingSplitter!string'


and

foreach (e; name)
{
version(show) writeln(e);
}

errors as

range_ex.d(132,5): Error: invalid foreach aggregate name, 
define opApply(), range primitives, or use .tupleof


which diagnostics I btw is responsible for :)

Could you please check?


Sounds like your range isn't a range. Did you check that:
isInputRange!(SlidingSplitter!string)
?

As mentioned in the first reply, it's a very important check, as 
it's very easy to get wrong.


For example, if you forget to mark front and empty as properties, 
then you don't have the correct range interface I believe.



On Friday, 3 October 2014 at 17:46:18 UTC, monarch_dodra wrote:

   writefln(%(%s\n%), slidingSplitter(Nordlöw));


That's a really cool syntax, btw. I got to remember that.


Yup. Love it. Use it.


Re: Find Semantically Correct Word Splits in UTF-8 Strings

2014-10-02 Thread monarch_dodra via Digitalmars-d-learn

On Wednesday, 1 October 2014 at 21:34:40 UTC, Nordlöw wrote:
On Wednesday, 1 October 2014 at 17:09:57 UTC, monarch_dodra 
wrote:
Does that even work? takeExactly would pop up to N 
*codepoints*, whereas your string only has N *codeunits*.


Your're right again :)

If forgot that takeExactly auto-decodes.


Technically, it only pops. It's front/popFront that auto-decode.


Re: How do I check if a function got CTFE?

2014-10-02 Thread monarch_dodra via Digitalmars-d-learn

On Thursday, 2 October 2014 at 18:42:56 UTC, AsmMan wrote:
I was thiking the dmd compiler did CTFE without someone ask for 
this, in the way as I've mentioned, checking for constant 
arguments + function's purity and if all this is true, it did 
the CTFE rather than generate code to compute it at run-time. 
In the case of it did happen, I just wanted to know. It was my 
misunderstsooding how it does works in dmd.


A convenient way to force ctfe is eval:
http://dlang.org/function.html (search for eval!)
Though you'd change const for enum.

Unfortunately, it's not in Phobos, but it should be!
https://issues.dlang.org/show_bug.cgi?id=11811


Re: Find Semantically Correct Word Splits in UTF-8 Strings

2014-10-01 Thread monarch_dodra via Digitalmars-d-learn

On Wednesday, 1 October 2014 at 11:47:41 UTC, Nordlöw wrote:

On Wednesday, 1 October 2014 at 11:06:24 UTC, Nordlöw wrote:

I'm looking for a way to make my algorithm



Update:

S[] findMeaningfulWordSplit(S)(S word,
   HLang[] langs = []) if 
(isSomeString!S)

{
for (size_t i = 1; i + 1  word.length; i++)
{
const first = word.takeExactly(i).to!string;
const second = word.dropExactly(i).to!string;
if (this.canMeanSomething(first, langs) 
this.canMeanSomething(second, langs))
{
return [first,
second];
}
}
return typeof(return).init;
}

works but has unfortunately O(word.length^^2) time-complexity.

Do we need a new InputRange algorithm for this?


This seems like a text-book case for a trie algorithm:
http://en.wikipedia.org/wiki/Trie

Once your dictionary is built, it can find *all* the splits in 
O(word.length).


...but I don't know how well it adapts to the range interface. 
Should still work though.


Also, Aho–Corasick might be relevant depending on what you want 
to do, for example, find all substrings that happen to be a word, 
regardless of what comes before or after:

http://en.wikipedia.org/wiki/Aho%E2%80%93Corasick_string_matching_algorithm


Re: Find Semantically Correct Word Splits in UTF-8 Strings

2014-10-01 Thread monarch_dodra via Digitalmars-d-learn

On Wednesday, 1 October 2014 at 11:06:24 UTC, Nordlöw wrote:

I'm looking for a way to make my algorithm

S[] findWordSplit(S)(S word,
 HLang[] langs = [])
{
for (size_t i = 1; i + 1  word.length; i++)
{
const first = word[0..i];
const second = word[i..$];
if (this.canMeanSomething(first, langs) 
this.canMeanSomething(second, langs))
{
return [first,
second];
}
}
return typeof(return).init;
}

correctly work if S is a (UTF-8) string without first, in lazy 
manner, encode word to a dstring.


Currently this algorithm works as

carwash = [car, wash]

and I would like it to work correctly and efficient in my 
native language aswell as


biltvätt = [bil, tvätt]

:)


Out of curiosity, why exactly isn't it working in your native 
language? If you avoid decoding in your canMeanSomething, you 
should encounter no problems.


Re: Find Semantically Correct Word Splits in UTF-8 Strings

2014-10-01 Thread monarch_dodra via Digitalmars-d-learn

On Wednesday, 1 October 2014 at 11:47:41 UTC, Nordlöw wrote:

On Wednesday, 1 October 2014 at 11:06:24 UTC, Nordlöw wrote:

I'm looking for a way to make my algorithm



Update:

S[] findMeaningfulWordSplit(S)(S word,
   HLang[] langs = []) if 
(isSomeString!S)

{
for (size_t i = 1; i + 1  word.length; i++)
{
const first = word.takeExactly(i).to!string;


Does that even work? takeExactly would pop up to N *codepoints*, 
whereas your string only has N *codeunits*.


Something like:

for (auto second = str ; !second.empty ; second.popFront() )
{
auto first = str[0 .. $ - second.length];
...
}
//special case str + str[$ .. $] here. (or adapt your loop)

Would also be unicode correct, without increasing the original 
complexity.


Re: isArray and std.container.Array

2014-09-29 Thread monarch_dodra via Digitalmars-d-learn

On Monday, 29 September 2014 at 10:18:09 UTC, Marc Schütz wrote:
On Sunday, 28 September 2014 at 20:24:11 UTC, monarch_dodra 
wrote:
On Sunday, 28 September 2014 at 19:06:09 UTC, Marc Schütz 
wrote:

On Sunday, 28 September 2014 at 16:12:53 UTC, Meta wrote:

On Sunday, 28 September 2014 at 08:01:00 UTC, Nordlöw wrote:
Is there a reason why isArray!T doesn't match T when T is a 
std.container.Array? I'm asking because after looking into 
msgpack-d because of


http://forum.dlang.org/thread/aclapseyptgcwntda...@forum.dlang.org#post-aclapseyptgcwntdavwt:40forum.dlang.org

I realized that this is the reason why msgpack doesn't 
correctly pack std.container.Array.


It's just an oversight in isArray as far as I can tell. I 
don't know if there's any specific reason that Array is not 
considered an array.


I don't think so. std.container.Array is just a data 
structure that behaves like an array, but there could be 
countless other user defined data structures. It should not 
get preferred treatment over those other types. At most, 
isArray could check for the presence of .length, .ptr and 
indexing/slicing. But I think isArray was intended 
specifically for built-in arrays. It's description is an 
array (static or dynamic [...]) is probably meant to express 
that, because it lists static and dynamic arrays, but doesn't 
mention array-like containers.


Yes, everything here is correct.

Interestingly though, Array is not actually array-like 
(it's not a range, it doesn't slice), however Array.Range 
*is* an array-like structure.


In regards to isArrayLike, it would probably be more 
interesting to instead integrate it as a isRandomAccessRange 
range refinement, which would also allow opSlice operations, 
eg (myRange[0 .. 3] = 5).


As for .ptr, I think no range *trait* should expose 
(require) that, as it would most probably be an underhanded 
way to leak some abstraction, which would be better expressed 
as a direct call *prior*, rather than a range proper. EG:

myRange.ptr[0 .. 10].doSomeOperation();


The question is whether you want to call something array-like 
if it isn't stored contiguously in memory. Most algorithms 
don't depend on it, but it's a significant divergence from what 
isArray guarantees.


Right, but just because it *is* stored contiguous in memory don't 
mean you want to expose it. Array.Range is contiguous in memory, 
but it does not provide .ptr.


Also, queue-like containers are not fully contiguous in memory, 
so *couldn't* expose .ptr. They'd still get major benefit from 
myRange[]=5 though.


Because of that, I think a trait like isArrayLike requiring 
full array-like behavior is not very useful. Rather, just 
isSliceOpRange would be better.


Re: Turn function into infinite range

2014-09-29 Thread monarch_dodra via Digitalmars-d-learn

On Monday, 29 September 2014 at 17:02:43 UTC, Martin Nowak wrote:
I though I've seen this around somewhere but can no longer find 
it.


AFAIK, this as never existed.

We recently merged in cache into phobos. This seems like a 
prime candidate to expand to also take a function/delegate, as on 
of its built-in feature is that the value of front is not 
changed until popFront() is called. Having it also accept a 
function/delegate would make sense.


The issue with *not* having that is that a dumb adapter would 
fail the:

r.front == r.front
Test. And I'm pretty sure this test is expected to pass, even for 
the so called transient ranges.


I think I'll get to it now (this week).

Thoughts?


Re: Turn function into infinite range

2014-09-29 Thread monarch_dodra via Digitalmars-d-learn
On Monday, 29 September 2014 at 21:16:27 UTC, Daniel Kozák via 
Digitalmars-d-learn wrote:

V Mon, 29 Sep 2014 19:02:36 +0200
Martin Nowak via Digitalmars-d-learn
digitalmars-d-learn@puremagic.com napsáno:

Does anyone know a construct to turn a lambda into an infinite 
range.


 import std.random;

 unittest
 {
 Random gen;
 foreach(v; xxx!(() = uniform(0, 100, gen)).take(10))
 writeln(v);
 }

I though I've seen this around somewhere but can no longer 
find it.


http://dlang.org/phobos/std_range.html#.Repeat ?


That just repeats the value, but doesn't re-evaluate the value on 
every call to front/popFront.


Re: isArray and std.container.Array

2014-09-28 Thread monarch_dodra via Digitalmars-d-learn

On Sunday, 28 September 2014 at 19:06:09 UTC, Marc Schütz wrote:

On Sunday, 28 September 2014 at 16:12:53 UTC, Meta wrote:

On Sunday, 28 September 2014 at 08:01:00 UTC, Nordlöw wrote:
Is there a reason why isArray!T doesn't match T when T is a 
std.container.Array? I'm asking because after looking into 
msgpack-d because of


http://forum.dlang.org/thread/aclapseyptgcwntda...@forum.dlang.org#post-aclapseyptgcwntdavwt:40forum.dlang.org

I realized that this is the reason why msgpack doesn't 
correctly pack std.container.Array.


It's just an oversight in isArray as far as I can tell. I 
don't know if there's any specific reason that Array is not 
considered an array.


I don't think so. std.container.Array is just a data structure 
that behaves like an array, but there could be countless other 
user defined data structures. It should not get preferred 
treatment over those other types. At most, isArray could check 
for the presence of .length, .ptr and indexing/slicing. But I 
think isArray was intended specifically for built-in arrays. 
It's description is an array (static or dynamic [...]) is 
probably meant to express that, because it lists static and 
dynamic arrays, but doesn't mention array-like containers.


Yes, everything here is correct.

Interestingly though, Array is not actually array-like (it's 
not a range, it doesn't slice), however Array.Range *is* an 
array-like structure.


In regards to isArrayLike, it would probably be more 
interesting to instead integrate it as a isRandomAccessRange 
range refinement, which would also allow opSlice operations, eg 
(myRange[0 .. 3] = 5).


As for .ptr, I think no range *trait* should expose (require) 
that, as it would most probably be an underhanded way to leak 
some abstraction, which would be better expressed as a direct 
call *prior*, rather than a range proper. EG:

myRange.ptr[0 .. 10].doSomeOperation();


Re: Non-const std.container.Array.opIndex and alikes blocks serialization

2014-09-28 Thread monarch_dodra via Digitalmars-d-learn

On Sunday, 28 September 2014 at 09:04:42 UTC, Nordlöw wrote:

On Sunday, 28 September 2014 at 08:58:27 UTC, Nordlöw wrote:
In my strive to add msgpacking support for std.container.Array 
I've been blocked by the fact that std.container.Array.opIndex 
only has one overload which is non-const probably because it 
returns a ref T. This doesn't place nicely with serialization.


Shouldn't inout be used here?


Further I've tried tagging all opIndex in array.d with inout as

inout ref T opIndex(size_t i) inout

but then I get another error

array.d(479,30): Error: 
cast(string)this._data.refCountedPayload()._payload[i] is not 
an lvalue


Probably you want:

ref inout(T) opIndex(size_t i) inout

Instead. What you wrote was basically the same as:
ref T opIndex(size_t i) inout inout

While compiling, the inout(T) obtained from _payload[i] is 
value-converted into a T (makes it an lvalue), and then the 
return (which is ref) fails.


This is the whole function attributes on left side confusion - 
fiasco thing...


Re: A few questions regarding GC.malloc

2014-09-26 Thread monarch_dodra via Digitalmars-d-learn
On Friday, 26 September 2014 at 18:03:40 UTC, Steven 
Schveighoffer wrote:

On 9/25/14 6:03 PM, Sean Kelly wrote:
On Thursday, 25 September 2014 at 21:43:53 UTC, monarch_dodra 
wrote:
On Thursday, 25 September 2014 at 20:58:29 UTC, Gary 
Willoughby wrote:
What does BlkAttr.FINALIZE do when used in the GC.malloc 
call?


I have no idea. I think its for classes though, since we 
(currently)

don't finalize structs anyways.


Yes it's for memory blocks containing class instances.  It 
basically

tells the GC to call Object.~this() when collecting the block.


Just to add to Sean's statement, don't use this flag. It will 
crash the runtime, unless you have properly set up the 
classinfo pointer :) It does NOT work on structs, though I 
think there is a PR in the works to have structs destroyed from 
the GC.


-Steve


Kind of like APPENDABLE I guess, since it only works if you 
correctly setup the appendable data, and correctly slice at the 
correct offset, both of which are implementation defined.


Re: Remove filename from path

2014-09-25 Thread monarch_dodra via Digitalmars-d-learn
On Wednesday, 24 September 2014 at 17:15:39 UTC, Ali Çehreli 
wrote:

find() and friends can be used:

import std.algorithm;

void main()
{
string path = myFile.doc;
string extension = .doc;

path = findSplitBefore(path, extension)[0];
assert(path == myFile);
}


I had thought of that, but then you might get in trouble with 
something like:

string path = myPath.doc.old


And three retro()s make one modern(): :p

import std.algorithm;
import std.range;

void main()
{
string path = myFile.doc;
string extension = .doc;

path = findSplitAfter(path.retro,
  extension.retro)
   [1].retro;

assert(path == myFile);
}

Ali


That was the next one I had. Except here:
- You still run into issues if the extension is *not* .doc (and 
there happens to be a .doc somewhere in there).
- You are paying for a search, when you are only interested in 
testing a prefix.


I had thought of this though:
void main()
{
string path = myFile.doc;
string extension = .doc;

auto rpath = path.retro();
skipOver(rpath, extension.retro);
path = rpath.retro();
assert(path == myFile);
}

The issue though is that skipOver modifies an rvalue, so it's 
not as functional-style as I would have liked it.


Anyways, the conclusion here (IMO), is that to manipulate paths, 
use std.path.


immutable T.init, and pointers to mutable data

2014-09-25 Thread monarch_dodra via Digitalmars-d-learn
I was playing around with how T.init works. And I think I may 
have found a type loophole.


Given that you may initialize a pointer member to the address to 
a static global:


//
__gshared int a = 0;
struct S
{
int* p = a;
}
//

Then, in theory, any variable, be they mutable or const, are 
initialized to T.init:


//
void main()
{
immutable S s;
}
//

This is an issue, because I now have an immutable pointer that 
points to mutable data:

//
immutable S s = S.init;
immutable int* p = s.p;
assert(*p == 0); //OK
a = 5;
assert(*p == 5); //OK
//

So this violates the type system...

The question here is:
Is this legit code? At what point do you think my code should 
have been rejected?


Re: immutable T.init, and pointers to mutable data

2014-09-25 Thread monarch_dodra via Digitalmars-d-learn
On Thursday, 25 September 2014 at 12:46:01 UTC, Steven 
Schveighoffer wrote:

On 9/25/14 5:47 AM, monarch_dodra wrote:
I was playing around with how T.init works. And I think I may 
have found

a type loophole.

Given that you may initialize a pointer member to the address 
to a

static global:

//
__gshared int a = 0;
struct S
{
int* p = a;
}
//

Then, in theory, any variable, be they mutable or const, are 
initialized

to T.init:

//
void main()
{
immutable S s;
}
//

This is an issue, because I now have an immutable pointer that 
points to

mutable data:
//
immutable S s = S.init;
immutable int* p = s.p;
assert(*p == 0); //OK
a = 5;
assert(*p == 5); //OK
//

So this violates the type system...

The question here is:
Is this legit code? At what point do you think my code 
should have

been rejected?


It should be rejected. The declaration of s (the variable) 
should be the trigger, since it casts the pointer to immutable.


Please file a bug report.

-Steve


Hum... So that means certain types just *can't* be initialized 
(as immutable) at all?


Re: immutable T.init, and pointers to mutable data

2014-09-25 Thread monarch_dodra via Digitalmars-d-learn
On Thursday, 25 September 2014 at 13:37:52 UTC, Steven 
Schveighoffer wrote:

On 9/25/14 9:00 AM, monarch_dodra wrote:
On Thursday, 25 September 2014 at 12:46:01 UTC, Steven 
Schveighoffer wrote:

On 9/25/14 5:47 AM, monarch_dodra wrote:
I was playing around with how T.init works. And I think I 
may have found

a type loophole.

Given that you may initialize a pointer member to the 
address to a

static global:

//
__gshared int a = 0;
struct S
{
   int* p = a;
}
//

Then, in theory, any variable, be they mutable or const, are 
initialized

to T.init:

//
void main()
{
   immutable S s;
}
//

This is an issue, because I now have an immutable pointer 
that points to

mutable data:
//
   immutable S s = S.init;
   immutable int* p = s.p;
   assert(*p == 0); //OK
   a = 5;
   assert(*p == 5); //OK
//

So this violates the type system...

The question here is:
Is this legit code? At what point do you think my code 
should have

been rejected?


It should be rejected. The declaration of s (the variable) 
should be

the trigger, since it casts the pointer to immutable.

Please file a bug report.

-Steve


Hum... So that means certain types just *can't* be initialized 
(as

immutable) at all?


I wouldn't say that:

immutable s = S(null);

But clearly, any code that results in an immutable pointer to 
mutable data without casts is incorrect. We should start by 
outlawing such code, and if there are ways we can carve out 
certain usages, we can do that.


-Steve


Hum... right, but I meant T.init itself would not be valid. As 
in:

alias T = immutable(S);
T t = T.init; //Illegal?

This might be a borderline case, but I kind of figured that that 
piece of code was the *only* one that was universally valid in 
generic code.


The context was this pull request:
https://github.com/D-Programming-Language/phobos/pull/2172

This sucks...


Re: Fail to compile phobos

2014-09-25 Thread monarch_dodra via Digitalmars-d-learn

On Thursday, 25 September 2014 at 17:20:42 UTC, JJDuck wrote:
I tried to compile phobos according to the last paragraph in 
this page:

http://dlang.org/dmd-linux.html

but this is the error I have
fatal: Not a git repository (or any of the parent directories): 
.git



I dont know what happened, i have tried for a few days.

BTW, should I place my dmd2 folder at ~ or /usr/local/share. 
which will have less prblem in installing and maintaining?


Thanks


Please provide the command that produced this output.


Re: A few questions regarding GC.malloc

2014-09-25 Thread monarch_dodra via Digitalmars-d-learn
On Thursday, 25 September 2014 at 20:58:29 UTC, Gary Willoughby 
wrote:

A few questions regarding GC.malloc.

When requesting a chunk of memory from GC.malloc am i right in 
assuming that this chunk is scanned for pointers to other GC 
resources in order to make decisions whether to collect them or 
not?


By default, yes, but you can use BlkAttr.NO_SCAN if you do not 
want that (eg, if you want to store integers). As a rule of 
thumb, you can use hasIndirections!T to know if or if not to scan 
(that's what most of phobos relies on).



What does BlkAttr.FINALIZE do when used in the GC.malloc call?


I have no idea. I think its for classes though, since we 
(currently) don't finalize structs anyways.


Re: Remove filename from path

2014-09-24 Thread monarch_dodra via Digitalmars-d-learn

On Wednesday, 24 September 2014 at 10:11:04 UTC, Suliman wrote:

What is the best way to remove file name from full path?

string path = thisExePath()


Seems like dirName in std.path is a good candidate ;)
http://dlang.org/phobos/std_path.html#.dirName

You'll find many other path manipulation functions there.


Re: Remove filename from path

2014-09-24 Thread monarch_dodra via Digitalmars-d-learn

On Wednesday, 24 September 2014 at 10:35:29 UTC, Suliman wrote:
I can't understand how to use strip? For example I would like 
to cut just extension.


path = path.stripRight(exe);
Error: no overload matches for stripRight(C)(C[] str) if


stripExtension would be your friend here.

If you want the extension, then extension.

As a general rule, everything you need to manipulate paths and 
filenames is in std.path:

http://dlang.org/phobos/std_path.html


Re: Remove filename from path

2014-09-24 Thread monarch_dodra via Digitalmars-d-learn

On Wednesday, 24 September 2014 at 10:35:29 UTC, Suliman wrote:
I can't understand how to use strip? For example I would like 
to cut just extension.


path = path.stripRight(exe);
Error: no overload matches for stripRight(C)(C[] str) if


strip doens't work that way. It simply removes leading/trailing 
white.


There's a version in std.algorithm which is more generic, but it 
accepts either a predicate, or an element, but not a range.


Unfortunately, there is no generic function that allows striping 
of a specific ending range (though there are ways to either 
detect it, or strip it from the end).

If you want something generic, then:

string path = myFile.doc;
string extension = .doc;
if (path.endsWith(extension))
path = path[0 .. $ - extension.length];

Would work.


Re: Recursive function call

2014-09-24 Thread monarch_dodra via Digitalmars-d-learn

On Wednesday, 24 September 2014 at 10:57:27 UTC, Suliman wrote:

string getFileName()
{
	//чтобы было проще обрабатываемый файл будем хранить рядом с 
бинариком

string filename = chomp(readln());
string path = getcwd();
writeln((path ~ \\ ~ filename));
if (exists(path ~ \\ ~ filename))
return (path ~ \\ ~ filename);


Don't do `path ~ \\ ~ filename`. Instead, use 
std.path.buildPath. It's more portable, faster, and convenient.


Also, you should store the result in a named variable, or you'll 
reallocate a new string everytime.



else
{
writeln(File do not exists. Please try again);
		getFilename(); //I need something similar, to call function 
again.

}

}


In case of error, how I can call function getFileName again?


Any kind of looping control structure would work. I'd advocate 
the while(1) loop with a break or return:


while(1)
{
  string filename = chomp(readln());
  string path = getcwd();
  string fullPath = buildPath(path, filename);
  if (exists(fullPath))
return fullPath;
  writeln(File does not exists. Please try again);
}


Re: Remove filename from path

2014-09-24 Thread monarch_dodra via Digitalmars-d-learn
On Wednesday, 24 September 2014 at 12:29:09 UTC, ketmar via 
Digitalmars-d-learn wrote:

On Wed, 24 Sep 2014 12:21:40 +
monarch_dodra via Digitalmars-d-learn
digitalmars-d-learn@puremagic.com wrote:

Unfortunately, there is no generic function that allows 
striping of a specific ending range

but for strings we have std.string.chomp.


I missread that documentation. I thought it removed all 
characters that can also be found in delim. Power to me.


Re: put string[] into a appender without loop?

2014-09-22 Thread monarch_dodra via Digitalmars-d-learn
On Sunday, 21 September 2014 at 23:50:50 UTC, H. S. Teoh via 
Digitalmars-d-learn wrote:
On Sun, Sep 21, 2014 at 11:41:56PM +, AsmMan via 
Digitalmars-d-learn wrote:
I'd like to copy an array string into a appender!string() but 
I can't
see how to do this without loop myself over the string array. 
Is there

a native function or should I write it myself?


Try this:

import std.array : appender;
import std.algorithm : joiner, copy;

string[] arr = [ab, cd, efg];
auto app = appender!string();
arr.joiner.copy(app);
assert(app.data == abcdefg);


T


FYI, that's probably scary expensive in terms of 
encoding/decoding.


Using the free std.range.put should take care of everything, 
natively.


Re: can't understand why code do not working

2014-09-22 Thread monarch_dodra via Digitalmars-d-learn

On Monday, 22 September 2014 at 20:37:42 UTC, Cliff wrote:

Is stdout threadsafe?


Yes. All io operations lock in D, so are thread safe. You will 
never have interlaced io. If you want to do several opeations, 
then you can use LockingTextWriter, which is faster, s it locks 
once until you are finished. Though to be honest, the io itself 
is slow enough that I've never needed it.


Re: can't understand why code do not working

2014-09-22 Thread monarch_dodra via Digitalmars-d-learn
On Monday, 22 September 2014 at 21:19:37 UTC, Steven 
Schveighoffer wrote:

On 9/22/14 4:37 PM, Cliff wrote:



Is stdout threadsafe?


Yes, stdout is thread safe, it's based on C's stdout which is 
thread safe.


-Steve


Techinallly, though thread safe, concurrent writes will create 
garbled text. D goes one step further in the sense that it 
prevents concurrent writes entirely.


Re: can't understand why code do not working

2014-09-22 Thread monarch_dodra via Digitalmars-d-learn

On Monday, 22 September 2014 at 20:12:28 UTC, Suliman wrote:
std.concurrency.OwnerTerminated@std\concurrency.d(234): Owner 
terminated


You need to make sure your main waits for its workers before 
exiting. When main dies, it sends an exception message to 
anyone still working.


Re: destroy(someStruct)

2014-09-21 Thread monarch_dodra via Digitalmars-d-learn

On Saturday, 20 September 2014 at 22:46:10 UTC, John Colvin wrote:

import core.stdc.stdio;
struct S
{
~this()
{
printf(%x\n.ptr, this);
}
}
void main()
{
S* sp = new S;
destroy(*sp);

S s;
destroy(s);

auto sa = new S[2];
foreach(ref s_; sa)
destroy(s_);
}

output:

4002dff0
bfa89a70
4002dfe0
4002dfe1
bfa89a70

Note the double destruction of s

Its seems that calling destroy on a stack-allocated struct is a 
no-no (unless you have a re-entrant destructor). The other two 
examples seem OK though.


Am I in dangerous territory? Will I see unexpected 
double-destructions in some cases?


Destroy leaves your struct in its T.init state, and T.init should 
always be destroyable. So even though the destroyer gets called 
twice, you should be perfectly safe.


FYI, move relies on this mechanism: it sets object state to 
T.init, to make sure the later stack destruction has no side 
effect.


Re: std.range.byLine

2014-09-12 Thread monarch_dodra via Digitalmars-d-learn

On Friday, 12 September 2014 at 13:25:22 UTC, Nordlöw wrote:
On Thursday, 11 September 2014 at 22:39:40 UTC, H. S. Teoh via 
Digitalmars-d-learn wrote:

foreach (line; myInput.split(regex(`\n|\r\n|\r`)))


Shouldn't you use

foreach (line; myInput.split(regex(\n|\r\n|\r)))

here?


Probably not, as (AFAIK) the splitter engine *itself* will *also* 
escape the passed in characters. IE: It literally needs the 
characters '\' and 'n'.


Re: std.conv checking if to will work

2014-09-11 Thread monarch_dodra via Digitalmars-d-learn
On Thursday, 11 September 2014 at 08:58:09 UTC, Robert burner 
Schadek wrote:
I like the to template a lot, but sometimes I want to make 
sure beforehand that a call to it works. Is there anything in 
phobos in missed to do that. And I don't want to try catch.


There's an open request for it, and plans to have a bool 
maybeTo!(OUT, WHAT)(WHAT what, ref OUT out), but we aren't quite 
there yet.


The idea is that *once* we have that, then to would simply 
become an enforce!maybeTo.


But in the meantime, no. you have to trycatch.


Re: std.range.byLine

2014-09-11 Thread monarch_dodra via Digitalmars-d-learn

On Wednesday, 10 September 2014 at 23:01:44 UTC, Nordlöw wrote:

On Wednesday, 10 September 2014 at 22:45:08 UTC, Nordlöw wrote:

auto byLine(Range)(Range input) if (isForwardRange!Range)
{
   import std.algorithm: splitter;
   import std.ascii: newline;
   static if (newline.length == 1)
   {
   return input.splitter(newline.front);
   }
   else
   {
   return input.splitter(newline);
   }
}


IMHO, this should be added to std.string and restricted to 
isSomeString. Should I do a PR?


Well, the issue is that this isn't very portable for *reading*, 
as even on linux, you may read files with \r\n line endings 
(It's standard for csv files, for example), or read \n 
terminated files on windows.


The issue is that (currently) we don't have any splitter that 
operates on multiple needles. *That'd* be what needs to be 
written (probably not too hard either, since find already 
exists).


We also have splitLines, 
http://dlang.org/phobos/std_string.html#.splitLines;. Is that 
good enough for you by any chance? Or do you need it to actually 
be lazy?


Re: std.conv checking if to will work

2014-09-11 Thread monarch_dodra via Digitalmars-d-learn
On Thursday, 11 September 2014 at 09:33:20 UTC, Robert burner 
Schadek wrote:
On Thursday, 11 September 2014 at 09:10:03 UTC, monarch_dodra 
wrote:


There's an open request for it, and plans to have a bool 
maybeTo!(OUT, WHAT)(WHAT what, ref OUT out), but we aren't 
quite there yet.


The idea is that *once* we have that, then to would simply 
become an enforce!maybeTo.


But in the meantime, no. you have to trycatch.


thanks for the quick anwser. Is anyone working on it currently?

just for completeness the bugzilla entry is: 
https://issues.dlang.org/show_bug.cgi?id=6840


Nope, no one (AFAIK).

I think it only needs a bit of refactoring std.conv, but it's a 
pretty damn big module.


Re: std.algorithm.reduce on an array of structs

2014-09-11 Thread monarch_dodra via Digitalmars-d-learn
On Thursday, 11 September 2014 at 14:56:00 UTC, Daniel Kozak via 
Digitalmars-d-learn wrote:

V Thu, 11 Sep 2014 14:49:02 +
bearophile via Digitalmars-d-learn 
digitalmars-d-learn@puremagic.com

napsáno:


Daniel Kozak:

You can just use min:

import std.stdio, std.algorithm;

struct Thing {
 uint x;
 alias x this;
}

alias minimum = reduce!min;

void main() {
immutable ar1 = [10, 20, 30, 40, 50];
ar1.minimum.writeln;

immutable ar2 = [Thing(10), Thing(20), Thing(40)];
ar2.minimum.writeln;
}

Bye,
bearophile


Yep, this look the most idiomatic :).

Why there is no phobos function for minimum of array(range)?


There is: http://dlang.org/phobos/std_algorithm.html#.minPos

To note though: minPos will find the position of the smallest 
element, whereas reduce will accumulate and return the lowest 
value. That said:


alias minmax = reduce!(min, max);

auto mm = ar1.minmax();
auto min = mm[0];
auto max = mm[1];

Found both in one line of code, and only 1 iteration of ar1.


Re: std.algorithm.reduce on an array of structs

2014-09-11 Thread monarch_dodra via Digitalmars-d-learn

On Thursday, 11 September 2014 at 15:29:18 UTC, Daniel Kozak
wrote:
On Thursday, 11 September 2014 at 15:07:03 UTC, Daniel Kozak 
wrote:


or use alias minimum = reduce!a  b;
;)


ok this one does not work


Yeah, it's actually reduce!a  b ? a : b


Re: std.range.byLine

2014-09-11 Thread monarch_dodra via Digitalmars-d-learn

On Thursday, 11 September 2014 at 20:03:26 UTC, Nordlöw wrote:
On Thursday, 11 September 2014 at 10:19:17 UTC, monarch_dodra 
wrote:
Well, the issue is that this isn't very portable for 
*reading*, as even on linux, you may read files with \r\n 
line endings (It's standard for csv files, for example), or 
read \n terminated files on windows.
The issue is that (currently) we don't have any splitter that 
operates on multiple needles. *That'd* be what needs to be 
written (probably not too hard either, since find already 
exists).


Good idea. So its just a matter of extending splitter with 
std.algorithm.find with these three keys:

- \n
- \r
- \r\n
then? Or are there more encodings to choose from?


Hum... no, those are the correct splitting elements. However, I 
don't think that would actually work, as find will privilege 
the first whole element to match as a hit, so \r\n never be 
hit (rather, it will be hit twice, in the form of two individual 
line breaks `\r` and '\n').


Bummer...


Re: Intended behavior of std.range.cycle?

2014-09-06 Thread monarch_dodra via Digitalmars-d-learn

On Friday, 5 September 2014 at 10:41:22 UTC, Vlad Levenfeld wrote:
On Thursday, 4 September 2014 at 11:43:28 UTC, monarch_dodra 
wrote:
*Should* cycle be negatively index-able? Personally, I don't 
think so. And even if it could, it has been proven non-size_t 
indexing is not well supported at all. It was de-facto chosen 
after the iota-map fiasco that all ranges be indexed with 
size_t and nothing else...


Can you elaborate on what the problem was? I'm curious as I've 
recently implemented a DSP module that uses ranges with 
floating-point slicing and, other than having to define a 
second kind of length (I call it measure so I can still have 
a discrete length when I need it), it seems to work well enough 
so far. It'd be bad if there were some unseen fiasco waiting 
for me...


In itself, there is nothing wrong with having a shallow 
container that can be indexed from -inf to +inf. The issues 
might appear if you try to tag on the range interface on it.


In particular, who is front? If I do a foreach over the 
sequence, then will it miss half the elements? What does it mean 
to slice from -5 to +5 ? Which element becomes the new 0?


As for floating point indexing, it's the same thing. The indexing 
itself is fine, there's no problem there. But if you popFront, 
how many elements are you actually skipping over. What would it 
mean if I were to take(4.5) elements?


*Overall*, it should be fine, but if you are creative, you could 
hurt yourself. I don't know your exact use case though.


So my conclusion is mostly that as long as you only index, you 
should be fine. Mix in range adaptors, and things *could* become 
less stable. *could*. But you should still be mostly safe. Again, 
depends on use case.


Re: How to get nogc to work with manual memory allocation

2014-09-05 Thread monarch_dodra via Digitalmars-d-learn

On Sunday, 24 August 2014 at 09:29:53 UTC, Jacob Carlborg wrote:

On 2014-08-24 10:03, Bienlein wrote:

I have omitted the code for the TestClass class to save space. 
Problem

is that the compiler outputs this:

Error: @nogc function 'main.nogcNew!(TestClass, ).nogcNew' 
cannot call

non-@nogc function 'core.exception.onOutOfMemoryError'
Error: @nogc function 'main.nogcNew!(TestClass, ).nogcNew' 
cannot call

non-@nogc function 'std.conv.emplace!(TestClass, ).emplace'
Error: @nogc function 'main.nogcDel!(TestClass).nogcDel' 
cannot call

non-@nogc function 'object.destroy!(TestClass).destroy'

Is there a way to get around this?


@nogc is a very new attribute. The runtime and standard library 
have not been properly annotated with this attribute yet.


As a workaround you could try copy implementation of these 
functions to you're own code and annotate them as appropriate.


The real issue here is actually the *language*. Exceptions and 
Errors are GC allocated, so if you try to check your no-GC 
allocation, you'll use the GC...


A possible workaround is to preemptively static allocate the 
Error. However, this can cause issues if you chain Errors, or 
re-enter your function while throwing.


Re: Good/Bad? @disable postblit for struct InputRange

2014-09-05 Thread monarch_dodra via Digitalmars-d-learn
On Friday, 5 September 2014 at 19:55:50 UTC, Nick Sabalausky 
wrote:
One issue with struct-based input ranges: Saving the state of 
an input range is not supported (by definition of input range), 
and yet, you can trivially and accidentally do so with a simple 
assignment or passing into a function. The results may or may 
not blow up depending on the exact situation.


And if the input range happens to hit a poorly-implemented 
algorithm which *should* be statically requiring a ForwardRange 
and using .save() to duplicate state, but instead accepts any 
range and (accidentally?) saves state by simple struct 
copy...which will work fine for most struct-based forward 
ranges and therefore could go completely unnoticed...Then once 
again, your input range touches it and BOOM.


This *could* be addressed by making the input range a class, 
but that seems a bit overkill in many cases.


So I'm tempted to give my struct-bassed input ranges a 
@disable'd postblit. That would solve the problem, right? Would 
there be any reason NOT to do this?


Ref semantics is one option, yes. Either by class, or by struct. 
For example, most IO ranges implemented ref-counted reference 
semantics.


IMO, disabling postblit is overkill, as almost anything that does 
anything with ranges will pass them by value at one point or 
another.


That said, most of the functions that do operate (and modify) a 
range either take it by reference, or return the modified copy. 
This means you can boomrang your range in and then back out. EG:

r = doIt(r);

For example, copy, find etc... do this.

*Ideally*, these functions would do a move-return, and you'd 
pass-by-move, so you'd be able to effectively disable postblit, 
but still pass by move-value. Unfortunately, we aren't quite 
there yet...


My 0.02$


Re: Intended behavior of std.range.cycle?

2014-09-04 Thread monarch_dodra via Digitalmars-d-learn

On Thursday, 4 September 2014 at 11:29:30 UTC, rcor wrote:

auto c = cycle([1,2,3]);
foreach(i ; iota(-4,4)) {
  writeln(c[i]);
}

prints the sequence
1
2
3
1
1   - c[0] == c[-1]
2
3

I understand this is what would happen if I were to just use 
modulus on an index to access the original array, but should 
Cycle really mimic this behavior? I feel like most uses of 
Cycle would expect element -1 to be the last element of the 
original range, not the first. I could manually apply addition 
with modulus to ensure that the index is always positive, but 
then there's not much benefit to using cycle anyways -- I might 
as well be accessing the original range.

Is this behavior intentional or an oversight?


Indexing is done with the unsigned size_t. You aren't indexing at 
-1, but rather, size_t.max. size_t.max % 3 probably doesn't 
result in 3 - 1 hence what you are observing.


*Should* cycle be negatively index-able? Personally, I don't 
think so. And even if it could, it has been proven non-size_t 
indexing is not well supported at all. It was de-facto chosen 
after the iota-map fiasco that all ranges be indexed with 
size_t and nothing else...


Re: Intended behavior of std.range.cycle?

2014-09-04 Thread monarch_dodra via Digitalmars-d-learn
On Thursday, 4 September 2014 at 11:43:28 UTC, monarch_dodra 
wrote:

Indexing is done with the unsigned size_t.


I re-read your post, and I don't think I actually answered your 
question...?


I don't know of any case where you'd want to index negativelly. 
That said, I'm sure it could be possible to wrap a cycle into a 
simple signed cycle adaptor.


There's one issue with what you want to do though: Who is front, 
and where does your range start?


Re: Should formattedWrite take the outputrange by ref?

2014-09-04 Thread monarch_dodra via Digitalmars-d-learn
On Thursday, 4 September 2014 at 17:06:00 UTC, Márcio Martins 
wrote:

On Wednesday, 3 September 2014 at 07:43:20 UTC, Guillaume
Chatelet wrote:

+1 I've been bitten by this also.


Same here, +1


It's still on my radar, but it's actually not that trivial of a 
change, especially if we want to avoid breaking code, and binary 
bloat...


Re: Allowing Expressions such as (low value high)

2014-09-04 Thread monarch_dodra via Digitalmars-d-learn

On Thursday, 4 September 2014 at 20:03:57 UTC, Nordlöw wrote:
Are there any programming languages that extend the behaviour 
of comparison operators to allow expressions such as


if (low  value  high)

?

This syntax is currently disallowed by DMD.

I'm aware of the risk of a programmer misinterpreting this as

if ((low  value)  high)

Is this the reason why no languages (including D allows it).

I'm asking for in some cases, where value is a long expression, 
it would be a nice syntatic sugar to use.


In the case of D, it's a C compatibility thing. Other languages I 
don't know.


Re: Building a string from n chars

2014-09-04 Thread monarch_dodra via Digitalmars-d-learn

On Thursday, 4 September 2014 at 20:38:39 UTC, Nordlöw wrote:

On Thursday, 4 September 2014 at 19:24:00 UTC, Nordlöw wrote:

   string t1; t1 ~= '*'.repeat(n).array;
   string t2; t2 ~= *.replicate(n);


After having read 
http://dlang.org/phobos/std_array.html#.replicate


I came to the conclusion that the lazy std.range:repeat is 
preferred.


If lazy is good enough for you yes. AFAIK, replicate is *very* 
close in terms of implementation to what a.repeat(n).array() 
would do anyways. Heck, I'd be surprised if it did it 
differently, since (again, AFAIK) repeat.array() is optimal 
anyways.


I'm still a bit confused about the fact that -vgc gives no 
warnings about GC-allocations, though.


Strange indeed. Both solutions allocate a slice, and then append 
that slice. The s[]='*' Solution I gave you will not create a 
temporary allocation.


Re: Building a string from n chars

2014-09-04 Thread monarch_dodra via Digitalmars-d-learn
On Thursday, 4 September 2014 at 20:57:43 UTC, monarch_dodra 
wrote:

On Thursday, 4 September 2014 at 20:38:39 UTC, Nordlöw wrote:

On Thursday, 4 September 2014 at 19:24:00 UTC, Nordlöw wrote:

  string t1; t1 ~= '*'.repeat(n).array;
  string t2; t2 ~= *.replicate(n);


After having read 
http://dlang.org/phobos/std_array.html#.replicate


I came to the conclusion that the lazy std.range:repeat is 
preferred.


If lazy is good enough for you yes. AFAIK, replicate is *very* 
close in terms of implementation to what a.repeat(n).array() 
would do anyways. Heck, I'd be surprised if it did it 
differently, since (again, AFAIK) repeat.array() is optimal 
anyways.


I re-read the doc and implementation: replicate replicates a 
*range*. It is a bit optimized to detect the case where the range 
is a single element, but it still has to do the check, and even 
then (implementation detail), it is less efficient. I might 
create a pull to tweak that.


Re: opSlice() or opIndex() for the entire slice?

2014-09-04 Thread monarch_dodra via Digitalmars-d-learn

On Thursday, 4 September 2014 at 19:12:27 UTC, Ali Çehreli wrote:
The documentation says To overload a[], simply define opIndex 
with no parameters:


  http://dlang.org/operatoroverloading.html#Slice

And it works with some uses of a[]. However, opSlice() seems to 
be needed to actually use the returned slice further.


This must be new, as I've read that page several times, and have 
never seen that before. Furthermore, I've done a *lot* pulls to 
improve ranges' slicing capabilities, and no reviewer has ever 
mentioned this before.


Re: std.container.Array

2014-09-03 Thread monarch_dodra via Digitalmars-d-learn
On Wednesday, 3 September 2014 at 16:44:45 UTC, Casper Færgemand 
wrote:
Is there a good reason std.container.Array doesn't work with 
@nogc? The ddoc seems pretty explicit about its purpose:


Array type with deterministic control of memory. The memory 
allocated for the array is reclaimed as soon as possible; there 
is no reliance on the garbage collector. Array uses malloc and 
free for managing its own memory.


Well, for starters, probably simply because we didn't take the 
right precautions to make it work. It should. I'll look into it.


That said, keep in mind that Array only manages *its* objects. 
But when an Array has pointers, then it *will* tell the GC it 
holds indirections, and that it should be scanned in regards to 
the cleanup of *other* objects. Think Array!string.


Re: Building a string from n chars

2014-09-03 Thread monarch_dodra via Digitalmars-d-learn

On Wednesday, 3 September 2014 at 19:43:26 UTC, Nordlöw wrote:

Is there a simpler way to way to

s ~= repeat('*', n).array.to!string;

if s has to be of type string?


s ~= repeat('*', n).array();

Should be enough. Why the to!string?

There's 1 useless allocation, but I think that's OK for code this 
trivial?


Else, you can do:
s.length+=n;
s[$-n .. $] []= '*';

This is also relatively simple. The ownside is doing double 
assignement, as length will initialize new elements to 
char.init. Probably not noticeable.


There *might* be more efficient ways to do it, but I'd doubt it 
qualifies as simpler. Or if it's really observeable. Are these 
good enough for you?


Re: Comparing TypeTuples

2014-09-02 Thread monarch_dodra via Digitalmars-d-learn

On Tuesday, 2 September 2014 at 08:27:14 UTC, Tudor Berariu wrote:
How can I check if two TypeTuples containing both types and 
values are the same?

This fails:

  static assert(is(TypeTuple!(3, int, Zorro) == TypeTuple!(3, 
int, Zorro)));


Thank you!
Tudor


Yeah, this fails because you can't use is(a == b) with values. 
However, *you* use is(a) to check if a is an actual type. Then, 
you can do something like:


alias Args1 = TypeTuple!(3, int, Zorro);
alias Args2 = TypeTuple!(3, int, Zorro);
static assert(Args1.length == Args2.length);
foreach (I, _; Args1)
{
pragma(msg, I);
static assert(is(Args1[I]) == is(Args2[I]));
static if (is(Args1[I]))
static assert(is(Args1[I] == Args2[I]));
else
static assert(Args1[I] == Args2[I]);
}



Re: Implementing Template Restrictions in Different Way

2014-09-02 Thread monarch_dodra via Digitalmars-d-learn

On Monday, 1 September 2014 at 22:46:52 UTC, Nordlöw wrote:
Is this a other/newer preferred way to describe the template 
restriction, using for example __traits(compiles, ...)? Is


is(typeof(...


AFAIK, those produce the same results 99% of the time. The only 
cases where they differ are borderline buggy.



the fastest way to do this?


Are you talking about constraints, or implementation of 
safeSkipOver?


BTW: Is there a way to prevent the calls to r1.length and 
r2.length in this case?


Hum... Are you writing this function because skipOver will 
actually fail? AFAIK, it shouldn't. We should fix skipOver...


Re: Implementing Template Restrictions in Different Way

2014-09-02 Thread monarch_dodra via Digitalmars-d-learn

On Monday, 1 September 2014 at 22:46:52 UTC, Nordlöw wrote:
BTW: Is there a way to prevent the calls to r1.length and 
r2.length in this case?


Also, this assumes your ranges have front at all. AFAIK, skipOver 
operates on forward ranges. Related: Your condition could fail if 
R1/R2 are strings of un-matching widths.


Re: Implementing Template Restrictions in Different Way

2014-09-02 Thread monarch_dodra via Digitalmars-d-learn

On Tuesday, 2 September 2014 at 11:41:51 UTC, Nordlöw wrote:
On Tuesday, 2 September 2014 at 10:22:49 UTC, monarch_dodra 
wrote:

the fastest way to do this?


Are you talking about constraints, or implementation of 
safeSkipOver?


The constraint.


In that case, I'm not sure what you mean by fastest in the 
context of constraints, which are compile-time.


Hum... Are you writing this function because skipOver will 
actually fail? AFAIK, it shouldn't. We should fix skipOver...


Yes, I'm writing this wrapper because call to r.front in

bool skipOver(alias pred = a == b, R, E)(ref R r, E e)
if (is(typeof(binaryFun!pred(r.front, e
{
if (!binaryFun!pred(r.front, e))
return false;
r.popFront();
return true;
}

fails when r is empty.

It believe it should be

if (r.empty || !binaryFun!pred(r.front, e))

right? Should I do a PR?


I think so yes. That's the R/E version though. Is the R/R 
version also subject to this issue?


Re: Overriding to!string on enum types

2014-09-02 Thread monarch_dodra via Digitalmars-d-learn

On Tuesday, 2 September 2014 at 14:59:41 UTC, evilrat wrote:

sorry, i forgot everything.
here is example of how to do this
-

import std.conv : to;

enum Test
{
 One,
 Two,
 Three,
}


template to(T: string)
{
 T to(A: Test)(A val)
 {
  final switch (val)
  {
   case Test.One: return 1;
   case Test.Two: return 2;
   case Test.Three: return 3;
  }
 }
}


void main()
{
assert(to!string(Test.One) == 1);
auto t = cast(Test)2;
assert(to!string(t) == 3);
assert(to!int(4) == 4); // shows original to! template works
}


Word of warning: You are not overriding to, but rather, simply 
defining your own to locally, which resolves as a better match 
in the context where you are using it.


If you pass the enum to another function in another module, your 
to will NOT be called.


Re: Overriding to!string on enum types

2014-09-02 Thread monarch_dodra via Digitalmars-d-learn

On Tuesday, 2 September 2014 at 12:54:55 UTC, Nordlöw wrote:
Is it possible to override the behaviour of to!string(x) when x 
is an enum. I'm asking because this


enum CxxRefQualifier
{
none,
normalRef,
rvalueRef
}

string toString(CxxRefQualifier refQ) @safe pure nothrow
{
final switch (refQ)
{
case CxxRefQualifier.none: return ;
case CxxRefQualifier.normalRef: return ;
case CxxRefQualifier.rvalueRef: return ;
}
}

doesn't affect behaviour of to!string(x) when x is an instance 
of CxxRefQualifier.


That won't work, because your toString is a free function. The 
module system doesn't allow this kind of Koenig lookup-like 
hijack. The only reason it allows for things like front/popFront 
and arrays, is that the other modules import std.array, and are 
aware of the functions. This is not true for user defined 
types. This may or may not be a feature :)


Unless we allow defining enum-member functions, AFAIK, it is 
impossible to override the printing behavior for enums... short 
of injecting your own modules in std.format/std.conv. Or to have 
a parameter moduleLookup in said template functions.


Re: Overriding to!string on enum types

2014-09-02 Thread monarch_dodra via Digitalmars-d-learn

On Tuesday, 2 September 2014 at 15:41:17 UTC, monarch_dodra wrote:
Unless we allow defining enum-member functions, AFAIK, it is 
impossible to override the printing behavior for enums...


... If your enum actually represents strings, then you could:

enum CxxRefQualifier : string
{
none  = ,
normalRef = ,
rvalueRef = ,
}

That in itself is not enough, but you *can* cast your enum to 
string, and then print that, or pass that.


See also:
https://issues.dlang.org/show_bug.cgi?id=11571


Re: Reading unicode chars..

2014-09-02 Thread monarch_dodra via Digitalmars-d-learn

On Tuesday, 2 September 2014 at 17:10:57 UTC, Ali Çehreli wrote:
1) To avoid a common gotcha, note that 'line' is reused at 
every iteration here. You must make copies of portions of it if 
you need to.


Ali


I don't know if you are aware, but byLineCopy was recently 
introduced. It will be available in 2.067. Just spreading info.


Re: Reading unicode chars..

2014-09-02 Thread monarch_dodra via Digitalmars-d-learn

On Tuesday, 2 September 2014 at 18:30:55 UTC, seany wrote:
Your example reads the file by lines, i need to get them by 
chars.


If you are intent on reading the stream character (or wcharacter) 
1 by 1, then you will have to decode them manually, as there is 
no getcd.


Unfortunately, the newer std.stdio module does not really 
provide facilities for such unitary reads.


I'd suggest you create a range out of your std.stream.File, which 
reads it byte by byte. Then, you pass it to the byDchar() 
range, which will auto decode those characters. If you really 
want to do it character by character.


What's wrong with reading line by line, but processing the 
characters in said lines 1 by 1? That works out of the box.


Re: Why is rehash not @safe?

2014-08-30 Thread monarch_dodra via Digitalmars-d-learn

On Saturday, 30 August 2014 at 14:27:04 UTC, Nordlöw wrote:
I just noticed that AA rehash is @system. Is there a reason for 
this? Is it system because bad things can happen or simply 
because it's a low level function? Should I always tag 
functions calling rehash as @trusted?


AFAIK, the whole problem is one of attributes, and run-time 
inference.


AA's are mostly run-time implemented. When you have a U[T], and 
you want to rehash, then the AA will make a run-time call to 
typeinfo(T).hash();


The issue is that here, you need to support *all* of the hash 
function for *all* of the T types.


If you make rehash @trusted, then you may end up calling @system 
hash functions in a @safe context.


If you make it @safe, then you either break code, or make it 
impossible for end users to provide their @system hash functions.


Really, it's lose-lose. The only (AFAIK) solution is to migrate 
AA's to a template-library that individually infers the correct 
safety for every types.


Re: Issue with dmd 2.066, alias this, and sort

2014-08-28 Thread monarch_dodra via Digitalmars-d-learn

On Wednesday, 27 August 2014 at 21:43:40 UTC, bearophile wrote:

rcor:

I've tried to express my problem in a mostly minimal example 
here:

https://gist.github.com/murphyslaw480/d4a5f857a104bcf62de1

The class Point has an alias this to its own property 
'feature()', which returns a reference to a private member. 
When I try to sort a Point[], DMD fails with mutable method 
feature is not callable on const object. I'm not actually 
using the property 'feature()' or the alias this in the 
sorting, so it seems like it shouldn't interfere. That being 
said, I'm still slightly const-challenged so maybe its an 
error on my part. However, the above example compiles fine 
with DMD 2.065.0-3.


It compiles if you use:
@property auto feature() const pure nothrow { return _feature; }

Otherwise I get strange errors like:

...\dmd2\src\phobos\std\exception.d(986,31): Error: pure 
function 'std.exception.doesPointTo!(Point, Point, 
void).doesPointTo' cannot call impure function 
'temp.Point.feature'


Bye,
bearophile


Seems like a library bug. Unsure if DMD or phobos for this one,
but there is definitely a phobos bug to be fixed anyways. I'll
investigate both.


How to cast to void*, while bypassing alias this or opCast

2014-08-28 Thread monarch_dodra via Digitalmars-d-learn

I'm investigating a phobos regression. From doesPointTo:

//
static if (isPointer!S || is(S == class) || is(S == 
interface))

{
const m = cast(void*) source;
//

Basically, given a pointer like structure, I want the void* 
equivalent. I really don't care about how S works, and am 
observing the source object as nothing more than a bag of 
member fields.


The issue though is that it turns out that such code can and will 
call either opCast or alias this, which is *not* what we want at 
all in this piece of code.


Is there any way to do a hard reinterpret cast in such a 
situation?


Re: Issue with dmd 2.066, alias this, and sort

2014-08-28 Thread monarch_dodra via Digitalmars-d-learn

On Thursday, 28 August 2014 at 10:38:12 UTC, monarch_dodra wrote:

On Wednesday, 27 August 2014 at 21:43:40 UTC, bearophile wrote:

rcor:


It compiles if you use:
@property auto feature() const pure nothrow { return _feature; 
}


Otherwise I get strange errors like:

...\dmd2\src\phobos\std\exception.d(986,31): Error: pure 
function 'std.exception.doesPointTo!(Point, Point, 
void).doesPointTo' cannot call impure function 
'temp.Point.feature'


Bye,
bearophile


Seems like a library bug. Unsure if DMD or phobos for this one,
but there is definitely a phobos bug to be fixed anyways. I'll
investigate both.


DMD issue:
https://issues.dlang.org/show_bug.cgi?id=13392

Phobos issue:
http://forum.dlang.org/thread/uignsankcumgmhwpo...@forum.dlang.org#post-uignsankcumgmhwpoead:40forum.dlang.org


Re: How to cast to void*, while bypassing alias this or opCast

2014-08-28 Thread monarch_dodra via Digitalmars-d-learn

On Thursday, 28 August 2014 at 11:02:03 UTC, anonymous wrote:
On Thursday, 28 August 2014 at 10:45:52 UTC, monarch_dodra 
wrote:

I'm investigating a phobos regression. From doesPointTo:

//
   static if (isPointer!S || is(S == class) || is(S == 
interface))

   {
   const m = cast(void*) source;
//

Basically, given a pointer like structure, I want the void* 
equivalent. I really don't care about how S works, and am 
observing the source object as nothing more than a bag of 
member fields.


The issue though is that it turns out that such code can and 
will call either opCast or alias this, which is *not* what we 
want at all in this piece of code.


Is there any way to do a hard reinterpret cast in such a 
situation?


*cast(void**)source


Hum... now I feel retarded.

In my mind I had I want re-interpret, not address of, so no 
operator.


Thanks.


Re: Issue with dmd 2.066, alias this, and sort

2014-08-28 Thread monarch_dodra via Digitalmars-d-learn

On Thursday, 28 August 2014 at 10:54:47 UTC, monarch_dodra wrote:

Phobos issue:
http://forum.dlang.org/thread/uignsankcumgmhwpo...@forum.dlang.org#post-uignsankcumgmhwpoead:40forum.dlang.org


https://github.com/D-Programming-Language/phobos/pull/2472


Re: 'idiomatic' porting of c and or c++ code that does NULL checking

2014-08-23 Thread monarch_dodra via Digitalmars-d-learn

On Saturday, 23 August 2014 at 10:33:02 UTC, nikki wrote:

A good to know! thanks.
I'd still be interrested to see the idiomatic D version of that 
function, what would that depend on ?


Honestly, I wouldn't change it much. If it didn't throw 
exceptions before, then it probably would have trouble handling 
them now.


What I *would* do is use multiple returns though. This style of 
if/else invariably leads to the dreaded diagonal line of death 
(http://geekandpoke.typepad.com/geekandpoke/2009/12/geek-for-dummies-chapter-2.html)


Once you've done that, any resource you'd have otherwise needed 
to Un-conditionally release, I'd do with a scope.


bool init()
{
//Initialize SDL
if( SDL_Init( SDL_INIT_VIDEO )  0 )
{
printf( SDL could not initialize! SDL_Error: %s\n,
SDL_GetError() );
return false;
}

//Create window
gWindow = SDL_CreateWindow( SDL Tutorial,
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH,
SCREEN_HEIGHT, SDL_WINDOW_SHOWN );
if( gWindow == NULL )
{
printf( Window could not be created! SDL_Error:
%s\n, SDL_GetError() );
return false;
}

//Get window surface
gScreenSurface = SDL_GetWindowSurface( gWindow );

return true;
}

Now, once you've adopted this kind of style, migrating to 
exceptions (should you so wish to do so) should much easier.


Re: Acces Values in DList

2014-08-23 Thread monarch_dodra via Digitalmars-d-learn

On Saturday, 23 August 2014 at 15:18:15 UTC, axwro wrote:

On Saturday, 23 August 2014 at 14:54:55 UTC, axwro wrote:

How can i access values in DList?

I save different objects of type Property in my DList, but 
if i want to access them this way:


this.properties[0].value.start

i get:

Error: no [] operator overload for type DList!(Property)



Fixed, i just used Array!Property


DList implements what is known as a (doubly) linked list. It is 
a container type that is not capable of providing random acess. 
As such, you cannot do properties[0]. You can either access the 
first (front) value individually, or iterate your DList (via 
its range interface foreach(val; this.properties[]) {...}).


Array implements a basic contiguous sequence of elements (hence 
provides RA).


It is important you understand what you are using, and which 
container best fits your needs.


Re: Module-level attributes and unit tests

2014-08-23 Thread monarch_dodra via Digitalmars-d-learn
On Saturday, 23 August 2014 at 15:26:02 UTC, Leandro Motta Barros 
via Digitalmars-d-learn wrote:

Hello,

I have a module which is completelly @nogc, and as such I'd 
like to just say


   @nogc:

at the top of the file and be happy.

However, my unit tests for this same module do some GC 
allocation, so the

module fails to compile.

Is there a way to disable @nogc for the unit tests only? Would 
this be a

bad idea in some way I cannot see?


Nope. At best, you might be able to *declare* a function that is 
GC, but even then, you wouldn't be able to call it.


I suppose the same question is valid for other attributes, like 
'nothrow'

and '@safe'.


Actually, you can undo @safe with an explicit @system. nothrow 
(and pure) are in the same boat as @nogc



Thank you,

LMB


Solutions I can see would be to:
a) Put your unittests in a separate module.
b) Place your unittests before your @nogc:
c) Instead of using @nogc:, use @nogc {}: This will make 
@nogc run until the end of the block.


Re: Generating a tree structure

2014-08-21 Thread monarch_dodra via Digitalmars-d-learn

On Thursday, 21 August 2014 at 14:09:24 UTC, Ricky C wrote:

TileTree* self;


Don't do that. D has banned internal pointers to implement its 
move semantics.



branches[index] = tile_trees[index];


This will make a *value-copy* of your TileTree nodes. There are 
good chances it'll break your tree.


As a rule of thumbn when managing an Node-like structure, try to 
avoid storing them by value in a container. Unless you are 
*exceptionally* about not copying the nodes from one container to 
another, you'll usually end up shooting yourself in the foot. 
This is particularly relevant what when you have an internal 
pointer, as the copy will point to the old node, not itself.


Try to rewrite your code to use TileTree* objects instead:
http://dpaste.dzfl.pl/13194a966c07


Re: Variadic parameter of length 1

2014-08-20 Thread monarch_dodra via Digitalmars-d-learn
On Wednesday, 20 August 2014 at 15:11:53 UTC, Dominikus Dittes 
Scherkl wrote:

I have several times seen a construct

template foo(T...) if(T.length == 1)
{
...
}

What is that good for?
Why using variadic parameter if anyway exactly one parameter is
required?!?


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


Re: Variadic parameter of length 1

2014-08-20 Thread monarch_dodra via Digitalmars-d-learn

On Wednesday, 20 August 2014 at 17:02:59 UTC, Dicebot wrote:
On Wednesday, 20 August 2014 at 15:34:30 UTC, Dominikus Dittes 
Scherkl wrote:
And why historical? Is that not necessary anymore? What better 
solution is there today?


Historical in a sense that distinct can be anything template 
parameter is probably a better approach but it is too late to 
change such core language part.


Yeah, what he said. It's a language artifact.


Re: Can you explain this?

2014-08-20 Thread monarch_dodra via Digitalmars-d-learn
On Wednesday, 20 August 2014 at 20:39:42 UTC, Jonathan M Davis 
wrote:
is(typeof(foo)) and __traits(compiles, foo) are not the same. 
The first tests for the existence of the symbol, whereas the 
second checks whether the code will actually compile.


Is that even true? I mean, are you just repeating something 
you've heard, or have you checked? is(typeof(foo)) has always 
failed for me merelly if foo fails to compile. foo being an 
existing (but private) symbol is enough.


Test case:
//
module foo;

struct S
{
private int i;
}
//
import foo;

void main(string[] args)
{
S s;
writeln(is(typeof(s.i)));
writeln(__traits(compiles, s.i));
}
//

This says false, false.

I've yet to find a usecase where is(typeof(...)) and 
__traits(compiles, ...) aren't interchangeable.


I mean, I may have missed something, but it seems the whole 
private thing is just miss-information.


Re: new error message in 2.066, type bool (const)

2014-08-20 Thread monarch_dodra via Digitalmars-d-learn
On Wednesday, 20 August 2014 at 20:46:20 UTC, Paul D Anderson 
wrote:
Re-compiling existing code with version 2.066 generates a lot 
of errors complaining about implicit conversion to const. 
Typical is this call (inside a struct with properties 1  2):


z.sign = x.sign ^ y.sign;

Error: None of the overloads of 'sign' are callable using 
argument types bool (const), candidates are:


1)  @property
@safe
bool sign() const
{
return signed;
}

2)  @property
@safe
bool sign(in bool value)
{
signed = value;
return signed;
}

What changed? It ran okay with early beta versions, but not 
with the release.


Paul


Could you provide a short, but complete program that reproduces 
the issue? With this:


//
struct S
{
bool signed;
@property
@safe
bool sign() const
{
return signed;
}

@property
@safe
bool sign(in bool value)
{
signed = value;
return signed;
}
}

void main(string[] args)
{
S s;
s.sign = s.sign ^ s.sign;
}
//

It works for me with both 2.065.0 and 2.066.0.

What is the type of signed ? Is it something other than bool, 
by any chance?


Re: String Prefix Predicate

2014-08-19 Thread monarch_dodra via Digitalmars-d-learn

On Monday, 18 August 2014 at 20:50:55 UTC, Nordlöw wrote:

On Monday, 18 August 2014 at 12:42:25 UTC, monarch_dodra wrote:
If you are using a string, the only thing helpful in there is 
`byCodeunit`. The rest is only useful if you have actual 
ranges.


Actual ranges of...characters and strings? Could you gives some 
examples? I'm curious.


You could define your own range of chars, for example, a rope. 
Or, you want to store your string in a deterministic container 
(Array!char). These would produce individual code units, but 
you'd still need them to be interpreted your range as a sequence 
of code points. This is where `byDchar` would come in handy.


There is a fair bit of discrepancy between a char[], and a 
range where `ElementType!R` is `char`, which is quite 
unfortunate. There have been talks of killing auto-decode, in 
which case, a range of chars would have the same behavior as a 
char[].


Re: In the new D release why use free functions instead of properties?

2014-08-19 Thread monarch_dodra via Digitalmars-d-learn

On Monday, 18 August 2014 at 21:17:11 UTC, Jonathan M Davis wrote:
On Monday, 18 August 2014 at 21:02:09 UTC, Gary Willoughby 
wrote:
In the new D release there have been some changes regarding 
built-in types.


http://dlang.org/changelog.html?2.066#array_and_aa_changes

I would like to learn why this has been done like this and why 
it is desired to be free functions rather than properties?


Probably because they never should have been properties in the 
first place. Properties are supposed to emulate variables, 
whereas something like dup is clearly an action. So, it's 
clearly not supposed to be a property. However, because D 
doesn't require parens on a function with no arguments, you can 
still call it without parens. Some of the changes probably also 
help with cleaning up the AA internals, which is sorely needed.


- Jonathan M Davis


Actually, the new free functions *are* properties. All that you 
just declared is valid, but we never got around to doing it. 
Walter (If I remember correctly) was opposed.


So right now, even if dup is a free function, myArray.dup() 
is still invalid.


:(


Re: goto skips declaration of variable

2014-08-19 Thread monarch_dodra via Digitalmars-d-learn

On Monday, 18 August 2014 at 13:51:14 UTC, nrgyzer wrote:

Hi all,

I've the following code snipped:

import std.bigint;
void main(string[] args)
{
BigInt i = 12345;
if (args.length  1)
{
goto Exit;
}
i = BigInt(67890);
Exit:
return;
}


For what it's worth, whenever you have goto-end style code, 
place all your code in a proper block, in such a way that all 
your variable declarations are in that block, and all your gotos 
break out of this block. This way, a goto will *never* cross a 
declaration, so coding is easy. The only variables you place at 
the top or the ones that could need cleanup.


void main(string[] args)
{
//Declarations that need cleanup:
void* p;

//Code
{
BigInt i = 12345; //Local variable
if (args.length  1)
{
goto Exit; //Breaks out of block
}
i = BigInt(67890);
BigInt j = 54321; //Local variable
}

//End
Exit:
CleanUp(p);
return;
}


Re: String Prefix Predicate

2014-08-18 Thread monarch_dodra via Digitalmars-d-learn

On Monday, 18 August 2014 at 11:28:25 UTC, Nordlöw wrote:
On Saturday, 16 August 2014 at 20:59:47 UTC, monarch_dodra 
wrote:
I don't get it? If you use byDchar, you are *explicitly* 
decoding. How is that any better? If anything, you are 
*preventing* the (many) opportunities phobos has to *avoid* 
decoding when it can...


byDchar and alikes are lazy ranges, ie they don't allocate.


Lazy does NOT mean does not allocate. You are making a terrible 
mistake if you assume that.


Furthermore decoding does NOT allocate either. At worst, it can 
throw an exception, but that's exceptional.


They also don't throw exceptions which is preferably in some 
cases.


Even then, startsWith(string1, string2) will *NOT* decode. It 
will do a binary comparison of the codeunits. A fast one at that, 
since you'll use SIMD vector comparison. Because of this, it 
won't throw any exceptions either. This compiles just fine:

void main() nothrow
{
bool b = foobar.startsWith(foo);
}


In contrast, with:
whole.byDchar().startsWith(part.byDchar())
You *will* decode. *THAT* will be painfully slow.


Read the details at
https://github.com/D-Programming-Language/phobos/pull/2043


If you are using a string, the only thing helpful in there is 
`byCodeunit`. The rest is only useful if you have actual ranges.


If you are using phobos, you should really trust the 
implementation that decoding will only happen on a as needed 
basis.


Re: Using std.container.BinaryHeap like C++

2014-08-18 Thread monarch_dodra via Digitalmars-d-learn

On Monday, 18 August 2014 at 06:50:08 UTC, Paulo Pinto wrote:

On Sunday, 17 August 2014 at 21:09:04 UTC, monarch_dodra wrote:

On Sunday, 17 August 2014 at 18:54:27 UTC, Paulo Pinto wrote:

Hi,

I was wondering if it is possible to use the BinaryHeap store 
like

the C++'s make_heap/pop_heap/push_heap functions.

I would like to port to D some A* C++ code I have which 
rearranges the priorities on the underlying store, followed 
by another

make_heap() call on the vector used as store.

Doing the same in D by calling again heapify() does not seem 
to provide similar behavior.


Just curious about it, as I don't plan to invest too much 
time on it.


Thanks,
Paulo


AFAIK, D's BinaryHeap works just like C++'s 
make_heap/pop_heap/push_heap, except that it provides an 
actual object you can interface with, which has font, 
removeFront, removeAny and insert.


What exactly is the difference in behavior you are seeing? 
Just different results that can be attributed to 
implementation details, or fundamental differences?


It doesn't seem to like I change the store contents directly 
under its feet
and recalling heapify again on the same store, like I am doing 
in C++'s heap.


Sometimes I get a different sequence of data or just a crash.

I still need to make the D code reflect my latest C++ changes, 
as the C++ code is what really matters in this hobby project, 
there is where my focus has been lately.


The D version is more of a playing around thing.

As I said, I curious what the behavior is supposed to be.

Thanks,
Paulo


Weird. The behavior should be the same as C++'s. As I said, the 
difference is that D gives you a handle object. This object 
assumes you *don't* modify it's store under the hood, but as long 
as you don't use the heap after a store modification, you should 
be fine. Do you have a minimal test case?


Re: Using std.container.BinaryHeap like C++

2014-08-17 Thread monarch_dodra via Digitalmars-d-learn

On Sunday, 17 August 2014 at 18:54:27 UTC, Paulo Pinto wrote:

Hi,

I was wondering if it is possible to use the BinaryHeap store 
like

the C++'s make_heap/pop_heap/push_heap functions.

I would like to port to D some A* C++ code I have which 
rearranges the priorities on the underlying store, followed by 
another

make_heap() call on the vector used as store.

Doing the same in D by calling again heapify() does not seem to 
provide similar behavior.


Just curious about it, as I don't plan to invest too much time 
on it.


Thanks,
Paulo


AFAIK, D's BinaryHeap works just like C++'s 
make_heap/pop_heap/push_heap, except that it provides an actual 
object you can interface with, which has font, removeFront, 
removeAny and insert.


What exactly is the difference in behavior you are seeing? Just 
different results that can be attributed to implementation 
details, or fundamental differences?


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

2014-08-16 Thread monarch_dodra via Digitalmars-d-learn
On Saturday, 16 August 2014 at 19:30:16 UTC, Jonathan M Davis via 
Digitalmars-d-learn wrote:

On Sat, 16 Aug 2014 14:39:00 +0200
Artur Skawina via Digitalmars-d-learn
digitalmars-d-learn@puremagic.com wrote:

On 08/16/14 13:58, Philippe Sigaud via Digitalmars-d-learn 
wrote:

 On Sat, Aug 16, 2014 at 1:30 PM, Artur Skawina via
 Digitalmars-d-learn

 
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).

@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. ;)

Other attributes, including 'pure' and 'nothrow' only affect 
symbols

in the current scope.


It sounds like a bug to me if they're not consistent.

- Jonathan M Davis


Well, you got  @system to override @safe, but no @impure or 
@throws. So the behavior can kind of make sense in a way. Maybe.


Re: drop* and take* only for specific element values

2014-08-16 Thread monarch_dodra via Digitalmars-d-learn

On Thursday, 14 August 2014 at 07:30:59 UTC, Nordlöw wrote:
On Thursday, 14 August 2014 at 00:56:47 UTC, Jonathan M Davis 
wrote:

You forgot the !, making the predicate a function argument. It


Great!

My solution:


Depending on your exact needs, don't forget too about findSkip 
(same as find, but skips found element), as well as filter.


In particular, r.filter!pred.take(N) would give you a (lazy) 
range consisting of the first 10 elements in r that verify pred. 
In some cases, until could also suit your needs.


Long story short, D range and algorithms are little building 
blocks. There aren't that many basic functions that can't 
simply be expressed as a combination of already existing blocks.


Re: String Prefix Predicate

2014-08-16 Thread monarch_dodra via Digitalmars-d-learn

On Thursday, 14 August 2014 at 17:41:08 UTC, Nordlöw wrote:

On Thursday, 14 August 2014 at 17:33:41 UTC, Justin Whear wrote:

std.algorithm.startsWith?  Should auto-decode, so it'll do a


What about 
https://github.com/D-Programming-Language/phobos/pull/2043


Auto-decoding should be avoided when possible.

I guess something like

whole.byDchar().startsWith(part.byDchar())

is preferred right?


I don't get it? If you use byDchar, you are *explicitly* 
decoding. How is that any better? If anything, you are 
*preventing* the (many) opportunities phobos has to *avoid* 
decoding when it can...


If you really want to avoid decoding, use either representation 
which will do char[] = ubyte[] conversion, or byCodeUnit, 
which will create a range that returns single elements (IMO, 
byCodeUnit should be prefered over byChar, as it infers the 
correct width).




Re: String Prefix Predicate

2014-08-16 Thread monarch_dodra via Digitalmars-d-learn

On Saturday, 16 August 2014 at 20:59:47 UTC, monarch_dodra wrote:
If anything, you are *preventing* the (many) opportunities 
phobos has to *avoid* decoding when it can...


By that I want to stress what Jonathan M Davis said
Unless the string types match, there's no way around it.

You should absolutely realize that that means that when the 
string types (widths) *do* match, then search (which includes 
all flavors in phobos) will NOT decode.


Heck, if you do a string, element search, eg find(my phrase, 
someDchar), then phobos will *encode* someDchar into a correctly 
sized string, and then do a full non-decoding string-string 
search, which is actually much faster than the naive decoding 
search.


Re: Appender is ... slow

2014-08-15 Thread monarch_dodra via Digitalmars-d-learn

On Friday, 15 August 2014 at 11:57:30 UTC, Messenger wrote:
T[size] beats all of those on dmd head, though it is inarguably 
a

bit limiting.


Hey guys, just a bit of background and my own understanding of
Appender, having worked on it a fair bit.

First of all, Appender was not designed as a neck-breaking,
mind-bending speed object. It is merely a tool to offset the
slow GC-based appending.

Indeed, when doing a raw GC-append, you first have to give the GC
a pointer to the start of your array. The GC will then lookup in
which block that pointer belongs, then look up the info related
to that block, check if appending is possible, and then do the
append proper...
...And then it will do all that all over again on the next append.

Appender is simply a tool to cache the results of that once,
and then do quicker appends.

There are two other things to take into consideration with
Appender: For starters, it can append to an *existing* array it
is given. Second, you may destroy the Appender object at any
time, and the referenced array is still valid: Appender does not
*own* its buffer, and as such, is not allowed certain
optimizations.

Really, it's just designed for convenience and pretty good
speed.

Also, another thing to take into account when benchmarking, is
that Appender is a reference semantic object: It has a payload
which itself references an array. This creates a double
indirection. This usually doesn't have much impact, but with the
right optimizations, it can probably explain the x10 performance
differences we are seeing, in our *synthetic* benchmarks. I have
some doubts about the validity of the results in a real
application.

So TL;DR; yeah, you can probably do faster. But Appender is
convenient, fast enough, and works with the GC.

If you *do* need super speeds, look into something a bit more
manual: Walter's ScopeBuffer would be a good choice.

I also did some work on something called ScopeAppender, but
didn't have time to finish it yet.
https://github.com/monarchdodra/phobos/compare/ScopeAppender
It provides better speeds and deterministic management, at the
cost of partial private buffer ownership.


Re: Appender is ... slow

2014-08-15 Thread monarch_dodra via Digitalmars-d-learn
On Friday, 15 August 2014 at 12:08:58 UTC, Philippe Sigaud via 
Digitalmars-d-learn wrote:
Hmm, what about a sort of linked list of static arrays, that 
allocates

a new one when necessary?


Appender is not a container, and has no freedom on the data it 
manipulates. It has to be able to accept an array as input, and 
when it is finished, it needs to be able to return an actual 
array, so that's arguably out of the question.


Re: Appender is ... slow

2014-08-15 Thread monarch_dodra via Digitalmars-d-learn

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).


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*)


  1   2   3   >