Re: Frontend and backend communication

2011-08-10 Thread Pelle
On Wed, 10 Aug 2011 10:35:46 +0200, Dainius (GreatEmerald)  
past...@gmail.com wrote:



I seem to have run into a problem with the function pointer method
here. I have this code:

arco.d:

struct FrontendFunctions {
void function(SoundTypes) Sound_Play;
void function() RedrawScreenFull;
void function(const char*, int) PrecacheCard;
void function(CardInfo, int) PlayCardAnimation;
}

cards.d:

void InitLuaFunctions()
{
lua[Damage] = (int Who, int Amount)
{
FrontendFunctions.Sound_Play(SoundTypes.Damage);
};
}

Essentially I am trying to get Lua (via LuaD) to call a function in D
that calls a frontend function. But when I compile the code, I get
this: cards.d(5): Error: 'this' is only defined in non-static member
functions, not __dgliteral14. Why is this and what can I do about it?


FrontendFunctions frontendFunctions;

use frontendFunctions everywhere.

OR (this makes them global):

struct FrontendFunctions {
static:
...
}


Re: More than one invariant per struct/class

2011-08-08 Thread Pelle
On Sat, 06 Aug 2011 22:53:31 +0200, Jonathan M Davis jmdavisp...@gmx.com  
wrote:



Feel free to create a feature request on it. It may even get the language
changed. However, having more than one invariant complicates things a  
bit,
since right now, it's easy for the runtime to just call the one  
invariant. If

you had multiple invariants, they would have to be merged somehow by the
compiler. It's completely doable, but it definitely complicates things,  
which

is probably why it doesn't work that way now.


unittests are already merged this way, so it should be easy.


Re: Multi-file byte comparison tool. What would you have done differently?

2011-08-08 Thread Pelle

On Fri, 05 Aug 2011 18:43:27 +0200, Kai Meyer k...@unixlords.com wrote:


On 08/05/2011 03:02 AM, Pelle wrote:


Don't declare variables until you need them, just leave bytes_read and
bytes_max here.

Is there a performance consideration? Or is it purely a style or  
D-Factor suggestion?


Just style and D-factor :-)

Also, resulting code is shorter, and you can replace a lot of type names  
with auto.



I don't understand why you use ByteUnion instead of just a plain array
of bytes.
I thought that comparing one byte at a time would be slower than  
comparing 8 bytes at a time (size_t on 64bit) and failing over to the  
byte-by-byte comparison only when the size_t value was different.


Maybe, but that's something that should be benchmarked. If a byte array is  
just as fast, and the code is simpler, that's a better solution :)


Re: Multi-file byte comparison tool. What would you have done differently?

2011-08-05 Thread Pelle

On Fri, 05 Aug 2011 00:25:38 +0200, Kai Meyer k...@unixlords.com wrote:

I have a need for detecting incorrect byte sequences in multiple files  
(2) at a time (as a part of our porting effort to new platforms.)  
Ideally the files should be identical for all but a handful of byte  
sequences (in a header section) that I can just skip over. I thought  
this would be a fun exercise for my D muscles. I found success creating  
a dynamic array of structs to keep information about each file passed in  
via command-line parameters. I'll append the code at the end (and I'm  
sure it'll get mangled in the process...)


(I'm not one for coming up with creative names, so it's SOMETHING) Then  
I loop around a read for each file, then manually run a for loop from 0  
to BLOCK_SIZE, copy the size_t value into a new dynamic array (one for  
each of the files opened), and run a function to ensure all values in  
the size_t array are the same. If not, I compare each ubyte value (via  
the byte_union) to determine which bytes are not correct by adding each  
byte to a separate array, and comparing each value in that array,  
printing the address and values of each bad byte as I encounter them.


This appears to work great. Some justifications:
I used size_t because I'm under the impression it's a platform specific  
size that best fits into a single register, thus making comparisons  
faster than byte-by-byte.

I used a union to extract the bytes from the size_t
I wanted to create a SOMETHING for each file at run-time, instead of  
only allowing a certain number of SOMETHINGS (either hard coded, or a  
limit).
Originally I wrote my own comparison function, but in my search for  
something more functional, I tried out std.algorithm's count. Can't say  
I can tell if it's better or worse.


Features I'll probably add if I have to keep using the tool:
1) Better support for starting points and bytes to read.
2) Threshold for errors encountered, perferrably managed by a  
command-line argument.

3) Coalescing error messages in sequential byte sequences.

When I run the program, it's certainly I/O bound at 30Mb/s to an  
external USB drive :).


So the question is, how would you make it more D-ish? (Do we have a term  
analogous to pythonic for D? :))



Code:

import std.stdio;
import std.file;
import std.conv;
import std.getopt;
import std.algorithm;

enum BLOCK_SIZE = 1024;
union byte_union
{
 size_t val;
 ubyte[val.sizeof] bytes;
}
struct SOMETHING
{
 string file_name;
 size_t size_bytes;
 File fd;
 byte_union[BLOCK_SIZE] bytes;
}


I would use TypeNames and nonTypeNames, so, blockSize, ByteUnion,  
Something, sizeBytes, etc.



void main(string[] args)
{
 size_t bytes_read;
 size_t bytes_max;
 size_t size_smallest;
 size_t[] comp_arr;
 SOMETHING[] somethings;


Don't declare variables until you need them, just leave bytes_read and  
bytes_max here.



 getopt(args,
 seek, bytes_read,
 bytes, bytes_max
 );
 if(bytes_max == 0)
 bytes_max = size_t.max; // Limit on the smallest file size
 else
 bytes_max += bytes_read;
 //bytes_read = bytes_read - (bytes_read % (BLOCK_SIZE *  
SOMETHING.size_bytes.sizeof));

 size_smallest = bytes_max;
 somethings.length = args.length - 1;
 comp_arr.length = args.length - 1;
 for(size_t i = 0; i  somethings.length; i++)
 {
 somethings[i].file_name = args[i + 1];
 somethings[i].size_bytes = getSize(somethings[i].file_name);
 stderr.writef(Opening file: %s(%d)\n,  
somethings[i].file_name, somethings[i].size_bytes);

 somethings[i].fd = File(somethings[i].file_name, r);
 somethings[i].fd.seek(bytes_read);
 if(somethings[i].fd.tell() != bytes_read)
 {
 stderr.writef(Failed to seek to position %d in %s\n,  
bytes_read, args[i + 1]);

 }
 // Pick the smallest file, or the limit
 size_smallest = min(size_smallest, somethings[i].size_bytes);
 }


Use foreach (ref something; somethings) and something instead of  
somethings[i].



 // Check file sizes
 for(size_t i = 0; i  somethings.length; i++)
 comp_arr[i] = somethings[i].size_bytes;
 writef(count: %s\n, count(comp_arr, comp_arr[0]));
 if(count(comp_arr, comp_arr[0]) != comp_arr.length)
 {
 stderr.writef(Files are not the same size!);
 foreach(s; somethings)
 stderr.writef([%s:%d], s.file_name, s.size_bytes);
 stderr.writef(\n);
 }


