D - functions and derived types
- LuigiG (12/12) Aug 17 2001 Hi All,
- Walter (3/13) Aug 17 2001 Functions are a derived type too. I'll fix the doc. -Walter
- Dan Hursh (15/33) Aug 24 2001 This looks like a great place to stir up a mess. How about anonymous
- Walter (3/17) Aug 29 2001 Anonymous functions are a good idea, I'll have to think about it. -Walte...
- Dan Hursh (60/82) Aug 29 2001 Geez! I was expecting to get shot down on this one. I always do when
- Walter (2/84) Sep 23 2001
- a (22/119) Sep 24 2001 Do you think there would be a way to pass info from the outside world
- Yu Qian Zhou (0/0) Sep 24 2001
- Walter (11/130) Sep 25 2001 The most obvious model for doing that is Pascal, which gives nested
- a (8/146) Sep 26 2001 Can you pass around pointers to functions in pascal? I don't know
- Axel Kittenberger (17/25) Sep 27 2001 Very interesting question, indeed.
- a (14/23) Sep 29 2001 Well, I'll agree that java won't let you see your foot, but I'll go with
Hi All, I had a look at the specifications of D, after reading the article on (surprise! ;-) Slashdot 1st comment: It looks great! ;-) I'd really like to get my hands on a D compiler. 2nd, one question: In the section "TYPES"; why isn't "function returning.." mentioned as a derived type? How/where do functions fit in D's type system? (apologies if this has been asked already) Cheers, --Luigi
Aug 17 2001
LuigiG wrote in message <9ljn4e$239i$1 digitaldaemon.com>...Hi All, I had a look at the specifications of D, after reading the article on (surprise! ;-) Slashdot 1st comment: It looks great! ;-) I'd really like to get my hands on a D compiler.Thanks!2nd, one question: In the section "TYPES"; why isn't "function returning.." mentioned as a derived type? How/where do functions fit in D's type system? (apologies if this has been asked already)Functions are a derived type too. I'll fix the doc. -Walter
Aug 17 2001
Walter wrote:LuigiG wrote in message <9ljn4e$239i$1 digitaldaemon.com>...This looks like a great place to stir up a mess. How about anonymous functions? Granted, they would be worth more once a good solution is found for generics. Say anywhere you could pass a pointer to function you could also write an inline int[] list = transform(otherlist, lambda(int x){return x*x;}; Just to note, I'm endorsing the functionality, but not necessarily this syntax. I just know I writing a million different little functions in C/C++ to print a variable a certain way or to install a temporary event handler of some sort is messy and it just makes me feel dirty. Some tasks are so trivial that they don't deserve a name or they should be "declared" where they are needed for clarity. I will punt on the issue of using variables in the enclosing scope (closure style) until I see how this is excepted. :-> DanHi All, I had a look at the specifications of D, after reading the article on (surprise! ;-) Slashdot 1st comment: It looks great! ;-) I'd really like to get my hands on a D compiler.Thanks!2nd, one question: In the section "TYPES"; why isn't "function returning.." mentioned as a derived type? How/where do functions fit in D's type system? (apologies if this has been asked already)Functions are a derived type too. I'll fix the doc. -Walter
Aug 24 2001
Anonymous functions are a good idea, I'll have to think about it. -Walter "Dan Hursh" <hursh infonet.isl.net> wrote in message news:3B873562.896B7FED infonet.isl.net...This looks like a great place to stir up a mess. How about anonymous functions? Granted, they would be worth more once a good solution is found for generics. Say anywhere you could pass a pointer to function you could also write an inline int[] list = transform(otherlist, lambda(int x){return x*x;}; Just to note, I'm endorsing the functionality, but not necessarily this syntax. I just know I writing a million different little functions in C/C++ to print a variable a certain way or to install a temporary event handler of some sort is messy and it just makes me feel dirty. Some tasks are so trivial that they don't deserve a name or they should be "declared" where they are needed for clarity. I will punt on the issue of using variables in the enclosing scope (closure style) until I see how this is excepted. :-> Dan
Aug 29 2001
Geez! I was expecting to get shot down on this one. I always do when I suggest it for C++. Now I feel obligated to go into the ideas I've had for enclosing scopes. Oh well, feel free to say if this is too much. 1) static scope This is the easiest. The anon gets no variable from the enclosing scope. It is a function like any other. If declared in an object, go ahead and give it object scope if that isn't too hard. Passing around a reference to the anon is safe. int f(){ int i = 5; thing t[8]; map(t, anon(thing t){t.add(i++);}); // illegal return i; } 2) implied copy This is similar to the above. The difference is that the code above would work. Any use of variable would imply a local variable set to the same variable within the anon. The anon does not share the variable though. It only copies that value, so f() would return 5. The best way to implement this is to implicitly create an object that contain the variable referenced and copy the values in the object where the anon is declared. The anon would run in this object's scope, so passing a reference to the anon out of the scope where it was declared would work. 3) implied reference In this case, the example for 1 would work. The anon would have references to the real variables in the enclosing scope. In this case then, f() would return 13; Now this has a serious potential for gross errors. If a reference to the anon were to be passed around, any variables referenced from an enclosing scope would be out of scope after exiting the enclosing scope. Since objects and arrays are all dynamically allocated they could be safe, but built-ins are a serious problem. Unfortunately the compiler probably could not detect all the way a function pointer could get passed beyond it's scope. We should only pick this one if we are willing to live with the possibility for misuse. Think of it like the delete operator. Powerful, but easily misused. 4) anonymous object scope Here we have another anonymous object created. This time however, the object is created when you enter a scope that uses an anon. Any variable that an anon might use from that scope is in the object instead of on the stack. All the anons in the scope share this object with the enclosing scope. When exiting the scope defining the object, any anons that are still referenced would share this object. Re-entering the scope would create a new object. This is the safest. I think it might be real closures. (I always get confused about what is or isn't a closure. If it is, it is. If it's not, it's not.) There may be the need to have an object of each scope, and the anon would have to reference the object of each scope contain a variable it references. This is also the most complex and hence the most likely to get turned down. Well maybe 3 would get turned down first. Anyhow, I know this might be inappropriate for D given it's design goals, but I've missed anonymous functions ever since I played with my lisp-a-like. Dan Walter wrote:Anonymous functions are a good idea, I'll have to think about it. -Walter "Dan Hursh" <hursh infonet.isl.net> wrote in message news:3B873562.896B7FED infonet.isl.net...This looks like a great place to stir up a mess. How about anonymous functions? Granted, they would be worth more once a good solution is found for generics. Say anywhere you could pass a pointer to function you could also write an inline int[] list = transform(otherlist, lambda(int x){return x*x;}; Just to note, I'm endorsing the functionality, but not necessarily this syntax. I just know I writing a million different little functions in C/C++ to print a variable a certain way or to install a temporary event handler of some sort is messy and it just makes me feel dirty. Some tasks are so trivial that they don't deserve a name or they should be "declared" where they are needed for clarity. I will punt on the issue of using variables in the enclosing scope (closure style) until I see how this is excepted. :-> Dan
Aug 29 2001
Making them static is the best idea. Dan Hursh wrote in message <3B8DCC3E.D59FEA4A infonet.isl.net>...Geez! I was expecting to get shot down on this one. I always do when I suggest it for C++. Now I feel obligated to go into the ideas I've had for enclosing scopes. Oh well, feel free to say if this is too much. 1) static scope This is the easiest. The anon gets no variable from the enclosing scope. It is a function like any other. If declared in an object, go ahead and give it object scope if that isn't too hard. Passing around a reference to the anon is safe. int f(){ int i = 5; thing t[8]; map(t, anon(thing t){t.add(i++);}); // illegal return i; } 2) implied copy This is similar to the above. The difference is that the code above would work. Any use of variable would imply a local variable set to the same variable within the anon. The anon does not share the variable though. It only copies that value, so f() would return 5. The best way to implement this is to implicitly create an object that contain the variable referenced and copy the values in the object where the anon is declared. The anon would run in this object's scope, so passing a reference to the anon out of the scope where it was declared would work. 3) implied reference In this case, the example for 1 would work. The anon would have references to the real variables in the enclosing scope. In this case then, f() would return 13; Now this has a serious potential for gross errors. If a reference to the anon were to be passed around, any variables referenced from an enclosing scope would be out of scope after exiting the enclosing scope. Since objects and arrays are all dynamically allocated they could be safe, but built-ins are a serious problem. Unfortunately the compiler probably could not detect all the way a function pointer could get passed beyond it's scope. We should only pick this one if we are willing to live with the possibility for misuse. Think of it like the delete operator. Powerful, but easily misused. 4) anonymous object scope Here we have another anonymous object created. This time however, the object is created when you enter a scope that uses an anon. Any variable that an anon might use from that scope is in the object instead of on the stack. All the anons in the scope share this object with the enclosing scope. When exiting the scope defining the object, any anons that are still referenced would share this object. Re-entering the scope would create a new object. This is the safest. I think it might be real closures. (I always get confused about what is or isn't a closure. If it is, it is. If it's not, it's not.) There may be the need to have an object of each scope, and the anon would have to reference the object of each scope contain a variable it references. This is also the most complex and hence the most likely to get turned down. Well maybe 3 would get turned down first. Anyhow, I know this might be inappropriate for D given it's design goals, but I've missed anonymous functions ever since I played with my lisp-a-like. Dan Walter wrote:Anonymous functions are a good idea, I'll have to think about it. -Walter "Dan Hursh" <hursh infonet.isl.net> wrote in message news:3B873562.896B7FED infonet.isl.net...This looks like a great place to stir up a mess. How about anonymous functions? Granted, they would be worth more once a good solution is found for generics. Say anywhere you could pass a pointer to function you could also write an inline int[] list = transform(otherlist, lambda(int x){return x*x;}; Just to note, I'm endorsing the functionality, but not necessarily this syntax. I just know I writing a million different little functions in C/C++ to print a variable a certain way or to install a temporary event handler of some sort is messy and it just makes me feel dirty. Some tasks are so trivial that they don't deserve a name or they should be "declared" where they are needed for clarity. I will punt on the issue of using variables in the enclosing scope (closure style) until I see how this is excepted. :-> Dan
Sep 23 2001
Do you think there would be a way to pass info from the outside world (say the block that declares the function) into the declaration of the function that would not violate the design goals of D? That would make them a lot more useful. It would be nice to be able the get result back, but that could be done with a pointer if there is a way to pass data into it. int foo(int a[], char prefix[]){ int ret = 0; // yes I know it's redundant // and yes I know a for() would work just fine here map(t, annon(int i){ printf("%.*s %d\n", prefix, i); ret += i; }); return ret; // it's just an example } This is an idealized chunk of code. I know the static version would require a lot less (almost no?) black magic in the compiler. Static annons would be cool, but the above feature (though maybe not the syntax) will be the first thing people ask for after they see annons. Just thought I'd see what you think would be the hardest part. Dan Walter wrote:Making them static is the best idea. Dan Hursh wrote in message <3B8DCC3E.D59FEA4A infonet.isl.net>...Geez! I was expecting to get shot down on this one. I always do when I suggest it for C++. Now I feel obligated to go into the ideas I've had for enclosing scopes. Oh well, feel free to say if this is too much. 1) static scope This is the easiest. The anon gets no variable from the enclosing scope. It is a function like any other. If declared in an object, go ahead and give it object scope if that isn't too hard. Passing around a reference to the anon is safe. int f(){ int i = 5; thing t[8]; map(t, anon(thing t){t.add(i++);}); // illegal return i; } 2) implied copy This is similar to the above. The difference is that the code above would work. Any use of variable would imply a local variable set to the same variable within the anon. The anon does not share the variable though. It only copies that value, so f() would return 5. The best way to implement this is to implicitly create an object that contain the variable referenced and copy the values in the object where the anon is declared. The anon would run in this object's scope, so passing a reference to the anon out of the scope where it was declared would work. 3) implied reference In this case, the example for 1 would work. The anon would have references to the real variables in the enclosing scope. In this case then, f() would return 13; Now this has a serious potential for gross errors. If a reference to the anon were to be passed around, any variables referenced from an enclosing scope would be out of scope after exiting the enclosing scope. Since objects and arrays are all dynamically allocated they could be safe, but built-ins are a serious problem. Unfortunately the compiler probably could not detect all the way a function pointer could get passed beyond it's scope. We should only pick this one if we are willing to live with the possibility for misuse. Think of it like the delete operator. Powerful, but easily misused. 4) anonymous object scope Here we have another anonymous object created. This time however, the object is created when you enter a scope that uses an anon. Any variable that an anon might use from that scope is in the object instead of on the stack. All the anons in the scope share this object with the enclosing scope. When exiting the scope defining the object, any anons that are still referenced would share this object. Re-entering the scope would create a new object. This is the safest. I think it might be real closures. (I always get confused about what is or isn't a closure. If it is, it is. If it's not, it's not.) There may be the need to have an object of each scope, and the anon would have to reference the object of each scope contain a variable it references. This is also the most complex and hence the most likely to get turned down. Well maybe 3 would get turned down first. Anyhow, I know this might be inappropriate for D given it's design goals, but I've missed anonymous functions ever since I played with my lisp-a-like. Dan Walter wrote:Anonymous functions are a good idea, I'll have to think about it. -Walter "Dan Hursh" <hursh infonet.isl.net> wrote in message news:3B873562.896B7FED infonet.isl.net...This looks like a great place to stir up a mess. How about anonymous functions? Granted, they would be worth more once a good solution is found for generics. Say anywhere you could pass a pointer to function you could also write an inline int[] list = transform(otherlist, lambda(int x){return x*x;}; Just to note, I'm endorsing the functionality, but not necessarily this syntax. I just know I writing a million different little functions in C/C++ to print a variable a certain way or to install a temporary event handler of some sort is messy and it just makes me feel dirty. Some tasks are so trivial that they don't deserve a name or they should be "declared" where they are needed for clarity. I will punt on the issue of using variables in the enclosing scope (closure style) until I see how this is excepted. :-> Dan
Sep 24 2001
The most obvious model for doing that is Pascal, which gives nested functions access to lexically enclosed local variables. -Walter a wrote in message <3BAFEA9E.2FAE409 b.c>...Do you think there would be a way to pass info from the outside world (say the block that declares the function) into the declaration of the function that would not violate the design goals of D? That would make them a lot more useful. It would be nice to be able the get result back, but that could be done with a pointer if there is a way to pass data into it. int foo(int a[], char prefix[]){ int ret = 0; // yes I know it's redundant // and yes I know a for() would work just fine here map(t, annon(intprintf("%.*s %d\n", prefix, i); ret += i; }); return ret; // it's just an example } This is an idealized chunk of code. I know the static version would require a lot less (almost no?) black magic in the compiler. Static annons would be cool, but the above feature (though maybe not the syntax) will be the first thing people ask for after they see annons. Just thought I'd see what you think would be the hardest part. Dan Walter wrote:it. -WalterMaking them static is the best idea. Dan Hursh wrote in message <3B8DCC3E.D59FEA4A infonet.isl.net>...Geez! I was expecting to get shot down on this one. I always do when I suggest it for C++. Now I feel obligated to go into the ideas I've had for enclosing scopes. Oh well, feel free to say if this is too much. 1) static scope This is the easiest. The anon gets no variable from the enclosing scope. It is a function like any other. If declared in an object, go ahead and give it object scope if that isn't too hard. Passing around a reference to the anon is safe. int f(){ int i = 5; thing t[8]; map(t, anon(thing t){t.add(i++);}); // illegal return i; } 2) implied copy This is similar to the above. The difference is that the code above would work. Any use of variable would imply a local variable set to the same variable within the anon. The anon does not share the variable though. It only copies that value, so f() would return 5. The best way to implement this is to implicitly create an object that contain the variable referenced and copy the values in the object where the anon is declared. The anon would run in this object's scope, so passing a reference to the anon out of the scope where it was declared would work. 3) implied reference In this case, the example for 1 would work. The anon would have references to the real variables in the enclosing scope. In this case then, f() would return 13; Now this has a serious potential for gross errors. If a reference to the anon were to be passed around, any variables referenced from an enclosing scope would be out of scope after exiting the enclosing scope. Since objects and arrays are all dynamically allocated they could be safe, but built-ins are a serious problem. Unfortunately the compiler probably could not detect all the way a function pointer could get passed beyond it's scope. We should only pick this one if we are willing to live with the possibility for misuse. Think of it like the delete operator. Powerful, but easily misused. 4) anonymous object scope Here we have another anonymous object created. This time however, the object is created when you enter a scope that uses an anon. Any variable that an anon might use from that scope is in the object instead of on the stack. All the anons in the scope share this object with the enclosing scope. When exiting the scope defining the object, any anons that are still referenced would share this object. Re-entering the scope would create a new object. This is the safest. I think it might be real closures. (I always get confused about what is or isn't a closure. If it is, it is. If it's not, it's not.) There may be the need to have an object of each scope, and the anon would have to reference the object of each scope contain a variable it references. This is also the most complex and hence the most likely to get turned down. Well maybe 3 would get turned down first. Anyhow, I know this might be inappropriate for D given it's design goals, but I've missed anonymous functions ever since I played with my lisp-a-like. Dan Walter wrote:Anonymous functions are a good idea, I'll have to think aboutanonymous"Dan Hursh" <hursh infonet.isl.net> wrote in message news:3B873562.896B7FED infonet.isl.net...This looks like a great place to stir up a mess. How aboutisfunctions? Granted, they would be worth more once a good solutionfunctionfound for generics. Say anywhere you could pass a pointer tothisyou could also write an inline int[] list = transform(otherlist, lambda(int x){return x*x;}; Just to note, I'm endorsing the functionality, but not necessarilyinsyntax. I just know I writing a million different little functionseventC/C++ to print a variable a certain way or to install a temporarybehandler of some sort is messy and it just makes me feel dirty. Some tasks are so trivial that they don't deserve a name or they should"declared" where they are needed for clarity. I will punt on the issue of using variables in the enclosing scope (closure style) until I see how this is excepted. :-> Dan
Sep 25 2001
Can you pass around pointers to functions in pascal? I don't know pascal well enough to know. If so, did they try to do something to keep the user from returning a pointer to the nested function? I don't think any C based language should have to, but I always got the impression that the pascal based languages tried to keep the programmer from shooting himself in the foot at (almost) any expense. Dan Walter wrote:The most obvious model for doing that is Pascal, which gives nested functions access to lexically enclosed local variables. -Walter a wrote in message <3BAFEA9E.2FAE409 b.c>...Do you think there would be a way to pass info from the outside world (say the block that declares the function) into the declaration of the function that would not violate the design goals of D? That would make them a lot more useful. It would be nice to be able the get result back, but that could be done with a pointer if there is a way to pass data into it. int foo(int a[], char prefix[]){ int ret = 0; // yes I know it's redundant // and yes I know a for() would work just fine here map(t, annon(intprintf("%.*s %d\n", prefix, i); ret += i; }); return ret; // it's just an example } This is an idealized chunk of code. I know the static version would require a lot less (almost no?) black magic in the compiler. Static annons would be cool, but the above feature (though maybe not the syntax) will be the first thing people ask for after they see annons. Just thought I'd see what you think would be the hardest part. Dan Walter wrote:it. -WalterMaking them static is the best idea. Dan Hursh wrote in message <3B8DCC3E.D59FEA4A infonet.isl.net>...Geez! I was expecting to get shot down on this one. I always do when I suggest it for C++. Now I feel obligated to go into the ideas I've had for enclosing scopes. Oh well, feel free to say if this is too much. 1) static scope This is the easiest. The anon gets no variable from the enclosing scope. It is a function like any other. If declared in an object, go ahead and give it object scope if that isn't too hard. Passing around a reference to the anon is safe. int f(){ int i = 5; thing t[8]; map(t, anon(thing t){t.add(i++);}); // illegal return i; } 2) implied copy This is similar to the above. The difference is that the code above would work. Any use of variable would imply a local variable set to the same variable within the anon. The anon does not share the variable though. It only copies that value, so f() would return 5. The best way to implement this is to implicitly create an object that contain the variable referenced and copy the values in the object where the anon is declared. The anon would run in this object's scope, so passing a reference to the anon out of the scope where it was declared would work. 3) implied reference In this case, the example for 1 would work. The anon would have references to the real variables in the enclosing scope. In this case then, f() would return 13; Now this has a serious potential for gross errors. If a reference to the anon were to be passed around, any variables referenced from an enclosing scope would be out of scope after exiting the enclosing scope. Since objects and arrays are all dynamically allocated they could be safe, but built-ins are a serious problem. Unfortunately the compiler probably could not detect all the way a function pointer could get passed beyond it's scope. We should only pick this one if we are willing to live with the possibility for misuse. Think of it like the delete operator. Powerful, but easily misused. 4) anonymous object scope Here we have another anonymous object created. This time however, the object is created when you enter a scope that uses an anon. Any variable that an anon might use from that scope is in the object instead of on the stack. All the anons in the scope share this object with the enclosing scope. When exiting the scope defining the object, any anons that are still referenced would share this object. Re-entering the scope would create a new object. This is the safest. I think it might be real closures. (I always get confused about what is or isn't a closure. If it is, it is. If it's not, it's not.) There may be the need to have an object of each scope, and the anon would have to reference the object of each scope contain a variable it references. This is also the most complex and hence the most likely to get turned down. Well maybe 3 would get turned down first. Anyhow, I know this might be inappropriate for D given it's design goals, but I've missed anonymous functions ever since I played with my lisp-a-like. Dan Walter wrote:Anonymous functions are a good idea, I'll have to think aboutanonymous"Dan Hursh" <hursh infonet.isl.net> wrote in message news:3B873562.896B7FED infonet.isl.net...This looks like a great place to stir up a mess. How aboutisfunctions? Granted, they would be worth more once a good solutionfunctionfound for generics. Say anywhere you could pass a pointer tothisyou could also write an inline int[] list = transform(otherlist, lambda(int x){return x*x;}; Just to note, I'm endorsing the functionality, but not necessarilyinsyntax. I just know I writing a million different little functionseventC/C++ to print a variable a certain way or to install a temporarybehandler of some sort is messy and it just makes me feel dirty. Some tasks are so trivial that they don't deserve a name or they should"declared" where they are needed for clarity. I will punt on the issue of using variables in the enclosing scope (closure style) until I see how this is excepted. :-> Dan
Sep 26 2001
a wrote:Can you pass around pointers to functions in pascal? I don't know pascal well enough to know.Yes you can.If so, did they try to do something to keep the user from returning a pointer to the nested function?Very interesting question, indeed. I just tried it out. At least in 'GNU Pascal version 19991030, based on 2.95.2 19991024 (release)' nothing prevents you from doing this. If you access arguments in the inner function from the outer one you get random results :( Might be worth checking out on newer release / reporting on their mailing list.I don't think any C based language should have to, but I always got the impression that the pascal based languages tried to keep the programmer from shooting himself in the foot at (almost) any expense.Well pascal tried that, but didn't really succeed. You can also as good call a function pointer holding yet null. However might be interesting that java is in principle C based and yet keeps you 100% assured not to reach your foot anyway, or to see it at all :o) - Axel \ |D> http://www.dtone.org /
Sep 27 2001
Axel Kittenberger wrote:Well, I'll agree that java won't let you see your foot, but I'll go with http://www.claessens16.yucom.be/howto.htm as to shooting yourself in the foot: Java The gun fires just fine, but your foot can't figure out what the bullets are and ignores them. http://duff.geology.washington.edu/mdbrg/staff_pages/shootfoot.html and http://compsoc.ucc.ie/joke14.html kind of agrees with you though: Java: You can do it with a standalone interpreter, but a java applet will not let you access your foot. Java The Java Verifier will not allow you to handle a Gun. DanI don't think any C based language should have to, but I always got the impression that the pascal based languages tried to keep the programmer from shooting himself in the foot at (almost) any expense.Well pascal tried that, but didn't really succeed. You can also as good call a function pointer holding yet null. However might be interesting that java is in principle C based and yet keeps you 100% assured not to reach your foot anyway, or to see it at all :o)
Sep 29 2001