pure functions/methods

2012-04-20 Thread Namespace

The sense of pure functions isn't clear to me.
What is the advantage of pure functions / methods?
I inform the compiler with const that this method does not 
change the current object, and therefore he can optimize (at 
least in C++) this method. How and what optimized the compiler if 
i have pure or const pure functions / methods?


Re: pure functions/methods

2012-04-20 Thread Ary Manzana

On 4/20/12 4:06 PM, Namespace wrote:

The sense of pure functions isn't clear to me.
What is the advantage of pure functions / methods?
I inform the compiler with const that this method does not change the
current object, and therefore he can optimize (at least in C++) this
method. How and what optimized the compiler if i have pure or const
pure functions / methods?


As far as I know pure functions always return the same results given the 
same arguments. They also don't cause any side effect.


http://en.wikipedia.org/wiki/Pure_function

Many invocations of a pure function can be executed in parallel because 
they don't have side effects. There's also a chance of caching their 
result since it only depends on the value of their arguments (though I 
doubt what rule the compiler can use to decide to do it).


I don't think any of the following benefits are implemented in DMD.


Re: pure functions/methods

2012-04-20 Thread Sean Cavanaugh

On 4/20/2012 3:06 AM, Namespace wrote:

The sense of pure functions isn't clear to me.
What is the advantage of pure functions / methods?
I inform the compiler with const that this method does not change the
current object, and therefore he can optimize (at least in C++) this
method. How and what optimized the compiler if i have pure or const
pure functions / methods?


Simplest explanation I can think of is:

a const function of a class can't modify its own classes data
a pure function can't modify any data, or call other functions that are 
not also pure (though there are exceptions)




Re: Allow empty field function arguments for default?

2012-04-20 Thread Christophe
Jakob Ovrum , dans le message (digitalmars.D.learn:34948), a écrit :
 On Thursday, 19 April 2012 at 18:34:41 UTC, Jacob Carlborg wrote:

 Named arguments would probably be better for this.

 fun(c = 5);
 
 Maybe so, but `fun(c = 5);` is not an additive change, while the 
 OP's suggestion actually is.

How about

int c;
fun(c = 5);

?

-- 
Christophe


Re: pure functions/methods

2012-04-20 Thread Timon Gehr

On 04/20/2012 10:06 AM, Namespace wrote:

The sense of pure functions isn't clear to me.
What is the advantage of pure functions / methods?


1. It enables stateless reasoning about program parts.
2. It enables certain compiler optimizations.


I inform the compiler with const that this method does not change the
current object, and therefore he can optimize (at least in C++) this
method.


const on a method does not give any guarantees in C++. A C++ compiler 
cannot perform optimizations based on a const method.



How and what optimized the compiler if i have pure or const
pure functions / methods?


DMD does not do a lot there currently.

This article seems to discuss what GCC does with pure functions:
http://lwn.net/Articles/285332/


Re: pure functions/methods

2012-04-20 Thread Namespace

On Friday, 20 April 2012 at 09:55:28 UTC, Timon Gehr wrote:

On 04/20/2012 10:06 AM, Namespace wrote:

The sense of pure functions isn't clear to me.
What is the advantage of pure functions / methods?


1. It enables stateless reasoning about program parts.
2. It enables certain compiler optimizations.

I inform the compiler with const that this method does not 
change the
current object, and therefore he can optimize (at least in 
C++) this

method.


const on a method does not give any guarantees in C++. A C++ 
compiler cannot perform optimizations based on a const method.



How and what optimized the compiler if i have pure or const
pure functions / methods?


DMD does not do a lot there currently.

This article seems to discuss what GCC does with pure functions:
http://lwn.net/Articles/285332/


So only GDC optimized pure functions at all?


Re: Allow empty field function arguments for default?

2012-04-20 Thread Jacob Carlborg

On 2012-04-20 11:17, Christophe wrote:

Jakob Ovrum , dans le message (digitalmars.D.learn:34948), a écrit :

On Thursday, 19 April 2012 at 18:34:41 UTC, Jacob Carlborg wrote:


Named arguments would probably be better for this.

fun(c = 5);


Maybe so, but `fun(c = 5);` is not an additive change, while the
OP's suggestion actually is.


How about

int c;
fun(c = 5);

?



I don't know. Default arguments would probably take precedence perhaps.

--
/Jacob Carlborg


Re: pure functions/methods

2012-04-20 Thread bearophile

Namespace:


So only GDC optimized pure functions at all?


I've seen DMD performs some optimizations with strongly pure 
functions that return integral values.


If you have code like:

int sqr(in int x) pure nothrow { return x * x; }

int y = ...
auto r = sqr(y) + sqr(y);

I think DMD replaces that with this, even when inlining is 
disabled:


int y = ...
auto r = sqr(y) * 2;

Bye,
bearophile


Re: Allow empty field function arguments for default?

2012-04-20 Thread Jakob Ovrum
On Friday, 20 April 2012 at 09:17:18 UTC, 
trav...@phare.normalesup.org (Christophe) wrote:
Jakob Ovrum , dans le message (digitalmars.D.learn:34948), a 
écrit :
On Thursday, 19 April 2012 at 18:34:41 UTC, Jacob Carlborg 
wrote:


Named arguments would probably be better for this.