You can use writefln() istead of writef(\n) everywhere.



 // While bytes_read  size of smallest file
 size_t block_counter;
 while(bytes_read  size_smallest)
 {
 // Read bytes
 //stderr.writef(tell: );
 for(size_t i = 0; i  somethings.length; i++)
 {
 //stderr.writef(Reading file %s\n, file_names[i]);
 //stderr.writef(%d , somethings[i].fd.tell());
 

Re: NaCl stable ABI

2011-08-05 Thread Pelle

On Thu, 04 Aug 2011 21:56:16 +0200, Nick Sabalausky a@a.a wrote:

OT: Who the hell uses MSN?


Almost everyone below 60 in Sweden, at least a few years ago.


Re: More than one invariant per struct/class

2011-08-04 Thread Pelle

On Thu, 04 Aug 2011 11:32:03 +0200, simendsjo simend...@gmail.com wrote:

I would like to use a template mixin to add some fields to a struct, but  
I'd also like the template to add additional invariant checks without  
having to remember to add this for all struct/classes that mixes in this  
code.


class C {
 int a;
}

mixin template EmbedC() {
 C _c;

 // oops.. more than one invariant
 invariant() {
 assert(_c);
 }

 void close() {
 _c = null;
 }
}

struct S {
 int i = 10;
 invariant() {
 assert(i = 10);
 }

 mixin EmbedC!();
}

void main() {
 S s;
 s.close();
 s._c.a = 10; // access violation, but I want assertion from  
invariant

}


What happens if you replace assert(_c) with assert(_c !is null)?


Re: More than one invariant per struct/class

2011-08-04 Thread Pelle

On Thu, 04 Aug 2011 12:40:48 +0200, simendsjo simend...@gmail.com wrote:

On 04.08.2011 12:30, Pelle wrote:

What happens if you replace assert(_c) with assert(_c !is null)?


The problem is that you cannot include more than one invariant() in a  
struct or class.


IIRC assert(obj) gets rewritten to obj.__invariant() or something like  
that, which segfaults if obj is null. I thought that maybe that was why  
the code didn't work. :--)


Re: Convert string to wchar.

2011-08-03 Thread Pelle

On Wed, 03 Aug 2011 08:29:09 +0200, Jacob Carlborg d...@me.com wrote:
Yes, convert the first code point to a wchar and then throw if there's  
more the one character in the string.




Not tested, and I might be wrong, but 'to!' should work between dchar and  
wchar, no?


wchar to_wchar(string s) {
auto c = s.front;
s.popFront();
assert (s.empty);
return to!wchar(c);
}


Re: Generate array of random values

2011-08-02 Thread Pelle
On Mon, 01 Aug 2011 21:43:13 +0200, Andrej Mitrovic  
andrej.mitrov...@gmail.com wrote:



Actually I don't really need *uniform* distribution, it's just that
when porting C code to D I didn't find any obvious random()/rnd()
functions, and uniform seemed to be the closest thing without having
to mess around with a bunch of randomization parameters which I don't
care about.

I don't see how we can claim D to be an elegant language with this mess:
array(map!a % 1024(take(rndGen(), 1024)))

That's just damn *horrible*.


If we ever get UFCS that'd be rndGen().take(1024).map!a % 1024().array()

Which is a lot better :--)

Without UFCS, well, how would you want it to look? How does it look in  
other languages?


Re: Empy program running time

2011-07-29 Thread Pelle
On Fri, 29 Jul 2011 15:37:36 +0200, bearophile bearophileh...@lycos.com  
wrote:


On an oldish Windows PC an empty C program generated by GCC takes about  
0.03 seconds to run. An empty D2 program runs in about 0.11 seconds. Is  
this expected/good/acceptable/fixable?


Bye,
bearophile


That's a lot better than I expected! I don't think anyone would notice  
such a small difference.


Re: Frontend and backend communication

2011-07-28 Thread Pelle
On Wed, 27 Jul 2011 19:41:37 +0200, Dainius (GreatEmerald)  
past...@gmail.com wrote:



I have one program design problem and I wonder if anyone here could
give any suggestions about it. The situation is like this: I am
splitting a game into a frontend (a library) and a backend (an
executable). The backend is going to handle all the game mechanics,
while the frontend is going to handle I/O. But there are certain
problems. For example, now I have a function Shuffle() that calls
PlaySound(SHUFFLE). Shuffle() is a backend function, while PlaySound()
is a frontend one, so obviously it won't work that way after the
split. It would be ideal if there was a way to create hooks - say an
empty PlaySound() function that the frontend could receive calls to.
But I can't see a way to do that. Another way to do that that was
suggested to me was to use an event loop - set a global variable, then
have the frontend monitor it for changes and then respond as
necessary, but that just isn't a very clean way to do it.

And then there is the fact that the backend is going to be written in
D (right now it's a mix of C and D), while the frontend will be in C
(one of the frontends, anyway - the second one will also be in D). Any
suggestions about this?


You could use a struct of function pointers to define the interface, if
you need it to work both in C and D.

extern (C) struct FrontEndFunctions {
void function(sound) playSound;
...
}

backend does myFrontEndFunctions.playSound(SHUFFLE);

The front end:

void myPlaySound(...) { ... }

void main() {
FrontEndFunctions functions;
functions.playSound = myPlaySound;
... etc for other functions ...;
backend.initialize(functions);
backend.run();
}


Re: Importing D libraries

2011-07-26 Thread Pelle
On Tue, 26 Jul 2011 13:06:56 +0200, Dainius (GreatEmerald)  
past...@gmail.com wrote:



I updated the DMD and tried RDMD, but still no luck. Linker errors
galore. You can see all of them here: http://pastebin.com/C6cRVGKt


You need to link the library as well, try adding -L-llua (I think) to the  
command.


Re: Calling anonymous delegate recursively ?

2011-01-08 Thread Pelle

On 01/08/2011 04:45 PM, tsukikage wrote:

eg. to return a fibonacci delegate:

return (ulong m) {
if(m  2) return m ;
return _self_ref(m-1)+_self_ref(m-2) ;
} ;

Is it possible? Thank you!


http://en.wikipedia.org/wiki/Fixed_point_combinator#Y_combinator

I don't think there's a built in way to self-recurse.


Re: How the GC distinguishes code from data

2011-01-06 Thread Pelle

On 01/06/2011 07:31 AM, %u wrote:

If you have allocated a large uint[], most likely =C3=ACt will be flagged

NO_SCAN, meaning it has no pointers in it, and the GC will ignore it.


Ah, but the trouble is, no one said that this array has to be in the GC heap! I
could easily have a void[] and a uint[] that both point to non-GC managed 
memory.
Or I might even have a uint[] allocated on the stack! How does the GC 
distinguish
these, when there's no attribute it can mark? (Or does it?!)


It assumes everything on the stack is pointers, at the moment, I believe.

If it's not on the garbage collected heap, it won't scan it unless you 
tell it to.


Re: terminology: l-value r-value

2011-01-04 Thread Pelle

On 01/04/2011 02:55 PM, spir wrote:

Hello,

I'm bluffed by the 2 terms l-value  r-value used in C-line language common 
terminologies. I think I guess what they mean, but I don't understand the need for such absconse 
idioms. Why not:
l-value-  variable
r-value-  value (or expression)
?

I guess (*p) is considered an l-value. Indeed, it's a special way of denoting a 
variable, matching the special case of a pointer. If correct, this requires 
slightly extending the notion of variable (and/or of identifier).
On the r-value side, I cannot find anything that makes it a distinct concept 
from the one of value, or of expression.

Explanations welcome, thank you,
Denis
-- -- -- -- -- -- --
vit esse estrany ☣

spir.wikidot.com



rvalue is easier than value-not-bound-to-a-memory-address.

lvalue is easier than value-with-memory-address.

Both lvalues and rvalues are values, both can be expressions, and 
lvalues doesn't have to be variables.


Perhaps a better terminology could have been chosen, but changing them 
doesn't provide real benefits, as far as I can tell.


Re: Odd to!string call

2010-12-26 Thread Pelle

On 12/21/2010 07:38 PM, Andrej Mitrovic wrote:

I found this by accident:

import std.stdio;
import std.conv;

void main()
{
 writeln(to!string(2, 2));  // writes 10
 writeln(to!string(1, 0));  // std.conv.ConvException: Radix error
}

I'm not sure why std.conv.to would even take multiple arguments. Bugzilla?


to! does some fancy stuff, like here:

auto myarr = [1,2,3];
writeln(to!string(myarr, myarr:\n, \n, \n-\n);

will write (untested, but should work :-)

myarr:
1
2
3
-

I find this most useful a lot of the time.


Re: List of derived types?

2010-12-16 Thread Pelle Månsson

On 12/16/2010 02:16 PM, d coder wrote:

Greetings

I need a way to know (using traits or other compile time constructs)
all the types derived from a given type.
Is it possible in D?

Is it possible to get a list of all the user-defined classes? I could
use that to filter out the classes that I need.

Regards
Cherry


I'm curious, why do you need that?


Re: Concurrency and transfering ownership of data between threads?

2010-12-14 Thread Pelle Månsson

On 12/13/2010 09:45 PM, Heywood Floyd wrote:

Good Evening from Berlin!


Have been reading the chapter about concurrency by Andrei. Nice.

I have some questions, of varying quality, I'm sure.


Let's say that we have some sort of structure of rather complex data. To give 
us something concrete to talk about, let's say this data is a tree of nodes 
representing 3-dimensional objects. It could look something like this: (Not 
complete example, just to give an idea.)

// ...
class Cube : Node{
float x, y, z, size, mass, elasticity;
// ...
}
// ...
tree.add(new Cube(cube1));
tree[cube1].add(new Cube(cube2));

Let's further say that this structure of data will be subjected to two 
different activities: 1) We will change properties of some nodes according to 
some complex lengthy calculations, which may even entail changing the position 
of nodes in the tree, and 2) we will traverse the tree in a recursive manner 
and read the properties in order to render a representation of these nodes to 
screen.

These two activities will then be repeated many times, so, let's say we wish to 
do these two activities in parallel as much as possible!

How do we do that?

 From what I can tell, one way of doing this would be to actually have two data structures, one 
which is the original and is used for the calculations, and one which is just a copy of 
the data after each calculation. We could then insert a third activity, which me can call 
copy, inbetween the two threads. Something like this:

|== Calculate ===| Copy |
|v   |= Render |

Seems to me this would then allow us to interlock these two activites:

..|== Calculate ===| Copy |== Calculate |..
..|=== Render  ===|v   |=== Render |..

(Sorry if the ASCII graphics looks skewed.)
So let me just try and set up some kind of rudamentary code for this in 
layman's D:

// import ...
void main()
{
 auto tree = new Node();
 tree.add(new Cube(cube1));

 auto child = spawn(renderLoop, thisTid);

 while(true)
 {
 calc(tree);
 auto treeCopy = tree.deepDup();
 receiveOnly!bool();
 send(child, treeCopy);
 }
}

void renderLoop(Tid parent){
{
 send(parent, true);
 while(true)
 {
 Node tree = receiveOnly!Node();
 render(tree);
 send(parent, true);
 }
}


So a couple of thoughts here.

- Is this looking ok? What is the proper way of going about this?

- How do we send over a large chunk of complex data to another thread and sort of let 
them assume ownership of this data? So that the thread receiving the data 
does not need any locks etc. when working with the data? I suppose we could send over the 
entire treeCopy as immutable (?) but let's for the sake of argument assume that 
renderLoop() needs to be able to _write_ in the copy of the tree structure too!

(- Sidenote: How do we efficiently copy a tree-structure of data several times 
per second? Sounds insane to me?)

Let's further, for the sake of argument, NOT consider that the GPU will do most 
of the rendering and that in effect parallelising in this particular case may 
be marginally beneficial. Let's simply assume we have only one processor here: 
your normal household dual-core CPU, and a VGA-graphics card from the 80s.

For me, in my head, parallelising is very much about designing a flow of data through different processes, 
and this flow chart will have certain hot spots where data must be guarded. You have one process 
doing something and then transfering over some data to the next process that continues the 
calculations. (With process I simply mean data processing activity, not a unix process.)

|---calc A---Ocalc C  etc.
|---calc B-^

O = transfer point

I find it difficult to see how this is done in D. (Of course, I'm not sure this 
transfer-idea makes any practical sense.) I understand immutable makes data 
read-only, contagiously, and shared makes data heavily guarded.

But yes, is there any way we can transfer ownership (not sure if that is the 
right term) of data from one thread to another? So that we can have two threads working 
on two pieces data, then let them copy it (or not!), and then transfer ownership and have 
a third thread work on the copied data, without barriers or guards or stuff like that 
during the time of actual work?


Kind regards and sorry for a lengthy sporadic post
/Heywood Floyd






I think you should probably use shared. With the guards and all. And 
then not copying it, just sending the reference.


If the write barriers make this too slow, try selectively casting away 
shared at heavy working spots, when you know that's the only place using 
the object at that time. I think that should be safe. (?) :)


Re: import inside a class overrides symbols imported in module scope?

2010-12-09 Thread Pelle Månsson

On 12/09/2010 10:53 PM, Trass3r wrote:

It was quite hard to track that one down.
In the following example the import statement was mixed into the class
among other code so it wasn't as obvious as here.

import std.traits;
class Foo
{
import std.string;
static assert(isNumeric!int);
}


foo.d(6): Error: template instance isNumeric is not a template
declaration, it is a function
foo.d(6): Error: static assert (isNumeric!(int)) is not evaluatable at
compile time

(There's an isNumeric function in std.string)


Local variables override global ones, but is this correct as well?


You probably want to use static import when mixing stuff in, to avoid 
this accidental invasion of namespace.


Re: C++ istream / ostream equivalent ?

2010-12-02 Thread Pelle Månsson

On 12/02/2010 09:05 AM, vincent picaud wrote:

Matthias Pleh Wrote:





Thank you for your reply and yes that works :)

Now i m facing with the following problem, what is the trick for input stream ?

( something like

std::istream   operator(std::istream   in,A   a)
{
//  A.someData   in;
return in;
}

in C++ )

I m thinking of the situation when we want to load some data from a file.

The toString() trick is okay for saving the object... but how to load it back 
(something like fromString(char[]) would do the job but it does not exist in 
Object) ?

Anyway thank you, you solved half of my problem :)




