Re: A little of coordination for Rosettacode

2014-01-15 Thread qznc

On Thursday, 16 January 2014 at 01:11:23 UTC, bearophile wrote:
- To test the compiler betas to see if they have "regressions" 
if you try to use the new features.


This sounds somewhat paradox to me. How can a new feature have a 
regression? A "regression" means it has worked before, but new 
feature did not exist before.


Maybe the question is about "before"? In my understanding 
"before" is "latest release", whereas "current" is "beta release" 
or "git HEAD". Do you mean "before" as something like "commit 
deadbeef~4" whereas "current" is "commit deadbeef"?


I see nothing wrong with using code from Rosettacode to try out 
new features. It is weird though, if people want to test an 
example, you have to tell them to compile dmd from git.


In practice the difference between the uses is not that important 
I think, because the sheer number of code snippets and release 
frequency means that most examples can be compiled with the 
latest release no matter what bearophile does. ;)


Btw are your scripts public, bearophile?


Re: Why is string.front dchar?

2014-01-15 Thread Maxim Fomin

On Thursday, 16 January 2014 at 05:56:48 UTC, Jakob Ovrum wrote:

On Tuesday, 14 January 2014 at 11:42:34 UTC, Maxim Fomin wrote:
The root of the issue is that string literals containing 
characters which do not fit into signle byte are still 
converted to char[] array. This is strictly speaking not type 
safe because it allows to reinterpret 2 or 4 byte code unit as 
sequence of characters of 1 byte size. The string type is in 
some sense problematic in D. That's why the fact that .front 
returns dhcar is a way to correct the problem, it is not an 
attempt to introduce confusion.


This assertion makes all the wrong assumptions.

`char` is a UTF-8 code unit[1], and `string` is an array of 
immutable UTF-8 code units. The whole point of UTF-8 is the 
ability to encode code points that need multiple bytes (UTF-8 
code units), so the string literal behaviour is perfectly 
regular.


This is wrong. String in D is de facto (by implementation, spec 
may say whatever is convenient for advertising D) array of single 
bytes which can keep UTF-8 code units. No way string type in D is 
always a string in a sense of code points/characters. Sometimes 
it happens that string type behaves like 'string', but if you put 
UTF-16 or UTF-32 text it would remind you what string type really 
is.


Operations on code units are rare, which is why the standard 
library instead treats strings as ranges of code points, for 
correctness by default. However, we must not prevent the user 
from being able to work on arrays of code units, as many string 
algorithms can be optimized by not doing full UTF decoding. The 
standard library does this on many occasions, and there are 
more to come.


This is attempt to explain problematic design as a wise action.

Note that the Unicode definition of an unqualified "character" 
is the translation of a code *point*, which is very different 
from a *glyph*, which is what people generally associate the 
word "character" with. Thus, `string` is not an array of 
characters (i.e. an array where each element is a character), 
but `dstring` can be said to be.


[1] http://dlang.org/type


By the way, the link you provide says char is unsigned 8 bit type 
which can keep value of UTF-8 code unit.


UTF is irrelevant because the problem is in D implementation. See 
http://forum.dlang.org/thread/hoopiiobddbapybbw...@forum.dlang.org 
(in particular 2nd page).


The root of the issue is that D does not provide 'utf' type which 
would handle correctly strings and characters irrespective of the 
format. But instead the language pretends that it supports such 
type by allowing to convert to single byte char array both 
literals "sad" and "säд". And ['s', 'ä', 'д'] is by the way 
neither char[], no wchar[], even not dchar[] but sequence of 
integers, which compounds oddities in character types.


Problems with string type can be illustrated as possible 
situation in domain of integers type. Assume that user wants 
'number' type which accepts both integers, floats and doubles and 
treats them properly. This would require either library solution 
or a new special type in a language which is supported by both 
compiler and runtime library, which performs operation at runtime 
on objects of number type according to their effective type.


D designers want to support such feature (to make the language 
better), but as it happens in other situations, the support is 
only limited: compiler allows to do


alias immutable(int)[] number;
number my_number = [0, 3.14, 3.14l];

