April 17, 2012
Off-topic, could can I define toString having this structure:

<Name of the function> (versió <version number>): <Domain> -> <Range>, <code of the function>

?

(For example, in https://gist.github.com/2394274 I want that Doblar displays as:
Doblar (versió 1): int -> int, { return 2 * a; }


Thanks a lot,
Xan.
April 17, 2012
On Tuesday, 17 April 2012 at 14:57:18 UTC, Xan wrote:
> On Tuesday, 17 April 2012 at 01:31:43 UTC, Kenji Hara wrote:
>> On Monday, 16 April 2012 at 18:48:52 UTC, Xan wrote:
>>> On Sunday, 15 April 2012 at 19:30:27 UTC, Ali Çehreli wrote:
>>>> On 04/15/2012 11:39 AM, Xan wrote:
>>>> > On Sunday, 15 April 2012 at 11:23:37 UTC, John Chapman wrote:
>>>> >> On Sunday, 15 April 2012 at 11:16:43 UTC, Xan wrote:
>>>> >>>
>>>> >>> int main(string [] args)
>>>> >>> {
>>>> >>> auto alg = Algorisme!(int,int);
>>>> >>
>>>> >> Should be:
>>>> >> auto alg = new Algorisme!(int, int);
>>>> >>
>>>> >>> alg.nom = "Doblar";
>>>> >>> alg.versio = 1;
>>>> >>> alg.funcio = (int a) {return 2*a};
>>>> >>
>>>> >> Should be:
>>>> >> alg.funcio = (int a) { return 2 * a; };
>>>> >> or:
>>>> >> alg.funcio = a => 2 * a;
>>>> >>
>>>> >>> }
>>>> >
>>>> >
>>>> > It does not work:
>>>> >
>>>> > $ gdmd-4.6 algorisme.d
>>>> > algorisme.d:18: Error: variable algorisme.main.alg voids have
>>>> no value
>>>> > algorisme.d:18: Error: expression class Algorisme is void and
>>>> has no value
>>>> >
>>>> > with the code https://gist.github.com/2394274
>>>> >
>>>> > What fails now?
>>>> >
>>>> > Thanks,
>>>> > Xan.
>>>>
>>>> Your code is still missing 'new':
>>>>
>>>> 	auto alg = new Algorisme!(int, int);
>>>
>>> With only this change, I receive this error:
>>>
>>> $ gdmd-4.6 algorisme.d
>>> algorisme.d:21: Error: cannot implicitly convert expression (__dgliteral1) of type int delegate(int a) pure nothrow to int function(int)
>>>
>>>>
>>>> Unrelated recommendations:
>>>>
>>>> - Return 0 from main() for successful exit, anything else by convention means some sort of error.
>>>>
>>>> - Take advantage of constructors (and 'alias') to simplify syntax and risk of bugs:
>>>>
>>>> import std.conv, std.stdio, std.stream, std.string;
>>>> import std.socket, std.socketstream;
>>>> import std.datetime;
>>>>
>>>> class Algorisme(U,V) {
>>>>  string nom;
>>>>  uint versio;
>>>>  alias V function (U) Funcio;
>>>>  Funcio funcio;
>>>>
>>>>  this(string nom, uint versio, Funcio funcio)
>>>>  {
>>>>      this.nom = nom;
>>>>      this.versio = versio;
>>>>      this.funcio = funcio;
>>>>  }
>>>> }
>>>>
>>>> int main(string [] args)
>>>> {
>>>>  alias Algorisme!(int, int) MeuAlgorism;
>>>>  auto alg = new MeuAlgorism("Doblar", 1,
>>>>                             (int a) { return 2 * a; });
>>>>
>>>>  return 0;
>>>> }
>>>>
>>>> Ali
>>>
>>> With all of your suggestion [https://gist.github.com/2394274], I get:
>>>
>>> $ gdmd-4.6 algorisme.d
>>> algorisme.d:30: Error: constructor algorisme.Algorisme!(int,int).Algorisme.this (string nom, uint versio, int function(int) funcio) is not callable using argument types (string,int,int delegate(int a) pure nothrow)
>>> algorisme.d:30: Error: cannot implicitly convert expression (__dgliteral1) of type int delegate(int a) pure nothrow to int function(int)
>>> algorisme.d:27: Error: function D main has no return statement, but is expected to return a value of type int
>>>
>>>
>>> What fails?
>>>
>>> PS: Thanks for your recommendations...
>>> PPS: By the other hand, I see you have learned catalan ("MeuAlgorisme"?) ;-)
>>
>> Problem may be here:
>>
>>> alg.funcio = (int a) { return 2 * a; };
>>
>> 2.057 and earlier (You may use gdc 2.057 and command line wrapper gdmd), function literal always deduced as 'delegate'. So this expression raises an error about type mismatching Lhs of 'int function(int)' and  Rhs of 'int delegate(int) pure nothrow'.
>>
>> Then, specifying explicit 'function' will resolve issue:
>>
>>  alg.funcio = function(int a) { return 2 * a; };
>>
>> Bye.
>>
>> Kenji Hara
>
> Thanks, Kenji. If I change function to delegate in declaration of field, it works too. What do you recommend to have delegates or functions? What are the benefits and ...
>
> Thanks,
> Xan.

For an example, you can't use function-pointer to access non-static methods, while with delegates you can. You can see some examples on http://www.dlang.org (Languate Reference).
April 17, 2012
On Tuesday, 17 April 2012 at 15:21:30 UTC, Dejan Lekic wrote:
> On Tuesday, 17 April 2012 at 14:57:18 UTC, Xan wrote:
>> On Tuesday, 17 April 2012 at 01:31:43 UTC, Kenji Hara wrote:
>>> On Monday, 16 April 2012 at 18:48:52 UTC, Xan wrote:
>>>> On Sunday, 15 April 2012 at 19:30:27 UTC, Ali Çehreli wrote:
>>>>> On 04/15/2012 11:39 AM, Xan wrote:
>>>>> > On Sunday, 15 April 2012 at 11:23:37 UTC, John Chapman wrote:
>>>>> >> On Sunday, 15 April 2012 at 11:16:43 UTC, Xan wrote:
>>>>> >>>
>>>>> >>> int main(string [] args)
>>>>> >>> {
>>>>> >>> auto alg = Algorisme!(int,int);
>>>>> >>
>>>>> >> Should be:
>>>>> >> auto alg = new Algorisme!(int, int);
>>>>> >>
>>>>> >>> alg.nom = "Doblar";
>>>>> >>> alg.versio = 1;
>>>>> >>> alg.funcio = (int a) {return 2*a};
>>>>> >>
>>>>> >> Should be:
>>>>> >> alg.funcio = (int a) { return 2 * a; };
>>>>> >> or:
>>>>> >> alg.funcio = a => 2 * a;
>>>>> >>
>>>>> >>> }
>>>>> >
>>>>> >
>>>>> > It does not work:
>>>>> >
>>>>> > $ gdmd-4.6 algorisme.d
>>>>> > algorisme.d:18: Error: variable algorisme.main.alg voids have
>>>>> no value
>>>>> > algorisme.d:18: Error: expression class Algorisme is void and
>>>>> has no value
>>>>> >
>>>>> > with the code https://gist.github.com/2394274
>>>>> >
>>>>> > What fails now?
>>>>> >
>>>>> > Thanks,
>>>>> > Xan.
>>>>>
>>>>> Your code is still missing 'new':
>>>>>
>>>>> 	auto alg = new Algorisme!(int, int);
>>>>
>>>> With only this change, I receive this error:
>>>>
>>>> $ gdmd-4.6 algorisme.d
>>>> algorisme.d:21: Error: cannot implicitly convert expression (__dgliteral1) of type int delegate(int a) pure nothrow to int function(int)
>>>>
>>>>>
>>>>> Unrelated recommendations:
>>>>>
>>>>> - Return 0 from main() for successful exit, anything else by convention means some sort of error.
>>>>>
>>>>> - Take advantage of constructors (and 'alias') to simplify syntax and risk of bugs:
>>>>>
>>>>> import std.conv, std.stdio, std.stream, std.string;
>>>>> import std.socket, std.socketstream;
>>>>> import std.datetime;
>>>>>
>>>>> class Algorisme(U,V) {
>>>>> string nom;
>>>>> uint versio;
>>>>> alias V function (U) Funcio;
>>>>> Funcio funcio;
>>>>>
>>>>> this(string nom, uint versio, Funcio funcio)
>>>>> {
>>>>>     this.nom = nom;
>>>>>     this.versio = versio;
>>>>>     this.funcio = funcio;
>>>>> }
>>>>> }
>>>>>
>>>>> int main(string [] args)
>>>>> {
>>>>> alias Algorisme!(int, int) MeuAlgorism;
>>>>> auto alg = new MeuAlgorism("Doblar", 1,
>>>>>                            (int a) { return 2 * a; });
>>>>>
>>>>> return 0;
>>>>> }
>>>>>
>>>>> Ali
>>>>
>>>> With all of your suggestion [https://gist.github.com/2394274], I get:
>>>>
>>>> $ gdmd-4.6 algorisme.d
>>>> algorisme.d:30: Error: constructor algorisme.Algorisme!(int,int).Algorisme.this (string nom, uint versio, int function(int) funcio) is not callable using argument types (string,int,int delegate(int a) pure nothrow)
>>>> algorisme.d:30: Error: cannot implicitly convert expression (__dgliteral1) of type int delegate(int a) pure nothrow to int function(int)
>>>> algorisme.d:27: Error: function D main has no return statement, but is expected to return a value of type int
>>>>
>>>>
>>>> What fails?
>>>>
>>>> PS: Thanks for your recommendations...
>>>> PPS: By the other hand, I see you have learned catalan ("MeuAlgorisme"?) ;-)
>>>
>>> Problem may be here:
>>>
>>>> alg.funcio = (int a) { return 2 * a; };
>>>
>>> 2.057 and earlier (You may use gdc 2.057 and command line wrapper gdmd), function literal always deduced as 'delegate'. So this expression raises an error about type mismatching Lhs of 'int function(int)' and  Rhs of 'int delegate(int) pure nothrow'.
>>>
>>> Then, specifying explicit 'function' will resolve issue:
>>>
>>> alg.funcio = function(int a) { return 2 * a; };
>>>
>>> Bye.
>>>
>>> Kenji Hara
>>
>> Thanks, Kenji. If I change function to delegate in declaration of field, it works too. What do you recommend to have delegates or functions? What are the benefits and ...
>>
>> Thanks,
>> Xan.
>
> For an example, you can't use function-pointer to access non-static methods, while with delegates you can. You can see some examples on http://www.dlang.org (Languate Reference).

So, I deduce it's better to use delegater than function?
April 17, 2012
On 04/17/2012 08:17 AM, Xan wrote:
> Off-topic, could can I define toString having this structure:
>
> <Name of the function> (versió <version number>): <Domain> -> <Range>,
> <code of the function>
>
> ?
>
> (For example, in https://gist.github.com/2394274 I want that Doblar
> displays as:
> Doblar (versió 1): int -> int, { return 2 * a; }
>
>
> Thanks a lot,
> Xan.

std.string.format is easy:

    format("%s%s", 42, "hello");

Ali
April 17, 2012
On Tuesday, 17 April 2012 at 15:30:36 UTC, Ali Çehreli wrote:
> On 04/17/2012 08:17 AM, Xan wrote:
>> Off-topic, could can I define toString having this structure:
>>
>> <Name of the function> (versió <version number>): <Domain> -> <Range>,
>> <code of the function>
>>
>> ?
>>
>> (For example, in https://gist.github.com/2394274 I want that Doblar
>> displays as:
>> Doblar (versió 1): int -> int, { return 2 * a; }
>>
>>
>> Thanks a lot,
>> Xan.
>
> std.string.format is easy:
>
>     format("%s%s", 42, "hello");
>
> Ali

How to get the "code" of a function or delegate

|___string toString() {
|___|___return format("%s (versió %s): Domini -> Recorregut, %s(x) = %s", nom, versio, nom, &funcio);

|___}

does not produce the desired result and &funcio without ampersand produces me an error.

So, my doubts are:
given a function:

- how can I get the domain
- how can I get the range
- how can I get the code of the function?

See https://gist.github.com/2394274

April 17, 2012
On 04/17/2012 08:42 AM, Xan wrote:

> How to get the "code" of a function or delegate
>
> |___string toString() {
> |___|___return format("%s (versió %s): Domini -> Recorregut, %s(x) =
> %s", nom, versio, nom, &funcio);
>
> |___}
>
> does not produce the desired result and &funcio without ampersand
> produces me an error.
>
> So, my doubts are:
> given a function:
>
> - how can I get the domain
> - how can I get the range

I did not understand those. :(

> - how can I get the code of the function?
>
> See https://gist.github.com/2394274
>

I don't think D has any help there. You can keep the function as a string yourself and convert to actual code at compile time with a string mixin. For that to happen, the function text may be an additional template parameter:

import std.conv, std.stdio, std.stream, std.string;
import std.socket, std.socketstream;
import std.datetime;

class Algorisme(U,V,string funcioText) {
	string nom;
	uint versio;
	alias V delegate (U) Funcio;
	Funcio funcio;


	this(string nom, uint versio) {
		this.nom = nom;
		this.versio = versio;
		this.funcio = mixin(funcioText);
	}

	string toString() {
            return format("%s (versió %s): Domini -> Recorregut, %s(x) = %s",
                          nom, versio, nom, funcioText);
	}
}


alias Algorisme!(int, int, "(int a) { return 2 * a; }") AlgorismeEnters;

void main(string [] args)
{

	auto alg = new AlgorismeEnters("Doblar", 1);
	writeln(alg);

}

Ali

April 17, 2012
On Tuesday, 17 April 2012 at 15:59:25 UTC, Ali Çehreli wrote:
> On 04/17/2012 08:42 AM, Xan wrote:
>
> > How to get the "code" of a function or delegate
> >
> > |___string toString() {
> > |___|___return format("%s (versió %s): Domini -> Recorregut,
> %s(x) =
> > %s", nom, versio, nom, &funcio);
> >
> > |___}
> >
> > does not produce the desired result and &funcio without
> ampersand
> > produces me an error.
> >
> > So, my doubts are:
> > given a function:
> >
> > - how can I get the domain
> > - how can I get the range
>
> I did not understand those. :(

Domain is the set of values that we pass to the function and Range is the set of Values which are returned by function.

V delegate (U) f;
f has Domain U and Range V

I want to "print" the type of "U" and "V".

Something like:

class Algorisme(U,V) {
	string nom;
	uint versio;
	alias V delegate (U) Funcio;
	Funcio funcio;


	this(string nom, uint versio, Funcio funcio) {
		this.nom = nom;
		this.versio = versio;
		this.funcio = funcio;
	}

	string toString() {
		return format("%s (versió %s): %s -> %s, %s(x) = %s", nom, versio, V, U, nom, &funcio);

	}
}


but I receive

algorisme.d:24: Error: type int has no value
algorisme.d:24: Error: type int has no value

when I call with Algorisme!(int, int) intead of receiving "int" and "int" as Domain and Range

>
> > - how can I get the code of the function?
> >
> > See https://gist.github.com/2394274
> >
>
> I don't think D has any help there. You can keep the function as a string yourself and convert to actual code at compile time with a string mixin. For that to happen, the function text may be an additional template parameter:
>
> import std.conv, std.stdio, std.stream, std.string;
> import std.socket, std.socketstream;
> import std.datetime;
>
> class Algorisme(U,V,string funcioText) {
> 	string nom;
> 	uint versio;
> 	alias V delegate (U) Funcio;
> 	Funcio funcio;
>
>
> 	this(string nom, uint versio) {
> 		this.nom = nom;
> 		this.versio = versio;
> 		this.funcio = mixin(funcioText);
> 	}
>
> 	string toString() {
>             return format("%s (versió %s): Domini -> Recorregut, %s(x) = %s",
>                           nom, versio, nom, funcioText);
> 	}
> }
>
>
> alias Algorisme!(int, int, "(int a) { return 2 * a; }") AlgorismeEnters;
>
> void main(string [] args)
> {
>
> 	auto alg = new AlgorismeEnters("Doblar", 1);
> 	writeln(alg);
>
> }
>
> Ali

It's ugly code. I think I could call some procedure like f.code (f is a function) to obtain the "code" how f is defined. But stricly in mathematical thinking it's not adequate, because more codes could result in the same (mathematical function): x + x is the double of x; and 2*x is too.

Perhaps if I change Algorisme and add the string field "code" and if there is any procedure to copy the 3rd argument in the constructor and pass as string in the 4th argument (in the constructor)

class Algorisme(U,V) {
|___string nom;
|___uint versio;
|___alias V delegate (U) Funcio;
|___Funcio funcio;
|___string code;


|___this(string nom, uint versio, Funcio funcio) {
|___|___this.nom = nom;
|___|___this.versio = versio;
|___|___this.funcio = funcio;
        this.code = funcio.WHAT PROCEDURE?;
|___}


Regards,
Xan.



April 17, 2012
On Tuesday, 17 April 2012 at 18:00:55 UTC, Xan wrote:
> On Tuesday, 17 April 2012 at 15:59:25 UTC, Ali Çehreli wrote:
>> On 04/17/2012 08:42 AM, Xan wrote:
>>
>> > How to get the "code" of a function or delegate
>> >
>> > |___string toString() {
>> > |___|___return format("%s (versió %s): Domini -> Recorregut,
>> %s(x) =
>> > %s", nom, versio, nom, &funcio);
>> >
>> > |___}
>> >
>> > does not produce the desired result and &funcio without
>> ampersand
>> > produces me an error.
>> >
>> > So, my doubts are:
>> > given a function:
>> >
>> > - how can I get the domain
>> > - how can I get the range
>>
>> I did not understand those. :(
>
> Domain is the set of values that we pass to the function and Range is the set of Values which are returned by function.
>
> V delegate (U) f;
> f has Domain U and Range V
>
> I want to "print" the type of "U" and "V".
>
> Something like:
>
> class Algorisme(U,V) {
> 	string nom;
> 	uint versio;
> 	alias V delegate (U) Funcio;
> 	Funcio funcio;
>
>
> 	this(string nom, uint versio, Funcio funcio) {
> 		this.nom = nom;
> 		this.versio = versio;
> 		this.funcio = funcio;
> 	}
>
> 	string toString() {
> 		return format("%s (versió %s): %s -> %s, %s(x) = %s", nom, versio, V, U, nom, &funcio);
>
> 	}
> }
>
>
> but I receive
>
> algorisme.d:24: Error: type int has no value
> algorisme.d:24: Error: type int has no value


Solved with typeid:

string toString() {
|___|___return format("%s (versió %s): %s -> %s, %s(x) = %s", nom, versio, typeid(V), typeid(U), nom, &funcio);

|___}


April 17, 2012
On Tuesday, 17 April 2012 at 18:00:55 UTC, Xan wrote:
> On Tuesday, 17 April 2012 at 15:59:25 UTC, Ali Çehreli wrote:
>> On 04/17/2012 08:42 AM, Xan wrote:
>>
>> > How to get the "code" of a function or delegate
>> >
>> > |___string toString() {
>> > |___|___return format("%s (versió %s): Domini -> Recorregut,
>> %s(x) =
>> > %s", nom, versio, nom, &funcio);
>> >
>> > |___}
>> >
>> > does not produce the desired result and &funcio without
>> ampersand
>> > produces me an error.
>> >
>> > So, my doubts are:
>> > given a function:
>> >
>> > - how can I get the domain
>> > - how can I get the range
>>
>> I did not understand those. :(
>
> Domain is the set of values that we pass to the function and Range is the set of Values which are returned by function.
>
> V delegate (U) f;
> f has Domain U and Range V
>
> I want to "print" the type of "U" and "V".
>
> Something like:
>
> class Algorisme(U,V) {
> 	string nom;
> 	uint versio;
> 	alias V delegate (U) Funcio;
> 	Funcio funcio;
>
>
> 	this(string nom, uint versio, Funcio funcio) {
> 		this.nom = nom;
> 		this.versio = versio;
> 		this.funcio = funcio;
> 	}
>
> 	string toString() {
> 		return format("%s (versió %s): %s -> %s, %s(x) = %s", nom, versio, V, U, nom, &funcio);
>
> 	}
> }
>
>
> but I receive
>
> algorisme.d:24: Error: type int has no value
> algorisme.d:24: Error: type int has no value
>
> when I call with Algorisme!(int, int) intead of receiving "int" and "int" as Domain and Range
>
>>
>> > - how can I get the code of the function?
>> >
>> > See https://gist.github.com/2394274
>> >
>>
>> I don't think D has any help there. You can keep the function as a string yourself and convert to actual code at compile time with a string mixin. For that to happen, the function text may be an additional template parameter:
>>
>> import std.conv, std.stdio, std.stream, std.string;
>> import std.socket, std.socketstream;
>> import std.datetime;
>>
>> class Algorisme(U,V,string funcioText) {
>> 	string nom;
>> 	uint versio;
>> 	alias V delegate (U) Funcio;
>> 	Funcio funcio;
>>
>>
>> 	this(string nom, uint versio) {
>> 		this.nom = nom;
>> 		this.versio = versio;
>> 		this.funcio = mixin(funcioText);
>> 	}
>>
>> 	string toString() {
>>            return format("%s (versió %s): Domini -> Recorregut, %s(x) = %s",
>>                          nom, versio, nom, funcioText);
>> 	}
>> }
>>
>>
>> alias Algorisme!(int, int, "(int a) { return 2 * a; }") AlgorismeEnters;
>>
>> void main(string [] args)
>> {
>>
>> 	auto alg = new AlgorismeEnters("Doblar", 1);
>> 	writeln(alg);
>>
>> }
>>
>> Ali
>
> It's ugly code. I think I could call some procedure like f.code (f is a function) to obtain the "code" how f is defined. But stricly in mathematical thinking it's not adequate, because more codes could result in the same (mathematical function): x + x is the double of x; and 2*x is too.
>
> Perhaps if I change Algorisme and add the string field "code" and if there is any procedure to copy the 3rd argument in the constructor and pass as string in the 4th argument (in the constructor)
>
> class Algorisme(U,V) {
> |___string nom;
> |___uint versio;
> |___alias V delegate (U) Funcio;
> |___Funcio funcio;
> |___string code;
>
>
> |___this(string nom, uint versio, Funcio funcio) {
> |___|___this.nom = nom;
> |___|___this.versio = versio;
> |___|___this.funcio = funcio;
>         this.code = funcio.WHAT PROCEDURE?;
> |___}
>
>
> Regards,
> Xan.


The idea is behind this https://gist.github.com/2407923
But I receive:

$ gdmd-4.6 algorisme_code.d
algorisme_code.d:22: Error: variable codi cannot be read at compile time
algorisme_code.d:22: Error: argument to mixin must be a string, not (codi)

What can I do?

Thanks,
Xan.
April 17, 2012
On 04/17/2012 11:13 AM, Xan wrote:

> The idea is behind this https://gist.github.com/2407923
> But I receive:
>
> $ gdmd-4.6 algorisme_code.d
> algorisme_code.d:22: Error: variable codi cannot be read at compile time
> algorisme_code.d:22: Error: argument to mixin must be a string, not (codi)

mixin is about code generation. For that reason the string that is given to it must be available at compile time. Upon analyzing the code, that is the case in your example, but because mixin() appears inside the constructor, it cannot use a string parameter.

That's why I had used a template parameter for the function string. There may be a number of solutions but only you can decide on what to do. One solution is to mixin the delegate outside of the constructor and pass as an argument along with its string representation:

    // Untested code
    this(... Funcio funcio, string funcioText) {
        ...
    }

In main:

    enum funcioText = "...";
    auto funcio = mixin(funcioText);

    ... new Algorisme(..., funcio, funcioText);

Ali