Re: Computer Language Popularity Trend

2006-09-27 Thread Joe Marshall

Xah Lee wrote:
> Computer Language Popularity Trend
>
> This page gives a visual report of computer languages's popularity, as
> indicated by their traffic level in newsgroups. This is not a
> comprehensive or fair survey, but does give some indications of
> popularity trends.

Suggestions:
  Provide a log-scale plot.  You can clearly see that there are
exponential trends in the data, these will turn into lines in
log-scale.  You can also see that the plots get more widely distributed
as the number of posts increase.  This too will be minimized in
log-scale.

  Make the horizontal scale for the `scripting' languages the same as
the others.  I know there isn't data out on the left of the graph, but
it surprised me to see points out there until I noticed the scale
change.

  For the Google trends, try looking for `java programming' or `written
in python' to avoid picking up the island and the popular comedy troupe.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is a type error?

2006-07-17 Thread Joe Marshall

Marshall wrote:
>
> I am having a hard time with this very broad definition of aliasing.

How about this definition:  Consider three variables, i, j, and k, and
a functional equivalence predicate (EQUIVALENT(i, j) returns true if
for every pure function F, F(i) = F(j)).  Now suppose i and j are
EQUIVALENT at some point, then a side effecting function G is invoked
on k, after which i and j are no longer equivalent.  Then there is
aliasing.

This is still a little awkward, but there are three main points:
  1.  Aliasing occurs between variables (named objects).
  2.  It is tied to the notion of equivalence.
  3.  You can detect it when a procedure that has no access to a value
can nonetheless modify the value.

In a call-by-value language, you cannot alias values directly, but if
the values are aggregate data structures (like in Java), you may be
able to modify a shared subcomponent.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is a type error?

2006-07-14 Thread Joe Marshall

Marshall wrote:
> Joe Marshall wrote:
> > Marshall wrote:
> > >
> > > Consider the following Java fragment:
> > >
> > > void foo() {
> > >   int i = 0;
> > >   int j = 0;
> > >
> > >   // put any code here you want
> > >
> > >   j = 1;
> > >   i = 2;
> > >   // check value of j here. It is still 1, no matter what you filled in
> > > above.
> > >   // The assignment to i cannot be made to affect the value of j.
> > >
> > > }
> >
> > True, but you have hidden the pointers.  Semantically, the identifiers
> > i and j refer not to integers but to locations that hold integers.  The
> > assignment modifies the location.
>
> What the implementation looks like shouldn't affect how we speak
> of the logical model. In the above code, there are no pointers.
>
> By your definition, "pointer" and "variable" are synonyms. That doesn't
> seem like a good idea to me. (What if i and j end up in registers?
> I have not heard it said that registers have addresses.)

You probably won't like this, but

The example you give above is a bit ambiguous as to whether or not it
shows `true' mutation.  So what do I mean by `true' mutation?  The code
above could be transformed by alpha-renaming into an equivalent version
that does no mutation:

void foo() {
   int i = 0;
   int j = 0;

   // put any code here you want

   int jj = 1;
   int ii = 2;
   // rename all uses of i to ii and j to jj after this point.

 }

Once I've done the renaming, we're left with a pure function.  I claim
that this sort of `mutation' is uninteresting because it can be
trivially eliminated through renaming.  Since we can eliminate it
through renaming, we can use a simplified semantics that does not
involve a `store', and use a substitution model of evaluation.

The more interesting kind of mutation cannot be eliminated through
renaming.  The semantic model requires the notion of a stateful
`store', and the model is not referentially transparent: substitution
does not work.  These qualities are what make mutation problematic.  My
claim is that this kind of mutation cannot be had without some model of
pointers and references.

There is a further distinguishing characteristic:  Can I write a
program that detects the mutation (and acts differently depending on
whether there is mutation or not)?  It is unclear from your example
above whether you intended this to be possible, but certainly there is
no way for a caller of foo to tell that foo reassigns an internal
variable.  If there a procedure is extrinsically a pure function, then
there is no real meaning to any `mutation' that goes on inside; there
is always a way to turn the internal mutation into a pure function
through alpha-renaming.

>
> Clearly there is *some* difference between a language which allows
> explicit pointers and thus aliasing and one that doesn't. What term
> would you use? First-class variables?

My argument to you in re this statement:
> Again, I disagree: it is posible to have mutability without
> pointers/identity/objects.

is that mutability without a notion of pointers, identity, or objects
is trivially eliminated through alpha renaming and thus isn't the
`mutability' of interest.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is a type error?

2006-07-13 Thread Joe Marshall

Marshall wrote:
>
> Consider the following Java fragment:
>
> void foo() {
>   int i = 0;
>   int j = 0;
>
>   // put any code here you want
>
>   j = 1;
>   i = 2;
>   // check value of j here. It is still 1, no matter what you filled in
> above.
>   // The assignment to i cannot be made to affect the value of j.
>
> }

True, but you have hidden the pointers.  Semantically, the identifiers
i and j refer not to integers but to locations that hold integers.  The
assignment modifies the location.

> Those two local primitive variables cannot be made to have the same
> identity. But you can update them, so this is an example of mutability
> without the possibility of identity.

The identity is temporal:  You use the same variable name at two
different times.  Do you intend for the second `i' to mean the same
variable as the first `i'?

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is a type error?

2006-07-13 Thread Joe Marshall

Marshall wrote:
>
> Again, I disagree: it is posible to have mutability without
> pointers/identity/objects.

I think you are wrong, but before I make a complete ass out of myself,
I have to ask what you mean by `mutability'.  (And
pointers/identity/objects, for that matter.)