Ther are many posibilities, depending on your further needs! Just have a
look at the online dokumentation:
http://www.digitalmars.com/d/2.0/phobos/phobos.html

But my first try would be such ..
(note: I've leaved out error-handling ...)

module test;

import std.stdio;
import std.file;

class A
{
  void writeToFile()  { std.file.write(sample.txt,someData);   }
  void readFromFile() { someData=cast(string)read(sample.txt); }
  void clear(){ someData=n/A\n; }
  string toString()   { return someData;  }
private:
  string someData=Just some data.
With anohter line of date.
Even more data.!; 
}

int main(string[] args)
{
A a=new A;
a.writeToFile();
a.clear();
writeln(a);
a.readFromFile();
writeln(a);
return 0;
}


thank you for all your answers. I understand the approach, but in the same 
time, I have the feeling that the C++ way is more convenient.

Look in C++ , to define I/O  for A,  you do not have to modify your class A and 
simply have to overload two functions:

std::ostream  operator(std::ostream  out,const A  a)
std::istream   operator(std::istream   in,A   a)

moreover this smoothly extend the I/O C++ framework without other side effect.

I was expecting to find a similar mecanism in D/Phobos

Perhaps by overloading some read(), write() functions of the Phobos library, but I do not 
know if it is moral to do that and which phobos functions are concerned... 
IMHO there is a documentation hole here




What you want is the new writeTo system for output. For input, a 
readFrom would be symmetrical and make sense :-)


To actually use it, you would just do myFile.write(your, stuff, etc);

For now, you can stringify using toString(). No way to read yet, except 
to!int, etc.




Re: 'in' for plain arrays?

2010-12-02 Thread Pelle Månsson

On 12/02/2010 01:07 PM, spir wrote:

Hello,

Is there an equivalent of 'in' for (non-associative) arrays? Cannot find any 
'contains' function.
(Wouldn't it be nice to have in work for all arrays? What is the reason why it 
only works with AAs?)

Denis
-- -- -- -- -- -- --
vit esse estrany ☣

spir.wikidot.com



It doesn't exist for performance reasons, I think.

Use std.algorithm.canFind, which doesn't have the best name, but works 
as expected.


Re: Const foreach

2010-11-22 Thread Pelle Månsson

On 11/22/2010 04:12 PM, Simen kjaeraas wrote:

spir denis.s...@gmail.com wrote:


On Sun, 21 Nov 2010 20:21:14 -0500
bearophile bearophileh...@lycos.com wrote:


If in a D2 program I have an array of mutable items I may want to
iterate on them but not modify them, so I'd like the iteration
variable to be const. This is possible, but it seems I lose type
inference:


void main() {
int[3] array; // not const
// foreach (const x; array) {} // Error
// foreach (const auto x; array) {} // Error
// foreach (const(int) x; array) {} // OK
foreach (const(typeof(array[0])) x; array) {} // OK
}


Is something wrong in that code? Is this a known limitation, an
inevitable one? Is this an enhancement request worth adding to Bugzilla?

Bye and thank you,
bearophile


