From: =?iso-8859-1?Q?Bj=F6rn?= Lindberg on
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
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
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
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
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