Alan Bawden discusses the phenomenon of `state' in his Ph.D.
dissertation "Implementing Distributed Systems Using Linear Naming".
MIT AI Lab Technical Report AITR-1627. March 1993  He makes a
persuasive argument that `state' is associated with cycles in naming.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is Expressiveness in a Computer Language [correction]

2006-06-28 Thread Joe Marshall

Andreas Rossberg wrote:
>
>~/> ocaml -rectypes
>  Objective Caml version 3.08.3
>
># let rec blackhole x = blackhole;;
>val blackhole : 'b -> 'a as 'a = 
>
> The problem is, though, that almost everything can be typed once you
> have unrestricted recursive types (e.g. missing arguments etc), and
> consequently many actual errors remain unflagged (which clearly shows
> that typing is not only about potential value class mismatches).
> Moreover, there are very few practical uses of such a feature, and they
> can always be coded easily with recursive datatypes.
>
> It is a pragmatic decision born from experience that you simply do *not
> want* to have this, even though you easily could. E.g. for OCaml,
> unrestricted recursive typing was removed as default because of frequent
> user complaints.
>
> Which is why this actually is a very bad example to chose for dynamic
> typing advocacy... ;-)

Actually, this seems a *good* example.  The problem seems to be that
you end up throwing the baby out with the bathwater:  your static type
system stops catching the errors you want once you make it powerful
enough to express certain programs.

So now it seems to come down to a matter of taste:  use a restricted
language and catch certain errors early or use an unrestricted language
and miss certain errors.  It is interesting that the PLT people have
made this tradeoff as well.  In the DrScheme system, there are
different `language levels' that provide a restricted subset of Scheme.
 At the beginner level, first-class procedures are not allowed.  This
is obviously restrictive, but it has the advantage that extraneous
parenthesis (a common beginner mistake) cannot be misinterpreted as the
intent to invoke a first-class procedure.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is Expressiveness in a Computer Language

2006-06-28 Thread Joe Marshall

David Hopwood wrote:
> Joe Marshall wrote:
> >
> > The point is that there exists (by construction) programs that can
> > never be statically checked.
>
> I don't think you've shown that. I would like to see a more explicit
> construction of a dynamically typed [*] program with a given specification,
> where it is not possible to write a statically typed program that meets
> the same specification using the same algorithms.

I think we're at cross-purposes here.  It is trivial to create a static
type system that has a `universal type' and defers all the required
type narrowing to runtime.  In effect, we've `turned off' the static
typing (because everything trivially type checks at compile time).

However, a sufficiently powerful type system must be incomplete or
inconsistent (by Godel).  A type system proves theorems about a
program.  If the type system is rich enough, then there are unprovable,
yet true theorems.  That is, programs that are type-safe but do not
type check.  A type system that could reflect on itself is easily
powerful enough to qualify.

> AFAIK, it is *always* possible to construct such a statically typed
> program in a type system that supports typerec or gradual typing. The
> informal construction you give above doesn't contradict that, because
> it depends on reflecting on a [static] type system, and in a dynamically
> typed program there is no type system to reflect on.

A static type system is usually used for universal proofs:  For all
runtime values of such and such...   Dynamic checks usually provide
existential refutations:  This particular value isn't a string.  It may
be the case that there is no universal proof, yet no existential
refutation.