Maybe you'll find it weird, but I would expect
foreach (const(auto) x; array) {};
to be the logical idiom for this. auto beeing a kind of placeholder
for a type name.


'auto' is not a placeholder for a type, but the default storage class.
IOW, 'int n;' == 'auto int n;'. This does however not compile,
complaining that it has no effect.

Specifying just the storage class signals the compiler to use type
inference. Try it:

const x = 4;
immutable y = 4;



I'm not sure you are correct:

const static auto x = 4;


Re: defining in a module symbols for export

2010-11-22 Thread Pelle Månsson

On 11/22/2010 08:18 PM, spir wrote:

Hello,

Let us say I have a parsing library. Now, I want to define parsers in 
stand-alone modules -- for code structuration and reusability. Then, import 
them from apps that need them.
Is there another way than defining the parser (== list of patterns) at the 
module's top-level. I have nothing against this, since the module is dedicated 
to this anyway -- but dmd refuses.
More generally, I find myself unable to define structured objects at a 
modules's top level. for instancz:

=== mod.d ==
import std.stdio;

struct S {
 int i;
 void speak() {writeln(i: ,this.i);}
}
=== __trials__.d ===
import mod;

auto s = S();
s.speak();
s.i = 1;
writeln(s.i);

void main () {
}

=== compilation ===
__trials__.d(19): no identifier for declarator s.speak
__trials__.d(20): no identifier for declarator s.i
__trials__.d(21): found '.' when expecting ')'
__trials__.d(21): semicolon expected, not 'i'
__trials__.d(21): no identifier for declarator i
__trials__.d(21): semicolon expected, not ')'
__trials__.d(21): Declaration expected, not ')'

Why does dmd refuse? If I put the code in a function, I can compile, link, and 
run it. But this does not match my use case: I need to export symbols 
(patterns) defined there; so, i guess, they must be defined at the top of the 
module. Is there another solution?

I take the opportunity to ask whether it is possible to define which symbols 
are to be _ex_ported.


Denis
-- -- -- -- -- -- --
vit esse estrany ☣

spir.wikidot.com



To initialize at runtime:

S s;
static this() {
s.i = 1;
}

to initialize at compile time:

S getS() { S s; s.i = 1; return s; }
S s = getS();

Use public/private to control which symbols are availible. 
Unfortunately, this doesn't really work at the moment :-)


Re: segfault

2010-11-14 Thread Pelle Månsson

On 11/12/2010 02:03 PM, Steven Schveighoffer wrote:


Pelle, I spent all this time helping him, and you swoop in with the
answer :)


I was in a rush when answering, causing the swoopiness of my post. :-)

I only knew the answer because I had almost exactly the same bug a week 
ago, or so. Coincidentally, for a parser generator.


Re: Combining variadic functions with class templates

2010-09-30 Thread Pelle

On 09/30/2010 08:25 PM, Sebastian Schuberth wrote:

On 30.09.2010 20:20, wrzosk wrote:


void main()
{
Vec3f v(1,1,1);
}

I still get

Building Release\ConsoleApp1.exe...
main.d(14): found 'v' when expecting ';' following statement
Building Release\ConsoleApp1.exe failed!


Change
Vec3f v(1,1,1);
into
Vec3f v = Vec3f(1,1,1);


Thanks, that works, but that syntax seems a little verbose to me. Is the
first syntax generally not supported in D?



It is not. You can use auto v = Vec3f(1,1,1);


Re: Immutable woes

2010-09-21 Thread Pelle

On 09/21/2010 09:29 AM, Bob Cowdery wrote:

  Hi

I'm stuggling with immutable.

I have a fixed size buffer which is used as a circular buffer of floats
and is effectively double buffering data I wish to transfer to another
thread. At an appropriate point I take the top half or bottom half of
the buffer and send it to another thread.

To do this I need to copy the data to an immutable transfer buffer to
use in the send. I'm sure this is simple but I can't figure it.

if I say something like:
float[] xfer = new float[512];
xfer = buffer[0 .. $/2];
tid.send(xfer);

it rightly tells me 'thread local data not allowed'. If I make it:

immutable (float)[] xfer;
xfer = buffer[0 .. $/2];
tid.send(xfer);

it tells me 'can't implicitly convert float[] to immutable (float)[]'

If I try a float by float copy into xfer it can't because I've said the
buffer is immutable. In the first example I can't figure out how to
convert the slice into an immutable copy which I think is what I should
be doing.

Can someone point me in the right direction.

Thanks
Bob



immutable(float)[] xfer = buffer[0 .. $/2].idup;
tid.send(xfer);

Don't use assumeUnique for non-unique references.


Re: ubyte[] - immutable(ubyte)[]

2010-09-10 Thread Pelle

On 09/10/2010 04:40 AM, Andrej Mitrovic wrote:

  I'm trying to use algorithm.copy, but I get back nothing in the copy buffer. 
How do I to copy an array of ubyte's?

iimport std.algorithm,
std.concurrency,
std.stdio;

void main()
{
 enum bufferSize = 4;
 auto tid = spawn(fileWriter);

 // Read loop
 foreach (ubyte[] buffer; stdin.byChunk(bufferSize))
 {
 immutable(ubyte)[] copy_buffer;
 copy(buffer, copy_buffer);

 writeln(copy_buffer);  // writes nothing

 send(tid, copy_buffer);
 }
}

void fileWriter()
{
 while (true)
 {
 auto buffer = receiveOnly!(immutable(ubyte)[])();
 // writeln(buffer);
 }
}

Andrej Mitrovic Wrote:


This is from TDPL page 407:

import std.algorithm,
std.concurrency,
std.stdio;

void main()
{
 enum bufferSize = 1024 * 100;
 auto tid = spawn(fileWriter);

 // Read loop
 foreach (immutable(ubyte)[] buffer; stdin.byChunk(bufferSize))
 {
 send(tid, buffer);
 }
}

void fileWriter()
{
 // write loop
 while (true)
 {
 auto buffer = receiveOnly!(immutable(ubyte)[])();
 tgt.write(buffer);
 }
}

Error:
C:\DMD\dmd2\windows\bin\..\..\src\phobos\std\stdio.d(1943):
Error: cannot implicitly convert expression (buffer) of type ubyte[]
to immutable(ubyte)[]

Yet interestingly I can't use type inference:

 foreach (buffer; stdin.byChunk(bufferSize))
 {
 send(tid, buffer);
 }

Error: stdin_stdout_copy.d(11): Error: cannot infer type for buffer

But in the original code I get back a mutable ubyte[] which I can't implicitly 
convert to immutable (I'd need a copy first). There's no .dup or .idup property 
for stdin.byChunk. So what am I supossed to do here?






std.algorithm.copy will copy an input range into an output range. An 
array is a valid output range, but does not append as you seem to 
expect. Instead, it fills the array.


int[] a = new int[](3);
copy([1,2,3],a);
assert (a == [1,2,3]);

To get an output range which appends to an array, use appender.

In this case, however, you simply want buffer.idup; :-)


Re: slow runtime

2010-09-10 Thread Pelle

On 09/10/2010 10:17 AM, Jonathan M Davis wrote:

On Friday 10 September 2010 00:50:32 bearophile wrote:

Jonathan M Davis:

Aren't they _always_ on the heap?


void main() {
 int[10] a;
 int[] b = a[];
}

Bye,
bearophile


Ah, good point. When you have a slice of a static array as opposed to a dynamic
arra allocated with new, then it's on the stack. Since I pretty much never use
static arrays, I forgot about that.

- Jonathan M Davis


int i;
int[] heh = (i)[0..1];


Re: Question about typeof(this)

2010-09-10 Thread Pelle

On 09/10/2010 03:20 PM, Jacob Carlborg wrote:

On 2010-09-07 22:32, Don wrote:

Jacob Carlborg wrote:

On 2010-09-07 17:29, Don wrote:

Jacob Carlborg wrote:

I'm reading http://www.digitalmars.com/d/2.0/declaration.html#Typeof
where it says:

typeof(this) will generate the type of what this would be in a
non-static member function, even if not in a member function. 

From that I got the impression that the code below would print the
same result, but it doesn't. It prints:

main.Bar
main.Foo

instead of:

main.Foo
main.Foo

Is this a bug or have I misunderstood the docs?


