digitalmars.D - immutable, const, enum
- bearophile (51/54) Apr 28 2009 I am about one year late for such comments or more. I also have some sug...
- Steve Teale (13/102) Apr 28 2009 Well, I'm glad it's just not me! Anytime I've used the keyword 'invarian...
- Derek Parnell (14/119) Apr 28 2009 The difference between immutable and const, in my understanding, is that
- BCS (5/11) Apr 28 2009 The language has asm blocks can can call C. The only things it can guara...
- Derek Parnell (10/15) Apr 28 2009 Oh, I agree. It is just that the documentation is pretty adamant that
- Andrei Alexandrescu (3/18) Apr 28 2009 IMHO it's more than a convention.
- Robert Fraser (3/17) Apr 29 2009 It's supposed to give the impression that if you DO change it, undefined...
- Walter Bright (7/11) Apr 29 2009 D is a systems programming language. By that I mean that there are
- Steven Schveighoffer (14/27) Apr 29 2009 I hate having to keep argue this, but you keep forgetting. You cannot
- Andrei Alexandrescu (5/27) Apr 29 2009 Yes, this is a bug, and one not easy to fix (requires a bit of flow
- Steven Schveighoffer (46/103) Apr 28 2009 First, C++ does it this way:
- Christian Kamm (9/13) Apr 28 2009 As far as I know, immutable has no effect on class declarations, so what...
- Jarrett Billingsley (5/6) Apr 28 2009 It does.
- bearophile (80/96) Apr 28 2009 Many thanks Steven Schveighoffer for the good explanations. Now I think ...
- Paul D. Anderson (6/21) Apr 28 2009 On the language/functions page:
-
Paul D. Anderson
(9/24)
Apr 28 2009
- bearophile (14/17) Apr 28 2009 Why is this working then, and printing 100?
- Georg Wrede (3/24) Apr 29 2009 You are not changig x here. The x*10 just multiplies and returns its
I am about one year late for such comments or more. I also have some suggestions and questions. I suggest to perform a serch & replace in all the D2 documentation to replace all "invariant" with "immutable". Some versions of D2 from now "invariant" can be removed from DMD itself. ----------------- From the examples of the docs. I hope to not see this code, it's not easy to understand: immutable(char*)** p = ...; -----------------The const and immutable function attributes can also appear after the closing parenthesis of the parameter list: <I think this doesn't produce much damage, but why? ----------------- Mutable and transitive-immutable data types are easy to understand. But "const" is less easy to understand for me:Const types are like immutable types, except that const forms a read-only view of data. Other aliases to that same data may change it at any time.<Regarding its purpose the docs say just:const finds applications in passing data through interfaces that promise not to modify them.<I suggest to add more examples of "const" usage, to show where it can be useful, because I am not much able to understand where to use it. It may also be better to rename "const" of D2 as "constview" or "cview" then (and the meaning of const can be kept from D1). The semantic overloading of the "enum" keyword doesn't look nice, but it's not too much bad. ----------------- The following things are written about constview/immutable member functions: immutable member functions are guaranteed that the object and anything referred to by the this reference is immutable. They are declared as: struct S { int x; immutable void foo() { x = 4; // error, x is immutable this.x = 4; // error, x is immutable } } constview member functions are functions that are not allowed to change any part of the object through the member function's this reference. I don't understand such explanations, and I'd like to see a bit wider example(s) about it. ----------------- Immutable structs/classes can be quite useful, they are safer, remove some complexity from a program, they can be sometimes the right thing you want (think about a Date object that keeps one day of the year), help paralellism, and they may allow for other optimizations (for example there's no need to copy them (so you can save memory and/or allocations, just like for immutable strings), or on the opposite you can have a copy of them on each CPU cache, and you are sure they will not go out of sync, this allows for a program more scalable on multi-cores). So I have tried to write a very simple program that uses immutable structs and classes: immutable struct S { int x; this(int xx) { this.x = x; } } immutable class C { int x; this(int xx) { this.x = x; } } void main() { auto s = S(10); auto c = new C(10); } But the compiler outputs: Error: cannot implicitly convert expression (this) of type immutable(C) to test.C test.d(8): Error: constructor test.C.this missing initializer for final field x test.d(12): Error: constructor test.S.this (int xx) does not match parameter types (int) test.d(12): Error: ((immutable immutable(S) __ctmp1 = 0; ) , __ctmp1).this can only be called on a mutable object, not immutable(S) I don't understand such errors much. What is that I am doing wrong? Note that if you remove the "immutable" that program works, and if you replace "immutable" with "invariant" the compiler gives thye same errors (internally it keeps using immutable(C)). Thank you, bye, bearophile
Apr 28 2009
bearophile Wrote:I am about one year late for such comments or more. I also have some suggestions and questions. I suggest to perform a serch & replace in all the D2 documentation to replace all "invariant" with "immutable". Some versions of D2 from now "invariant" can be removed from DMD itself. ----------------- From the examples of the docs. I hope to not see this code, it's not easy to understand: immutable(char*)** p = ...; -----------------Well, I'm glad it's just not me! Anytime I've used the keyword 'invariant' what I get just won't compile. So I remove it, which suggests that from a practical point of view, it is not much use. Const for me should mean pretty much what it means in C++ If I write: foo(const Bar b) { // I mean that if in my implementation of the function, I try to alter // b, then the compiler should flag it as an error. } foo(invariant Bar b) { // Does not seem to offer anything else that I need! }The const and immutable function attributes can also appear after the closing parenthesis of the parameter list: <I think this doesn't produce much damage, but why? ----------------- Mutable and transitive-immutable data types are easy to understand. But "const" is less easy to understand for me:Const types are like immutable types, except that const forms a read-only view of data. Other aliases to that same data may change it at any time.<Regarding its purpose the docs say just:const finds applications in passing data through interfaces that promise not to modify them.<I suggest to add more examples of "const" usage, to show where it can be useful, because I am not much able to understand where to use it. It may also be better to rename "const" of D2 as "constview" or "cview" then (and the meaning of const can be kept from D1). The semantic overloading of the "enum" keyword doesn't look nice, but it's not too much bad. ----------------- The following things are written about constview/immutable member functions: immutable member functions are guaranteed that the object and anything referred to by the this reference is immutable. They are declared as: struct S { int x; immutable void foo() { x = 4; // error, x is immutable this.x = 4; // error, x is immutable } } constview member functions are functions that are not allowed to change any part of the object through the member function's this reference. I don't understand such explanations, and I'd like to see a bit wider example(s) about it. ----------------- Immutable structs/classes can be quite useful, they are safer, remove some complexity from a program, they can be sometimes the right thing you want (think about a Date object that keeps one day of the year), help paralellism, and they may allow for other optimizations (for example there's no need to copy them (so you can save memory and/or allocations, just like for immutable strings), or on the opposite you can have a copy of them on each CPU cache, and you are sure they will not go out of sync, this allows for a program more scalable on multi-cores). So I have tried to write a very simple program that uses immutable structs and classes: immutable struct S { int x; this(int xx) { this.x = x; } } immutable class C { int x; this(int xx) { this.x = x; } } void main() { auto s = S(10); auto c = new C(10); } But the compiler outputs: Error: cannot implicitly convert expression (this) of type immutable(C) to test.C test.d(8): Error: constructor test.C.this missing initializer for final field x test.d(12): Error: constructor test.S.this (int xx) does not match parameter types (int) test.d(12): Error: ((immutable immutable(S) __ctmp1 = 0; ) , __ctmp1).this can only be called on a mutable object, not immutable(S) I don't understand such errors much. What is that I am doing wrong? Note that if you remove the "immutable" that program works, and if you replace "immutable" with "invariant" the compiler gives thye same errors (internally it keeps using immutable(C)). Thank you, bye, bearophile
Apr 28 2009
On Tue, 28 Apr 2009 14:08:58 -0400, Steve Teale wrote:bearophile Wrote:The difference between immutable and const, in my understanding, is that 'immutable' means that nothing in the program will change it, and 'const' means that this function won't change it but it might be changed by other functions in the program. What has surprised me is that immutability is *not* guaranteed. It is also just a promise that the coder makes to the compiler. You can declare something as immutable and have the program change it. The compiler does not actually prevent that happening, it only makes it difficult to do. Same with const. -- Derek Parnell Melbourne, Australia skype: derek.j.parnellI am about one year late for such comments or more. I also have some suggestions and questions. I suggest to perform a serch & replace in all the D2 documentation to replace all "invariant" with "immutable". Some versions of D2 from now "invariant" can be removed from DMD itself. ----------------- From the examples of the docs. I hope to not see this code, it's not easy to understand: immutable(char*)** p = ...; -----------------Well, I'm glad it's just not me! Anytime I've used the keyword 'invariant' what I get just won't compile. So I remove it, which suggests that from a practical point of view, it is not much use. Const for me should mean pretty much what it means in C++ If I write: foo(const Bar b) { // I mean that if in my implementation of the function, I try to alter // b, then the compiler should flag it as an error. } foo(invariant Bar b) { // Does not seem to offer anything else that I need! }The const and immutable function attributes can also appear after the closing parenthesis of the parameter list: <I think this doesn't produce much damage, but why? ----------------- Mutable and transitive-immutable data types are easy to understand. But "const" is less easy to understand for me:Const types are like immutable types, except that const forms a read-only view of data. Other aliases to that same data may change it at any time.<Regarding its purpose the docs say just:const finds applications in passing data through interfaces that promise not to modify them.<I suggest to add more examples of "const" usage, to show where it can be useful, because I am not much able to understand where to use it. It may also be better to rename "const" of D2 as "constview" or "cview" then (and the meaning of const can be kept from D1). The semantic overloading of the "enum" keyword doesn't look nice, but it's not too much bad. ----------------- The following things are written about constview/immutable member functions: immutable member functions are guaranteed that the object and anything referred to by the this reference is immutable. They are declared as: struct S { int x; immutable void foo() { x = 4; // error, x is immutable this.x = 4; // error, x is immutable } } constview member functions are functions that are not allowed to change any part of the object through the member function's this reference. I don't understand such explanations, and I'd like to see a bit wider example(s) about it. ----------------- Immutable structs/classes can be quite useful, they are safer, remove some complexity from a program, they can be sometimes the right thing you want (think about a Date object that keeps one day of the year), help paralellism, and they may allow for other optimizations (for example there's no need to copy them (so you can save memory and/or allocations, just like for immutable strings), or on the opposite you can have a copy of them on each CPU cache, and you are sure they will not go out of sync, this allows for a program more scalable on multi-cores). So I have tried to write a very simple program that uses immutable structs and classes: immutable struct S { int x; this(int xx) { this.x = x; } } immutable class C { int x; this(int xx) { this.x = x; } } void main() { auto s = S(10); auto c = new C(10); } But the compiler outputs: Error: cannot implicitly convert expression (this) of type immutable(C) to test.C test.d(8): Error: constructor test.C.this missing initializer for final field x test.d(12): Error: constructor test.S.this (int xx) does not match parameter types (int) test.d(12): Error: ((immutable immutable(S) __ctmp1 = 0; ) , __ctmp1).this can only be called on a mutable object, not immutable(S) I don't understand such errors much. What is that I am doing wrong? Note that if you remove the "immutable" that program works, and if you replace "immutable" with "invariant" the compiler gives thye same errors (internally it keeps using immutable(C)). Thank you, bye, bearophile
Apr 28 2009
Reply to Derek,What has surprised me is that immutability is *not* guaranteed. It is also just a promise that the coder makes to the compiler. You can declare something as immutable and have the program change it. The compiler does not actually prevent that happening, it only makes it difficult to do. Same with const.The language has asm blocks can can call C. The only things it can guarantee are the same things the OS can guarantee. If the the language can get at sprintf and sscanf, you can get around any const system ever made.
Apr 28 2009
On Tue, 28 Apr 2009 23:39:14 +0000 (UTC), BCS wrote:Reply to Derek,What has surprised me is that immutability is *not* guaranteed.The language has asm blocks can can call C. The only things it can guarantee are the same things the OS can guarantee.Oh, I agree. It is just that the documentation is pretty adamant that "immutability" means that the data WILL NOT change. It gives the impression that there is compiler support to ensure that this is axiomatic rather than just a convention. -- Derek Parnell Melbourne, Australia skype: derek.j.parnell
Apr 28 2009
Derek Parnell wrote:On Tue, 28 Apr 2009 23:39:14 +0000 (UTC), BCS wrote:IMHO it's more than a convention. AndreiReply to Derek,What has surprised me is that immutability is *not* guaranteed.The language has asm blocks can can call C. The only things it can guarantee are the same things the OS can guarantee.Oh, I agree. It is just that the documentation is pretty adamant that "immutability" means that the data WILL NOT change. It gives the impression that there is compiler support to ensure that this is axiomatic rather than just a convention.
Apr 28 2009
Derek Parnell wrote:On Tue, 28 Apr 2009 23:39:14 +0000 (UTC), BCS wrote:It's supposed to give the impression that if you DO change it, undefined behavior (including crashes, if the value was stored in ROM) could result.Reply to Derek,What has surprised me is that immutability is *not* guaranteed.The language has asm blocks can can call C. The only things it can guarantee are the same things the OS can guarantee.Oh, I agree. It is just that the documentation is pretty adamant that "immutability" means that the data WILL NOT change. It gives the impression that there is compiler support to ensure that this is axiomatic rather than just a convention.
Apr 29 2009
Derek Parnell wrote:Oh, I agree. It is just that the documentation is pretty adamant that "immutability" means that the data WILL NOT change. It gives the impression that there is compiler support to ensure that this is axiomatic rather than just a convention.D is a systems programming language. By that I mean that there are mechanisms to defeat the type system, for those that know what they're doing. If you defeat the type system, and mutate immutably-typed data, the onus is on you. It's like if you pop the carburetor off and put a supercharger on, you void the warranty <g>.
Apr 29 2009
On Wed, 29 Apr 2009 03:35:32 -0400, Walter Bright <newshound1 digitalmars.com> wrote:Derek Parnell wrote:I hate having to keep argue this, but you keep forgetting. You cannot create immutable data without circumventing the type system (except strings which have special treatment). Only way to make an immutable class: auto c = cast(immutable(C))new C; You have just circumvented the type system, and it's on you as a programmer to guarantee that C's constructor didn't store mutable references to itself somewhere, NOT the compiler. Until this is fixed, immutability is far less useful (except for strings). It's like you are buying a car where the dealer says you void the warranty if you put gas in it. -SteveOh, I agree. It is just that the documentation is pretty adamant that "immutability" means that the data WILL NOT change. It gives the impression that there is compiler support to ensure that this is axiomatic rather than just a convention.D is a systems programming language. By that I mean that there are mechanisms to defeat the type system, for those that know what they're doing. If you defeat the type system, and mutate immutably-typed data, the onus is on you. It's like if you pop the carburetor off and put a supercharger on, you void the warranty <g>.
Apr 29 2009
Steven Schveighoffer wrote:On Wed, 29 Apr 2009 03:35:32 -0400, Walter Bright <newshound1 digitalmars.com> wrote:Yes, this is a bug, and one not easy to fix (requires a bit of flow control in constructors), but we know how to fix it. It's just a matter of time. AndreiDerek Parnell wrote:I hate having to keep argue this, but you keep forgetting. You cannot create immutable data without circumventing the type system (except strings which have special treatment).Oh, I agree. It is just that the documentation is pretty adamant that "immutability" means that the data WILL NOT change. It gives the impression that there is compiler support to ensure that this is axiomatic rather than just a convention.D is a systems programming language. By that I mean that there are mechanisms to defeat the type system, for those that know what they're doing. If you defeat the type system, and mutate immutably-typed data, the onus is on you. It's like if you pop the carburetor off and put a supercharger on, you void the warranty <g>.
Apr 29 2009
On Tue, 28 Apr 2009 13:43:48 -0400, bearophile <bearophileHUGS lycos.com> wrote:First, C++ does it this way: int foo() const { } Second, because const/immutable is a type constructor, it can be applied to the return type as well as the function. So what looks less confusing to you: const A foo() // const function which returns a mutable A A foo() const // same thing, clearly const can't apply to A const const A foo() // const function which returns a const A const A foo() const // ditto There have been proposals to change const to const(this), so it is clear what you are applying const to (in fact, that is what a const function does, just mark the hidden "this" parameter as const): const(this) A foo() const A foo() // would either be syntax error or mean a normal fn that returns a const A I'd be in favor of such a change.The const and immutable function attributes can also appear after the closing parenthesis of the parameter list: <I think this doesn't produce much damage, but why?----------------- The following things are written about constview/immutable member functions: immutable member functions are guaranteed that the object and anything referred to by the this reference is immutable. They are declared as: struct S { int x; immutable void foo() { x = 4; // error, x is immutable this.x = 4; // error, x is immutable } } constview member functions are functions that are not allowed to change any part of the object through the member function's this reference. I don't understand such explanations, and I'd like to see a bit wider example(s) about it.The detail you are missing is that anything is implicitly castable to const, but nothing else implicitly casts. Think about it this way: const means "I cannot change this, but something else might be able to." So mutable can implicitly be cast to const if I don't want to change it, and immutable can implicitly cast to const. Mutable and immutable cannot implicitly be cast to eachother because that would violate immutability. So since something that is const could potentially be immutable OR mutable, it can't be implicitly cast to immutable or mutable because that would violate immutability. Many functions want the contract "I won't change this, but I don't care what anybody else does to it", so those are perfect candidates for const. The benefit is you can pass in mutable, const, or immutable data without an explicit cast. Immutable functions can add extra optimizations to their code. For example, you don't need to lock an immutable object to access its data. This kind of thing is very important for statically provable purity.----------------- Immutable structs/classes can be quite useful, they are safer, remove some complexity from a program, they can be sometimes the right thing you want (think about a Date object that keeps one day of the year), help paralellism, and they may allow for other optimizations (for example there's no need to copy them (so you can save memory and/or allocations, just like for immutable strings), or on the opposite you can have a copy of them on each CPU cache, and you are sure they will not go out of sync, this allows for a program more scalable on multi-cores). So I have tried to write a very simple program that uses immutable structs and classes: immutable struct S { int x; this(int xx) { this.x = x; } } immutable class C { int x; this(int xx) { this.x = x; } } void main() { auto s = S(10); auto c = new C(10); } But the compiler outputs: Error: cannot implicitly convert expression (this) of type immutable(C) to test.C test.d(8): Error: constructor test.C.this missing initializer for final field x test.d(12): Error: constructor test.S.this (int xx) does not match parameter types (int) test.d(12): Error: ((immutable immutable(S) __ctmp1 = 0; ) , __ctmp1).this can only be called on a mutable object, not immutable(S) I don't understand such errors much. What is that I am doing wrong? Note that if you remove the "immutable" that program works, and if you replace "immutable" with "invariant" the compiler gives thye same errors (internally it keeps using immutable(C)).Unfortunately, the whole thing is not completely fleshed out. currently, the only way to make an immutable class instance is to make a mutable class instance, and cast it to immutable once you have constructed it. Therefore, saying all instances of a class are immutable renders it useless. I don't really like the way this works, as the compiler is depending on the developer to ensure something marked as immutable really doesn't have any other mutable references to it. This can be difficult if you don't know the contents of the class. -Steve
Apr 28 2009
immutable struct S { int x; this(int xx) { this.x = x; } }As far as I know, immutable has no effect on class declarations, so what your code says is struct S { immutable int x; this(int xx) immutable { this.x = x; } } and that's causing problems. If you want an immutable instance, you can say: auto c = new immutable(C)(10); or cast an existing instance to immutable.
Apr 28 2009
On Tue, Apr 28, 2009 at 5:17 PM, Christian Kamm <kamm-incasoftware removethis.de> wrote:As far as I know, immutable has no effect on class declarationsIt does. http://www.digitalmars.com/d/2.0/class.html At the very bottom it describes const and invariant (i.e. immutable) classes.
Apr 28 2009
Many thanks Steven Schveighoffer for the good explanations. Now I think I have understood what's one of the purposes of const. const arguments of a function just states that you aren't going to change the data inside a function/method, more or less like in C++, but in a transitive way. But wasn't "in" before an argument type already doing that? I presume "in" isn't transitive. I have tried this: import std.stdio: writeln; void foo(in int* x) { (*x) = (*x) * 10; writeln(*x); } void main() { int y = 10; foo(&y); } But it doesn't work, so maybe in and const are the same thing now. Is "in" going to be removed then? Or maybe it's better to remove const and keep just a transitive "in". And I have seen "immutable ref" too is allowed, I guess it's mostly for performance reasons. Maybe "immutable in" is just for show, this works: import std.stdio: writeln; void foo(immutable in int x) { writeln(x * 2); } void main() { int y = 10; foo(y); } I want a simpler language -.- While this doesn't work: import std.stdio: writeln; void foo(const in int x) { writeln(x * 2); } void main() { int y = 10; foo(y); } it prints: "redundant storage class in". So const and "in" seem really the same thing. But then what does it mean "immutable in"? I guess it just means transitive-immutable. "immutable out" and "const out" are thankfully disallowed. So I guess "in" is now deprecated, it's just an alias of "const. But this idea seems wrong because "in ref" is disalloed but "const ref" is allowed, so they aren't just an alias of each other. So the available ones are ("in" not listed to keep a bit of my sanity): immutable type const type out type immutable ref type const ref type type type* type** etc ----------------------------- Christian Kamm:Sorry, the constructor was: this(int xx) { this.x = xx; } The following code works, and x can't be modified from outside the constructor: import std.stdio: writeln; immutable struct S { int x; this(int xx) { this.x = xx * 2; } } void main() { auto s = new S(10); writeln(s.x); // 20 } I think it works because s is a mutable pointer to an immutable struct. If you do this: auto s = S(10); The assignment doesn't work because s too is immutable. Well, this idea may be false because a line of code just like this doesn't work: S(10); I don't see ways yet to create an immutable struct on the stack. Well... you can do: S s = { 10 }; But then the constructor isn't called. The following too works: import std.stdio: writeln; struct S { int x; this(int xx) { this.x = xx * 2; } } void main() { auto s = new immutable(S)(10); writeln(s.x); } I don't repeat similar experiments with immutable classes because they seem to never work to me. I think I have already understood about 5% of this topic :-) Bye, bearophileimmutable struct S { int x; this(int xx) { this.x = x; } }As far as I know, immutable has no effect on class declarations, so what your code says is struct S { immutable int x; this(int xx) immutable { this.x = x; } } and that's causing problems. If you want an immutable instance, you can say: auto c = new immutable(C)(10);
Apr 28 2009
bearophile Wrote:Many thanks Steven Schveighoffer for the good explanations. Now I think I have understood what's one of the purposes of const. const arguments of a function just states that you aren't going to change the data inside a function/method, more or less like in C++, but in a transitive way.<snip>But it doesn't work, so maybe in and const are the same thing now. Is "in" going to be removed then? Or maybe it's better to remove const and keep just a transitive "in". And I have seen "immutable ref" too is allowed, I guess it's mostly for performance reasons. Maybe "immutable in" is just for show, this works: So the available ones are ("in" not listed to keep a bit of my sanity): immutable type const type out type immutable ref type const ref type type type* type** etcOn the language/functions page: "The in storage class is equivalent to const scope." I hope that clears everything up for you! :-) Paul
Apr 28 2009
bearophile Wrote: <snip>it prints: "redundant storage class in". So const and "in" seem really the same thing. But then what does it mean "immutable in"? I guess it just means transitive-immutable. "immutable out" and "const out" are thankfully disallowed. So I guess "in" is now deprecated, it's just an alias of "const. But this idea seems wrong because "in ref" is disalloed but "const ref" is allowed, so they aren't just an alias of each other. So the available ones are ("in" not listed to keep a bit of my sanity): immutable type const type out type immutable ref type const ref type type type* type** etc<snip> From the D2.0/Language/Functions page, under Function Parameters: "The in storage class is equivalent to const scope." That's why the "const in" combination doesn't work. Paul "I can't tell a lie -- not even when I hear one." John Kendrik Bangs, A House-Boat on the Styx.
Apr 28 2009
Paul D. Anderson:From the D2.0/Language/Functions page, under Function Parameters: "The in storage class is equivalent to const scope." That's why the "const in" combination doesn't work.Why is this working then, and printing 100? import std.stdio: writeln; void foo(const ref int x) { writeln(x * 10); } void main() { int y = 10; foo(y); } Note that the following doesn't compile: void foo(in ref int x) { Bye, bearophile
Apr 28 2009
bearophile wrote:Paul D. Anderson:You are not changig x here. The x*10 just multiplies and returns its result to writeln.From the D2.0/Language/Functions page, under Function Parameters: "The in storage class is equivalent to const scope." That's why the "const in" combination doesn't work.Why is this working then, and printing 100? import std.stdio: writeln; void foo(const ref int x) { writeln(x * 10); }void main() { int y = 10; foo(y); } Note that the following doesn't compile: void foo(in ref int x) { Bye, bearophile
Apr 29 2009