Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

10 Reasons Why Scheme is Better Than C/C++

9 views
Skip to first unread message

David Hanley

unread,
Nov 27, 1996, 3:00:00 AM11/27/96
to

Just a few corrections, but overall you had some good points:

>GoldenEye wrote:
>1.Since Scheme has an interpreter, you can run individual functions and
>play with your data structures
> without writing stubs.
> 2.Dynamic typing allows you to concentrate on real errors, rather than
> trying to placate the compiler god. It
> also makes code vastly more reusable.

Hardly true. The only time I ever notice the static type checker is
when I get a type mismatch. This would have been a run-time error in
scheme that may have hit for a long time, and been hard to debug.
Dynamic type checking is a hack to allow for faster interpretation which
gives awayt a lot.

> 3.Scheme is actually portable.

If you're using the cortect version.

> 4.Every Scheme function is prefix. We don't need no stinkin' 19-level
> operator precedence heirarchy.
> 5.In C, you have to write the code if you want a really exotic data
> structure, like a linked list.

Not with stl you don't. And I actually think it's easier to do complex
data structures in C++ because you actually have data structures. I
certianly find it easier in java or ML.


> Similarly, you
> have to include a special library if you want to do something
> bizarre, like write to standard output.

#include <iostream.h>

Is not a hard thig to do.

> 6.Scheme has first-class functions and continuations.

Well, C++ has function pointers, which can be used much like
first-class functions, though they are harder to use! I wish scheme had
currying too, I use that a lot.

> 7.In Scheme, (* 3 (/ 1 3)) evaluates to 1.

Bad in 2 ways. With integers, this is not the result you want.
Frequently you want integers to behave like integers. Secondly, this is
a lot easier for me to read:

3*(1/3)

> 8.Scheme has no *&%@#! pointers. Memory management is for compilers.
> 9.It's a lot harder to confuse set! and eq? than = and ==.
> 10.The following is actually a legal C statement, according to The
> UNIX-HATERS Handbook:
>
> for(;P("\n"),R=;P("|"))for(e=C;e=P("_"+(*u++/8)%2))P("|"+(*u/4)%2);

Doesn't look valid to me. R=; will probably cause a compiler error.

Here's the original post:


2.Dynamic typing allows you to concentrate on real errors, rather than
trying to placate the compiler god. It
also makes code vastly more reusable.
3.Scheme is actually portable.

5.In C, you have to write the code if you want a really exotic data
structure, like a linked list. Similarly, you
have to include a special library if you want to do something
bizarre, like write to standard output.

7.In Scheme, (* 3 (/ 1 3)) evaluates to 1.

10.The following is actually a legal C statement, according to The
UNIX-HATERS Handbook:

for(;P("\n"),R=;P("|"))for(e=C;e=P("_"+(*u++/8)%2))P("|"+(*u/4)%2);

Doug Bell

unread,
Nov 27, 1996, 3:00:00 AM11/27/96
to

da...@netright.com wrote:

> >GoldenEye wrote:
> > 10.The following is actually a legal C statement, according to The
> > UNIX-HATERS Handbook:
> >
> > for(;P("\n"),R=;P("|"))for(e=C;e=P("_"+(*u++/8)%2))P("|"+(*u/4)%2);
>
> Doesn't look valid to me. R=; will probably cause a compiler error.

Also, the second 'for' statement is missing the second semicolon which
should be inserted at:

for(;P("\n"),R=;P("|"))for(e=C;e=P("_"+(*u++/8)%2);)P("|"+(*u/4)%2);
^

I guess the point being that it's not possible to abuse Scheme's syntax?

Doug Bell
db...@shvn.com

Thant Tessman

unread,
Dec 2, 1996, 3:00:00 AM12/2/96
to

GoldenEye wrote:

[...]

> 2.Dynamic typing allows you to concentrate on real errors, rather
> than trying to placate the compiler god. It also makes code vastly
> more reusable.

David Hanley wrote:

> Hardly true. The only time I ever notice the static type
> checker is when I get a type mismatch. This would have been a
> run-time error in scheme that may have hit for a long time, and

> been hard to debug. [...]

A good type system is better than no type system, but no type system
is better than a bad type system. C++ has a bad type system.


Goldeneye:

> 6.Scheme has first-class functions and continuations. [...]

David Hanley:

> Well, C++ has function pointers, which can be used much like
> first-class functions, though they are harder to use! I wish scheme had
> currying too, I use that a lot.

Function pointers are in no way a substitute for higher-order functions.
As for currying in scheme:

(define (curry f arg)
(lambda rest (apply f (cons arg rest))))

(define add3 (curry + 3))
(add3 4) => 7

...which also happens to be a good example of why function pointers are
in no way a substitute for higher-order functions.


Goldeneye:

> 7.In Scheme, (* 3 (/ 1 3)) evaluates to 1.


David Hanley:

> Bad in 2 ways. With integers, this is not the result you
> want. Frequently you want integers to behave like integers.

No. You mean that sometimes you don't want division to behave like
division:

(* 3 (quotient 1 3))


> Secondly, this is
> a lot easier for me to read:
>
> 3*(1/3)

Do you actually have all the operator precidences in C++ memorized? Or do
you, like me, put redundant parentheses in your code where-ever you're not
sure about them? (Or, do you, like many others, merely discover bugs in
your programs caused by operator precidences you didn't think about?)

Here's my very short list of reasons why Scheme is a better language
than C++:

1) Print out the (R4RS) definition of Scheme and have someone drop it
on your head. Next, print out the (ANSI Draft Standard) definition of
C++ and have someone drop that on your head.

Which is the better language?

I have to admit that there are situations where I would choose C++ over
Scheme. However, my only choices aren't Scheme and C++, and the only
reason I program in C++ at all is because the people I work with don't
have any experience with alternatives. If it weren't for that, I
wouldn't use C++ at all. C++ a disgusting hairball of a language that
should have been abandoned long ago for the obvious mistake that it was.

-thant


--
Thant Tessman <th...@shoreline-studios.com>
http://www.shoreline-studios.com

David Hanley

unread,
Dec 2, 1996, 3:00:00 AM12/2/96
to

Thant Tessman wrote:
>
> GoldenEye wrote:
>
> [...]
>
> > 2.Dynamic typing allows you to concentrate on real errors, rather
> > than trying to placate the compiler god. It also makes code vastly
> > more reusable.
>
> David Hanley wrote:
>
> > Hardly true. The only time I ever notice the static type
> > checker is when I get a type mismatch. This would have been a
> > run-time error in scheme that may have hit for a long time, and
> > been hard to debug. [...]
>
> A good type system is better than no type system, but no type system
> is better than a bad type system. C++ has a bad type system.

This is, of course, a matter of taste. I would qualify scheme's
runtime determination of all types as a really bad type system. C++'s
type system is actually not all *that* bad, though it certianly could be
better.

Nonetheless, the claim made in the original post was the dynamic typing
is inherently better than static typing, which I personally feel is
incorrect.

>
> Goldeneye:
>
> > 6.Scheme has first-class functions and continuations. [...]
>
> David Hanley:
>
> > Well, C++ has function pointers, which can be used much like
> > first-class functions, though they are harder to use! I wish scheme had
> > currying too, I use that a lot.
>
> Function pointers are in no way a substitute for higher-order functions.

I didn't say that they were as good in all cases; however, in many
cases they serve a similar function.

> As for currying in scheme:
>
> (define (curry f arg)
> (lambda rest (apply f (cons arg rest))))
>
> (define add3 (curry + 3))
> (add3 4) => 7
>
> ...which also happens to be a good example of why function pointers are
> in no way a substitute for higher-order functions.

Eh, no, sorry. That's not a full curry, though it's quite clever. I
was unaware of that construct. As long as we're talking about language
hacks, you could do something similar( though surely not the same not as
nice ) in C++ with either function poiners, or an object chain.

>
> Goldeneye:
>
> > 7.In Scheme, (* 3 (/ 1 3)) evaluates to 1.
>
> David Hanley:
>
> > Bad in 2 ways. With integers, this is not the result you
> > want. Frequently you want integers to behave like integers.
>
> No. You mean that sometimes you don't want division to behave like
> division:

No, the integer division of 1/3 is 0. Period. Claiming this correct
result as a language defect is foolish.

>
> (* 3 (quotient 1 3))
>
> > Secondly, this is
> > a lot easier for me to read:
> >
> > 3*(1/3)
>
> Do you actually have all the operator precidences in C++ memorized?

No, this is not necessary.

> Or do
> you, like me, put redundant parentheses in your code where-ever you're not
> sure about them?

Sure. So what?

>
> Here's my very short list of reasons why Scheme is a better language
> than C++:
>
> 1) Print out the (R4RS) definition of Scheme and have someone drop it
> on your head. Next, print out the (ANSI Draft Standard) definition of
> C++ and have someone drop that on your head.

That's a pretty good reason, actually, but I don't think it's the
end-all either.

>
> Which is the better language?
>
> I have to admit that there are situations where I would choose C++ over
> Scheme. However, my only choices aren't Scheme and C++, and the only
> reason I program in C++ at all is because the people I work with don't
> have any experience with alternatives. If it weren't for that, I
> wouldn't use C++ at all. C++ a disgusting hairball of a language that
> should have been abandoned long ago for the obvious mistake that it was.

I do think that C++ is not a very good language. I'd like to see
better languages succeed. However, language devotees have a serious
problem of refusing to see the flaws in thier pet languages. Heck, if
the language was the best soloution, it would probably be a lot more
widely used, right?

Refusing to see the problems with a something is highly destriental to
advancing it's success.

dave

Kent Tong

unread,
Dec 3, 1996, 3:00:00 AM12/3/96
to

Thant Tessman <th...@shoreline-studios.com> wrote:

>A good type system is better than no type system, but no type system
>is better than a bad type system. C++ has a bad type system.

Why do you say that? C++ has a bad type system?

>Function pointers are in no way a substitute for higher-order functions.

>As for currying in scheme:
>
> (define (curry f arg)
> (lambda rest (apply f (cons arg rest))))
>
> (define add3 (curry + 3))
> (add3 4) => 7
>
>...which also happens to be a good example of why function pointers are
>in no way a substitute for higher-order functions.

This can be done in C++ or Java if all the functions take
their parameters from an array or something like that.
Then all we need to do is to store "f" and "arg" in a
(functional) object just like what you did.


---
Kent Tong
v3 is out!!!
Freeman Installer ==> http://www.netnet.net/users/freeman/

Peter Drake

unread,
Dec 3, 1996, 3:00:00 AM12/3/96
to

David Hanley <da...@netright.com> writes:

> Thant Tessman wrote:
> >
> > GoldenEye wrote:

(For the record, no he didn't. He took the top ten list off of one of
my pages, http://www.cs.indiana.edu/hyplan/pedrake/scheme.html.)

> > As for currying in scheme:
> >
> > (define (curry f arg)
> > (lambda rest (apply f (cons arg rest))))
> >
> > (define add3 (curry + 3))
> > (add3 4) => 7
> >
> > ...which also happens to be a good example of why function pointers are
> > in no way a substitute for higher-order functions.
>

> Eh, no, sorry. That's not a full curry, though it's quite clever. I

What constitutes a full curry, IYHO?

> was unaware of that construct. As long as we're talking about language
> hacks, you could do something similar( though surely not the same not as
> nice ) in C++ with either function poiners, or an object chain.

I wasn't aware that C++ could generate functions (or methods) on the
fly. Pray tell, what is the C++ code equivalent to the above? Also,
what language does offer easy "full" currying?

> > > 7.In Scheme, (* 3 (/ 1 3)) evaluates to 1.
> >
> > David Hanley:
> >
> > > Bad in 2 ways. With integers, this is not the result you
> > > want. Frequently you want integers to behave like integers.
> >
> > No. You mean that sometimes you don't want division to behave like
> > division:
>
> No, the integer division of 1/3 is 0. Period. Claiming this correct
> result as a language defect is foolish.

I want numbers to behave like numbers; I'd rather do rounding
explicitly in those rare instances where I want it.

> I do think that C++ is not a very good language. I'd like to see
> better languages succeed. However, language devotees have a serious
> problem of refusing to see the flaws in thier pet languages. Heck, if
> the language was the best soloution, it would probably be a lot more
> widely used, right?

Non sequitur. The most widely used things are not the best. Look at
Microsoft products. Look at television. Look at McDonald's.

> Refusing to see the problems with a something is highly destriental to
> advancing it's success.

Granted. One of the things I like about Scheme is that it can be
expanded. Procedural abstraction is quite difficult in most other
languages. While the Powers That Be have not agreed on it yet, many
Scheme systems also have a <snorts manfully> REAL macro system, which
allows for defining new syntax. If there's something you don't like
about C++, you're stuck with it.


--
Peter Drake PhD Student in Cognitive Science, IU Bloomington
ped...@cs.indiana.edu http://www.cs.indiana.edu/hyplan/pedrake.html
"There's nothing wrong with you that an expensive operation can't
prolong." -- Surgeon to Mr. Notlob


Seth Tisue

unread,
Dec 3, 1996, 3:00:00 AM12/3/96
to

In article <32A373...@netright.com>,

David Hanley <da...@netright.com> wrote:
>> As for currying in scheme:
>> (define (curry f arg)
>> (lambda rest (apply f (cons arg rest))))
>> (define add3 (curry + 3))
>> (add3 4) => 7
>
> Eh, no, sorry. That's not a full curry, though it's quite clever. I
>was unaware of that construct. As long as we're talking about language
>hacks, you could do something similar( though surely not the same not as
>nice ) in C++ with either function poiners, or an object chain.

Could you explain in what way this is not a full curry?

It's not a language hack either, it's fully idiomatic, ordinary Scheme.
--
== Seth Tisue <s-t...@nwu.edu> http://www.cs.nwu.edu/~tisue/

David Hanley

unread,
Dec 3, 1996, 3:00:00 AM12/3/96
to

> > was unaware of that construct. As long as we're talking about language
> > hacks, you could do something similar( though surely not the same not as
> > nice ) in C++ with either function poiners, or an object chain.
>
> I wasn't aware that C++ could generate functions (or methods) on the
> fly.

You don't need to.

> Pray tell, what is the C++ code equivalent to the above?

class add1
{
int i1;
int apply( int i2 ) { return i1 + i2; }
}

class add2
{
add1 *apply( int iv ) { return new add1( iv ); }
}

This is just one way; I can think of a lot of others offhand. I used a
somewhat similar technique in a sml->java comiler I am writing, though
that scheme was a bit more elegant( no pun intended ).

Since you're promoting a language which doesn't provide much, and asks
for programmed extensions for the simplest things, I hope you don;t
criticize this use of the C++ object system.

> Also,
> what language does offer easy "full" currying?

SML has a pretty nice curry system.


> > No, the integer division of 1/3 is 0. Period. Claiming this correct
> > result as a language defect is foolish.
>
> I want numbers to behave like numbers; I'd rather do rounding
> explicitly in those rare instances where I want it.

Well, I hope you're ready for:

1) Actual computer programmers misunderstanding when they see integer
division not behaving like integer division.
2) You programs running really slow when that cool integer computation
gets faulted to floating pint.