fun(c = 5);


Maybe so, but `fun(c = 5);` is not an additive change, while 
the OP's suggestion actually is.


How about

int c;
fun(c = 5);

?


That is what I was talking about. (did you mean to quote the post 
I quoted, perhaps?)


Re: Allow empty field function arguments for default?

2012-04-20 Thread Jakob Ovrum

On Friday, 20 April 2012 at 11:09:30 UTC, Jacob Carlborg wrote:

On 2012-04-20 11:17, Christophe wrote:
Jakob Ovrum , dans le message (digitalmars.D.learn:34948), a 
écrit :
On Thursday, 19 April 2012 at 18:34:41 UTC, Jacob Carlborg 
wrote:


Named arguments would probably be better for this.

fun(c = 5);


Maybe so, but `fun(c = 5);` is not an additive change, while 
the

OP's suggestion actually is.


How about

int c;
fun(c = 5);

?



I don't know. Default arguments would probably take precedence 
perhaps.


That is exactly the problem though, it can silently change the 
behaviour of existing code. It is the worst kind of breaking 
change, hence I don't think it will ever be in D in this form, 
much less the current iteration of the language.


Re: D, Derelict2, and OpenGL

2012-04-20 Thread David

Am 20.04.2012 00:34, schrieb Stephen Jones:

In the same vein, I have getting nothing on the screen when there should
be rendered a red triangle. The vertex positions are those used by
McKeeson http://www.arcsynthesis.org/gltut/, being in ndc fall within
the frustum. The code for setting up vao and shaders is:

module ShaderHub;

import std.stdio;
import std.string;
import derelict.opengl3.gl3;

class ShaderHub{
private bool ok=true;
private GLuint shad=0, vshad=0, fshad=0;
private int voff=0;
private GLuint vbo=0, vao=0;
const float[] v = [ 0.75f, 0.75f, 0.0f, 1.0f,
0.75f, -0.75f, 0.0f, 1.0f,
-0.75f, -0.75f, 0.0f, 1.0f];

public this(){
immutable string vshader = `
#version 330
layout(location = 1) in vec4 pos;
void main(void)
{
gl_Position = pos;
}
`;

immutable string fshader = `
#version 330
void main(void)
{
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
`;

shad=glCreateProgram();
if(shad==0){
writeln(Error: GL did not assigh main shader program id);
ok=false;
}

vshad=glCreateShader(GL_VERTEX_SHADER);
const char *vptr=toStringz(vshader);
glShaderSource(vshad, 1, vptr, null);
glCompileShader(vshad);
int status, len;
glGetShaderiv(vshad, GL_COMPILE_STATUS, status);
if(status==GL_FALSE){
glGetShaderiv(vshad, GL_INFO_LOG_LENGTH, len);
char[] error=new char[len];
glGetShaderInfoLog(vshad, len, null, cast(char*)error);
writeln(error);
ok=false;
}

fshad=glCreateShader(GL_FRAGMENT_SHADER);
const char *fptr=toStringz(fshader);
glShaderSource(fshad, 1, fptr, null);
glCompileShader(fshad);
glGetShaderiv(vshad, GL_COMPILE_STATUS, status);
if(status==GL_FALSE){
glGetShaderiv(fshad, GL_INFO_LOG_LENGTH, len);
char[] error=new char[len];
glGetShaderInfoLog(fshad, len, null, cast(char*)error);
writeln(error);
ok=false;
}

glAttachShader(shad, vshad);
glAttachShader(shad, fshad);
glLinkProgram(shad);
glGetShaderiv(shad, GL_LINK_STATUS, status);
if(status==GL_FALSE){
glGetShaderiv(shad, GL_INFO_LOG_LENGTH, len);
char[] error=new char[len];
glGetShaderInfoLog(shad, len, null, cast(char*)error);
writeln(error);
ok=false;
}


glGenVertexArrays(1, vao);
if(vao1){
writeln(Error: GL failed to assign vao id);
ok=false;
}
glBindVertexArray(vao);

glGenBuffers(1, vbo);
if(vbo1){
writeln(Error: GL failed to assign vbo id);
ok=false;
}
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, v.length * GL_FLOAT.sizeof, v[0],
GL_STATIC_DRAW);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, cast(void*)voff);

glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}

public void draw(){
glUseProgram(shad);

writeln(glGetAttribLocation(shad, pos));//prints 1

glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);


glUseProgram(0);
}
}

//__

the code for setting up openGL3 is:


import std.stdio;
import derelict.sdl2.sdl;
import derelict.opengl3.gl3;

import EventHub;
import ExposeApp;

pragma(lib, DerelictUtil.lib);
pragma(lib, DerelictSDL2.lib);
pragma(lib, DerelictGL3.lib);