>
> Note that I'm not claiming that you can check any desirable property of
> a program (that would contradict Rice's Theorem), only that you can
> express any dynamically typed program in a statically typed language --
> with static checks where possible and dynamic checks where necessary.

Sure.  And I'm not saying that you cannot express these programs in a
static language, but rather that there exist programs that have
desirable properties (that run without error and produce the right
answer) but that the desirable properties cannot be statically checked.

The real question is how common these programs are, and what sort of
desirable properties are we trying to check.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is Expressiveness in a Computer Language

2006-06-27 Thread Joe Marshall

David Hopwood wrote:
> Joe Marshall wrote:
>
> > (defun blackhole (argument)
> >   (declare (ignore argument))
> >   #'blackhole)
>
> This is typeable in any system with universally quantified types (including
> most practical systems with parametric polymorphism); it has type
> "forall a . a -> #'blackhole".

The #' is just a namespace operator.  The function accepts a single
argument and returns the function itself.  You need a type that is a
fixed point (in addition to the universally quantified argument).

> >>The real question is, are there some programs that we
> >>can't write *at all* in a statically typed language, because
> >>they'll *never* be typable?
> >
> > Certainly!  As soon as you can reflect on the type system you can
> > construct programs that type-check iff they fail to type-check.
>
> A program that causes the type checker not to terminate (which is the
> effect of trying to construct such a thing in the type-reflective systems
> I know about) is hardly useful.
>
> In any case, I think the question implied the condition: "and that you
> can write in a language with no static type checking."

Presumably the remainder of the program does something interesting!

The point is that there exists (by construction) programs that can
never be statically checked.  The next question is whether such
programs are `interesting'.  Certainly a program that is simply
designed to contradict the type checker is of limited entertainment
value, but there should be programs that are independently non
checkable against a sufficiently powerful type system.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is Expressiveness in a Computer Language

2006-06-27 Thread Joe Marshall

QCD Apprentice wrote:
> Joe Marshall wrote:
> > Marshall wrote:
> >>
> >> The real question is, are there some programs that we
> >> can't write *at all* in a statically typed language, because
> >> they'll *never* be typable?
> >
> > Certainly!  As soon as you can reflect on the type system you can
> > construct programs that type-check iff they fail to type-check.
>
> Sorry, but can you elaborate on this last point a little?  I think I
> missed something.

This is just the halting problem lifted up into the type domain.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is Expressiveness in a Computer Language

2006-06-27 Thread Joe Marshall

Marshall wrote:
> Joe Marshall wrote:
> > Looking back in comp.lang.lisp, I see these examples:
> >
> > (defun noisy-apply (f arglist)
> >   (format t "I am now about to apply ~s to ~s" f arglist)
> >   (apply f arglist))
> >
> > (defun blackhole (argument)
> >   (declare (ignore argument))
> >   #'blackhole)
> >
> > But wait a sec.  It seems that these were examples I invented in
> > response to the same question from you!
>
> Ah, how well I remember that thread, and how little I got from it.
>
> My memories of that thread are
> 1) the troll who claimed that Java was unable to read two numbers from
> standard input and add them together.
> 2) The fact that all the smart people agreed the blackhole
> function indicated something profound.
> 3) The fact that I didn't understand the black hole function.
>
> The noisy-apply function I think I understand; it's generic on the
> entire arglist. In fact, if I read it correctly, it's even generic
> on the *arity* of the function, which is actually pretty impressive.
> True?

Yes.

> This is an issue I've been wrestling with in my own type
> system investigations: how to address genericity across arity.
>
> Does noisy-apply get invoked the same way as other functions?
> That would be cool.

Yes, but in testing I found an incompatability.  Here's a better
definiton:

(defun noisy-apply (f &rest args)
  (format t "~&Applying ~s to ~s." f (apply #'list* args))
  (apply f (apply #'list* args)))

CL-USER> (apply #'+ '(2 3))
5

CL-USER> (noisy-apply #'+ '(2 3))
Applying # to (2 3).
5

The internal application of list* flattens the argument list.  The
Common Lisp APPLY function has variable arity and this change makes my
NOISY-APPLY be identical.

> As to the black hole function, could you explain it a bit?

It is a function that takes any argument and returns the function
itself.

> I apologize
> for my lisp-ignorance. I am sure there is a world of significance
> in the # ' on the third line, but I have no idea what it is.

The #' is a namespace operator.  Since functions and variables have
different namespaces, I'm indicating that I wish to return the function
named blackhole rather than any variable of the same name that might be
around.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is Expressiveness in a Computer Language

2006-06-27 Thread Joe Marshall

Marshall wrote:
>
> Yes, an important question (IMHO the *more* important question
> than the terminology) is what *programs* do we give up if we
> wish to use static typing? I have never been able to pin this
> one down at all.

It would depend on the type system, naturally.

It isn't clear to me which programs we would have to give up, either.
I don't have much experience in sophisticated typed languages.  It is
rather easy to find programs that baffle an unsophisticated typed
language (C, C++, Java, etc.).

Looking back in comp.lang.lisp, I see these examples:

(defun noisy-apply (f arglist)
  (format t "I am now about to apply ~s to ~s" f arglist)
  (apply f arglist))

(defun blackhole (argument)
  (declare (ignore argument))
  #'blackhole)

But wait a sec.  It seems that these were examples I invented in
response to the same question from you!


>
> The real question is, are there some programs that we
> can't write *at all* in a statically typed language, because
> they'll *never* be typable?

Certainly!  As soon as you can reflect on the type system you can
construct programs that type-check iff they fail to type-check.

> > Perhaps, there is no such beast.  Or, perhaps I just can't formulate
> > it.  Or, perhaps we have static type checkers which can do
> > computations of unbounded complexity.  However, I thought that one of
> > the characteristics of type systems was that they did not allow
> > unbounded complexity and weren't Turing Complete.
>
> The C++ type system is Turing complete, although in practical terms
> it limits how much processing power it will spend on types at
> compile time.

I think templates only have to expand to seven levels, so you are
severely limited here.

> > If you allow Turing Complete type systems, then I would say no--every
> > bug can be reforumlated as a type error.  If you require your type
> > system to be less powerful, then some bugs must escape it.
>
> I don't think so. Even with a Turing complete type system, a program's
> runtime behavior is still something different from its static behavior.
> (This is the other side of the "types are not tags" issue--not only
> is it the case that there are things static types can do that tags
> can't, it is also the case that there are things tags can do that
> static types can't.)

I agree.  The point of static checking is to *not* run the program.  If
the type system gets too complicated, it may be a de-facto interpreter.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is Expressiveness in a Computer Language

2006-06-26 Thread Joe Marshall

David Hopwood wrote:
> > Joe Marshall wrote:
> >>
> >>I do this quite often.  Sometimes I'll develop `in the debugger'.  I'll
> >>change some piece of code and run the program until it traps.  Then,
> >>without exiting the debugger, I'll fix the immediate problem and
> >>restart the program at the point it trapped.  This technique takes a
> >>bit of practice, but if you are working on something that's complex and
> >>has a lot of state, it saves a lot of time because you don't have to
> >>reconstruct the state every time you make a change.
>
> The problem with this is that from that point on, what you're running
> is neither the old nor the new program, since its state may have been
> influenced by the bug before you corrected it.

Yes.  The hope is that it is closer to the new program than to the old.

> I find it far simpler to just restart the program after correcting
> anything. If this is too difficult, I change the design to make it
> less difficult.

In the most recent case where I was doing this, I was debugging
transaction rollback that involved multiple database extents.  It was
somewhat painful to set up a clean database to the point where I wanted
to try the rollback, and I wanted a pristine database for each trial so
I could examine the raw bits left by a rollback.  It was pretty easy to
deal with simple errors in the debugger, so I chose to do that instead.





>
> > Wow, interesting.
> >
> > (I say the following only to point out differing strategies of
> > development, not to say one or the other is right or bad or
> > whatever.)
> >
> > I occasionally find myself doing the above, and when I do,
> > I take it as a sign that I've screwed up. I find that process
> > excruciating, and I do everything I can to avoid it. Over the
> > years, I've gotten more and more adept at trying to turn
> > as many bugs as possible into type errors, so I don't have
> > to run the debugger.
> >
> > Now, there might be an argument to be made that if I had
> > been using a dynamic language, the process wouldn't be
> > so bad, and I woudn't dislike it so much. But mabe:
> >
> > As a strawman: suppose there are two broad categories
> > of mental strategies for thinking about bugs, and people
> > fall naturally into one way or the other, the way there
> > are morning people and night people. One group is
> > drawn to the static analysis, one group hates it.
> > One group hates working in the debugger, one group
> > is able to use that tool very effectively and elegantly.
> >
> > Anyway, it's a thought.
>
> I don't buy this -- or at least, I am not in either group.
>
> A good debugger is invaluable regardless of your attitude to type
> systems. Recently I was debugging two programs written to do similar
> things in the same statically typed language (C), but where a debugger
> could not be used for one of the programs. It took maybe 5 times
> longer to find and fix each bug without the debugger, and I found it
> a much more frustrating experience.
> 
> -- 
> David Hopwood <[EMAIL PROTECTED]>

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is Expressiveness in a Computer Language

2006-06-26 Thread Joe Marshall

Marshall wrote:
>
> I stand corrected: if one is using C and writing self-modifying
> code, then one *can* zip one's pants.

Static proofs notwithstanding, I'd prefer a dynamic check just prior to
this operation.

I want my code to be the only self-modifying thing around here.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is Expressiveness in a Computer Language

2006-06-23 Thread Joe Marshall

Marshall wrote:
> Timo Stamm wrote:
> >
> > This is actually one of the most interesting threads I have read in a
> > long time. If you ignore the evangelism, there is a lot if high-quality
> > information and first-hand experience you couldn't find in a dozen books.
>
> Hear hear! This is an *excellent* thread. The evangelism is at
> rock-bottom
> and the open exploration of other people's way of thinking is at what
> looks to me like an all-time high.

What are you, some sort of neo-static pseudo-relational
object-disoriented fascist?

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is Expressiveness in a Computer Language

2006-06-23 Thread Joe Marshall

Marshall wrote:
> Joe Marshall wrote:
> >
> > That's the important point:  I want to run broken code.
>
> I want to make sure I understand. I can think of several things
> you might mean by this. It could be:
> 1) I want to run my program, even though I know parts of it
> are broken, because I think there are parts that are not broken
> and I want to try them out.

I think I mean a little of each of these.

Nearly *every* program I have ever used is buggy, so this is actually a
normal state of affairs even when I'm not debugging or developing.

> 2) I want to run my program, even though it is broken, and I
> want to run right up to a broken part and trap there, so I can
> use the runtime facilities of the language to inspect what's
> going on.

