Account Options

  1. Sign in
The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Google Groups Home
« Groups Home
compiler-macro example shortage (was Re: Eureka! Lexical bindings can be guaranteed!)
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  Messages 76 - 100 of 132 - Collapse all  -  Translate all to Translated (View all originals) < Older  Newer >
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
Lieven Marchand  
View profile  
 More options Mar 11 2000, 3:00 am
Newsgroups: comp.lang.lisp
From: Lieven Marchand <m...@bewoner.dma.be>
Date: 2000/03/11
Subject: Re: compiler-macro example shortage (was Re: Eureka! Lexical bindings can be guaranteed!)
cba...@2xtreme.net (Christopher R. Barry) writes:

> Does anyone have any good examples of using them?

Allegro's regular expression package has defined a compiler macro for
MATCH-REGEXP that will call COMPILE-REGEXP when the regular expression
is a constant string.

--
Lieven Marchand <m...@bewoner.dma.be>
If there are aliens, they play Go. -- Lasker


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Joe Marshall  
View profile  
 More options Mar 11 2000, 3:00 am
Newsgroups: comp.lang.lisp
From: Joe Marshall <jmarsh...@alum.mit.edu>
Date: 2000/03/11
Subject: Re: compiler-macro example shortage (was Re: Eureka! Lexical bindings can be guaranteed!)
cba...@2xtreme.net (Christopher R. Barry) writes:

> Does anyone have any good examples of using [compiler macros]?

In a commercial project I am working on, we use compiler macros in a
few places.  Here are some examples (variable names have been changed
to protect the innocent):

(defun calculate-foo (bar baz)
   (+ bar (* baz +foo-constant+)))

(define-compiler-macro calculate-foo (&whole form bar baz
                                      &environment env)
  (if (and (constantp bar env)
           (constantp baz env))
      (calculate-foo bar baz)
    form))

In this case, we noticed that the function calculate-foo was
frequently, but not always, used where the arguments were available at
compile time.  The compiler macro checks to see if the arguments are
constant, and if so, computes the value at compile time and uses that.
If not, the form is left unchanged.

This one is hairier:

(defun mapfoo (function element-generator)
  (loop
      while (element-available? element-generator)
      do
        (funcall function (get-next-element element-generator))))

