www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - getAttr method

reply =?ISO-8859-1?Q?Guillaume_Ch=e9reau?= <charlie137 gmail.com> writes:
Hello, I would like to suggest an feature to the language :

Every time we try to access a member of an object that has no such member, the
compiler try to call a special method with the member name as a template
parameter.
This  would be similar to the __getattr__ method in python, and it can be
useful sometime.

Ex:
class Test {
     string getAttr(string name)() {return name;}
}

void main() {
    Test t = Test();
    writefln(t.hello);    // write "hello"
}

- Guillaume
Feb 01 2008
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Guillaume Chéreau:
and it can be useful sometime.
Can you show one or more (practical) examples of situations where it can be useful? Bye, bearophile
Feb 01 2008
next sibling parent reply Michiel Helvensteijn <nomail please.com> writes:
bearophile wrote:

and it can be useful sometime.
Can you show one or more (practical) examples of situations where it can be useful?
PHP has something similar. These sorts of features seem to be used to make classes do magic things and be harder to understand. But just this feature for D? Well, I suppose you could use it to print something like: "Test has no function called 'hello', silly programmer!" Ehm.. at runtime, it would seem. ;-) -- Michiel
Feb 01 2008
parent reply bearophile <bearophileHUGS lycos.com> writes:
Michiel Helvensteijn:
 PHP has something similar.
I use that in Python, so I know that (once in while) it can be useful in Python code. But what I don't understand how much good it can be in a static language like D. I think Python has many other features that can be more useful for D (likes list comprehensions, generators, and few other syntactically sugared things, that ShedSkin translates to C++ quite well). Bye, bearophile
Feb 01 2008
parent reply downs <default_357-line yahoo.de> writes:
bearophile wrote:
 Michiel Helvensteijn:
 PHP has something similar.
I use that in Python, so I know that (once in while) it can be useful in Python code. But what I don't understand how much good it can be in a static language like D. I think Python has many other features that can be more useful for D (likes list comprehensions, generators, and few other syntactically sugared things, that ShedSkin translates to C++ quite well).
Well, generators are available as add-on libraries; StackThreads form a superset of them :) the following code is entirely valid D if you have scrapple.tools installed: auto generator = stackthread = (void delegate(int) yield) { int i; while (true) yield(i++); }; writefln(generator(), generator(), generator()); Except that probably won't work on a stock phobos, because win32's MmFile is broken (patch in bugzilla), and the GC can be made to work with StackThreads but it's horribly inefficient, which is why scrapple.tools currently only works with the GC patch posted above. Sorry. But hey, maybe it or a similar patch will eventually be integrated into phobos! :cue laugh track: Yeah I know. But I still have a few specks of hope left. Call me stupid :)
 Bye,
 bearophile
--downs
Feb 01 2008
next sibling parent bearophile <bearophileHUGS lycos.com> writes:
downs Wrote:

 Except that probably won't work on a stock phobos, because win32's MmFile is
broken (patch in bugzilla), and the GC can be made to work with StackThreads
but it's horribly inefficient, which is why scrapple.tools currently only works
with the GC patch posted above.
I see.
 Yeah I know. But I still have a few specks of hope left. Call me stupid :)
I like people that have hope still. I think I'll eventually drop Phobos and I'll start using Tango, despite some things I don't like of it (like the too much long dotted names, its source code being less readable, and other things), because I think it's already better debugged, a bit more open to external contributors, and I think with time it will become good enough :-) Bye, bearophile
Feb 01 2008
prev sibling parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"downs" <default_357-line yahoo.de> wrote in message 
news:fnvs99$qm$1 digitalmars.com...

 the following code is entirely valid D if you have scrapple.tools 
 installed:
 auto generator = stackthread = (void delegate(int) yield) { int i; while 
 (true) yield(i++); };
 writefln(generator(), generator(), generator());