>
> > I do think that C++ is not a very good language. I'd like to see
> > better languages succeed. However, language devotees have a serious
> > problem of refusing to see the flaws in thier pet languages. Heck, if
> > the language was the best soloution, it would probably be a lot more
> > widely used, right?
>
> Non sequitur. The most widely used things are not the best.

If you had read the paragraph above, you would have seen that I already
know that. However, there are reasons that the widely used things are
widely used. Simply waving our arms and saying that the popular option
sucks doesn't advance the art one iota.

Making silly claims about scheme's supposed superiority to C++ won't
make more commercial projects use scheme, especially if the people who
chose C++ for them chose C++ for those supposed defects, such as the
type system.


> > Refusing to see the problems with a something is highly destriental to
> > advancing it's success.
>
> Granted. One of the things I like about Scheme is that it can be
> expanded. Procedural abstraction is quite difficult in most other
> languages. While the Powers That Be have not agreed on it yet, many
> Scheme systems also have a <snorts manfully> REAL macro system, which
> allows for defining new syntax.

Uck. I _hate_ that. The _last_ thing I want to do when trying to
debug someone else's code is trying to decipher the new language
features they've added. That possibility alone has probably caused
scheme not to be used for some projects.

> If there's something you don't like
> about C++, you're stuck with it.

To an extent, yes. Many projects choose not to use some of the more
esoteric concepts, such as multiple inheretence and the like. Though,
in truth, the only feature I've ever really pined for in C++ is garbage
collection, though people have added that in add-on packages.

dave

Raymond Toy

unread,
Dec 3, 1996, 3:00:00 AM12/3/96
to

David Hanley <da...@netright.com> writes:

> > > No, the integer division of 1/3 is 0. Period. Claiming this correct
> > > result as a language defect is foolish.
> >
> > I want numbers to behave like numbers; I'd rather do rounding
> > explicitly in those rare instances where I want it.
>
> Well, I hope you're ready for:
>
> 1) Actual computer programmers misunderstanding when they see integer
> division not behaving like integer division.
> 2) You programs running really slow when that cool integer computation
> gets faulted to floating pint.

This follows only because many LANGUAGEs define 1 / 3 to be
truncation (or floating point division).

Mathematically, integer division is well defined IF you include
rationals as a possible result. If you do not, you get possible
strange results like

x = 1 / 3
y = 3 * x

and y is 0. Hardly the expected mathematical result of multiplying a
number with is multiplicative inverse.

It's even worse when you multiply large positive integers and get a
negative result because you overflowed a machine register.

Scheme and Lisp try to be mathematically correct. Languages are free
to ignore mathematics in lieu of something that is right most of the
time but is mathematically wrong sometimes.

The bottom line is you must know exactly how the language defines
operations and note that many times they do not match the mathematical
answer.


No need to comment on other things which are basically computer
language flame wars....

Ray

Vassili Bykov

unread,
Dec 3, 1996, 3:00:00 AM12/3/96
to

free...@wr.com.au (Kent Tong) wrote:
> Thant Tessman <th...@shoreline-studios.com> wrote:
> >[...]

> >...which also happens to be a good example of why function pointers are
> >in no way a substitute for higher-order functions.
>
> This can be done in C++ or Java if all the functions take
> their parameters from an array or something like that.
> Then all we need to do is to store "f" and "arg" in a
> (functional) object just like what you did.

Even if it is so, would you mind writing a C analog of the following
recursive factorial:

(define y-fact
((lambda (f)
((lambda (g)
(f (lambda (arg)
((g g) arg))))
(lambda (g)
(f (lambda (arg)
((g g) arg))))))
(lambda (rec)
(lambda (n)
(if (< n 1)
1
(* n (rec (- n 1))))))))

the point is not whether it is possible or not, actually. Just how
contrived will it be, and how much harder will it be to recognize Y
combinator in it? The point is, any language can do anything, but is
good only for what it's good for.

--Vassili

Rob Warnock

unread,
Dec 4, 1996, 3:00:00 AM12/4/96
to

David Hanley <da...@netright.com> wrote:
+---------------

| No, the integer division of 1/3 is 0. Period. Claiming this correct
| result as a language defect is foolish.
+---------------

The language defect is C++'s (and C's before it). As we were all taught
in grade school, 1 divided by 3 is 1/3 (one third). And that's what you
get in Scheme... which includes has rational numbers. The fact that C
didn't know about anything but "int" and "double" is a historical wart that
C++ inherited, but it's *NOT* particularly correct -- quite the contrary.

As someone else pointed out, if you *want* truncation in Scheme, you can
*ask* for it, several ways, in fact:

(floor (/ 1 3)) ==> 0
(ceiling (/ 1 3)) ==> 1

or more simply:

(quotient 1 3) ==> 0

It's simply that in Scheme it's not automatic that division of exact numbers
will truncate. Instead, division of exact numbers gives you an exact result,
namely, an exact rational number:

(/ 22674322497976 104331282936392) ==> 617/2839

How do you say *that* in C++?


-Rob

-----
Rob Warnock, 7L-551 rp...@sgi.com
Silicon Graphics, Inc. http://reality.sgi.com/rpw3/
2011 N. Shoreline Blvd. Phone: 415-933-1673 FAX: 415-933-0979
Mountain View, CA 94043 PP-ASEL-IA


bmb...@acsu.buffalo.edu

unread,
Dec 4, 1996, 3:00:00 AM12/4/96
to

I only want to address one topic of your message:

David Hanley <da...@netright.com> writes:

[Note: I'm re-adding the Scheme curry function under discussion]

>>>> (define (curry f arg)
>>>> (lambda rest (apply f (cons arg rest))))
>>>>
>>>> (define add3 (curry + 3))
>>>> (add3 4) => 7
>

> > Pray tell, what is the C++ code equivalent to the above?
>
> class add1
> {
> int i1;
> int apply( int i2 ) { return i1 + i2; }
> }
>
> class add2
> {
> add1 *apply( int iv ) { return new add1( iv ); }
> }
>
> This is just one way; I can think of a lot of others offhand. I used a
> somewhat similar technique in a sml->java comiler I am writing, though
> that scheme was a bit more elegant( no pun intended ).

Maybe it's my lack of understanding of C++, but it doesn't look
equivilant to me. Given the above definitions, I would almost say
that the equivilant to your add2 would be (curry curry +).

Give me a curry function in C++ (perhaps heavily templated and
overloaded) that would allow me to do the equivilant of the following
(using the above Scheme definition of the curry function):

(define add3 (curry + 3))

(define 5-or-greater (curry max 5))
(add3 4) => 7
(add3 4 5 6) => 18
(5-or-greater 1) => 5
(5-or-greater 1 2 3 4) => 5
(5-or-greater 4 5 6) => 6

Allowing me to use int add(int,...) and int max(int,...) functions,
although preferrably I'd like to use arbitrary classes and function
arities.

The closest I can see is something like so:

template<Type1,Type2,Type3>
class curry {
Type1 (*fun)(Type2,Type3);
Type2 arg;

public:
curry(Type1 (*f)(Type2,Type3),Type2 a) : fun = f; arg = a; {}
Type1 operator()(Type3 arg2) {return (*fun)(arg,arg2)}
};

But that limits one to reducing functions with two arguments to
functions with one argument, not quite the same as the scheme version.

--
Buddha Buck bmb...@acsu.buffalo.edu
"Just as the strength of the Internet is chaos, so the strength of our
liberty depends upon the chaos and cacaphony of the unfettered speech
the First Amendment protects." -- A.L.A. v. U.S. Dept. of Justice

David Hanley

unread,
Dec 4, 1996, 3:00:00 AM12/4/96
to

Rob Warnock wrote:
>
> David Hanley <da...@netright.com> wrote:
> +---------------
> | No, the integer division of 1/3 is 0. Period. Claiming this correct
> | result as a language defect is foolish.
> +---------------
>
> The language defect is C++'s (and C's before it). As we were all taught
> in grade school, 1 divided by 3 is 1/3 (one third).

Maybe I just went to a bad school, but was learned about something
called "integers" first. If i remember correctly, when dividing these
"integers" 1/3 the correct result was zero. I use this kind of stuff a
lot when I write computer programs, and am saddened that I've been using
an invalid construct all these years. ( note sarcasm )

> And that's what you
> get in Scheme...

The fact it gives a wrong result doesn't impress me too much.

> which includes has rational numbers. The fact that C
> didn't know about anything but "int" and "double"

hardly--it has short, long, float, et al.

dave

Matthias Blume

unread,
Dec 4, 1996, 3:00:00 AM12/4/96
to

In article <5837bn$l...@tokyo.engr.sgi.com> rp...@rigden.engr.sgi.com (Rob Warnock) writes:

David Hanley <da...@netright.com> wrote:
+---------------
| No, the integer division of 1/3 is 0. Period. Claiming this correct
| result as a language defect is foolish.
+---------------

The language defect is C++'s (and C's before it). As we were all taught

in grade school, 1 divided by 3 is 1/3 (one third). And that's what you
get in Scheme... which includes has rational numbers.

Actually, 1/3 is 2. No, I am not kidding, I am just doing arithmetic
in Z_5 -- the (finite) field you get by taking the integers mod 5.

The "fact" that (/ 1 3) is 1/3, or 0, or 2, ... is nothing but an
_arbitrary_ choice. Of course, 1/3 is the most common choice outside
of computer programming, so you might argue that 1/3 is the "correct"
result. But it is only correct up to the definition of what the
division operator does on integers. The definitions for C and Scheme
are different, both are correct. We can argue about the usefulness of
either, not about correctness.

It's simply that in Scheme it's not automatic that division of exact numbers
will truncate. Instead, division of exact numbers gives you an exact result,
namely, an exact rational number:

(/ 22674322497976 104331282936392) ==> 617/2839

Scheme implementations are only encourages, not required to give the
above result. An error due to implementations restrictions may be
signalled as well. So much for Scheme's alleged portability.

--
-Matthias

David Hanley

unread,
Dec 4, 1996, 3:00:00 AM12/4/96
to

bmb...@acsu.buffalo.edu wrote:
>
> I only want to address one topic of your message:
>

okay.

> Maybe it's my lack of understanding of C++, but it doesn't look
> equivilant to me. Given the above definitions, I would almost say
> that the equivilant to your add2 would be (curry curry +).
>
> Give me a curry function in C++ (perhaps heavily templated and
> overloaded) that would allow me to do the equivilant of the following
> (using the above Scheme definition of the curry function):
>
> (define add3 (curry + 3))
> (define 5-or-greater (curry max 5))
> (add3 4) => 7
> (add3 4 5 6) => 18
> (5-or-greater 1) => 5
> (5-or-greater 1 2 3 4) => 5
> (5-or-greater 4 5 6) => 6
>

C doesn't have a way ( simple ) way to have a one-parameter funcrion
take a string of parameters, but this is how I implemented this in the
ml->java compiler:

First, in the class library:

class CurryBase {
protected int intApply() { retutn intApplication(); }
virtual intApplication() = 0;
}

class CurryInt : CurryBase
{
int i1;
CurryBase *CurryInt( int i ) { i1 = i; return this; }
}

class CurryIntInt : CurryInt
{
int i2;
CurryInt *CurryInt( int i ) { i2 = i; return this; }
}

Now, we can extend CurryIntInt:

class Adder : CurryIntInt // needs two integers
{
int intApplication() { return i1 + i2; }
}

class Max5 : CurryInt // needs one integer
{
int intApplicaion() { return max( i1 , 5 ); }
}

So, when we want to curry, we extend a class which represents the tuple
we want to process at the result of the curry process. It's more
keystrokes then the scheme code you posted, but I'm not sure if it's
better or worse.

When you apply an integer to an object that wants two integers, you get
an object that wants one integer. When you apply an integer to an
object that wants one integer, you get an object to which you can apply
an application method, yeilding your result. At each step along the
way, you can pass the objects around, etc,etc. The helper class
hierarchy can be generated with templates.

> class Adder extends Curry


> Allowing me to use int add(int,...) and int max(int,...) functions,
> although preferrably I'd like to use arbitrary classes and function
> arities.
>
> The closest I can see is something like so:
>
> template<Type1,Type2,Type3>
> class curry {
> Type1 (*fun)(Type2,Type3);
> Type2 arg;
>
> public:
> curry(Type1 (*f)(Type2,Type3),Type2 a) : fun = f; arg = a; {}
> Type1 operator()(Type3 arg2) {return (*fun)(arg,arg2)}
> };
>
> But that limits one to reducing functions with two arguments to
> functions with one argument, not quite the same as the scheme version.

That would work too, probably faster, though a bit less flexible.

dave

Mike Haertel

unread,
Dec 4, 1996, 3:00:00 AM12/4/96
to

In article <5837bn$l...@tokyo.engr.sgi.com>,

Rob Warnock <rp...@rigden.engr.sgi.com> wrote:
>It's simply that in Scheme it's not automatic that division of exact numbers
>will truncate. Instead, division of exact numbers gives you an exact result,
>namely, an exact rational number:
>
> (/ 22674322497976 104331282936392) ==> 617/2839

The R4RS does not require all implementations to support rationals.
They are an optional feature. So I strongly disagree with your
blanket statement "In Scheme...".

*Some* scheme implementations support bignums and rationals. Others
don't even unlimited precision "bignum" integers, and have smaller
integers than C implementations on the same machine.

Scheme's generic arithmetic has in some sense been one of the achilles'
heels of the language, since it is difficult to compile to efficient
code in common cases.

>How do you say *that* in C++?

Well, C++ has operator overloading and user-defined types. It would
be pretty easy, just like the usual textbook example of complex numbers.
Remember... "C++: The most elaborate complex number extension ever
added to a language."
--
Mike Haertel <hae...@ichips.intel.com>
Not speaking for Intel.

Charles Bacon

unread,
Dec 4, 1996, 3:00:00 AM12/4/96
to

Blatant snips of authorship:

> +---------------
> | No, the integer division of 1/3 is 0. Period. Claiming this correct
> | result as a language defect is foolish.
> +---------------
>
> The language defect is C++'s (and C's before it). As we were all taught
> in grade school, 1 divided by 3 is 1/3 (one third). And that's what you
> get in Scheme... which includes has rational numbers.
>
>Actually, 1/3 is 2. No, I am not kidding, I am just doing arithmetic
>in Z_5 -- the (finite) field you get by taking the integers mod 5.

I think this has been the most correct post so far (but then
again, I study math). I personally think that the integer division of
1/3 should be an error, since 1/3 doesn't exist. This probably isn't
the most useful interpretation for computer programming, but then
again, we've strayed from talking about that.
I'd also like to add that, quibbles aside, I thought the 10
reasons were pretty funny. That seems to have been lost in the
shuffle.

Guillermo (Bill) J. Rozas

unread,
Dec 4, 1996, 3:00:00 AM12/4/96
to

In article <4nenh74a...@rtp.ericsson.se> Raymond Toy <t...@rtp.ericsson.se> writes:

| From: Raymond Toy <t...@rtp.ericsson.se>
| Date: 03 Dec 1996 15:47:08 -0500
|
| It's even worse when you multiply large positive integers and get a
| negative result because you overflowed a machine register.