class App{
private ExposeApp funcPtrs;
private EventHub ehub;
private SDL_Window *win;
private SDL_GLContext context;
private int w=600, h=480, fov=55;
private bool running=true;

public this(){
if(!initSDL()){
writeln(Error initializing SDL);
SDL_Quit();
}
initGL();

funcPtrs=new ExposeApp();
funcPtrs.stop=stopLoop;
funcPtrs.grabMouse=grabMouse;
funcPtrs.releaseMouse=releaseMouse;
ehub=new EventHub(funcPtrs);


while(running){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

ehub.tick();

SDL_GL_SwapWindow(win);
}


SDL_GL_DeleteContext(context);
SDL_DestroyWindow(win);
SDL_Quit();
}

private void stopLoop(){
running=false;
}
private void grabMouse(){
SDL_ShowCursor(SDL_DISABLE);
SDL_SetWindowGrab(win, SDL_TRUE);
}
private void releaseMouse(){
SDL_ShowCursor(SDL_ENABLE);
SDL_SetWindowGrab(win, SDL_FALSE);
}
private bool initSDL(){
if(SDL_Init(SDL_INIT_VIDEO) 0){
writefln(Error initializing SDL);
SDL_Quit();
return false;
}

SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);

win=SDL_CreateWindow(3Doodle, SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED, w, h, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN);
if(!win){
writefln(Error creating SDL window);
SDL_Quit();
return false;
}

context=SDL_GL_CreateContext(win);
SDL_GL_SetSwapInterval(1);

DerelictGL3.reload();

return true;
}
private void initGL(){
resize(w, h);

glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);

glDepthFunc(GL_LEQUAL);

glClearColor(0.0, 0.0, 0.0, 1.0);
glClearDepth(1.0);

glCullFace(GL_BACK);
glFrontFace(GL_CCW);

}
private void resize(int w, int h){
//this will contain the makings of the projection matrix, which we go
into next tut
glViewport(0, 0, w, h);
}
}


