Re: Json

2017-11-19 Thread Mafi via Digitalmars-d-learn

On Saturday, 18 November 2017 at 14:25:58 UTC, kerdemdemir wrote:
I am using vibe.d's json(http://vibed.org/api/vibe.data.json/) 
module without a problem and really happy with it. There are 
also some 
examples(https://github.com/vibe-d/vibe.d/tree/master/examples/json). If you are using "dub" package manager it is also very easy to integrate vibe.d.


Well, this would pull the whole vibe.d into the executable, 
wouldn't it? I'll stick with stdx.data.json for now, which I have 
tried and it does work in my case. But I'll minimize the actual 
json-interaction code so I can switch out the lib at any time.


Thank you all! It's rather unfortunate that the (std lib) json 
situation is still not sorted out!


Json

2017-11-17 Thread Mafi via Digitalmars-d-learn
What is the current best practice for parsing JSON in D? What 
library (on code.dlang.org) should I use?


I do not want to (de-)serialize structs. Instead I want a simple 
DOM-API.


Thank you very much :)


Re: Output-Range and char

2017-04-23 Thread Mafi via Digitalmars-d-learn

On Sunday, 23 April 2017 at 12:03:58 UTC, Ali Çehreli wrote:

On 04/23/2017 04:17 AM, Mafi wrote:

/opt/compilers/dmd2/include/std/range/primitives.d(351): 
Error: static

assert  "Cannot put a char into a char[]."


Appender recommended:

import std.format, std.stdio, std.array;

void main() {
auto sink = appender!(char[])();
formattedWrite(sink, "Long string %s\n", "more more more");
write(sink.data);
}

Of course appender!string is more natural but I just wanted to 
see that it works with char[] as well.


Ali


Thank you. I see. But I would really like not to allocate ever. 
Instead I want to fill a given buffer, then stop formatting.


I probably have to implement my own output-range for this use 
case. It would fill the buffer and then ignore further 
'put'-calls. I can live with this.


I do have a follow-up question though. Why does formattedWrite 
take the output-range by value? It just doesn't make sense for 
value-type output-ranges; especially with consecutive calls. One 
has to pass the pointer of the output-range (this does work 
because of auto-dereferencing). Forgetting it one place, lets the 
code still compile, with very strange semantics which most 
probably were not intended.


Output-Range and char

2017-04-23 Thread Mafi via Digitalmars-d-learn

Hi there,
every time I want to use output-ranges again they seem to be 
broken in a different way (e.g. value/reference semantics). This 
time it is char types and encoding.


How do I make formattedWrite work with a char buffer? I tried the 
following code and it fails with a *static assert*; it is 
itentionally disabled. I suspects it is again something about 
autodecoding but in this case I don't understand it.


https://dpaste.dzfl.pl/c68b3e3529f6

```
import std.format, std.stdio;

void main() {
char[20] buffer;
formattedWrite(buffer[], "Long string %s\n", "more more more");
write(buffer);
}
```

Compilation output:

/opt/compilers/dmd2/include/std/range/primitives.d(351): Error: 
static assert  "Cannot put a char into a char[]."
/opt/compilers/dmd2/include/std/format.d(2647):
instantiated from here: put!(char[], char)
/opt/compilers/dmd2/include/std/format.d(2297):
instantiated from here: formatRange!(char[], string, char)
/opt/compilers/dmd2/include/std/format.d(3778):
instantiated from here: formatValue!(char[], string, char)
/opt/compilers/dmd2/include/std/format.d(460):
instantiated from here: formatGeneric!(char[], string, char)
/d446/f470.d(5):instantiated from here: 
formattedWrite!(char[], char, string)




Re: Unexpected behavior when casting away immutable

2015-09-23 Thread Mafi via Digitalmars-d-learn
On Wednesday, 23 September 2015 at 05:24:05 UTC, John Colvin 
wrote:
On Wednesday, 23 September 2015 at 03:39:02 UTC, Mike Parker 
wrote:

...


```
immutable int x = 10;
int* px = cast(int*)
*px = 9;
writeln(x);
```

It prints 10, where I expected 9. This is on Windows. I'm 
curious if anyone knows why it happens.


violating immutable is undefined behaviour, so the compiler is 
technically speaking free to assume it never happens. At the 
very least, neither snippet's result is guaranteed to show a 
change or not. At the most, literally anything can happen.


In essence, this code snippet is even better than the OP expected 
in showing why you shouldn't cast away immutable.


Re: Unresolvable references to dlopen, dlclose etc

2013-12-07 Thread Mafi

On Friday, 6 December 2013 at 16:54:14 UTC, Jacob Carlborg wrote:

On 2013-12-06 14:25, Mafi wrote:

Thank you! This has helped and I linked my program. As it 
turned out dmd

invoked gcc to link and it supplied my -ldl argument first! I
copy-pasted that command into a shell and moved the -ldl to 
the very end

and it worked.

How do instruct dmd to do the same? As far as I understand the 
problem
is that I specified the full path to the Derelict lib files by 
hand for
each lib instead of using -L and -l. Libraries specifed like 
that are
put after the gilen linker flags and before the buitlin ones 
(-lphobos
etc). Is this a bug or is there any reason for dmd's behavior? 
It seems

very wrong to me.


I would say that linking order shouldn't matter. But for some 
reason it does. This not really my area of expertise but I know 
that others have had the same problem. You can try and search 
the newsgroups for linking order related problems.


So after some tweaking I made it work. Specfying the libpath with 
-L-L and the actual -L-l invokes gcc correctly. But the other 
behavior is still odd for me. I mean invoking dmd with


dmd myprog.d /path/to/libSomething.a -L[Linkerflags]

links with

gcc myprog.o [Linkerflags] /path/to/libSomething.a [Phobos]

you must

dmd myprog.d -L-L/path/to/ -l-lSomething

and hope the file name has the format libName.a .

But why? Both are objects. Why seperate them? For me there is no 
reason to ever want this order!


Re: Unresolvable references to dlopen, dlclose etc

2013-12-06 Thread Mafi

On Thursday, 5 December 2013 at 19:20:16 UTC, Mafi wrote:
I am on fresh install of Linux Mint 16 64bit and I tried to 
compile some D code I have writen and I have problems (Hello 
World works btw). I uses Derelict (v2) and I have successfully 
compiled/linked/rurn my program on Windows 7 64bit. But on 
Linux I get errors about unresolved references to dlopen, 
dlclose etc. although I am linking against libdl (ld finds the 
so; I checked the verbose output).


Interestingly libdl.so is empty by nm. I found the symbols in 
libc.