but there is no support in runtime library. On surface, this 
looks like language have type which supports wanted feature, but 
if you use it, you will face the problems, as my_number[2] would 
give strange integer instead of float 3.14 and length of this 
array is 4 instead of 3. In addition this is not a type safe 
approach because there is option to reinterpret double as two 
integers.


Now in order to fix this, there is number of functions in library 
which treat number type properly. Such practice (limited and 
broken language support, unsafe and illogical type, functions to 
correct design mistakes) is embedded into practice so deeply, 
that anyone who point out on this problem in newsgroup is treated 
as a fool and is sent to study IEE 754 standard.


Re: Why is string.front dchar?

2014-01-15 Thread Jakob Ovrum
On Wednesday, 15 January 2014 at 20:05:32 UTC, TheFlyingFiddle 
wrote:
This is why i was confused really since the normal foreach is 
char it's weird that string.front is not a char. But if foreach 
being a char is only the way it is for legacy reasons it all 
makes sense.


Unfortunately, it's not that simple. D arrays/slices have two 
distinct interfaces - the slice interface and the range 
interface. The latter is a library convention built on top of the 
former - thus the existence of the slice interface is necessary.


A generic algorithm can choose to work on arrays (array 
algorithm) or ranges (range algorithm) among other kinds of type 
federations:


auto algo(E)(E[] t); // array algorithm
auto algo(R)(R r) if (isInputRange!R); // range algorithm

The array algorithm can assume that:

foreach(e; t)
static assert(is(typeof(e) == E));

While the range algorithm *cannot* assume that:

foreach(e; r)
static assert(is(typeof(e) == ElementType!R));

Because this fails when R is a narrow string (slice of UTF-8 or 
UTF-16 code units). Thus, the correct way to use foreach over a 
range in a generic range algorithm is:


foreach(ElementType!R e; r) {}

Swapping the default just swaps which kind of algorithm can make 
the assumption. The added cost of breaking existing algorithms is 
a big deal, but as demonstrated, it's not a panacea.


Re: Why is string.front dchar?

2014-01-15 Thread Jakob Ovrum

On Tuesday, 14 January 2014 at 11:42:34 UTC, Maxim Fomin wrote:
The root of the issue is that string literals containing 
characters which do not fit into signle byte are still 
converted to char[] array. This is strictly speaking not type 
safe because it allows to reinterpret 2 or 4 byte code unit as 
sequence of characters of 1 byte size. The string type is in 
some sense problematic in D. That's why the fact that .front 
returns dhcar is a way to correct the problem, it is not an 
attempt to introduce confusion.


This assertion makes all the wrong assumptions.

`char` is a UTF-8 code unit[1], and `string` is an array of 
immutable UTF-8 code units. The whole point of UTF-8 is the 
ability to encode code points that need multiple bytes (UTF-8 
code units), so the string literal behaviour is perfectly regular.


Operations on code units are rare, which is why the standard 
library instead treats strings as ranges of code points, for 
correctness by default. However, we must not prevent the user 
from being able to work on arrays of code units, as many string 
algorithms can be optimized by not doing full UTF decoding. The 
standard library does this on many occasions, and there are more 
to come.


Note that the Unicode definition of an unqualified "character" is 
the translation of a code *point*, which is very different from a 
*glyph*, which is what people generally associate the word 
"character" with. Thus, `string` is not an array of characters 
(i.e. an array where each element is a character), but `dstring` 
can be said to be.


[1] http://dlang.org/type


Re: A little of coordination for Rosettacode

2014-01-15 Thread bearophile

arithmetic_evaluation.d
balanced_ternary.d
combinations_with_repetitions1.d
k_means_plus_plus_clustering.d
names_to_numbers.d or number_names.d


I have "fixed" them.

This is the problem in array, already in Bugzilla, I think it's a 
kind of regression:



import std.array: array;
immutable foo = [""].array;
void main() {}


The problem with inout in balanced_ternary.d was caused by inout 
semantics that keeps subtly changing every month. I don't know 
the causes of such micro-regressions.


Bye,
bearophile


Re: A little of coordination for Rosettacode

2014-01-15 Thread bearophile

qznc:

[0] 
https://bitbucket.org/qznc/rosetta/src/da12e3673b0d/compile_all/?at=master