void main(){
try{
DerelictSDL2.load();
}catch(Exception e){
writeln(Error loading SDL2 lib);
}
try{
DerelictGL3.load();
}catch(Exception e){
writeln(Error 

variadic mixin templates and other stuff

2012-04-20 Thread Martin Drasar
Hi,

I am migrating a C++ project to D and I have hit a roadblock that I hope
you might help me with.

My code is heavily inspired by the COM architecture, so I have naturally
take a look at std/c/windows/com.d, just to find out that it does not
contain all I need.

In the C++ code I have several interfaces and a class. The class
inherits from these interfaces, exposes some of them and it is possible
to get one interface from another using the QueryInterface function by
supplying correct GUID:

class C : IA, IB, IC
{
  EXPOSE_INTERFACE(IA, IC);
  ...
}

where EXPOSE_INTERFACE is macro that expands to something like this:

void QueryInterface (IComponent** comp, GUID* guid)
{
  ...
  if (guid == IAGuid) *comp = ...some casting
  if (guid == IBGuid) *comp = ...some casting
  ...
}

So I was thinking that in D I could use mixin templates with variadic
arguments, so I tried something like that:

string interfaceGuid(string ifaceName)
{
  return ifaceName ~ Guid;
}

mixin template EXPOSE_INTERFACE(string ifaceName)
{
  if (mixin(interfaceGuid(ifaceName)) == guid) { ... some casting }
}

mixin template EXPOSE_INTERFACES(T...)(T args)
{
  void QueryInterface(ref IComponent comp, string guid)
  {
foreach (arg; args)
{
  mixin EXPOSE_INTERFACE!arg;
}
  }
}

But I got this:

component.d(8): Declaration expected, not 'if'
component.d(15): no identifier for declarator args
component.d(15): semicolon expected, not ')'
component.d(15): Declaration expected, not ')'
component.d(19): unrecognized declaration

Then I got confused and realized that my D is as sharp as is my German -
studied it for some time, but still has a problem to order a bread in a
store...

My questions are following:
- can mixin templates be used this way?
- why are they complaining?
- is there a better way to do this other than reproducing C macros?

Thanks,
Martin


Re: Allow empty field function arguments for default?

2012-04-20 Thread bearophile

ixid:


fun( , 4, ); //Modifies b
fun( , , 5); //Modifies c

for when you want to call fun with other fields not being 
default? This would seem more flexible and pretty clear what is 
intended.


I think that for the programmer's eye it's easy to miss one or 
more of those commas, when reading code. So to me something like 
this seems significantly less bug-prone:


fun(void, 4, void); // Modifies b
fun(void, void, 5); // Modifies c

Bye,
bearophile


Re: Operator overloading

2012-04-20 Thread Xan
On Thursday, 19 April 2012 at 20:59:05 UTC, Jonathan M Davis 
wrote:

On Thursday, April 19, 2012 21:14:43 Xan wrote:

Hi, I read http://dlang.org/operatoroverloading.html but in my
code it does not work. I tried to overload '*' binary operator 
in

my class Algorisme:

[...]
class Algorisme(U,V) {
string nom;
uint versio;
alias V function (U) Funcio;
Funcio funcio;

this(string nom, uint versio, Funcio funcio) {
try {
this.nom = nom;
this.versio = versio;
this.funcio = funcio;
}
catch {
writeln(Error);
}
}

string toString() {
return format(%s (versió %s): %s - %s, nom, versio,
typeid(U), typeid(V));
}

Algorisme(U, V) opBinary(string op) (Algorisme(U, V) alg) {
static if (op == '*') return new Algorisme(U,V)(composició,
this.versio+alg.versio, this.funcio);
}

}
[...]

but I receive these errors:

$ gdmd-4.6 algorisme.d
algorisme.d:31: function declaration without return type. (Note
that constructors are always named 'this')
algorisme.d:31: no identifier for declarator Algorisme(U, V)
algorisme.d:31: semicolon expected following function 
declaration

algorisme.d:31: function declaration without return type. (Note
that constructors are always named 'this')
algorisme.d:31: function declaration without return type. (Note
that constructors are always named 'this')
algorisme.d:31: found 'alg' when expecting ')'
algorisme.d:31: no identifier for declarator
opBinary(Algorisme(U, V))
algorisme.d:31: semicolon expected following function 
declaration

algorisme.d:31: Declaration expected, not ')'
algorisme.d:35: unrecognized declaration


Why it fails?
Anyone could help me?


Use a template constraint rather than a static if. As it 
stands, any operator
other than * will result in a function with no return 
statement.


Algorisme opBinary(string op)(Algorisme alg)
 if(op == *)
{
 return new Algorisme(composició, this.versio+alg.versio, 
this.funcio);

}

- Jonathan M Davis


Thanks, Jonathan. I suppose with 'if' (dynamic), it generates 
Exception if we call with other operator than '*', isn't?


Thanks,
Xan.


Re: variadic mixin templates and other stuff

2012-04-20 Thread Timon Gehr

On 04/20/2012 03:23 PM, Martin Drasar wrote:

Hi,

I am migrating a C++ project to D and I have hit a roadblock that I hope
you might help me with.

My code is heavily inspired by the COM architecture, so I have naturally
take a look at std/c/windows/com.d, just to find out that it does not
contain all I need.

In the C++ code I have several interfaces and a class. The class
inherits from these interfaces, exposes some of them and it is possible
to get one interface from another using the QueryInterface function by
supplying correct GUID:

class C : IA, IB, IC
{
   EXPOSE_INTERFACE(IA, IC);
   ...
}

where EXPOSE_INTERFACE is macro that expands to something like this:

void QueryInterface (IComponent** comp, GUID* guid)
{
   ...
   if (guid == IAGuid) *comp = ...some casting
   if (guid == IBGuid) *comp = ...some casting
   ...
}

So I was thinking that in D I could use mixin templates with variadic
arguments, so I tried something like that:

string interfaceGuid(string ifaceName)
{
   return ifaceName ~ Guid;
}

mixin template EXPOSE_INTERFACE(string ifaceName)
{
   if (mixin(interfaceGuid(ifaceName)) == guid) { ... some casting }
}

mixin template EXPOSE_INTERFACES(T...)(T args)
{
   void QueryInterface(ref IComponent comp, string guid)
   {
 foreach (arg; args)
 {
   mixin EXPOSE_INTERFACE!arg;
 }
   }
}

But I got this:

component.d(8): Declaration expected, not 'if'
component.d(15): no identifier for declarator args
component.d(15): semicolon expected, not ')'
component.d(15): Declaration expected, not ')'
component.d(19): unrecognized declaration

Then I got confused and realized that my D is as sharp as is my German -
studied it for some time, but still has a problem to order a bread in a
store...

My questions are following:
- can mixin templates be used this way?


They can only mixin declarations.


- why are they complaining?


Because if is a statement and not a declaration.


- is there a better way to do this other than reproducing C macros?



Inline EXPOSE_INTERFACE into EXPOSE_INTERFACES and it'll work.


Re: Operator overloading

2012-04-20 Thread Xan

What fails if I want to define this:

Algorisme!(T,V) opBinary(string op)(Algorisme!(T,U) alg) {
if (op==*) {
//fer la funció composicio
			return new Algorisme!(T,V)(Composició de ~this.nom ~  i  
~ alg.nom, 1, function(T t) { return this.funcio(alg.funcio(t)); 
} );

}
}

}


within my
class Algorisme(U,V) {
string nom;
uint versio;
alias V function (U) Funcio;
Funcio funcio;
...
}

?


I want to combine Algorisme(U,V) and Algorisme(T,V) with 
operator. Is it possible?


The errors I get are:

 gdmd-4.6 algorisme
algorisme.d:32: Error: undefined identifier T, did you mean 
variable E?
algorisme.d:51: Error: 'alg' is not of arithmetic type, it is a 
algorisme.Algorisme!(int,int).Algorisme
algorisme.d:51: Error: 'alg2' is not of arithmetic type, it is a 
algorisme.Algorisme!(int,int).Algorisme




Thanks in advance,
Xan.



Re: Operator overloading

2012-04-20 Thread Dmitry Olshansky

On 20.04.2012 18:10, Xan wrote:

What fails if I want to define this:

Algorisme!(T,V) opBinary(string op)(Algorisme!(T,U) alg) {


 Algorisme!(T,V) opBinary(string op, T)(Algorisme!(T,U) alg) {

You need to name what T is and that is *sometype*. Anyway I suggest 
getting a decent book (TDPL).



if (op==*) {


static if is conceptually and technically better here.


--
Dmitry Olshansky


Re: Operator overloading

2012-04-20 Thread Xan

On Friday, 20 April 2012 at 14:10:31 UTC, Xan wrote:

What fails if I want to define this:

Algorisme!(T,V) opBinary(string op)(Algorisme!(T,U) alg) {
if (op==*) {
//fer la funció composicio
			return new Algorisme!(T,V)(Composició de ~this.nom ~  i 
 ~ alg.nom, 1, function(T t) { return 
this.funcio(alg.funcio(t)); } );

}
}

}


within my
class Algorisme(U,V) {
string nom;
uint versio;
alias V function (U) Funcio;
Funcio funcio;
...
}

?


I want to combine Algorisme(U,V) and Algorisme(T,V) with 
operator. Is it possible?


The errors I get are:

 gdmd-4.6 algorisme
algorisme.d:32: Error: undefined identifier T, did you mean 
variable E?
algorisme.d:51: Error: 'alg' is not of arithmetic type, it is a 
algorisme.Algorisme!(int,int).Algorisme
algorisme.d:51: Error: 'alg2' is not of arithmetic type, it is 
a algorisme.Algorisme!(int,int).Algorisme




Thanks in advance,
Xan.


The full code is here: https://gist.github.com/2429005
(I put the code out of the class and I drop one error)


Re: variadic mixin templates and other stuff

2012-04-20 Thread Martin Drasar
On 20.4.2012 16:09, Timon Gehr wrote:

Thanks Timon for the answer.

 My questions are following:
 - can mixin templates be used this way?
 
 They can only mixin declarations.
 
 - why are they complaining?
 
 Because if is a statement and not a declaration.

Ok.

 - is there a better way to do this other than reproducing C macros?

 
 Inline EXPOSE_INTERFACE into EXPOSE_INTERFACES and it'll work.

I tried but it still refuses to compile:

string interfaceGuid(string ifaceName)
{
  return ifaceName ~ Guid;
}

mixin template EXPOSE_INTERFACES(T...)(T args)
{
  void QueryInterface(ref IComponent comp, string guid)
  {
foreach (arg; args)
{
  if (mixin(interfaceGuid(arg)) == guid) {}
}
  }
}

component.d(6): members of template declaration expected
component.d(6): Declaration expected, not '('
component.d(10): no identifier for declarator args
component.d(10): semicolon expected, not ')'
component.d(10): Declaration expected, not ')'

I am compiling it with dmd v2.058.

Martin


Re: Operator overloading

2012-04-20 Thread Xan

On Friday, 20 April 2012 at 14:18:37 UTC, Dmitry Olshansky wrote:

On 20.04.2012 18:10, Xan wrote:

What fails if I want to define this:

Algorisme!(T,V) opBinary(string op)(Algorisme!(T,U) alg) {


 Algorisme!(T,V) opBinary(string op, T)(Algorisme!(T,U) alg) {

You need to name what T is and that is *sometype*. Anyway I 
suggest getting a decent book (TDPL).



if (op==*) {


static if is conceptually and technically better here.



Thanks, Dmitry, for your suggestions, but it does not work too:

$ gdmd-4.6 algorisme
algorisme.d:54: Error: 'alg' is not of arithmetic type, it is a 
algorisme.Algorisme!(int,int).Algorisme
algorisme.d:54: Error: 'alg2' is not of arithmetic type, it is a 
algorisme.Algorisme!(int,int).Algorisme



I update de gist: https://gist.github.com/2429005

By the other hand, is there any way to put the definition of 
operator * in the class (not out like I have now)?



Thanks,
Xan.


primitive type operator overload

2012-04-20 Thread dominic jones

Hello,

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


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

but have no idea how to do it. Something similar(?) is already 
implemented in the language, i.e.


double x;
double[] y;
writeln(x + y);

but after searching the dmd2/src, what I found didn't offer any 
help.


-Dominic Jones


Re: primitive type operator overload

2012-04-20 Thread 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:

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

a.opBinary!(op)(b)
b.opBinaryRight!(op)(a)

so adding an inverse + operator inside myStruct is possible.

Bye,
bearophile


Re: variadic mixin templates and other stuff

2012-04-20 Thread John Chapman

On Friday, 20 April 2012 at 14:57:03 UTC, Martin Drasar wrote:

On 20.4.2012 16:09, Timon Gehr wrote:

I tried but it still refuses to compile:

string interfaceGuid(string ifaceName)
{
  return ifaceName ~ Guid;
}

mixin template EXPOSE_INTERFACES(T...)(T args)


Try this:

  mixin template EXPOSE_INTERFACES(T...)


{
  void QueryInterface(ref IComponent comp, string guid)
  {
foreach (arg; args)


and this:

  foreach (arg; T)


{
  if (mixin(interfaceGuid(arg)) == guid) {}
}
  }
}

component.d(6): members of template declaration expected
component.d(6): Declaration expected, not '('
component.d(10): no identifier for declarator args
component.d(10): semicolon expected, not ')'
component.d(10): Declaration expected, not ')'

I am compiling it with dmd v2.058.

Martin


John


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: Operator overloading

2012-04-20 Thread Jonathan M Davis
On Friday, April 20, 2012 15:37:57 Xan wrote:
 Thanks, Jonathan. I suppose with 'if' (dynamic), it generates
 Exception if we call with other operator than '*', isn't?

Exception? No. You get a compilation error. You should read

http://dlang.org/template.html#Constraint
http://dlang.org/version.html#staticif

Template constraints are used to indicate what will and won't compile with a 
template and can be used to overload templates.

For instance, with

auto opBinary(string op)(MyType mt)
 if(op == + || op == -)
{...}

auto opBinary(string op)(MyType mt)
 if(op == * || op == /)
{...}

the first function would work with + and -, whereas the second would work with 
* and /, and those are the only overloads for opBinary, and you tried to 
compile with another binary operator, you'd get a compilation error. It's 
quite typical to do stuff like

auto MyType(string op)(MyType mt)
 if(op == + || op == -' || op == * || op == /)
{
 return MyType(mixin(this.value  ~ op ~  mt.value));
}

You use static if when you want a section of code to be different based on some 
condition. So, you could do something like

auto MyType(string op)(MyType mt)
 if(op == + || op == -' || op == * || op == /)
{
 static if(op == /)
 enforce(mt.value != 0, Error: Division by zero!);
 
 return MyType(mixin(this.value  ~ op ~  mt.value));
}

The problem with your example

 Algorisme!(U,V) opBinary(string op)(Algorisme!(U,V) alg) {
 static if (op==*) return new Algorisme!(U,V)(composició, 
this.versio+alg.versio, this.funcio);
 }

what happens when you try and compile with an operator other than *. When it's 
*, you end up with a function looking like

 Algorisme!(U,V) opBinary(string op)(Algorisme!(U,V) alg) {
 return new Algorisme!(U,V)(composició, 
this.versio+alg.versio, this.funcio);
 }

but when it's anything else, you get a function looking like

 Algorisme!(U,V) opBinary(string op)(Algorisme!(U,V) alg) {
 }

It has no return value and won't compile, giving you an error about returning 
void or something similar.

If at all possible, you should always have a template constraint on a template 
which restricts it to arguments which will work with that template. You can 
then further specialize sections of it using static if, but if you use static 
if only, then you get nasty compilation errors when you misuse the template. 
Also, you can't overload templates based on static if, so if you need to have 
mulitple overloads of a template, you _need_ to use template constraints.

- Jonathan M Davis


Re: primitive type operator overload

2012-04-20 Thread H. S. Teoh
On Fri, Apr 20, 2012 at 07:12:41PM +0200, Mafi wrote:
 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++).

UFCS only kicks in if no matching method is found for the given type. So
UFCS can be used to provide default implementations for when an
operator is not defined for a given type, but the operator defined by
the type takes precedence over UFCS.


T

-- 
How are you doing? Doing what?


Re: Operator overloading

2012-04-20 Thread Dmitry Olshansky

On 20.04.2012 19:14, Xan wrote:

On Friday, 20 April 2012 at 14:18:37 UTC, Dmitry Olshansky wrote:

On 20.04.2012 18:10, Xan wrote:

What fails if I want to define this:

Algorisme!(T,V) opBinary(string op)(Algorisme!(T,U) alg) {


Algorisme!(T,V) opBinary(string op, T)(Algorisme!(T,U) alg) {

You need to name what T is and that is *sometype*. Anyway I suggest
getting a decent book (TDPL).


if (op==*) {


static if is conceptually and technically better here.



Thanks, Dmitry, for your suggestions, but it does not work too:

$ gdmd-4.6 algorisme
algorisme.d:54: Error: 'alg' is not of arithmetic type, it is a
algorisme.Algorisme!(int,int).Algorisme
algorisme.d:54: Error: 'alg2' is not of arithmetic type, it is a
algorisme.Algorisme!(int,int).Algorisme


I update de gist: https://gist.github.com/2429005

By the other hand, is there any way to put the definition of operator *
in the class (not out like I have now)?



it should be inside the class. Why would you put it outside and hope it 
work? What 'this' can refer to in free function?


Please read spec at the very least.
http://dlang.org/operatoroverloading.html



Thanks,
Xan.



--
Dmitry Olshansky


Re: Operator overloading

2012-04-20 Thread Xan

Yes, you're wright. So in.

But what fails?

I reveice these errors and I have no idea what fails!



Sorry, the errors are:

$ gdmd-4.6 algorisme.d
algorisme.d:35: Error: 'this' is only defined in non-static 
member functions, not __funcliteral1
algorisme.d:35: Error: function 
algorisme.Algorisme!(int,int).Algorisme.opBinary!(*,int).opBinary.__funcliteral1 
cannot access frame of function 
algorisme.Algorisme!(int,int).Algorisme.opBinary!(*,int).opBinary
algorisme.d:35: Error: function 
algorisme.Algorisme!(int,int).Algorisme.opBinary!(*,int).opBinary.__funcliteral1 
cannot access frame of function 
algorisme.Algorisme!(int,int).Algorisme.opBinary!(*,int).opBinary
algorisme.d:35: Error: function 
algorisme.Algorisme!(int,int).Algorisme.opBinary!(*,int).opBinary.__funcliteral1 
cannot access frame of function 
algorisme.Algorisme!(int,int).Algorisme.opBinary!(*,int).opBinary
algorisme.d:35: Error: constructor 
algorisme.Algorisme!(int,int).Algorisme.this (string nom, uint 
versio, int function(int) funcio) is not callable using argument 
types (string,int,_error_ function(int t) nothrow @system)
algorisme.d:35: Error: cannot implicitly convert expression 
(__funcliteral1) of type _error_ function(int t) nothrow @system 
to int function(int)
algorisme.d:52: Error: template instance 
algorisme.Algorisme!(int,int).Algorisme.opBinary!(*,int) error 
instantiating




I update the gist: https://gist.github.com/2429005


Re: Operator overloading

2012-04-20 Thread Xan

On Friday, 20 April 2012 at 18:47:14 UTC, Dmitry Olshansky wrote:

On 20.04.2012 19:14, Xan wrote:
On Friday, 20 April 2012 at 14:18:37 UTC, Dmitry Olshansky 
wrote:

On 20.04.2012 18:10, Xan wrote:

What fails if I want to define this:

Algorisme!(T,V) opBinary(string op)(Algorisme!(T,U) alg) {


Algorisme!(T,V) opBinary(string op, T)(Algorisme!(T,U) alg) {

You need to name what T is and that is *sometype*. Anyway I 
suggest

getting a decent book (TDPL).


if (op==*) {


static if is conceptually and technically better here.



Thanks, Dmitry, for your suggestions, but it does not work too:

$ gdmd-4.6 algorisme
algorisme.d:54: Error: 'alg' is not of arithmetic type, it is a
algorisme.Algorisme!(int,int).Algorisme
algorisme.d:54: Error: 'alg2' is not of arithmetic type, it is 
a

algorisme.Algorisme!(int,int).Algorisme


I update de gist: https://gist.github.com/2429005

By the other hand, is there any way to put the definition of 
operator *

in the class (not out like I have now)?



it should be inside the class. Why would you put it outside and 
hope it work? What 'this' can refer to in free function?


Yes, you're wright. So in.

But what fails?

I reveice these errors and I have no idea what fails!




Please read spec at the very least.
http://dlang.org/operatoroverloading.html


I read it. It served me as guide. But not I'm in trouble
Can you help me fixing the bug!

Regards,
Xan.






Thanks,
Xan.






Re: Operator overloading

2012-04-20 Thread Dmitry Olshansky

On 20.04.2012 23:33, Xan wrote:

Yes, you're wright. So in.

But what fails?

I reveice these errors and I have no idea what fails!



Sorry, the errors are:

$ gdmd-4.6 algorisme.d
algorisme.d:35: Error: 'this' is only defined in non-static member
functions, not __funcliteral1


Easy - _this_ inside of
 function (T t) { return this.funcio(alg.funcio(t)); }

Is not going to fly because there is no way to store _this_ in 
function, use delegates (this is a context and it has to be copied - 
use delegates). But then you'd have to change to delegate everywhere.


(and there is toDelegate function in std.functional, that converts 
function to delegate)



algorisme.d:35: Error: function
algorisme.Algorisme!(int,int).Algorisme.opBinary!(*,int).opBinary.__funcliteral1
cannot access frame of function
algorisme.Algorisme!(int,int).Algorisme.opBinary!(*,int).opBinary
algorisme.d:35: Error: function
algorisme.Algorisme!(int,int).Algorisme.opBinary!(*,int).opBinary.__funcliteral1
cannot access frame of function
algorisme.Algorisme!(int,int).Algorisme.opBinary!(*,int).opBinary
algorisme.d:35: Error: function
algorisme.Algorisme!(int,int).Algorisme.opBinary!(*,int).opBinary.__funcliteral1
cannot access frame of function
algorisme.Algorisme!(int,int).Algorisme.opBinary!(*,int).opBinary
algorisme.d:35: Error: constructor
algorisme.Algorisme!(int,int).Algorisme.this (string nom, uint versio,
int function(int) funcio) is not callable using argument types
(string,int,_error_ function(int t) nothrow @system)
algorisme.d:35: Error: cannot implicitly convert expression
(__funcliteral1) of type _error_ function(int t) nothrow @system to int
function(int)
algorisme.d:52: Error: template instance
algorisme.Algorisme!(int,int).Algorisme.opBinary!(*,int) error
instantiating



I update the gist: https://gist.github.com/2429005



--
Dmitry Olshansky


Formatting dates in std.datetime?

2012-04-20 Thread H. S. Teoh
Is there a way to format std.datetime.Date objects with a custom format
string? In particular, I'd like to reuse month short names defined in
std.datetime, but it appears that the names are private. I'd really
rather not duplicate them by hand, if there's a way to get them.

Alternatively, if there's a date formatting function that lets you use
strftime-like format strings, that would work too.


T

-- 
Век живи - век учись. А дураком помрёшь.


Re: Formatting dates in std.datetime?

2012-04-20 Thread Jonathan M Davis
On Friday, April 20, 2012 13:29:34 H. S. Teoh wrote:
 Is there a way to format std.datetime.Date objects with a custom format
 string? In particular, I'd like to reuse month short names defined in
 std.datetime, but it appears that the names are private. I'd really
 rather not duplicate them by hand, if there's a way to get them.
 
 Alternatively, if there's a date formatting function that lets you use
 strftime-like format strings, that would work too.

Such functionality does not currently exist. It was too much to design it on 
top of everything else when std.datetime was initially put up for review. 
There was a lot to it already. There has been some discussion on how to design 
the format strings ( 
http://forum.dlang.org/thread/mailman.1806.1324525352.24802.digitalmars-
d...@puremagic.com ), but nothing has been actually added to std.datetime yet. 
My 
proposed format is very good, I think, but the examples that I chose were 
nasty enough that a number of people weren't all that happy with it. Stewart's 
proposal is more user-friendly for the basic stuff, but I don't think that it 
does as well with the more complicated stuff. I haven't decided what I'm going 
to do about it yet. It's on my TODO list.

As for the month names, they're private and will stay that way. Really, 
they're an internationalization issue, and having them in the first place was 
already debatable (they're there primarily because of toSimpleString, which 
came from Boost and they almost didn't end up in there at all).

Once the custom format string stuff has been sorted out, it will end up with a 
way to indicate that you want either the English abbreviations (which 
std.datetime currently uses) or the locale-specific ones, but that's the 
closest that you're ever going to get to have access to them without copying 
them yourself.

- Jonathan M Davis


Derelict2 openGL3 issues

2012-04-20 Thread Stephen Jones
David suggested I start a new thread rather than asking on an old 
existing one (probably wants to get rid of me). So what I have 
done is created the most parred back, hello world type program 
that could run under the GL3 enforcement policies dictated by 
Derelict2. Fixed function pipeline is out. The vertex positions 
fit within clip space so there is no need to be sending 
projection, view or model matricies to the vertex shader, nor any 
need therein to be altering the vertex positions; they simply get 
set to gl_Position. The fragment shader assigns red to 
gl_FragColor. I have read somewhere that vaos are required for 
GL3 and that vbos hang pointlessly without the chaperone of a 
vao, regardless, the code can draw either vao or vbo depending on 
which draw function is not commented out in the loop. The problem 
is, however, that neither function draws anything. Yet all the 
initializations are returning true; the SDL window pops up and 
gets cleared to black. Is there a problem with Derelict2?



import std.stdio;
import std.string;
import std.conv;
import derelict.sdl2.sdl;
import derelict.opengl3.gl3;

pragma(lib, DerelictUtil.lib);
pragma(lib, DerelictSDL2.lib);
pragma(lib, DerelictGL3.lib);

SDL_Window *win;
SDL_GLContext context;
int w=800, h=600;
bool running=true;
int shader = 0;
uint vao=0, vbo=0;

bool loadLibs(){
try{
DerelictSDL2.load();
}catch(Exception e){
writeln(Error loading SDL2 lib);
return false;
}
try{
DerelictGL3.load();
}catch(Exception e){
writeln(Error loading GL3 lib);
return false;
}

return true;
}
bool initSDL(){
if(SDL_Init(SDL_INIT_VIDEO)  0){
writefln(Error initializing SDL);
return false;
}
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);

	win=SDL_CreateWindow(3Doodle, SDL_WINDOWPOS_CENTERED, 
SDL_WINDOWPOS_CENTERED, w, h, SDL_WINDOW_OPENGL | 
SDL_WINDOW_SHOWN);

if(!win){
writefln(Error creating SDL window);
SDL_Quit();
return false;
}

context=SDL_GL_CreateContext(win);
SDL_GL_SetSwapInterval(1);

DerelictGL3.reload();

return true;
}
bool initGL(){
glClearColor(0.0, 0.0, 0.0, 1.0);
glViewport(0, 0, w, h);

return true;
}
bool initShaders(){
const string vshader=
#version 330
layout(location = 0) in vec4 pos;
void main(void)
{
gl_Position = pos;
}
;
const string fshader=
#version 330
void main(void)
{
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
;

shader=glCreateProgram();
if(shader == 0){
writeln(Error: GL did not assigh main shader program id);
return false;
}
int vshad=glCreateShader(GL_VERTEX_SHADER);
const char *vptr=toStringz(vshader);
glShaderSource(vshad, 1, vptr, null);
glCompileShader(vshad); 
int status, len;
glGetShaderiv(vshad, GL_COMPILE_STATUS, status);
if(status==GL_FALSE){
glGetShaderiv(vshad, GL_INFO_LOG_LENGTH, len);
char[] error=new char[len];
glGetShaderInfoLog(vshad, len, null, cast(char*)error);
writeln(error);
return false;
}
int fshad=glCreateShader(GL_FRAGMENT_SHADER);
const char *fptr=toStringz(fshader);
glShaderSource(fshad, 1, fptr, null);
glCompileShader(fshad); 
glGetShaderiv(vshad, GL_COMPILE_STATUS, status);
if(status==GL_FALSE){
glGetShaderiv(fshad, GL_INFO_LOG_LENGTH, len);
char[] error=new char[len];
glGetShaderInfoLog(fshad, len, null, cast(char*)error);
writeln(error);
return false;
}
glAttachShader(shader, vshad);
glAttachShader(shader, fshad);
glLinkProgram(shader);
glGetShaderiv(shader, GL_LINK_STATUS, status);
if(status==GL_FALSE){
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, len);
char[] error=new char[len];
glGetShaderInfoLog(shader, len, null, cast(char*)error);
writeln(error);
return false;
}

return true;
}
bool initVAO(){
const float[] v = [ 0.75f, 0.75f, 0.0f, 1.0f,
0.75f, -0.75f, 0.0f, 1.0f,
-0.75f, -0.75f, 0.0f, 1.0f];
glGenVertexArrays(1, vao);
if(vao1){
writeln(Error: GL failed to assign vao id);
return false;
}

glBindVertexArray(vao);

glGenBuffers(1, vbo);
if(vbo1){