Or even add them and get a nonsense negative result.

This is a much better example of why generic arithmetic in Lisp and
Scheme is a win in many cases. After all, the ring of integers is
well understood, and so is the ring of integers modulo any value
(including 2^16, 2^32, 2^64).

The problem with the lack of bignums in C and ML (the trapping
behavior of signed overflow in ML is not really adequate) is that it
makes the meaning of a program dependent on the machine word size and
the choice that the compiler-writer made for the size of one or
several flavors of integers.

Yes, this leads to greater efficiency in the absence of both hardware
and runtime system support, but it also leads to porting problems when
going to a different compiler or machine.

Robert McDermid

unread,
Dec 4, 1996, 3:00:00 AM12/4/96
to

In message <4nenh74a...@rtp.ericsson.se> - Raymond Toy

<t...@rtp.ericsson.se>03 Dec 1996 15:47:08 -0500 writes:
>
>
>Mathematically, integer division is well defined IF you include
>rationals as a possible result. If you do not, you get possible
>strange results like
>
> x = 1 / 3
> y = 3 * x
>
>and y is 0. Hardly the expected mathematical result of multiplying a
>number with is multiplicative inverse.


:-) I think you should re-read what you just wrote, as it's
rather funny. If you include rationals as a possible result,
then you're not doing integer division, since a rational number
is, by definition, not an integer - it's a rational. Integer
division of 1 by 3 produces a result of 0 - there's no other
way to present the result in the integer number system. If you
want to handle rational results on a computer, you must use
floating point (and start worrying about round-off error, truncation
error, etc., etc., etc.) Whole courses are taught in
Computer Science which deal with nothing but this single area
of computation - it is by no means a simple topic.

BTW, 1/3 is an irrational, not a rational, and there's no way to
represent that precisely at all (using floating point) on a computer.
Thus, in the example you give, y will never equal x no matter
what computer language you use. (Do any of the symbolic manipulation
packages like Maple have a way of handling this better?)

-- Rob
==============================================================
Rob McDermid Hummingbird Communications Ltd.
mcde...@hcl.com All opinions expressed are my own.
==============================================================


Seth Tisue

unread,
Dec 4, 1996, 3:00:00 AM12/4/96
to

In article <584nbh$1...@news.hcl.com>, Robert McDermid <mcde...@hcl.com> wrote:
>BTW, 1/3 is an irrational, not a rational

Bzzzzzzzzzzt!

Seth Tisue

unread,
Dec 4, 1996, 3:00:00 AM12/4/96
to

In article <32A5A2...@netright.com>,

David Hanley <da...@netright.com> wrote:
> C doesn't have a way ( simple ) way to have a one-parameter funcrion
>take a string of parameters, but this is how I implemented this in the
>ml->java compiler:

So what would this code look like if you used templates or whatever to
extend it to work on other things besides integers?

Curious,

Matthias Blume

unread,
Dec 5, 1996, 3:00:00 AM12/5/96
to

In article <584nbh$1...@news.hcl.com> mcde...@hcl.com (Robert McDermid) writes:

BTW, 1/3 is an irrational, not a rational,

Huh?

and there's no way to
represent that precisely at all (using floating point) on a computer.
Thus, in the example you give, y will never equal x no matter
what computer language you use. (Do any of the symbolic manipulation
packages like Maple have a way of handling this better?)

Of course -- by using rational numbers. (Which, btw, are _not_ to be
confused with floating point.)


--
-Matthias

Mark Meiss

unread,
Dec 5, 1996, 3:00:00 AM12/5/96
to

In article <584nbh$1...@news.hcl.com>, Robert McDermid <mcde...@hcl.com> wrote:
>
>BTW, 1/3 is an irrational, not a rational, and there's no way to

>represent that precisely at all (using floating point) on a computer.

It is too a rational. It's the ratio of two integers. It's a repeating
decimal. And it can be expressed exactly in base 3 as 0.1, in base 6
as 0.2, in base 12 as 0.25, and so on.

In fact, it would be interesting to write a package that used "BCDD"
(Binary-Coded DuoDecimal) to represent floating-point numbers, since
many more rational numbers would then have exact representations.
IMHO, anyway.

--Mark
--
Mark Meiss (mme...@indiana.edu) | No eternal reward will
Indiana University CS Dept. | forgive us now for - Jim Morrison
Bloomington, Indiana, USA | wasting the dawn.

Chris Dollin

unread,
Dec 5, 1996, 3:00:00 AM12/5/96
to

In article <584nbh$1...@news.hcl.com> mcde...@hcl.com (Robert McDermid) writes:

BTW, 1/3 is an irrational, not a rational,

This will be news to many generations of mathematicians. 1/3 is more rational
than I am.

and there's no way to represent that precisely at all (using floating
point) on a computer.

Certainly there is; just use base 3 arithmetic. (Of course you'll have to
*implement* it all, which is a tad tricky, and there might be a little
performance reduction, but the principle's sound.)

Perhaps you mean that 1/3 has no finte exact representation in base 2 (or
10)? That's rather different from being ``irrational'', surely?

Thus, in the example you give, y will never equal x no matter
what computer language you use. (Do any of the symbolic manipulation
packages like Maple have a way of handling this better?)

Yes, they represent 1/3 as 1/3. The obvious implementation that comes to mind
is to represent a rational as a pair of integers with highest common factor
1. (That's what Poplog does, although it's not a symbolic manipulation
package.)
--

Regards, | "You're better off not dreaming of the things to come;
Kers. | Dreams are always ending far too soon." - Caravan.

bmb...@acsu.buffalo.edu

unread,
Dec 5, 1996, 3:00:00 AM12/5/96
to

David Hanley <da...@netright.com> writes:

>
> C doesn't have a way ( simple ) way to have a one-parameter funcrion
> take a string of parameters, but this is how I implemented this in the
> ml->java compiler:

OK, so I'll ignore the multiple arity issue for now.


> First, in the class library:

> class CurryBase {
> protected int intApply() { retutn intApplication(); }
> virtual intApplication() = 0;
> }

> class CurryInt : CurryBase
> {
> int i1;
> CurryBase *CurryInt( int i ) { i1 = i; return this; }
> }

> class CurryIntInt : CurryInt
> {
> int i2;
> CurryInt *CurryInt( int i ) { i2 = i; return this; }
> }

> Now, we can extend CurryIntInt:

> class Adder : CurryIntInt // needs two integers
> {
> int intApplication() { return i1 + i2; }
> }

> class Max5 : CurryInt // needs one integer
> {
> int intApplicaion() { return max( i1 , 5 ); }
> }

> So, when we want to curry, we extend a class which represents the tuple
> we want to process at the result of the curry process. It's more
> keystrokes then the scheme code you posted, but I'm not sure if it's
> better or worse.

OK, but does this scheme allow me to generate curried functions at run-time?

In scheme, I can pass curry a function that I can't determine what is
at compile-time, such as the comparison function used in qsort(). (I
doubt it if creating a less_than_pivot(void*) in this case would be
worth the effort, but is certainly is one implementation).

(This could be solved by having intApplication be not a virtual null
member function, but rather a pointer to an int(int,int), and
modifying the constructor appropriately, I guess. But that sort of
puts you where I was below).

I can also use as my argument to be curried any arbitrary run-time
value, as opposed to the Max5 class above (effectively, a MaxN class).

> When you apply an integer to an object that wants two integers, you get
> an object that wants one integer. When you apply an integer to an
> object that wants one integer, you get an object to which you can apply
> an application method, yeilding your result. At each step along the
> way, you can pass the objects around, etc,etc. The helper class
> hierarchy can be generated with templates.

> > The closest I can see is something like so:

> > template<Type1,Type2,Type3>
> > class curry {
> > Type1 (*fun)(Type2,Type3);
> > Type2 arg;

> > public:
> > curry(Type1 (*f)(Type2,Type3),Type2 a) : fun = f; arg = a; {}
> > Type1 operator()(Type3 arg2) {return (*fun)(arg,arg2)}
> > };

> > But that limits one to reducing functions with two arguments to
> > functions with one argument, not quite the same as the scheme version.

> That would work too, probably faster, though a bit less flexible.

I fail to see it as less flexible. It generates curries at run-time,
instead of using distinct classes for each curry, and allows arbitrary
2-arity functions with arbitrary return values.

Extending this seamlessly to 3-arity or higher functions doesn't seem
as simple as in your example, I will admit.

(If I am missing something, -please- explain: I'm a college student
who has never had a formal class in Scheme or any Lisp-like language,
and this is the first semester that C++ has been thrust upon me. It
is very likely that I am indeed missing something due to lack of
exposure and experience.)

In line with the previous parethesized remark, what, exactly, do you
mean by "full currying" as opposed to what the Scheme implementation
does? You stated a few messages ago that the scheme code didn't do
full currying. To my understanding (albeit limited), it does
(generates a function of n-1 arguments out of a function of n
arguments plus an argument).

Or would you prefer having to use syntax like so:

(define (5args a1 a2 a3 a4 a5)
(+ a1 a2 a3 a4 a5))

((((((curry 5args) 5) 4) 3) 2) 1) => 15

which could be considered "full currying" (replacing a function that
takes n arguments with a series of functions that take one argument
each and return a function that takes one argument each).

> dave

Stuart I Reynolds

unread,
Dec 5, 1996, 3:00:00 AM12/5/96
to

David Hanley wrote:
>
> Rob Warnock wrote:

> > The language defect is C++'s (and C's before it). As we were all taught
> > in grade school, 1 divided by 3 is 1/3 (one third).


No, no no!!
Even the most hardend mathematicians agree that 1/3 is 0 if 1 and 3 are
in the INTEGER domain. To evaluate the division of one integer with
another integer will result in an integer, whether using programming
lanuages, alogrithms on paper or whatever. Integers have well defined
properties as does integer division - this is not in any way a fault of
C++.

Besides, what C++ does do is let you create your own types, which in
turn could represent numbers as numerators and denominators, and
redefine the meaning of operators which act upon them. C++ is pretty
poineering (and still unique, I believe) in this respect. What you have
described in Scheme takes that flexibilty away from you - can it do
integer division?

If you don't want to do integer division, don't use integers. This is
why C++ is a strongly typed language - unlike BBC BASIC say which also
dynamically altered the types of variables.

Are you saying BASIC is better than C++.

Stu

Justin Pearson

unread,
Dec 5, 1996, 3:00:00 AM12/5/96
to

Stuart I Reynolds <s...@cs.bham.ac.bham> writes:

>
> David Hanley wrote:
>
> If you don't want to do integer division, don't use integers. This is
> why C++ is a strongly typed language - unlike BBC BASIC say which also
> dynamically altered the types of variables.

\begin{Pedant mode}
Actually BBC BASIC was in a sense strongly typed, just that the typing
information was included in the variable name.
So A$ could only hold string values
A could only hold floating point values and A% could only hold integer
values.
Further A$ A% and A where distinct variables. I don't think there was
a way of dynamically altering the types of variables in BBC Basic.

\end{Pedant mode}

Will Ware

unread,
Dec 5, 1996, 3:00:00 AM12/5/96
to

Mark Meiss (mme...@beavis.indiana.edu) wrote:
: In article <584nbh$1...@news.hcl.com>, Robert McDermid <mcde...@hcl.com> wrote:
: >
: >BTW, 1/3 is an irrational, not a rational...
: It is too a rational. It's the ratio of two integers. It's a repeating

: decimal. And it can be expressed exactly in base 3 as 0.1, in base 6
: as 0.2, in base 12 as 0.25, and so on.

Sorry to pick nits, but the number in base 12 is 0.4.
--
-------------------------------------------------------------
Will Ware <ww...@world.std.com> web <http://world.std.com/~wware/>
PGP fingerprint 45A8 722C D149 10CC F0CF 48FB 93BF 7289

Mark Meiss

unread,
Dec 5, 1996, 3:00:00 AM12/5/96
to

In article <E1y1K...@world.std.com>, Will Ware <ww...@world.std.com> wrote:
>Mark Meiss (mme...@beavis.indiana.edu) wrote:
>: In article <584nbh$1...@news.hcl.com>, Robert McDermid <mcde...@hcl.com> wrote:
>: >
>: >BTW, 1/3 is an irrational, not a rational...
>: It is too a rational. It's the ratio of two integers. It's a repeating
>: decimal. And it can be expressed exactly in base 3 as 0.1, in base 6
>: as 0.2, in base 12 as 0.25, and so on.
>
>Sorry to pick nits, but the number in base 12 is 0.4.

Well, if I'm picking nits, I deserve to have my nits picked too.
Yeah, what you said. My brain burped halfway back into base 10 there.

a...@laphroig.mch.sni.de

unread,
Dec 5, 1996, 3:00:00 AM12/5/96
to

David Hanley wrote:
>>
>> Goldeneye:

>>
>> > 7.In Scheme, (* 3 (/ 1 3)) evaluates to 1.
>>
>> David Hanley:
>>
>> > Bad in 2 ways. With integers, this is not the result you
>> > want. Frequently you want integers to behave like integers.
>>
>> No. You mean that sometimes you don't want division to behave like
>> division:
>
> No, the integer division of 1/3 is 0. Period. Claiming this correct
>result as a language defect is foolish.

That's simply not true! You just can't divide the integer 1 by the
integer 3 and get an integer result. It certainly is not zero. You can
enlarge the ring of integers with their field of fractions to get the
rational numbers and then 1 / 3 = 1/3. If you want a result like 0 you
should take the floor or the the Gauss bracket of 1/3. Scheme is
(thankfully) one of the few languages that gets arithmetic right.


Andreas Eder

Thant Tessman

unread,
Dec 5, 1996, 3:00:00 AM12/5/96
to

[comp.lang.java.programmer taken out of followups]


I wrote:

> Function pointers are in no way a substitute for
> higher-order functions.


> As for currying in scheme:
>

> (define (curry f arg)
> (lambda rest (apply f (cons arg rest))))
>

> (define add3 (curry + 3))

> (add3 4) => 7


>
>...which also happens to be a good example of why function
> pointers are in no way a substitute for higher-order functions.

Kent Tong wrote:

> This can be done in C++ or Java if all the functions take
> their parameters from an array or something like that.
> Then all we need to do is to store "f" and "arg" in a
> (functional) object just like what you did.

How convenient.

Actually, I've built a curry system for C++ using templates. You
can do things like this:

void f(const int& i, const int& j) {
cout << i << " " << j << endl;
}

Thunk1<int> f2 = curry1(f, 23);
Thunk0 f3 = curry0(f2, 5);

f3();

"curry0" and "curry1" are function templates that automatically
instantiate other helper template classes. "f2" is a function
object taking a single integer as an argument, and "f3" is a
function object taking no arguments. The output of evaluating
"f3()" is "23 5" as one would expect. You can even combine
the two statements and evaluate them immediately like this:

(curry0(curry1(f, 23), 5))();

Now given that we're working in C++, you gotta admit this is
pretty cool--certainly better than passing arguments in by way
of an array. But let's start comparing it to, say, the Scheme
example above, or the equally fully-polymorphic yet type-safe
equivalent in SML.

