Re: Program compression
- From: jaycx2.3.calrobert@xxxxxxxxxxxxxxxxxxxxxx (Robert Maas, http://tinyurl.com/uh3t)
- Date: Fri, 15 Aug 2008 04:01:36 -0700
thomas.mer...@xxxxxx wrote:
TM> I get the impression that you think that only concepts
TM> supported by your favorite language (LISP) are good concepts.
TM> If some concept is not present in LISP you conclude that it is
TM> bad and everybody using it does not know any better.
Your impression is slightly wrong. While I immediately appreciate
mechanisms present in Lisp, I'm willing to hear a convincing case
why some additional mechanism would also be useful. But as soon as
you convince me that the additional mechanism is useful, I'll ask
how much trouble would it take to implement as an add-on module
within Lisp, thereby making that "other" language unnecessary. If
there's a very natural way to express the additional mechanism
within Lisp, such that it also generates reasonably efficient
compiled code, then Lisp wins again. But if there were ever a case
where it would take an extreme contortion to accomplish the task in
Lisp, ...
I hope you return the favor. Whenever somebody shows some mechanism
in Lisp that isn't naturally present in *your* favorite language,
you figure out how Lisp's mechanism could be implemented in your
favorite language, and evaluate whether it's impossible or possible
but only by extreme contortions of your language or in fact easy to
express directly in your language.
For example, suppose your favorite language is Java. So I give an
example where in Lisp your code can analyze a file of columnar data
statistically to decide where the start/end of each column of data
lies, producing a list of start/end index pairs. Then your code can
build a list of forms to select those particular sub-strings from a
line of input from the file. Then your code can compile that list
of forms into a function that when applied to a line will produce a
list of sub-strings representing the fields of data.
Then I show how in Java, if you want to accomplish the same task,
you need to generate Java source code and write it to a disk file,
then call the Java compiler to compile that source file to a Class
file, then load the Class file back in. The Class is a sub-class or
satisfies an interface, so as soon as it's loaded you can apply the
generic methods of the parent class or interface (the Class
contains a constructor that converts a string into an instance of
that class, then another method returns the vector of fields within
the string). The problem is that you're writing a disk file which
must have a name that isn't going to step on similar disk files
written by other instances of exactly the same software that by
chance is running at the same time. So you need to include the
process number in the names of the files, and you need to run a
'chron' job to check from time to time to see if any crashed
process has left any of its files around that need to be deleted.
Big royal pain in Java. Is there any better way to do it in Java
that is as "clean" as the way it's done in Lisp by constructing a
LAMBDA expression and compiling it into an anonymous FUNCTION
object?
So is that fair, a design pattern that is nice and straightforward
(and clean, no need to run a 'chron' job to clean up the mess) in
one person's favorite language, and asking how nice and
straightforward and clean it is to do in somebody else's favorite
language?
TM> I know that you hate static type checking
Yeah, most of the time it terribly slows down line-at-a-time REPL
development of new code, and it doesn't seem to provide any
advantage that can't be easily obtained by runtime checking of
parameters going into each function. (Furthermore, runtime checking
can go far beyond static machine-type checking, to include full
intentional-type checking as well as various sub-type checking such
as whether a particular field has been added to a data record yet.
There's just no way to know at compile time that upon entry to this
particular routine somebody else has already filled in the FOO
field within this type of data record.)
TM> but I think that you[r] should look at concepts from outside your
TM> (LISP) world.
You show me a concept, nicely explained so that I understand it, or
maybe confusing at first but you be available to answer my followup
questions, and show why you believe it's of general use, not just
some special dohicky needed for a single problem domain, and I'll
consider it. One example that has been touted recently is Google's
map-reduce paradigm. I don't yet fully appreciate it, but I do
appreciate it enough to accept it as a valuable idea that I might
eventually find a use for in my own work. I won't be using it for
its primary purpose of expressing algorithms for server farms,
because I don't have any money to lease time on any server farm,
and the number of regular systems I can run software on is fewer
than the fingers on one hand. But I might someday implement it in a
non-parallel way, just as a way to cleanly express some algorithms.
My ProxHash algorithms are already working fine without it, and I
don't feel like refactoring them into map-reduce form, so at
present I can't think of any algorithm I would want to express in
map-reduce form. But you never know, maybe someday...
TM> I tried to include answers to your previous arguments ag[g]ainst
TM> static typ[e] checking in my FAQ at:
TM> http://seed7.sourceforge.net/faq.htm#static_type_checking
***START***
TM-STC> Type errors, such as an attempt to divide an integer by a
TM-STC> string, can be caught earlier
That's not earlier at all. With my line-at-a-time development
style, as soon as I write the line of code that tries to do the
illegal operation and submit it to REP, it'll signal an error. This
is long before the point where I build this line of code with other
lines of code into a function where it's possible to declare static
types which can then be checked during compilation of the function
definition.
TM-STC> Since static type checking makes run-time type checks unnecessary, ...
That is the big lie right there! Suppose you have a data record
that has ten optional fields. These ten fields can be filled in any
sequence, and for many applications several of them will remain
unfilled. Each function that uses these fields can have a runtime
check to make sure all the required fields are filled in, ignoring
the other fields not needed for that particular function. It would
be horrendous to set up a hierarchy of classes of objects that were
parameterized according to which fields were always defined per
that class of object, and convert an object from one class to
another (in Java using a constructor that took the old object and
the new field to yield a new object of the new class; in Common
Lisp using the CHANGE-CLASS function) each time one of the fields
got filled in for the first time. There's just no practical way for
compile-time static type-checking to completely replace runtime
checking. Note that it's *intentional* type checking that most
requires runtime checking. For example, you might use exactly the
same static compiletime type for a whole bunch of intentional
types, because setting up a separate static type for each separate
intentional type would be a royal pain.
Static type: Animal &optional gut legs wings fins lungs gills breasts
Intentional type: Mammal = animal+gut+legs(4)+lungs+breasts
Intentional type: Fish = animal+gut+fins+gills
Intentional type: Marsupial = animal+gut+legs(4)+lungs-breasts
Intentional type: Bird = animal+gut+legs(2)+wings(2)+lungs
Intentional type: Worm = animal+gut-legs-fins
Intentional type: Sponge = animal-gut
Intentional type: Crocodile = animal+gut+legs(4)+lungs+fins
Intentional types can be so subtle that no imaginable compile time
declarations would suffice to distinguish them and thereby allow
that compile-time type-checking would protect against all possible
inappropriate function-data applications.
TM-STC> Although static type checking is very helpful in finding
TM-STC> type errors, it cannot replace a careful program design.
TM-STC> Some operations, allowed by the static type system, can
TM-STC> still be wrong because of different measurement units or
TM-STC> other reasons.
If the static type system is sufficiently advanced, such
distinctions *can* be included. Instead of having a type FLOAT, you
have a type FLOAT_FEET or FLOAT_METERS, and funtions that expect a
measurement in feet but get passed a measurement in meters could
generate a compile time type-check error. Are you saying that Seed7
is not capable of having two different FLOAT types, one for feet
and one for meters, and distinguishing them from each other at
compile time? In Java or CL this would be trivial to implement.
(The trick is to make sure the **input** data is of the correct
type, since input data sitting in a disk file or feeding from a
live instrucment is outside the protection of the compile-time
type-checking ability. If the input data explicitly said in
English or other natural language what the units were, that might
help reduce the error rate. For example, an input form for data
entry could pre-load the TextField with "NN feet" with the NN part
selected so that keystrokes will replace it without harming the
"feet" part, so that the user would constantly see "feet" alongside
what he/she was typing and would have to be very very stupid to
enter a reading in meters there and still press the ENTER or
SUBMIT button.)
TM-STC> In the end there are also other possible sources of errors,
TM-STC> such as range violations.
And how will static type checking protect against those, where
runtime intentional-type checking already does? Do you define a
different static type for each possible range of a value, thereby
having thousands of different static types for all the possible
ranges for intermediate results within a lengthy calculation?
float[0..5] x = 4.2;
float[0..25] y = x**2;
float[-12.5..12.5] z = y - 12.5;
float[0..12.5] w = abs(z);
TM> Basing on this arguments, it would be nice to discuss static
TM> type checking.
OK, I'm game, under the rules that if I present a case for runtime
checking of intentional type (for example the weight of a backpack
must be between zero and whatever weight the human is capable of
carrying on his/her back, which varies from person to person, so
effectively for each type of person in regard to weight lifting
capability there's a different type of backpack), you must tell how
the same protection against inappropriate operations can be somehow
accomplished by compile-time type-checking without any runtime
checking whatsoever. So for a starter, how would you propose to
guarantee, by compile-time type-checking *only*, that arithmetic
overflow never happens in a complicated chain of calculations, and
that nobody is ever fitted with a backpack too heavy for that
person.
TM> BTW.: I am still waiting to get an answer for my other mail in
TM> this thread.
This thread is in a newsgroup. No mail is involved here.
I'm going to guess that you mean posted articles, not mail. There
is no practical way for me to check that I haven't missed one of
the articles you posted that you intended me to see. There is no
practical way for you to know whether I missed an article, or I
downloaded it but haven't yet replied because I currently have a
backlog of 38 articles (after this) which I've downloaded but not
yet replied to, except if you ask me. Of those 38, one was written
by you, namely this one:
Message-ID: <cc834369-ea96-4ddd-bf3f-67dfd72b9a39@xxxxxxxxxxxxxxxxxxxxxxxxxxx>
If any other articles you wrote haven't been answered by me when
you believe I should have answered, please e-mail me the list of
such message-IDs so that I can fetch them via Google Groups and see
what each was and why I didn't respond to it.
Meanwhile, if you haven't done so yet, please create a CGI
hello-world example, and also a CGI hello-world-plus-form-decode
example, using Seed7. If you can make such examples work on
cellphones that have mobile InterNet (WAP) enabled, that would be
even better.
.
- Follow-Ups:
- Re: Program compression
- From: thomas . mertes
- Re: Program compression
- Prev by Date: Speculation about Dijkstra's primitives and how small each function should be
- Next by Date: Re: Program compression
- Previous by thread: Re: Program compression
- Next by thread: Re: Program compression
- Index(es):
Loading