[1] https://gist.github.com/qznc/9ba4b0e78abfc35d4694


Few of the tasks of your list were never updated to D2/Phobos, 
and they should be updated.


Among the ones that are updated, I have found five that don't 
compile on dmd 2.065 because of compiler changes and one (I think 
already reported) regression in std.array.array:


arithmetic_evaluation.d
balanced_ternary.d
combinations_with_repetitions1.d
k_means_plus_plus_clustering.d
names_to_numbers.d or number_names.d

I will try to fix them (and probably I will leave the one with a 
regression untouched).


Bye,
bearophile


Re: A little of coordination for Rosettacode

2014-01-15 Thread bearophile

Brad Roberts:

Requiring that users of the code in resottacode be using 
bleeding edge, unreleased, compilers is a disservice to those 
users.  Typical users will not and should not need to use 
anything other than a released compiler.


Some of the rosettacode usages/purposes are:
- Trying new compiler features to see if they work correctly;
- Try the new compiler features to learn to use them effectively;
- To test the compiler betas to see if they have "regressions" if 
you try to use the new features.
- To show "good" (== short, fast, elegant, clean) D code, thanks 
to some nicer recently introduced compiler improvements;


So do you want to throw away those purposes?
Also keep in mind that if you throw away those purposes, I will 
lose some of my desire to work on Rosettacode, so you will have a 
less good and less updated rosettacode site. And I have found 
probably more than 300 dmd bugs/regressions thanks to those 
beta-related purposes. If you throw away those purposes you will 
lose a significant amount of my future bug reports. Are those 
prices low enough for you?



The point is you shouldn't have to, unless the code is taking 
advantage of broken behavior.  Any changes that 'have' to be 
made due to a compiler release need to be carefully examined as 
probable regressions in the compiler.


One of the points of improving a compiler is offering new 
features that are advantageous to use. If you don't want to use 
them it often means they are a failure. In many other cases the 
dmd compiler rejects older code that was wrong, because it 
becomes more tight.


Rosettacode tasks are usually short. If you don't try new 
compiler features in such little programs that have no 
production-level significance, then you will never try them in 
production code, and you will probably use just C-like code.


Being a little compiler-bold in those tasks is acceptable.

Bye,
bearophile


Re: A little of coordination for Rosettacode

2014-01-15 Thread Brad Roberts

On 1/15/14 4:42 PM, bearophile wrote:

Brad Roberts:


I think this is a mistake.  They should compile with a released compiler.


Why? And why do you think that outweighs the several advantages of having 
entries compilable only
with the latest beta compiler?
(Currently there are 40-50 entries that don't compile with the released dmd 
2.064.)


Requiring that users of the code in resottacode be using bleeding edge, unreleased, compilers is a 
disservice to those users.  Typical users will not and should not need to use anything other than a 
released compiler.



They also likely form a potentially interesting set of regression tests that 
someone ought to
volunteer to test beta's against.


Rosettacode site has many different purposes; I also use those programs to test 
the dmd compiler for
regressions. But to do this effectively you have to use the latest compiler 
changes.

Also, how can you update manually on the site tens of entries all at once when 
a new compiler comes
out?


The point is you shouldn't have to, unless the code is taking advantage of broken behavior.  Any 
changes that 'have' to be made due to a compiler release need to be carefully examined as probable 
regressions in the compiler.





Re: A little of coordination for Rosettacode

2014-01-15 Thread bearophile

Brad Roberts:

I think this is a mistake.  They should compile with a released 
compiler.


Why? And why do you think that outweighs the several advantages 
of having entries compilable only with the latest beta compiler?
(Currently there are 40-50 entries that don't compile with the 
released dmd 2.064.)



They also likely form a potentially interesting set of 
regression tests that someone ought to volunteer to test beta's 
against.


Rosettacode site has many different purposes; I also use those 
programs to test the dmd compiler for regressions. But to do this 
effectively you have to use the latest compiler changes.


Also, how can you update manually on the site tens of entries all 
at once when a new compiler comes out?


Bye,
bearophile


Re: A little of coordination for Rosettacode

2014-01-15 Thread Brad Roberts