First off, this C++ version was a pain to write, and it took a
long time to get it correct. Second, it's a pain to use because
you have to produce a different version of the template function
for every possible number of arguments (note the "1" and "0" in
curry1 and curry0 and Thunk1 and Thunk0) *and* for every possible
return type. (I've only built them for functions and function
objects returning void.) Also, you have to have a different
version for whether you're going to pass arguments by reference,
or literally on the stack. (I've only implemented the former,
which is why "f" takes "const int&" instead of "int".)

And to top it off, I have a completely different set of
template functions for packaging up objects and member
function pairs into thunks. (They do mix and match though.)

Some people might think that this is a good demonstration
of how expressive C++ is. Compared to C, yeah, sure. But
the truth is that it took several orders-of-magnitude longer
to implement than the equivalent Scheme or SML construct, and
yet it is also a much more awkward and less general solution.
And attempts to further generalize the solution always start
looking like full-fledged interpreters in their own right, so
you lose the supposed benefits of using C++ in the first place.

C++ just plain sucks. But you'll never know that if all you've
ever programmed in is C++ (or C, or Pascal, or Fortran, or
COBOL).

-thant

--
Thant Tessman <th...@acm.org>

Dennis Weldy

unread,
Dec 5, 1996, 3:00:00 AM12/5/96
to

Stuart I Reynolds <s...@cs.bham.ac.bham> wrote in article
<32A6B7...@cs.bham.ac.bham>...

> Besides, what C++ does do is let you create your own types, which in
> turn could represent numbers as numerators and denominators, and
> redefine the meaning of operators which act upon them. C++ is pretty
> poineering (and still unique, I believe) in this respect. What you have
> described in Scheme takes that flexibilty away from you - can it do
> integer division?
>
Not quite - Ada also allowed operator overloading. Indeed, when I learned
about Ada in grad school, I thought "gosh, I'd love a langugae that
combined the best of C and Ada!"
Little did I know it already existed as C++. :-)

Dennis

a...@laphroig.mch.sni.de

unread,
Dec 5, 1996, 3:00:00 AM12/5/96
to

Davide Hanley wrote:
>> Pray tell, what is the C++ code equivalent to the above?
>
>class add1
>{
> int i1;
> int apply( int i2 ) { return i1 + i2; }
>}
>
>class add2
>{
> add1 *apply( int iv ) { return new add1( iv ); }
>}
>
That's only good if you like writing out the gory detail for thousands
of different addn classes. In scheme you can do it once and for all if
you define a function addn:
(define addn (lambda (n) (lambda (x) (+ xn))))
and then if you need, say add1024, you do (define add1024 (addn 1024))
and that's it.

>> > No, the integer division of 1/3 is 0. Period. Claiming this correct
>> > result as a language defect is foolish.
>>

>> I want numbers to behave like numbers; I'd rather do rounding
>> explicitly in those rare instances where I want it.
>
> Well, I hope you're ready for:
>
> 1) Actual computer programmers misunderstanding when they see integer
>division not behaving like integer division.
> 2) You programs running really slow when that cool integer computation
>gets faulted to floating pint.

In scheme integer arithmetic will never get faulted to floating point!
Integer arithmetic will always stay integer arithmetic; if you cross the
fixnum boundary it might get slower, but at least you will get the right
result. And integer + integer is never a floating point, but always
integer.

>> Non sequitur. The most widely used things are not the best.
>
> If you had read the paragraph above, you would have seen that I already
>know that. However, there are reasons that the widely used things are
>widely used. Simply waving our arms and saying that the popular option
>sucks doesn't advance the art one iota.
>
> Making silly claims about scheme's supposed superiority to C++ won't
>make more commercial projects use scheme, especially if the people who
>chose C++ for them chose C++ for those supposed defects, such as the
>type system.

There"s no need here to advance the art. There are already better
things, and the reasons why the aren't used but obvioulsy inferior
things are mor of a psychological end educational nature. (You could
also say marketing). Do you really think that most commercial projects
are done in C or C++, because they are technically superior to other
languages ? No, it's because they simply don't know about modern
developments in programming languages!

>> > Refusing to see the problems with a something is highly destriental to
>> > advancing it's success.
>>
>> Granted. One of the things I like about Scheme is that it can be
>> expanded. Procedural abstraction is quite difficult in most other
>> languages. While the Powers That Be have not agreed on it yet, many
>> Scheme systems also have a <snorts manfully> REAL macro system, which
>> allows for defining new syntax.
>
> Uck. I _hate_ that. The _last_ thing I want to do when trying to
>debug someone else's code is trying to decipher the new language
>features they've added. That possibility alone has probably caused
>scheme not to be used for some projects.

Uck. I _hate_ that. The _last_ thing I want to do when trying to

debug someone else's code is trying to decipher the new procedures
they've added. Why can't they just use the predefined functions and
write everything in one big file full of asm statements. :-)
Seriously, abstraction helps to debug other peoples code, if it's done
right. And to do that properly you often need a good macro system. (Not
what C programmers think is a macro system).

Andreas


a...@laphroig.mch.sni.de

unread,
Dec 5, 1996, 3:00:00 AM12/5/96
to

Robert McDermid wrote:
>Integer division of 1 by 3 produces a result of 0 - there's no other
>way to present the result in the integer number system. If you
>want to handle rational results on a computer, you must use
>floating point (and start worrying about round-off error, truncation
Of course - if you insist on an integer result for dividing 1 by 3
there is much more choice than just 0. I personally prefer 42 :-)
And certainly 1/3 is not a floating point number but rational. You can
easily represent it as a pair of integers. And by the way, we don't need
negative numbers too, we can also easily represent them as a pair of
natural numbers. And if go into the other direction, we can also exactly
represent algebraic numbers without resort to floating point and you can
even do exact arithmetic on all computable numbers.

Andreas

Robert McDermid

unread,
Dec 5, 1996, 3:00:00 AM12/5/96
to

In message <585pah$o...@dismay.ucs.indiana.edu> - mme...@beavis.indiana.edu

(Mark Meiss)5 Dec 1996 06:15:45 GMT writes:
>
>In article <584nbh$1...@news.hcl.com>, Robert McDermid <mcde...@hcl.com> wrote:
>>
>>BTW, 1/3 is an irrational, not a rational, and there's no way to

>>represent that precisely at all (using floating point) on a computer.
>
>It is too a rational. It's the ratio of two integers. It's a repeating
>decimal. And it can be expressed exactly in base 3 as 0.1, in base 6
>as 0.2, in base 12 as 0.25, and so on.

Oops. Sorry, brain wasn't working very well towards the end of the day.


>
>In fact, it would be interesting to write a package that used "BCDD"
>(Binary-Coded DuoDecimal) to represent floating-point numbers, since
>many more rational numbers would then have exact representations.
>IMHO, anyway.
>

Didn't Borland used to have this as part of their C library? Or was
it just BCD?

Once you start getting into special-purpose math packages you can
do almost anything, of course, at the expense of efficiency (at least
on a binary-hardware computer). Of course, all of the compromises
we routinely make in mathematics on computers are directly related
to increasing the computation speed in binary, for general purpose
computation.

Guillermo (Bill) J. Rozas

unread,
Dec 5, 1996, 3:00:00 AM12/5/96
to

In article <32A6B7...@cs.bham.ac.bham> Stuart I Reynolds <s...@cs.bham.ac.bham> writes:

| From: Stuart I Reynolds <s...@cs.bham.ac.bham>
| Date: Thu, 05 Dec 1996 11:53:45 +0000
|
| Besides, what C++ does do is let you create your own types, which in
| turn could represent numbers as numerators and denominators, and
| redefine the meaning of operators which act upon them. C++ is pretty
| poineering (and still unique, I believe) in this respect. What you have
| described in Scheme takes that flexibilty away from you - can it do
| integer division?

Scheme can do both integer and complex number division (in an
implementation that supports the full numeric tower).

The / operator performs complex division. The quotient operator
performs integer division.

Scheme has not taken the flexibility away. It has just made a
different choice on the meaning of a common operator.

The generic arithmetic of Scheme (and other Lisps) isolates from
word-size vagaries (implementations often have limited-size operators
as well, but not the standard) and some loss of accuracy.

scha...@wat.hookup.net

unread,
Dec 5, 1996, 3:00:00 AM12/5/96
to

In <32A59F...@netright.com>, David Hanley <da...@netright.com> writes:
> ...

> Maybe I just went to a bad school, but was learned about something
>called "integers" first. If i remember correctly, when dividing these
>"integers" 1/3 the correct result was zero. I use this kind of stuff a

No: the correct result in the domain of integers is 0 with a remainder of 2.
to handle such results more concisely, fractions were invented.

>lot when I write computer programs, and am saddened that I've been using
>an invalid construct all these years. ( note sarcasm )

> ...
> The fact it gives a wrong result doesn't impress me too much.

It gives you the right result in the domain of rational numbers, and there
either is a library function or you can write one yourself for each of the
following desired results:

- integer quotient
- remainder
- pair of quotient and remainder

>> which includes has rational numbers. The fact that C
>> didn't know about anything but "int" and "double"
>
> hardly--it has short, long, float, et al.
>
> dave

Hartmann Schaffer


Matthias Blume

unread,
Dec 5, 1996, 3:00:00 AM12/5/96
to

In article <32A6B7...@cs.bham.ac.bham> Stuart I Reynolds <s...@cs.bham.ac.bham> writes:

Even the most hardend mathematicians agree that 1/3 is 0 if 1 and 3 are
in the INTEGER domain.

Nonsense. There is no division in the integer domain. That is to
say, in the ring of integers there doesn't exist a multiplicative
inverse for most of the elements. What you call integer division is a
very different concept. And here the answer 0 for 1/3 is not even
complete, because you forgot to mention the remainder. The result of
integer division is _two_ numbers: a quotient and a remainder.
Unfortunately, languages which get this right are extremely rare, even
though most microprocessors actually calculate both numbers at the
same time.

To evaluate the division of one integer with
another integer will result in an integer, whether using programming
lanuages, alogrithms on paper or whatever. Integers have well defined
properties as does integer division - this is not in any way a fault of
C++.

Yes, it is just a different concept, not at all the same as taking the
inverse in a domain that provides such multiplicative inverses. If
you make clear beforehand what you are talking about, then, of course,
there is no confusion later on. As I pointed out in another reply
before, you could just as easily define 1/3 to be 2. And it would
even make sense.

It is C's fault to denote two very different concepts by the same
symbol: /. C++ has inherited this fault. Furthermore, by allowing
programmers to add their own overloads it has made the situation
worse. Example: cout << 2 << 2. This one should print "22". On
the other hand: cout << (2 << 2) completely changes the meaning of the
second << and prints "8".

Besides, what C++ does do is let you create your own types, which in
turn could represent numbers as numerators and denominators, and
redefine the meaning of operators which act upon them. C++ is pretty
poineering (and still unique, I believe) in this respect.

Huh? Do you actually know any other language. C++ is by no means
pioneering in _any_ respect.

What you have
described in Scheme takes that flexibilty away from you - can it do
integer division?

Of course. Except, in Scheme you use a different name for that
operation (which is appropriate, since it is conceptually very
different).

--
-Matthias

David Hanley

unread,
Dec 5, 1996, 3:00:00 AM12/5/96
to

a...@laphroig.mch.sni.de wrote:
>
> Davide Hanley wrote:
> >> Pray tell, what is the C++ code equivalent to the above?
> >
> >class add1
> >{
> > int i1;
> > int apply( int i2 ) { return i1 + i2; }
> >}
> >
> >class add2
> >{
> > add1 *apply( int iv ) { return new add1( iv ); }
> >}
> >
> That's only good if you like writing out the gory detail for thousands
> of different addn classes. In scheme you can do it once and for all if
> you define a function addn:
> (define addn (lambda (n) (lambda (x) (+ xn))))
> and then if you need, say add1024, you do (define add1024 (addn 1024))
> and that's it.

That's what the c++ version was doing. You could learn a little c++
before criticizing it.

ish.
> >>
> >> I want numbers to behave like numbers; I'd rather do rounding
> >> explicitly in those rare instances where I want it.
> >
> > Well, I hope you're ready for:
> >
> > 1) Actual computer programmers misunderstanding when they see integer
> >division not behaving like integer division.
> > 2) You programs running really slow when that cool integer computation
> >gets faulted to floating pint.
>
> In scheme integer arithmetic will never get faulted to floating point!
> Integer arithmetic will always stay integer arithmetic; if you cross the
> fixnum boundary it might get slower, but at least you will get the right
> result.

No. The correct result of an integer (1/3)*3 is zero. Now, it's fine
to have a language that gives the wrong result for integer math, along
wiht a big speed hit, but I was trying to point out that it's silly to
riticize other languages for doing something right. There's a lot of
bad stuff in C++ that could be picked on, like MI, casting, and it's
header file approach to project management.

> And integer + integer is never a floating point, but always
> integer.
>

> > Making silly claims about scheme's supposed superiority to C++ won't
> >make more commercial projects use scheme, especially if the people who
> >chose C++ for them chose C++ for those supposed defects, such as the
> >type system.
>
> There"s no need here to advance the art. There are already better
> things, and the reasons why the aren't used but obvioulsy inferior
> things are mor of a psychological end educational nature.

Frankly, I don't buy that argument for a minute. People _are_ moving
away from C++. 4GL's are common, Java is catching on fast, and a lot of
applications are written in visual basic, for crying out loud.
Pprogrammers have demonstrated their ability to change technologies when
there is something better suited waiting.

? (You could


> also say marketing). Do you really think that most commercial projects
> are done in C or C++, because they are technically superior to other
> languages ? No, it's because they simply don't know about modern
> developments in programming languages!

This is not my experience. A lot of people would be happy to stop
using C++ if there was a better alternative--a better language, similar
in speed, with as good enviornments, and a similar array of tools. I
don't think anyone is going to claim that scheme can fill this need.


> > Uck. I _hate_ that. The _last_ thing I want to do when trying to
> >debug someone else's code is trying to decipher the new language
> >features they've added. That possibility alone has probably caused
> >scheme not to be used for some projects.
>
> Uck. I _hate_ that. The _last_ thing I want to do when trying to
> debug someone else's code is trying to decipher the new procedures
> they've added.

Haha. Funny. Are you trying to claim that it's easier to decipher a
procedure in a language that you know, rather than deciphering a new
language? i _really_ doubt that.

dave

James Lee

unread,
Dec 5, 1996, 3:00:00 AM12/5/96
to

mcde...@hcl.com wrote in <584nbh$1...@news.hcl.com>:

] :-) I think you should re-read what you just wrote, as it's
] rather funny.

Maybe you should take your own advice.

] want to handle rational results on a computer, you must use


] floating point (and start worrying about round-off error, truncation

] error, etc., etc., etc.)

No, if you want to handle rational results, you must use
rational numbers (p/q, p q in Z), which *are not* floating point.

] BTW, 1/3 is an irrational, not a rational, and there's no way to

;-)


--
James Lee <jl...@math.purdue.edu> / Dirk <di...@purdue.edu>
Fingerprint = 2F 00 21 17 A5 16 04 7 8D EC 4E C7 9D 90 22 5F
PGP mail encouraged Key ID: 1024/39A4CC25 Finger for public key