I am compiling everything from scratch with the newest dmd 
(2.064.2 that is) with -m64 in my dmd.conf (doesn't work 
without either). I have posted on the Derelict forums 
(http://dblog.aldacron.net/forum/index.php?topic=864.0) but I 
don't think it is a Derelict specific problem. Pleas help me!


Could at least somebody approve they have read it? Maybe I did 
the installation wrong. I don't the slightest idea what to do. I 
am already trying for days.


Re: Unresolvable references to dlopen, dlclose etc

2013-12-06 Thread Mafi
You can compile with the verbose flag, -v, to make sure it 
links as you expect it to. The linking command will be at the 
bottom of the output.


Thank you! This has helped and I linked my program. As it turned 
out dmd invoked gcc to link and it supplied my -ldl argument 
first! I copy-pasted that command into a shell and moved the -ldl 
to the very end and it worked.


How do instruct dmd to do the same? As far as I understand the 
problem is that I specified the full path to the Derelict lib 
files by hand for each lib instead of using -L and -l. Libraries 
specifed like that are put after the gilen linker flags and 
before the buitlin ones (-lphobos etc). Is this a bug or is there 
any reason for dmd's behavior? It seems very wrong to me.




Unresolvable references to dlopen, dlclose etc

2013-12-05 Thread Mafi
I am on fresh install of Linux Mint 16 64bit and I tried to 
compile some D code I have writen and I have problems (Hello 
World works btw). I uses Derelict (v2) and I have successfully 
compiled/linked/rurn my program on Windows 7 64bit. But on Linux 
I get errors about unresolved references to dlopen, dlclose etc. 
although I am linking against libdl (ld finds the so; I checked 
the verbose output).


Interestingly libdl.so is empty by nm. I found the symbols in 
libc.


I am compiling everything from scratch with the newest dmd 
(2.064.2 that is) with -m64 in my dmd.conf (doesn't work without 
either). I have posted on the Derelict forums 
(http://dblog.aldacron.net/forum/index.php?topic=864.0) but I 
don't think it is a Derelict specific problem. Pleas help me!


Re: ~= call copy ctor?

2012-07-22 Thread Mafi
On the other hand, calling the destructor is still acceptable 
in D because it may be important for the programmer to run the 
contents earlier than GC would. clear() does that:


auto t = new Test(f3);
// ...
clear(t);// -- Run the destructor

Unfortunately it has a bad name, which is going to be changed.

Ali


Really? I thought we have to stay with this name now. In my
opinion this name is quite bad, especially in the presence of
UFCS. What is going to be changed to? destroy()?

Mafi




Re: primitive type operator overload

2012-04-20 Thread Mafi

Am 20.04.2012 18:41, schrieb bearophile:

Dominic Jones:


I want to overload a primitive type operator so that I can do
something like

double a;
myStruct b;
writeln(a + b);


You can't overload the operator of a primitive, but binary operators
come in left and right versions:

...


Bye,
bearophile


Shouldn't a consequence of UFCS be that you can overload binary 
operators for primitives, as should global overloads (like in C++).


Re: Conversion to output ranges

2012-02-08 Thread Mafi

Am 07.02.2012 16:50, schrieb Timon Gehr:

On 02/07/2012 04:49 PM, Timon Gehr wrote:

On 02/07/2012 02:35 PM, Mafi wrote:

Hi,
does anybody know how to bring std.conv.to or something similar to
output into an output range?

int a = 42;
char[25] buffer;
to!typeof(buffer[])(a, buffer[]);

I want to send these texts throw sockets. Therefore I'd like to reuse
the buffer.

Mafi


You could use std.format.formattedWrite.

import std.exception, std.format, std.stdio;

// I don't know if this already exists somewhere:
struct Filler(T:T[]){
this(T[] pl){payload = pl;}
size_t index=0;
T[] payload;
void put(const T[] s){
enforce(payload.length=index+s.length);
payload[index..index+s.length]=s;
index+=s.length;
}
void put(char s){


Should be 'void put(T s)'.


enforce(payload.length=index);
payload[index++]=s;
}
@property auto data(){return payload[0..index];}
}
auto filler(T)(T pl){return Filler!T(pl);}

void main(){
int a = 42;
char[25] buffer;
auto f = filler(buffer[]);
formattedWrite(f,%s,a);
writeln(f.data);
}




Thanks :) This solution seems to work.
I just wanted to point out that I forgot the ampersand and this was hard 
to track down. I seemed to work but index wasn't incremented so I always 
got an empty slice.


Mafi


Conversion to output ranges

2012-02-07 Thread Mafi

Hi,
does anybody know how to bring std.conv.to or something similar to 
output into an output range?


int a = 42;
char[25] buffer;
to!typeof(buffer[])(a, buffer[]);

I want to send these texts throw sockets. Therefore I'd like to reuse 
the buffer.


Mafi


Hole of new? (Re: Array of array)

2012-01-02 Thread Mafi

Am 02.01.2012 23:33, schrieb Timon Gehr:

On 01/02/2012 11:21 PM, RenatoL wrote:

Just curious... the answer of the compiler it's a bit unclear to
me...

T[] is a dynamic array of type T.
T[][] is a dynamic array of T[]. But this doesn't work. Why?


It does work. Why do you think it does not?

T[] a; // ok
T[][] b; // ok
auto c = new T[5]; // ok
auto d = new T[][5]; // ok
auto e = new T[]; // fail, nonsensical
auto f = new T[][]; // fail, nonsensical



Here we come to an interesting point I often thought of. How do you 
allocate a T[] itself (so you get a T[]*) or a ClassType reference (so 
you get a ClassType*) on the heap (without casting)?

As far as I know it's not possible with new.
new T[n] is of type T[].
new T[]* is of type T[]**.
new ClassType is of type ClassType.
new ClassType* is of type ClassType**.

Is this a Hole of new?

Mafi


Re: Reading about D: few questions

2011-12-23 Thread Mafi

Am 23.12.2011 16:25, schrieb Mr. Anonymous:

Hi guys!

I'm mostly familiar with C (and a bit of PHP). I've stumbled upon the D
language, and I must say I really like it.
Now I'm reading the The D Programming Language book, and I have a
couple of questions:


[]


3. const and immutable.

Is there any use for const when defining variables?
As I see it, there is no use for using e.g. const int x;, as it can't be
modified anyway;
So with immutable, const is only good for reference variables that are
initialized to refer to another variable (like a function const ref
parameter).
Am I right?
Right. There's no point in a const int but of course there is a big 
difference between const(int)* and immutable(int)*.





4. if (lhs != rhs)?

std.algorithm has this in it's swap function.
Is it different than if (lhs !is rhs)?
Just wondering.

They're not the same at all. is checks if the two operands have binary 
equality.
To understand, you have to keep in mind that lhs and rhs are references 
and could refer to one and the same variable as in:

int a = 0; swap(a, a);
Now, if you want to know if two refs refer to the same variable, you
use lhs == rhs. If want to know if two class instances are the same, 
you use is. If you want to know if two things (instances or anything 
else) are equal, you use ==.

lhs == rhs (makes only sense with refs)
rhs is lhs (always true, if the above is true)
rhs == lhs (always true, if the above is true)

import std.stdio;
void f(ref int[] a, ref int[] b) {
  writefln(%s %s %s, a == b, a is b, a == b);
}

void main() {
  auto u = [1, 2, 3];
  auto u2 = u;
  auto v = [1, 2, 3];
  auto w = [4, 5, 6];
  f(u, u); // true true true
  f(u, u2);// false true true
  f(u, v); // false false true
  f(u, w); // false false false
}   

 [...]

Mafi



Re: ref struct?

2011-10-11 Thread Mafi

Am 09.10.2011 19:52, schrieb bearophile:

(I show this here because it's probably a silly idea, but it may a chance to 
learn something.)
Do you like the idea of a POD that is always managed by reference, as class 
instances?


ref struct Foo {}
static assert(Foo.sizeof == 1);
void main() {
 Foo f1; // void reference
 Foo f2 = new Foo; // by reference
}


It is as light as a struct, but you don't need to use the pointer syntax to 
manage a Foo instance, the code is cleaner. There is no info field inside a ref 
struct, so in some situations the destructor doesn't get called, like regular 
structs.

Bye,
bearophile


What about:

struct FooData {...}
alias FooData* Foo;

//dot syntax etc works like you want
//only problem: (new FooData) instead of (new Foo)


Re: Why no (auto foo = bar) in while loops?

2011-08-24 Thread Mafi

Am 24.08.2011 21:04, schrieb Timon Gehr:

On 08/24/2011 08:04 PM, Andrej Mitrovic wrote:

Here's some code that iterates through parents of some class object
until it finds an object with no parent (where parent is null):

import std.stdio;

class Foo
{
Foo parent;
int state;

this (int state) { this.state = state; }
}

void main()
{
auto foo = new Foo(0);
foo.parent = new Foo(1);
foo.parent.parent = new Foo(2);

while (true)
{
if (auto par = foo.parent)
{
writeln(par.state);
foo = par;
}
else
{
break;
}
}
}

(syntax-highlighted: http://codepad.org/8yHRmICh)

But I was hoping I could simplify this by doing:

while (auto par = foo.parent)
{
writeln(par.state);
foo = par;
}

However that doesn't work, I get back:
expression expected, not 'auto'

Is there a limitation on why this couldn't work or can this be added
to the language?


Afaics, this could be added just like it could be added for if. In fact
the compiler should be able to simply rewrite it to your first example.
I think it is worth an enhancement request, because there are situations
where this would be useful, and implementation should be trivial, if
somebody has the time. (I also think it adds to the consistency of the
language, but others may disagree.)


(btw, i always use for(;;) instead of while(true), it is usually faster
in debug mode and faster to type :))


I just have to say that it already works for 'if'. It's a great feature 
because in the body of the 'if' you know the value is non-null and 
outside,  where there could be an segfault, the variable is not visible.

I'm not really sure if it's good for 'while'.
I'm unsure because there are two somewhat natural semantics for such a 
construct.


//example
//more to the nature of while
while(auto obj = init) { work(obj); }

//1 (your interpretation)
typeof(init) obj;
while(obj = init) { work(obj); }

//2
/*
seems more natural for me because init runs only once (like any other 
init and like in 'for' or 'if')

*/
auto obj = init;
while(obj) { work(obj); }

This could confuse many people, I think. What do you think?

Mafi



Re: byte* and int length - byte[]

2011-08-15 Thread Mafi

Am 15.08.2011 19:16, schrieb mimocrocodil:

I obtain immutable(byte)* and int where contained length of bytes block from C 
library.

Can I convert this into byte[] without explict copying etc.

Something like:

byte* p; // bytes
int size; // size of bytes block

byte[] b;
b.length = size;
b.ptr = p;

// now b contains bytes from library


Pointers support indexing (like C) but additionally also slicing so if 
you have a byte* b and a int/long/size_t (or similiar) len then

b[0.. len]
is a slice starting b conatining len elements of type typeof(*b)[].


Re: Very strange linker error

2011-07-26 Thread Mafi

Am 23.07.2011 17:10, schrieb Mafi:

I'm trying to rebuild my projects with new dmd and after fixing some
minor issues in my code I get the following:

Warning: As of Phobos 2.054, std.file.listDir has been scheduled for
deprecation in August 2011. Please use std.file.dirEntries instead.

OPTLINK (R) for Win32 Release 8.00.12
Copyright (C) Digital Mars 1989-2010 All rights reserved.
http://www.digitalmars.com/ctg/optlink.html
obj\main.obj(main) Offset 35B56H Record Type 00C3
Error 1: Previous Definition Different : _D5mysdl5input8Joystick6__ctorM
--- errorlevel 1

So I went to http://www.digitalmars.com/d/2.0/abi.html (which I by the
wy couldn't find on d-p-l.org) and it seems to be an incorrect mangling
because there's no 'type' after M but maybe it's a special case for the
constructor.

So looked for mysdl.input.Joystick.this(...). The struct (!) Joystick in
input.d has two constructors:

public this(SDL_Joystick* somePtr) {
this.joyptr = somePtr;
}

public this(int index)
in {
assert(index = 0);
assert(index  Joystick.getCount());
} body {
this(SDL_JoystickOpen(index));
}

No overlaping. So I went dumping all my object files and I found that
dmd generated this strange sambol in input.obj twice. So it's not
optlink's fault but dmd's!

I'd really like to solve this problem because otherwise this would be
second release in a row that I can't use.
The worst thing is I don't even now any ugly workaround. :(

Mafi


I commented out the first contructor and inlined it into the other: no 
linker errors.
But it used to compile with two constructors. If it's ok that it does 
not compile, the compiler should catch it and not the linker IMO.


Is it a bug in the compiler??

Mafi


Very strange linker error

2011-07-23 Thread Mafi
I'm trying to rebuild my projects with new dmd and after fixing some 
minor issues in my code I get the following:


Warning: As of Phobos 2.054, std.file.listDir has been scheduled for 
deprecation in August 2011. Please use std.file.dirEntries instead.


OPTLINK (R) for Win32  Release 8.00.12
Copyright (C) Digital Mars 1989-2010  All rights reserved.
http://www.digitalmars.com/ctg/optlink.html
obj\main.obj(main)  Offset 35B56H Record Type 00C3
 Error 1: Previous Definition Different : _D5mysdl5input8Joystick6__ctorM
--- errorlevel 1

So I went to http://www.digitalmars.com/d/2.0/abi.html (which I by the 
wy couldn't find on d-p-l.org) and it seems to be an incorrect mangling 
because there's no 'type' after M but maybe it's a special case for the 
constructor.


So looked for mysdl.input.Joystick.this(...). The struct (!) Joystick in 
input.d has two constructors:


public this(SDL_Joystick* somePtr) {
this.joyptr = somePtr;
}

public this(int index)
in {
assert(index = 0);
assert(index  Joystick.getCount());
} body {
this(SDL_JoystickOpen(index));
}

No overlaping. So I went dumping all my object files and I found that 
dmd generated this strange sambol in input.obj twice. So it's not 
optlink's fault but dmd's!


I'd really like to solve this problem because otherwise this would be 
second release in a row that I can't use.

The worst thing is I don't even now any ugly workaround. :(

Mafi


Re: Infer purity of functions too?

2011-07-21 Thread Mafi

Am 21.07.2011 02:01, schrieb bearophile:

Jonathan M Davis:


I believe that there is some level of purity inference with delegates, but I
don't know what the situation with that is exactly.


I didn't know/remember this, but it seems you are right, delegates too seem to 
receive purity inference. This has one downside too, this innocent-looking 
program doesn't compile:


import std.math;
void main() {
 auto funcs = [(int x){return x; },
   (int x){return abs(x); }];
}


The error, DMD 2.054:

test.d(4): Error: incompatible types for ((__dgliteral1) ? (__dgliteral2)): 
'int delegate(int x) pure nothrow' and 'int delegate(int x) nothrow'

How to solve this specific problem: I think abs() can be pure.

An example of a bit more general class of problems:

import std.math;
void main() {
 auto funcs = [sin,tan];
}


test.d(3): Error: incompatible types for ((  sin) ? (  tan)): 'real 
function(real x) pure nothrow @safe' and 'real function(real x) pure nothrow @trusted'

To solve this more generic class of problems the compiler has to give to the 
funcs array a common type (where possible), here int delegate(int x) pure 
nothrow[] is able to contain both kinds of delegates, and cast all the array 
delegates to the common type (I have a bug report about this in Bugzilla).

Bye,
bearophile


I would say the common type is int delegate(int) pure nothrow @trustd .


switch generation

2011-07-16 Thread Mafi

This code worked in dmd 2.052:

///
ubyte[] getIncludedFileImpl(FS...)(string file) {
switch(file) {
foreach(F; FS) { //ct foreach
//forever in love with you D
case F: return cast(ubyte[]) import(F);
}
default: throw new Exception(format(A needed included file not 
found %s, file));

}
assert(0);
}
///

It does not work anymore. I know about switch changes but the following 
doesn't work either:


///
ubyte[] getIncludedFileImpl(FS...)(string file) {
switch(file) {
foreach(F; FS) { //ct foreach
//forever in love with you D
case F: return cast(ubyte[]) import(F);
break; // --- here
}
default: throw new Exception(format(A needed included file not 
found %s, file));

}
assert(0);
}


How can I fix this code?

Mafi

PS: I know I can be done with some ugly string mixins but I want it to 
work somewhat like it worked before.


Re: Runtime evaluation

2011-07-08 Thread Mafi

Am 07.07.2011 23:23, schrieb nrgyzer:

Hi guys,

I'm trying to read a string from a text file which contains a value of an 
enumeration like:

enum MyEnum : string {
Entry_1 = abc,
Entry_2 = def,
Entry_3 = ghi,
}

Stream s = new File(myFile.ext, FileMode.In);
uint len;
s.read(len);
string entry = cast(string) s.readString(len);
s.close();

writeln(mixin(MyEnum. ~ entry));

myFile.ext may contain:
...
Entry_2
Entry_1
Entry_2
Entry_3
...

But mixin's are for compile time only... is there any chance to do this or do 
I've to use another method (like if/else or switch/case):

if (entry == Entry_1) ...
else if (entry == Entry_2) ...
...

Thanks a lot!


Metaprogramming is the keyword but you don't have to do it yourself. 
Just use std.conv.to!MyEnum(string_without_the prefix).


Mafi


Re: Undefined function, even though imported

2011-06-13 Thread Mafi

Am 13.06.2011 23:18, schrieb Loopback:

Hi!

Let me begin by saying, I'm sorry if this is caused of some obvious
error but since I am new to D, I am not aware of all the tricks and
treats it offers.

I am working with the WindowsAPI binding at dsource.org (though I do not
believe this is related to the binding itself). However, in my code I
call the function LOWORD (win32 specific). This function is defined in
the win32.windef module. Although it is defined there (without any
encapsulations in version statements or anything similar) I receive this
error:

Error 42: Symbol Undefined _D5win326windef6LOWORDFkZt (LOWORD undefined)

To solve this I had to copy-paste the exact function directly into my
own file/module instead. So my question is the following; why do I have
to copy and paste the function directly in my code when it is clearly
defined in one of the files I import?

Windef.d attached


Your error is an linker error.  This means the last step of creating an 
exceutable couldn't be taken: finding all names you promised to be there.
When you, import a module, you promise: Compiler, I know that 
definitions I'm using in this module aren't declared in there, but look 
at this module. I promise that all these functions in there will be 
there during the linking process. The compiler gives no error because 
you promised, but now the linker has problem: It hasn't got the 
defintions you said to be there. You have to say the linker where to 
find them.

One way is to give your .d/.lib file to dmd so he can give it to the linker:
dmd main.d path/to/windef.d

Mafi


Re: Problem with associative arrays

2011-03-19 Thread Mafi

Am 19.03.2011 17:29, schrieb Piotr Szturmaj:

Shouldn't dynamic array be reference type?

uint[][uint] aa;
uint[] temp;

aa[5] = new uint[0];
temp = aa[5]; // copy uint[] reference
temp ~= 1;

assert(temp.length == 1  temp[0] == 1); // pass
assert(aa[5].length == 1  aa[5][0] == 1); // fail

Is this a bug?


They are not 'perfect' references. There are pointer+length to/of memory.
If you just pass around these refences they reference the same memory. 
If you change the reference in some way (eg appending, concating etc) 
the memory could be reallocated.


int[] a, b;
a = [3,4,5];
b = a;
assert(a == b);
assert(a is b); //test for refence equality
//a and b now reference exactly the same memory
//concatening is guaranteed to reallocate
a = a ~ [6, 7];
assert(a == [3, 4, 5, 6, 7]);
assert(b == [3, 4, 5]);
// BUT these 3,4,5 are in different places in memeory
b[0] = 42;
assert(a == [3, 4, 5, 6, 7]);
// when slicing you know reference a subpart of the other array
b = a[0.. 3];
assert(b == [3, 4, 5]);
// changes of b will now be visible in a
// until a or b get reallocated
b[0] = 42;
assert(a == [42, 4, 5, 6, 7]);
assert(b == [42, 4, 5]);

Just one note: appending (ar ~= 1) differs from concating (ar = ar ~ 1) 
that while the second is guanranteed to reallocate, about the first you 
can't be sure. It depends on the GC.


Re: Semi-const methods?

2011-03-14 Thread Mafi

Am 13.03.2011 23:27, schrieb Magnus Lie Hetland:

I have a data structure that's generally static (const, or even
immutable), but it has some utility storage, which caches certain
results during use. This caching etc. doesn't really affect the
semantics of the main object, and are reset between operations, so I
think it still would be useful to declare (and statically check) that
certain methods don't modify any of the *rest* of the structure (i.e.,
the main parts).

