Re: Put Tuple in templates in a class fails
Thank you very much, Philippe. I have several questions: * Why do you think I can't compose functions with tuples? Your implentation does exactly this, isn't? * What is RHS? Thanks, Xan. On Thursday, 10 May 2012 at 20:17:12 UTC, Philippe Sigaud wrote: On Thu, May 10, 2012 at 4:48 PM, Xan wrote: public class Algorisme(V,U...) { but when I do: https://gist.github.com/2653643 I get error: prova_amb_tuples_a_Algorisme.d:84: Error: 'alg' is not of arithmetic type, it is a prova_amb_tuples_a_Algorisme.Algorisme!(int,int).Algorisme prova_amb_tuples_a_Algorisme.d:84: Error: 'alg2' is not of arithmetic type, it is a prova_amb_tuples_a_Algorisme.Algorisme!(int,int).Algorisme You have to help the type-deduction algorithm a bit. By exposing the Domini/Codomini tuples, for example. Here: https://gist.github.com/2655583 See the new template constraint on lines 52-54 and the helper template at the beginning of the file. Also, in the string example, you inverted the domain and codomain. Btw, I'm not sure you can compose function with tuple-domains/codomains in general... Philippe
Put Tuple in templates in a class fails
Hi, I have this code: https://gist.github.com/2653620 and I want to change public class Algorisme(U,V) { to public class Algorisme(V,U...) { but when I do: https://gist.github.com/2653643 I get error: prova_amb_tuples_a_Algorisme.d:84: Error: 'alg' is not of arithmetic type, it is a prova_amb_tuples_a_Algorisme.Algorisme!(int,int).Algorisme prova_amb_tuples_a_Algorisme.d:84: Error: 'alg2' is not of arithmetic type, it is a prova_amb_tuples_a_Algorisme.Algorisme!(int,int).Algorisme What fails? Thanks in advance, Xan.
Re: Operator overloading
Thank you very very much, Dmitry. Now all it's fine! Xan. On Friday, 20 April 2012 at 19:51:40 UTC, Dmitry Olshansky wrote: 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
Re: Operator overloading
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
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
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.
Re: Operator overloading
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: Operator overloading
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
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: Operator overloading
On Thursday, 19 April 2012 at 19:24:40 UTC, Dmitry Olshansky wrote: On 19.04.2012 23:14, 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) { Algorisme! opBinary(string op) (Algorisme alg) { or Algorisme!(U,V) opBinary(string op) (Algorisme!(U,V) alg) { should do it static if (op == '*') return new Algorisme("composició", or: static if (op == '*') return new Algorisme!(U,v)("composició", same here. There is no need to put !(params) explicitly if it's the same as the template you are writing. this.versio+alg.versio, this.funcio); } Thanks, Dmitry, but it's a correction "*" instead of '*' (string instead of char) The definitive code is: 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); } Thanks a lot, another time, Xan. } [...] 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? Thanks, Xan.
Operator overloading
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? Thanks, Xan.
Re: delegates vs functions => practical consequences
On Thursday, 19 April 2012 at 11:46:59 UTC, Steven Schveighoffer wrote: On Wed, 18 Apr 2012 17:07:07 -0400, Xan wrote: Hi, I want to know what is most interesting for me: delegates or functions. I consulted sources but none say the practical consequences of such election. What can I do and what can't I do with functions and delegates? Please, be didactics, I'm a newbee In my experience, delegates are the more useful type to *store*. I've implemented this in some places: int delegate(int) stored_dg; void setDelegate(int delegate(int) dg) { stored_dg = dg; } void setDelegate(int function(int) fn) { stored_dg = std.functional.toDelegate(fn); } On the whole, delegates are slightly more expensive to call, but not by much. However, a function converted to a delegate pays the penalty of a double call, because it takes a call to strip out the context pointer. I wish there was a more straightforward way to do this... But I've not seen this be a huge factor -- yet. -Steve Thank you very much all of you for the information. Now I have an idea of practical benefits and contra-benefits of these. By the other hand, is there toFunction for passing delegate to function (theorically it's possible, isn't?) Thanks, Xan.
delegates vs functions => practical consequences
Hi, I want to know what is most interesting for me: delegates or functions. I consulted sources but none say the practical consequences of such election. What can I do and what can't I do with functions and delegates? Please, be didactics, I'm a newbee Thanks, Xan.
Re: Templates in classes => what is wrong?
On Tuesday, 17 April 2012 at 18:39:16 UTC, Xan wrote: On Tuesday, 17 April 2012 at 18:25:21 UTC, Ali Çehreli wrote: 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 What is change is this code? Is it the same as this https://gist.github.com/2407923 (I revise the code)? With my (v. 2) code I receive the errors: $ gdmd-4.6 algorisme_code.d algorisme_code.d:44: Error: variable codi cannot be read at compile time algorisme_code.d:44: Error: argument to mixin must be a string, not (codi) algorisme_code.d:45: Error: constructor algorisme_code.Algorisme!(int,int).Algorisme.this (string nom, uint versio, int function(int) funcio, string codi) is not callable using argument types (string,int,_error_,string) Why the string is not given at compile code? I don't understand it! Xan. It works with enum instead of string: https://gist.github.com/2407923 Thanks all of you, Xan.
Re: Templates in classes => what is wrong?
On Tuesday, 17 April 2012 at 18:25:21 UTC, Ali Çehreli wrote: 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 What is change is this code? Is it the same as this https://gist.github.com/2407923 (I revise the code)? With my (v. 2) code I receive the errors: $ gdmd-4.6 algorisme_code.d algorisme_code.d:44: Error: variable codi cannot be read at compile time algorisme_code.d:44: Error: argument to mixin must be a string, not (codi) algorisme_code.d:45: Error: constructor algorisme_code.Algorisme!(int,int).Algorisme.this (string nom, uint versio, int function(int) funcio, string codi) is not callable using argument types (string,int,_error_,string) Why the string is not given at compile code? I don't understand it! Xan.
Re: Templates in classes => what is wrong?
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.
Re: Templates in classes => what is wrong?
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); |___}
Re: Templates in classes => what is wrong?
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.
Re: Templates in classes => what is wrong?
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: (versió ): -> , ? (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
Re: Templates in classes => what is wrong?
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?
Re: Templates in classes => what is wrong?
Off-topic, could can I define toString having this structure: (versió ): -> , ? (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.
Re: Templates in classes => what is wrong?
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.
Re: A "general" tag
Uf!, it's more than I can process It's really a **complicated** thing to do that in D. On Monday, 16 April 2012 at 07:50:28 UTC, Denis Shelomovskij wrote: 15.04.2012 0:31, Xan написал: On Saturday, 14 April 2012 at 19:40:06 UTC, Aleksandar Ružičić wrote: On Saturday, 14 April 2012 at 19:17:52 UTC, Xan wrote: Hi, I try to translate a script I wrote in Fantom [www.fantom.org]. In my script, I have a type "Tag" defined as a triple of: - String (the name of the tag), - Type (the type of the tag: could be Str, Date, Int, etc.) - Obj (the value of the tag; Fantom has Objects of Top-Class hierachy). (normally the tag has Type = Obj.Type, but you can manually set). For example, you could have: (name, Str#, "John") or (date, Date#, 2011-09-02) (# is the Fantom way for specifying type: Str# is the sys::Str type) Is there any way for emulating this? My main trouble is how to define Type and Object in D. Thanks in advance, Xan. PS: Please, be patient, I'm a newbee. For "Type" look at enum (http://dlang.org/enum.html) and for "Object" look at std.variant (http://dlang.org/phobos/std_variant.html). And since Variant can tell you what type it contains you might no longer need that "Type" parameter. I think it's not what I expect. Can I have a generic object type? Something like an assigment like: Any a ? With templates? Please, guide me. I'm a newbee What you are looking for is a boxing. http://en.wikipedia.org/wiki/Boxing_(computer_science)#Boxing D doesn't support auto boxing/unboxing. For a reason see, e.g. this thread: http://forum.dlang.org/thread/ckoaum$1lbg$1...@digitaldaemon.com http://forum.dlang.org/thread/cr7njl$18j3$1...@digitaldaemon.com There was std.boxer module, but it was deprecated and removed, this is the last version before removal: https://github.com/D-Programming-Language/phobos/blob/c20d454d63861a0c4bab647b37c01b0dd981a3f8/std/boxer.d std.variant is really what you are looking for. See example: --- import std.stdio; import std.variant; import std.string: format; struct Tag { string name; Variant entity; } class C { int i; this(int i) { this.i = i; } string toString() { return format("C(i: %s)", i); } } struct SmallStruct { int a; } struct Huge { real a, b, c, d, e, f, g; } void writeTag(Tag tag) { writeln(tag); with(tag.entity) if(auto intVal = peek!int()) { writeln(" Contains int: ", *intVal); // Arithmetic is supported too writeln(" + 3: ", tag.entity + 3); writeln(" * 2: ", tag.entity * 2); } else if(auto hugeVal = peek!Huge()) // Don't use *hugeVal for now, there is a bug in peek writeln(" Contains Huge struct: ", tag.entity.get!Huge()); else if(auto classInfo = cast(TypeInfo_Class)type) writefln(" Contains class %s: %s", classInfo.name, get!Object()); else if(auto structInfo = cast(TypeInfo_Struct)type) writefln(" Contains struct %s: %s", structInfo.name, tag.entity); // else if etc. } void main() { writeTag(Tag("tag1", Variant(12))); writeTag(Tag("tag2", Variant("str"))); writeTag(Tag("tag3", Variant(["str1", "str2"]))); writeTag(Tag("tag4", Variant(new C(17; writeTag(Tag("tag4", Variant(SmallStruct(3; // Variant isn't enough to hold Huge so a copy // will be accocated in GC heap. // Yes, this isn't documented yet and `peek` will give you garbage // for this case because of a bug. writeTag(Tag("tag4", Variant(Huge(1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7; } --- std.variant has some bugs for now but is usable: http://d.puremagic.com/issues/buglist.cgi?query_format=advanced&short_desc=variant&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&short_desc_type=allwords Templates are usable in other cases, not this.
Re: Templates in classes => what is wrong?
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"?) ;-)
Re: Templates in classes => what is wrong?
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.
Templates in classes => what is wrong?
hi, I have this code: 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; V delegate (U) funcio; } int main(string [] args) { auto alg = Algorisme!(int,int); alg.nom = "Doblar"; alg.versio = 1; alg.funcio = (int a) {return 2*a}; } but when I compile I receive errors: $ gdmd-4.6 algorisme.d algorisme.d:22: found '}' when expecting ';' following return statement algorisme.d:25: found 'EOF' when expecting ';' following statement algorisme.d:25: found 'EOF' when expecting '}' following compound statement What is wrong? Thanks in advance, Xan.
Re: A "general" tag
On Saturday, 14 April 2012 at 19:40:06 UTC, Aleksandar Ružičić wrote: On Saturday, 14 April 2012 at 19:17:52 UTC, Xan wrote: Hi, I try to translate a script I wrote in Fantom [www.fantom.org]. In my script, I have a type "Tag" defined as a triple of: - String (the name of the tag), - Type (the type of the tag: could be Str, Date, Int, etc.) - Obj (the value of the tag; Fantom has Objects of Top-Class hierachy). (normally the tag has Type = Obj.Type, but you can manually set). For example, you could have: (name, Str#, "John") or (date, Date#, 2011-09-02) (# is the Fantom way for specifying type: Str# is the sys::Str type) Is there any way for emulating this? My main trouble is how to define Type and Object in D. Thanks in advance, Xan. PS: Please, be patient, I'm a newbee. For "Type" look at enum (http://dlang.org/enum.html) and for "Object" look at std.variant (http://dlang.org/phobos/std_variant.html). And since Variant can tell you what type it contains you might no longer need that "Type" parameter. I think it's not what I expect. Can I have a generic object type? Something like an assigment like: Any a ? With templates? Please, guide me. I'm a newbee
A "general" tag
Hi, I try to translate a script I wrote in Fantom [www.fantom.org]. In my script, I have a type "Tag" defined as a triple of: - String (the name of the tag), - Type (the type of the tag: could be Str, Date, Int, etc.) - Obj (the value of the tag; Fantom has Objects of Top-Class hierachy). (normally the tag has Type = Obj.Type, but you can manually set). For example, you could have: (name, Str#, "John") or (date, Date#, 2011-09-02) (# is the Fantom way for specifying type: Str# is the sys::Str type) Is there any way for emulating this? My main trouble is how to define Type and Object in D. Thanks in advance, Xan. PS: Please, be patient, I'm a newbee.
Re: Name of files causes error. Why?
On Friday, 13 April 2012 at 04:16:52 UTC, Jesse Phillips wrote: On Wednesday, 11 April 2012 at 19:33:58 UTC, Xan wrote: Hi, With helloworld program named with score or underscore, I receive the following __annoying__ error: $ gdmd-4.6 hola-temp.d hola-temp.d: Error: module hola-temp has non-identifier characters in filename, use module declaration instead Why? Can someone fix it. It's really annoying Thanks in advance, Xan. Module names are used for import statements: import mymodule; As this is D code, it must have a valid identifier so that it parses import my-module; This could probably be special cased, but you can use these names in code auto a = my-module.foo(); Are you subtracting 'my' from 'module.foo()?' You can name you files whatever you want. Just include your module name at the top (recommended anyway) module my_module; In this case, if you module file is named my-module, then rdmd and other build tools that use your import information will be unable to locate my_module.d because that file does not exist. Thanks, Jesse, for your deep explanation. Now I understant: it's for not confusing with minus Thanks, Xan.
Re: Name of files causes error. Why?
On Wednesday, 11 April 2012 at 19:50:18 UTC, Steven Schveighoffer wrote: On Wed, 11 Apr 2012 15:33:56 -0400, Xan wrote: Hi, With helloworld program named with score or underscore, I receive the following __annoying__ error: $ gdmd-4.6 hola-temp.d hola-temp.d: Error: module hola-temp has non-identifier characters in filename, use module declaration instead Why? Can someone fix it. It's really annoying Thanks in advance, Xan. All d module files (i.e. d source files) must be a valid identifier. See this document for what an identifier can contain: http://dlang.org/lex.html#Identifier Now, you *can* possibly name the module differently using a module statement, but this is highly discouraged. If you do this, the only way another module can import your differently-named module is if you pass the file on the command line. -Steve But it's a messy limitation. Why we should have it? For C++ compatibilities? Thanks,
Name of files causes error. Why?
Hi, With helloworld program named with score or underscore, I receive the following __annoying__ error: $ gdmd-4.6 hola-temp.d hola-temp.d: Error: module hola-temp has non-identifier characters in filename, use module declaration instead Why? Can someone fix it. It's really annoying Thanks in advance, Xan.
Re: Passing function as values and returning functions
On Wednesday, 11 April 2012 at 13:04:01 UTC, Steven Schveighoffer wrote: On Wed, 11 Apr 2012 08:53:00 -0400, Xan wrote: Thanks, Steve, but another problem: [snip] void main() { |___writeln(g(f)(1)); } writeln(g(&f)(1)); Unlike C, you *must* take the address of a function symbol to get a function pointer. -Steve Yes, it works, finally. Thanks, Steve. Xan.
Re: Passing function as values and returning functions
On Wednesday, 11 April 2012 at 12:19:06 UTC, Steven Schveighoffer wrote: On Wed, 11 Apr 2012 08:08:44 -0400, Xan wrote: On Wednesday, 11 April 2012 at 11:59:14 UTC, Jacob Carlborg wrote: Use "delegate" or "function" both for the argument type and return type. How to do that? int function(int) g(int function(int a) p) { return p; } Should do the trick. delegates are not implicitly convertible to/from function pointers. You can, however, explicitly convert a function to a delegate. But this should be done only when there is a requirement to use delegates. However, use std.functional.toDelegate if you are interested. -Steve Thanks, Steve, but another problem: $ gdmd-4.6 functions.d functions.d:13: Error: function functions.f (int a) is not callable using argument types () functions.d:13: Error: expected 1 function arguments, not 0 functions.d:13: Error: function functions.g (int function(int) p) is not callable using argument types (int) functions.d:13: Error: cannot implicitly convert expression (f()) of type int to int function(int) import std.functional, std.stdio; int f (int a) { |___return 2*a; } int function(int) g(int function(int a) p) { |___return p; } void main() { |___writeln(g(f)(1)); } I want to g return f and then f evaluate 1.
Re: Passing function as values and returning functions
On Wednesday, 11 April 2012 at 11:59:14 UTC, Jacob Carlborg wrote: On 2012-04-11 13:10, Xan wrote: Hi, Following the thread of Higher-order functions, how can I do to pass a function as a parameter and return a function. That is a something like: import std.functional, std.stdio; int f (int a) { return 2*a; } int delegate (int) g(int function(int a) p) { return p; } void main() { writeln(g(f)(1)); } but it gives me: $ gdmd-4.6 functions.d functions.d:8: Error: cannot implicitly convert expression (p) of type int function(int a) to int delegate(int) functions.d:13: Error: function functions.f (int a) is not callable using argument types () functions.d:13: Error: expected 1 function arguments, not 0 functions.d:13: Error: function functions.g (int function(int a) p) is not callable using argument types (int) functions.d:13: Error: cannot implicitly convert expression (f()) of type int to int function(int a) Use "delegate" or "function" both for the argument type and return type. How to do that?
Passing function as values and returning functions
Hi, Following the thread of Higher-order functions, how can I do to pass a function as a parameter and return a function. That is a something like: import std.functional, std.stdio; int f (int a) { return 2*a; } int delegate (int) g(int function(int a) p) { return p; } void main() { writeln(g(f)(1)); } but it gives me: $ gdmd-4.6 functions.d functions.d:8: Error: cannot implicitly convert expression (p) of type int function(int a) to int delegate(int) functions.d:13: Error: function functions.f (int a) is not callable using argument types () functions.d:13: Error: expected 1 function arguments, not 0 functions.d:13: Error: function functions.g (int function(int a) p) is not callable using argument types (int) functions.d:13: Error: cannot implicitly convert expression (f()) of type int to int function(int a) Thanks, Xan.
Re: Higher-order functions?
Apparently your compiler does not support parameter type deduction yet. void main () { writeln("add: ", someprocedure(2, 3, (int a, int b) { return a + b; })); writeln("multiply: ", someprocedure(2, 3, (int a, int b) { return a * b; })); } Yes, now it works! Thanks,
Re: Higher-order functions?
On Wednesday, 11 April 2012 at 10:14:21 UTC, Mirko Pilger wrote: What is the error? e.g. try this: auto someprocedure (int a, int b, int delegate (int, int) f) I receive the same error
Re: Higher-order functions?
On Wednesday, 11 April 2012 at 09:43:27 UTC, Timon Gehr wrote: On 04/11/2012 11:37 AM, Xan wrote: On Wednesday, 11 April 2012 at 09:17:12 UTC, Jacob Carlborg wrote: On 2012-04-11 10:45, Xan wrote: Good answer. For the other hand, what is the simplest method for implementing this (in pseucode) in D: Sure: FUNC someprocedure(int a, int b, func f) int RETURN f(a, b) } And call it with: IO.writeLine("add: " .. someprocedure(2, 3, { a, b => a + b })) IO.writeLine("multiply: " .. someprocedure(2, 3, { a, b => a * b })) (Read the => as "gives") Is it possible to have this? If I understand the above code correctly: import std.stdio; int someprocedure (int a, int b, int delegate (int, int) f) { return f(a, b); } Yes, you undertood correcty. Your code gives me an error: $ gdmd-4.6 funcions.d funcions.d:10: expression expected, not '>' funcions.d:10: found 'a' when expecting ',' funcions.d:11: expression expected, not '>' funcions.d:11: found 'a' when expecting ',' void main () { writeln("add: ", someprocedure(2, 3, (a, b) => a + b)); writeln("multiply: ", someprocedure(2, 3, (a, b) => a * b)); } AFAIK GDC does not yet support the new lambda literal syntax. You can use void main () { writeln("add: ", someprocedure(2, 3, (a, b) { return a + b; })); writeln("multiply: ", someprocedure(2, 3, (a, b) { return a * b; })); } Better but with error ;-) $ gdmd-4.6 func2.d func2.d:10: Error: undefined identifier a func2.d:10: Error: undefined identifier b func2.d:10: Error: function func2.someprocedure (int a, int b, int delegate(int, int) f) is not callable using argument types (int,int,_error_ delegate(_error_, _error_)) func2.d:10: Error: cannot implicitly convert expression (__dgliteral1) of type _error_ delegate(_error_, _error_) to int delegate(int, int) With: import std.stdio; int someprocedure (int a, int b, int delegate (int, int) f) { return f(a, b); } void main () { writeln("add: ", someprocedure(2, 3, (a, b) { return a + b; } )); writeln("multiply: ", someprocedure(2, 3, (a, b) { return a * b; } )); } What is the error?
Re: Higher-order functions?
On Wednesday, 11 April 2012 at 09:17:12 UTC, Jacob Carlborg wrote: On 2012-04-11 10:45, Xan wrote: Good answer. For the other hand, what is the simplest method for implementing this (in pseucode) in D: Sure: FUNC someprocedure(int a, int b, func f) int RETURN f(a, b) } And call it with: IO.writeLine("add: " .. someprocedure(2, 3, { a, b => a + b })) IO.writeLine("multiply: " .. someprocedure(2, 3, { a, b => a * b })) (Read the => as "gives") Is it possible to have this? If I understand the above code correctly: import std.stdio; int someprocedure (int a, int b, int delegate (int, int) f) { return f(a, b); } Yes, you undertood correcty. Your code gives me an error: $ gdmd-4.6 funcions.d funcions.d:10: expression expected, not '>' funcions.d:10: found 'a' when expecting ',' funcions.d:11: expression expected, not '>' funcions.d:11: found 'a' when expecting ',' void main () { writeln("add: ", someprocedure(2, 3, (a, b) => a + b)); writeln("multiply: ", someprocedure(2, 3, (a, b) => a * b)); }
Re: Higher-order functions?
Good answer. For the other hand, what is the simplest method for implementing this (in pseucode) in D: Sure: FUNC someprocedure(int a, int b, func f) int RETURN f(a, b) } And call it with: IO.writeLine("add: " .. someprocedure(2, 3, { a, b => a + b })) IO.writeLine("multiply: " .. someprocedure(2, 3, { a, b => a * b })) (Read the => as "gives") Is it possible to have this? Thanks, Xan On Wednesday, 11 April 2012 at 00:03:05 UTC, Timon Gehr wrote: On 04/11/2012 01:13 AM, Jonas H. wrote: Hi everyone, does D have any runtime higher-order function facilities? D has full runtime support for higher-order functions and closures. import std.stdio; int[] map(scope int delegate(int) f, int[] a){ auto b = new int[a.length]; foreach(i,x;a) b[i] = f(x); return b; } void main(){ int a = 2; writeln(map(x=>a*x, [1,2,3])); } (I'm not talking about templates.) You will often use templates together with runtime higher order functions. Eg: import std.stdio; T[] map(T,S)(scope T delegate(S) f, S[] a){ auto b = new T[a.length]; foreach(i,x;a) b[i] = f(x); return b; } void main(){ int a = 2; writeln(map((int x)=>a*x, [1,2,3])); writeln(map((double x)=>a*x, [1.6,2.7,3.8])); } For function literals that contain more than one statement, there is an alternate syntax: auto dg = (int a, double b){a*=b; return a+b;} You can explicitly specify 'function' or 'delegate': auto fp = function (int x) => 2*x; // not a closure, simple function pointer (uses less space, but is less powerful) int a = 2; auto dg = delegate (int x) => a*x; // closure, can refer to a You can leave out argument types when they can be directly deduced from the context. Finally, if the literal has an explicit 'function' or 'delegate' it is possible to explicitly specify the return type: auto dg = delegate int(int x) => x; More specifically, is something like this possible? (That's how I'd do it in Python) car_prices = map(Car.get_price, list_of_cars) car = new Car foobar(car.get_price) Thanks Jonas (Well, the standard way to do what that python code does is using templates. auto car_prices = map!(car => car.get_price)(list_of_cars);// lazy range auto car_prices = array(map!(car => car.get_price(list_of_cars)); // eager array)
Re: HelloWordl in Webserver
On Tuesday, 3 April 2012 at 13:33:19 UTC, Adam D. Ruppe wrote: On Tuesday, 3 April 2012 at 08:42:01 UTC, Xan wrote: I receive errors: I changed some stuff since the beginning of thi thread. cgi.d now includes a http server without needing the other modules. So if you just get the new cgi.d, you can: dmd server.d cgi.d -version=embedded_httpd without bothering with the httpd.d nor netman.d Not, I receive the error: $ gdmd-4.6 server.d cgi.d -version=embedded_httpd std.algorithm.indexOf has been scheduled for deprecation. You may want to use std.algorithm.countUntil instead. cgi.d:2231: Error: undefined identifier lastSocketError
Re: HelloWordl in Webserver
And with comment the UTC line I get: s$ gdmd-4.6 server.d cgi.d netman.d httpd.d Notice: As of Phobos 2.055, std.date and std.dateparse have been deprecated. They will be removed in February 2012. Please use std.datetime instead. httpd.d:72: Error: undefined identifier peerAddress httpd.d:72: Error: constructor cgi.Cgi.this (long maxContentLength = cast(long)500, in const(immutable(char)[][string]) env = null, const(ubyte)[] delegate() readdata = null, void delegate(const(ubyte)[]) _rawDataOutput = null) is not callable using argument types (string[],immutable(ubyte)[],_error_,void delegate(const(ubyte)[]))
Re: HelloWordl in Webserver
Thanks, You can just comment out the code there (afaik it is only a custom formatting routine), or compile with the -d flag. $ gdmd-4.6 -d server.d cgi.d netman.d httpd.d Notice: As of Phobos 2.055, std.date and std.dateparse have been deprecated. They will be removed in February 2012. Please use std.datetime instead. httpd.d:72: Error: undefined identifier peerAddress httpd.d:72: Error: constructor cgi.Cgi.this (long maxContentLength = cast(long)500, in const(immutable(char)[][string]) env = null, const(ubyte)[] delegate() readdata = null, void delegate(const(ubyte)[]) _rawDataOutput = null) is not callable using argument types (string[],immutable(ubyte)[],_error_,void delegate(const(ubyte)[])) What happens now?
Re: HelloWordl in Webserver
On Tuesday, 3 April 2012 at 08:42:01 UTC, Xan wrote: I receive errors: xan@gerret:~/proves/dlang-proves$ ls cgi.d functions.d httpd.d netman.d server.d xan@gerret:~/proves/dlang-proves$ gdmd-4.6 server.d cgi.d netman.d httpd.d httpd.d:5: Error: module netman is in file 'arsd/netman.d' which cannot be read import path[0] = /usr/include/d2/4.6/i686-linux-gnu import path[1] = /usr/include/d2/4.6 What fails? I use gdmd instead of dmd It works when I change arsd. to in import.But I receive several warnings: $ gdmd-4.6 server.d cgi.d netman.d httpd.d Notice: As of Phobos 2.055, std.date and std.dateparse have been deprecated. They will be removed in February 2012. Please use std.datetime instead. netman.d:428: Error: function std.date.getUTCtime is deprecated I suspect your code is too elder. Thanks,
Re: HelloWordl in Webserver
I receive errors: xan@gerret:~/proves/dlang-proves$ ls cgi.d functions.d httpd.d netman.d server.d xan@gerret:~/proves/dlang-proves$ gdmd-4.6 server.d cgi.d netman.d httpd.d httpd.d:5: Error: module netman is in file 'arsd/netman.d' which cannot be read import path[0] = /usr/include/d2/4.6/i686-linux-gnu import path[1] = /usr/include/d2/4.6 What fails? I use gdmd instead of dmd On Saturday, 17 March 2012 at 20:18:39 UTC, Adam D. Ruppe wrote: On Saturday, 17 March 2012 at 20:08:24 UTC, Xan wrote: I'm convinced there is a D equivalent? It all depends on the library. If you use my code https://github.com/adamdruppe/misc-stuff-including-D-programming-language-web-stuff It looks like this: == import arsd.cgi; void hello(Cgi cgi) { cgi.write("Hello, world!"); } mixin GenericMain!hello; == You can build that as a cgi app to drop into any web server, a FastCGI app to use a longer running process on almost any webserver, or a HTTP server, standalone. Get cgi.d from my github then dmd hello.d cgi.d # builds cgi version dmd hello.d cgi.d -version=fastcgi # fastcgi, you also need the Fast CGI C library from the internet (search for libfcgi) or get netman.d and httpd.d and dmd hello.d cgi.d netman.d httpd.d -version=embedded_httpd # standalone, only works on linux
Re: HelloWordl in Webserver
On Sunday, 18 March 2012 at 05:19:48 UTC, Kapps wrote: On Saturday, 17 March 2012 at 20:52:33 UTC, Xan wrote: So, there is not built-in functions? Thanks, Xan. There's no built in webserver class, and it's not something that should be in the standard library in the first place. A pain. A planning for that?
Re: HelloWordl in Webserver
So, there is not built-in functions? Thanks, Xan. On Saturday, 17 March 2012 at 20:18:39 UTC, Adam D. Ruppe wrote: On Saturday, 17 March 2012 at 20:08:24 UTC, Xan wrote: I'm convinced there is a D equivalent? It all depends on the library. If you use my code https://github.com/adamdruppe/misc-stuff-including-D-programming-language-web-stuff It looks like this: == import arsd.cgi; void hello(Cgi cgi) { cgi.write("Hello, world!"); } mixin GenericMain!hello; == You can build that as a cgi app to drop into any web server, a FastCGI app to use a longer running process on almost any webserver, or a HTTP server, standalone. Get cgi.d from my github then dmd hello.d cgi.d # builds cgi version dmd hello.d cgi.d -version=fastcgi # fastcgi, you also need the Fast CGI C library from the internet (search for libfcgi) or get netman.d and httpd.d and dmd hello.d cgi.d netman.d httpd.d -version=embedded_httpd # standalone, only works on linux
HelloWordl in Webserver
I dont' want to battle among languages, but I see that in Golang there is a beatiful solution to display HelloWorld program in web server [rosettacode.org/wiki/Hello_world/Web_server#Go]. I'm convinced there is a D equivalent? Can someone say what's its aspect? Thanks in advance, Xan.
Re: actors library?
Something like Class MyActor : Actor { receive { case i int: writeln("Received integer: ", i) } } pseudocode 2012/1/23 Timon Gehr : > On 01/23/2012 08:01 PM, Xan xan wrote: >> >> Hi. >> >> Is there any actors library in D. Spawn and etc is ok, but I want more >> high-level thing and actors it's the best I get, I think. >> I searched and nothing. >> >> I'm interested in D 2.0 or 1.0. Whatever! >> >> Thanks in advace, >> Xan. > > > std.concurrency is an actors library. > What exactly do you mean when you say more high-level?
actors library?
Hi. Is there any actors library in D. Spawn and etc is ok, but I want more high-level thing and actors it's the best I get, I think. I searched and nothing. I'm interested in D 2.0 or 1.0. Whatever! Thanks in advace, Xan.
Re: Reading web pages
With png works, with pdf not: ./spider2 http://www.google.com/intl/ca/images/logos/mail_logo.png [a lot of output] $ ./spider2 http://static.arxiv.org/pdf/1109.4897.pdf [Longitud: [Excepció: std.conv.ConvException@/usr/include/d2/4.6/std/conv.d(1640): Can't convert value `HTT' of type string to type uint] 2012/1/20 Bystroushaak : > On 20.1.2012 18:42, Xan xan wrote: >> >> Thank you very much. I should invite you to a beer ;-) > > > Write me if you will be in prag/czech republic :) > > >> For the other hand, >> >> I get this error: >> >> [Excepció: std.conv.ConvException@/usr/include/d2/4.6/std/conv.d(1640): >> Can't convert value `HTT' of type string to type uint] > > > This is very strange error, because on my computer it works well. Can you > remove try..catch and post full error list and program parameters?
Re: Reading web pages
The full code is:; //D 2.0 //gdmd-4.6 dhttpclient => surt el fitxer amb el mateix nom i .o //Usa https://github.com/Bystroushaak/DHTTPClient //versió 0.0.3 import std.stdio, std.string, std.conv, std.stream; import std.socket, std.socketstream; import dhttpclient; int main(string [] args) { if (args.length < 2) { writeln("Usage:"); writeln(" ./spider {, , ...}"); return 0; } else { try { string[string] capcalera = dhttpclient.FFHeaders; HTTPClient navegador = new HTTPClient(); navegador.setClientHeaders(capcalera); foreach (a; args[1..$]) { write("[Longitud: "); stdout.rawWrite(cast(ubyte[]) navegador.get(a)); writeln("]"); } } catch (Exception e) { writeln("[Excepció: ", e, "]"); } return 0; } } I don't know what happens!!! And no, I don't live in Czech Republic: we have to postpone the invitation ;-) 2012/1/20 Bystroushaak : > On 20.1.2012 18:42, Xan xan wrote: >> >> Thank you very much. I should invite you to a beer ;-) > > > Write me if you will be in prag/czech republic :) > > >> For the other hand, >> >> I get this error: >> >> [Excepció: std.conv.ConvException@/usr/include/d2/4.6/std/conv.d(1640): >> Can't convert value `HTT' of type string to type uint] > > > This is very strange error, because on my computer it works well. Can you > remove try..catch and post full error list and program parameters?
Re: Reading web pages
The same error with: [...] foreach (a; args[1..$]) { |___|___|___|___write("[Longitud: "); |___|___|___|___stdout.rawWrite(cast(ubyte[]) navegador.get(a)); |___|___|___|___writeln("]"); |___|___|___} [...] 2012/1/20 Bystroushaak : > rawWrite(): > > stdout.rawWrite(cast(ubyte[]) navegador.get(a)); > > > On 20.1.2012 18:18, Xan xan wrote: >> >> Mmmm... I understand it. But is there any way of circumvent it? >> Perhaps I could write to one file, isn't? >> >> >> >> 2012/1/20 Bystroushaak: >>> >>> Thats because you are trying writeln binary data, and that is impossible, >>> because writeln IMHO checks UTF8 validity. >>> >>> >>> On 20.1.2012 18:08, Xan xan wrote: >>>> >>>> >>>> Before and now, I get this error: >>>> >>>> $ ./spider http://static.arxiv.org/pdf/1109.4897.pdf >>>> [Excepció: std.conv.ConvException@/usr/include/d2/4.6/std/conv.d(1640): >>>> Can't convert value `HTT' of type string to type uint] >>>> >>>> The code: >>>> >>>> //D 2.0 >>>> //gdmd-4.6 => surt el fitxer amb el mateix nom i .o >>>> //Usa https://github.com/Bystroushaak/DHTTPClient >>>> import std.stdio, std.string, std.conv, std.stream; >>>> import std.socket, std.socketstream; >>>> import dhttpclient; >>>> >>>> int main(string [] args) >>>> { >>>> if (args.length< 2) { >>>> writeln("Usage:"); >>>> writeln(" ./spider {,, ...}"); >>>> return 0; >>>> } >>>> else { >>>> try { >>>> string[string] capcalera = dhttpclient.FFHeaders; >>>> //capcalera["User-Agent"] = "arachnida yottiuma"; >>>> HTTPClient navegador = new HTTPClient(); >>>> navegador.setClientHeaders(capcalera); >>>> >>>> foreach (a; args[1..$]) { >>>> writeln("[Contingut: ", cast(ubyte[]) >>>> navegador.get(a), "]"); >>>> } >>>> } >>>> catch (Exception e) { >>>> writeln("[Excepció: ", e, "]"); >>>> } >>>> return 0; >>>> } >>>> } >>>> >>>> >>>> >>>> What happens? >>>> >>>> >>>> 2012/1/20 Bystroushaak: >>>>> >>>>> >>>>> It is unlimited, you just have to cast output to ubyte[]: >>>>> >>>>> std.file.write("logo3w.png", cast(ubyte[]) >>>>> cl.get("http://www.google.cz/images/srpr/logo3w.png";)); >>>>> >>>>> >>> >
Re: Reading web pages
Thank you very much. I should invite you to a beer ;-) For the other hand, I get this error: [Excepció: std.conv.ConvException@/usr/include/d2/4.6/std/conv.d(1640): Can't convert value `HTT' of type string to type uint] if I only want the length: //D 2.0 //gdmd-4.6 dhttpclient => surt el fitxer amb el mateix nom i .o //Usa https://github.com/Bystroushaak/DHTTPClient //versió 0.0.2 import std.stdio, std.string, std.conv, std.stream; import std.socket, std.socketstream; import dhttpclient; int main(string [] args) { if (args.length < 2) { writeln("Usage:"); writeln(" ./spider {, , ...}"); return 0; } else { try { string[string] capcalera = dhttpclient.FFHeaders; HTTPClient navegador = new HTTPClient(); navegador.setClientHeaders(capcalera); foreach (a; args[1..$]) { auto tamany = cast(ubyte[]) navegador.get(a); writeln("[Contingut: ", tamany.length, "]"); } } catch (Exception e) { writeln("[Excepció: ", e, "]"); } return 0; } } In theory, tamany.length is completely defined. Xan. 2012/1/20 Bystroushaak : > rawWrite(): > > stdout.rawWrite(cast(ubyte[]) navegador.get(a)); > > > On 20.1.2012 18:18, Xan xan wrote: >> >> Mmmm... I understand it. But is there any way of circumvent it? >> Perhaps I could write to one file, isn't? >> >> >> >> 2012/1/20 Bystroushaak: >>> >>> Thats because you are trying writeln binary data, and that is impossible, >>> because writeln IMHO checks UTF8 validity. >>> >>> >>> On 20.1.2012 18:08, Xan xan wrote: >>>> >>>> >>>> Before and now, I get this error: >>>> >>>> $ ./spider http://static.arxiv.org/pdf/1109.4897.pdf >>>> [Excepció: std.conv.ConvException@/usr/include/d2/4.6/std/conv.d(1640): >>>> Can't convert value `HTT' of type string to type uint] >>>> >>>> The code: >>>> >>>> //D 2.0 >>>> //gdmd-4.6 => surt el fitxer amb el mateix nom i .o >>>> //Usa https://github.com/Bystroushaak/DHTTPClient >>>> import std.stdio, std.string, std.conv, std.stream; >>>> import std.socket, std.socketstream; >>>> import dhttpclient; >>>> >>>> int main(string [] args) >>>> { >>>> if (args.length< 2) { >>>> writeln("Usage:"); >>>> writeln(" ./spider {,, ...}"); >>>> return 0; >>>> } >>>> else { >>>> try { >>>> string[string] capcalera = dhttpclient.FFHeaders; >>>> //capcalera["User-Agent"] = "arachnida yottiuma"; >>>> HTTPClient navegador = new HTTPClient(); >>>> navegador.setClientHeaders(capcalera); >>>> >>>> foreach (a; args[1..$]) { >>>> writeln("[Contingut: ", cast(ubyte[]) >>>> navegador.get(a), "]"); >>>> } >>>> } >>>> catch (Exception e) { >>>> writeln("[Excepció: ", e, "]"); >>>> } >>>> return 0; >>>> } >>>> } >>>> >>>> >>>> >>>> What happens? >>>> >>>> >>>> 2012/1/20 Bystroushaak: >>>>> >>>>> >>>>> It is unlimited, you just have to cast output to ubyte[]: >>>>> >>>>> std.file.write("logo3w.png", cast(ubyte[]) >>>>> cl.get("http://www.google.cz/images/srpr/logo3w.png";)); >>>>> >>>>> >>> >
Re: Reading web pages
Mmmm... I understand it. But is there any way of circumvent it? Perhaps I could write to one file, isn't? 2012/1/20 Bystroushaak : > Thats because you are trying writeln binary data, and that is impossible, > because writeln IMHO checks UTF8 validity. > > > On 20.1.2012 18:08, Xan xan wrote: >> >> Before and now, I get this error: >> >> $ ./spider http://static.arxiv.org/pdf/1109.4897.pdf >> [Excepció: std.conv.ConvException@/usr/include/d2/4.6/std/conv.d(1640): >> Can't convert value `HTT' of type string to type uint] >> >> The code: >> >> //D 2.0 >> //gdmd-4.6 => surt el fitxer amb el mateix nom i .o >> //Usa https://github.com/Bystroushaak/DHTTPClient >> import std.stdio, std.string, std.conv, std.stream; >> import std.socket, std.socketstream; >> import dhttpclient; >> >> int main(string [] args) >> { >> if (args.length< 2) { >> writeln("Usage:"); >> writeln(" ./spider {,, ...}"); >> return 0; >> } >> else { >> try { >> string[string] capcalera = dhttpclient.FFHeaders; >> //capcalera["User-Agent"] = "arachnida yottiuma"; >> HTTPClient navegador = new HTTPClient(); >> navegador.setClientHeaders(capcalera); >> >> foreach (a; args[1..$]) { >> writeln("[Contingut: ", cast(ubyte[]) >> navegador.get(a), "]"); >> } >> } >> catch (Exception e) { >> writeln("[Excepció: ", e, "]"); >> } >> return 0; >> } >> } >> >> >> >> What happens? >> >> >> 2012/1/20 Bystroushaak: >>> >>> It is unlimited, you just have to cast output to ubyte[]: >>> >>> std.file.write("logo3w.png", cast(ubyte[]) >>> cl.get("http://www.google.cz/images/srpr/logo3w.png";)); >>> >>> >
Re: Reading web pages
Thanks, but what fails that, because I downloaded as collection of bytes. No matter if a file is a pdf, png or whatever if I downloaded as bytes, isn't? Thanks, 2012/1/20 Bystroushaak : > If you want to know what type of file you just downloaded, look at > .getResponseHeaders(): > > > std.file.write("logo3w.png", cast(ubyte[]) > cl.get("http://www.google.cz/images/srpr/logo3w.png";)); > writeln(cl.getResponseHeaders()["Content-Type"]); > > Which will print in this case: image/png > > Here is full example: > https://github.com/Bystroushaak/DHTTPClient/blob/master/examples/download_binary_file.d > > > On 20.1.2012 18:00, Bystroushaak wrote: >> >> It is unlimited, you just have to cast output to ubyte[]: >> >> std.file.write("logo3w.png", cast(ubyte[]) >> cl.get("http://www.google.cz/images/srpr/logo3w.png";)); >> >> On 20.1.2012 17:53, Xan xan wrote: >>> >>> Thank you very much, Bystroushaak. >>> I see you limite httpclient to xml/html documents. Is there >>> possibility of download any files (and not only html or xml). Just >>> like: >>> >>> HTTPClient navegador = new HTTPClient(); >>> auto file = navegador.download("http://www.google.com/myfile.pdf";) >>> >>> ? >>> >>> Thanks a lot, >>> >>> >>> >>> 2012/1/20 Bystroushaak: >>>> >>>> First version was buggy. I've updated code at github, so if you want >>>> to try >>>> it, pull new version (git pull). I've also added new example into >>>> examples/user_agent_change.d >>>> >>>> >>>> On 20.1.2012 16:08, Bystroushaak wrote: >>>>> >>>>> >>>>> There are two ways: >>>>> >>>>> Change global variable for module: >>>>> >>>>> dhttpclient.DefaultHeaders = dhttpclient.IEHeaders; // or your own >>>>> >>>>> This will change headers for all clients. >>>>> >>>>> --- >>>>> >>>>> Change instance headers: >>>>> >>>>> string[string] my_headers = dhttpclient.FFHeaders; // there are more >>>>> headers than just User-Agent and you have to copy it >>>>> my_headers["User-Agent"] = "My own spider!"; >>>>> >>>>> HTTPClient navegador = new HTTPClient(); >>>>> navegador.setClientHeaders(my_headers); >>>>> >>>>> --- >>>>> >>>>> Headers are defined as: >>>>> >>>>> public enum string[string] FFHeaders = [ >>>>> "User-Agent" : "Mozilla/5.0 (Windows; U; Windows NT 5.1; cs; >>>>> rv:1.9.2.3) >>>>> Gecko/20100401 Firefox/3.6.13", >>>>> "Accept" : >>>>> >>>>> >>>>> "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain", >>>>> >>>>> >>>>> "Accept-Language" : "cs,en-us;q=0.7,en;q=0.3", >>>>> "Accept-Charset" : "utf-8", >>>>> "Keep-Alive" : "300", >>>>> "Connection" : "keep-alive" >>>>> ]; >>>>> >>>>> /// Headers from firefox 3.6.13 on Linux >>>>> public enum string[string] LFFHeaders = [ >>>>> "User-Agent" : "Mozilla/5.0 (X11; U; Linux i686; cs; rv:1.9.2.3) >>>>> Gecko/20100401 Firefox/3.6.13", >>>>> "Accept" : >>>>> >>>>> >>>>> "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain", >>>>> >>>>> >>>>> "Accept-Language" : "cs,en-us;q=0.7,en;q=0.3", >>>>> "Accept-Charset" : "utf-8", >>>>> "Keep-Alive" : "300", >>>>> "Connection" : "keep-alive" >>>>> ]; >>>>> >>>>> Accept, Accept-Charset, Kepp-ALive and Connection are important and if >>>>> you redefine it, module can stop work with some servers. >>>>> >>>>> On 20.1.2012 15:56, Xan xan wrote: >>>>>> >>>>>> >>>>>> On the other hand, I see dhttpclient identifies as >>>>>> "Mozilla/5.0 (Windows; U; Windows NT 5.1; cs; rv:1.9.2.3) >>>>>> Gecko/20100401 Firefox/3.6.13" >>>>>> >>>>>> How can I change that?
Re: Reading web pages
Before and now, I get this error: $ ./spider http://static.arxiv.org/pdf/1109.4897.pdf [Excepció: std.conv.ConvException@/usr/include/d2/4.6/std/conv.d(1640): Can't convert value `HTT' of type string to type uint] The code: //D 2.0 //gdmd-4.6 => surt el fitxer amb el mateix nom i .o //Usa https://github.com/Bystroushaak/DHTTPClient import std.stdio, std.string, std.conv, std.stream; import std.socket, std.socketstream; import dhttpclient; int main(string [] args) { if (args.length < 2) { writeln("Usage:"); writeln(" ./spider {, , ...}"); return 0; } else { try { string[string] capcalera = dhttpclient.FFHeaders; //capcalera["User-Agent"] = "arachnida yottiuma"; HTTPClient navegador = new HTTPClient(); navegador.setClientHeaders(capcalera); foreach (a; args[1..$]) { writeln("[Contingut: ", cast(ubyte[]) navegador.get(a), "]"); } } catch (Exception e) { writeln("[Excepció: ", e, "]"); } return 0; } } What happens? 2012/1/20 Bystroushaak : > It is unlimited, you just have to cast output to ubyte[]: > > std.file.write("logo3w.png", cast(ubyte[]) > cl.get("http://www.google.cz/images/srpr/logo3w.png";)); > >
Re: Reading web pages
Thank you very much, Bystroushaak. I see you limite httpclient to xml/html documents. Is there possibility of download any files (and not only html or xml). Just like: HTTPClient navegador = new HTTPClient(); auto file = navegador.download("http://www.google.com/myfile.pdf";) ? Thanks a lot, 2012/1/20 Bystroushaak : > First version was buggy. I've updated code at github, so if you want to try > it, pull new version (git pull). I've also added new example into > examples/user_agent_change.d > > > On 20.1.2012 16:08, Bystroushaak wrote: >> >> There are two ways: >> >> Change global variable for module: >> >> dhttpclient.DefaultHeaders = dhttpclient.IEHeaders; // or your own >> >> This will change headers for all clients. >> >> --- >> >> Change instance headers: >> >> string[string] my_headers = dhttpclient.FFHeaders; // there are more >> headers than just User-Agent and you have to copy it >> my_headers["User-Agent"] = "My own spider!"; >> >> HTTPClient navegador = new HTTPClient(); >> navegador.setClientHeaders(my_headers); >> >> --- >> >> Headers are defined as: >> >> public enum string[string] FFHeaders = [ >> "User-Agent" : "Mozilla/5.0 (Windows; U; Windows NT 5.1; cs; rv:1.9.2.3) >> Gecko/20100401 Firefox/3.6.13", >> "Accept" : >> >> "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain", >> >> "Accept-Language" : "cs,en-us;q=0.7,en;q=0.3", >> "Accept-Charset" : "utf-8", >> "Keep-Alive" : "300", >> "Connection" : "keep-alive" >> ]; >> >> /// Headers from firefox 3.6.13 on Linux >> public enum string[string] LFFHeaders = [ >> "User-Agent" : "Mozilla/5.0 (X11; U; Linux i686; cs; rv:1.9.2.3) >> Gecko/20100401 Firefox/3.6.13", >> "Accept" : >> >> "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain", >> >> "Accept-Language" : "cs,en-us;q=0.7,en;q=0.3", >> "Accept-Charset" : "utf-8", >> "Keep-Alive" : "300", >> "Connection" : "keep-alive" >> ]; >> >> Accept, Accept-Charset, Kepp-ALive and Connection are important and if >> you redefine it, module can stop work with some servers. >> >> On 20.1.2012 15:56, Xan xan wrote: >>> >>> On the other hand, I see dhttpclient identifies as >>> "Mozilla/5.0 (Windows; U; Windows NT 5.1; cs; rv:1.9.2.3) >>> Gecko/20100401 Firefox/3.6.13" >>> >>> How can I change that?
Re: Reading web pages
Yes. I ddi not know that I have to compile the two d files, although it has sense ;-) Perfect. On the other hand, I see dhttpclient identifies as "Mozilla/5.0 (Windows; U; Windows NT 5.1; cs; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.13" How can I change that? 2012/1/20 Bystroushaak : > With dmd 2.057 on my linux machine: > > bystrousak:DHTTPClient,0$ dmd spider.d dhttpclient.d > bystrousak:DHTTPClient,0$ ./spider http://kitakitsune.org > [Contingut: "http://www.w3.org/TR/html4/loose.dtd";> > > > . > > > > On 20.1.2012 15:37, Xan xan wrote: >> >> I get errors: >> >> xan@gerret:~/yottium/@codi/aranya-d2.0$ gdmd-4.6 spider.d >> spider.o: In function `_Dmain': >> spider.d:(.text+0x4d): undefined reference to >> `_D11dhttpclient10HTTPClient7__ClassZ' >> spider.d:(.text+0x5a): undefined reference to >> `_D11dhttpclient10HTTPClient6__ctorMFZC11dhttpclient10HTTPClient' >> spider.o:(.data+0x24): undefined reference to >> `_D11dhttpclient12__ModuleInfoZ' >> collect2: ld returned 1 exit status >> >> >> with the file spider.d: >> >> //D 2.0 >> //gdmd-4.6 => surt el fitxer amb el mateix nom i .o >> //Usa https://github.com/Bystroushaak/DHTTPClient >> import std.stdio, std.string, std.conv, std.stream; >> import std.socket, std.socketstream; >> import dhttpclient; >> >> int main(string [] args) >> { >> if (args.length< 2) { >> writeln("Usage:"); >> writeln(" ./spider {,, ...}"); >> return 0; >> } >> else { >> try { >> HTTPClient navegador = new HTTPClient(); >> foreach (a; args[1..$]) { >> writeln("[Contingut: ", navegador.get(a), >> "]"); >> } >> } >> catch (Exception e) { >> writeln("[Excepció: ", e, "]"); >> } >> return 0; >> } >> } >> >> >> >> What happens now? >> >> Thanks a lot, >> Xan. >> >> 2012/1/20 Bystroushaak: >>> >>> You can always use my module: >>> https://github.com/Bystroushaak/DHTTPClient >>> >>> >
Re: Reading web pages
I get errors: xan@gerret:~/yottium/@codi/aranya-d2.0$ gdmd-4.6 spider.d spider.o: In function `_Dmain': spider.d:(.text+0x4d): undefined reference to `_D11dhttpclient10HTTPClient7__ClassZ' spider.d:(.text+0x5a): undefined reference to `_D11dhttpclient10HTTPClient6__ctorMFZC11dhttpclient10HTTPClient' spider.o:(.data+0x24): undefined reference to `_D11dhttpclient12__ModuleInfoZ' collect2: ld returned 1 exit status with the file spider.d: //D 2.0 //gdmd-4.6 => surt el fitxer amb el mateix nom i .o //Usa https://github.com/Bystroushaak/DHTTPClient import std.stdio, std.string, std.conv, std.stream; import std.socket, std.socketstream; import dhttpclient; int main(string [] args) { if (args.length < 2) { writeln("Usage:"); writeln(" ./spider {, , ...}"); return 0; } else { try { HTTPClient navegador = new HTTPClient(); foreach (a; args[1..$]) { writeln("[Contingut: ", navegador.get(a), "]"); } } catch (Exception e) { writeln("[Excepció: ", e, "]"); } return 0; } } What happens now? Thanks a lot, Xan. 2012/1/20 Bystroushaak : > You can always use my module: > https://github.com/Bystroushaak/DHTTPClient > >
Re: Reading web pages
Thanks for that. The standard library would include it. It will easy the things high level, please. For the other hand, how to specify the protocol? It's not the same http://foo than ftp://foo Thanks, Xan. 2012/1/20 Bystroushaak : > You can always use my module: > https://github.com/Bystroushaak/DHTTPClient > > > On 19.1.2012 20:24, Timon Gehr wrote: >> >> On 01/19/2012 04:30 PM, Xan xan wrote: >>> >>> Hi, >>> >>> I want to simply code a script to get the url as string in D 2.0. >>> I have this code: >>> >>> //D 2.0 >>> //gdmd-4.6 >>> import std.stdio, std.string, std.conv, std.stream; >>> import std.socket, std.socketstream; >>> >>> int main(string [] args) >>> { >>> if (args.length< 2) { >>> writeln("Usage:"); >>> writeln(" ./aranya {,, ...}"); >>> return 0; >>> } >>> else { >>> foreach (a; args[1..$]) { >>> Socket sock = new TcpSocket(new InternetAddress(a, 80)); >>> scope(exit) sock.close(); >>> Stream ss = new SocketStream(sock); >>> ss.writeString("GET" ~ a ~ " HTTP/1.1\r\n"); >>> writeln(ss); >>> } >>> return 0; >>> } >>> } >>> >>> >>> but when I use it, I receive: >>> $ ./aranya http://www.google.com >>> std.socket.AddressException@../../../src/libphobos/std/socket.d(697): >>> Unable to resolve host 'http://www.google.com' >>> >>> What fails? >>> >>> Thanks in advance, >>> Xan. >> >> >> The protocol specification is part of the get request. >> >> ./aranaya www.google.com >> >> seems to actually connect to google. (it still does not work fully, I >> get back 400 Bad Request, but maybe you can figure it out)
Re: Reading web pages
Nope: xan@gerret:~/yottium/@codi/aranya-d2.0$ gdmd-4.6 aranya.d xan@gerret:~/yottium/@codi/aranya-d2.0$ ./aranya www.google.com std.socket.TcpSocket What fails? 2012/1/19 Timon Gehr : > On 01/19/2012 04:30 PM, Xan xan wrote: >> >> Hi, >> >> I want to simply code a script to get the url as string in D 2.0. >> I have this code: >> >> //D 2.0 >> //gdmd-4.6 >> import std.stdio, std.string, std.conv, std.stream; >> import std.socket, std.socketstream; >> >> int main(string [] args) >> { >> if (args.length< 2) { >> writeln("Usage:"); >> writeln(" ./aranya {,, ...}"); >> return 0; >> } >> else { >> foreach (a; args[1..$]) { >> Socket sock = new TcpSocket(new InternetAddress(a, >> 80)); >> scope(exit) sock.close(); >> Stream ss = new SocketStream(sock); >> ss.writeString("GET" ~ a ~ " HTTP/1.1\r\n"); >> writeln(ss); >> } >> return 0; >> } >> } >> >> >> but when I use it, I receive: >> $ ./aranya http://www.google.com >> std.socket.AddressException@../../../src/libphobos/std/socket.d(697): >> Unable to resolve host 'http://www.google.com' >> >> What fails? >> >> Thanks in advance, >> Xan. > > > The protocol specification is part of the get request. > > ./aranaya www.google.com > > seems to actually connect to google. (it still does not work fully, I get > back 400 Bad Request, but maybe you can figure it out)
Reading web pages
Hi, I want to simply code a script to get the url as string in D 2.0. I have this code: //D 2.0 //gdmd-4.6 import std.stdio, std.string, std.conv, std.stream; import std.socket, std.socketstream; int main(string [] args) { if (args.length < 2) { writeln("Usage:"); writeln(" ./aranya {, , ...}"); return 0; } else { foreach (a; args[1..$]) { Socket sock = new TcpSocket(new InternetAddress(a, 80)); scope(exit) sock.close(); Stream ss = new SocketStream(sock); ss.writeString("GET" ~ a ~ " HTTP/1.1\r\n"); writeln(ss); } return 0; } } but when I use it, I receive: $ ./aranya http://www.google.com std.socket.AddressException@../../../src/libphobos/std/socket.d(697): Unable to resolve host 'http://www.google.com' What fails? Thanks in advance, Xan.