typeof(this) gives the *compile-time* type of this. Inside Bar, it has
to return 'Bar'.
typeid(this) gives the *runtime* type of this. So it can work that it's
Bar is actually a Foo.


I know that typeof(this) is a compile time expression but in this case
I think the compiler has all the necessary information at compile
time. Note that I'm not calling method on a base class reference,
I'm calling it on the static type Foo. In this case I think
typeof(this) would resolve to the type of the receiver, i.e. the type
offoo.


Even though in this instance it could work out which derived class is
being used, it's not allowed to use that information while compiling
method(). There is only ONE function method(), and it has to work for
Bar, and all classes derived from Bar.


I think Scala can handle this problem, the following text is a snippet
from a paper called Scalable Component Abstractions (link at the
bottom), page 4 Type selection and singleton types:

class C {
protected var x = 0;
def incr: this.type = { x = x + 1; this }
}

class D extends C {
def decr: this.type = { x = x - 1; this }
}

Then we can chain calls to the incr and decr method, as in

val d = new D; d.incr.decr;

Without the singleton type this.type, this would not have
been possible, since d.incr would be of type C, which does
not have a decr member. In that sense, this.type is similar
to (covariant uses of ) Kim Bruce's mytype construct [5].

I'm not very familiar with Scala but the above code example seems to
work as I want typeof(this) to work.

http://www.scala-lang.org/sites/default/files/odersky/ScalableComponent.pdf



You can do this in D, but the syntax is clumsy. And it uses templates.

class C {
int x;
T incr(this T)() {
x += 1;
return cast(T)this; // clumsy, but always works (?)
}
}
class D : C {
T decr(this T)() {
x -= 1;
return cast(T)this;
}
}

void main() {
D d = new D;
d.decr.incr.decr.incr.incr;
writeln(d.x);

}


Re: Generic collection/element function signatures in D2 versus D1

2010-09-08 Thread Pelle

On 09/08/2010 02:24 PM, Steven Schveighoffer wrote:

On Tue, 07 Sep 2010 14:06:58 -0400, Steven Schveighoffer
schvei...@yahoo.com wrote:


On Tue, 07 Sep 2010 11:37:20 -0400, Pelle pelle.mans...@gmail.com
wrote:


On 09/07/2010 04:33 PM, Steven Schveighoffer wrote:

Yes, a valid return. Your function should be:

