While working on my master thesis, I have once again discovered the many similarities between C# and Pike. With the C# spec 2.0, C# will become even more Pike-like and for example introduce lambda expressions.
At present, there is one thing in C# which I would very much like to see in Pike.
C# has a concept called property. It's a mix of a variable and methods to get and set that variable.
It is considered good OO-practise to hide variables and use methods to access them but this causes a lot of polution within the namespace of a class with a log of variables if each one must have a getFoo() and a setFoo() method. Here is how to do it the C# way:
private int foo; public int Foo { get { return foo; } set { foo = value; } }
To access the Foo property, one just uses it just like a normal variable:
int x = Foo; Foo = x+1;
C# appears to implement this by turning the property into two methods, which in the example above would be called get_Foo() and set_Foo(). These methods cannot be called directly by the code, attempts to do so causes a compilation error.
In my sample, there is not much use in having a property, since no processing of the value is done, but in real life situations, there are many times I found that I may want to limit the value set by the caller to a certain range or similar. This is easily done with properties in C#.
Ofcourse, the problem can be solved by implementing the get and set methods manually, as one does today, but I believe that the C# way is much better looking and, at least to me, feels more natural.
My suggestion is that we put implementation of a C#-like property concept on the TODO-list. Thoughts, other ideas?
This is just the old "overloading assignment" feature, which has been discussed before. I think the general opinion was that its disadvantages outweighed its advantages.
Ofcourse, the problem can be solved by implementing the get and set methods manually,
Wasn't that exactly what you did with these two lines?
get { return foo; } set { foo = value; }
/ Marcus Comstedt (ACROSS) (Hail Ilpalazzo!)
Previous text:
2003-12-20 10:24: Subject: C#-like properties
While working on my master thesis, I have once again discovered the many similarities between C# and Pike. With the C# spec 2.0, C# will become even more Pike-like and for example introduce lambda expressions.
At present, there is one thing in C# which I would very much like to see in Pike.
C# has a concept called property. It's a mix of a variable and methods to get and set that variable.
It is considered good OO-practise to hide variables and use methods to access them but this causes a lot of polution within the namespace of a class with a log of variables if each one must have a getFoo() and a setFoo() method. Here is how to do it the C# way:
private int foo; public int Foo { get { return foo; } set { foo = value; } }
To access the Foo property, one just uses it just like a normal variable:
int x = Foo; Foo = x+1;
C# appears to implement this by turning the property into two methods, which in the example above would be called get_Foo() and set_Foo(). These methods cannot be called directly by the code, attempts to do so causes a compilation error.
In my sample, there is not much use in having a property, since no processing of the value is done, but in real life situations, there are many times I found that I may want to limit the value set by the caller to a certain range or similar. This is easily done with properties in C#.
Ofcourse, the problem can be solved by implementing the get and set methods manually, as one does today, but I believe that the C# way is much better looking and, at least to me, feels more natural.
My suggestion is that we put implementation of a C#-like property concept on the TODO-list. Thoughts, other ideas?
/ Marcus Agehall (Scanian)
I don't remember a discussion that came to that conclusion. Got a pointer to it, or can you reiterate the disadvantages that were discussed then?
/ Martin Stjernholm, Roxen IS
Previous text:
2003-12-20 13:58: Subject: C#-like properties
This is just the old "overloading assignment" feature, which has been discussed before. I think the general opinion was that its disadvantages outweighed its advantages.
Ofcourse, the problem can be solved by implementing the get and set methods manually,
Wasn't that exactly what you did with these two lines?
get { return foo; } set { foo = value; }
/ Marcus Comstedt (ACROSS) (Hail Ilpalazzo!)
I did some digging in the conference, but failed to come up with the relevant thread. IIRC the main disadvantages were that they were inefficent to implement, and were bad for code readability. I say "they", becase just overloading assignment is not enough, you need an operator to overload read accesses too.
/ Marcus Comstedt (ACROSS) (Hail Ilpalazzo!)
Previous text:
2003-12-21 14:20: Subject: C#-like properties
I don't remember a discussion that came to that conclusion. Got a pointer to it, or can you reiterate the disadvantages that were discussed then?
/ Martin Stjernholm, Roxen IS
i think you mean the thread "assignment operator function" from february this year, in the pike@roxen list.
the question there was to be able to overload `= itself, not just `->=
greetings, martin.
Precisely. Thanks.
/ Marcus Comstedt (ACROSS) (Hail Ilpalazzo!)
Previous text:
2003-12-21 16:23: Subject: Re: C#-like properties
i think you mean the thread "assignment operator function" from february this year, in the pike@roxen list.
the question there was to be able to overload `= itself, not just `->=
greetings, martin.
/ Brevbäraren
Ah, that one. This suggestion is different and doesn't have the hairy semantic problems that one has.
/ Martin Stjernholm, Roxen IS
Previous text:
2003-12-21 16:23: Subject: Re: C#-like properties
i think you mean the thread "assignment operator function" from february this year, in the pike@roxen list.
the question there was to be able to overload `= itself, not just `->=
greetings, martin.
/ Brevbäraren
No it isn't. The "set" function in the Foo object is exactly the `= operator, and the "get" function is the corresponding read operator (I don't remember if we gave it a name, possibly the cast lfun was used somehow). This is Agehall's C# code in Pike syntax, using the imaginary `= operator, and an equally imaginary `get operator.
static int foo; object Foo = class { int `get() { return foo; } void `=(mixed value) { foo = value; } }();
/ Marcus Comstedt (ACROSS) (Hail Ilpalazzo!)
Previous text:
2003-12-21 17:48: Subject: Re: C#-like properties
Ah, that one. This suggestion is different and doesn't have the hairy semantic problems that one has.
/ Martin Stjernholm, Roxen IS
Agehall wanted to overload access to a certain identifier in an object, whereas the old discussion was about returning another value when the the value of the object itself is requested. The latter could probably be used to implement the former as your example shows, but it isn't necessary to do it that way. A solution restricted to a named lvalue would work too.
/ Martin Stjernholm, Roxen IS
Previous text:
2003-12-21 17:55: Subject: Re: C#-like properties
No it isn't. The "set" function in the Foo object is exactly the `= operator, and the "get" function is the corresponding read operator (I don't remember if we gave it a name, possibly the cast lfun was used somehow). This is Agehall's C# code in Pike syntax, using the imaginary `= operator, and an equally imaginary `get operator.
static int foo; object Foo = class { int `get() { return foo; } void `=(mixed value) { foo = value; } }();
/ Marcus Comstedt (ACROSS) (Hail Ilpalazzo!)
Something like this?
class Property { mixed value; mixed `->(string id) { return value; } mixed `->=(string id, mixed v) { value=v; return v; } }
int main() {
mixed foo = Property(); #define foo foo->bar
// ...
}
/ Martin Nilsson (saturator)
Previous text:
2003-12-20 10:24: Subject: C#-like properties
While working on my master thesis, I have once again discovered the many similarities between C# and Pike. With the C# spec 2.0, C# will become even more Pike-like and for example introduce lambda expressions.
At present, there is one thing in C# which I would very much like to see in Pike.
C# has a concept called property. It's a mix of a variable and methods to get and set that variable.
It is considered good OO-practise to hide variables and use methods to access them but this causes a lot of polution within the namespace of a class with a log of variables if each one must have a getFoo() and a setFoo() method. Here is how to do it the C# way:
private int foo; public int Foo { get { return foo; } set { foo = value; } }
To access the Foo property, one just uses it just like a normal variable:
int x = Foo; Foo = x+1;
C# appears to implement this by turning the property into two methods, which in the example above would be called get_Foo() and set_Foo(). These methods cannot be called directly by the code, attempts to do so causes a compilation error.
In my sample, there is not much use in having a property, since no processing of the value is done, but in real life situations, there are many times I found that I may want to limit the value set by the caller to a certain range or similar. This is easily done with properties in C#.
Ofcourse, the problem can be solved by implementing the get and set methods manually, as one does today, but I believe that the C# way is much better looking and, at least to me, feels more natural.
My suggestion is that we put implementation of a C#-like property concept on the TODO-list. Thoughts, other ideas?
/ Marcus Agehall (Scanian)
I think that would be good enough if you could access the value by just evaluating the object, ie if you could remove the #define from the code and still use foo the same way as if it had been there.
/ Marcus Agehall (Scanian)
Previous text:
2003-12-20 14:28: Subject: C#-like properties
Something like this?
class Property { mixed value; mixed `->(string id) { return value; } mixed `->=(string id, mixed v) { value=v; return v; } }
int main() {
mixed foo = Property(); #define foo foo->bar
// ...
}
/ Martin Nilsson (saturator)
Make a property.h with the needed toolkit and put it in lib/include
/ Martin Nilsson (saturator)
Previous text:
2003-12-20 14:31: Subject: C#-like properties
I think that would be good enough if you could access the value by just evaluating the object, ie if you could remove the #define from the code and still use foo the same way as if it had been there.
/ Marcus Agehall (Scanian)
On Sat, Dec 20, 2003 at 02:30:04PM +0100, Martin Nilsson (saturator) @ Pike (-) developers forum wrote:
mixed foo = Property(); #define foo foo->bar
Ugly... Involves preprocessor (which is bad)... Requires that every property will be #define's (and header file included)...
Additionally, there is no compiler-time type checks possible when custom class used (only run-time and only on assignment), and properties cannot be inherited (which is huge disadvantage).
Some may argue that this is "syntactic sugar", but anyway - properties (like n C#) are far more convenient (C# doesn't have preprocessor, BTW).
As of me, sometimes I miss this functionality (using `->() isn't always possible - at least when inheritance is involved), OTOH, this is not something that makes _huge_ difference (i.e. I can live without this).
Regards, /Al
The way to do that in Pike currently is to overload `-> and `->=, but that has several disadvantages when it comes to inheritance. If it's possible to overload indexing for specific identifiers, it'd become much less of a problem. It could look like this:
int `->foo() {return foo;} void `->foo= (int value) {foo = value;}
Even if it doesn't solve the inheritance problem, this would be a nice addition imho. It's easier to write than full-blown `-> and `->=, if nothing else.
Footnote: I think it has been mentioned before, but the inheritance problem is this:
class Foo { // This class emulates an identifier foo private int value; mixed `-> (string index) { if (index == "foo") return value; else return ::`-> (index); } void `->= (string index, mixed val) { if (index == "foo") value = val; else ::`->= (index, val); } }
class Bar { inherit Foo; void f() { foo = 17; // Error - the inherited identifier is not really there. } }
The identifier specific `->foo and `->foo= could solve that too, but then they're not really overload functions for -> and ->= anymore.
/ Martin Stjernholm, Roxen IS
Previous text:
2003-12-20 10:24: Subject: C#-like properties
While working on my master thesis, I have once again discovered the many similarities between C# and Pike. With the C# spec 2.0, C# will become even more Pike-like and for example introduce lambda expressions.
At present, there is one thing in C# which I would very much like to see in Pike.
C# has a concept called property. It's a mix of a variable and methods to get and set that variable.
It is considered good OO-practise to hide variables and use methods to access them but this causes a lot of polution within the namespace of a class with a log of variables if each one must have a getFoo() and a setFoo() method. Here is how to do it the C# way:
private int foo; public int Foo { get { return foo; } set { foo = value; } }
To access the Foo property, one just uses it just like a normal variable:
int x = Foo; Foo = x+1;
C# appears to implement this by turning the property into two methods, which in the example above would be called get_Foo() and set_Foo(). These methods cannot be called directly by the code, attempts to do so causes a compilation error.
In my sample, there is not much use in having a property, since no processing of the value is done, but in real life situations, there are many times I found that I may want to limit the value set by the caller to a certain range or similar. This is easily done with properties in C#.
Ofcourse, the problem can be solved by implementing the get and set methods manually, as one does today, but I believe that the C# way is much better looking and, at least to me, feels more natural.
My suggestion is that we put implementation of a C#-like property concept on the TODO-list. Thoughts, other ideas?
/ Marcus Agehall (Scanian)
accessor-functions would be nice, but they would incur significant overhead. In particular, looking up the `-> and `->= functions can be done in O(1) time, but looking up a function with a varying name currently takes O(log(n)) time (where n is the number of functions in the class) In a language with static binding, this is of course not a problem. Unfortunately pike only has static binding within objects, as soon as you call another object, dynamic binding is used.
A workaround for this problem would be to convert the method lookup function to use a hash-table instead of a binary seek. That way, method lookups would *always* be O(1), and while accessor functions would still incur some overhead, it wouln't be nearly as bad. (Also, converting the lookup function would make it possible to get rid of a function lookup cache, which could be a very nice net gain.)
The drawback is that hash tables use a bit more memory than binary seeks, but I don't think that's a major issue in this day and age. Especially since memory usage is linear to the total number of functions in the program, not the number of instances.
/ Fredrik (Naranek) Hubinette (Real Build Master)
Previous text:
2003-12-21 14:16: Subject: C#-like properties
The way to do that in Pike currently is to overload `-> and `->=, but that has several disadvantages when it comes to inheritance. If it's possible to overload indexing for specific identifiers, it'd become much less of a problem. It could look like this:
int `->foo() {return foo;} void `->foo= (int value) {foo = value;}
Even if it doesn't solve the inheritance problem, this would be a nice addition imho. It's easier to write than full-blown `-> and `->=, if nothing else.
Footnote: I think it has been mentioned before, but the inheritance problem is this:
class Foo { // This class emulates an identifier foo private int value; mixed `-> (string index) { if (index == "foo") return value; else return ::`-> (index); } void `->= (string index, mixed val) { if (index == "foo") value = val; else ::`->= (index, val); } }
class Bar { inherit Foo; void f() { foo = 17; // Error - the inherited identifier is not really there. } }
The identifier specific `->foo and `->foo= could solve that too, but then they're not really overload functions for -> and ->= anymore.
/ Martin Stjernholm, Roxen IS
That sounds like a great idea. I don't think many people use such systems where the memory used by programs (not instances or raw data) is significant at all...
/ Mirar
Previous text:
2003-12-22 09:26: Subject: C#-like properties
accessor-functions would be nice, but they would incur significant overhead. In particular, looking up the `-> and `->= functions can be done in O(1) time, but looking up a function with a varying name currently takes O(log(n)) time (where n is the number of functions in the class) In a language with static binding, this is of course not a problem. Unfortunately pike only has static binding within objects, as soon as you call another object, dynamic binding is used.
A workaround for this problem would be to convert the method lookup function to use a hash-table instead of a binary seek. That way, method lookups would *always* be O(1), and while accessor functions would still incur some overhead, it wouln't be nearly as bad. (Also, converting the lookup function would make it possible to get rid of a function lookup cache, which could be a very nice net gain.)
The drawback is that hash tables use a bit more memory than binary seeks, but I don't think that's a major issue in this day and age. Especially since memory usage is linear to the total number of functions in the program, not the number of instances.
/ Fredrik (Naranek) Hubinette (Real Build Master)
Isn't there already a lookup for the variable itself that's O(log(n))? It ought to be possible to device a system where the accessor functions internally are named identically as the identifier they cover, and then there's just some flag test to find out whether it's an accessor function pair or a real variable. If that means that no real variable can be named the same, I wouldn't regard it as a problem (rather the contrary, actually).
/ Martin Stjernholm, Roxen IS
Previous text:
2003-12-22 09:26: Subject: C#-like properties
accessor-functions would be nice, but they would incur significant overhead. In particular, looking up the `-> and `->= functions can be done in O(1) time, but looking up a function with a varying name currently takes O(log(n)) time (where n is the number of functions in the class) In a language with static binding, this is of course not a problem. Unfortunately pike only has static binding within objects, as soon as you call another object, dynamic binding is used.
A workaround for this problem would be to convert the method lookup function to use a hash-table instead of a binary seek. That way, method lookups would *always* be O(1), and while accessor functions would still incur some overhead, it wouln't be nearly as bad. (Also, converting the lookup function would make it possible to get rid of a function lookup cache, which could be a very nice net gain.)
The drawback is that hash tables use a bit more memory than binary seeks, but I don't think that's a major issue in this day and age. Especially since memory usage is linear to the total number of functions in the program, not the number of instances.
/ Fredrik (Naranek) Hubinette (Real Build Master)
In the original example, no real variable can be named the same, so it sounds very fine to me.
/ Mirar
Previous text:
2003-12-22 21:50: Subject: C#-like properties
Isn't there already a lookup for the variable itself that's O(log(n))? It ought to be possible to device a system where the accessor functions internally are named identically as the identifier they cover, and then there's just some flag test to find out whether it's an accessor function pair or a real variable. If that means that no real variable can be named the same, I wouldn't regard it as a problem (rather the contrary, actually).
/ Martin Stjernholm, Roxen IS
Intiguing idea. Basically, you could just do it as a keyword:
float value;
accessor inverse(void|float i) { if(query_num_arg()) value=1/i; return 1/value; }
Afterwards any access to 'myvariable' will call the function instead of returning a function pointer, and any assignment will call the same function with a value.
/ Fredrik (Naranek) Hubinette (Real Build Master)
Previous text:
2003-12-22 21:50: Subject: C#-like properties
Isn't there already a lookup for the variable itself that's O(log(n))? It ought to be possible to device a system where the accessor functions internally are named identically as the identifier they cover, and then there's just some flag test to find out whether it's an accessor function pair or a real variable. If that means that no real variable can be named the same, I wouldn't regard it as a problem (rather the contrary, actually).
/ Martin Stjernholm, Roxen IS
accessor inverse(void|float i)
^^^^^^^
Afterwards any access to 'myvariable' will call the function instead
^^^^^^^^^^ 'inverse' I hope?
It's excellent except that I would like syntactic sugar for get instead of counting arguments...
But that would/could coincide with something else, default values.
accessor inverse(float i=value) { ... }
where i gets the default value of value if not set. (I suggested this a long time ago.)
/ Mirar
Previous text:
2003-12-22 22:53: Subject: C#-like properties
Intiguing idea. Basically, you could just do it as a keyword:
float value;
accessor inverse(void|float i) { if(query_num_arg()) value=1/i; return 1/value; }
Afterwards any access to 'myvariable' will call the function instead of returning a function pointer, and any assignment will call the same function with a value.
/ Fredrik (Naranek) Hubinette (Real Build Master)
It could be combined with variants, perhaps:
variant accessor float inverse() { return 1/value; } variant accessor void inverse (float i) { value = 1/i; }
Another syntax that makes it look even more like a cross between a variable and a function declaration:
float inverse // Note: Not function arglist at all. { return 1/value; }
void inverse = float i { value = 1/i; }
I think it can be fit into the parser without ambiguities, but I'm not sure.
/ Martin Stjernholm, Roxen IS
Previous text:
2003-12-22 22:56: Subject: C#-like properties
accessor inverse(void|float i)
^^^^^^^
Afterwards any access to 'myvariable' will call the function instead
^^^^^^^^^^
'inverse' I hope?
It's excellent except that I would like syntactic sugar for get instead of counting arguments...
But that would/could coincide with something else, default values.
accessor inverse(float i=value) { ... }
where i gets the default value of value if not set. (I suggested this a long time ago.)
/ Mirar
I'm starting to like the syntax suggestions.
/ Johan Sundström (achtung xmas!)
Previous text:
2003-12-23 00:13: Subject: C#-like properties
It could be combined with variants, perhaps:
variant accessor float inverse() { return 1/value; } variant accessor void inverse (float i) { value = 1/i; }
Another syntax that makes it look even more like a cross between a variable and a function declaration:
float inverse // Note: Not function arglist at all. { return 1/value; }
void inverse = float i { value = 1/i; }
I think it can be fit into the parser without ambiguities, but I'm not sure.
/ Martin Stjernholm, Roxen IS
I think Pike has too much syntax already...
/ Fredrik (Naranek) Hubinette (Real Build Master)
Previous text:
2003-12-23 00:13: Subject: C#-like properties
It could be combined with variants, perhaps:
variant accessor float inverse() { return 1/value; } variant accessor void inverse (float i) { value = 1/i; }
Another syntax that makes it look even more like a cross between a variable and a function declaration:
float inverse // Note: Not function arglist at all. { return 1/value; }
void inverse = float i { value = 1/i; }
I think it can be fit into the parser without ambiguities, but I'm not sure.
/ Martin Stjernholm, Roxen IS
Well, it depends on my mood really... Some days I think that gauge, sscanf, catch, :: and much more just needs to go. Others I feel that most of that stuff would be too hard to change or too practical to get rid of.
I'm sure there are more things I would like to get rid of, but it seems I have managed to suppress any memory of them..
/ Fredrik (Naranek) Hubinette (Real Build Master)
Previous text:
2003-12-23 01:53: Subject: C#-like properties
What's the top 5 syntax grejs you would like to remove?
/ Martin Nilsson (saturator)
sscanf is on the top of my list of things that should go. the current implicit lambda is next.
for gauge, catch and :: i wonder how would you achive their functionality in other ways?
greetings, martin.
gauge & catch should be done with implicit lambdas or something that achives the same thing. (And if possible without performance penalty, so should for, if and while...)
I've been dreaming of converting :: from being 100% syntax to becoming a part of the identifiers themselves. Or, solved entirely with named scopes (similar to python). However, that might not be solvable.
sscanf would probably be the last thing to go on my list, because it's soo damn convenient... :)
/ Fredrik (Naranek) Hubinette (Real Build Master)
Previous text:
2003-12-23 02:24: Subject: Re: C#-like properties
sscanf is on the top of my list of things that should go. the current implicit lambda is next.
for gauge, catch and :: i wonder how would you achive their functionality in other ways?
greetings, martin.
/ Brevbäraren
Special sscanf seems less necessary nowadays when you can write
[a, b] = array_sscanf(format, s);
(and if this is ever the "official" way of using sscanf, the "array_" prefix should of course be deleted).
/ Niels Möller (igelkottsräddare)
Previous text:
2003-12-23 03:05: Subject: Re: C#-like properties
gauge & catch should be done with implicit lambdas or something that achives the same thing. (And if possible without performance penalty, so should for, if and while...)
I've been dreaming of converting :: from being 100% syntax to becoming a part of the identifiers themselves. Or, solved entirely with named scopes (similar to python). However, that might not be solvable.
sscanf would probably be the last thing to go on my list, because it's soo damn convenient... :)
/ Fredrik (Naranek) Hubinette (Real Build Master)
That won't work for the cases when not all patterns match. Also, it's longer and harder to write and read.
/ Per Hedbor ()
Previous text:
2004-01-02 00:55: Subject: Re: C#-like properties
Special sscanf seems less necessary nowadays when you can write
[a, b] = array_sscanf(format, s);
(and if this is ever the "official" way of using sscanf, the "array_" prefix should of course be deleted).
/ Niels Möller (igelkottsräddare)
I often find the construct
sscanf(str, "potential_leading_junk%s", str);
handy.
/ Martin Nilsson (saturator)
Previous text:
2004-01-02 00:55: Subject: Re: C#-like properties
Special sscanf seems less necessary nowadays when you can write
[a, b] = array_sscanf(format, s);
(and if this is ever the "official" way of using sscanf, the "array_" prefix should of course be deleted).
/ Niels Möller (igelkottsräddare)
On Tue, Dec 23, 2003 at 02:24:48AM +0100, Martin B?hr wrote:
for gauge, catch and :: i wonder how would you achive their functionality in other ways?
Gauge is not really necessary, just make a wrapper around code (this is rare animal anyway).
catch (and likes) - well, quite difficult (in case if we want to keep exceptions).
:: - hmm... too fundamental, and I would extend it instead of removing (to handle namespaces if they will be implemented oney day, etc).
But concerning sscanf()... This is extremely convenient thing, why do you want to remove it? Using regexps and extraction, then type conversion is extremely slow (comparing even to decent sscanf()) - perhaps you know a better alternative? :) Just keep in mind that some apps do it very often (not only to validate user input, where performance is not so critical).
Regards, /Al
On Tue, Dec 23, 2003 at 03:10:18AM +0100, Alexander Demenshin wrote:
But concerning sscanf()... This is extremely convenient thing, why do you want to remove it?
sscanf looks like a function but is not. string, int and float are passed by reference contrary to the behaviour of a normal function. as for the convenience, array_sscanf() fills the need nicely. it does everything sscanf() does without breaking the behaviour of passing arguments.
greetings, martin.
On Tue, Dec 23, 2003 at 03:41:03AM +0100, Martin B?hr wrote:
string, int and float are passed by reference contrary to the behaviour of a normal function.
array, mapping and multiset are passed by reference always, contrary to string, int and float - so anyway there is some confusion (for those who don't know). Perhaps, cleaner solution would be to implement a reference to variable (something like x(int &x) in C/C++ or x(ref int i) in C#), but this is another question.
as for the convenience, array_sscanf() fills the need nicely.
Not really. First - you have to allocate array (well, it _will_ be allocated), second - you may need to assign values from this array to variables. Every array allocation is expensive (comparing to simple assignment), and every access to array and assignment after this - additional penalty.
Imagine that your application doing sscanf() most of time, then try to replace sscanf() with array_sscanf() - you will see the difference. Not that this is _so_ critical nowadays, but "why pay more?"
Regards, /Al
Perhaps, cleaner solution would be to implement a reference to variable (something like x(int &x) in C/C++ or x(ref int i) in C#),
we are trying to reduce the syntax (in this discussion anyways)
you may need to assign values from this array to variables.
[foo, bar, baz] = array_sscanf(...);
Imagine that your application doing sscanf() most of time, then try to replace sscanf() with array_sscanf() - you will see the difference. Not that this is _so_ critical nowadays, but "why pay more?"
how many calls to sscanf will it take before this difference becomes significant?
greetings, martin.
On Tue, Dec 23, 2003 at 04:19:57AM +0100, Martin B?hr wrote:
we are trying to reduce the syntax (in this discussion anyways)
Uhm... I thoutgh we are trying to improve it :)
[foo, bar, baz] = array_sscanf(...);
And if you need elements 1, 5, 7 only? Again - array will be allocated anyway - which is too much overhead.
how many calls to sscanf will it take before this difference becomes significant?
1 million, 50 millions, few billions... That's typical when you process large data files (billing-like apps), or anything that involves a lot of input data (log files, etc).
As I said before - user input is not only case where sscanf() is used and/or convenient.
And, honestly, sometimes I miss this feature - passing by reference for ints/floats/strings... After all, passing by reference (in case of interpreted languages) is more effective (you don't need to make a copy, you don't need to allocate additional memory (svalue), etc) - that't why arrays/mappings/etc passed by reference.
Hmm... Just an idea... Why not pass "scalar" types by reference (avoid copying) and implement "copy-on-write"? :) Since most of the time values passed are not modified (well, depends on app - but anyway) - it may give a significant performance gain, or?
Even simplier - compiler always (almost) "knows" - is value modified in function or not, so sometimes it is safe enough just to pass reference to svalue instead of a copy...
Regards, /Al
On Tue, Dec 23, 2003 at 04:34:48AM +0100, Alexander Demenshin wrote:
[foo, bar, baz] = array_sscanf(...);
And if you need elements 1, 5, 7 only?
then you use %*x in the format to skip the ones you don't need.
Hmm... Just an idea... Why not pass "scalar" types by reference (avoid copying) and implement "copy-on-write"? :)
i believe this actially is being done. i know it is done for strings.
greetings, martin.
On Tue, Dec 23, 2003 at 04:42:42AM +0100, Martin B?hr wrote:
then you use %*x in the format to skip the ones you don't need.
I can't use %*x because the processing of some fields may depend on value of other fields.
i know it is done for strings.
Yes, but AFAIK - only for strings (because they are shared, and shared strings may not be implemented correctly without copy-on-write).
OTOH... floats/ints are not dynamically allocated? I remember some bits about this...
Regards, /Al
I can't use %*x because the processing of some fields may depend on value of other fields.
Then you can't use a single sscanf expression to solve your problem anyway, so you are off topic.
Yes, but AFAIK - only for strings
For floats and ints the pointer is as large as the data it would point to, so it would be a silly way to make Pike slower.
/ Martin Nilsson (saturator)
Previous text:
2003-12-23 05:39: Subject: Re: C#-like properties
On Tue, Dec 23, 2003 at 04:42:42AM +0100, Martin B?hr wrote:
then you use %*x in the format to skip the ones you don't need.
I can't use %*x because the processing of some fields may depend on value of other fields.
i know it is done for strings.
Yes, but AFAIK - only for strings (because they are shared, and shared strings may not be implemented correctly without copy-on-write).
OTOH... floats/ints are not dynamically allocated? I remember some bits about this...
Regards, /Al
/ Brevbäraren
On Tue, Dec 23, 2003 at 02:19:45PM +0100, Martin B?hr wrote:
I can't use %*x because the processing of some fields may depend on value of other fields.
example?
Very simple. Assume that we have variable x, y, and z. Variable z is only needed when x is below 100. Actually, Mirar made a demonstration already, so.. :) I can add that sscanf() won't change anything that is not matched by format, so you can assign default values - which is impossible in case of array (you have to check it manually).
In any case, sscanf() is far more flexible and convenient comparing to array_sscanf(), and I don't think than it will be removed :)
Contrary to non-existing features, existing are easy to ignore, i.e. - if you prefer not to use it - don't use it, that's so simple - nobody forces you to use it anyway, while you are trying to withdraw this from those who need/like it :)
Regards, /Al
On Tue, Dec 23, 2003 at 05:09:53PM +0100, Alexander Demenshin wrote:
I can't use %*x because the processing of some fields may depend on value of other fields.
example?
Very simple. Assume that we have variable x, y, and z. Variable z is only needed when x is below 100.
i meant a code example, i can't figure out how to express the above in code myself.
Actually, Mirar made a demonstration already,
i understand mirars example, but it barely hints at how it relates to yours,
I don't think than it will be removed :)
i don't think so either, but only now i understand why removing it would be hard to do.
greetings, martin.
On Tue, Dec 23, 2003 at 06:11:33PM +0100, Martin Baehr wrote:
i understand mirars example, but it barely hints at how it relates to yours,
It fits perfectly, since after:
n = sscanf("%d %d %s", x, y, z); I can do something like:
if (n > 2 && x > 100) foo(z); while in case of array_sscanf() I've to reassing array's values to variables - using array directly will degrade code readability - symbolic are better, and again - performance because of array allocations (and extra copying).
Case of default values also significant. To be short - sscanf() simplifies the code and damn convenient, comparing to other methods.
Regards, /Al
This is a discussion that seems to pop up ever 1-2 yrs. Kind of funny really. The conclusion is always that sscanf is "incorrect" or "invalid" but too useful to remove.
/ David Hedbor
Previous text:
2003-12-23 19:30: Subject: Re: C#-like properties
On Tue, Dec 23, 2003 at 06:11:33PM +0100, Martin Baehr wrote:
i understand mirars example, but it barely hints at how it relates to yours,
It fits perfectly, since after:
n = sscanf("%d %d %s", x, y, z);
I can do something like:
if (n > 2 && x > 100) foo(z); while in case of array_sscanf() I've to reassing array's values to variables
- using array directly will degrade code readability - symbolic are
better, and again - performance because of array allocations (and extra copying).
Case of default values also significant. To be short - sscanf() simplifies the code and damn convenient, comparing to other methods.
Regards, /Al
/ Brevbäraren
Yes. Even since lpc4, iirc... :)
/ Mirar
Previous text:
2004-01-03 00:19: Subject: Re: C#-like properties
This is a discussion that seems to pop up ever 1-2 yrs. Kind of funny really. The conclusion is always that sscanf is "incorrect" or "invalid" but too useful to remove.
/ David Hedbor
Hmm... Just an idea... Why not pass "scalar" types by reference (avoid copying) and implement "copy-on-write"? :) Since most of the time values passed are not modified (well, depends on app - but anyway) - it may give a significant performance gain, or?
scalar types are small, copying them costs little or nothing
/ Fredrik (Naranek) Hubinette (Real Build Master)
Previous text:
2003-12-23 04:34: Subject: Re: C#-like properties
On Tue, Dec 23, 2003 at 04:19:57AM +0100, Martin B?hr wrote:
we are trying to reduce the syntax (in this discussion anyways)
Uhm... I thoutgh we are trying to improve it :)
[foo, bar, baz] = array_sscanf(...);
And if you need elements 1, 5, 7 only? Again - array will be allocated anyway - which is too much overhead.
how many calls to sscanf will it take before this difference becomes significant?
1 million, 50 millions, few billions... That's typical when you process large data files (billing-like apps), or anything that involves a lot of input data (log files, etc).
As I said before - user input is not only case where sscanf() is used and/or convenient.
And, honestly, sometimes I miss this feature - passing by reference for ints/floats/strings... After all, passing by reference (in case of interpreted languages) is more effective (you don't need to make a copy, you don't need to allocate additional memory (svalue), etc) - that't why arrays/mappings/etc passed by reference.
Hmm... Just an idea... Why not pass "scalar" types by reference (avoid copying) and implement "copy-on-write"? :) Since most of the time values passed are not modified (well, depends on app - but anyway) - it may give a significant performance gain, or?
Even simplier - compiler always (almost) "knows" - is value modified in function or not, so sometimes it is safe enough just to pass reference to svalue instead of a copy...
Regards, /Al
/ Brevbäraren
Sort of. It's not really copy-on-write, because there is no "write" operation for bignums. (Same thing is true for strings.) Basically, all bignum operations creates a new bignum. (In practice, this is sometimes optimized to allow bignum modification, but that's not really relevant here..)
/ Fredrik (Naranek) Hubinette (Real Build Master)
Previous text:
2003-12-23 19:29: Subject: Re: C#-like properties
what about bignums? are they copy-on-write?
greetings, martin.
/ Brevbäraren
There was a thread last spring about adding a reference/pointer data type to Pike (title "Pointers/lvalues", message 10034173 for those that use LysKOM). I still think it'd be a useful thing. But it wouldn't behave like C++ references (that requires strong typing), so using it to implement sscanf as a normal function wouldn't work.
Besides, I don't really see the problem that sscanf is a special construct.
/ Martin Stjernholm, Roxen IS
Previous text:
2003-12-23 04:34: Subject: Re: C#-like properties
On Tue, Dec 23, 2003 at 04:19:57AM +0100, Martin B?hr wrote:
we are trying to reduce the syntax (in this discussion anyways)
Uhm... I thoutgh we are trying to improve it :)
[foo, bar, baz] = array_sscanf(...);
And if you need elements 1, 5, 7 only? Again - array will be allocated anyway - which is too much overhead.
how many calls to sscanf will it take before this difference becomes significant?
1 million, 50 millions, few billions... That's typical when you process large data files (billing-like apps), or anything that involves a lot of input data (log files, etc).
As I said before - user input is not only case where sscanf() is used and/or convenient.
And, honestly, sometimes I miss this feature - passing by reference for ints/floats/strings... After all, passing by reference (in case of interpreted languages) is more effective (you don't need to make a copy, you don't need to allocate additional memory (svalue), etc) - that't why arrays/mappings/etc passed by reference.
Hmm... Just an idea... Why not pass "scalar" types by reference (avoid copying) and implement "copy-on-write"? :) Since most of the time values passed are not modified (well, depends on app - but anyway) - it may give a significant performance gain, or?
Even simplier - compiler always (almost) "knows" - is value modified in function or not, so sometimes it is safe enough just to pass reference to svalue instead of a copy...
Regards, /Al
/ Brevbäraren
[foo, bar, baz] = array_sscanf(...);
[foo, bar, baz] = array_sscanf(...); doesn't equal sscanf(...,foo,bar,baz), unfortunately.
| > int foo,bar,baz; | > sscanf("17,42","%d,%d,%d",foo,bar,baz); | (1) Result: 2 | > foo; bar; baz; | (2) Result: 17 | (3) Result: 42 | (4) Result: 0
| > [foo,bar,baz]=array_sscanf("17,42","%d,%d,%d"); | Not enough values for multiple assign. | HilfeInput:1: HilfeInput()->___HilfeWrapper()
/ Mirar
Previous text:
2003-12-23 04:20: Subject: Re: C#-like properties
Perhaps, cleaner solution would be to implement a reference to variable (something like x(int &x) in C/C++ or x(ref int i) in C#),
we are trying to reduce the syntax (in this discussion anyways)
you may need to assign values from this array to variables.
[foo, bar, baz] = array_sscanf(...);
Imagine that your application doing sscanf() most of time, then try to replace sscanf() with array_sscanf() - you will see the difference. Not that this is _so_ critical nowadays, but "why pay more?"
how many calls to sscanf will it take before this difference becomes significant?
greetings, martin.
/ Brevbäraren
private int foo; public int Foo { get { return foo; } set { foo = value; } }
int x = Foo; Foo = x+1;
So what you're saying is that you'd like automatic overloading of access methods in objects, and write these functions in sub-scopes near the variable itself?
It's not a bad idea, I think. It could make it easier to write OO code, without having to resort to "getFoo or setFoo".
You can do this in Pike today, with `-> and `->=, but there isn't any sugar around it, and you can only do it if you handle all the indices of the object yourself...
Since I like sugar, I like your idea...
/ Mirar
Previous text:
2003-12-20 10:24: Subject: C#-like properties
While working on my master thesis, I have once again discovered the many similarities between C# and Pike. With the C# spec 2.0, C# will become even more Pike-like and for example introduce lambda expressions.
At present, there is one thing in C# which I would very much like to see in Pike.
C# has a concept called property. It's a mix of a variable and methods to get and set that variable.
It is considered good OO-practise to hide variables and use methods to access them but this causes a lot of polution within the namespace of a class with a log of variables if each one must have a getFoo() and a setFoo() method. Here is how to do it the C# way:
private int foo; public int Foo { get { return foo; } set { foo = value; } }
To access the Foo property, one just uses it just like a normal variable:
int x = Foo; Foo = x+1;
C# appears to implement this by turning the property into two methods, which in the example above would be called get_Foo() and set_Foo(). These methods cannot be called directly by the code, attempts to do so causes a compilation error.
In my sample, there is not much use in having a property, since no processing of the value is done, but in real life situations, there are many times I found that I may want to limit the value set by the caller to a certain range or similar. This is easily done with properties in C#.
Ofcourse, the problem can be solved by implementing the get and set methods manually, as one does today, but I believe that the C# way is much better looking and, at least to me, feels more natural.
My suggestion is that we put implementation of a C#-like property concept on the TODO-list. Thoughts, other ideas?
/ Marcus Agehall (Scanian)
Yes, that is the idea. I normally don't like sugar, but in this case, it results in better looking code with high readability since one can drop a bunch of getFoo() and setFoo() methods.
/ Marcus Agehall (Scanian)
Previous text:
2003-12-21 14:22: Subject: C#-like properties
private int foo; public int Foo { get { return foo; } set { foo = value; } }
int x = Foo; Foo = x+1;
So what you're saying is that you'd like automatic overloading of access methods in objects, and write these functions in sub-scopes near the variable itself?
It's not a bad idea, I think. It could make it easier to write OO code, without having to resort to "getFoo or setFoo".
You can do this in Pike today, with `-> and `->=, but there isn't any sugar around it, and you can only do it if you handle all the indices of the object yourself...
Since I like sugar, I like your idea...
/ Mirar
On Mon, Dec 22, 2003 at 10:45:01AM +0100, Marcus Agehall (Scanian) @ Pike (-) developers forum wrote:
it results in better looking code with high readability since one can drop a bunch of getFoo() and setFoo() methods.
...so there is a small step left to implement `=() for objects... :)
Regards, /Al
In my opinion, `= on objects is an entirely different problem...
/ Mirar
Previous text:
2003-12-22 11:10: Subject: Re: C#-like properties
On Mon, Dec 22, 2003 at 10:45:01AM +0100, Marcus Agehall (Scanian) @ Pike (-) developers forum wrote:
it results in better looking code with high readability since one can drop a bunch of getFoo() and setFoo() methods.
...so there is a small step left to implement `=() for objects... :)
Regards, /Al
/ Brevbäraren
pike-devel@lists.lysator.liu.se