[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Var-free programming (slightly off-topic)
Date: Tue, 4 Dec 2001 18:39:49 -0500 (EST)
From: Shriram Krishnamurthi <sk@cs.brown.edu>
1. I should be able to write expressions without wrapping them. That
is, no publicstaticvoidmainmumbojumbo. This may be the single most
important property. It distinguishes LLs from the Pascal mindset.
There are really two things here that you're rejecting:
-- Mandatory type declarations for methods/functions/whatever.
-- Mandatory "programming-in-the-large" declarations.
2. I should not have to declare types most of the time. This is NOT
the same as saying the language does not enforce type boundaries
statically: in this sense, ML counts.
3. I should be allowed to submit, but not run, buggy programs. That
is, for rapid prototyping, I should be able to write a program with
3 functions, A, B, and C; C can be buggy, but so long as I use A
and B only, I shouldn't be prevented from running the code. ML
fails at this. The ML-like type systems for Scheme succeed.
OK. I'll just point out that this probably isn't properly considered
part of the definition of the langauge. It seems to me that it's part
of the programming environment.
In Sun's Java implementation, you can do this at the granularity of a
source file, i.e. if one source file is rejected by the compiler, you
can still run stuff in another file. It would be pretty easy to come
up with a Java compiler that would generate class files containing all
the methods that did compile properly. The Lisp machine had a
"compile this file" command that would not produce an output file if
there were compile-time errors; it *also* had function-at-a-time
compilation, but if you had a big function (or method) with a
compile-time error in it, the whole function could not be run.
So I think this criterion has to be paramerized by a granularity,
and we might way that a language is more lightweight to the
extent that this granularity is smaller.
4. Implementations must be safe, ie, they should catch mis-application
of primitives to values of the wrong kind.
This may need to be divided into a "language definition" part and a
"language implementation" part. In C, could you build a C
implementation that always detects array-out-of-bound errors at
runtime? Did Saber/Centerline do this? I actually can't remember. I
have some memory that in C, doing pointer arithmetic that takes a
pointer out of the allocated object that it started in is actually
considered illegal, even though normal C implementations never detect
it, but I could be wrong about this.
5. I'll cross the line from language to implementation (hit me hard on
the head, Simon!): it needs to provide a rapid execution
environment.
I think that needs to be said more carefully. It could easily be
interpreted as "programs must execute quickly". Python, I was told,
doesn't even try to do this.
The Perl folks prefer the command line; us paren
wankers like a REPL. Whatever. I shouldn't be forced to go
through some sort of compilation process. As you point out,
however, this is a property even C enjoys (indeed, I remember
using a C interpreter as far back as high school (~1985)), and Java
can support. So it's not sufficient, but it sure is necessary.
Actually now I'm not sure whether you're talking about whether you
are referring to the time taken by the program to run, or the
time between the last edit and the beginning of program execution.
Anyway, yes, this is implementation for sure.
I do think it's a property of the language. I think #1 is
definitional, but #4 is a key player. We don't want seg faults from
our LL, so we want safe implementations. On the other hand, some
languages compromise this property by making just about every
syntactically legal program have some meaning.
Hence, I'll propose that weight is inversely proportional to the
number of syntactically legal expressions that execute correctly. In
that respect, Arc is like Lisp on a diet.
Gee, that's not what I expected you to say. If it's bad for just
about every syntactically legal program to have some meaning, then it
would seem to be good to add redundancy that give you extra checking,
such as mandatory typed variables. (Unless I'm misunderstanding the
gist of your point...)
Maybe I'm misunderstanding what you mean by "execute correctly". Of
course no language defines any syntactically legal expression to
execute incorrectly in the sense of returning the wrong answer. I
presume you mean something about expressions that are syntactically
legal but "semantically" signal an error sometimes between being
written and being executed?