I *could* declare the methods const, and pass in a second object (a
non-const parameter) for the caching etc. Or I cast the relevant parts
to const (assigning them to local variables) early on in the relevant
methods (dropping the const modifier on the method itself -- sort of a
bummer).

Any other ideas on how to handle this sort of mostly const or const
where it counts stuff? Perhaps my design intentions here are off to
begin with?-)



I found away which doesn't use casts or bugs.
Just use delegates/closures.

class C {
int i;
int delegate(int) getCache;

this(int fi) {
this.i = fi;
int lastX, lastR;
this.getCache = (int x) {
if(x == lastX) return lastR;
lastX = x;
lastR = x * i;
return lastR;
};
}

const multiply(int x) {
return getCache(x);
}
}


Re: Overriding in operator

2011-03-04 Thread Mafi

Am 04.03.2011 17:01, schrieb Magnus Lie Hetland:

I'm writing a collection with functionality for membership checking. I
thought it would be nice to use the in operator. In the docs for
std.collections I surmise that this is the standard way to go. From the
source code, I see there's no special opIn, but that it can be done with
the more general...

bool opBinary(string op)(T k) if (op == in) {
...
}

Here T is, of course, a compile-time argument of the surrounding struct
or class.

So ... this is used in the the Phobos source in the DMD 2.052 distro (if
I'm not mistaken), but I can't get dmd 2.052 to accept it? I keep
getting the error message Error: rvalue of in expression must be an
associative array, not Foo!(uint).

I guess either that this is a recent feature -- I didn't see it
mentioned in Andrei's book -- and that my Phobos source is too recent
for my dmd ... or that I'm doing something wrong elsewhere in my code,
preventing the operator overloading to take force. Suggestions/solutions?-)



If you try to use it in the manner of `something in 
classWhichDefinesThisOpBinary` then it doesn't work because operator 
overloading normally overloads on the left operand (ie something). Use 
opBinaryRight(string op)(...) if(...) to get it working.


Mafi


Re: Multiple opCall's

2011-02-21 Thread Mafi

Am 21.02.2011 11:18, schrieb useo:

Hey guys,

I've a small problem implementing multiple opCall()-methods. At first, I've the 
following interface:

interface Invoker {
  void opCall(uint i);
}

... and an abstract class which inherits from the Invoker-interface like the 
following:

abstract class AbstractInvoker : Invoker {

  private int myInt;

  override void opCall(uint i) { /** do nothing */ }


In an abstract class you can just leave this out. The inheriting class 
will then be checked to implement this.




  void opCall() {
   opCall(myInt);
  }

}

I know... I can remove the opCall(uint i) from the interface, but it's needed 
for some other classes which implements this method. For
those classes the opCall(uint i)-method is needed.

But... when I now declare a class like this:

class InvokableClass : AbstractInvoker {
  override void opCall(uint i) {
   // do something
  }
}

and do the following:

void main(string[] args) {
  InvokableClass() ic = new InvokeableClass();
  ic();
}

I always get the following errors:

Error: function InvokableClass.opCall (uint i) is not callable using argument 
types ().
Error: expected 1 function arguments, not 0

But I think opCall() is implemented in the abstract class and should be 
callable using opCall() instead using opCall(uint i)?


Overriding one opCall shadows all other opCalls inherited from the base 
class. This behaviour is like with any method. Write:


override void opCall() {
super.opCall();
}

to forward to the base class method.
AFAIK it's an anti-hijacking machanism.


Re: intrinsic min and max for ints

2011-02-16 Thread Mafi

Am 16.02.2011 10:54, schrieb Dominic Jones:

Hello,

Is there a library function for min/max for integers. I would rather not use
the ?-operator, it's rather clumsy. I looked in the standard lib and only
found f(min|max).

Thank you,
Dominic Jones
They're in 'std.algorithm'. They work for all types a, b where a  b is 
defined so also for ints.


Mafi


Re: using a binary tree container

2011-02-13 Thread Mafi

Am 12.02.2011 00:02, schrieb spir:

On 02/11/2011 10:33 PM, Mafi wrote:


I allways try to import 'algorythm' because of the german word
'Algorythmus'.
When this happend for the first time, I spent about five minutes to
find out
what's wrong.


It is spelled Algorithmus in German, no ypsilon ;-)
http://de.wiktionary.org/wiki/Algorithmus
The word is not from greek, but from arabic/persian etymology (like many
words starting in al-). From wiktionary:
http://en.wiktionary.org/wiki/algorithm:

 From French algorithme; from the Old French algorisme (the Arabic
numeral system), a modification likely due to a mistaken connection
with Greek ἀριθμός (number); from Medieval Latin algorismus, a
transliteration of the name of the Persian mathematician al-Khwārizmī
(Arabic: الخوارزمي, native of Khwarezm.)

denis