You should start an IODCC. Your code would win every time.
Feb 01 2008
parent reply downs <default_357-line yahoo.de> writes:
Jarrett Billingsley wrote:
 "downs" <default_357-line yahoo.de> wrote in message 
 news:fnvs99$qm$1 digitalmars.com...
 
 the following code is entirely valid D if you have scrapple.tools 
 installed:
 auto generator = stackthread = (void delegate(int) yield) { int i; while 
 (true) yield(i++); };
 writefln(generator(), generator(), generator());
You should start an IODCC. Your code would win every time.
gentoo-pc ~ $ cat test.d; rebuild test.d && echo "---------" && ./test // sorry, I left out the indentation because I was in a hurry. module test; import tools.stackthreads, std.stdio; void main() { auto generator = stackthread = (void delegate(int) yield) { int i; while (true) { yield(i); i++; } }; writefln([generator(), generator(), generator()]); } // better? :) // --downs --------- [0,1,2] gentoo-pc ~ $
Feb 01 2008
next sibling parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"downs" <default_357-line yahoo.de> wrote in message 
news:fo0i97$1cla$1 digitalmars.com...

 auto generator = stackthread = (void delegate(int) yield) ...
In this code, I'm mostly concerned with your (ab)use of the property syntax to call functions which aren't properties. This looks like assignment, but sure as heck doesn't have the semantics thereof. You do realize that writing obtuse, unreadable code is not something to be proud of?
Feb 01 2008
next sibling parent Christopher Wright <dhasenan gmail.com> writes:
Jarrett Billingsley wrote:
 "downs" <default_357-line yahoo.de> wrote in message 
 news:fo0i97$1cla$1 digitalmars.com...
 
 auto generator = stackthread = (void delegate(int) yield) ...
In this code, I'm mostly concerned with your (ab)use of the property syntax to call functions which aren't properties. This looks like assignment, but sure as heck doesn't have the semantics thereof. You do realize that writing obtuse, unreadable code is not something to be proud of?
It is creative and clever. You can be proud of an unusual ability to write such code, but not if you are incapable of writing readable code.
Feb 01 2008
prev sibling parent reply downs <default_357-line yahoo.de> writes:
Jarrett Billingsley wrote:
 "downs" <default_357-line yahoo.de> wrote in message 
 news:fo0i97$1cla$1 digitalmars.com...
 
 auto generator = stackthread = (void delegate(int) yield) ...
In this code, I'm mostly concerned with your (ab)use of the property syntax to call functions which aren't properties. This looks like assignment, but sure as heck doesn't have the semantics thereof. You do realize that writing obtuse, unreadable code is not something to be proud of?
Actually, joke's on you - that actually is opAssign. Static opAssign. stackthread is a struct. :p You're right about the semantics though. The problem is that I don't want to use a function call, because it requires you to place a closing paren far, far away at the other end of the delegate literal, and it is my firm conviction that }); looks butt ugly and should die. So, if you can recommend a better operator than opAssign, one with better semantics, I'm all ears. :) --downs
Feb 01 2008
parent reply downs <default_357-line yahoo.de> writes:
downs wrote:
 Jarrett Billingsley wrote:
 "downs" <default_357-line yahoo.de> wrote in message 
 news:fo0i97$1cla$1 digitalmars.com...

 auto generator = stackthread = (void delegate(int) yield) ...
In this code, I'm mostly concerned with your (ab)use of the property syntax to call functions which aren't properties. This looks like assignment, but sure as heck doesn't have the semantics thereof. You do realize that writing obtuse, unreadable code is not something to be proud of?
Actually, joke's on you - that actually is opAssign. Static opAssign. stackthread is a struct. :p You're right about the semantics though. The problem is that I don't want to use a function call, because it requires you to place a closing paren far, far away at the other end of the delegate literal, and it is my firm conviction that }); looks butt ugly and should die. So, if you can recommend a better operator than opAssign, one with better semantics, I'm all ears. :) --downs
Oh, and note that if we had trailing delegate syntax, we could use the far superior "auto generator = stackthread (void delegate(int) yield) { };" :) --downs, PS
Feb 01 2008
parent reply "Janice Caron" <caron800 googlemail.com> writes:
On 2/2/08, downs <default_357-line yahoo.de> wrote:
 So, if you can recommend a better operator than opAssign, one with better