On 1/15/14 4:18 PM, bearophile wrote:


What version of the D compiler are you using? I am assuming Rosettacode to be 
compilable with the
latest "bleeding edge" compiler. So if you use the latest released compiler 
some of the entries will
not compile. Such entries should not be "fixed" at all.


I think this is a mistake.  They should compile with a released compiler.  They also likely form a 
potentially interesting set of regression tests that someone ought to volunteer to test beta's against.




Re: A little of coordination for Rosettacode

2014-01-15 Thread bearophile
[0] 
https://bitbucket.org/qznc/rosetta/src/da12e3673b0d/compile_all/?at=master

[1] https://gist.github.com/qznc/9ba4b0e78abfc35d4694


Another reason for some of your entries to not compile seems to 
be that you have missed that some entries need other entries to 
compile, so "rc_24_game_solve.d" needs "permutations2.d" and 
"arithmetic_rational.d", and then compiles and runs fine. (I 
number 1 2 3 ... the tasks that have more than one D solution).


Bye,
bearophile


Re: A little of coordination for Rosettacode

2014-01-15 Thread bearophile

https://bitbucket.org/qznc/rosetta/src/da12e3673b0d/compile_all/?at=master
[1] https://gist.github.com/qznc/9ba4b0e78abfc35d4694


Regarding Task names that start with a number, like 
rosettacode_24_game_solve_00.d, I usually prefix them with "rc_".


Bye,
bearophile


Re: A little of coordination for Rosettacode

2014-01-15 Thread bearophile

qznc:

I just made some scripts [0] to download and compile all D 
examples from Rosettacode. From 186 of 716 examples fail to 
compile [1]. Some for trivial reasons like not wrapped into a 
main function or a missing import. Some require SDL or Tango or 
other third-party libraries.


My ultimate goal was to use this for regression testing dmd. 
Anyways if people try code examples they should compile out of 
the box for good PR.


If you are looking for a low-barrier way to support D a little, 
feel free to check out the fail list [1] and fix some. :)


[0] 
https://bitbucket.org/qznc/rosetta/src/da12e3673b0d/compile_all/?at=master

[1] https://gist.github.com/qznc/9ba4b0e78abfc35d4694


I am using similar scripts written in Python since years.

Currently there are around 760-770 D programs in Rosettacode.

What version of the D compiler are you using? I am assuming 
Rosettacode to be compilable with the latest "bleeding edge" 
compiler. So if you use the latest released compiler some of the 
entries will not compile. Such entries should not be "fixed" at 
all.


Your list of failing to compile just say "fail", but there are 
several reasons for a program to fail.


Some programs need a "modulename_main" version to be compiled, 
because D lacks a built-in way to tell apart the main module of a 
program from the other modules. (In Python you use the "if 
__name__ == '__main__':" for this purpose).


Some programs don't compile because require Tango. I have not 
removed them all because some Tango programmer has written them 
and I guess such person doesn't like to see their work removed 
from the pages.


Some entries don't compile because they are not yet updated, or 
dmd has had some regressions. Thankfully Kenji usually fixes such 
regressions in just few days when I find them.


Bye,
bearophile


Re: std.algorithm for changing array values

2014-01-15 Thread bearophile

Kapps:

One thing to keep in mind is that structs are passed by value, 
so this foreach would be operating on a copy of the entry. So

your setting the value to 42 would have no effect.

Instead you would need "foreach(ref entry; entries)" in order to
have the change take effect (regardless of whether or not you 
use std.algorithm).


This is a common bug in D code, especially in code of D newbies, 
but it's also occasionally present in the code of more seasoned D 
programmers.


One solution to avoid it that I suggested is that on default 
foreach yields const values. So if you want to mutate the value 
you have to add a "mutable" or "ref":


foreach (mutable entry; entries) {

Another language solution is to iterate by reference on default, 
so the ref is implicit:


foreach (entry; entries) {

And if you want to iterate by value you need to write something 
different.


There are other solutions. But none of them were accepted by 
Walter :-(


Bye,
bearophile


Re: Compile/link Win64

2014-01-15 Thread Nick Sabalausky

On 1/12/2014 5:37 PM, Erik van Velzen wrote:

On Friday, 10 January 2014 at 21:47:23 UTC, Nick Sabalausky wrote:

Hmm, I hadn't ever uninstalled it.

Regardless, *now* I've just uninstalled and reinstalled the Windows
SDK, and re-ran vcvarsall.bat. The %WindowsSdkDir% is now set, but I'm
still getting the same problem.

The %WindowsSdkDir% is set to "C:\Program Files (x86)\Microsoft
SDKs\Windows\v8.0A", but there doesn't appear to be much in there
(Just a "Bootstrapper\Packages" directory with not much inside it
either). I don't think it installed correctly. There doesn't appear to
be any other Windows SDK installation AFAICT either. Stupid f#&*^&#
microsoft tools...



The lastest Windows SDK installs to C:\Program Files (x86)\Windows
Kits\8.1\



"\Program Files (x86)\Windows Kits\" doesn't exist :(

As I suspected, it must not have installed correctly.



Re: Is continuously seeding a random number generator performance intensive?

2014-01-15 Thread Frustrated

On Friday, 3 January 2014 at 13:39:41 UTC, Andrea Fontana wrote:

On Friday, 3 January 2014 at 01:01:21 UTC, Frustrated wrote:
On Thursday, 2 January 2014 at 20:38:10 UTC, Jeroen Bollen 
wrote:

[...]
e.g.,

seed(k);
for(i = 1..10)
print(rnd(i));

and

for(i = 1..10)
{
seed(time);
print(rnd(i));
}

will both produce random sequences of numbers(and random 
sequences of numbers are "identically random".

[...]


The second example is error-prone. If "time" var doesn't change 
between cycle, it's not random at all.


Wrong, in this example I'm using rnd(i) as having a seed i. 
Obviously, I'm not using i as an interval.


i still changes per iteration of the loop so rnd still changes. 
(if I did not seed the rnd I would not have used rnd(i) but rnd;)


i.e.,

for(i = 1..10)
{
seed(time);
print(rnd(i));
}

and

for(i = 1..10)
{
seed(time);
print(rnd);
}

are different

but my example could easily have been written as

for(i = 1..10)
{
seed(time+i);
print(rnd);
}

which may be more obvious. The point of writing it the first way 
was to try to make it more clear about actually changing the seed 
vs the ith random number. (the seed changes the sequence of 
random numbers to another sequence but rnd returns the ith value 
in the sequence which is ultimately cyclical)











Re: Is continuously seeding a random number generator performance intensive?

2014-01-15 Thread Frustrated
On Wednesday, 15 January 2014 at 21:00:57 UTC, Jeroen Bollen 
wrote:
How do you correctly create a MersenneTwisterEngine with a 
ulong as seed?


If you are trying to create a very large 2D noise generator, this 
is how you do it, and you can any degree of smoothness you want:


Create a 2D RNG.

e.g.,

RND2D(x,y) { seed(S + x + N*y); return rand; }


You could use this to generate your whole map very predictably up 
to the seed length(at some point it will repeat because of the 
finite size of the seed).


If you have any degree of smoothness you do not want to use this 
per point unless you do want to have some "noise" which could be 
controlled by weighting the RND2D function so intergrid points 
are not so random:



RND2D(x,y, xS, yS)
{
s = RND2D(x,y)
sm1m1 = RND2D((int)(x/xS) - 1, (int)(y / yS - 1));
sm1m1 = RND2D((int)(x/xS) - 1, (int)(y / yS + 1));
...
return interpolate(s, x, y, sm1m1, sm1p1, ...);
}

where interpolate returns the modified seed that is partially 
based on the seed at the point x,y and partially an interpolation 
value between the sub grid points.


Anyways, now that you have your RND2D you don't ever have to 
pre-generate your noise. Obviously it is more computationally 
expensive though.


I guess this was the function you were looking for before if I 
now understand what you are trying to do?










Re: std.algorithm for changing array values

2014-01-15 Thread Meta

On Wednesday, 15 January 2014 at 20:34:32 UTC, Andre wrote:

Hi,

I checked std.algorithm but have no glue which
functions I can use to rewrite following code
with some nice algorithm functions.

I have an array of structs. I want to check for
a specific key and if found I change the value.
If it is not found I add the entry.

Kind regards
André


struct Data{
int key;
int value;
}

void main(){
Data[] entries = [Data(1,1),Data(2,2)];
bool found;

foreach(entry;entries){
if (entry.key == 3){
entry.value = 42;
found = true;
}
}

if (found == false){
entries ~= Data(3,42);
}
}


Ranges in general don't work very well for modifying values in 
place. The Data structs are passed by value between functions, so 
any modifications made won't be reflected in the original array. 
Using ranges to modify values usually entails making a copy. You 
can still use std.algorithm to simplify the above code a bit, 
however:


void main()
{
auto entries = [Data(1, 1), Data(2, 2)];
auto pos = entries.countUntil!(d => d.key == 3);
if (pos >= 0)
{
entries[pos].value = 42;
}
else
{
entries ~= Data(3, 42);
}
writeln(entries);
}

Basically, just to abstract away the loop.



Re: std.algorithm for changing array values

2014-01-15 Thread Kapps

On Wednesday, 15 January 2014 at 20:34:32 UTC, Andre wrote:

foreach(entry;entries){
if (entry.key == 3){
entry.value = 42;
found = true;
}
}



One thing to keep in mind is that structs are passed by value, so
this foreach would be operating on a copy of the entry. So your
setting the value to 42 would have no effect.

Instead you would need "foreach(ref entry; entries)" in order to
have the change take effect (regardless of whether or not you use
std.algorithm).


Re: Is continuously seeding a random number generator performance intensive?

2014-01-15 Thread Jeroen Bollen
How do you correctly create a MersenneTwisterEngine with a ulong 
as seed?


Re: std.algorithm for changing array values

2014-01-15 Thread Andre

Am 15.01.2014 21:54, schrieb anonymous:

If you want to stop after the first match:

auto f = entries.find!(d => d.key == 3);
if(f.empty) entries ~= Data(3,42);
else f.front.value = 42;

If there can be duplicates and you want to change them all:

auto f = entries.filter!(d => d.key == 3);
if(f.empty) entries ~= Data(3,42);
else foreach(ref e; f) e.value = 42;


Fantastic!
Thanks a lot.

Kind regards
André


Re: std.algorithm for changing array values

2014-01-15 Thread anonymous

On Wednesday, 15 January 2014 at 20:54:06 UTC, anonymous wrote:

On Wednesday, 15 January 2014 at 20:34:32 UTC, Andre wrote:

Hi,

I checked std.algorithm but have no glue which
functions I can use to rewrite following code
with some nice algorithm functions.

I have an array of structs. I want to check for
a specific key and if found I change the value.
If it is not found I add the entry.

Kind regards
André


struct Data{
int key;
int value;
}

void main(){
Data[] entries = [Data(1,1),Data(2,2)];

[...]


If you want to stop after the first match:

auto f = entries.find!(d => d.key == 3);
if(f.empty) entries ~= Data(3,42);
else f.front.value = 42;

If there can be duplicates and you want to change them all:

auto f = entries.filter!(d => d.key == 3);
if(f.empty) entries ~= Data(3,42);
else foreach(ref e; f) e.value = 42;


PS: You might want to consider using a different data structure
with better performance. An associative array for example:

int[int] entries = [1: 1, 2: 2];
entries[3] = 42;


Re: std.algorithm for changing array values

2014-01-15 Thread anonymous

On Wednesday, 15 January 2014 at 20:34:32 UTC, Andre wrote:

Hi,

I checked std.algorithm but have no glue which
functions I can use to rewrite following code
with some nice algorithm functions.

I have an array of structs. I want to check for
a specific key and if found I change the value.
If it is not found I add the entry.

Kind regards
André


struct Data{
int key;
int value;
}

void main(){
Data[] entries = [Data(1,1),Data(2,2)];
bool found;

foreach(entry;entries){
if (entry.key == 3){
entry.value = 42;
found = true;
}
}

if (found == false){
entries ~= Data(3,42);
}
}


If you want to stop after the first match:

auto f = entries.find!(d => d.key == 3);
if(f.empty) entries ~= Data(3,42);
else f.front.value = 42;

If there can be duplicates and you want to change them all:

auto f = entries.filter!(d => d.key == 3);
if(f.empty) entries ~= Data(3,42);
else foreach(ref e; f) e.value = 42;


Re: std.algorithm for changing array values

2014-01-15 Thread TheFlyingFiddle

On Wednesday, 15 January 2014 at 20:34:32 UTC, Andre wrote:

Hi,

I checked std.algorithm but have no glue which
functions I can use to rewrite following code
with some nice algorithm functions.

I have an array of structs. I want to check for
a specific key and if found I change the value.
If it is not found I add the entry.

Kind regards
André


struct Data{
int key;
int value;
}

void main(){
Data[] entries = [Data(1,1),Data(2,2)];
bool found;

foreach(entry;entries){
if (entry.key == 3){
entry.value = 42;
found = true;
}
}

if (found == false){
entries ~= Data(3,42);
}
}



You can use canFind.

import std.algorithm;

struct Data{
   int key;
   int value;
}

void main()
{
   auto entries = [Data(1,1),Data(2,2)];

   if(!entries.canFind!(x => x.key == 3))
  entries ~= Data(3, 42);
}



std.algorithm for changing array values

2014-01-15 Thread Andre

Hi,

I checked std.algorithm but have no glue which
functions I can use to rewrite following code
with some nice algorithm functions.

I have an array of structs. I want to check for
a specific key and if found I change the value.
If it is not found I add the entry.

Kind regards
André


struct Data{
int key;
int value;
}

void main(){
Data[] entries = [Data(1,1),Data(2,2)];
bool found;

foreach(entry;entries){
if (entry.key == 3){
entry.value = 42;
found = true;
}
}

if (found == false){
entries ~= Data(3,42);
}
}


Re: Why is string.front dchar?

2014-01-15 Thread TheFlyingFiddle

On Tuesday, 14 January 2014 at 01:12:40 UTC, bearophile wrote:

TheFlyingFiddle:



But for backwards compatibility reasons in this code:

foreach (c; "somestring")

c is a char, not a dchar. You have to type it explicitly to 
handle the UTF safely:


foreach (dchar c; "somestring")


This is why i was confused really since the normal foreach is 
char it's weird that string.front is not a char. But if foreach 
being a char is only the way it is for legacy reasons it all 
makes sense.


Re: A little of coordination for Rosettacode

2014-01-15 Thread qznc
I just made some scripts [0] to download and compile all D 
examples from Rosettacode. From 186 of 716 examples fail to 
compile [1]. Some for trivial reasons like not wrapped into a 
main function or a missing import. Some require SDL or Tango or 
other third-party libraries.


My ultimate goal was to use this for regression testing dmd. 
Anyways if people try code examples they should compile out of 
the box for good PR.


If you are looking for a low-barrier way to support D a little, 
feel free to check out the fail list [1] and fix some. :)


[0] 
https://bitbucket.org/qznc/rosetta/src/da12e3673b0d/compile_all/?at=master

[1] https://gist.github.com/qznc/9ba4b0e78abfc35d4694


Re: errors with filesystem operations

2014-01-15 Thread Hugo Florentino

On Wed, 15 Jan 2014 13:41:50 +0100, Jacob Carlborg wrote:

... On Linux, hidden files are all files where
the filename starts with a dot. To make it visible you need to rename
the file. As far as I know, Linux doesn't have any form of system
attribute.


I am aware of this. However, FAT32 and NTFS (through ntfs-3g) and even 
ExFAT (I do not remember now the name of the project) are supported by 
Linux, so there should be a way to alter file structure so as to change 
attributes even if the OS does not natively provide a function for this 
(why should a user working in Linux be forced to reboot in Windows not 
even to run an unported application but just to change file attributes 
in a filesystem the OS supports)?


Has anyone attempted it from D?


Re: errors with filesystem operations

2014-01-15 Thread Jacob Carlborg

On 2014-01-15 11:33, Hugo Florentino wrote:

Hi,

I am trying to make a little application to revert the effect of some
viruses on USB memories, and running it from Windows encountered some
exceptions that IMHO should not have happened.
Maybe I am missing something. Can you please check the commented blocks
for errors?

Also, is there a way from Linux to remove attributes readonly, system,
hidden ?


As of 2.065 (not release yet) you can set file attributes using 
std.file.setAttributes [1]. On Linux, hidden files are all files where 
the filename starts with a dot. To make it visible you need to rename 
the file. As far as I know, Linux doesn't have any form of system attribute.


[1] 
https://github.com/D-Programming-Language/phobos/commit/5ab8dae665c27ed45eced244720e23e53ef23457


--
/Jacob Carlborg


errors with filesystem operations

2014-01-15 Thread Hugo Florentino

Hi,

I am trying to make a little application to revert the effect of some 
viruses on USB memories, and running it from Windows encountered some 
exceptions that IMHO should not have happened.
Maybe I am missing something. Can you please check the commented blocks 
for errors?


Also, is there a way from Linux to remove attributes readonly, system, 
hidden ?


Regards, Hugo



import std.stdio;
import std.path;
import std.regex;
import std.file;
import std.string;

static string info = "CureUSB 0.3 (2014-01-14)";
static string str_moved   = "Moved";
static string str_deleted = "Deleted";
static string str_finished   = "Done";
static string str_setattrib = "Attributes set";
static string str_safename = "SafeToDelete";

// Expression to match directories with blanks for name
static auto re = regex(`^\s+$`);

version(Windows)
{
  import core.sys.windows.windows;
  extern(Windows) uint SetFileAttributesA(LPCSTR, DWORD);
}

int main()
{
  string ExePath = thisExePath();
  string SearchPath = rootName(ExePath);
  string BlankDirToDelete;

  version(Windows) SetConsoleOutputCP(65001);
  writefln(info);

  foreach(DirEntry d; dirEntries(SearchPath, SpanMode.shallow))
  {
auto m = matchFirst(baseName(d.name), re);
if (m.captures.length > 0)
{
  if (isDir(d.name))
  {
foreach(DirEntry f; dirEntries(d.name, SpanMode.shallow))
{
  string origname = buildPath(SearchPath, baseName(f.name));
  rename(f.name, origname);
  writefln(`%s "%s"`, str_moved, origname);
}
BlankDirToDelete = d.name;
  }

  break;
}
  }

  // The following block does not work; supposedly the process does not 
have
  // access to the directory because it is being used by another 
process,

  // which does not seem to be the case. Uncomment to try
  /*
  if (exists(BlankDirToDelete)) try
  {
string SafeToBeDeleted = buildPath(SearchPath, str_safename)
rename(BlankDirToDelete, SafeToBeDeleted);
remove(SafeToBeDeleted);
  }
  catch (FileException e)
writeln(e.msg);
  */

  foreach(DirEntry d; dirEntries(SearchPath, SpanMode.shallow))
  {
if (d.name != ExePath)
{
  string bname = baseName(d.name);
  version(Windows)
  {
if ( (bname != "RECYCLER")
  && (bname != "$Recycle.bin")
  && (bname != "System Volume Information")
  && (bname != "Recovery")
  && (bname != "MSOCache")
) SetFileAttributesA(toStringz(d.name), FILE_ATTRIBUTE_NORMAL + 
FILE_ATTRIBUTE_ARCHIVE);

  }

  // The following block gives a FileException, claiming that the 
specified file

  // could not befound. Uncomment to try
  /*
  string exten = extension(d.name);
  if (exten.length > 0)
  {
// writefln(`"%s" "%s"`, d.name, extension(d.name)); //debug 
line

if ( (exten == ".exe")
  || (exten == ".lnk")
  || (exten == ".scr")
  || (exten == ".cpl")
  || (exten == ".hta")
  || (exten == ".com")
  || (exten == ".bat")
  || (exten == ".vb")
  || (exten == ".vbs") )
  if (isDir(buildPath(SearchPath, 
stripExtension(baseName(d.name)

  {
remove(d.name);
writefln(`%s "%s"`, str_deleted, d.name);
  }
  }
  */
}
  }

  writefln("%s", str_setattrib);

  writefln("%s.", str_finished);

  return 0;
}