I do this quite often.  Sometimes I'll develop `in the debugger'.  I'll
change some piece of code and run the program until it traps.  Then,
without exiting the debugger, I'll fix the immediate problem and
restart the program at the point it trapped.  This technique takes a
bit of practice, but if you are working on something that's complex and
has a lot of state, it saves a lot of time because you don't have to
reconstruct the state every time you make a change.

> > I want to run
> > as much of the working fragments as I can, and I want a `safety net' to
> > prevent me from performing undefined operations, but I want the safety
> > net to catch me at the *last* possible moment.
>
> This statement is interesting, because the conventional wisdom (at
> least as I'm used to hearing it) is that it is best to catch bugs
> at the *first* possible moment. But I think maybe we're talking
> about different continua here. The last last last possible moment
> is after the software has shipped to the customer, and I'm pretty
> sure that's not what you mean. I think maybe you mean something
> more like 2) above.

It is often the case that the proximate cause of a bug is nowhere near
where the fix needs to be applied.  This is especially true with the
really hard bugs.  A static type system will tell me that there (may)
exist a path through the code that results in an error, but the runtime
check that fails will provide a witness.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is Expressiveness in a Computer Language

2006-06-22 Thread Joe Marshall

Chris Smith wrote:
> Joachim Durchholz <[EMAIL PROTECTED]> wrote:
> > Assume a language that
> > a) defines that a program is "type-correct" iff HM inference establishes
> > that there are no type errors
> > b) compiles a type-incorrect program anyway, with an establishes
> > rigorous semantics for such programs (e.g. by throwing exceptions as
> > appropriate).
>
> So the compiler now attempts to prove theorems about the program, but
> once it has done so it uses the results merely to optimize its runtime
> behavior and then throws the results away.  I'd call that not a
> statically typed language, then.

You're assuming that type-correctness is an all-or-nothing property
(well, technically it *is*, but bear with me).  What if the compiler is
unable to prove a theorem about the entire program, but *can* prove a
theorem about a subset of the program.  The theorems would naturally be
conditional, e.g.  `Provided the input is an integer, the program is
type-safe', or time-bounded, e.g. `Until the program attempts to invoke
function FOO, the program is type-safe.'