Alan Bawden

unread,
Dec 5, 1996, 3:00:00 AM12/5/96
to

In article <32A6B7...@cs.bham.ac.bham>
Stuart I Reynolds <s...@cs.bham.ac.bham> writes:

> > The language defect is C++'s (and C's before it). As we were all taught
> > in grade school, 1 divided by 3 is 1/3 (one third).

No, no no!!


Even the most hardend mathematicians agree that 1/3 is 0 if 1 and 3 are
in the INTEGER domain.

You're all wrong.

The correct answer should depend on the size of an int. On a 32 bit
machine, the correct answer is: -1431655765

I am surrounded by morons.
--
Alan Bawden Al...@LCS.MIT.EDU
617/492-7274 06BF9EB8FC4CFC24DC75BDAE3BB25C4B

Raffael Cavallaro

unread,
Dec 5, 1996, 3:00:00 AM12/5/96
to

In article <584nbh$1...@news.hcl.com>, mcde...@hcl.com wrote:


> BTW, 1/3 is an irrational, not a rational, and there's no way to

> represent that precisely at all (using floating point) on a computer.

You're confusing a repeating decimal with an irrational number. There a
rational number is any number that can be expressed by the ratio of two
integers. That's why they're called *rational* numbers (get it?--ratio,
rational).1/3 is *obviously* a rational number. Pi is irrational -- it
can't be expressed by the ratio of two integers.

Just because 1/3 is an infinitely repeating number in the *decimal*
system, doesn't make it irrational. After all, in base 3, 1/3 is expressed
as .1

Raf

Christopher Oliver

unread,
Dec 5, 1996, 3:00:00 AM12/5/96
to

Stuart I Reynolds (s...@cs.bham.ac.bham) wrote:
: No, no no!!

: Even the most hardend mathematicians agree that 1/3 is 0 if 1 and 3 are
: in the INTEGER domain.

Ummmm... no.

I think the hardened mathematicians will agree that division isn't closed
over the integers, and that there is no integer value for the ratio 1/3.

--
Christopher Oliver Traverse Communications
Systems Coordinator 223 Grandview Pkwy, Suite 108
oli...@traverse.com Traverse City, Michigan, 49684
The loop macro: because no language is complete without a little COBOL.

Alberto C Moreira

unread,
Dec 6, 1996, 3:00:00 AM12/6/96
to

In article <587dlg$5...@bert.traverse.com>, oli...@co.traverse.com says...

> Stuart I Reynolds (s...@cs.bham.ac.bham) wrote:
> : No, no no!!
> : Even the most hardend mathematicians agree that 1/3 is 0 if 1 and 3
are
> : in the INTEGER domain.
>
> Ummmm... no.
>
> I think the hardened mathematicians will agree that division isn't
closed
> over the integers, and that there is no integer value for the ratio
1/3.


I tought the quotient of two positive integers a/b under integer
division was the number q such that (1) 0 < q <= a, (2) 0 <= r < b, and
(3) a = qb + r.

At least that's what they taught me back in elementary school, and it's
quite a useful definition.


Alberto.

Matthias Blume

unread,
Dec 6, 1996, 3:00:00 AM12/6/96
to

The following article is a reply to e-mail from Thomas Breuel, who by
means of clever sender address design cannot be reached otherwise....

In some e-mail that was sent to me Thomas Breuel <t...@intentionally.blank>
writes:

> bl...@dynamic.cs.princeton.edu (Matthias Blume) writes:
> > It is C's fault to denote two very different concepts by the same
> > symbol: /.

> Actually, Fortran did this before, and C simply followed established
> practice (just like many other programming languages). For writing
> numerical algorithms, this convention seems to be much more useful
> than dynamically switching to a rational number representation.

I fail to see the usefulness of it. Why can't you have a different
name for integer division, like so many other languages actually do to
avoid this sort of confusion?

BTW, Fortran is hardly the prototypical example to look at when
studying good language design. [I don't blame the designers of
Fortran, after all, there was hardly any prior art at that time. But
I do blame the designers of C, and even more so, of C++ for making the
same mistakes (and then some) all over again.]

-Matthias
--
-Matthias

Michael Simpson

unread,
Dec 6, 1996, 3:00:00 AM12/6/96
to

In article <imbuc7n...@elk.cs.uidaho.edu> Faried Nawaz, f...@uidaho.edu
writes:
>
> It really would not matter if the Scheme semantics were
> 100 times better than C++. I'm going to use the language that brings me
> the highest hourly rate and the most billable hours period.
>
>Then whether a language is good or not isn't all that important to you.
>
>

C/C++ accomplishes everything I need it to do as efficient as I need it
to be. I don't see hundreds of help wanted ads asking for scheme
programmers. I do see hundreds of help-wanted C/C++ ads.

Too many programmers are chasing the perfect language that will enable
them to write what they want without errors. Maybe they just aren't good
programmers.

Michael

Buddha M Buck

unread,
Dec 6, 1996, 3:00:00 AM12/6/96
to

In article <MPLANET.32a8427...@news.tiac.net>,

Alberto C Moreira <amor...@nine.com> wrote:
>In article <587dlg$5...@bert.traverse.com>, oli...@co.traverse.com says...
>> Stuart I Reynolds (s...@cs.bham.ac.bham) wrote:
>> : No, no no!!
>> : Even the most hardend mathematicians agree that 1/3 is 0 if 1 and 3
>> : are in the INTEGER domain.

>> Ummmm... no.

>> I think the hardened mathematicians will agree that division isn't closed
>> over the integers, and that there is no integer value for the ratio 1/3.

>I tought the quotient of two positive integers a/b under integer
>division was the number q such that (1) 0 < q <= a, (2) 0 <= r < b, and
>(3) a = qb + r.

Yes, that is the quotient, but that's not what we were discussing (we
were talking about integer division, not quotients).

The standard definition of integer division I've seen is that q=a/b
iff qb == a and b != 0. For any given a,b, q is unique if it exists
at all. Division is the operation that expands integers into
rationals (much the same way that subtraction is the operation that
expands naturals into integers). Scheme, when using the full numeric
tower recommended by the Scheme standard, automatically converts the
result of (/ a b) into a rational if no q as defined above exists. It
uses a -different- terminology for your quotient.

Are you saying that integer division in C acts like the quotient rule
above? In that case, does C say that (-3)/2 is -2 or -1?

>At least that's what they taught me back in elementary school, and it's
>quite a useful definition.

True, and few languages exactly implement it, especially in the face
of negative integers.

I don't even know if Scheme requires:

(eq? a (+ (* b (quotient a b)) (remainder a b))) ==> #t

for all integers a,b with b != 0. I know C does -not- require

(a == b*(a/b) + a%b)

to be true for all signed integers a,b (b!=0).

Grant Edwards

unread,
Dec 6, 1996, 3:00:00 AM12/6/96
to

Robert McDermid (mcde...@hcl.com) wrote:

: BTW, 1/3 is an irrational, not a rational,

Wow. Things have changed a bit since I was in school. Anything that could
be expressed as a "ratio" of two integers was a "ratio"nal number.

: and there's no way to represent that precisely at all (using floating
: point) on a computer.

Maybe on _you're_ computer there isn't. I could design you one upon which
1/3 could be represented exactly in floating point. The cost/performance
would be worse that current architectures -- being able to exactly represent
1/3 in floating point isn't seen as a big performance gain. I can't
guarantee that this computer I design you will be able to exactly represent
_all_ rational numbers. In fact, the architecture I have in mind won't
represent 1/10 or 1/2 exactly.

: Thus, in the example you give, y will never equal x no matter what computer
: language you use.

Depends on the language and the underlying representation. One could design
a computer and a language that would do it. Why one would do such a thing
is another matter.

: (Do any of the symbolic manipulation packages like Maple have a way of
: handling this better?)

--
Grant Edwards | Microsoft isn't the | Yow! Do you have exactly
Rosemount Inc. | answer. Microsoft | what I want in a plaid
| is the question, and | poindexter bar bat??
gra...@rosemount.com | the answer is no. |

Faried Nawaz

unread,
Dec 6, 1996, 3:00:00 AM12/6/96
to

In article <589p1v$8...@qualcomm.com> Michael Simpson <simp...@cts.com> writes:


C/C++ accomplishes everything I need it to do as efficient as I need it
to be. I don't see hundreds of help wanted ads asking for scheme
programmers. I do see hundreds of help-wanted C/C++ ads.

You say that C/C++ does all you want it to do. So, for you, it is
a perfect language (or something reasonably close to that for all
your purposes). It also meets your needs efficiently -- it does the
work, it's good code, and it has no bugs (assuming working, efficient
code has no bugs). You say that you see a lot of help-wanted ads for
C/C++ programmers (compared to Scheme programmers), and so there's a
large demand for C/C++ programmers; presumably a lot of C/C++
programmers exist (or will exist) to meet that demand.

And then you say



Too many programmers are chasing the perfect language that will enable
them to write what they want without errors. Maybe they just aren't good
programmers.


I guess you've finally realized that you need to learn something
more than C/C++ to be a good programmer.


Isn't self-enlightenment such a beautiful, wonderous thing?

faried.
--
faried nawaz WAR IS PEACE FREEDOM IS SLAVERY BACKSPACE IS DELETE
box 3582, moscow, id 83843-1914, usa linux, the ms-dos of the nineties
AT&T YOU WILL!!!11 let all the poisons that lurk in the mud hatch out
not a system janitor would you die for me?

Daniel Wang

unread,
Dec 6, 1996, 3:00:00 AM12/6/96
to

>>>>> "David" == David Hanley <da...@netright.com> writes:

David> Thant Tessman wrote:
>> GoldenEye wrote:
>>
>> [...]
>>
>> > 2.Dynamic typing allows you to concentrate on real errors, rather >
>> than trying to placate the compiler god. It also makes code vastly >
>> more reusable.
>>
>> David Hanley wrote:
>>
>> > Hardly true. The only time I ever notice the static type > checker
>> is when I get a type mismatch. This would have been a > run-time
>> error in scheme that may have hit for a long time, and > been hard to
>> debug. [...]
>>
>> A good type system is better than no type system, but no type system
>> is better than a bad type system. C++ has a bad type system.

David> This is, of course, a matter of taste. I would qualify
David> scheme's runtime determination of all types as a really bad type
David> system. C++'s type system is actually not all *that* bad, though
David> it certianly could be better.

David> Nonetheless, the claim made in the original post was the
David> dynamic typing is inherently better than static typing, which I
David> personally feel is incorrect.

Hmm I always thought static "typing" was better than dynamic "typing" but never
had anything but my own personal experience to back this claim up. I was
groveling through some old books when I ran across this following tidbit.
[It's a shame that the research in this area has been neglected, I doubt that
there's been any recent replication of the experiment with modern languages.]

(Shneiderman, Ben,_Software_Psychology_, pg 89-99 c1980 Winthrop Publishers.)

\begin{quote}
Gannon (1977) studied the impact of statically-typed versus non-typed
languages on error statistics. In statically-typed languages (e.g. COBOL,
PL/I, FORTAN), declarations statements associate a data type with an
identifier to permit type checking and prevent mixed mode operations. In
non-typed languages (e.g. BCPL, BLISS or Assemblers), each identifier refers
to a group of bits and no restrictions on operations are
imposed. Thirty-eight graduate and advanced undergraduates subjects were
divided into two groups for this counterbalanced ordering experiment: 21
subjects worked with the statically-typed language first and then the
non-typed language while the remaining 17 did the tasks in the reverse
order. The sequence of 48 to 297 line listings and were collected and errors
counted (Table...).

[Abbreviated Table]

Typeless/Statically Typed Group (Order)

Typeless Typed
Total occurrences 125.80 31.40

Statically Typed Group/Typeless (Order)

Typeless Typed
Total occurrences 99.61 51.72

...

The results favoring the statically-typed language are statistically
significant by most measures. The order effect suggests that those who begin
with static typing carry their learned data abstractions to the non-typed
language.
\end{quote}

The Gannon reference is

Gannon, John D., "An experimental evaluation of data type conventions",
Communications of the ACM, 20, 8, (August 1977), 584-595.

I've got to go track it down myself and look at the details to figure out of
the conclusion it makes would probably hold with some of the more popular
langauges of today. (My experience suggests that this is the case..)

I suspect any advantage Scheme has over C/C++ is probably not related to
"dynamic types"..

Dennis Weldy

unread,
Dec 7, 1996, 3:00:00 AM12/7/96
to

pi is an irrational number, as theres no way to write it as a ratio of two
numbers, a close approximation is 22/7. the number e is also irrational.

1/3 is a rational number, as one can write it as a ratio of two numbers,
namely 1 and 3.
1 is a third of 3, 3 is three times 1. A nice ratio.

:-)

Dennis
James Lee <jl...@math.purdue.edu> wrote in article
<587j9j$2...@mozo.cc.purdue.edu>...

Dennis Weldy

unread,
Dec 7, 1996, 3:00:00 AM12/7/96
to

People already complain about the number of operators in c/c++.
Oh yeah, lets add another. :-)

Personally, I prefer C/C++ single operator approach. One operator to handle
both integer and floating point division. I know what's going on based on
they types of the variables I'm using.

But, if you want a second operator do the following:

#define div /

int func(int x, int y)
{
int v ;
if(y != 0)
{
v = x div y ;
}
}

There, y'have your operator. :-)

Dennis

Matthias Blume <bl...@dynamic.cs.princeton.edu> wrote in article
<izwwuvy...@dynamic.CS.Princeton.EDU>...


>
> I fail to see the usefulness of it. Why can't you have a different
> name for integer division, like so many other languages actually do to
> avoid this sort of confusion?
>

> -Matthias
>

Seth Tisue

unread,
Dec 7, 1996, 3:00:00 AM12/7/96
to

In article <32A733...@netright.com>,

David Hanley <da...@netright.com> wrote:
>> > Uck. I _hate_ that. The _last_ thing I want to do when trying to
>> >debug someone else's code is trying to decipher the new language
>> >features they've added. That possibility alone has probably caused
>> >scheme not to be used for some projects.
>>
>> Uck. I _hate_ that. The _last_ thing I want to do when trying to
>> debug someone else's code is trying to decipher the new procedures
>> they've added.
>
> Haha. Funny. Are you trying to claim that it's easier to decipher a
>procedure in a language that you know, rather than deciphering a new
>language? i _really_ doubt that.

It will be easier, if the addition of the new language features
results in a considerable enough overall simplification of the code.
Which is the only justification for adding new language features in
the first place.

--
== Seth Tisue <s-t...@nwu.edu> http://www.cs.nwu.edu/~tisue/

Seth Tisue

unread,
Dec 7, 1996, 3:00:00 AM12/7/96
to

In article <r8t3exj...@salomon.CS.Princeton.EDU>,