void foo(void delegate(const(C) f) const

It helps to understand that inout/const/immutable has NOTHING to do
with
code generation, it only has to do with limiting what compiles. For
this
reason, an inout function is compiled once, and works on all three
constancies (4 if you have a nested inout function). For the entire
function any inout variable is treated as a non-changeable value, just
like const. Then when you return, it's converted at the call site back
to the constancy with which it was called. If the return value is void,
then there's nothing to convert, and no reason to use inout over const.

I'll repeat -- there is no benefit to inout if you are not returning
anything.

-Steve


That's not an equivalent function signature. Or maybe it is, but look
at this (sorry it's so long):

class C {
int x;
this(int y) { x = y; }

inout(int*) foo() inout {
return x;
}
void bar(void delegate(int*) f) {
f(x);
}
void bar(void delegate(const(int*)) f) const {
f(x);
}
void bar(void delegate(immutable(int*)) f) immutable {
f(x);
}
}

void main() {

immutable(int)* wah;
void wahwah(immutable(int*) x) {
wah = x;
}
auto c = new immutable(C)(10);
wahwah(c.foo); // why is this privilegied with inout
c.bar(wahwah); // and this not?

writeln(*wah);

}

Can't use void delegate(const(int*)) there.


Thanks for clarifying, I didn't quite understand the usage before.

This is a limitation of inout's design. Technically inout requires a
single inout output, and can have multiple inout inputs. Your example
matches that description, so in theory it's possible.


I realized last night that this won't work. Simple reason -- during an
inout function, the function promises to treat the arguments as if they
were const.

If your class instance was mutable, this would not be true, e.g.:

class C
{
int x;
void bar(void delegate(inout(int)* f) inout { f(x); }
}

void main() {

auto c = new C;
void dg(int *f) {*f = 10;}
c.bar(dg); // modifies c, even though the function is marked as inout
}

-Steve


Well, inout was conceived as a counter to where you need to write the 
exact same function for every type of constness, was it not? :-)


Re: Generic collection/element function signatures in D2 versus D1

2010-09-07 Thread Pelle

On 09/07/2010 03:15 PM, Steven Schveighoffer wrote:

On Tue, 07 Sep 2010 08:56:15 -0400, Jacob Carlborg d...@me.com wrote:


On 2010-09-07 14:49, Steven Schveighoffer wrote:

On Sun, 05 Sep 2010 09:40:59 -0400, BLS windev...@hotmail.de wrote:


On 05/09/2010 02:16, Jonathan M Davis wrote:

void foo(T)(T[] collection, T elem)

{
// Blah, whatever
}



I am curious, how this will look and feel once inout is working ?

inout void foo(T)(inout(T)[] collection, inout T elem)
{
// Blah, whatever}
}



inout void doesn't make any sense. You can't have a const void or
immutable void.

Now, if foo is a member function, then inout applies to the this
pointer, but even then, you need a return type other than void for inout
to be used.

-Steve


inout is only used when you want to return the same constness
(mutable, const, immutable) as you passed in to the function. If you
don't want that, or don't want to return anything then const(T)[] is
what you want. It will accept mutable, const and immutable.


Yes, exactly. This is why inout functions cannot return void.

-Steve


Hmm.

class C {
void foo(void delegate(inout(C)) f) inout {
f(this);
}
}

Am I missing something?


Re: Generic collection/element function signatures in D2 versus D1

2010-09-07 Thread Pelle

On 09/07/2010 04:33 PM, Steven Schveighoffer wrote:

Yes, a valid return. Your function should be:

void foo(void delegate(const(C) f) const

It helps to understand that inout/const/immutable has NOTHING to do with
code generation, it only has to do with limiting what compiles. For this
reason, an inout function is compiled once, and works on all three
constancies (4 if you have a nested inout function). For the entire
function any inout variable is treated as a non-changeable value, just
like const. Then when you return, it's converted at the call site back
to the constancy with which it was called. If the return value is void,
then there's nothing to convert, and no reason to use inout over const.

I'll repeat -- there is no benefit to inout if you are not returning
anything.

-Steve


That's not an equivalent function signature. Or maybe it is, but look at 
this (sorry it's so long):


class C {
int x;
this(int y) { x = y; }

inout(int*) foo() inout {
return x;
}
void bar(void delegate(int*) f) {
f(x);
}
void bar(void delegate(const(int*)) f) const {
f(x);
}
void bar(void delegate(immutable(int*)) f) immutable {
f(x);
}
}

void main() {

immutable(int)* wah;
void wahwah(immutable(int*) x) {
wah = x;
}
auto c = new immutable(C)(10);
wahwah(c.foo);  // why is this privilegied with inout
c.bar(wahwah); // and this not?

writeln(*wah);

}

Can't use void delegate(const(int*)) there.


Re: Understanding isInfinite(Range)

2010-09-06 Thread Pelle

On 09/04/2010 02:11 PM, Simen kjaeraas wrote:

Peter Alexander peter.alexander...@gmail.com wrote:


== Quote from Steven Schveighoffer (schvei...@yahoo.com)'s article

On Fri, 03 Sep 2010 11:12:29 -0400, Andrej Mitrovic
andrej.mitrov...@test.com wrote:
 What does char[1 + Range.empty] do? It looks rather cryptic..
char[1+Range.empty] is a type. If Range.empty is a compile-time
constant,
then this type is valid, otherwise it's not valid (the is expression
results to true if the argument is a valid type).
If it's valid, then Range.empty never changes. If it never changes and
it's always false, then it's infinite.
-Steve


That's really ugly code :-(

Is there a way you could write an isStatic(expr) template? Using
something like that would make the
code a hell of a lot more readable. At the moment, the code itself
does a very poor job of conveying
what it's trying to accomplish.

These SFINAE-like tricks should be black-boxed as much as possible, or
(at the very least)
commented so that people know what's going on.


template isStatic( alias T ) {
enum isStatic = is( char[1+T] );
}

unittest {
int n = 3;
assert( !isStatic!n );
assert( isStatic!1 );
enum r = 5;
assert( isStatic!r );
}


enum s = Hello;

assert (isStatic!s);

Gonna need more work than that.


Re: Understanding isInfinite(Range)

2010-09-06 Thread Pelle

On 09/06/2010 08:53 PM, Philippe Sigaud wrote:

On Mon, Sep 6, 2010 at 18:47, Pelle pelle.mans...@gmail.com
mailto:pelle.mans...@gmail.com wrote:

On 09/04/2010 02:11 PM, Simen kjaeraas wrote:

Is there a way you could write an isStatic(expr) template? Using


template isStatic( alias T ) {
enum isStatic = is( char[1+T] );
}

unittest {
int n = 3;
assert( !isStatic!n );
assert( isStatic!1 );
enum r = 5;
assert( isStatic!r );
}


enum s = Hello;

assert (isStatic!s);

Gonna need more work than that.


Why? That's exactly the behavior we want, or so it seems to me.




Sorry if I was unclear, that assert fails. Due to that you cannot add an 
integer and a string, not not that the string isn't static. It's an 
enum, so it definitely is static.


Re: SO rotate question

2010-09-03 Thread Pelle

On 09/02/2010 10:24 PM, bearophile wrote:

simendsjo:

Suggestions for D-ifying the code is welcome.


Your unit tests are not good enough, they miss some important corner cases.
This my first version in D2:

import std.string: indexOf;

/// return True if s1 is a rotated version of s2
bool isRotated(T)(T[] s1, T[] s2) {
 return (s1.length + s2.length == 0) ||
(s1.length == s2.length  indexOf(s1 ~ s1, s2) != -1);
}

unittest { // of isRotated
 assert(isRotated(, ));
 assert(!isRotated(, x));
 assert(!isRotated(x, ));
 assert(isRotated(x, x));

 string s = rotato;
 assert(isRotated(s, rotato));
 assert(isRotated(s, otator));
 assert(isRotated(s, tatoro));
 assert(isRotated(s, atorot));
 assert(isRotated(s, torota));
 assert(isRotated(s, orotat));

 assert(!isRotated(s, rotator));
 assert(!isRotated(s, rotat));
 assert(!isRotated(s, rotata));
}

void main() {}

Bye,
bearophile


This is what I wrote:

bool isRotated(T)(T[] a, T[] b) {
return a.length == b.length  (a.length == 0 || 
canFind(chain(a,a), b));

}

Use chain to avoid allocation.

canFind isn't really the best possible name, is it?


Re: SO rotate question

2010-09-03 Thread Pelle

On 09/03/2010 01:35 PM, bearophile wrote:

Pelle:


bool isRotated(T)(T[] a, T[] b) {
  return a.length == b.length  (a.length == 0 ||
canFind(chain(a,a), b));
}


Nice clean solution. I suggest to add pure and two const in the signature.



canFind isn't really the best possible name, is it?


Some name/APIs of Phobos are not the best possible, they were often invented by 
a single person. I don't know if contains() or isIn() are better.

Bye,
bearophile


Heh, I actually tried that before posting, but chain doesn't seem to 
support const. :-)


Should probably be two forward ranges, not two arrays, as well.


Re: built-in string hash ?

2010-08-28 Thread Pelle

On 08/28/2010 10:25 PM, bearophile wrote:

torhu:

string a = abc;
auto hash = typeid(a).getHash(a);


If higher performance is necessary, you may pre-compute part of that:

void main() {
 string a = abc;
 auto hash1 = typeid(a).getHash(a);
 auto stringHash =(typeid(a).getHash);
 auto hash2 = stringHash(a);
 assert(hash1 == hash2);
}

Bye,
bearophile


I doubt that gives any performance gains. typeid(a).getHash should be a 
constant expression anyway, and I don't see any gains in my tiny 
benchmark test.


Perhaps it works better if a was an Object, since typeid for objects 
does more.


Re: associative array of associative arrays.

2010-08-13 Thread Pelle

On 08/13/2010 01:17 AM, dcoder wrote:

Hello.  How do you declare and initialize a map that looks like the following:

Name =  [ Personal Info]

Where personal info is type string[string].

I can't get this to compile.  I'm wondering what I am doing wrong:

import std.stdio;


void main() {
   int[string] helloworld = [ Hello:0, World:1 ];



   foreach( k,v;helloworld) {
 writefln( %s -  %s, k, v);
   }


   writefln( helloworld type: %s, typeid(helloworld));


   string[string] table = [ City:Boston, Title:Vice President ];

   foreach( k, v; table) {
 writefln( %s: %s, k, v);
   }

   // Here's the problem:
   string[string[string]] leaders = [ Obama:[City:DC, Title:ThePrez],
Cameron:[City:London, 
Title:DaPrimeMinista]];

   foreach( k, v; leaders) {
 writefln( first foreach type: %s, typeid(v));
 writefln( Person: %s, k);
 foreach( kk, vv; v) {
   writefln( \t%s\t%s, kk, vv);
 }
   }

   return;
}



Here's the output:


$ dmd AssocArray.d
AssocArray.d(25): Error: Integer constant expression expected instead of City
AssocArray.d(25): Error: Integer constant expression expected instead of Title
AssocArray.d(25): Error: Integer constant expression expected instead of City
AssocArray.d(25): Error: Integer constant expression expected instead of Title
AssocArray.d(24): Error: not an associative array initializer




$ dmd --help
Digital Mars D Compiler v2.047
Copyright (c) 1999-2010 by Digital Mars written by Walter Bright
Documentation: http://www.digitalmars.com/d/2.0/index.html




thanks

dcoder


This is probably a bug, I think I have run into it.

Try this:

string[string[string]] leaders;
leaders[Obama] = [City:DC, Title:ThePrez];
leaders[Cameron] =  [City:London, Title:DaPrimeMinista];

And if that doesn't work, try unfolding more :-)

Probably should report this as a bug, as well.


Re: Problem with std.array(std.regex.splitter())

2010-08-09 Thread Pelle

On 08/09/2010 12:50 AM, bearophile wrote:

This D2 code:

import std.regex: splitter, regex;
import std.array: array;
void main() {
 array(splitter(, abc, de, regex(, *)));
}


Gives the errors:

test.d(4): Error: template std.array.array(Range) if (isForwardRange!(Range)) 
does not match any function template declaration
test.d(4): Error: template std.array.array(Range) if (isForwardRange!(Range)) 
cannot deduce template function from argument types !()(Splitter!(string))

Do you know what's wrong in it?

Bye and thank you,
bearophile


std.array.array() erroneously requires a forward range, where it should 
require an input range.


Splitter also does not define save(), so it's not a forward range.


Re: std.file.read

2010-08-02 Thread Pelle

On 08/02/2010 10:23 AM, Dmitry Olshansky wrote:

On 02.08.2010 5:23, bearophile wrote:

Can you tell me why std.file.read() returns a void[] instead of
something like a ubyte[]?


Well, it magically converts to whatever array type you have. So this works:
ubyte[] data = read(trash.txt);


This code does not work for me.


It's interesting fact deserving further investigation. It seems that
void[] arrays are converted implicitly, this also works:
void[] tr = malloc(20)[0..20];
data = tr;


Neither does this.

I am running 2.047, am I doing something wrong?


Re: null dereference exception vs. segfault?

2010-08-02 Thread Pelle

On 08/02/2010 11:27 PM, bearophile wrote:

Ryan W Sims:

The problem isn't how to check it on a case-by-case basis, there are
plenty of ways to check that a given pointer is non-null. The problem is
debugging _unexpected_ null dereferences, for which a NPE or its
equivalent is very helpful, a segfault is _not_.


I don't know what NPE is, but if you program with DbC your nulls are very often 
found out by asserts, so you have assert errors (that show line number  file 
name) instead of segfaults.


Null Pointer Exception! However, I agree with getting segfaults from 
them. Otherwise, you will be tempted to use the exception handling 
mechanisms to catch null pointer exceptions, which is a bad thing.


I also agree with the notion of using DbC to find nulls.

What I really wish for is non-nullable types, though. Maybe in D3... :P


Re: null dereference exception vs. segfault?

2010-08-02 Thread Pelle

On 08/03/2010 12:02 AM, bearophile wrote:

Pelle:

What I really wish for is non-nullable types, though. Maybe in D3... :P


I think there is no enhancement request in Bugzilla about this, I will add one.


I think there has been, at least this has been discussed on the newsgroup.


To implement this you have to think about the partially uninitialized objects 
too, this is a paper about it, given a class type T it defines four types (I 
think the four types are managed by the compiler only, the programmer uses only 
two of them, nullable class references and nonnullable ones):
http://research.microsoft.com/pubs/67461/non-null.pdf

If a language defaults to nonnullable references, then you can use this syntax:

class T {}
T nonnullable_instance = new T;
T? nullable_instance;

But now it's probably nearly impossible to make D references nonnullable on 
default, so that syntax can't be used. And I don't what syntax to use yet. 
Suggestions welcome.

Bye,
bearophile


That is a good syntax indeed. What is also needed is a way of 
conditionally getting the reference out of the nullable.


I think delight uses something like this:

T? nullable;
if actual = nullable:
actual.dostuff;

I think a good thing would be NonNull!T, but I haven't managed to create 
one. If this structure exists and becomes good practice to use, maybe we 
can get the good syntax in D3. In 20 years or so :P


Re: null dereference exception vs. segfault?

2010-08-02 Thread Pelle

On 08/03/2010 12:32 AM, bearophile wrote:

Pelle:

I think a good thing would be NonNull!T, but I haven't managed to create
one. If this structure exists and becomes good practice to use, maybe we
can get the good syntax in D3. In 20 years or so :P


Maybe we are talking about two different things, I was talking about nonnull 
class references/pointers, you seem to talk about nullable values :-) Both can 
be useful in D, but they are different things.
Nullable values are simpler to design, they are just wrapper structs that 
contain a value plus a boolean, plus if you want some syntax sugar to manage 
them with a shorter syntax.

Bye,
bearophile


I am talking about non-nullable references indeed. I don't think I 
mentioned nullable types, really.


I also created this, as the simplest NotNull-type concievable:

struct NotNull(T) if(is(typeof(T.init !is null))) {
private T _instance;

this(T t) {
enforce(t !is null, Cannot create NotNull from null);
_instance = t;
}

T get() {
assert (_instance !is null,
text(Supposed NotNull!(, T.stringof, ) is null));
return _instance;
}
alias get this;
}


This has the obvious bug in that you can declare a nonnull without an 
initializer and get a null from it. If we ever get @disable this(){} for 
structs, this struct can become better.


I'll probably try it out in some code.


Re: null dereference exception vs. segfault?

2010-08-02 Thread Pelle

On 08/03/2010 01:08 AM, bearophile wrote:

Pelle:


struct NotNull(T) if(is(typeof(T.init !is null))) {


Is this enough?
struct NotNull(T) if (is(T.init is null)) {



  this(T t) {
  enforce(t !is null, Cannot create NotNull from null);


enforce() is bad, use Design by Contract instead (a precondition with an assert 
inside).

Bye,
bearophile


If NotNull will be in a library, it should probably use enforce, if I 
have understood things correctly. External input, and all that. I think 
most of phobos does it like this currently.


Re: D2 map trouble

2010-07-28 Thread Pelle

On 07/28/2010 12:57 AM, Nick Sabalausky wrote:

Trying to convert some D1 code to D2:

On 2.047, I'm trying to do this:

import std.string;
void foo(string str)
{
str =
   std.algorithm.map!(
(char a) { return inPattern(a, [digits, letters])? a : '_'; }
   )(str);
}

And I'm getting:

delegate std.algorithm.__dgliteral1 cannot access frame of function
__dgliteral1

What's going on? How do I do it right? I figure I probably have some sort of
problem with strings being immutable(char)[] instead of char[], but it
doesn't look like that's the issue it's complaining about. Also, in this
particular case, I'm not concerned about multi-unit UTF-8 characters.



This is a compiler bug. Easy workaround:

auto fn = (char a) { ... };
str = map!fn(str);


Re: Cannot initialize associative array.

2010-06-23 Thread Pelle

On 06/23/2010 09:41 AM, Ali Çehreli wrote:

Ali Çehreli wrote:

dcoder wrote:

 So, I moved the initialization to inside the main function, and now
it works.
 Great. I think we need to put this question in the FAQ.

For future reference, if it really needs to be global:

uint[string] mywords;

static this()
{
mywords = [ Hello : 1, World : 1, Cat : 1, Dog : 1 ];
}


Could someone please verify whether the above is really necessary? Is it
actually a dmd bug that we need to use 'static this()' to initialize an
associative array?

Ali


I say it's a bug, a literal like that should be a constant expression. 
Someone report it!


Re: opAddAssign still works

2010-05-11 Thread Pelle

On 05/11/2010 01:38 AM, Trass3r wrote:

Yeah it still works for compatibility reasons but is deprecated.


Not yet, it's not. To compile something that's deprecated, you will need 
the -d switch.


Right now, both are allowed, but the old one is scheduled for 
deprecation and presumably later removal. :)




Re: Fixed-size arrays on the heap

2010-05-06 Thread Pelle

On 05/06/2010 01:10 PM, bearophile wrote:

Lars T. Kyllingstad:

In particular, note Kasumi Hanazuki's post and Andrei's response to it.


Thank you, it seems Andrei agrees with me. But I think here thinks have to be 
kept tidy, otherwise it's easy to make a mess.

The syntax offers various interesting possibilities for a future International 
Obfuscated D Code Contest:

import std.stdio: writeln;
struct Arr(int N) {
 int[N] data;
 alias data this;
}
void main() {
 auto p = new Arr!(10);
 *p = 10;
 writeln(p.data); // Output: 10 10 10 10 10 10 10 10 10 10
}


This is not good :-(
Bye,
bearophile


Which is why they decided that the [] will always be needed for array 
operations. Right?


Re: Operators overloading in D2 again

2010-05-03 Thread Pelle

On 05/03/2010 04:28 PM, Dan wrote:

Hi,

it certainly helps. However I can't help myself, I still thinking that this is 
the most complicated, hard read and to understand way to
overload operators. Maybe there is something I'm missing but I can't really see 
the reason of all that. Other languages adopts a much
easier approach, for example python but also C++ that D is trying to surpass 
(and it does in most cases) when it comes to operator
overloading is much more clear than D.

I still thinking that the D1's approach was much better than this.


The D way is superior, because you don't need to come up with arbitrary 
names, like the D1/Python way, and it's much easier to parse than the 
C++-way, at least I think it is.




Anyway, now I have another problem: I can't get how to overload operators like 
these=,,=,.
I read the documentation but I can't really understand it.



http://digitalmars.com/d/2.0/operatoroverloading.html#compare

You should define an opCmp.


Thanks for the precious help guys.
   DAniele




Re: How to implement a copy

2010-03-19 Thread Pelle Månsson

On 03/18/2010 05:43 PM, Paul D. Anderson wrote:

If I'm implementing a struct and want to provide for duplication, is there a 
standard way to implement this?

Here's an example:

//---

struct S {

 // members of the struct -- three integer values
 int a;
 int b;
 int c;

 // here's a copy constructor
 this(S s) {
 this.a = s.a;
 this.b = s.b;
 this.c = s.c;
 }

 // here's the dup property
 S dup() {
 S s;
 result.a = this.a;
 result.b = this.b;
 result.c = this.c;
 return s;
 }

 // here's opAssign for S
 void opAssign(S s) {
 this.a = s.a;
 this.b = s.b;
 this.c = s.c;
 }


} // end struct S

// and here's a copy function
S copy(S s) {
 S t;
 t.a = s.a;
 t.b = s.b;
 t.c = s.c;
 return t;
}

//---

Which of these three calls is better (more efficient, more intuitive, more 
consistent...)?

S s;// the original struct

S t = s.dup; // copied via dup
S u = S(s);  // copied via copy constructor
S v = s;   // copied via opAssign
S w = copy(s);  // copied via copy function

Or is this a distinction without a difference?

Paul






this(this) is the copy constructor, I think.

Try using that :)


Re: Tidy attributes

2010-03-11 Thread Pelle Månsson

On 03/11/2010 10:20 PM, bearophile wrote:

While looking for possible attribute problems to add to Bugzilla, I have seen 
the following D2 program compiles and runs with no errors or warnings:


static foo1() {}


static does not apply to free functions, I would guess this means the 
same as auto.



final foo2() {}
ref foo3() {}
enum void foo5() {}


Wow.


nothrow foo4() {}
pure foo6() {}


Would guess for auto here. Not tidy, as you say :)


static int x1 = 10;
static x2 = 10;


static here means 'known at compile time', I think.


- What is a static global function in D?


It means nothing, but I can't seem to find the documentation. It's just 
ignored.



- A final global function?
- Is that ref of void correct? (I think it is not)
- A enum of void function?


These are mysteries.


- What are global static variables in D?


variables evaluated at compile time, for example

int cfte_able_function() {
return 14423 + 12341;
}

int other_function() {
writeln(Not cfte);
return 7;
}

static x1 = 123; //works
static x2 = cfte_able_function; //works;
static x3 = other_function; //cannot evaluate other_function() at 
compile time


As you say, these are odd issues indeed. :)


Re: Tidy attributes

2010-03-11 Thread Pelle Månsson

On 03/11/2010 10:44 PM, bearophile wrote:

As far as I know, it's enum that has that purpose.


Oh, but they are not the same. enum declares a constant, whereas static 
declares a variable. A static global is still mutable.



Thank you for your answers,
bearophile


Why thank you!


Re: Static attributes aren' immutable

2010-03-05 Thread Pelle Månsson

On 03/05/2010 07:50 PM, bearophile wrote:

div0:

putting it in Foo simply puts it in a namespace.


So my (wrong) idea of immutable applied to a struct was that every thing in 
such namespace becomes immutable (I think this is a bit more intuitive).

What do you think of modifying D2 so in a situation like the one I've shown 
even static arguments become const/immutable? Can this cause troubles to other 
things?

Thank you to you and Lars T. Kyllingstad for the answers.

Bye,
bearophile


Immutability (somewhat) guarantees the value will never ever change. The 
static attribute could be changed by a non-immutable instance, and can 
therefore not be immutable. It could be const for the immutable 
instance, but I don't see the gains from it.


I do, however, see the gains from not being able to access the static 
members through an instance.


Re: raii

2010-02-28 Thread Pelle Månsson

On 02/28/2010 09:16 PM, Ellery Newcomer wrote:

Hello

The impetus:


I agree, except I more and more think that scope classes were a
mistake. Structs with destructors are a much better solution, and
wrapping a class inside a struct would give it RAII semantics.


The problem:

In designing a library (or rather touching up someone else's library), I
have a class (interface?) Foo, and it has a method close (actually
several methods). Almost invariably (although conceivably not always),
usage involves manipulating Foo, and then remembering to call close.
That last part is obnoxious.

One obtains a Foo from function foo.

What I'd like is for the result of foo to have RAII semantics by
default, with the possibility of nixing it if the user actually cares.

I want to take the burden of remembering that stupid close off the user.

For example:

void bar(){
auto a = foo();
a.doStuff();
}

has an implicit call to close after doStuff.

The impetus suggests I can do this by wrapping Foo inside a struct, but
I'm not so sure how well this would work out. Also note that close can
fail in a number of ways relating to file io.

So I wrote up a simple prototype.

Thoughts?




import std.stdio;
class Foo{
int k;
this(int i){
writefln(bin %d,k);
k = i;
}
void doStuff(){
writefln(do stuff %d,k);
}
void close(){
writefln(close %d,k);
}
}
struct RAII(T){
T b;
bool extracted = false;
alias b this;
this (T i){
assert(i !is null);
writeln(in);
b = i;
}
~this(){
writeln(~this);
if(!extracted) b.close();
}
T extract(){
assert(!extracted);
T t = b;
b = null;
extracted = true;
return t;
}
}
RAII!(Foo) foo(int i){
return RAII!(Foo)(new Foo(i));
}
void main(){
auto a = foo(1);
auto b = foo(2).extract();
a.doStuff();
b.doStuff();
}




Maybe something along the lines of this

struct RAII(T : Object){
T b;
alias b this;

void delegate(T) destroyer;

this (T i, void delegate(T) called_at_exit){
b = i;
destroyer = called_at_exit;
}
~this(){
if (b) destroyer(b);
}
T extract(){
T t = b;
b = null;
return t;
}
}

class Foo {
this() { }
void close() {
writeln(closed.);
}
}

RAII!Foo foo() {
return RAII!Foo(new Foo, (Foo f) {f.close;});
}

for a slightly more generalized RAII struct, which works on classes only.


Re: running an external .exe

2010-02-17 Thread Pelle Månsson

On 02/16/2010 08:09 PM, Funog wrote:

Is it possible to run an external .exe and have access to its standard 
input/output? Apparently std.process does not allow this.





You'll want to choose either the input or the output stream, otherwise 
you might get eaten by a deadlock.


Re: Why isn't == used to compare structs

2010-02-08 Thread Pelle Månsson

On 02/08/2010 01:48 PM, Trass3r wrote:

Why isn't == used to compare the struct members in the code above? I
mean, if I compare the structs with == it could also use == to compare
the members. If I use is to compare the structs it could use is to
compare them members.


Structs are compared *bitwise*!
When you dup your pointer is different and thus the structs are different.


I believe the question was *why* things are this way. I think it's weird.


Re: default opAssign(string) behaviour

2010-01-28 Thread Pelle Månsson

On 01/28/2010 02:32 AM, strtr wrote:

Personally, I use (D1)std2.conv a lot to get values from strings and thus would 
love the following default behaviour for all types:

int i = 0; // i = 0
i = cast( int ) 0; // i = 48 ( If I read the utf8 table correctly )

What keeps this from being the case?


Strong typing, mostly. It's messy.

to!int(0) is seriously pretty, though. :)


Re: boolean over multiple variables

2010-01-26 Thread Pelle Månsson

On 01/26/2010 01:02 AM, Nick Sabalausky wrote:

strtrst...@spam.com  wrote in message
news:hjd6t1$be...@digitalmars.com...

This may be is a very basic question, but is there a way to let me omit a
repeating variable when doing multiple boolean operations?

if ( var == a || var == b || var == c || var == d)
if ( var == (a || b || c || d) )


I do this:

-
import tango.core.Array;

void main()
{
 if( [3, 5, 6, 12].contains(7) )
 {
 }
}
-

There's probably a phobos equivilent, too.

Alhough, I would much prefer what other people mentioned about having in
refer to the values of a collection rather than the keys. But I've been
using the above as a substitute.


I think in should work for keys in an associative array and for values 
in a regular array.


This is how it works in python.


Re: boolean over multiple variables

2010-01-25 Thread Pelle Månsson

On 01/23/2010 12:29 AM, strtr wrote:

Simen kjaeraas Wrote:



Not tested, but they should work:

if ( anySame( var, a, b, c, d ) ) {
}

if ( allSame( var, a, b, c, d ) ) {
}



A lot prettier.
I thought there would be a generic (basic) solution to this which I just didn't 
know about but maybe I actually do know the basics by now :)

--
Simen



If we get opIn_r for arrays, you can do

if (var in [a, b, c, d]) {
}

Which I find a lot prettier.


Timer library?

2010-01-25 Thread Pelle Månsson
I'm in need for a timer library that measures the acutal time. I have 
tried std.c.time's clock(), but it only measures time spent inside the 
program, not actual time elapsed.


I need at least millisecond resolution, so std.c.time.time() is not an 
option.


I wonder, is there a good library for this?


Re: Timer library?

2010-01-25 Thread Pelle Månsson

On 01/25/2010 04:02 PM, strtr wrote:

Stanislav Blinov Wrote:


Pelle M�nsson wrote:

I'm in need for a timer library that measures the acutal time. I have
tried std.c.time's clock(), but it only measures time spent inside the
program, not actual time elapsed.

I need at least millisecond resolution, so std.c.time.time() is not an
option.

I wonder, is there a good library for this?


Have you tried std.date? :-)


and there is of course the undocumented std.perf.


It seems std.perf is indeed suitable. Thank you!