Of course, we could encode that by restricting the type of the input
and everything would be copacetic, but suppose there is a requirement
that floating point numbers are valid input.  For some reason, our
program is not type-safe for floats, but as a developer who is working
on the integer math routines, I have no intention of running that code.
 The compiler cannot prove that I won't perversely enter a float, but
it can prove that if I enter an integer everything is type-safe.  I can
therefore run, debug, and use a subset of the program.

That's the important point:  I want to run broken code.  I want to run
as much of the working fragments as I can, and I want a `safety net' to
prevent me from performing undefined operations, but I want the safety
net to catch me at the *last* possible moment.  I'm not playing it safe
and staying where the compiler can prove I'll be ok.  I'm living
dangerously and wandering near the edge where the compiler can't quite
prove that I'll fail.

Once I've done the major amount of exploratory programming, I may very
well want to tighten things up.  I'd like to have the compiler prove
that some mature library is type-safe and that all callers to the
library use it in a type-correct manner.  I'd like the compiler to say
`Hey, did you know that if the user enters a floating point number
instead of his name that your program will crash and burn?', but I
don't want that sort of information until I'm pretty sure about what I
want the program to do in the normal case.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is Expressiveness in a Computer Language

2006-06-21 Thread Joe Marshall

Marshall wrote:
>
> That's really coming home to me in this thread: the terminology is *so*
> bad. I have noticed this previously in the differences between
> structural
> and nominal typing; many typing issues associated with this distinction
> are falsely labeled as a static-vs-dynamic issues, since so many
> statically
> type languages are nominally typed.
>
> We need entirely new, finer grained terminology.

Agreed.  That's why I've been biting my tongue and avoiding posting.
The discussion is going along the lines of the blind men and the
elephant.  I've seen about seven different definitions of what a `type'
is, and most of the arguments seem to come from people misunderstanding
the other person's definition.  I think that *most* of the people
arguing here would agree with each other (possibly in detail) if only
they understood each other.

Static type aficionados have a specialized jargon that has precise
meaning for a number of the terms being used.  People that aren't into
that field of computer science use the same terms in a much looser
sense.  But static type aficionados are definitely in the minority in
comp.lang.lisp, and probably in a few of the other comp.langs as well.

What we need is an FAQ entry for how to talk about types with people
who are technically adept, but non-specialists.  Or alternatively, an
FAQ of how to explain the term `dynamic typing' to a type theorist.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is Expressiveness in a Computer Language

2006-06-20 Thread Joe Marshall

Chris Smith wrote:
> Joe Marshall <[EMAIL PROTECTED]> wrote:
> >
> > Agreed.  That is why there is the qualifier `dynamic'.  This indicates
> > that it is a completely different thing from static types.
>
> If we agree about this, then there is no need to continue this
> discussion.  I'm not sure we do agree, though, because I doubt we'd be
> right here in this conversation if we did.

I think we do agree.

