From: =?iso-8859-1?Q?Bj=F6rn?= Lindberg on 3 Aug 2010 03:25 RG <rNOSPAMon(a)flownet.com> writes: > But that is exactly what puzzles me. You see the value in latent > typing, but not in abstraction. And yet the value in those two things > is exactly the same, namely, the ability to write code in a way that > lets you defer decisions. So I don't understand how you can value one > and not the other. If I may interject, I do see value in abstraction, but it will usually take a different form than what you propose. Let's say that we in our program have objects of the kind foo, indexed by bar, stored in collections bork. You do not want to prematurely select the implementation of bork to be either hash tables, alists or something else. You now write accessors like ADD-FOO, FIND-FOO, and the like, essentially creating an ADT specific to the program. This ADT encapsulates whatever implementation is chosen for bork, making change later easy. The advantages of this approach are plenty: The accessors can be written to fit the semantics of foo, bar and bork, rather than shoe-horning the behaviour of those into some generic collections framework. It makes the code much more descriptive of what it is doing than if it is sprinkled with "generic" REF calls, which from a documentation perspective is even worse than having it filled with calls to GETHASH. In other words, instead of using a generic collections framework which by necessity will have the semantics of a lowest common denominator and not the ones of your program, construct abstractions specific to your problem. What happened to the idea of building up the language to your problem? Bj�rn Lindberg
From: Alessio Stalla on 3 Aug 2010 03:54 On Aug 3, 9:25 am, bj...(a)runa.se (Björn Lindberg) wrote: > RG <rNOSPA...(a)flownet.com> writes: > > But that is exactly what puzzles me. You see the value in latent > > typing, but not in abstraction. And yet the value in those two things > > is exactly the same, namely, the ability to write code in a way that > > lets you defer decisions. So I don't understand how you can value one > > and not the other. > > If I may interject, I do see value in abstraction, but it will usually > take a different form than what you propose. > > Let's say that we in our program have objects of the kind foo, indexed > by bar, stored in collections bork. You do not want to prematurely > select the implementation of bork to be either hash tables, alists or > something else. You now write accessors like ADD-FOO, FIND-FOO, and the > like, essentially creating an ADT specific to the program. This ADT > encapsulates whatever implementation is chosen for bork, making change > later easy. The advantages of this approach are plenty: The accessors > can be written to fit the semantics of foo, bar and bork, rather than > shoe-horning the behaviour of those into some generic collections > framework. It makes the code much more descriptive of what it is doing > than if it is sprinkled with "generic" REF calls, which from a > documentation perspective is even worse than having it filled with calls > to GETHASH. > > In other words, instead of using a generic collections framework which > by necessity will have the semantics of a lowest common denominator and > not the ones of your program, construct abstractions specific to your > problem. > > What happened to the idea of building up the language to your problem? One abstraction does not exclude the other. Abstractions can be layered. In your example, ADD-FOO and FIND-FOO might call, say, CONCAT and FIND rather than CONS/APPEND and... the equivalent of FIND that only works on lists, if it existed. It all boils down to some common sense. Just like we use + rather than fixnum+, bignum+, float+, double+, it's often convenient to use ELT rather than AREF or NTH. In fact, of the CL operators that deal with lists, most actually abstract over lists and vectors (and other sequence types if the implementation allows them). Alessio
From: =?iso-8859-1?Q?Bj=F6rn?= Lindberg on 3 Aug 2010 08:02 Alessio Stalla <alessiostalla(a)gmail.com> writes: > On Aug 3, 9:25�am, bj...(a)runa.se (Bj�rn Lindberg) wrote: >> RG <rNOSPA...(a)flownet.com> writes: >> > But that is exactly what puzzles me. �You see the value in latent >> > typing, but not in abstraction. �And yet the value in those two things >> > is exactly the same, namely, the ability to write code in a way that >> > lets you defer decisions. �So I don't understand how you can value one >> > and not the other. >> >> If I may interject, I do see value in abstraction, but it will usually >> take a different form than what you propose. >> >> Let's say that we in our program have objects of the kind foo, indexed >> by bar, stored in collections bork. You do not want to prematurely >> select the implementation of bork to be either hash tables, alists or >> something else. You now write accessors like ADD-FOO, FIND-FOO, and the >> like, essentially creating an ADT specific to the program. This ADT >> encapsulates whatever implementation is chosen for bork, making change >> later easy. The advantages of this approach are plenty: The accessors >> can be written to fit the semantics of foo, bar and bork, rather than >> shoe-horning the behaviour of those into some generic collections >> framework. It makes the code much more descriptive of what it is doing >> than if it is sprinkled with "generic" REF calls, which from a >> documentation perspective is even worse than having it filled with calls >> to GETHASH. >> >> In other words, instead of using a generic collections framework which >> by necessity will have the semantics of a lowest common denominator and >> not the ones of your program, construct abstractions specific to your >> problem. >> >> What happened to the idea of building up the language to your problem? > > One abstraction does not exclude the other. Abstractions can be > layered. In your example, ADD-FOO and FIND-FOO might call, say, CONCAT > and FIND rather than CONS/APPEND and... the equivalent of FIND that > only works on lists, if it existed. That is true, but if you create custom ADTs and interfaces as needed, then what Ron advocates as the big advantage of generic collection frameworks, namely ease of refactoring, no longer speaks for them. > It all boils down to some common sense. Just like we use + rather than > fixnum+, bignum+, float+, double+, it's often convenient to use ELT > rather than AREF or NTH. No, these are two completely different topics. We do not use generic arithmetic operators to delay an implementation choice of which number type to use. Bj�rn Lindberg
From: Nick Keighley on 3 Aug 2010 08:59 On 2 Aug, 18:41, x <a...(a)b.c> wrote: > RG <rNOSPA...(a)flownet.com> wrote innews:rNOSPAMon-2C2847.23140231072010(a)news.albasani.net: > > OK, I guess we'll just have to agree to disagree about that. Maybe > > you never experienced the pain of having to make a change in a large > > system that was not properly abstracted. > > "Properly abstracted" is the issue. Good software uses a tree of > abstractions. If you have to make changes throughout your code because > of a change in usage of a collection abstraction, it's because the higher > level abstractions weren't done properly, not because the collection > abstraction wasn't done properly. > > If you change a list to a vector, why should you have to change access to > it in dozens of different places? Why not only in the abstraction where > the list or vector is used? > > That's the fallacy of the value of collection frameworks. They're > inherently low level. Programmers use them incorrectly as substitutes > for proper abstraction. ah! I'd been wondering how to put that. I'd been thinking "but SICP uses abstractions all over the place"
From: Alessio Stalla on 3 Aug 2010 09:02
On Aug 3, 2:02 pm, bj...(a)runa.se (Björn Lindberg) wrote: > Alessio Stalla <alessiosta...(a)gmail.com> writes: > > On Aug 3, 9:25 am, bj...(a)runa.se (Björn Lindberg) wrote: > >> RG <rNOSPA...(a)flownet.com> writes: > >> > But that is exactly what puzzles me. You see the value in latent > >> > typing, but not in abstraction. And yet the value in those two things > >> > is exactly the same, namely, the ability to write code in a way that > >> > lets you defer decisions. So I don't understand how you can value one > >> > and not the other. > > >> If I may interject, I do see value in abstraction, but it will usually > >> take a different form than what you propose. > > >> Let's say that we in our program have objects of the kind foo, indexed > >> by bar, stored in collections bork. You do not want to prematurely > >> select the implementation of bork to be either hash tables, alists or > >> something else. You now write accessors like ADD-FOO, FIND-FOO, and the > >> like, essentially creating an ADT specific to the program. This ADT > >> encapsulates whatever implementation is chosen for bork, making change > >> later easy. The advantages of this approach are plenty: The accessors > >> can be written to fit the semantics of foo, bar and bork, rather than > >> shoe-horning the behaviour of those into some generic collections > >> framework. It makes the code much more descriptive of what it is doing > >> than if it is sprinkled with "generic" REF calls, which from a > >> documentation perspective is even worse than having it filled with calls > >> to GETHASH. > > >> In other words, instead of using a generic collections framework which > >> by necessity will have the semantics of a lowest common denominator and > >> not the ones of your program, construct abstractions specific to your > >> problem. > > >> What happened to the idea of building up the language to your problem? > > > One abstraction does not exclude the other. Abstractions can be > > layered. In your example, ADD-FOO and FIND-FOO might call, say, CONCAT > > and FIND rather than CONS/APPEND and... the equivalent of FIND that > > only works on lists, if it existed. > > That is true, but if you create custom ADTs and interfaces as needed, > then what Ron advocates as the big advantage of generic collection > frameworks, namely ease of refactoring, no longer speaks for them. > > > It all boils down to some common sense. Just like we use + rather than > > fixnum+, bignum+, float+, double+, it's often convenient to use ELT > > rather than AREF or NTH. > > No, these are two completely different topics. We do not use generic > arithmetic operators to delay an implementation choice of which number > type to use. We use them because we don't care about the low-level details of how arithmetic operations are implemented on the CPU; we only care about summing numbers together. Similarly, at a higher level, there are cases when we don't care whether a sequence is a list or a vector; we just want to append an element to it, or change the value of the nth element, and so on. If there were no abstractions - and by that I mean no generic operations that abstract over several data types - then all the benefits of dynamic typing would be gone. If I have to write list-nth, vector-nth, int+, float+, ..., type-operation for each (type, operation) pair, I'm basically writing a statically-typed program that is just not checked for correctness at compile-time - i.e. the worst case possible :) Alessio > Björn Lindberg |