Holly shit! I feel ashamed now. :(
I'm going to correct all my personal notes about algorithms.

Mafi


Re: using a binary tree container

2011-02-11 Thread Mafi

Am 11.02.2011 21:38, schrieb Steven Schveighoffer:

On Fri, 11 Feb 2011 14:46:26 -0500, Tom no.em...@gmail.com wrote:


what with this?:
auto arr = [foo, bar, aaa, zzz];
sort(arr);
assert(canFind(foo));
assert(canFind(aaa));
assert(!canFind(aa));
I had a Error 1 Error: module algorithem is in file 'std\algorithem.d'


it's spelled algorithm, no e in there.

-Steve


I allways try to import 'algorythm' because of the german word 
'Algorythmus'. When this happend for the first time, I spent about five 
minutes to find out what's wrong.


Mafi


Re: New to D: parse a binary file

2011-02-06 Thread Mafi

Am 06.02.2011 19:38, schrieb Jesse Phillips:

scottrick Wrote:


T[] rawRead(T)(T[] buffer);

I understand that T is generic type, but I am not sure of the
meaning of the (T) after the method name.


That T is defining the symbol to represent the generic type. It can have more 
than one and D provides other things like aliases... Another way to write that 
function (I may get something wrong here but give it a shot) is:

template(T) {
 T[] rawRead(T[] buffer);
}

I think you meant

template(T) rawRead{
T[] rawRead(T[] buffer);
}

'template' defines a namespace which is normally accessed like

templ!(parameters).member;
templ!(parameters).memberfunc(parameters);

Because the template and it's member are called identically this member 
is accessed autoatically (the eponymous-trick). If it's a function you 
call it like that:


templfunc!(compiletimeparam)(param);

The compile time parameters can left out, if these can be derived from 
the normal parameters' type.


templfun(param);

Voilla! You have a completely transparent templated func.

Mafi


Re: Foreach type infering only works up to 2 levels?

2011-02-02 Thread Mafi

Am 02.02.2011 20:16, schrieb Andrej Mitrovic:

int[][][][] multiArray;

void main()
{
 foreach (one, two; multiArray)  // ok
 {
 }

 foreach (one, two, three; multiArray)  // fail
 {
 }
}

test.d(13): Error: cannot infer type for two
test.d(13): Error: cannot infer type for three

Same thing happens with hashes as well. Is this a limitation in the language or 
a bug?

I use the following idiom.

foreach(x, ref column; array)
foreach(y, ref element; column)
//maybe more...
{
//do something
}

It works because of constructs take one staement  one block is one 
statement. It is really great because it leads to such flexible soultions.
You might say it's bad practise bad then you have to say the same about 
'else if'.


Mafi


Re: Structs with pointers?

2011-01-23 Thread Mafi

Am 23.01.2011 11:00, schrieb Dmitry Olshansky:

On 23.01.2011 2:02, bearophile wrote:

Is this another compiler bug?

The situation is nice:

struct Foo1 {}
struct Foo2 { int x; }
const struct Foo3 { int* p; }
struct Foo4 { int* p; }
void bar1(Foo1 f) {}
void bar2(Foo2 f) {}
void bar3(Foo3 f) {}
void bar4(Foo4 f) {}
void main() {
const f1 = Foo1();
bar1(f1); // no error
const f2 = Foo2();
bar2(f2); // no error
const f3 = Foo3();
bar3(f3); // no error
const f4 = Foo4();
bar4(f4); // error
}

Bye,
bearophile


The first two are actually OK, since you pass a copy of a value type
FooX to barX.
If signature was void bar(ref FooX) then it should have failed.
But the third makes me wonder what the *** is going on.



I think it's absolutely correct. Look: Foo3 is declared as const struct 
meaning all it's members are const. We are passing a struct like that to 
bar3:

 const Foo3 { const int* p}
which is implicitely converted to:
 Foo3 { const int* p } //not ref !!
Because it's not ref you can't manipulate the original struct anyways 
and the pointer is still const. As long as you don't cast you cannot 
change what the pointer points to so this implicit conversion is correct 
IMO.

It's like const(T[]) = const(T)[] .

Mafi


Re: (coff)-Implib lib from dll

2011-01-15 Thread Mafi

Am 15.01.2011 17:07, schrieb %u:

Hey guys,

I'm trying to connect to my mysql-server on windows. I'm using the mysql 
binding from http://www.steinmole.de/d/ because as I know the
DDBI project doesn't support D2.
I followed the instructions on the site and first created the lib file with implib 
with the following command: implib libmysql.lib
libmysql.dll (without ).
Next, I changed the extern(C) statement in mysql.d to extern(Windows).

Now... I create a simple application with the following source:

module test;

pragma(lib, libmysql.lib);

import mysql;

int main(string[] args) {

MYSQL* mysql;
mysql = mysql_init(null);
mysql_close(mysql);

return 0;

}

I'm trying to compile the source file by using the following command:
dmd -d test.d mysql.d (without quotas). The result is the following:

test.obj(test)
  Error 42: Symbol Undefined _mysql_init@4
test.obj(test)
  Error 42: Symbol Undefined _mysql_close@4
--- errorlevel 2

I also tried dmd -d test.d mysql.d libmysql.lib without any success. When I 
remove the extern-statement from mysql.d, I get similar
errors.

Note... I'm using the github-version 0.2.3 which was released last week.

I think my mistake is the linking because the binding works on Linux. But... 
not on Windows - perhaps... anyone know how what I'm doing
wrong?

Thanks...
Did you try to use the system flag ('/system') for implib which adds 
leading underscores? I had a similar problem and that solved it for me.


Re: (coff)-Implib lib from dll

2011-01-15 Thread Mafi

Am 15.01.2011 17:46, schrieb nrgyzer:

I just used implib libmysql.lib libmysql.dll /system but it produces
the same errors.


In the implib help it says:
implib [switches] libfile [ dllfile | deffile ]

I'm not sure but implib could be picky about where the switches are.

Mafi


Re: cstrings

2011-01-02 Thread Mafi

Am 02.01.2011 05:12, schrieb Ellery Newcomer:

are there any other cstring - dstring functions than to!string(char*) ?

something like to!(char[])(char*)

(the memory allocation bothers me)


You can simply make a slice. Indexing and sclicing works also with 
c-style pointers in D. Obviously $ is not allowed because bare pointers 
don't have a length.

poinetr[0 .. strlen(pointer)]
Be sure to not give this array to functions which relies on your char[] 
to be GC-allocated.


Re: C structs

2010-10-20 Thread Mafi

Am 19.10.2010 23:39, schrieb Stanislav Blinov:

Lutger wrote:

Mafi wrote:


Hello,
I'm trying to write some SDL wrapper. After a long fight against
objconv, implib and optlink I finally got SDL loading.


Have you tried Derelict? (dsource.org/projects/derelict). There is a
branch called Derelict2 which is D2-compatible. Derelict does not
require import libraries, only DLLs/SOs - it does run-time dynamic
linking (i.e. loads dynamic library and binds function pointers at
runtime). The only major caveat with Derelict at the moment is lack of
proper support for 'shared' directive, which leads to chaos in
multithreaded applications. Some work has been done to fix that, but
much is to be done still.
I've tried Derelict2 first. I'm using D2 so Dererelict1 was no option. 
After svn checkout (I know it could be broken but I found no 
'stable'-link) I tried to compile and got a bunch of immutability 
errors. I thought that it must be an yet uncomplete port so I went with 
static linking but I tried to write everything so I could use Derelict 
in some future.



Hurray! Now I'm going to write a wrapper for SDL_Surface. I will only
use surface
poiters so my questions is if I can safely put these pointers into class
instances which on destruction free the surface (iff it's no display)?


Some caveats apply:

iirc with SDL you typically initialize and close down the different
subsystems. With the GC finalizing surfaces will be freed after sdl
shutdown, dunno if that's legal.


Generally, it's not.
Mafi, if you really want to wrap up SDL handles into classes, I'd advise
you to either:

1) Rethink your design. For example, you could store references to all
objects that are bound to SDL handles and free resources before
SDL_Quit()/SDL_QuitSubSystem() call.

That sounds good. It isn't even reference counting.


2) Manually 'tell' classes they should free SDL resources via some
method. Even in C++ you'd delete all your heap-allocated objects anyway,
so there's no difference, except that instead of calling delete you'd
call some custom method.
Yea, I didn't want to prevent people from using from using some close 
moethod but D has a GC included so why don't use it? Now I know it's a 
horrible idea.


Pretty much anything that concerns video in SDL should go into one and
only thread, so you should be doubly careful, for all manner of stupid
mousetraps await our toes in the dark if you think of multithreaded
application. This means that lazy SDL resource management is in no way
an option.
[...]
I very much like the design decision made by Eric Poggel in Yage
(yage3d.net). This mostly concerns OpenGL resources, but generalization
is clear enough: GL resources are allocated and initialized on demand
(i.e. when first used) and freed if not used in some time. Similar
approach may be taken with SDL as well, I think.
I think you can't do it with sdl. If I understood this bit right, you 
want to free resources when not used and reload them later again. A 
problem with this is that loaded-and-then-manipulated surfaces would 
loose their change and completely code generated surfaces would be 
completly lost.




C structs

2010-10-19 Thread Mafi