The issue of `static vs. dynamic types' comes up about twice a year in
comp.lang.lisp  It generally gets pretty heated, but eventually people
come to understand what the other person is saying (or they get bored
and drop out of the conversation - I'm not sure which).  Someone always
points out that the phrase `dynamic types' really has no meaning in the
world of static type analysis.  (Conversely, the notion of a `static
type' that is available at runtime has no meaning in the dynamic
world.)  Much confusion usually follows.

You'll get much farther in your arguments by explaining what you mean
in detail rather than attempting to force a unification of teminology.
You'll also get farther by remembering that many of the people here
have not had much experience with real static type systems.  The static
typing of C++ or Java is so primitive that it is barely an example of
static typing at all, yet these are the most common examples of
statically typed languages people typically encounter.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is Expressiveness in a Computer Language

2006-06-19 Thread Joe Marshall

Chris Smith wrote:
> Joe Marshall <[EMAIL PROTECTED]> wrote:
> >
> > Chris Smith wrote:
> > >
> > > Knowing that it'll cause a lot of strenuous objection, I'll nevertheless
> > > interject my plea not to abuse the word "type" with a phrase like
> > > "dynamically typed".
> >
> > Allow me to strenuously object.  The static typing community has its
> > own set of
> > terminology and that's fine.  However, we Lisp hackers are not used to
> > this terminology.
> > It confuses us.  *We* know what we mean by `dynamically typed', and we
> > suspect *you* do, too.
>
> I know what you mean by types in LISP.  The phrase "dynamically typed,"
> though, was explicitly introduced as a counterpart to "statically
> typed" in order to imply (falsely) that the word "typed" has related
> meanings in those two cases.

They *do* have a related meaning.  Consider this code fragment:
(car "a string")

Obviously this code is `wrong' in some way.  In static typing terms, we
could say that
we have a type error because the primitive procedure CAR doesn't
operate on strings.
Alternatively, we could say that since Lisp has one universal type (in
static type terms)
the code is correctly statically typed - that is, CAR is defined on all
input, but it's definition is to raise a runtime exception when passed
a string.

But regardless of which way you want to look at it, CAR is *not* going
to perform its usual computation and it is *not* going to return a
value.  The reason behind this is that you cannot take the CAR of a
string.  A string is *not* a valid argument to CAR.  Ask anyone why and
they will tell you `It's the wrong type.'

Both `static typing' and `dynamic typing' (in the colloquial sense) are
strategies to detect this sort of error.

> Nevertheless, I did not really object,
> since it's long since passed into common usage,

Exactly.  And you are far more likely to encounter this sort of usage
outside of a type theorist's convention.


> until Torben attempted
> to give what I believe are rather meaningless definitions to those
> words, in terms of some mythical thing called "type violations" that he
> seems to believe exist apart from any specific type systems.

It's hardly mythical.  (car "a string") is obviously an error and you
don't need a static type system to know that.

> > > This cleaner terminology eliminates a lot of confusion.
> >
> > Hah!  Look at the archives.
>
> I'm not sure what you mean here.  You would like me to look at the
> archives of which of the five groups that are part of this conversation?
> In any case, the confusion I'm referring to pertains to comparison of
> languages, and it's already been demonstrated once in the half-dozen or
> so responses to this branch of this thread.

I mean that this has been argued time and time again in comp.lang.lisp
and probably the other groups as well.  You may not like the fact that
we say that Lisp is dynamically typed, but *we* are not confused by
this usage.  In fact, we become rather confused when you say `a
correctly typed program cannot go wrong at runtime' because we've seen
plenty of runtime errors from code that is `correctly typed'.

> > >  If types DON'T mean a compile-time method for proving the
> > > absence of certain program behaviors, then they don't mean anything at
> > > all.
> >
> > Nonsense.
>
> Please accept my apologies for not making the context clear.  I tried to
> clarify, in my response to Pascal, that I don't mean that the word
> "type" can't have any possible meaning except for the one from
> programming language type theory.  I should modify my statement as
> follows:
>
> An attempt to generalize the definition of "type" from programming
> language type theory to eliminate the requirement that they are
> syntactic in nature yields something meaningless.  Any concept of
> "type" that is not syntactic is a completely different thing from
> static types.

Agreed.  That is why there is the qualifier `dynamic'.  This indicates
that it is a completely different thing from static types.

> Basically, I start objecting when someone starts comparing "statically
> typed" and "dynamically typed" as if they were both varieties of some
> general concept called "typed".  They aren't.

I disagree.  There is clearly a concept that there are different
varieties of data and they are not interchangable.  In some languages,
it is up to the programmer to ensure that mistakes in data usage do not
happen.  In oth

Re: What is Expressiveness in a Computer Language

2006-06-19 Thread Joe Marshall

Chris Smith wrote:
>
> Knowing that it'll cause a lot of strenuous objection, I'll nevertheless
> interject my plea not to abuse the word "type" with a phrase like
> "dynamically typed".

Allow me to strenuously object.  The static typing community has its
own set of
terminology and that's fine.  However, we Lisp hackers are not used to
this terminology.
It confuses us.  *We* know what we mean by `dynamically typed', and we
suspect *you* do, too.


> This cleaner terminology eliminates a lot of confusion.

Hah!  Look at the archives.

> This isn't just a matter of preference in terminology.

No?

>  If types DON'T mean a compile-time method for proving the
> absence of certain program behaviors, then they don't mean anything at
> all.

Nonsense.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is Expressiveness in a Computer Language

2006-06-09 Thread Joe Marshall

Xah Lee wrote:
> in March, i posted a essay "What is Expressiveness in a Computer
> Language", archived at:
> http://xahlee.org/perl-python/what_is_expresiveness.html
>
> I was informed then that there is a academic paper written on this
> subject.
>
> On the Expressive Power of Programming Languages, by Matthias
> Felleisen, 1990.
> http://www.ccs.neu.edu/home/cobbe/pl-seminar-jr/notes/2003-sep-26/expressive-slides.pdf
>
> Has anyone read this paper? And, would anyone be interested in giving a
> summary?

The gist of the paper is this:  Some computer languages seem to be
`more expressive' than
others.  But anything that can be computed in one Turing complete
language can be computed in any other Turing complete language.
Clearly the notion of
expressiveness isn't concerned with ultimately computing the answer.

Felleisen's paper puts forth a formal definition of expressiveness in
terms of semantic
equivilances of small, local constructs.  In his definition, wholescale
program transformation is
disallowed so you cannot appeal to Turing completeness to claim program
equivalence.

Expressiveness isn't necessarily a good thing.  For instance, in C, you
can express the
addresses of variables by using pointers.  You cannot express the same
thing in Java, and
most people consider this to be a good idea.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A critic of Guido's blog on Python's lambda

2006-05-10 Thread Joe Marshall

Alex Martelli wrote:
> Joe Marshall <[EMAIL PROTECTED]> wrote:
>...
> > The problem is that a `name' is a mapping from a symbolic identifier to
> > an object and that this mapping must either be global (with the
> > attendant name collision issues) or within a context (with the
> > attendant question of `in which context').
>
> Why is that a problem?  Even for so-called "global" names, Python
> supports a structured, hierarchical namespace, so there can never be any
> collision betwen the "globals" of distinct modules (including modules
> which happen to have the same name but live in distinct packages or
> subpackages) -- I did mention that names could usefully be displayed in
> some strcutured form such as apackage.somemodule.thefunction but perhaps
> I was too tangential about it;-).

Can you refer to inner functions from the global context?  Suppose I
have this Python code:

def make_adder(x):
def adder_func(y):
sum = x + y
return sum
return adder_func

Can I refer to the inner adder_func in any meaningful way?


>
>
> > Matthias Felleisen once suggested that *every* internal function should
> > be named.  I just said `continuations'.  He immediately amended his
> > statement with `except those'.
>
> If I used continuations (I assume you mean in the call/cc sense rather
> than some in which I'm not familiar?) I might feel the same way, or not,
> but I don't (alas), so I can't really argue the point either way for
> lack of real-world experience.

I meant continuations as in the receiver function in
continuation-passing-style.  If you have a function that has to act
differently in response to certain conditions, and you want to
parameterize the behavior, then one possibility is to pass one or more
thunks to the function in addition to the normal arguments.  The
function acts by selecting and invoking one of the thunks.  A classic
example is table lookup.  It is often the case you wish to proceed
differently depending upon whether a key exists in a table or not.
There are several ways to provide this functionality.  One is to have a
separate `key-exists?' predicate.  Another is to have a special return
value for `key not found'.  Another is to throw an exception when a key
is not found.  There are obvious advantages and drawbacks to all of
these methods.  By using continuation-passing-style, we can
parameterize how the table lookup proceeds once it determines whether
or not the key is found.  We have the lookup procedure take two thunks
in addition to the key.  If the key is found, the first thunk is
invoked on the associated value.  If the key is not found, the second
thunk is invoked.  We can subsume all the previous behaviors:

(define (key-exists? key table)
  (lookup key table
 (lambda (value) #t) ;; if found, ignore value, return true
 (lambda () #f)))  ;; if not found, return false.

(define (option1 key table)
  (lookup key table
(lambda (value) value)
(lambda () 'key-not-found)))

(define (option2 key table)
  (lookup key table
(lambda (value) value)
(lambda () (raise 'key-not-found-exception

(define (option3 key table default-value)
  (lookup key table
(lambda (value) value)
(lambda () default-value)))

The unnamed functions act in this regard much like a `local label'.  We
wrap two chunks of code in a lambda and the lookup function `jumps' to
the appropriate chunk.  (If the compiler knows about thunks, the
generated assembly code really will have local labels and jump
instructions.  It can be quite efficient.)

This may look odd and cumbersome, but with a little practice the
lambdas fade into the background and it becomes easy to read.

My point with Matthias, however, was that defining all these
continuations (the thunks) as named internal functions was not only
cumbersome, but it obscured the control flow.  Notice:

(define (named-option3 key table default-value)
  (define (if-found value)
 value)
  (define (if-not-found)
 default-value)
  (lookup key table if-found if-not-found))

When we enter the function, we skip down to the bottom (past the
internal definitions) to run lookup, which transfers control to a
function defined earlier in the code.

There are many reasons to avoid this style in Python, so this probably
won't win you over, but my point is that there are times where
anonymous functions have an advantage over the named alternative and
that disallowing anonymous functions can be as cumbersome as
disallowing anonymous integers.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A critic of Guido's blog on Python's lambda

2006-05-09 Thread Joe Marshall

Alex Martelli wrote:
>
> I think it's reasonable to make a name a part of functions, classes and
> modules because they may often be involved in tracebacks (in case of
> uncaught errors): to me, it makes sense to let an error-diagnosing
> tracebacks display packages, modules, classes and functions/methods
> involved in the chain of calls leading to the point of error _by name_.
>
> I think it's reasonable to make a name a part of types for a different
> reason: new types are rarely meant to be used "just once"; but also, if
> during debugging any object is displayed, it's nice to be able to show,
> as part of the display, "this object is of type X and ...", with X shown
> as a name rather than as a complete (thus lengthy) description. (any
> decent interactive shell/debugger will let you drill down into the
> details as and when you need to, of course, but a well-chosen name can
> be often sufficient during such interactive exploration/debugging
> sessions, and therefore save time and effort).

I agree that symbolic debugging info is a good thing.

> Indeed, "given an object, how do I get its NAME" (for inspection and
> debugging purposes) is the most frequently asked question on
> comp.lang.python, and I've grown a bit tired of answering "you can't, an
> object in general intrinsically ``has no name'', it might have many or
> none at all, blah blah" -- yeah, this is technically true (in today's
> Python), but there's no real reason why it should stay that way forever
> (IMHO).  If we at least ALLOWED named objects everywhere, this would
> further promote the use of names as against mysterious "magic numbers",
> since the programmer would KNOW that after
> VAT_MULTIPLIER = 1.19
> then displaying in a debugger or other interactive session that
> PARTICULAR instance of the value 1.19 would show the name string
> 'VAT_MULTIPLIER' as well (or no doubt a more structured name constructed
> on the fly, identifying package and module-within-package too).

The problem is that a `name' is a mapping from a symbolic identifier to
an object and that this mapping must either be global (with the
attendant name collision issues) or within a context (with the
attendant question of `in which context').

> Mandating names for _everything_ would complicate the language by
> forcing it to provide builtin names for a lot of elementary building
> blocks: so for most types of objects it's best to "gently nudge".  For
> functions, classes, modules, and packages, I think the naming is
> important enough (as explained above) to warrant a syntax including the
> name; better, therefore, not to complicate the language by providing
> another different syntax in each case just to allow the name to be
> omitted -- why encourage a pratice that's best discouraged, at the price
> of language simplicity?

I agree.  This is why I write
(defun foo (x) ...)

rather than
(setf (symbol-function 'foo) (lambda (x) ...))

However, there are places where names are cumbersome.  They are
certainly cumbersome for most literal objects like numbers and strings.
 There are circumstances where they are cumbersome for function
objects.  The function (lambda (x) (+ x 3)) doesn't really need a name.
 It isn't any big deal if you give it a name, but it's a trivial
annoyance to be forced to give it a name.  It becomes a major annoyance
when you write code in continuation-passing-style or monadic style.

It is an annoyance when refactoring code, too.  Suppose you had written
(mapcar #'sin list-of-numbers)

and you realize that the numbers are in degrees.  With an unnamed
function, this is an easy fix:
(mapcar (lambda (x) (sin (deg->rad x))) list-of-numbers)

With a named function, you have to do one of these:
(flet ((sin-d (x) (sin (deg->rad x
  (mapcar #'sin-d list-of-numbers))

or
(mapcar (flet ((sin-d (x) (sin (deg->rad x #'sin-d)
list-of-numbers)


Matthias Felleisen once suggested that *every* internal function should
be named.  I just said `continuations'.  He immediately amended his
statement with `except those'.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A critic of Guido's blog on Python's lambda

2006-05-09 Thread Joe Marshall

Pisin Bootvong wrote:
> Is this a Slippery Slope fallacious argument?
> (http://c2.com/cgi/wiki?SlipperySlope)
>
> "if python required you to name every function then soon it will
> require you to name every number, every string, every immediate result,
> etc. And we know that is bad. Therefore requiring you to name your
> function is bad So Python is bad"

No, it is a question about consistency.  Why are functions singled out?

Or is this an attempt to apply an Argumentum ad Logicam fallacy?

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A critic of Guido's blog on Python's lambda

2006-05-08 Thread Joe Marshall

Alex Martelli wrote:
>
> Your "pragmatic benefits", if such they were, would also apply to the
> issue of "magic numbers", which was discussed in another subthread of
> this unending thread; are you therefore arguing, contrary to widespread
> opinion [also concurred in by an apparently-Lisp-oriented discussant],
> that it's BETTER to have magic unexplained numbers appear as numeric
> constants "out of nowhere" smack in the middle of expressions, rather
> than get NAMED separately and then have the names be used?  If you
> really believe in the importance of the "pragmatic benefits" you claim,
> then to be consistent you should be arguing that...:
>
> return total_amount * 1.19
>
> is vastly superior to the alternative which most everybody would deem
> preferable,
>
> VAT_MULTIPLIER = 1.19
> return total_amount * VAT_MULTIPLIER
>
> because the alternative with the magic number splattered inexplicably
> smack in the middle of code "communicated the fact" that it's used only
> within that expression, and makes all context available without having
> to look "elsewhere" (just one statement up of course, but then this
> would be identically so if the "one statement up" was a def, and we were
> discussing named vs unnamed functions vs "magic numbers").

Most languages allow `unnamed numbers'.  The `VAT_MULTIPLIER' argument
is a
strawman.  Would you want to have to use a special syntax to name the
increment
in loop?

 defnumber zero 0
 defnumber one { successor (zero); }

 for (int i = zero; i < limit; i += one) { ...}

If you language allows unnamed integers, unnamed strings, unnamed
characters, unnamed arrays or aggregates, unnamed floats, unnamed
expressions, unnamed statements, unnamed argument lists, etc.  why
*require* a name for trivial functions?
Wouldn't all the other constructs benefit by having a required name as
well?

>
> To my view of thinking, offering multiple semantically equivalent ways
> (or, perhaps worse, "nearly equivalent but with subtle differences"
> ones) to perform identical tasks is a *HUGE* conceptual cost: I like
> languages that are and stay SMALL and SIMPLE.

Then why not stick with S and K combinators?  There are few languages
SMALLER and
SIMPLER.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A critic of Guido's blog on Python's lambda

2006-05-08 Thread Joe Marshall

Alex Martelli wrote:
> Ken Tilton <[EMAIL PROTECTED]> wrote:
>...
> > But the key in the whole thread is simply that indentation will not
> > scale. Nor will Python.
>
> Absolutely.  That's why firms who are interested in building *seriously*
> large scale systems, like my employer (and supplier of your free mail
> account), would never, EVER use Python,

So how much Python code runs when I check my gmail?

> nor employ in prominent
> positions such people as the language's inventor and BDFL, the author of
> the most used checking tool for it, and the author of the best-selling
> reference book about that language; and, for that matter, a Director of
> Search Quality who, while personally a world-renowned expert of AI and
> LISP, is on record as supporting Python very strongly, and publically
> stating its importance to said employer.

Doesn't Google also employ such people as the inventor of Limbo
programming language, one of the inventors of Dylan, and a Smalltalk
expert?

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Lambda: the Ultimate Design Flaw

2005-04-01 Thread Joe Marshall
Jeremy Bowers <[EMAIL PROTECTED]> writes:

> On Thu, 31 Mar 2005 23:30:42 -0800, Erik Max Francis wrote:
>
>> Daniel Silva wrote:
>> 
>>> Shriram Krishnamurthi has just announced the following elsewhere; it might
>>> be of interest to c.l.s, c.l.f, and c.l.p:
>>> http://list.cs.brown.edu/pipermail/plt-scheme/2005-April/008382.html
>> 
>> April Fool's Day again, eh?
>
> Yes and no. In the Python community, we're taking all of that pretty
> seriously. 

The Python community takes many things pretty seriously.  Whitespace
and Guido come to mind.

-- 
http://mail.python.org/mailman/listinfo/python-list