Daniel Wang <dan...@salomon.CS.Princeton.EDU> wrote:
>Hmm I always thought static "typing" was better than dynamic "typing" but never
>had anything but my own personal experience to back this claim up. I was
>groveling through some old books when I ran across this following tidbit.
>[It's a shame that the research in this area has been neglected, I doubt that
>there's been any recent replication of the experiment with modern languages.]

The study you cite compares static typing versus no typing, not static
typing versus dynamic typing.

For example, in assembler, adding two pointers produces a probably
nonsensical answer but does not signal an error.

In a dynamically typed language such as Lisp, trying to add two
non-numeric objects immediately signals an error.

A less confusing terminology might be "compile-time type-checking"
versus "run-time type-checking" versus "no type-checking".

David Hanley

unread,
Dec 7, 1996, 3:00:00 AM12/7/96
to

Seth Tisue wrote:
>
> >> Uck. I _hate_ that. The _last_ thing I want to do when trying to
> >> debug someone else's code is trying to decipher the new procedures
> >> they've added.
> >
> > Haha. Funny. Are you trying to claim that it's easier to decipher a
> >procedure in a language that you know, rather than deciphering a new
> >language? i _really_ doubt that.
>
> It will be easier, if the addition of the new language features
> results in a considerable enough overall simplification of the code.
> Which is the only justification for adding new language features in
> the first place.

I suppose that what I doubt is that, using a macro system, a programmer
could perform an application-specific language extension that would be
"better" ( making the code smaller and easier to debug ) than adding a
new procedure or two. In any case, I haven't seen many examples of
this.

Now, I suppose in certian instances, such as an object system, it's
possible.. But most languages come with that anyaways, and I wouldn't
exactly be thrilled about having to decipher code using someone's (
probably buggy ) homebrewed object system.

Having had to spend a lot of time debugging code written by others, I
have a vast appreciation for the stupid and contrived mistakes people
make. I can just imagine if I had to regularly had to debug code writen
for a subtly different language.


dave

Daniel Wang

unread,
Dec 7, 1996, 3:00:00 AM12/7/96
to

>>>>> "Seth" == Seth Tisue <ti...@cs.nwu.edu> writes:

Seth> In article <r8t3exj...@salomon.CS.Princeton.EDU>, Daniel Wang


Seth> <dan...@salomon.CS.Princeton.EDU> wrote:
>> Hmm I always thought static "typing" was better than dynamic "typing"
>> but never had anything but my own personal experience to back this
>> claim up. I was groveling through some old books when I ran across
>> this following tidbit. [It's a shame that the research in this area
>> has been neglected, I doubt that there's been any recent replication
>> of the experiment with modern languages.]

Seth> The study you cite compares static typing versus no typing, not
Seth> static typing versus dynamic typing.

Regardless of the dynamic/no-typing distinction the conclusion that
static-types (or at least variables declared with a specific type) helps
people reason and write correct programs is supported.

i.e. The average difference between the number of errors between the typeless
and static-type groups may not be relevant, but the fact that people did
better in the typeless condition if they did the static types first than if
they did the typless condition second is an important result. It shows that
if you do static types first you learn how to do the typeless problems
better. However if you do the typless problems first it doesn't help you
solve the static types problems.

Writing with types helps you think about how to write correct programs
regardless of whether the progamming language supports types or not.

Daniel Wang

unread,
Dec 7, 1996, 3:00:00 AM12/7/96
to

>>>>> "Daniel" == Daniel Wang <dan...@hart.CS.Princeton.EDU> writes:
{following up myself}
Daniel> Writing with types helps you think about how to write correct
Daniel> programs regardless of whether the progamming language supports
Daniel> types or not.


Well, I headed off to the library and dug up the CACM article to read myself
some specific details that might be of interest are that the languages used
were created specifically for the test, and the difference I talk about
above is seen mostly in "noivce" programmers. The article is a pretty
interesting read... (One of these days, I've got to go sit in the library
and start browsing all the old CACM's it's way more educational than surfing
the web :).. Anyways there's also an article about Mesa that talks about
some anecdotal comments about types and the Mesa system.


scha...@wat.hookup.net

unread,
Dec 7, 1996, 3:00:00 AM12/7/96
to

checking out problem with newsserver


David Hopwood

unread,
Dec 7, 1996, 3:00:00 AM12/7/96
to

In message <32A6B7...@cs.bham.ac.bham>

Stuart I Reynolds <s...@cs.bham.ac.bham> writes:

> David Hanley wrote:
> >
> > Rob Warnock wrote:

> > > The language defect is C++'s (and C's before it). As we were all taught
> > > in grade school, 1 divided by 3 is 1/3 (one third).

> No, no no!!


> Even the most hardend mathematicians agree that 1/3 is 0 if 1 and 3 are
> in the INTEGER domain.

No they don't. In mathematics / is defined as the inverse of *, so
1/3 can only equal 0 if 1 = 0*3 (in any particular field).

They do, however, agree that 1 div 3 = 0. C's mistake is in misnaming this
operation as '/', rather than 'div' or 'quotient'.

David Hopwood
david....@lmh.ox.ac.uk, hop...@zetnet.co.uk

Fergus Henderson

unread,
Dec 8, 1996, 3:00:00 AM12/8/96
to

a...@laphroig.mch.sni.de writes:

>You just can't divide the integer 1 by the
>integer 3 and get an integer result. It certainly is not zero.

Yes, that's because division on integers is a partial function.
And the only language that _I_ know of in which you can directly
implement partial functions such as this one is Mercury.
For example:

:- func '/'(int, int) = int.
:- mode '/'(in, in) = out is semidet. % "semidet" means it is
% a partial function
A / B = Result :-
% check divisor not equal to zero
B \= 0,
% check divisibility
A mod B = 0,
% compute result ("//" is truncating integer division)
Result = A // B.

:- func div3(int) = int.
:- mode div3(in) = out is semidet.
div3(X) = X / 3.

:- func foo(int) = int.
foo(X) = if div3(X) > 10 then 42 else X + 1.
% ... then foo(31) = 32, not 42

For more info on Mercury, see <http://www.cs.mu.oz.au/mercury>.

(Please CC me a copy of any followups, I don't usually read these groups.)

--
Fergus Henderson <f...@cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger f...@128.250.37.3 | -- the last words of T. S. Garp.

scha...@wat.hookup.net

unread,
Dec 8, 1996, 3:00:00 AM12/8/96
to

In <58c493$f...@Godzilla.cs.nwu.edu>, ti...@cs.nwu.edu (Seth Tisue) writes:
> ...
>The study you cite compares static typing versus no typing, not static
>typing versus dynamic typing.
>

>For example, in assembler, adding two pointers produces a probably
>nonsensical answer but does not signal an error.
>
>In a dynamically typed language such as Lisp, trying to add two
>non-numeric objects immediately signals an error.
>
>A less confusing terminology might be "compile-time type-checking"
>versus "run-time type-checking" versus "no type-checking".

Some Lisp compilers put lots of effort into compile time type checking, so
your terminology would create yet another type of confusion. How about
variable bound typing versus valu bound typing?

Hartmann Schaffer


Seth Tisue

unread,
Dec 8, 1996, 3:00:00 AM12/8/96
to

In article <32A9BA...@netright.com>,

David Hanley <da...@netright.com> wrote:
> I suppose that what I doubt is that, using a macro system, a programmer
>could perform an application-specific language extension that would be
>"better" ( making the code smaller and easier to debug ) than adding a
>new procedure or two. In any case, I haven't seen many examples of
>this.

You might be interested in looking through Paul Graham's book "On
Lisp", which is an extended series of such examples.

Seth Tisue

unread,
Dec 8, 1996, 3:00:00 AM12/8/96
to

In article <58c493$f...@Godzilla.cs.nwu.edu>,

Seth Tisue <ti...@cs.nwu.edu> wrote:
>A less confusing terminology might be "compile-time type-checking"
>versus "run-time type-checking" versus "no type-checking".

OK, enough people have now pointed out that this was a pretty bad
suggestion. Remind me not to tack on last minute additions to my
posts...

Matt Kennel

unread,
Dec 9, 1996, 3:00:00 AM12/9/96
to

Seth Tisue (ti...@cs.nwu.edu) wrote:
: In article <r8t3exj...@salomon.CS.Princeton.EDU>,

: Daniel Wang <dan...@salomon.CS.Princeton.EDU> wrote:
: >Hmm I always thought static "typing" was better than dynamic "typing" but never
: >had anything but my own personal experience to back this claim up. I was
: >groveling through some old books when I ran across this following tidbit.
: >[It's a shame that the research in this area has been neglected, I doubt that
: >there's been any recent replication of the experiment with modern languages.]

: The study you cite compares static typing versus no typing, not static
: typing versus dynamic typing.

: For example, in assembler, adding two pointers produces a probably
: nonsensical answer but does not signal an error.

: In a dynamically typed language such as Lisp, trying to add two
: non-numeric objects immediately signals an error.

: A less confusing terminology might be "compile-time type-checking"


: versus "run-time type-checking" versus "no type-checking".

Not quite. Idiomatic programs in a 'statically typed' language
possess more assertions about the intended operation of the program.

The 'static typing' is really 'static type constraints and assertions'.

Some may be checked at compile time, some at run time, but there
are simply more there to check.

"static typing" also needn't imply explicit, manifest typing: the programmer
doesn't always have to explicitly provide names for the type constraints.

: --

--
Matthew B. Kennel/m...@caffeine.engr.utk.edu/I do not speak for ORNL, DOE or UT
Oak Ridge National Laboratory/University of Tennessee, Knoxville, TN USA/
I would not, could not SAVE ON PHONE, |==================================
I would not, could not BUY YOUR LOAN, |The US Government does not like
I would not, could not MAKE MONEY FAST, |spam either. It is ILLEGAL!
I would not, could not SEND NO CA$H, |USC Title 47, section 227
I would not, could not SEE YOUR SITE, |p (b)(1)(C) www.law.cornell.edu/
I would not, could not EAT VEG-I-MITE, | /uscode/47/227.html
I do *not* *like* GREEN CARDS AND SPAM! |==================================
M A D - I - A M!


Stuart I Reynolds

unread,
Dec 9, 1996, 3:00:00 AM12/9/96
to

David Hanley wrote:
>
> Rob Warnock wrote:
> > The language defect is C++'s (and C's before it). As we were all taught
> > in grade school, 1 divided by 3 is 1/3 (one third).


No, no no!!
Even the most hardend mathematicians agree that 1/3 is 0 if 1 and 3 are

in the INTEGER domain. To evaluate the division of one integer with
another integer will result in an integer, whether using programming
lanuages, alogrithms on paper or whatever. Integers have well defined
properties as does integer division - this is not in any way a fault of
C++.

Besides, what C++ does do is let you create your own types, which in
turn could represent numbers as numerators and denominators, and
redefine the meaning of operators which act upon them. C++ is pretty
poineering (and still unique, I believe) in this respect. What you have
described in Scheme takes that flexibilty away from you - can it do
integer division?

If you don't want to do integer division, don't use integers. This is
why C++ is a strongly typed language - unlike BBC BASIC say which also
dynamically altered the types of variables.

Are you saying BASIC is better than C++.

Stu

Seth Tisue

unread,
Dec 9, 1996, 3:00:00 AM12/9/96
to

Hey everybody, let's post 100 *more* messages about what 1 divided by
3 is!!

ko besuijen

unread,
Dec 9, 1996, 3:00:00 AM12/9/96
to

Chris Bitmead wrote:
>
> David Hanley <da...@netright.com> writes:
>
> > > > Bad in 2 ways. With integers, this is not the result you
> > > > want. Frequently you want integers to behave like integers.
> > >
> > > No. You mean that sometimes you don't want division to behave like
> > > division:
> >
> > No, the integer division of 1/3 is 0. Period. Claiming this correct
> > result as a language defect is foolish.
>
> But who said that 1/3 is integer division? Take someone off the street
> and say that if he gives you 1/3 of a dollar you'll give him 0 dollars
> which is the same.

If he would cut his dollar in two parts that is exactly what would
happen.


>
> Perhaps I'm naive, but I reckon 1/3 equals 1/3.

Matthias Blume

unread,
Dec 9, 1996, 3:00:00 AM12/9/96
to

In article <m3g21fv...@thepla.net> Chris Bitmead <Chr...@thepla.net> writes:

David Hanley <da...@netright.com> writes:

> Hardly true. The only time I ever notice the static type checker is
> when I get a type mismatch. This would have been a run-time error in
> scheme that may have hit for a long time, and been hard to debug.

> Dynamic type checking is a hack to allow for faster interpretation which
> gives awayt a lot.

Obviously you havn't spent a great deal of time writing scheme
code. Consider the scheme function "map". Consider how powerful it
is. Also consider that you can't do anything this powerful in
C++. Consider how many reusable abstractions you can write if you
abandon static type checking.

Obviously you havn't spent a great deal of time writing SML
code. Consider the scheme function "map". Consider how powerful it
is. Also consider that you can't do anything this powerful in
C++. Consider how many reusable abstractions you can write even if you
don't abandon static type checking.

Don't get me wrong, I can see the advantages of static checking. I've
used Sather and Eiffel and they have a lot of good points. But I can
do more in less space with scheme, and reuse more too.

Don't get me wrong, I can see some advantages of dynamic
checking. I've used Scheme (have even written a compiler for it) and
it has a lot of good points. But I can do more in less space with
SML, and reuse at least as much too.

[Of course, this is a bit off topic. Maybe I should add comp.lang.ml
to the list of newsgroups -- just to make sure this flamefest keeps
going.]

Regards,
--
-Matthias

Matthias Blume

unread,
Dec 9, 1996, 3:00:00 AM12/9/96
to

In article <m3g21fv...@thepla.net> Chris Bitmead <Chr...@thepla.net> writes:

David Hanley <da...@netright.com> writes:

> Hardly true. The only time I ever notice the static type checker is
> when I get a type mismatch. This would have been a run-time error in
> scheme that may have hit for a long time, and been hard to debug.
> Dynamic type checking is a hack to allow for faster interpretation which
> gives awayt a lot.

Obviously you havn't spent a great deal of time writing scheme
code. Consider the scheme function "map". Consider how powerful it
is. Also consider that you can't do anything this powerful in
C++. Consider how many reusable abstractions you can write if you
abandon static type checking.

Obviously you havn't spent a great deal of time writing SML

code. Consider the SML function "map". Consider how powerful it


is. Also consider that you can't do anything this powerful in
C++. Consider how many reusable abstractions you can write even if you
don't abandon static type checking.

Don't get me wrong, I can see the advantages of static checking. I've
used Sather and Eiffel and they have a lot of good points. But I can
do more in less space with scheme, and reuse more too.

Don't get me wrong, I can see some advantages of dynamic

checking. I've used Scheme (and have even written a compiler for it)


and it has a lot of good points. But I can do more in less space with
SML, and reuse at least as much too.

[Of course, this is a bit off topic. Maybe I should add comp.lang.ml
to the list of newsgroups -- just to make sure this flamefest keeps

going. (Not that there is any danger for it to die soon even now.)]

Regards,
--
-Matthias

Bruce Stephens

unread,
Dec 9, 1996, 3:00:00 AM12/9/96
to

>>>>> "Stuart" == Stuart I Reynolds <s...@cs.bham.ac.bham> writes:

> Even the most hardend mathematicians agree that 1/3 is 0 if 1 and 3
> are in the INTEGER domain.

What does 1 in the rational domain look like? How do I write it?
Should sqrt(3) evaluate to 1?
--
Bruce Stephens | email: B.Ste...@math.ruu.nl
Utrecht University | telephone: +31 30 2534630
Department of Mathematics | telefax: +31 30 2518394
P.O. Box 80010, 3508 TA Utrecht, The Netherlands

David Hanley

unread,
Dec 9, 1996, 3:00:00 AM12/9/96
to

Chris Bitmead wrote:
>
> David Hanley <da...@netright.com> writes:
>
> > > 2.Dynamic typing allows you to concentrate on real errors, rather than
> > > trying to placate the compiler god. It
> > > also makes code vastly more reusable.
> >
> > Hardly true. The only time I ever notice the static type checker is
> > when I get a type mismatch. This would have been a run-time error in
> > scheme that may have hit for a long time, and been hard to debug.
> > Dynamic type checking is a hack to allow for faster interpretation which
> > gives awayt a lot.
>
> Obviously you havn't spent a great deal of time writing scheme
> code. Consider the scheme function "map". Consider how powerful it
> is.

SML also has a 'map' function which works perfectly well, and SML has a
more encompasing type system than C++.

> Consider how many reusable abstractions you can write if you
> abandon static type checking.

I don't necessarily agree with that. Could I see some examples of
abstractions that are possible only in a dynamically typed language?

dave

David Hanley

unread,
Dec 9, 1996, 3:00:00 AM12/9/96
to

Chris Bitmead wrote:
>
> David Hanley <da...@netright.com> writes:
>
> > > > Bad in 2 ways. With integers, this is not the result you
> > > > want. Frequently you want integers to behave like integers.
> > >
> > > No. You mean that sometimes you don't want division to behave like
> > > division:
> >
> > No, the integer division of 1/3 is 0. Period. Claiming this correct
> > result as a language defect is foolish.
>
> But who said that 1/3 is integer division? Take someone off the street
> and say that if he gives you 1/3 of a dollar you'll give him 0 dollars
> which is the same.

Not the same thing at all, but thank you, you've made my point
beautifully.

A dollar is 100 cents. If you get back 1/3 of a dollar, you're going
to get 33 cents, every time. No one will even think about this. Maybe
a nice person will give you 34 cents, if the money's not going into
their pocket.

What do you think you're going to get when the store has a penny, and
you're owed 1/3rd of it? Probably zero, right?

It seems that th only people unable to comprehend integer mathemaics
here are the scheme advocates. :) ( it's a JOKE! )

>
> Perhaps I'm naive, but I reckon 1/3 equals 1/3.

Did you ever get fired as a cashier?

dave

Patric Jonsson

unread,
Dec 9, 1996, 3:00:00 AM12/9/96
to

David Hanley wrote:
> I suppose that what I doubt is that, using a macro system, a programmer
> could perform an application-specific language extension that would be
> "better" ( making the code smaller and easier to debug ) than adding a
> new procedure or two. In any case, I haven't seen many examples of
> this.
>
Try
http://www.stat.ucla.edu/develop/lisp/common/docs/Evolution-of-Lisp.ps.gz
Exercise 2
Page 59

David Doolin

unread,
Dec 9, 1996, 3:00:00 AM12/9/96
to

In article <m3d8wjv...@thepla.net>, Chris Bitmead <Chr...@thepla.net> writes:
|> David Hanley <da...@netright.com> writes:
|>
|> > > > Bad in 2 ways. With integers, this is not the result you
|> > > > want. Frequently you want integers to behave like integers.
|> > >
|> > > No. You mean that sometimes you don't want division to behave like
|> > > division:
|> >
|> > No, the integer division of 1/3 is 0. Period. Claiming this correct
|> > result as a language defect is foolish.
|>
|> But who said that 1/3 is integer division? Take someone off the street
|> and say that if he gives you 1/3 of a dollar you'll give him 0 dollars
|> which is the same.
|>
|> Perhaps I'm naive, but I reckon 1/3 equals 1/3.
|>

Well, you said it. Check any text on elementary number theory
or abstract algebra. The integer division of 1/3 is 0. Period.
^^^^^^^^^^^^^^^^

--
David M. Doolin Institute for Geotechnology
doo...@cs.utk.edu Department of Civil Eng. UTK


__________________________________________________

You may add me to your junk email list for $1000.00,
payable in US currency. Otherwise, don't call me,
I'll call you. Sending me junk email from a list
obligates you to this contract.
_________________________________________________

Alberto C Moreira

unread,
Dec 9, 1996, 3:00:00 AM12/9/96
to

In article <589unn$1...@prometheus.acsu.buffalo.edu>,
bmb...@acsu.buffalo.edu says...

> The standard definition of integer division I've seen is that q=a/b
> iff qb == a and b != 0. For any given a,b, q is unique if it exists
> at all. Division is the operation that expands integers into
> rationals (much the same way that subtraction is the operation that
> expands naturals into integers).

Sorry, I haven't bumped into this definition of integer division yet.
I thought the result of "integer division" of two integers a and b
was the quotient of a divided by b.

> Scheme, when using the full numeric
> tower recommended by the Scheme standard, automatically converts the
> result of (/ a b) into a rational if no q as defined above exists. It
> uses a -different- terminology for your quotient.

In other words, it uses a different operation for the "/" operator.
Maybe the real issue is, we're comparing apples and oranges.

> Are you saying that integer division in C acts like the quotient rule
> above? In that case, does C say that (-3)/2 is -2 or -1?

My compiler (MSVC++ 4.2) says (-3)/2 = -1, remainder -1.

> True, and few languages exactly implement it, especially in the face
> of negative integers.

I'm not too sure about the C standard, but there's been extensive
debate on the relative benefits of rounding towards zero vs.
rounding towards minus infinity. I believe the C standard says
"round towards zero", but I'm not sure. Anyone knows the answer ?

> I don't even know if Scheme requires:
>
> (eq? a (+ (* b (quotient a b)) (remainder a b))) ==> #t
>
> for all integers a,b with b != 0. I know C does -not- require
>
> (a == b*(a/b) + a%b)
>
> to be true for all signed integers a,b (b!=0).

From "C, A Reference Manual", by Harbison and Steele, p. 187:

" It is always true that (a/b)*b + a%b is equal to a if b is not zero,
so the behavior of the remainder operation is coupled to that of
integer division". I don't know however if the standard says that.


Alberto.

scha...@wat.hookup.net

unread,
Dec 9, 1996, 3:00:00 AM12/9/96
to

In <584nbh$1...@news.hcl.com>, mcde...@hcl.com (Robert McDermid) writes:
> ...
>:-) I think you should re-read what you just wrote, as it's
>rather funny. If you include rationals as a possible result,
>then you're not doing integer division, since a rational number
>is, by definition, not an integer - it's a rational. Integer