Hello,
I'm trying to write some SDL wrapper. After a long fight against 
objconv, implib and optlink I finally got SDL loading. Hurray! Now I'm 
going to write a wrapper for SDL_Surface. I will only use surface 
poiters so my questions is if I can safely put these pointers into class 
instances which on destruction free the surface (iff it's no display)?


Re: Understanding isInfinite(Range)

2010-09-06 Thread Mafi

Am 06.09.2010 21:24, schrieb Andrej Mitrovic:

Apparently I can't post to D.learn from gmail without waiting for a review? 
What the..?

Anyway, I've posted this:

On a related note, I always wanted to make a template to replace the
dreaded is(typeof('delegate literal'())); calls.

For example, instead of this:

enum bool isInputRange = is(typeof(
{
R r; // can define a range object
if (r.empty) {}  // can test for empty
r.popFront;  // can invoke next
auto h = r.front; // can get the front of the range
}()));

We'd have a much cleaner call like so:

enum bool isInputRange = validate!(
{
R r; // can define a range object
if (r.empty) {}  // can test for empty
r.popFront;  // can invoke next
auto h = r.front; // can get the front of the range
});

But I haven't found a way to do it properly. If I call validate on a
type R range which doesn't feature the empty() method, then no matter
what the definition of validate is the compiler will error out because
it sees the call to r.empty() in the function literal, and 'r' doesn't
have an empty method.



You could just let your template get a string. Then
validate!q{}
should work. It looks almost exactly the same but has a 'q'.

Maybe you could even create an template overload which gets delegate 
which has always failing static assert with message you forget the 'q' 
but I don't know if template initialization comes before semantic 
analisys so I'm not sure this will work.


Mafi




Re: template deduction

2010-08-23 Thread Mafi

Am 22.08.2010 21:45, schrieb bearophile:
(...)

import std.stdio: writeln;
import std.typecons: Tuple, tuple;
import std.traits: ReturnType, ParameterTypeTuple;

struct Memoize(alias F) {
 ReturnType!F opCall(ParameterTypeTuple!F args) {
 alias ReturnType!F ResultType;
 static ResultType[Tuple!(ParameterTypeTuple!F)] cache;
 auto ptr = tuple(args) in cache;
 if (ptr == null) {
 auto result = F(args);
 cache[tuple(args)] = result;
 return result;
 } else {
 return *ptr;
 }
 }
}

pure int fib(int n) {
 if (n  2)
 return n;
 return fib(n - 1) + fib(n - 2);
}

void main() {
 pure int delegate(int n) cfib_impl;
 Memoize!cfib_impl cfib;

 cfib_impl = (int n) {
 if (n  2)
 return n;
 return cfib(n - 1) + cfib(n - 2);
 };

 enum int N = 40;
 writeln(fib(, N, ) = , fib(N));
 writeln(cfib(, N, ) = , cfib(N));
}

Bye,
bearophile
I see; I should use template magic. Oh, and I used Tuple the wrong way 
beacuse I've never used it before.

Thanks

Mafi


Re: dmd: Module X conflicts with itself (Was: Re: RDMD on Windows)

2010-08-22 Thread Mafi

Am 22.08.2010 16:39, schrieb Andrej Mitrovic:

That's very interesting.

But wouldn't that cause problems if you're using package labels in some of those modules? 
AFAIK package gives access to all files in the current directory, so even if you 
move a module by changing the module declaration, the files in the current 
directory will still have access to it, right?

If that's true, I'm thinking this could potentially cause problems (if you're 
moving modules by changing their declaration instead of physically moving them).

AFAIK the package attribute gives access to all modules which define to 
be in the same package, ie module declarations are eqivalent before the 
*last* dot.

If it's not like that, then package should be called 'directory'.



template deduction

2010-08-22 Thread Mafi

Hey,
I've written some caching template which should cache the return values. 
It looks like this:

//
template cached(F : R function(P), R, P...) {
R cached(P p) {
static R[Tuple!(P)] cache = [];
R* pointer = Tuple!(P)(p) in cache;
if(pointer !is null) {
return *pointer;
} else {
cache[Tuple!(P)(p)] = F(p);
return cache[Tuple!(P)(p)];
}
}
}
//
I am not able to instatiate ths template in any way. In my opinion there 
is enough information so that I can my template like this:

//
alias cached!(func) cfunc;
//
But this doesn't work. It doesn't work the verbose way either. I've 
attached the whole test code so you can see if the error is somewhere else.

Thanks for reading!

Mafi

PS: I used the verbose variant of template declaration because my old 
template signature didn't work with the short form.


PPS: I'm usinng D2

module caching;

import std.typecons;

template cached(F : R function(P), R, P...) {
R cached(P p) {
static R[Tuple!(P)] cache = [];
R* pointer = Tuple!(P)(p) in cache;
if(pointer !is null) {
return *pointer;
} else {
cache[Tuple!(P)(p)] = F(p);
return cache[Tuple!(P)(p)];
}
}
}

pure int fib(int n) {
if(n2) return n;
return fib(n-1) + fib(n-2);
}

pure int cfib_impl(int n){
if(n2) return n;
return cfib(n-1) + cfib(n-2);
}

alias cached!cfib_impl cfib;

void main() {
writeln(Running fib());
fib(200);
writeln(Running cfib());
cfib(200);
writeln(Finished!);
}

Re: Duck typing and safety.

2010-08-13 Thread Mafi

Am 13.08.2010 19:01, schrieb simendsjo:

import std.stdio;

struct S
{
 void shittyNameThatProbablyGetsRefactored() { };
}

void process(T)(T s)
{
 static if( __traits(hasMember, T,
shittyNameThatProbablyGetsRefactored))
 {
 writeln(normal processing);
 }
 else
 {
 writeln(Start nuclear war!);
 }
}


void main()
{
 S s;
 process(s);
}


If you rename S's method, process() does something completely different
without a compile time error. By using interfaces this is avoided as the
rename would break the interface.
As I understand this, you want t never start a nuclear war (lol) so do 
something like this:


void process(T)(T s) if ( __traits(hasMember, T, 
shittyNameThatProbablyGetsRefactored)) {...}


The if here is a template constraint, which is part of the signature 
(which means you can overload with those). If you try to instantiate 
your template in a wrong manner, you get a nice ct error at the 
instantiation.


Then you can remove the unreachable 'war'-branch.

Mafi


Re: typeof and block statements

2010-08-12 Thread Mafi

Am 12.08.2010 15:13, schrieb simendsjo:

The spec doesn't mention anything about block statements in typeof
declarations.

//typeof({1}) a; // found } expecting ;
//typeof({1}()) b; // same as a
typeof(1) c; // int

I'm asking because isInputRange from std.range the idom from the b test:

template isInputRange(R)
{
enum bool isInputRange = is(typeof(
{
R r; // can define a range object
if (r.empty) {} // can test for empty
r.popFront; // can invoke next
auto h = r.front; // can get the front of the range
}()));
}


Also... The unittest contains
static assert(isInputRange!(int[]));
static assert(isInputRange!(char[]));

But arrays doesn't include these methods.. I don't understand a thing :(
The braces create an delegate which should be directly called after its 
 creation (this do the parens). If you put this into typeof, this 
delegate will never be created, we just get the type of calling it. The 
type of calling a delegate is of course the delegate's return type which 
is automatically deduced.
Your exampley a and b are invalid beacuse '1' is not a valid statement 
it's only a expression. 'return 1;' would work as expected.
Why does the spec don't mention it? It's beacuse a delegate is always a 
valid expresion. typeof has no special case of braces.


Mafi


Re: Is there a queue class in phobos?

2010-08-10 Thread Mafi

Am 10.08.2010 18:22, schrieb Trass3r:

Container has List, BinaryHeap etc. but no Queue. Is there anything like
that in Phobos?

Hi,
I don't know if ther is one but I think D's arrays are powerful enough 
unless you avoid the GC.


1. a.front() = a[0]
2. a.popFront() = a = a[1..$]
3. a.pushBack(x) = a ~= x

I think in phobos there must be front and popFront for arrays to make 
them ranges but I don't know where.


Re: Casting away const

2010-08-09 Thread Mafi

Am 09.08.2010 17:31, schrieb bearophile:

Steven Schveighoffer:

But an extern(C) function does not have to be written in C :)


You are right. But that function written in an arbitrary language has to follow 
the C interface rules and limitations, and among those there is no way to 
define a variable to be const(char)*.

So in that line of code you are writing something that can't be enforced. 
Generally D design refuses features that the compiler is unable to verify. So I 
think an enhancement request to disallow that is good here. An extern(C) call 
has to specify only things that are understood by the C interface.

On the other hand in C you have const, but its semantics is different. Uhm...

Bye,
bearophile


I think, that isn't a good idea. I mean const-ness a compile time thing 
so the c abi has no problem with it. What's wrong when I define a

extern(c) bool thinkeAboutMyInt(const int* x) {
  
}
I want to inform the D typesystem that I'm not going to change the int 
but I need a pointer because the adress is important. I want this 
function to be also callable outside D (eg C).


Mafi


Re: Array Operations and type inference

2010-08-07 Thread Mafi

Am 07.08.2010 14:10, schrieb simendsjo:

I'm new to D2, so please.. :)

The spec on Array Operations,
http://www.digitalmars.com/d/2./arrays.html says:
A vector operation is indicated by the slice operator appearing as
the lvalue of an =, +=, -=, *=, /=, %=, ^=, = or |= operator.

The following tests works fine as I expected:


{
double[3] a = [1,1,1];
double[3] b;
b[] = a[] + 3;
assert(a == [1,1,1]);
assert(b == [4,4,4]);
}

{
double[3] a = [1,1,1];
auto b = a;
b[] = a[] + 3;
assert(a == [1,1,1]);
assert(b == [4,4,4]);
}

But from here on I'm having problems...

{
double[] a = [1,1,1];
double[] b;
b[] = a[] + 3;
assert(a == [1,1,1]);
assert(b == [4,4,4]); // fails as b.length == 0.. Should the compiler
say something?
}

{
double[] a = [1,1,1];
double[] b;
b.length = a.length;
b[] = a[] + 3;
assert(a == [1,1,1]);
assert(b == [4,4,4]); // Now it's fine
}

{
double[3] a = [1,1,1];
double[3] b = a[] + 3; // works although lvalue isn't a slice. Static
arrays? Because it's an initial value?
assert(a == [1,1,1]);
assert(b == [4,4,4]);
}

{
double[3] a = [1,1,1];
auto b = a;
b = a[] + 3; // And so does this.. Something to do with static arrays?
assert(a == [1,1,1]);
assert(b == [4,4,4]);
}

{ // Like the previous example, but with dynamic arrays..
double[] a = [1,1,1];
auto b = a;
assert(a is b);
b = a[] + 3;
assert(a == [1,1,1]);
//writeln(b); // access violation. Because of dynamic arrays?
}

{ // Like above, but using slicing like the spec says.. Works fine
double[] a = [1,1,1];
auto b = a;
assert(a is b);
writeln(typeof(b).stringof); // double[]
b[] = a[] + 3;
assert(a == [4,4,4]); // a also changed. I expected this
assert(b == [4,4,4]);
}

{
double[3] a = [1,1,1];
auto b = a[] + 3; // What happens here?
writeln(typeof(b).stringof); // double[]
assert(b.length == 3);
assert(b.capacity == 0);
//writeln(b); // access violation
}

{ // Same as above?
double[3] a = [1,1,1];
//writeln(a[] + 3); // access violation
}


Hi,
I don't the answer to all of your problems but what I can say you is:
* D-Arrays are references to structs which point to the data
* An arrayvariable on the left-hand-side of an assignment sets the 
reference of this variable. (no copy!)
* An array slice is mostly the same as the array variable itself but if 
it's on the left-hand-side of an assignment, the data is copied from the 
right-hand-side.


So for example your third example can't work because b is null and so 
there's no place you can copy the data to.


Re: Array Operations and type inference

2010-08-07 Thread Mafi

Hey, here Mafi again,
I thought about your snippets and here's what I have.

Am 07.08.2010 14:10, schrieb simendsjo:

{
double[3] a = [1,1,1];
double[3] b;
b[] = a[] + 3;
assert(a == [1,1,1]);
assert(b == [4,4,4]);
}

{
double[3] a = [1,1,1];
auto b = a;
b[] = a[] + 3;
assert(a == [1,1,1]);
assert(b == [4,4,4]);
}

But from here on I'm having problems...

{
double[] a = [1,1,1];
double[] b;
b[] = a[] + 3;
assert(a == [1,1,1]);
assert(b == [4,4,4]); // fails as b.length == 0.. Should the compiler say 
something?
}
As I said in my first post b is null. Now the third line tries to _copy_ 
the result to b which is impossible. About your question:
that the compiler complains would be difficult but in my opinion it 
should result in an runtime error.


{
double[] a = [1,1,1];
double[] b;
b.length = a.length;
b[] = a[] + 3;
assert(a == [1,1,1]);
assert(b == [4,4,4]); // Now it's fine
}
With setting b's length you (re)allocate(1) memory for the array so now 
there's place to copy to.



{
double[3] a = [1,1,1];
double[3] b = a[] + 3; // works although lvalue isn't a slice. Static
arrays? Because it's an initial value?
assert(a == [1,1,1]);
assert(b == [4,4,4]);
}
You simply intialize the fixed-size array with a dynamic one. I'm not 
sure but I think the data is copied out of the dynamic temporary array to b.

{
double[3] a = [1,1,1];
auto b = a;
b = a[] + 3; // And so does this.. Something to do with static arrays?
assert(a == [1,1,1]);
assert(b == [4,4,4]);
}

In the second line you initialize to a and then do the same as above.
Note: In D fixed-size arrays are value types.

{ // Like the previous example, but with dynamic arrays..
double[] a = [1,1,1];
auto b = a;
assert(a is b);
b = a[] + 3;
assert(a == [1,1,1]);
//writeln(b); // access violation. Because of dynamic arrays?
}
I have no idea. Maybe the array generated by the vector addition is kind 
of temporary and you have to copy. But it could also be a bug.

Vector-operations are still quite buggy.

{ // Like above, but using slicing like the spec says.. Works fine
double[] a = [1,1,1];
auto b = a;
assert(a is b);
writeln(typeof(b).stringof); // double[]
b[] = a[] + 3;
assert(a == [4,4,4]); // a also changed. I expected this
assert(b == [4,4,4]);
}

Now you are copying to b(which references the same struct as a).

{
double[3] a = [1,1,1];
auto b = a[] + 3; // What happens here?
writeln(typeof(b).stringof); // double[]
assert(b.length == 3);
assert(b.capacity == 0);
//writeln(b); // access violation
}

It's the same as to steps before this(my  english isn't ver good ;))