(define-compiler-macro mapfoo (&whole form function element-generator)
  (if (and
        ;; Look for '(FUNCTION ...)
        (consp function)
        (eq (car function) 'FUNCTION)
        (consp (cdr function))
        (null (cddr function)))
      (let ((pl (cadr function)))
        (if (and
              ;; Look for '(LAMBDA (...) ...)
              (consp pl)
              (eq (car pl) 'LAMBDA)
              (consp (cdr pl))
              (consp (cddr pl)))
            (let ((lambda-bound-variables (cadr pl))
                  (lambda-body            (caddr pl)))
              (if (and (consp lambda-bound-variables)
                       (null (cdr lambda-bound-variables)))
                (let ((generator-var (gensym))
                      (bound-variable (car lambda-bound-variables)))
                  `(let ((,generator-var ,element-generator))
                     (loop while (element-available? ,generator-var)
                        do (let ((,bound-variable (get-next-element ,generator-var)))
                             ,@lambda-body))))
               form)) ;; '(function (lambda (...) ...)) syntactically wrong.
           form)) ;; didn't find '(lambda ...)
    form)) ;; didn't find '(function ...)

In this case, we often found that MAPFOO was called with a literal
lambda expression like this:

(mapfoo #'(lambda (a-foo) (frob a-foo t nil)) (get-foo-generator))

The compiler-macro looks for this pattern, and if it finds it, turns
it into

(let ((#:G1234 (get-foo-generator)))
  (loop
    while (element-available? #:G1234)
    do (let ((a-foo (get-next-element #:G1234)))
         (frob a-foo t nil))))

So we can use the higher-order function mapfoo everywhere, but still
get the performance of the obvious loop function when we know what the
mapped function will be.  This avoids the consing of a closure, the
multiple levels of function calls, and the indirect variable lookup.

> Erik Naggum <e...@naggum.no> writes:

> >   compiler macros provide the best of both worlds, and can be quite the
> >   tool to optimize code beyond belief without being force into macro land.

Compiler macros are a useful tool.  In this case I can write my code
in a more abstract style and not think about optimization.  Then, when
I discover some of the bottlenecks, I can add a compiler macro to
optimize the critical sections without doing a single rewrite of the
existing code.

On the other hand, compiler-macros are macros, and they come with all
the variable capture problems of regular macros.  They have one great
advantage of allowing you to punt and return the original form if
things get too hairy.

But in both cases I have outlined above, the compiler-macros are
acting as a `poor-man's inliner'.  If inline declarations worked, I
could have simply declared the relevant functions as inline and not
bothered with the compiler-macros at all.  Most of our uses of
compiler-macros are to make up for this deficiency.

There are uses for compiler-macros other than getting around the lack
of inlining:  Suppose you are writing a function that has some
constraints on its arguments, e.g., the first argument should be a
compile-time constant number.  You can write a compiler macro to check
that this is the case.

--
~jrm


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Christopher R. Barry  
View profile  
 More options Mar 11 2000, 3:00 am
Newsgroups: comp.lang.lisp
From: cba...@2xtreme.net (Christopher R. Barry)
Date: 2000/03/11
Subject: Re: compiler-macro example shortage (was Re: Eureka! Lexical bindings can be guaranteed!)

Lieven Marchand <m...@bewoner.dma.be> writes:
> cba...@2xtreme.net (Christopher R. Barry) writes:

> > Does anyone have any good examples of using them?

> Allegro's regular expression package has defined a compiler macro for
> MATCH-REGEXP that will call COMPILE-REGEXP when the regular expression
> is a constant string.

regexp.cl isn't included with a trial edition but I guess I get the
idea.

USER(9): (funcall (compiler-macro-function 'match-regexp)
                  '(match-regexp "foo" "barfoobaz") nil)
(MATCH-REGEXP (LOAD-TIME-VALUE (COMPILE-REGEXP "foo")) "barfoobaz")

Thank you,
Christopher


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Paolo Amoroso  
View profile  
 More options Mar 11 2000, 3:00 am
Newsgroups: comp.lang.lisp
From: Paolo Amoroso <amor...@mclink.it>
Date: 2000/03/11
Subject: Re: compiler-macro example shortage (was Re: Eureka! Lexical bindings can be guaranteed!)
On Sat, 11 Mar 2000 02:57:19 GMT, cba...@2xtreme.net (Christopher R. Barry)
wrote:

> Does anyone have any good examples of using them? None of the Lisp
> books out there give them any non-reference coverage at all. The
> HyperSpec shows some short examples, but I'm curious how real
> programmers use them in real programs.

The following recent paper deals with compiler macros:

  "Increasing Readability and Efficiency in Common Lisp"
  Ant\'{o}nio Menenzes Leit\~{a}o
  aml AT gia DOT ist DOT utl DOT pt
  Proceedings of the European Lisp User Group Meeting '99

  Abstract:
  Common Lisp allows programmer intervention in the compilation process by
  means of macros and, more appropriately, compiler macros. A compiler
  macro describes code transformations to be done during the compilation
  process. Unfortunately, compiler macros are difficult to write, read and
  extend. This article presents a portable extension to Common Lisp's
  compiler macros. The extension allows easy definition and overloading of
  compiler macros and is based in two known techniques, namely pattern
  matching and data driven programming. Three different uses are presented:

  (1) Code optimization, (2) Code deprecation, and (3) Code quality
  assessment. The extension is being used extensively in the reengineering
  of a large AI system, with good results.

As I write this I am offline and I don't know whether the paper is also
available at a Web site. If you need a copy of the proceedings you may
contact Franz's sales department. The proceedings include another paper by
the same author, titled "FoOBaR - A Prehistoric Survivor", which
illustrates the evolution of the large AI system mentioned in the abstract.

Paolo
--
EncyCMUCLopedia * Extensive collection of CMU Common Lisp documentation
http://cvs2.cons.org:8000/cmucl/doc/EncyCMUCLopedia/


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Discussion subject changed to "Eureka! Lexical bindings can be guaranteed!" by Russell Wallace
Russell Wallace  
View profile  
 More options Mar 13 2000, 3:00 am
Newsgroups: comp.lang.lisp
From: Russell Wallace <manor...@iol.ie>
Date: 2000/03/13
Subject: Re: Eureka! Lexical bindings can be guaranteed!

Andrew Cooke wrote:
> Because I program in Java and a (the one> ;-) advantage over Lisp is
> that it catches some mistakes that dynamic testing doesn't.  I know that
> one can have tests etc, but it seems that the earlier one catches errors
> the better.  The original post was about software which is effectively
> run once (outside testing) and must work - I was thinking that the
> extreme emphasis on perfect code must favour anything that detects
> errors.

Having programmed in Scheme as well as in a bunch of statically typed
languages (including C, C++, Ada and Java), in my experience it actually
doesn't matter.

I find that something which will show up at compile time in an ST
language will show up immediately on even the most cursory of testing in
a DT language.  Call a function with the wrong type and it'll usually
give an error the first time you run the code (whereas calling with
incorrect values may require extensive testing to find).  The bugs that
make it past testing into production code, IME, are of a very different
nature, and usually result from misunderstood specifications or poor
design.

There is an advantage in *convenience*: in an ST language I can have a
bunch of errors found for me for the effort of typing 'make' rather than
having to run tests.  OTOH, there's a cost in convenience of having to
write the type declarations (and of having to explicitly say so when you
really do want 'any type', e.g. for collection classes).  On the third
hand, I usually need to figure out what the types should be anyway from
a design point of view.  Six of one, half a dozen of the other.

I'm inclined to the opinion that this whole issue of typing errors is
worth, at a generous estimate, a tenth the amount of ink/electrons
that's been spilled over it :)

--
"To summarize the summary of the summary: people are a problem."
Russell Wallace
mailto:manor...@iol.ie


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Michael Hudson  
View profile  
 More options Mar 13 2000, 3:00 am
Newsgroups: comp.lang.lisp
From: Michael Hudson <mw...@cam.ac.uk>
Date: 2000/03/13
Subject: Re: Eureka! Lexical bindings can be guaranteed!

Russell Wallace <manor...@iol.ie> writes:
> Andrew Cooke wrote:
> > Because I program in Java and a (the one> ;-) advantage over Lisp is
> > that it catches some mistakes that dynamic testing doesn't.  I know that
> > one can have tests etc, but it seems that the earlier one catches errors
> > the better.  The original post was about software which is effectively
> > run once (outside testing) and must work - I was thinking that the
> > extreme emphasis on perfect code must favour anything that detects
> > errors.

> Having programmed in Scheme as well as in a bunch of statically typed
> languages (including C, C++, Ada and Java), in my experience it actually
> doesn't matter.

Ah, but have you programmed in a language that has a *proper* types
system, like Haskell or ml?  For *certain classes of problem* I find
the thinking I have to do to work out the types of things leads to
insights into the problem I probably wouldn't otherwise have had.

I had a minor epiphany in this direction just the other day, so I hope
you'll forgive the evangelism.

Cheers,
Michael

--
very few people approach me in real life and insist on proving they are
drooling idiots.                         -- Erik Naggum, comp.lang.lisp


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Andrew Cooke  
View profile  
 More options Mar 13 2000, 3:00 am
Newsgroups: comp.lang.lisp
From: Andrew Cooke <and...@andrewcooke.free-online.co.uk>
Date: 2000/03/13
Subject: Re: Eureka! Lexical bindings can be guaranteed!
In article <38CCF7CF.7...@iol.ie>,

  manor...@iol.ie wrote:
> There is an advantage in *convenience*: in an ST language I can have a
> bunch of errors found for me for the effort of typing 'make' rather
than
> having to run tests.  OTOH, there's a cost in convenience of having to
> write the type declarations (and of having to explicitly say so when
you
> really do want 'any type', e.g. for collection classes).  On the third
> hand, I usually need to figure out what the types should be anyway
from
> a design point of view.  Six of one, half a dozen of the other.

It's not just running tests, but also writing them and making sure they
check all the things that a compiler would check for a static-typed
language - you would have tests anyway, but you might well need more
without static types.

(But I agree with some of what you've said and other posts on this
thread show that some static type checking is possible - it varies
significantly with the implementation).

Andrew

Sent via Deja.com http://www.deja.com/
Before you buy.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
William Deakin  
View profile  
 More options Mar 13 2000, 3:00 am
Newsgroups: comp.lang.lisp
From: William Deakin <wi...@pindar.com>
Date: 2000/03/13
Subject: Re: Eureka! Lexical bindings can be guaranteed!

Michael Hudson wrote:
> I had a minor epiphany in this direction just the other day, so I hope
> you'll forgive the evangelism.

You are forgiven as, with all fad-gadgets, it'll wear off in the fullness of
time

;) will


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Discussion subject changed to "Ariane (was Re: Eureka! Lexical bindings can be guaranteed!)" by Jon S Anthony
Jon S Anthony  
View profile  
 More options Mar 13 2000, 3:00 am
Newsgroups: comp.lang.lisp
From: Jon S Anthony <j...@synquiry.com>
Date: 2000/03/13
Subject: Re: Ariane (was Re: Eureka! Lexical bindings can be guaranteed!)

Tim Bradshaw wrote:

> * Jon S Anthony wrote:
> > still do.  This stuff _is_ like the "physical world context" as it
> > _does_ have constraints on the total package size.  For example, you
> > typically can't use some new wonder processor with a 1/2 Gig of RAM,
> > but rather some rather primitive thing (perhaps a decade or so old)
> > and with very limited amounts of memory and such.  Why use this
> > "junk"?  Because they are _hardened_ in various ways that the newer
> > stuff isn't.  Constraints may literally be the amount of generated
> > code as it won't fit on the available ROM.

> I have never heard a claim that the Ariane code was up against memory
> size limits.  Do you have any evidence for that?

No one here has made that claim and nothing in the above paragraph
says otherwise.

> Incidentally, please don't assume I'm not aware of the issues with

I have not made that assumption.

> > But that's not even the point.  When you design and build something
> > for a given context and you clearly specify what this context of use
> > is (whether you think such design and construction is "good" or not is
> > completely _irrelevant_ to the point), then if someone _ignores_ this
> > approved context of use, the burden is _not_ on the builder of the
> > component, but rather on the user of it.  That's the point.

> Right.  BUT THAT IS NOT WHAT I WAS ARGUING ABOUT.  I was arguing
> about the specific claim made in the second paragraph of section 2.2
> of the report on the disaster.  And that is *all*.

Then we have simply been talking past one another.  After all, the
message you replied to by me was _only_ about this point and that is
all.  Go back and look.  Which is why I kept remarking that you were
missing the point.  If you didn't want to discuss this point, then
there was no point in replying to that message in the first place.
Criminey!

> Sigh.

Really.

/Jon

--
Jon Anthony
Synquiry Technologies, Ltd. Belmont, MA 02478, 617.484.3383
"Nightmares - Ha!  The way my life's been going lately,
 Who'd notice?"  -- Londo Mollari


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Discussion subject changed to "Testing approaches" by Ray Blaak
Ray Blaak  
View profile  
 More options Mar 13 2000, 3:00 am
Newsgroups: comp.lang.lisp
From: Ray Blaak <bl...@infomatch.com>
Date: 2000/03/13
Subject: Re: Testing approaches

cbbro...@knuth.brownes.org (Christopher Browne) writes:
> Static typing may provide *some* of the testing implicitly; the real
> point is that type errors are only a subset of the total list of possible
> errors that may be made in writing a program.

The errors its tends to find are the common ones that are completely avoidable
(admittedly much more prevalent in the C family of languages than than in
Lisp).

> It's not that "static typing is downright bad, and never finds errors
> for you."

> It is rather the case that if you construct the "unit tests" *that should
> be built* to examine boundary cases and the likes, this will indirectly
> provide much of the testing of types that you suggest need to be implicit
> in the type system.

Yes an no. Unit testing is fundamentally important even with static typing. A
good test would indeed have boundary cases to catch the typing errors. But now
you have to do the tedious effort of writing those cases. It is better if those
cases can't even be expressed in the first place. For example, how many kinds
of invalid values can you pass to a function? A string, an atom, a list, a
vector, a float, an integer,... If your function was restricted to integers,
say, then you could simply concentrate on the invalid integer values.

> If there are good unit tests, this diminishes the importance of static
> type checking.  Not to zero, but possibly to the point of not being
> dramatically useful.

Static typing is dramatically useful in integration tests. A unit test will not
exhaustively exercise other units. Static typing allows units to fit together
without the piles of dumb stupid interface errors, allowing you to concentrate
on the smart stupid logic errors :-).

--
Cheers,                                        The Rhythm is around me,
                                               The Rhythm has control.
Ray Blaak                                      The Rhythm is inside me,
bl...@infomatch.com                            The Rhythm has my soul.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Christopher Browne  
View profile  
 More options Mar 14 2000, 3:00 am
Newsgroups: comp.lang.lisp
From: cbbro...@knuth.brownes.org (Christopher Browne)
Date: 2000/03/14
Subject: Testing approaches
Centuries ago, Nostradamus foresaw a time when Andrew Cooke would say:

Static typing may provide *some* of the testing implicitly; the real
point is that type errors are only a subset of the total list of possible
errors that may be made in writing a program.

It's not that "static typing is downright bad, and never finds errors
for you."

It is rather the case that if you construct the "unit tests" *that should
be built* to examine boundary cases and the likes, this will indirectly
provide much of the testing of types that you suggest need to be implicit
in the type system.

If there are good unit tests, this diminishes the importance of static
type checking.  Not to zero, but possibly to the point of not being
dramatically useful.
--
"Bother," said Pooh, as he deleted his root directory.
cbbro...@hex.net - - <http://www.ntlug.org/~cbbrowne/lsf.html>


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Erik Naggum  
View profile  
 More options Mar 14 2000, 3:00 am
Newsgroups: comp.lang.lisp
From: Erik Naggum <e...@naggum.no>
Date: 2000/03/14
Subject: Re: Testing approaches
* Ray Blaak <bl...@infomatch.com>
| For example, how many kinds of invalid values can you pass to a function?
| A string, an atom, a list, a vector, a float, an integer,... If your
| function was restricted to integers, say, then you could simply
| concentrate on the invalid integer values.

  (check-type <argument> <restricted-type>) takes care of this one for you,
  or you can use assert or throw your own errors if you really have to.  I
  don't see the problem.  writing safe code isn't hard in Common Lisp.

| Static typing is dramatically useful in integration tests.  A unit test
| will not exhaustively exercise other units.  Static typing allows units
| to fit together without the piles of dumb stupid interface errors,
| allowing you to concentrate on the smart stupid logic errors :-).

  when the compiler stores away the type information, this may be true.
  when the programmers have to keep them in sync manually, it is false.

  static typing is like a religion: it has no value outside the community
  of believers.  inside the community of believers, however, it is quite
  impossible to envision a world where static types do not exist, and they
  think in terms that restrict their concept of "type" to that which fits
  the static typing religion.

  to break out of the static typing faith, you have to realize that there
  is nothing conceptually different between an object of type t that holds
  a value you either know or don't know how to deal with, and an object of
  a very narrow type that holds a value you either know or don't know how
  to deal with.  the issue is really programming pragmatics.  static typing
  buys you exactly nothing over dynamic typing when push comes to shove.
  yes, it does buy you something _superficially_, but look beneath it, and
  you find that _nothing_ has actually been gained.  the bugs you found are
  fixed, and the ones you didn't find aren't fixed.  the mistakes you made
  that escaped the testing may differ very slightly in expression, but they
  are still there.  the mistakes you did find may also differ slightly in
  expression, but they are still gone.  what did you gain by believing in
  static typing?  pain and suffering and a grumpy compiler.  what did you
  gain by rejecting this belief and understanding that neither humans nor
  the real world fits the static typing model?  freedom of expression!  of
  course, it comes with a responsibility, but so did the static typing,
  only the dynamic typing responsibility is not to abuse freedom, while the
  static typing responsibility is not to abuse the power of restriction.

  personally, I think this is _actually_ a personality issue.  either you
  want to impose control on your environment and believe in static typing,
  or you want to understand your environment and embrace whatever it is.

#:Erik


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Marc Battyani  
View profile  
 More options Mar 14 2000, 3:00 am
Newsgroups: comp.lang.lisp
From: "Marc Battyani" <Marc_Batty...@csi.com>
Date: 2000/03/14
Subject: Re: Testing approaches
It's not a specific response to Erik's post just some info on the subject.

For the static typing believers (of which i'm not) here is a new language
that is supposed to be a "Typed Lisp" "even faster than C" "As a summary:
Pliant is typed-Lisp + C++ + reflective-C in one language"

They got rid of the GC, which is rather unusal for a lisp...

You can look at the rest here: http://pliant.cams.ehess.fr/pliant/

Marc Battyani


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Ray Blaak  
View profile  
 More options Mar 14 2000, 3:00 am
Newsgroups: comp.lang.lisp
From: Ray Blaak <bl...@infomatch.com>
Date: 2000/03/14
Subject: Re: Testing approaches

Erik Naggum <e...@naggum.no> writes:
> * Ray Blaak <bl...@infomatch.com>
> | Static typing allows units
> | to fit together without the piles of dumb stupid interface errors,
> | allowing you to concentrate on the smart stupid logic errors :-).

>   when the compiler stores away the type information, this may be true.
>   when the programmers have to keep them in sync manually, it is false.

How so? If there is an error, the programmer has to manually fix things
anyway, regardless of whether or not it was automatically discovered, or
whether or not the compiler stores type information. Maybe I misunderstood
what you mean by "keep them in sync".

> static typing is like a religion [...]

The point is that having tool support to detect the kinds of errors that
static typing can discover is helpful. In my experience these errors are very
common, easy to detect, and easy to fix. It is only a useful tool, no
fanatical zeal required.

I freely admit, however, that with Lisp systems at least, the consequences of
no static typing are not as important as with other languages, mainly due to
the built-in abilities of the language. One just doesn't corrupt things as
easily.

>   the issue is really programming pragmatics.  static typing
>   buys you exactly nothing over dynamic typing when push comes to shove.
>   yes, it does buy you something _superficially_, but look beneath it, and
>   you find that _nothing_ has actually been gained.  the bugs you found are
>   fixed, and the ones you didn't find aren't fixed.  the mistakes you made
>   that escaped the testing may differ very slightly in expression, but they
>   are still there.  the mistakes you did find may also differ slightly in
>   expression, but they are still gone.

I disagree with the "slightly". Pragmatically speaking, I have found the
number of errors prevented to be significant. One still has real bugs of
course, it's just the the silly ones I don't have to worry about.

>   what did you gain by believing in static typing?  pain and suffering and a
>   grumpy compiler.  what did you gain by rejecting this belief and
>   understanding that neither humans nor the real world fits the static
>   typing model?  freedom of expression!  

I encounter this attitude of "fighting the compiler" often, and I don't
understand it. A programmer describes an abstraction to a computer. The
computer then adheres to it, and points out violations that do not conform to
it. If one finds that they are bumping against a restriction that means either
the abstraction is not general enough, or that there is an error of usage that
should be fixed. The programmer has complete freedom to change things. One
does not fight the compiler per se; rather, one discovers the correctness of
their design.

It's not about "believing" in static typing. It's about being able to describe
an abstraction to an appropriate level of detail. Any tool support that can
aid in verifying it is only a win.

>   of course, it comes with a responsibility, but so did the static typing,
>   only the dynamic typing responsibility is not to abuse freedom, while the
>   static typing responsibility is not to abuse the power of restriction.

I don't agree with this dichotomy. To me there is only freedom. Dynamic vs
static typing is actually a false distinction. They are really different
points along a continuum of "typing". One makes abstractions as general or as
constrained as necessary, balancing flexibility, robustness and correctness.

The responsibility is simply to do things "right" :-).

>   personally, I think this is _actually_ a personality issue.  either you
>   want to impose control on your environment and believe in static typing,
>   or you want to understand your environment and embrace whatever it is.

I think that one can and should do both. The art is in acheiving the
appropriate balance.

--
Cheers,                                        The Rhythm is around me,
                                               The Rhythm has control.
Ray Blaak                                      The Rhythm is inside me,
bl...@infomatch.com                            The Rhythm has my soul.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Christopher Browne  
View profile  
 More options Mar 15 2000, 3:00 am
Newsgroups: comp.lang.lisp
From: cbbro...@news.hex.net (Christopher Browne)
Date: 2000/03/15
Subject: Re: Testing approaches
Centuries ago, Nostradamus foresaw a time when Ray Blaak would say:

This assumes that the function is necessarily supposed to be
restricted to integers.

The "Lisp assumption" is that this is *not* the case.  

Alternatively, if this *should* be the case, then it may make sense to
define the function as a CLOS method, and attach typing information to
the method, at which point you get similar guarantees to those
provided by static type checking.

But at any rate, by the time you've thrown boundary case testing at
the code, it is relatively unimportant what kinds of values are
invalid.

If each function has been tested to verify that it accepts reasonable
input, and produces reasonable output, I'm not terribly worried about
how it copes with unreasonable input/output.  After all, *all* of the
functions are producing reasonable output, right?

>> If there are good unit tests, this diminishes the importance of static
>> type checking.  Not to zero, but possibly to the point of not being
>> dramatically useful.

>Static typing is dramatically useful in integration tests. A unit
>test will not exhaustively exercise other units. Static typing allows
>units to fit together without the piles of dumb stupid interface
>errors, allowing you to concentrate on the smart stupid logic errors
> :-).

I have yet to write CLOS code, but it looks to me like that (or
"tiny-CLOS" schemes), combined with packaging, are the ways that
Lisp-like systems can attack the "interface control" problem...

The point here is that CLOS does "type-based" dispatching which
grapples with at least part of the "dumb stupid" interface problems.

And the other point that you appear quite obstinate in refusing to
recognize is that as soon as one pushes even *faintly* realistic test
data through a set of functions, this *quickly* shakes out much of
those "piles of dumb stupid interface errors."
--
Q: If  toast always  lands butter-side down,  and cats always  land on
their feet, what happens  if you strap toast on the back  of a cat and
drop it?  
A: it spins, suspended horizontally, a few inches from the ground.
cbbro...@ntlug.org- <http://www.ntlug.org/~cbbrowne/lsf.html>


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Gareth McCaughan  
View profile  
 More options Mar 15 2000, 3:00 am
Newsgroups: comp.lang.lisp
From: Gareth McCaughan <Gareth.McCaug...@pobox.com>
Date: 2000/03/15
Subject: Re: Testing approaches

Ray Blaak wrote:
> The point is that having tool support to detect the kinds of errors that
> static typing can discover is helpful. In my experience these errors are very
> common, easy to detect, and easy to fix. It is only a useful tool, no
> fanatical zeal required.

Hmm. My experience is that most of the type errors I make when
programming in C or C++[1] are ones that don't really have
counterparts in Lisp. I mistype a declaration, or accidentally
refer to |foo| where I mean |*foo| or vice versa, or use a signed
integral type when I want an unsigned one; in Lisp I don't write
declarations until later, when I'm thinking hard about types of
objects, andconfusing an object with its address is an issue
that just doesn't arise, and integers are *real* integers :-).

What sort of type errors do you make that get caught in languages
with static typing?

> I encounter this attitude of "fighting the compiler" often, and I
> don't understand it. A programmer describes an abstraction to a
> computer. The computer then adheres to it, and points out violations
> that do not conform to it. If one finds that they are bumping
> against a restriction that means either the abstraction is not
> general enough, or that there is an error of usage that should be
> fixed. The programmer has complete freedom to change things. One
> does not fight the compiler per se; rather, one discovers the
> correctness of their design.

If all languages were elegantly and consistently designed,
that might be true. But when there are gratuitous restrictions
or inconsistencies or complications in the language design,
it seems perfectly reasonable to me to speak of "fighting
the compiler" (or, maybe, "fighting the language").

Having to write

    #define FOO(x) do { ... } while (0)

in C is "fighting the compiler". So is having to make up names
for intermediate objects if you want to set up (at compile
time) a nested structure where the nesting is done via pointers.
So is having to allocate and free temporary objects explicitly
on account of there being no GC.

All these things are just consequences of the language being
how it is, yes. That doesn't mean that the restrictions and
annoyances aren't real. The programmer *doesn't* have complete
freedom to change things; s/he can't change the language.
I don't think that "it's unpleasant to express in C" indicates
a flaw in the design of a program. It might indicate a flaw
in the design of C.

I'm not saying that a design should take no notice of the
language it's likely to get implemented in, of course. I'm
saying that often the best design still lumbers you with some
annoyances in implementation that could have been alleviated
if the language had been slightly different, and that these
count as "fighting the compiler".

[1] I haven't done anything non-trivial in languages like ML and
    Haskell that are statically typed but have "better" type
    systems than C's.

--
Gareth McCaughan  Gareth.McCaug...@pobox.com
sig under construction


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Ray Blaak  
View profile  
 More options Mar 15 2000, 3:00 am
Newsgroups: comp.lang.lisp
From: Ray Blaak <bl...@infomatch.com>
Date: 2000/03/15
Subject: Re: Testing approaches

cbbro...@news.hex.net (Christopher Browne) writes:
> Centuries ago, Nostradamus foresaw a time when Ray Blaak would say:
> If each function has been tested to verify that it accepts reasonable
> input, and produces reasonable output, I'm not terribly worried about
> how it copes with unreasonable input/output.  After all, *all* of the
> functions are producing reasonable output, right?

Testing with bad inputs is a fundamental part of testing. This is definitely a
religious belief on my part. If you don't agree, we'll simply leave it at
that.

> And the other point that you appear quite obstinate in refusing to
> recognize is that as soon as one pushes even *faintly* realistic test
> data through a set of functions, this *quickly* shakes out much of
> those "piles of dumb stupid interface errors."

Actually I agree with this. My point was to be able to avoid doing the work of
writing certain kinds of (tedious) tests in the first place. That is, let the
computer effectively do it for me.

Also, consider that unit tests often use "stub" versions of other units, since
they might not be available yet, be mutually dependent, etc. In that case
exercising your unit can test it adequately, but you can still miss bad calls
to the other units due to differences in behaviour between the stubbed
versions and the real versions. Some sort of interface specification ability
(static typing, CLOS style descriptions, whatever) can help reduce these
problems.

--
Cheers,                                        The Rhythm is around me,
                                               The Rhythm has control.
Ray Blaak                                      The Rhythm is inside me,
bl...@infomatch.com                            The Rhythm has my soul.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Ray Blaak  
View profile  
 More options Mar 15 2000, 3:00 am
Newsgroups: comp.lang.lisp
From: Ray Blaak <bl...@infomatch.com>
Date: 2000/03/15
Subject: Re: Testing approaches

Gareth McCaughan <Gareth.McCaug...@pobox.com> writes:
> What sort of type errors do you make that get caught in languages
> with static typing?

Things like using an object in a context where it shouldn't, just because it
has the same representation. E.g. A record with two integer fields can be
considered a point or a rational number. If I was using a rational number in a
context where a point was expected, it is most likely an error. A reasonable
statically typed language would prevent such accidental (or lazy) uses. If I
really intended such behaviour, I would be forced to be explicit about it, and
provide conversion routines. E.g.

  (let ((p (make-point 1 2))     ; Assume representation as a list of length 2
        (r (make-rational 3 4))) ; Ditto
     (draw-to p)
     (draw-to r) ; Shouldn't be allowed.
     (draw-to (point-of r))) ; Ok, now I am being explicit

This is an example only to illustrate a type mismatches due to identical
representations. Forget for the moment that real Lisp structs and rational
numeric types exist.

Another common situation is getting parameter values right. E.g.

  (defun make-person (name age) ...)

  (let ((p1 (make-person "Joe" 5)) ; Ok.
        (p2 (make-person 15 "John"))) ; Not ok.
     ...)

Note that I don't consider C to be any sort of reasonable statically typed
language. C++ can be alright if one disciplines themselves to stick the
classes as much as possible and avoid the macros and low level features. The
primary example of a "traditional" statically typed language is Ada, with its
rich type specification ability. [Most Ada programmers are serious static
typing freaks. If people think I am a zealot about this, they haven't met the
real ones yet. I am distinctly mellow by comparison.]

Haskell and ML I would like to learn more about since they seem fundamentally
more expressive.

> Ray Blaak wrote:
> > I encounter this attitude of "fighting the compiler" often, and I
> > don't understand it. [...] One does not fight the compiler per se; rather,
> > one discovers the correctness of their design.

> If all languages were elegantly and consistently designed,
> that might be true. But when there are gratuitous restrictions
> or inconsistencies or complications in the language design,
> it seems perfectly reasonable to me to speak of "fighting
> the compiler" (or, maybe, "fighting the language").
[...]
> I'm saying that often the best design still lumbers you with some annoyances
> in implementation that could have been alleviated if the language had been
> slightly different, and that these count as "fighting the compiler".

Fair enough. I was referring to bumping against restrictions of the
programmer's abstractions, not language features. Using a castrated language
is always frustrating.

--
Cheers,                                        The Rhythm is around me,
                                               The Rhythm has control.
Ray Blaak                                      The Rhythm is inside me,
bl...@infomatch.com                            The Rhythm has my soul.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Pierre R. Mai  
View profile  
 More options Mar 15 2000, 3:00 am
Newsgroups: comp.lang.lisp
From: p...@acm.org (Pierre R. Mai)
Date: 2000/03/15
Subject: Re: Testing approaches

Ray Blaak <bl...@infomatch.com> writes:
> Gareth McCaughan <Gareth.McCaug...@pobox.com> writes:
> > What sort of type errors do you make that get caught in languages
> > with static typing?

> Things like using an object in a context where it shouldn't, just
> because it has the same representation. E.g. A record with two
> integer fields can be considered a point or a rational number. If
> I was using a rational number in a context where a point was
> expected, it is most likely an error. A reasonable statically
> typed language would prevent such accidental (or lazy) uses. If I
> really intended such behaviour, I would be forced to be explicit
> about it, and provide conversion routines. E.g.

This issue is totally independent of the distinction between static
vs. dynamic typing.  It's a case of strong vs. weak/no typing.  Sadly
the two almost always get mixed up, which further diminishes the value
of "discussions" about dynamic vs. static typing.

> This is an example only to illustrate a type mismatches due to identical
> representations. Forget for the moment that real Lisp structs and rational
> numeric types exist.

If you forget for the moment all higher level type constructors found
in your favourite statically typed language, you'll get the same
results, with the one distinction that the supposed type-mismatch
which previously wasn't found at run-time, will now _not_ be found at
compile-time, i.e. there is no difference.  This tells us that the
issue is about something different from dynamic vs. static typing.
See above.

> Another common situation is getting parameter values right. E.g.

>   (defun make-person (name age) ...)

>   (let ((p1 (make-person "Joe" 5)) ; Ok.
>         (p2 (make-person 15 "John"))) ; Not ok.
>      ...)

Now here the only distinction is between dynamic vs. static typing.

OTOH since a meaningful unit test will have to cover all executable
branches of code anyway, this kind of error will always be caught with
no additional testing effort, as long as the types of the arguments
and parameters that are mismatched are indeed different.  Given the
prevalence of string and integer types, this will often not be the
case, in which case both static and dynamic typing will break down.
This is one of the reasons why I think that environmental support
(automagic display of lambda lists, online HyperSpec) is the better
way to tackle issues of this sort.

Things will get a little more complicated to test when the type of a
parameter depends on dynamic properties of the program:

  (make-person (blabla <something dynamic>) 5)

OTOH in statically-typed languages the code will look like this:

  (make-person (union-string (blabla ...)) 5)

I.e. blabla now has a declared union type, and you need to explicitly
invoke the union accessor that gets you the string, for this to
type-check correctly.  BUT you'll still need to test, since the
accessor will fail (either loudly (=> strongly-typed), or silently (=>
C unions)) at run-time, if the return value isn't the string variant
expected.  You simply can't do better than run-time checking here.

Some B&D languages will make you put in a case construct, but since
you'll only raise an error in the else case anyway, this doesn't get
you more safety, but gives you more headaches.  B&D.

I believe that anyone who doesn't exercise each part[1] of a unit at
least once during testing deserves any bugs he gets.  I also believe
that static-typing would be more useful if computer programs consisted
of total, non-discrete functions.  Since they don't, it isn't.  ;-)

Regs, Pierre.

Footnotes:
[1]  Note that this is different from (and easier than) exercising
     each possible path through a program/unit/function.  The one
     grows linearly, the other grows exponentially.

--
Pierre Mai <p...@acm.org>         PGP and GPG keys at your nearest Keyserver
  "One smaller motivation which, in part, stems from altruism is Microsoft-
   bashing." [Microsoft memo, see http://www.opensource.org/halloween1.html]


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Gareth McCaughan  
View profile  
 More options Mar 15 2000, 3:00 am
Newsgroups: comp.lang.lisp
From: Gareth McCaughan <Gareth.McCaug...@pobox.com>
Date: 2000/03/15
Subject: Re: Testing approaches

Ray Blaak wrote:

[I asked him:]

>> What sort of type errors do you make that get caught in languages
>> with static typing?

> Things like using an object in a context where it shouldn't, just because it
> has the same representation. E.g. A record with two integer fields can be
> considered a point or a rational number.

Hmm. Using conses and lists for everything is sort of the Lisp
equivalent of using |void *| for everything in C and casting
every pointer every time you use it. If you do that, then you
*deserve* to lose. :-)

> This is an example only to illustrate a type mismatches due to identical
> representations. Forget for the moment that real Lisp structs and rational
> numeric types exist.

But they do, and they do away with this kind of problem pretty
completely, no? I mean, do you often define several kinds of
object with the same representation? (If so, why?)

> Another common situation is getting parameter values right. E.g.

>   (defun make-person (name age) ...)

>   (let ((p1 (make-person "Joe" 5)) ; Ok.
>         (p2 (make-person 15 "John"))) ; Not ok.
>      ...)

    (defun make-person (&key name age) ...)

    (let ((p1 (make-person :name "Joe" :age 5))
          (p2 (make-person :age 15 :name "John")))
      ...)

I suppose the point of all this is that static typing does
buy you something, but that in a well-designed dynamic language
the amount it buys you is very little unless you choose to
shoot yourself in the foot.

> Note that I don't consider C to be any sort of reasonable statically typed
> language.

I'm very pleased to hear it! It's amusing just how much more
weakly typed C is than CL. (Which is one reason why I don't
like to hear people say "strong typing" when they mean "static
typing". C is weakly typed and statically typed; CL is strongly
typed and dynamically typed. I am not, at all, suggesting that
you don't understand this.)

>           C++ can be alright if one disciplines themselves to stick the
> classes as much as possible and avoid the macros and low level features. The
> primary example of a "traditional" statically typed language is Ada, with its
> rich type specification ability. [Most Ada programmers are serious static
> typing freaks. If people think I am a zealot about this, they haven't met the
> real ones yet. I am distinctly mellow by comparison.]

I don't think you're a zealot about it, for what it's worth.

> Haskell and ML I would like to learn more about since they seem
> fundamentally more expressive.

I'm not sure I'd go that far, but they do combine strict static
typing with a good enough type inference system that you don't
have to decorate everything with types as you do in C. That's
certainly a good thing.

>> I'm saying that often the best design still lumbers you with some annoyances
>> in implementation that could have been alleviated if the language had been
>> slightly different, and that these count as "fighting the compiler".

> Fair enough. I was referring to bumping against restrictions of the
> programmer's abstractions, not language features. Using a castrated language
> is always frustrating.

Almost all languages are castrated to some degree, I think.
I've never yet used one where I don't sometimes think "aargh,
if only I could say X". Common Lisp can at least be extended
when that happens (though it isn't always wise).

--
Gareth McCaughan  Gareth.McCaug...@pobox.com
sig under construction


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Ray Blaak  
View profile  
 More options Mar 15 2000, 3:00 am
Newsgroups: comp.lang.lisp
From: Ray Blaak <bl...@infomatch.com>
Date: 2000/03/15
Subject: Re: Testing approaches

Gareth McCaughan <Gareth.McCaug...@pobox.com> writes:
> Ray Blaak wrote:
> > Things like using an object in a context where it shouldn't, just because
> > it has the same representation.
[...]
> > This is an example only to illustrate a type mismatches due to identical
> > representations. Forget for the moment that real Lisp structs and rational
> > numeric types exist.

> But they do, and they do away with this kind of problem pretty
> completely, no? I mean, do you often define several kinds of
> object with the same representation? (If so, why?)

If typing information is automatically part of the representation itself
(i.e. some sort of type tag), then the answer is no, I don't have different
objects with same representation. Otherwise, yes, its definitely possible.

Let me flip to Ada for a second:

  type Seconds is range 0 .. 59;
  type Minutes is range 0 .. 59;

These are both integer types, both with exactly the same representation, and
yet because they are different types, I cannot accidently use minutes where
seconds is required, and vice versa. E.g.

  declare
    m : Minutes;
    s : Seconds;
  begin
    s := 10;
    m := s; -- won't compile
    m := Minutes(s); -- ok, explicit conversion
  end;

To me the representation of an object is in general a private thing to the
object, and a user of the object should only think in terms of the allowable
operations on the object.

>     (let ((p1 (make-person :name "Joe" :age 5))
>           (p2 (make-person :age 15 :name "John")))
>       ...)

This is also an excellent feature that I like to have in languages. It prevents
errors, makes things clearer to the reader, etc. In Ada, for example, I could
say:

  p2 := Make_Person (Age => 15, Name => "John");

> > Haskell and ML I would like to learn more about since they seem
> > fundamentally more expressive.

> I'm not sure I'd go that far [...]

Well, more expressive in terms of specifying types is what I meant, at least
compared to Ada and C++. How do they compare to CL in that regard?

--
Cheers,                                        The Rhythm is around me,
                                               The Rhythm has control.
Ray Blaak                                      The Rhythm is inside me,
bl...@infomatch.com                            The Rhythm has my soul.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Ray Blaak  
View profile  
 More options Mar 15 2000, 3:00 am
Newsgroups: comp.lang.lisp
From: Ray Blaak <bl...@infomatch.com>
Date: 2000/03/15
Subject: Re: Testing approaches
p...@acm.org (Pierre R. Mai) writes:

> Ray Blaak <bl...@infomatch.com> writes:
> > Things like using an object in a context where it shouldn't, just
> > because it has the same representation.
> This issue is totally independent of the distinction between static
> vs. dynamic typing.  It's a case of strong vs. weak/no typing.  Sadly
> the two almost always get mixed up, which further diminishes the value
> of "discussions" about dynamic vs. static typing.

Well, I do indeed mean strong static typing vs strong dynamic typing.

Hmmm.

I think the issue here is this example is not really appropriate to Lisp, where
objects of different types have different representations by definition. If I
used real Lisp types, my example becomes good old fashioned parameter type
mismatch:

  (let ((p (make-point 1 2)) ; a struct
        (r 3/4))
    (draw-to p)  ; ok
    (draw-to r)) ; error

See my reply to Gareth for a realistic example in Ada of different types with
identical representations.

> > Another common situation is getting parameter values right. E.g.

> Now here the only distinction is between dynamic vs. static typing.

> OTOH since a meaningful unit test will have to cover all executable
> branches of code anyway, this kind of error will always be caught with
> no additional testing effort

Not if the operation being invoked is in another unit stubbed for testing
purposes, such that the stubbed version doesn't care about the parameter
type. Unit tests will cover the paths through the unit but can miss this case
due to the stub. Integration tests will bring the real units together, but
don't necessarily cover all paths. Some sort of static specification ability
will catch the bad call.

Now it all depends what you are doing, and in what language. For a smallish
system the testing of all representative paths with actual units is feasible
and will indeed catch the error. Large systems, on the other hand need every
bit of automated error detection they can reasonably get.

> Things will get a little more complicated to test when the type of a
> parameter depends on dynamic properties of the program [...] in
> statically-typed languages [...] you'll still need to test

Indeed you will. Statically typed doesn't mean completely static. There is
almost always some dynamic aspect possible, and run-time checking cannot be
completely avoided, even in Ada. However, usually (especially with
object-oriented programming) you might not know the exact type, but can assume
some minimal abilities. E.g. in Java:

  class Root
  {
    public void Doit ()
    {...}
  }

  class Descendant extends Root
  {...}

  void DoADescendant(Descendant d)
  {...}

  void DoARoot(Root obj)
  {
    obj.Doit(); // I don't know the exact type, but I know I can do this.
    DoADescendant(obj); // run-time check
  }

In DoARoot, know I cannot be passed anything else but an object descended from
Root. Thus I don't have to test such cases such as trying with a string, an
integer, a whatzit. Clients cannot accidentally call DoARoot with such cases.

Static typing is only a additional tool in a programmer's bag of useful
tricks. Maybe I should really be saying "machine verifiable specification
abilities".

--
Cheers,                                        The Rhythm is around me,
                                               The Rhythm has control.
Ray Blaak                                      The Rhythm is inside me,
bl...@infomatch.com                            The Rhythm has my soul.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Discussion subject changed to "Eureka! Lexical bindings can be guaranteed!" by Russell Wallace
Russell Wallace  
View profile  
 More options Mar 16 2000, 3:00 am
Newsgroups: comp.lang.lisp
From: Russell Wallace <manor...@iol.ie>
Date: 2000/03/16
Subject: Re: Eureka! Lexical bindings can be guaranteed!

Michael Hudson wrote:
> Ah, but have you programmed in a language that has a *proper* types
> system, like Haskell or ml?  For *certain classes of problem* I find
> the thinking I have to do to work out the types of things leads to
> insights into the problem I probably wouldn't otherwise have had.

Nope.  I've looked at the docs and sample code for them and figured
they're not my style, though I understand for some people they work very
well.

--
"To summarize the summary of the summary: people are a problem."
Russell Wallace
mailto:manor...@iol.ie


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Discussion subject changed to "Testing approaches" by Gareth McCaughan
Gareth McCaughan  
View profile  
 More options Mar 16 2000, 3:00 am
Newsgroups: comp.lang.lisp
From: Gareth McCaughan <Gareth.McCaug...@pobox.com>
Date: 2000/03/16
Subject: Re: Testing approaches

OK, that's a good example. I like it.

A question, though: does the decrease in testing time that
comes from declaring all your counts of minutes and seconds
explicitly make up for the increase in coding time that
comes from, er, declaring all your counts of minutes and
seconds explicitly?

Actually, this particular example isn't so great because
the Right Answer is almost certainly not to have separate
types for minutes and seconds, but to have objects for
holding times, or time intervals, of which minutes and
seconds would just be special cases. But there are other
parallel examples where similar options aren't available.
(Distances and angles, maybe.)

These examples make me wonder whether there's anything to
be said for giving a programming language a notion of
*units*, so that (+ (minutes 5) (seconds 5)) is (seconds 305)
and (+ (metres 10) (square-metres 10)) is a type error.
It's probably just much, much too painful. :-)

(There are systems that let you do things like this.
For instance, the "Mathcad" package does.)

> To me the representation of an object is in general a private thing to the
> object, and a user of the object should only think in terms of the allowable
> operations on the object.

I agree. But I wonder how far you really want to take it.
Distinguish between a positive integer that describes the
length of a list and another that describes the length
of an array, perhaps? Or between indices into two different
arrays? Should two cons cells be of different types, if
the CAR of one is a symbol representing a kind of fruit
and the CAR of the other is a symbol representing a kind
of bread? That way, I think, lies madness...

>>     (let ((p1 (make-person :name "Joe" :age 5))
>>           (p2 (make-person :age 15 :name "John")))
>>       ...)

> This is also an excellent feature that I like to have in
> languages. It prevents errors, makes things clearer to the reader,
> etc. In Ada, for example, I could say:

>   p2 := Make_Person (Age => 15, Name => "John");

One of the things I really hate about C and C++ is that they
have no keyword arguments.

>>> Haskell and ML I would like to learn more about since they seem
>>> fundamentally more expressive.

>> I'm not sure I'd go that far [...]

> Well, more expressive in terms of specifying types is what I meant, at least
> compared to Ada and C++. How do they compare to CL in that regard?

Well, obviously, *nothing* is more expressive than CL in
any regard whatever. :-)

In ML there are types like "list of integers" or "function
that, given an object of any type, returns a list of objects
of that type". CL's type system doesn't have those. On
the other hand, I don't think ML has the "list of objects
of any types" type.

--
Gareth McCaughan  Gareth.McCaug...@pobox.com
sig under construction


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Ray Blaak  
View profile  
 More options Mar 16 2000, 3:00 am
Newsgroups: comp.lang.lisp
From: Ray Blaak <bl...@infomatch.com>
Date: 2000/03/16
Subject: Re: Testing approaches

Gareth McCaughan <Gareth.McCaug...@pobox.com> writes:
> OK, that's a good example. I like it.

> A question, though: does the decrease in testing time that
> comes from declaring all your counts of minutes and seconds
> explicitly make up for the increase in coding time that
> comes from, er, declaring all your counts of minutes and
> seconds explicitly?

There is the up front work of declaring the types and their allowable
operations. Once that is done, actually using the types is not really much more
work than using the default types.

The payoff is not so much a decrease in testing time. It is substantial
decrease in development time in general. The Ada development cycle tends to be
compile->link->run with the occasional foray into the debugger. C++, by
comparison is more like compile->link->whoops, unresolveds!->link->debug->
debug->debug->...->eventually run for real.

On the other hand, Ada is fundamentally a compiled language, with a mandatory
analysis phase. An interpreted version of Ada would be tedious to use indeed.

Ray Blaak wrote:
> > To me the representation of an object is in general a private thing to the
> > object, and a user of the object should only think in terms of the
> > allowable operations on the object.

> I agree. But I wonder how far you really want to take it.

In the Ada mindset one tends to take things pretty far. The guiding principle
is that abstractions that are not supposed to interfere with each other will
not, at least not implicitly. For abstractions that are supposed to deal with
each other, one constructively specifies what one is allowed to express.

But this is not an Ada newsgroup, and I think I have said enough on the matter.

--
Cheers,                                        The Rhythm is around me,
                                               The Rhythm has control.
Ray Blaak                                      The Rhythm is inside me,
bl...@infomatch.com                            The Rhythm has my soul.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Messages 76 - 100 of 132 < Older  Newer >
« Back to Discussions « Newer topic     Older topic »