Have you ever heard of functions (operators) where the result is not the
same type as the arguments? Operations on integers producing rational
results seem perfectly legitimate to me.

>division of 1 by 3 produces a result of 0 - there's no other
>way to present the result in the integer number system. If you

This is only a partial result: the true result is the pair (quotient= 0,
remainder= 1). Too bad that you seem to think in a language that permits
only single function values.

>want to handle rational results on a computer, you must use
>floating point (and start worrying about round-off error, truncation
>error, etc., etc., etc.) Whole courses are taught in

Ignorance must be bliss! You can encode a rational number as a pair of
integers.

>Computer Science which deal with nothing but this single area
>of computation - it is by no means a simple topic.

Have you taken any of them?

>BTW, 1/3 is an irrational, not a rational, and there's no way to

Is this New Math? When I went to school it was rational, and according to
the definition I learned then it still is.

>represent that precisely at all (using floating point) on a computer.

Who else is talking about floating point?

>Thus, in the example you give, y will never equal x no matter
>what computer language you use. (Do any of the symbolic manipulation
>packages like Maple have a way of handling this better?)
>
>-- Rob
>==============================================================
>Rob McDermid Hummingbird Communications Ltd.
>mcde...@hcl.com All opinions expressed are my own.
>==============================================================
>

Hartmann Schaffer


Mukesh Prasad

unread,
Dec 9, 1996, 3:00:00 AM12/9/96
to

Fergus Henderson wrote:
>
> a...@laphroig.mch.sni.de writes:
>
> >You just can't divide the integer 1 by the
> >integer 3 and get an integer result. It certainly is not zero.
>
> Yes, that's because division on integers is a partial function.
> And the only language that _I_ know of in which you can directly
> implement partial functions such as this one is Mercury.
> For example:

There is the "multiple returns" approach, as in CLU

int result, remainder := div( 5, 3 )

will leave "result" set to 1 and "remainder" to 2.

David Hanley

unread,
Dec 9, 1996, 3:00:00 AM12/9/96
to

Sorry, I couldn't download this. In any case, A few people have
misunderstood me on this point. I've seen examples of it, I just
haven't seen any that I think would be smaller, faster, and easier to
debug than just using a few new procedures. The last criteria is pretty
subjective, I think anyone would agree.

The point is that that "great feature" of scheme is a "great feature"
only in a few person's opinions; others might not like it at all. For
example, in C++ you can cast pointers to integers and add them. It's a
feature C++ has that scheme doesn't ( I think it's bad too ). Does that
fact that C++ has this feature make it better than scheme, for that
reason?

---------------------------------------------------------------------
David Hanley, Software Developer, NetRight technologies.
My employer pays me for my opinions; nonetheless he does not share all
of them
E-mail address munged to defeat automailers, Delete _nospam

Dennis Weldy

unread,
Dec 9, 1996, 3:00:00 AM12/9/96
to

Please take a look at Ada. Its has this feature also. I can define an ada
package where I can define what it means to "add" two items of my type, or
my type and another type.

Possibly Smalltalk allows this as well.

Stuart I Reynolds <s...@cs.bham.ac.bham> wrote in article
<32ABEA...@cs.bham.ac.bham>...

Chris Bitmead

unread,
Dec 10, 1996, 3:00:00 AM12/10/96
to

David Hanley <da...@netright.com> writes:

> > 2.Dynamic typing allows you to concentrate on real errors, rather than
> > trying to placate the compiler god. It
> > also makes code vastly more reusable.
>
> Hardly true. The only time I ever notice the static type checker is
> when I get a type mismatch. This would have been a run-time error in
> scheme that may have hit for a long time, and been hard to debug.
> Dynamic type checking is a hack to allow for faster interpretation which
> gives awayt a lot.

Obviously you havn't spent a great deal of time writing scheme
code. Consider the scheme function "map". Consider how powerful it

is. Also consider that you can't do anything this powerful in

C++. Consider how many reusable abstractions you can write if you
abandon static type checking.

Don't get me wrong, I can see the advantages of static checking. I've

Chris Bitmead

unread,
Dec 10, 1996, 3:00:00 AM12/10/96
to

Dr. C.F. Chong

unread,
Dec 10, 1996, 3:00:00 AM12/10/96
to

User defined operators are first introduced in Algol68. You are allowed to
specify the precedence level of the operator and overloading is allowed.

Dennis Weldy (dmw...@ingr.com) wrote:
: Please take a look at Ada. Its has this feature also. I can define an ada

: >


Buddha M Buck

unread,
Dec 10, 1996, 3:00:00 AM12/10/96
to

In article <58hgcp...@cs.utk.edu>,

David Doolin <doo...@menkar.cs.utk.edu> wrote:
>
>Well, you said it. Check any text on elementary number theory
>or abstract algebra. The integer division of 1/3 is 0. Period.
> ^^^^^^^^^^^^^^^^

Very strange... The abstract algebra text I used doesn't define a
division operator on integers -- because it isn't a closed operation
on integers.

It did define +, -, and *, on integers, and / on rationals. I'm
perfectly willing to accept ( ((int)1) / ((int)3) ) to be silently
converted into ( ((rat)(1/1) / ((rat)(3/1)) ) = (rat)(1/3), if it
makes sense to do so.


Vadim Berman

unread,
Dec 10, 1996, 3:00:00 AM12/10/96
to

Take someone off the street and ask him:

"The price of a cinema ticket is $3. I have $1. How many tickets can I buy?"

Perhaps I'm naive, but I think the answer is 0.
Now:

"The price of a cinema ticket is $3. You have $0. How many tickets can you buy?"

0 again. Doesn't it mean that 1/3==0/3==0?

And, speaking about "1/3 of a dollar", how will you give someone 1/3 dollar?
Does it mean that you have 33.333333... cents coin? Or does it mean that 1/3=0.33 (more
exactly, 100/3=33)?

And again about opinion of "someone off the street". Take someone off the street and
ask him what does "a=a+1" mean, assuming he is not a programmer :)

Steve Bryan

unread,
Dec 10, 1996, 3:00:00 AM12/10/96
to

In article <32ABEA...@cs.bham.ac.bham>, Stuart I Reynolds
<s...@cs.bham.ac.bham> wrote:

> David Hanley wrote:
> >
> > Rob Warnock wrote:
> > > The language defect is C++'s (and C's before it). As we were all taught
> > > in grade school, 1 divided by 3 is 1/3 (one third).
>
>
> No, no no!!

> Even the most hardend mathematicians agree that 1/3 is 0 if 1 and 3 are

> in the INTEGER domain. To evaluate the division of one integer with
> another integer will result in an integer, whether using programming
> lanuages, alogrithms on paper or whatever. Integers have well defined
> properties as does integer division - this is not in any way a fault of
> C++.

You haven't had any coffee yet today, have you? What integer when
multiplied by 3 produces the result 1? There is no integer that satisfies
that condition. This illustrates the fact that the integers form a ring,
not a field. On the other hand you could talk about quotient and remainder,
Euclid's method, etc. Nothing prevents one from performing rational
arithmetic with C or C++ but it is not usually built into an implementation
(unlike Lisp, for example).

James Lee

unread,
Dec 10, 1996, 3:00:00 AM12/10/96
to

b...@digideas.com.au wrote in <32ACEA...@digideas.com.au>:

] Take someone off the street and ask him:

]
] "The price of a cinema ticket is $3. I have $1. How many
] tickets can I buy?"
]
] Perhaps I'm naive, but I think the answer is 0.
] Now:
]
] "The price of a cinema ticket is $3. You have $0. How many
] tickets can you buy?"
]
] 0 again. Doesn't it mean that 1/3==0/3==0?

Take someone off the street and ask him:

"The price of a cinema ticket is $3. The concert is sold out.


How many tickets can I buy?"

Doesn't it mean that 3/0 == 0?

There's no use trying to find which answer is "better" or "more natural"
intuitively. This thread is, in essence, useless. Division isn't a
closed operation over the set of integers, therefore if you're looking
to return only one result, you have to return a "new" type of object
(i.e. rational or representation that allows for quotient and remainder).
or return a "limited" answer of the same type (just the quotient or
remainder). There is no "right" or "wrong" as long as the person using
the division operation in question understands how it works.

--
James Lee <jl...@math.purdue.edu>
Fingerprint = 2F 00 21 17 A5 16 04 7 8D EC 4E C7 9D 90 22 5F
PGP mail encouraged Key ID: 1024/39A4CC25 Finger for public key

Dennis Weldy

unread,
Dec 10, 1996, 3:00:00 AM12/10/96
to

So much for it being unique to C++ then. :-)