{ // Same as above?

I think it is.

double[3] a = [1,1,1];
//writeln(a[] + 3); // access violation
}


(1)It's normally for reallocation when you need more space.



Re: template fiddling

2010-08-07 Thread Mafi

Am 07.08.2010 18:40, schrieb Blonder:

Hello,

I am trying to understand the template mechanism in D, but I don't get it 
working.

I want to compute the dot product as follows:
int[] a = [1, 2, 3];
int[] b = [5, 6, 7];

double dd = ???.dot_product( a, b );

with classes like this:
class DotProduct(DIM, T)
{
static T result(T a, T b)
{
return a * b + DotProduct!(DIM-1, T).result(a+1, b+1);
}
}

class DotProduct(1, T)
{
static T result(T a, T b)
{
return a * b;
}
}

and a function :
T dot_product(DIM a, T b)
{
   return ???.result( a, b );
}

Can anyone help me? In C++ its not the problem but with D I can't
get it working.

Thanks,
Andreas


Hi,
to make an instance of an template you use the !-infix operator: 
'template!(param,...)'. If you want to give only one parameter you can 
use 'template!param'. But your example can't work because template 
arguments have to be evaluatable at compile time (which function 
parameters are not). You can use a normal function parameter.


In your example you use a template class which isn't supposed to be used 
as class, I think. If so, you should make a simple template

template MyTemplate(...){
  int myFunction(){}
  int myFunction2(){}
}
Then you can say MyTemplate!(...).myFunction(...). You can leave out 
tralling template arguments which deducable by the arguments of the 
function.


There also a trick that you can use to make a shortcut. Add
  alias MyTemplate myFunction
to the template. Then you can use MyTemplate!()()instead of 
MyTemplate!(.).myFunction(). MyTemplate!().myFunction2() 
will still work.


The above trick is also how class and function templates work.

Mafi


P.S. If you often use some template instance you can use an alias
  alias MyTemplate!(.) MyInstance


Re: template fiddling

2010-08-07 Thread Mafi

Am 07.08.2010 21:04, schrieb Blonder:

Hello,
the template!(...) mechanism I understand.
But I think I need the two classes, the first is the primary template
and the second the partial specialization (this is the end of the loop), or 
can
I do this in D with functions?

The normal computation of the dot product is normally done in a for loop. But 
with
templates you can enroll the loop.
template!(...)(3, a, b). In this example 3 is the dimension of the arrays a and 
b.

Andreas.

Is that what you are searching for:
/
module templatetest;

import std.stdio;

T[] foo(T : T[], int S) (T[] t) {
  writeln(Hey ,S);
  return foo!(T[],S-1)(t);
}

T[] foo(T : T[], int S : 0) (T[] t) {
  writeln(END);
  return(t);
}

/*
//Can't get static arrays right
//always uses dynamic version
T[S] foo(T : T[S], int S) (T[S] t) {
  writeln(Hello ,S);
  return foo!(T[],S-1)(t);
}

T[S] foo(T : T[S], int S:0) (T[S] t) {
  writeln(END2);
}*/

void main() {
  int[] x = [25,42,26,34,10];
  foo!(int[],5)(x);
}
//
Uage foo!(int[],5)(xy). If you swap around the array parameters in your 
version then you should be able to omit T.

Also when you have fixed-size arrays the array length isn't DRY.


Re: hijacking a class's members

2010-08-04 Thread Mafi

Am 04.08.2010 12:11, schrieb Rory Mcguire:

Hi,

The code below is my beginning to attempt a class which implements any class
and throws an exception if one tries to access any member of that class.

Problem is that if I use:
auto a1 = noinit!(A)();

it works and accesses the int x() {...} member of the generated class, but
if I use:
A a1 = noinit!(A)();

it accesses A.x instead of the generated classes x.

So am I wrong in making a sub class have a member function which hides a
parent class's member variable or is the compiler wrong and it should
generate a call to generated sub class?


Thanks!!!
-Rory

Hi,
if x is a field (ie a member variable) it's statically bound. In your 
example it is a field so it gets A.x of your subclass which is still 
there becuase of the methoda of A which could use A.x.
Fields have to be statically bound because there's no covariance 
guarateed with them. Use getters and setters instead.
BTW are @propertys statically or dynamically bound. They're kind of 
both: fields and methods.


Mafi



Re: hijacking a class's members

2010-08-04 Thread Mafi

Thats what feels weird to me. a.x can result in different things happening
even though x exists in both A and the generated class. However the
generated class has two fields called x one you can't access anymore and
the @property one.
When I create an instance of the generated class I would expect it to always
to the same thing if I use one of its methods/properties/etc...
Kind of like you would expect the following to print out hello 2:
class A {
 string toString() { return hello; }
}
class B : A {
 string toString() { return super.toString() ~  2; }
}
void main() {
 A a = new B();
 writeln(a.toString()); // uses B.toString()
}

What I've got is:
class A {
 int x;
}
class B : A {
 int x() { throw new Exception(); }
}
void main() {
 A a = new B();
 writeln(a.x); // this accesses A.x not B.x
}

just seems like properties are not quite right or something.

-Rory



If you want that to work, both x have to be virtual (ie dynamically 
bound). In D all non-final non-ststic clsss-methods are virtual(1). 
Consider the following:

///
class A {
  int x = 0;
  int getX() { //-- it's virtual
return x;
  }
}

class B : A{
  int x = 5;
  override int getX() { //-- it's virtual too
return x;
  }
}

void thinAboutA(A a) {
  /* Now a call to a non virtual method
   * which results in vtbl lookup. a's vtbl
   * contains B.getX().
  writeln(a.getX());
  /* Non virtual field.
   * Has to be statically bound
   * to a lookup in A.x
   */
  writeln(a.x);
}

void main() {
  thinkAboutA(new B);
}


Fields have to be statically bound bcause the compiler doesn't enforce 
covariance with fields. So you can:

///
class C : A {
  string x = ;
}

void main()  {
  thinkAboutA(new C); //Should evrything crash now? I won't.
}
//

1) I'm not sure about @propertys.


Re: xfbuild, optlink and pragma(lib)

2010-08-03 Thread Mafi

Am 02.08.2010 16:19, schrieb Trass3r:

[1] http://www.digitalmars.com/ctg/coff2omf.html
[2] http://www.digitalmars.com/download/freecompiler.html


The tool sounds cool but it seems that I have to buy it, so that's no
option for me.


