[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

some questions

    Date: Sun, 17 Jul 83 18:53:23 PDT

    	How is one supposed to read the debug stack printed out by the
    	inspector? What do the numbers on the left mean? What do some
    	of the wierd values mean? Is there anything written about this?

Nothing written.  The numbers on the left are a menu; you can crawl
object [n] by giving "n" as a debug command.  (Actually they are
structure indices, which can be passed to a system internal accessor
procedure.)  DEBUG and CRAWL are exactly the same program, it's just
that the prompt is "debug" if the current object is a stack frame.  The
objects are the objects internal to that stack frame, as determined by
TC; TC being an optimizing compiler, these are often pretty random

debug: x
 [2] (A B C)
 [3] #{Procedure BAR}
debug: 3
#{Procedure BAR}
crawl: w

    	What is the Z system that one sometimes lands up in?

The Z system is an independent read-eval-print loop which is entered if
for some reason the system thinks that the normal one won't work,
e.g. in the middle of a GC, or when reporting the fact that reporting
an error caused an error causes an error.

    	Is there some way of storing lisp trees or other data in their
    	parsed (internal) form on disk files? ...

This would be very nice, would not be too difficult, and is planned, but
no such feature exists yet besides TC (one can put a single form '(A B
...) in a file, compile the file, and the value returned by LOADing the
file will be the (A B ...)), which is not tuned for this kind of use -
loading object files is quite fast, but generating them is quite slow.

    	Is LSET only used to declare variables in a locale?
Yes.  It is legal but pointless to use it on lambda-bound variables.

    	Why are LSET and DEFINE different? Couldn't both functions be
    	provided by one of them?

Two differences: (a) error checking, (b) optimization.  Setting a
defined variable, or vice versa, or redefining a defined variable, are
error situations, and generate warning messages.  Setting an variable
bound with LSET is fine.  Also, if TC sees that a variable FOO has been
defined, it assumes that its value won't be set, which makes its code
passability predicate more liberal.  E.g. the expressions FOO and (BAR)
can be evaluated in either order if FOO has been defined; if it isn't
known to be defined then the call to BAR might change its value.

    	I'm not sure if this makes any sense, but ... What sort of memory
    	allocation goes on in a LET? Is it static or dynamic? I guess I am
    	asking for some sort of memory model of what is going on in contours.

EVAL does one cons per lexical variable bound by a LAMBDA (into which
LET expands); so all environments are heap-allocated.  This is not
optimimal, and is likely to be improved in the future, but it's simple.
TC is smarter, and only generates code which conses when it sees that
general closures need to have heap-allocated environments.  Otherwise
variables are kept in registers or on the stack.

    	What is the difference between
    		(HERALD X)
    		(REQUIRE FILE1 "file1")
    		(REQUIRE FILE2 "file2")

ENV and REQUIRE are ungerneral kludges.  REQUIRE is sort of like
load-into-current-environment-if-not-already-loaded, and TC knows
nothing about it.  ENV is a directive to TC only, and tells TC
to obtain "support files", which contain early binding information
(define-integrable's and define-constant's).  Currently support files
contain macro definitions also, but this will change.

    	Do the dependencies of REQUIRE's have to be tree-structures? or can
    	they be circular?
Circularities currently lose.

    	What are the differences between LOAD, REQUIRE, and INCLUDE?
    	Is the following satisfactory? or is there something more?
    	... LOAD and INCLUDE always load the file in, REQUIRE checks to see
    	if the file has already been loaded and refrains from doing so a
    	second time. LOAD is used to load in a file into the interpreter,
    	whereas INCLUDE is used in the compiler. ...

This is mostly correct.  See above.  LOAD is a procedure which takes an
optional environment argument, defaulting to (REPL-ENV).  REQUIRE is a
special form which picks up on the current environment.  (Environments
are becoming increasingly serious.)  There is no INCLUDE.  There
probably ought to be.

    	How does one handle class hierarchies (i.e. inheritance)? Can you
    	give a simple example? or point me to one?
The right thing to do is to use JOIN, but JOIN doesn't exist yet.
Currently you can do a sort of limited inheritance using => and
HANDLER, which will go away when JOIN arrives.  I think there are
some instances of this in the T sources; try looking at "streams.t",
"env.t", and "eval.t".

    	Can you define operations on structures? You mentioned in a message
    	to one of the lists that it was possible, but involved the use of
    	unreleased functions. Is this still true?

Still true.  Another unsolved problem.  Tell me if the previous
explanation was unsatisfactory.

    	Why are there three different equality predicates?
    	Is it only because of efficiency?

Sort of.  EQ?, EQUIV?, and = are defined to take constant time (except
for bignums...), whereas ALIKE? does a tree-traversal, which may not
even terminate if the structures involved are circular.  EQUIV? would be
the ideal object identity test but it is too difficult to implement
efficiently, so EQ? is available to do the obvious pointer comparison,
which is what you want most of the time anyhow.

    	Is eq? defined on numbers? - the manual seems to be vague about this.

Intentionally vague.  I'm ambivalent about this.  It at least produces
some true/false result, if not a determinate one in the case of certain
EQUIV objects.  We want to allow for possible future BIBOP
implementations of T, and this necessitates some strangeness.
But it would be very nice if at least integers in some range were defined
to be EQ? to themselves.

    	(READ SO) ; reading from standard output!!
    	gives a very incomprehensible error message.


    	The manual mentions that the use of EVAL should be avoided.
    	Is there a way to accomplish the following without recourse to EVAL
    	or ENV-LOOKUP?
    	(LSET a 5)
    	(LSET B 'A)
    	Now, I want to get at the value of the object that is the value of B.
    	i.e. this is like symbolic indirection.

Why would you want to do this in the first place?  There's probably a way
to do what you want to do without resorting to this kind of thing.

However, one could do (CONTENTS (ENV-LOOKUP environment B NIL NIL))
using ENV-LOOKUP and CONTENTS as described in the current manual.
Version 2.7 might have a more concise notation for this.

    	We would like to embed our user-language in T. It would be basically
    	T syntax augmented by some readmacros. However, we would like it to
    	be case-sensitive. I looked at the code for the reader and found that
    	changing the definition of *TRANSLATE-CONSTITUENT* seems to work.
    	However, the the standard T functions (SET, CAR, etc) are still
    	uppercase and we would prefer for them to be lowercase. Is there
    	some way around this?

It's very difficult to engineer this well.  It would be fairly easy to
kludge.  If you want a lower-case-oriented case-insensitive system,
that's even easier to kludge in the current system.  (There's another
variable *TRANSLATE-CONTITUENT-INVERSE* which the printer uses.)  We've
been considering changing T's orientation to lower case, but this would
be Common Lisp incompatible.