D - Lexical Closures and D
- Walter (10/10) Feb 25 2003 The exciting thing about nested functions, delegates, closures, literals...
- Dan Liebgold (16/26) Feb 25 2003 Ack... I think I might have misled you. I've done some looking around f...
- Dan Liebgold (15/15) Feb 25 2003 Ack, I may have misled you... in my search for info on closures, I've di...
- Dan Liebgold (2/17) Feb 25 2003
- Patrick Down (71/74) Feb 25 2003 Not a great example but here's wordcount recast.
- Patrick Down (62/65) Feb 26 2003 A sorting example. Not really what you are looking for either and it do...
- Walter (7/72) Feb 26 2003 Yes, a sort might do the trick. In my own work, I've had to use globals ...
- Antti Sykari (6/16) Mar 08 2003 Touching the topic of closures...
The exciting thing about nested functions, delegates, closures, literals, etc. in D is that as I was implementing them and exchanging ideas about how to do it with Burton, I got the feeling that I was *discovering* something that was already in D. The reason is they fit so seamlessly into both the syntax and semantics already existing. Class member delegates and nested function delegates turned out to be the same thing! It's really fun when that happens. Anyhow, I want to write an article about it, but I need a seminal example that's short, sweet, and captures the essence of this style of programming. Anyone have any ideas?
Feb 25 2003
Ack... I think I might have misled you. I've done some looking around for good descriptions of the types of closures, and it seems lexical closures are the real closures, and dynamic closures are the D (and old Lisp) style closures. It relates to the scope of the variables in the frame of the function definition... whether they will have lexical or dynamic scope. Dynamic scope refers essentially to stack-based locals, or locals with dynamic extent (they leave scope when the execution thread exits their containing block). Lexical scope is when variables' extents are dicated by the structure of the source.. that is if I call function A, A should get the scope of its definition as written in the source (d*mn the implementation). Check out http://www.dreamsongs.com/NewFiles/HOPL2-Uncut.pdf to see a history of the transition from dynamic scope/closure to lexical scope/closure in Lisp. It appears that at this point even the term "dynamic scope" is long dead in that community. Hopefully I'm not confusing things further... In article <b3gn23$1e86$1 digitaldaemon.com>, Walter says...The exciting thing about nested functions, delegates, closures, literals, etc. in D is that as I was implementing them and exchanging ideas about how to do it with Burton, I got the feeling that I was *discovering* something that was already in D. The reason is they fit so seamlessly into both the syntax and semantics already existing. Class member delegates and nested function delegates turned out to be the same thing! It's really fun when that happens. Anyhow, I want to write an article about it, but I need a seminal example that's short, sweet, and captures the essence of this style of programming. Anyone have any ideas?
Feb 25 2003
Ack, I may have misled you... in my search for info on closures, I've discovered that lexical closure generally refers to "real" closures, and the D style closures are generally called dynamic closures. Dynamic closures mean the "captured" variables have dynamic scope, which means they are valid only as long as the execution thread is in their code block or subblock. Lexical closures means that variables are captures according to lexical scoping, which means the scope is dictated by the structure of the source code. So if you call function A -- even if its from another scope through a delegate -- A must be able to access its environment as it exists in A's definition, let the implementation be d*mned. For a perspective on the transition from dynamic to lexical scoping/closure, see http://www.dreamsongs.com/NewFiles/HOPL2-Uncut.pdf. It seems that in the Lisp community, dynamic closure is a dead idea. Hopefully I haven't confused things further...
Feb 25 2003
Sorry for the double post. In article <b3gsnm$1icm$1 digitaldaemon.com>, Dan Liebgold says...Ack, I may have misled you... in my search for info on closures, I've discovered that lexical closure generally refers to "real" closures, and the D style closures are generally called dynamic closures. Dynamic closures mean the "captured" variables have dynamic scope, which means they are valid only as long as the execution thread is in their code block or subblock. Lexical closures means that variables are captures according to lexical scoping, which means the scope is dictated by the structure of the source code. So if you call function A -- even if its from another scope through a delegate -- A must be able to access its environment as it exists in A's definition, let the implementation be d*mned. For a perspective on the transition from dynamic to lexical scoping/closure, see http://www.dreamsongs.com/NewFiles/HOPL2-Uncut.pdf. It seems that in the Lisp community, dynamic closure is a dead idea. Hopefully I haven't confused things further...
Feb 25 2003
"Walter" <walter digitalmars.com> wrote in news:b3gn23$1e86$1 digitaldaemon.com:Anyhow, I want to write an article about it, but I need a seminal example that's short, sweet, and captures the essence of this style of programming. Anyone have any ideas?Not a great example but here's wordcount recast. BTW, http://www.digitalmars.com/d/index.html doesn't compile. import file; import ctype; void withWordsFromFile(char[] file, void delegate(char[]) callback) { char[] input; bit inword; int wstart; input = cast(char[])file.read(); for (int j = 0; j < input.length; j++) { if (isalpha(input[j])) { if (!inword) { wstart = j; inword = 1; } } else if (inword) { callback(input[wstart .. j]); inword = false; } } if (inword) { callback(input[wstart .. input.length]); } } int main (char[][] args) { int w_total; int[char[]] dictionary; for (int i = 1; i < args.length; ++i) { try { int w_cnt; void wordHandler(char[] word) { dictionary[word]++; w_cnt++; } withWordsFromFile(args[i],&wordHandler); printf("%.*s : %d words\n", args[i], w_cnt); w_total += w_cnt; } catch(FileError e) { printf("%.*s\n",e.toString()); } } if (args.length > 2) { printf("%d words total", w_total); } printf("--------------------------------------\n"); char[][] keys = dictionary.keys; for (int i = 0; i < keys.length; i++) { char[] word; word = keys[i]; printf("%3d %.*s\n", dictionary[word], word); } return 0; }
Feb 25 2003
In article <b3gn23$1e86$1 digitaldaemon.com>, Walter says...Anyhow, I want to write an article about it, but I need a seminal example that's short, sweet, and captures the essence of this style of programming. Anyone have any ideas?A sorting example. Not really what you are looking for either and it does not access local scoped variables. But perhaps it will sparks some ideas. template SortTemplate(Type) { void insertionSort(Type array[], bit delegate(Type a,Type b) lessThan) { for (int i=1; i < array.length; i++) { Type index = array[i]; int j = i; while ((j > 0) && lessThan(index,array[j-1])) { array[j] = array[j-1]; j = j - 1; } array[j] = index; } } } class Person { this(char[] n, int a) { name = n; age = a; } char[] name; int age; } alias instance SortTemplate(Person).insertionSort PersonSort; void PrintByName(Person[] people) { PersonSort(people, delegate bit(Person a, Person b) { return a.name < b.name; } ); printf("\nPeople by sorted by name\n========================\n"); for(int i = 0; i < people.length; ++i) printf("%.*s,%d\n",people[i].name,people[i].age); } void PrintByAge(Person[] people) { PersonSort(people, delegate bit(Person a, Person b) { return a.age < b.age; } ); printf("\nPeople by sorted by age\n========================\n"); for(int i = 0; i < people.length; ++i) printf("%.*s,%d\n",people[i].name,people[i].age); } void main(char[][] argv) { Person people[]; // Naughty people ~= new Person("Zeb",27); people ~= new Person("Betty",22); people ~= new Person("Casy",15); people ~= new Person("Mike",50); people ~= new Person("Linda",12); people ~= new Person("Freda",33); people ~= new Person("Rudy",45); people ~= new Person("Holly",18); PrintByName(people); PrintByAge(people); }
Feb 26 2003
Yes, a sort might do the trick. In my own work, I've had to use globals and semaphores to pass context info to the qsort sorting function. Ugh. Nested functions will work much better. "Patrick Down" <Patrick_member pathlink.com> wrote in message news:b3j6je$19a$1 digitaldaemon.com...In article <b3gn23$1e86$1 digitaldaemon.com>, Walter says...programming.Anyhow, I want to write an article about it, but I need a seminal example that's short, sweet, and captures the essence of this style ofnotAnyone have any ideas?A sorting example. Not really what you are looking for either and it doesaccess local scoped variables. But perhaps it will sparks some ideas. template SortTemplate(Type) { void insertionSort(Type array[], bit delegate(Type a,Type b) lessThan) { for (int i=1; i < array.length; i++) { Type index = array[i]; int j = i; while ((j > 0) && lessThan(index,array[j-1])) { array[j] = array[j-1]; j = j - 1; } array[j] = index; } } } class Person { this(char[] n, int a) { name = n; age = a; } char[] name; int age; } alias instance SortTemplate(Person).insertionSort PersonSort; void PrintByName(Person[] people) { PersonSort(people, delegate bit(Person a, Person b) { return a.name < b.name; } ); printf("\nPeople by sorted by name\n========================\n"); for(int i = 0; i < people.length; ++i) printf("%.*s,%d\n",people[i].name,people[i].age); } void PrintByAge(Person[] people) { PersonSort(people, delegate bit(Person a, Person b) { return a.age < b.age; } ); printf("\nPeople by sorted by age\n========================\n"); for(int i = 0; i < people.length; ++i) printf("%.*s,%d\n",people[i].name,people[i].age); } void main(char[][] argv) { Person people[]; // Naughty people ~= new Person("Zeb",27); people ~= new Person("Betty",22); people ~= new Person("Casy",15); people ~= new Person("Mike",50); people ~= new Person("Linda",12); people ~= new Person("Freda",33); people ~= new Person("Rudy",45); people ~= new Person("Holly",18); PrintByName(people); PrintByAge(people); }
Feb 26 2003
"Walter" <walter digitalmars.com> writes:The exciting thing about nested functions, delegates, closures, literals, etc. in D is that as I was implementing them and exchanging ideas about how to do it with Burton, I got the feeling that I was *discovering* something that was already in D. The reason is they fit so seamlessly into both the syntax and semantics already existing. Class member delegates and nested function delegates turned out to be the same thing! It's really fun when that happens. Anyhow, I want to write an article about it, but I need a seminal example that's short, sweet, and captures the essence of this style of programming. Anyone have any ideas?Touching the topic of closures... There's currently a discussion about "Closures vs. objects" at comp.lang.lisp that I found quite interesting: http://groups.google.com/groups?selm=ccc7084.0303042203.f057f86%40posting.google.com -Antti
Mar 08 2003