Yeah, it's a pity that such an important tool for D development on
Windoze isn't free.
You may try objconv though: http://www.agner.org/optimize/?e=0,24#objconv
Thanks, it's a great utility. Converting and dumping works fine. My 
Program compiles now but a get object.Error: Access Violation when I 
run it. Factored out it's the call to SDL_Init(). Is it because of the 
conversion (COFF - ELF - OMF; COFF - OMF wasn't possible) or because 
of my wrong prototype

 export extern(C) { int SDL_Init(Uint32 flags); }
BTW what does a Acces Violation mean?

Mafi


Re: null dereference exception vs. segfault?

2010-08-02 Thread Mafi

Am 02.08.2010 16:50, schrieb Ryan W Sims:

On 8/2/10 1:56 AM, Jonathan M Davis wrote:

On Sunday 01 August 2010 21:59:42 Ryan W Sims wrote:

The following code fails with a Bus error (OSX speak for Segfault,
if I understand correctly).

// types.d
import std.stdio;

class A {
int x = 42;
}

void fail_sometimes(int n) {
A a;
if (n == 0) {
a = new A; // clearly a contrived example
}
assert(a.x == 42, Wrong x value);
}

void main() {
fail_sometimes(1);
}

It's even worse if I do a 'dmd -run types.d', it just fails without even
the minimalistic Bus error. Is this correct behavior? I searched the
archives looked at the FAQ found workarounds (registering a signal
handler), but not a justification, and the threads were from a couple
years ago. Wondering if maybe something has changed and there's a
problem with my system?

--
rwsims


You are getting a segmentation fault because you are dereferencing a null
reference. All references are default initialized to null. So, if you
fail to
explicitly initialize them or to assign to them, then they stay null,
and in
such a case, you will get a segfault if you try to dereference them.


Yes, I know *why* I'm getting a segfault, thank you - I set up the
example explicitly to defeat the compiler's null checking to test the
behavior. I was startled that there wasn't an exception thrown w/ a
stack trace.

[snip]




Unlike Java, there is no such thing as a NullPointerException in D.
You just get
segfaults - just like you would in C++. So, if you don't want
segfaults from
derefencing null references, you need to make sure that they aren't
null when
you dereference them.

- Jonathan M Davis


That was my question, thanks. It seemed like such an un-D thing to have
happen; I was surprised. I guess w/o the backing of a full virtual
machine, it's tricker to catch null dereferences on the fly, but boy
it'd be nice to have. Don't want to re-fire the debate here, though.

--
rwsims


If you want a NullPointerException as part of your program flow, you can 
use enforce() (in std.contracts I think). I don't think catching a 
NullPointerException in a big code block where you don't know which 
dereferencing should fail is good style.


Mafi


Re: xfbuild, optlink and pragma(lib)

2010-08-01 Thread Mafi

Ok,
OPTLINK is the problem. Without linking SDL, it complains about missing 
symbol (good) and creates a corrupt executable (so-so). With linking SDL 
in any way (explicitly or with pragma(lib)) it shows no errormessage 
(really bad) and does not create any executable (bad).

Should I fill a bug report or am I doing something wrong?



Re: xfbuild, optlink and pragma(lib)

2010-08-01 Thread Mafi

libSDL.dll.a is a MingW- or Cygwin-compiled link library. That's not
going to work on Windows with DMD and may very likely be the source of
your problem. If you want to link with a DLL link lib, then you need to
get the tool coff2omf[1] (part of the Extended Utilities Package[2]) run
it on SDL.lib (I suppose it might work on SDL.dll.a), and link with the
resulting converted file. Either that or compile SDL with DMC.

Alternatively, you could modify your binding to load SDL dynamically
like Derelict does. Then you don't need to fool around with any link
libs. But, you do need a fair amount of implementation code to load the
function symbols from the DLL.

[1] http://www.digitalmars.com/ctg/coff2omf.html
[2] http://www.digitalmars.com/download/freecompiler.html


The tool sounds cool but it seems that I have to buy it, so that's no 
option for me. So I tried to compile SDL myself. I have to say I'm to 
stupid for it. I tried to do the same thing as the makefile in 
powershell. After I hacked together some solution that worked dmc 
complained about missing Gl.h. It isn't there. So I added some MinGW to 
the include-path and then I get a bunch of errors in SDL without 
linenumbers. And anyways I am trying to compile it without MinGW, aren't 
I. Please, help me!


xfbuild, optlink and pragma(lib)

2010-07-30 Thread Mafi

Hi,
I wanted to create an simple wrapper around SDL. After my simple first 
steps, I wanted to create a simple application using my wrapper. That's it:

///
module test;

import std.stdio;
import mysdl.system;

//pragma(lib,rPath\to\SDL\lib\libSDLmain.a);
pragma(lib,rPath\to\SDL\lib\libSDL.dll.a);


void main() {
  initAll(); //Init all SDL-subsystems
}

I tried to compile it using
xfbuild test.d +full +xstd +xcore -debug -I.. +v +o=test
(-I.. - there is mysdl)
That doesn't work! It doesn't create any executable but there's no 
error. Because xfbuild -v doesn't show the linker-command either I tried 
to reproduce it myself. It seems that optlink is the problem because it 
does nothing but shows no errormessages.


When I comment out the pragma(lib) optlink fails (correctly) and xfbuild 
crashes (:-(). Then I call optlink myself with libsdl.dll.a and it 
creates a corrupt exe without errormessages.


Please help me. It seems that there are bugs over bugs. I don't konw 
what to do.


I use Windows 7, dmd (2.047), xfbuild with cmd/powershell.

PS: I know there's Derelict but wanted to create this myself as a task 
for learning D.


Re: No constructor for a templated class?

2010-07-25 Thread Mafi

Am 25.07.2010 14:55, schrieb Philippe Sigaud:

OK, I must be tired, I don't know.
While switching from a template struct to a templated class, I got the
following problem:

class A(T)
{
 T _t;
 this(U)(U u) if (is(U == T))
 {
 _t = u;
 }
}


Probably this case is reduced, but anyways:
Having a template(U) where U must be == T (another template parameter) 
is complettly useless. Maybe I'm missing something but isn't this 
equivalent to the above:

class A(T)
 {
  T _t;
  this(T u)
  {
  _t = u;
  }
 }



Re: Multi dimensional array question.

2010-07-16 Thread Mafi

Am 16.07.2010 11:12, schrieb Heywood Floyd:

Lars T. Kyllingstad Wrote:


I do agree that, if possible, the language should match how most people
think.  But in this case, it is impossible, because of templates.  How
would the following example work with T = int[3], if arrays worked the
way you want?

   struct MyArray(T)
   {
   T[] a;
   }

C doesn't have this issue, because it doesn't have templates.  And I'll
have my templates over C-style array declarations any time, thank you. :)

-Lars



Well, I suppose the obvious way is to introduce array as a proper type, and not
just as syntactical sugar. For instance, consider:

array[11] int myArr;

...

I don't really like it. Of course the order of indices feels better but 
it breaks the rule of reading types from right to left. It also 
introduces more parenthesis and a new keyword into types (amongst const, 
immutable and delegate etc). Consider:

  shared array[3](const( array[5] immuttable((SList!(int)*)[]) ))
WTF, that doesn't look good. I would be a real type if your answer was 
accepted.


It was
  shared const( immutable(Slist!(int)*[])[5] )[3]
which reads perfectly from right to left.

What about this:
  // int[width,height] as sugar for int[height][width]
  int[width,height] arr = ...;
  // arr[x,y] as sugar for arr[x][y]
  int element = arr[x,y];
  // then this works as expected
  int[height] column = arr[x];


Re: Some testing?

2010-07-14 Thread Mafi

Am 14.07.2010 20:55, schrieb bearophile:

This small D2 program compiles with no errors:

T foo(T)(T x) {}
void main() {}

But there is no way it can compile, regardless of the type T, because foo()() 
lacks a return statement.
So is it possible for the D compiler to perform some sanity tests for the 
template functions too, to catch a bugs like this one?


Imagine T was void. Then no return was ok. It wouldn't (shouldn't) 
compile anyways because a parameter of type void is (should be) invalid. 
However to enforce the compiler to see that T can't be void is a bit to 
complicated, I think.


Mafi



d2 compiler

2010-07-04 Thread Mafi

Hello everybody,
i'm new to D but not to programming in general. I wrote some todo-lister 
in D1. It compiles and works nearly perfectly except some little issues. 
I wanted to check if it works under D2. I renamed my

DMD version 1 compiler to dmd1.exe so I could use dsss/rebuild.
When try to compile my code doesn't stop to take more RAM.
Where's the issue. Is it my code, dsss or the compiler.

I use dmd 2.047, dsss/rebuild through the commandline, win7.
Here's my code: http://pastebin.com/DRCbg03v

Mafi


Re: d2 compiler

2010-07-04 Thread Mafi

bearophile:

Mafi:

When try to compile my code doesn't stop to take more RAM.


Maybe it's those appensds. If you have many large strings it's much better both 
in D and other languages to collect them in an array of strings, and then join 
them all at the end.
Try to strip your program to bare-bones if you want to find the source of your 
problems.
If I understood you correctly, you want to say that the contactation 
takes much RAM, but it doesn't even compile. There's no error. It simply 
doesn't stop to build and takes more and more RAM.



Note $[0] is probably written '$'.

Yeah, that's right!

It seems some problem of dmd or rebuild because a Hello-World-Program 
which also import std.file doesn't stop to compile. If comment out the 
std.file-import everything is fine.