There any algol68 compilers around still?
Yes, Im exposing my weak knowledge in this area :-)

Dennis

Dr. C.F. Chong <ch...@csd.hku.hk> wrote in article
<58if0c$7...@ns.cs.hku.hk>...

Carl Laurence Gonsalves

unread,
Dec 11, 1996, 3:00:00 AM12/11/96
to

Chris Bitmead <Chr...@thepla.net> wrote in article
<m3g21fv...@thepla.net>...

> David Hanley <da...@netright.com> writes:
>
> > > 2.Dynamic typing allows you to concentrate on real errors, rather
than
> > > trying to placate the compiler god. It
> > > also makes code vastly more reusable.
> >
> > Hardly true. The only time I ever notice the static type checker is
> > when I get a type mismatch. This would have been a run-time error in
> > scheme that may have hit for a long time, and been hard to debug.
> > Dynamic type checking is a hack to allow for faster interpretation
which
> > gives awayt a lot.
>
> Obviously you havn't spent a great deal of time writing scheme
> code. Consider the scheme function "map". Consider how powerful it
> is. Also consider that you can't do anything this powerful in
> C++. Consider how many reusable abstractions you can write if you
> abandon static type checking.

map is a very powerful function (and probably my favorite "feature" of
Scheme), but I don't think static type checking and something very much
like map are mutually exclusive. It probably isn't possible with C++
(unless it's changed a *lot* recently...), but I could imagine a language
that would allow such a thing. A very watered down version of map in C++
might look like this:

template<class T1, class T2> list<T1> map( list<T1>, T2 (*f)(T1) );

(I've only shown the prototype here because it's been a long time since I
did anything with templates in C++, and I can't recall how lists work)
Scheme's map can of course map from multiple lists into one. This C++ map
is less powerful in that it's restricted to mapping from a single list.
This is a fault of C++, not static typing though. It wouldn't be too hard
to conceive of a language with static type checking that would allow
something as powerful as Scheme's map. It would require significantly
better "varargs" support than C++ has.

> Don't get me wrong, I can see the advantages of static checking. I've
> used Sather and Eiffel and they have a lot of good points. But I can
> do more in less space with scheme, and reuse more too.

I like Scheme as well, but I find that often (not always) I can squeeze
more reusability out of Java than Scheme. Java also lets one decide where
dynamic typing is appropriate, and where it is not (well, that's an over
simplification, but this is Usenet...).

Java *still* doesn't have generics, nor does it have any support for
"varargs", so doing something like the above in Java would not have to rely
on dynamic type checking. (because the "list<T>"'s would probably become
Vector's, which can hold any subclass of Object, which means no real static
type checking)

In Scheme, I find one of the most annoying things is the fact that I can
usually take some really kooky piece of data, and pass it to virtually any
function I write, and rather than the compiler telling me "no, don't do
that", I end up with strange run-time errors.

And there is also that point about efficiency. If you can check at compile
time it makes sense to do it once there, rather than every single time you
execute a particular piece of code.

--
Carl Laurence Gonsalves | "Any sufficiently advanced
clgo...@kami.com | technology is
indistinguishable
| from magic."
http://www.csclub.uwaterloo.ca/~clgonsal/ | -Arthur C.
Clarke


Sean Case

unread,
Dec 11, 1996, 3:00:00 AM12/11/96
to

In article <32A6B7...@cs.bham.ac.bham>,

Stuart I Reynolds <s...@cs.bham.ac.bham> wrote:

>Even the most hardend mathematicians agree that 1/3 is 0 if 1 and 3 are
>in the INTEGER domain.

But no sane mathematician would use a slash for integer division. Ever.

Integer division (to be pedantic, Euclidean division) is a useful
operation, but its usual notation is a division sign, not a slash.

The reason that Scheme (like Pascal) uses a different notation for
integer division (as opposed to rational or floating point division)
is that unlike integer addition, subtraction, multiplication, and for
that matter exponentiation, it doesn't commute with the natural
embedding of the integers into the rationals or the reals.

The original mistake was made in Fortran, and C (which owes more of its
syntax and semantics to Fortran than its designers care to admit) has
perpetuated it.

Sean Case


---------------------------------------------
Sean Case gsc...@tpgi.com.au

Code is an illusion. Only assertions are real.

Sean Case

unread,
Dec 11, 1996, 3:00:00 AM12/11/96
to

In article <32A6B7...@cs.bham.ac.bham>,
Stuart I Reynolds <s...@cs.bham.ac.bham> wrote:

>Besides, what C++ does do is let you create your own types, which in
>turn could represent numbers as numerators and denominators, and
>redefine the meaning of operators which act upon them. C++ is pretty
>poineering (and still unique, I believe) in this respect.

Actually, this facility goes at least as far back as Algol-68 and Clu,
and appears to have arrived in C++ by way of Ada.

Thant Tessman

unread,
Dec 11, 1996, 3:00:00 AM12/11/96
to

Stuart I Reynolds wrote:

> Besides, what C++ does do is let you create your own types,
> which in turn could represent numbers as numerators and
> denominators, and redefine the meaning of operators which
> act upon them. C++ is pretty poineering (and still unique,

> I believe) in this respect. [...]

C++ is neither pioneering, nor unique in this respect.
However, I will admit that the ability to add your own
types and operators is indeed cool in some situations,
which is why some people add this capability to Scheme
using macros. (See Meroon, for example.)

Face it: C++ sucks shit through a straw.

-thant

[...followups trimmed...]

--
Thant Tessman <th...@acm.org>

scha...@wat.hookup.net

unread,
Dec 11, 1996, 3:00:00 AM12/11/96
to

In <AED4B321...@rd-ppp-089.tpgi.com.au>, gsc...@tpgi.com.au (Sean Case) writes:
> ...

>Actually, this facility goes at least as far back as Algol-68 and Clu,
>and appears to have arrived in C++ by way of Ada.

The first language I saw where you could do it was Simula, and I strongly
suspect that it got into C++ straight from there

Hartmann Schaffer

Zuwei Thomas Feng

unread,
Dec 11, 1996, 3:00:00 AM12/11/96
to

In article <32a5e60...@uchinews.uchicago.edu> cab...@midway.uchicago.edu (Charles Bacon) writes:
>
>Blatant snips of authorship:
>> +---------------

>> | No, the integer division of 1/3 is 0. Period. Claiming this correct
>> | result as a language defect is foolish.
>> +---------------

>>
>> The language defect is C++'s (and C's before it). As we were all taught
>> in grade school, 1 divided by 3 is 1/3 (one third). And that's what you
>> get in Scheme... which includes has rational numbers.
>>
>>Actually, 1/3 is 2. No, I am not kidding, I am just doing arithmetic
>>in Z_5 -- the (finite) field you get by taking the integers mod 5.
>
> I think this has been the most correct post so far (but then
>again, I study math). I personally think that the integer division of
>1/3 should be an error, since 1/3 doesn't exist. This probably isn't
>the most useful interpretation for computer programming, but then
>again, we've strayed from talking about that.

Well it's still not 100% correct :) "Z_5" refers to the 5-adic integer ring
(in which 3 happens to have an inverse too), not the 5-element finite field.
The latter should be "Z/5" or "Z/5Z".

(Assuming, of course, that the "_" means subscript a la TeX).

> I'd also like to add that, quibbles aside, I thought the 10
>reasons were pretty funny. That seems to have been lost in the
>shuffle.

Me too.

--
Zuwei Thomas Feng ztf...@math.princeton.edu `,`,`,` ,-._;^7 `,`,`,
http://www.math.princeton.edu/~ztfeng `,`,`, < `\ ,`,`,
-=- Check out the Internet MahJong Servers: -=- `,`,`, `-^>__/, ,`,`,
http://www.math.princeton.edu/~ztfeng/mj_servers.html `,`,`,` CHINA ' `,`,`,

Dennis Weldy

unread,
Dec 11, 1996, 3:00:00 AM12/11/96
to

Which makes sense, given that (if I recall) Bjarne Stroustrup worked with
Simula prior to beginning work in C++. I think it's mentioned in the D&E of
C++.


scha...@wat.hookup.net wrote in article
<58msbl$kc7$2...@nic.wat.hookup.net>...

Bjarne Stroustrup

unread,
Dec 12, 1996, 3:00:00 AM12/12/96
to

gsc...@tpgi.com.au (Sean Case) writes:

> In article <32A6B7...@cs.bham.ac.bham>,


> Stuart I Reynolds <s...@cs.bham.ac.bham> wrote:
>
> >Besides, what C++ does do is let you create your own types, which in
> >turn could represent numbers as numerators and denominators, and
> >redefine the meaning of operators which act upon them. C++ is pretty
> >poineering (and still unique, I believe) in this respect.
>

> Actually, this facility goes at least as far back as Algol-68 and Clu,
> and appears to have arrived in C++ by way of Ada.

C++ got its classes from Simula and its operator overloading from Algol68.
See "The Design and Evolution of C++" for details.

- Bjarne

Bjarne Stroustrup, AT&T Research, http://www.research.att.com/~bs/homepage.html

Ray S. Dillinger

unread,
Dec 13, 1996, 3:00:00 AM12/13/96
to

Steve Bryan wrote:


> What integer when
> multiplied by 3 produces the result 1? There is no integer that satisfies
> that condition. This illustrates the fact that the integers form a ring,
> not a field. On the other hand you could talk about quotient and remainder,
> Euclid's method, etc. Nothing prevents one from performing rational
> arithmetic with C or C++ but it is not usually built into an implementation
> (unlike Lisp, for example).


I fully accept the validity of applying rational division to integers, because
integers are in fact rational.

What I want to take issue with is the idea that the integers form a ring.
The only way that the integers form a ring is if they are taken modulo some
finite integral value.

Traditionally in computer science, we have had such a modulus applied for us
by the width of our words. But that has never meant that it is correct
behavior for integers at large. On the contrary, it is not.

Integers are an infinite closed group (not a ring) under addition,
subtraction, and multiplication. They are also closed under modulus
and div (the name by which the operation that has been referred to as
"integer division" is known to scheme.)

Integers are a subset of the infinite set of rational numbers, which is
closed under division proper.

I think it's really neat to have a language like scheme, which treats
integers properly as *INTEGERS* rather than as integers modulo 65536 or
integers modulo 32768 or some other stupid number. (I'm using MIT Scheme,
or a recompilation of it for pentium, which implements the whole numeric
tower and allows me to use *very* long integers. I'm also working (slowly)
on my own scheme, as a project to get familiar with c++ (sad, isn't it??).

I would really like a language with a good notation for exact irrationals
(you can represent most of the ones you might reach by computation from
finite forms) and, even when finally coerced to floating-point, not being
restricted to the little machine-word width. I think scheme is a good
candidate; these seem like things that very naturally "belong" as extensions
to its numeric tower.

Bear
---
God does not care about our mathematical difficulties. He
integrates empirically.
--Albert Einstein (1879-1955)

Dmitrii V. Pasechnik

unread,
Dec 14, 1996, 3:00:00 AM12/14/96
to

"Ray S. Dillinger" <be...@sonic.net> writes:

>Steve Bryan wrote:


>> What integer when
>> multiplied by 3 produces the result 1? There is no integer that satisfies
>> that condition. This illustrates the fact that the integers form a ring,
>> not a field. On the other hand you could talk about quotient and remainder,
>> Euclid's method, etc. Nothing prevents one from performing rational
>> arithmetic with C or C++ but it is not usually built into an implementation
>> (unlike Lisp, for example).


>I fully accept the validity of applying rational division to integers, because
>integers are in fact rational.

>What I want to take issue with is the idea that the integers form a ring.
>The only way that the integers form a ring is if they are taken modulo some
>finite integral value.

Of course the integers *themselves* form a ring - being closed under
division is *not* among the requirements for being a ring.

By the way, if the modulus you take is not prime you'd still
have noninvertable elements...

[...]


Dmitrii V. Pasechnik
Department of Mathematics
Eindhoven University of Technology
PO Box 513, 5600 MB Eindhoven
The Netherlands
e-mail: di...@win.tue.nl
http://www.can.nl/~pasec

Chris Bitmead

unread,
Dec 15, 1996, 3:00:00 AM12/15/96
to

doo...@menkar.cs.utk.edu (David Doolin) writes:

> In article <m3d8wjv...@thepla.net>, Chris Bitmead <Chr...@thepla.net> writes:

> |> David Hanley <da...@netright.com> writes:
> |>
> |> > > > Bad in 2 ways. With integers, this is not the result you
> |> > > > want. Frequently you want integers to behave like integers.
> |> > >
> |> > > No. You mean that sometimes you don't want division to behave like
> |> > > division:
> |> >

> |> > No, the integer division of 1/3 is 0. Period. Claiming this correct
> |> > result as a language defect is foolish.
> |>

> |> But who said that 1/3 is integer division? Take someone off the street
> |> and say that if he gives you 1/3 of a dollar you'll give him 0 dollars
> |> which is the same.
> |>

> |> Perhaps I'm naive, but I reckon 1/3 equals 1/3.

> |>
>
> Well, you said it. Check any text on elementary number theory

> or abstract algebra. The integer division of 1/3 is 0. Period.
> ^^^^^^^^^^^^^^^^

Yes fine, BUT, who said that 1/3 should default to integer arithmetic?
Most people when they do arithmetic are looking for an exact result,
and it is confusing to have something rounded off.

Now if you've got a case where you explicitely WANT integer arithmetic
then that is a special case and should be coded as such.

Chris Bitmead

unread,
Dec 15, 1996, 3:00:00 AM12/15/96
to

David Hanley <da...@netright.com> writes:

> SML also has a 'map' function which works perfectly well, and SML has a
> more encompasing type system than C++.


>
> > Consider how many reusable abstractions you can write if you
> > abandon static type checking.
>

> I don't necessarily agree with that. Could I see some examples of
> abstractions that are possible only in a dynamically typed language?

Here is an example (in C++ style code), that has no elegant solution
in typed languages...

class Food
{
int weight;
};
class Grass : Food
{
int height
}
class Animal
{
Food * diet;
}
class Cow : Animal
{
void lookForFood()
{
if (diet->height > 10) // Nice long grass to eat
// OOPS the compiler won't allow this
eat(diet);
}
}

No typed language (that I know of) has a nice solution for these sorts
of problems. Eiffel has a redefines clause, but the compiler can't
always know if your code is right or not.


Rolf-Thomas Happe

unread,
Dec 15, 1996, 3:00:00 AM12/15/96
to

In article <32B240...@sonic.net> "Ray S. Dillinger" <be...@sonic.net> writes:
[...]

What I want to take issue with is the idea that the integers form a ring.
The only way that the integers form a ring is if they are taken modulo some
finite integral value.
[...]

Integers are an infinite closed group (not a ring) under addition,
subtraction, and multiplication. They are also closed under modulus
and div (the name by which the operation that has been referred to as
"integer division" is known to scheme.)

The integers (Z, *) are certainly not a group under multiplication (13 has
no multiplicative inverse), but the integers (Z, +, *) are _the_ standard
ring, I would say. (Or your ring is not my ring. Which your-ring axiom
is not fulfilled?)

rthappe


It is loading more messages.
0 new messages