semantics, I'm all ears. :)
The only thing that comes to mind is member assignment. e.g. stackthread.dg = { ... }; instead of stackthread = { ... }; You still get the braces at the end, and it's clear you're assigning a property of stackthread, rather than overwriting its entire value. (It is more typing though).
Feb 01 2008
parent downs <default_357-line yahoo.de> writes:
Janice Caron wrote:
 On 2/2/08, downs <default_357-line yahoo.de> wrote:
 So, if you can recommend a better operator than opAssign, one with better
semantics, I'm all ears. :)
The only thing that comes to mind is member assignment. e.g. stackthread.dg = { ... }; instead of stackthread = { ... }; You still get the braces at the end, and it's clear you're assigning a property of stackthread, rather than overwriting its entire value. (It is more typing though).
I'm not though. Semantically, I'm creating a new StackThread from a delegate. ^^ I wish we could overload arbitrary keywords. "stackthread of " or "stackthread from " would be perfect. I'm tending towards either "stackthread/ (void delegate(int) yield) { " (in keeping with the rest of my syntax), or "stacthread ~ (void delegate(int", because ~ is less semantically burdened. Or, you know, keeping "=" :) The best thing is probably to not read it as "assign to stackthread", but as "auto generator [= stackthread] [= (void delegate(int) yield) { ... }];" i.e. assign to generator a stackthread; assign to generator this delegate; meaning "assign to generator this delegate which is also a stackthread." :) --downs
Feb 02 2008
prev sibling parent =?ISO-8859-1?Q?Jari-Matti_M=E4kel=E4?= <jmjmak utu.fi.invalid> writes:
On Sat, 2 Feb 2008, downs wrote:

 Jarrett Billingsley wrote:
 "downs" <default_357-line yahoo.de> wrote in message
 news:fnvs99$qm$1 digitalmars.com...

 the following code is entirely valid D if you have scrapple.tools
 installed:
 auto generator = stackthread = (void delegate(int) yield) { int i; while
 (true) yield(i++); };
 writefln(generator(), generator(), generator());
You should start an IODCC. Your code would win every time.
gentoo-pc ~ $ cat test.d; rebuild test.d && echo "---------" && ./test // sorry, I left out the indentation because I was in a hurry. module test; import tools.stackthreads, std.stdio; void main() { auto generator = stackthread = (void delegate(int) yield) { int i; while (true) { yield(i); i++; } }; writefln([generator(), generator(), generator()]); } // better? :) // --downs --------- [0,1,2] gentoo-pc ~ $
Lazy lists would be much cleaner: l = [0,1..] Start = take 3 l // => [0,1,2] Of course stackthreads have their use too.
Feb 08 2008
prev sibling parent =?ISO-8859-1?Q?guillaume_Ch=e9reau?= <charlie137 gmail.com> writes:
bearophile Wrote:

 Guillaume Chéreau:
and it can be useful sometime.
Can you show one or more (practical) examples of situations where it can be useful?
It could be useful to create 'decorator' objects. That is an object that encapsulate an other object and redirect all the methods except a particular one. This can be used for iterators. ex : (I will suppose we also have a function glob_getAttr(o)(name) that calls the method with the given name of the object o) Class Decorator(T) { T obj; this(T obj) {this.obj = obj;} typeof(glob_getAttr!(T)(name)) getAttr(string name)() { return glob_getAttr(obj, name); } int x() {return 2 * obj.x();} } void main() { A a = new A(); auto d = new Decorator!(A)(a); d.f // return a.f d.x // return 2 * a.x } OK, as I write it i realize how more useful and simple this kind of things are in python than in compiled language. Maybe it is not as good an idea as I though after all :) Guillaume
 
 Bye,
 bearophile
Feb 01 2008
prev sibling parent reply "Janice Caron" <caron800 googlemail.com> writes:
parent reply Ary Borenszweig <ary esperanto.org.ar> writes:
Janice Caron escribió:
parent Frank Benoit <keinfarbton googlemail.com> writes:
Ary Borenszweig schrieb:
 Janice Caron escribió: