Dear Mr. Cowan,

Thanks a lot for your thoughtful reading of and reply to my message.  In fact, 
I wondered whether anyone would read it at all..  Of course my notes were never 
meant for anyone but myself.  Let me reply quickly, taking advantage of the 
burst of energy I am experiencing - but please:
- be warned: this is long;
- don't expect me to reply as quickly, or at all, in the general case.


Scripsi:
>> (And I think "Schemest" would then be a one-syllable word.)

Ac respondisti
> introducing novel consonant clusters like /mst/ into it.

Or rather, reviving old ones.  I suppose verb forms such as "thou seemst" were 
pronounced that way.  But your point is taken.  This was not a prescriptive 
remark, but rather a musing - if there were an adjecive on -eme that took the 
gradus, how would its superlative be pronounced.

> (Sorry, but you pushed a button.)

Please don't apologise, I like such information!

====
>> (a micro Scheme might not even KNOW about, say, lower-case letters),

> the day of the PDP-8 and the ASR-33 Teletype is now over.

True, but one never knows what will turn up.  A chip with 2^256 really tiny 
processors?

====
>> * The asymmmetry between multiple inputs and multiple outputs for
>> procedures. (lambda (a b - result rem quot) (quotient+remainder a b -
>> quot rem) (* quot rem - result) (display result -))

> I don't think this is recognizable as Scheme any more,

I agree.  That's why that remark starts with "This is inherent in Scheme 
syntax".  I don't quite remember the context, but there was some discussion 
about dealing with multiple outputs, and in my remarks I tried to find for 
myself how much would be possible within the "feel" of Scheme, where the 
boundary was.

> It's just Prolog in S-expressions.

It was an attempt to decouple the machine and the syntax.  Prolog syntax that 
could drive a Scheme machine.  (The inverse is possible by having a symbol, say 
'$', indicate an output variable.  A Prolog predicate with one $ argument could 
then take the place of the companion variable of that elided output variable, 
as in
  threeappend(A, B, C, Z) :- append(B, C, X), append(A, X, Z). ;; Prolog style
  threeappend(A, B, C, Z) ;- append(A, append(B, C, $), Z) ;; Scheme style
The presence of the $ would also indicate to the compiler that the internal 
append is not a term but a call.

====
>> Barely possible is "splicing in" multiple results

> The idea of using splicing is interesting, though.

So it seems we come to the same conclusion as to where that boundary lies.


>> Maybe symbols should be decoupled from code text

> This can be provided by

My point was more fundamental than applied: I think they possibly ought to be 
decoupled.  Symbols are a combination of two orthogonal ideas, uniqueness and 
name - and I think it is always better to have one construct for one idea.  How 
this decoupling would pay off was the remainder.

>> syntax could be decoupled.

> I don't think, however, that it is ripe for standardization.

Here, too, is the same principle.  If code structure and surface form had never 
been coupled in the Lisp tradition, I am sure we would look down a bit on those 
poor languages that had irrevocably linked two completely different concepts as 
if they were one.  I am not proposing Scheme add more surface forms, just that 
it recognise the two concepts, and standardise one surface form, the current 
one.  Others could then provide other forms, without a standard, or with a 
different standard - that would not be the Scheme standard's business.
(In fact, as far as I am concerned even the standard for the current surface 
form could be moved out of the core into a library, as could the names of the 
procedures, keywords, etc. that the standard defines.  Let the core contain 
exactly that - the core.)

> In general, I'd say this of many of your points:
> they are a manifesto for an implementation, not for standardization,

I did not mean these ones that way.

====
>> This would lead to mutable first-class environments.

> WG1 went down this rathole in its earliest days.

Did it keep the identifiers hygienic too, as I want?  Otherwise you just get a 
mess, of course, when the underlying location of a variable can change or 
disappear.  But there is a subtlety for the garbage collector, because code can 
point to potential locations, the actual instance of which is not garbage 
collectable as long as that code is callable.

(define (test-builder x) ;; Build a location for x
   (do-lots-of-stuff-including-deleting-x) ;; Delete the location, but don't 
garbage collect it.
   (maybe-even-insert-a-new-x-in-the-environment)
   (lambda () x) ) ;; ..because here it is still needed (lexical scoping).


> If you want completely dynamic languages,

Well, I don't, but I want to push the limit as far as I can without losing some 
important properties.  I think part of the Scheme spirit is about removing 
limits without seeing the baby go down the drain.

====
>> Oh, and environments shouldn't be different from other tables,
>> and should have a way to indicate where to find
>> a location that is not locally available.

> Self-modifying code provides immense power,
> but it's practically impossible to reason about,

I know.  While I fondly remember programming my first "while", by rplacd-ing 
the code into one of its own cond-clauses, I am not looking forward to going 
there again.  I do not propose changing the inheritance structure of a closure 
after it has been made - that would break lexical transparency.  But besides 
'lambda', other closure-generating constructs might exist that use other 
inheritance schemes, and such constructs could be codable in Scheme without 
adding indirection or even interpreter levels. 

====
>> A common interface should govern all external resources

> A view of the user that doesn't distinguish them from a file
> is even more restrictive than TTY interaction.

I was thinking in the other direction.  A CD may have immutable data on it, but 
my OS still sees that as files, without therefore imposing immutability on all 
files.  the immutable ones are merely a degenerate case.
Likewise, a file is like the degenerately dumb form of a user.

====
>> Single pass with maximal deferment is the Scheme way: variables inside
>> lambdas don't need to be resolved yet, resolution can be deferred
>> until they are called.

> I think this is a very narrow exception to an essentially static design.

But one that is paramount in the notion of Schemeyness - to me, at least.  (I 
admit being a REPL fan.)  ML requires a letrec for each indirectly recursive 
function, which makes the language feel very different.  That goes well with 
the static typing, but wouldn't go well with Scheme.

>> Without very strong reasons, one should not request different behaviour
>> from syntax transformers. Ease of compilation, or speed of the
>> resulting system are no strong reasons.

> Reasoning about code,
> including your own code a month after you wrote it,
> is a very strong reason.

I think code that can be read roughly linearly is easier to understand.  
Multi-pass means you can't understand your code on your first reading - if you 
could, so could the compiler.

====
>> A rewriter can be written in Scheme and then used in macro expansion -
>> great, but let the rewriter then be generally available (because it
>> has other possible uses),

> I agree, and have added this idea to WG2's input hopper
> to be voted on when WG2 reconvenes.

Thanks.  Or you you mean you already had done that independent of my mail? 
(Even then, thanks, of course.)

>> and be optional in writing syntax (because there are other ways
>> that sometimes may be better).

> I happen to think that going beyond `syntax-rules` is a mistake,

I definitely don't want another CL macro system, but I also think syntax-rules 
was a mistake.  Not bad in itself, but definitely not Scheme, so suddenly we 
had several constructs with restrictions on them - contrary to the Clinger 
manifest.
But more importantly, I think the language shouldn't prescribe how I write my 
macros, even if what it prescribes is the best way, as long as my way doesn't 
break important properties without me realising.  I know I break functionalness 
when I use a feature initially bound to a symbol with a name ending in an 
exclamation mark - but Scheme will let me do it anyway, having warned me.
If being able to break the properties has bad consequences for programs that 
don't - say compilation becomes impossible - then a reverse warning may be 
necessary: me flagging the system that I break the properties.  Without that 
warning the compiler can then do its efficient thing, and if I lied, shame on 
me.

>> Something else is lost here. Scheme was about the right thing,
>> but also about the minimal thing.

> there is nothing tiny or jewel-like about
> Scheme's standard procedure library, and never has been.

I think there is something t&j about it, at least.  Lisp didn't start out that 
way, of course - it had dynamic scoping, for one thing, and PROG with labels..  
Heck, even 'lambda' came from a mis-typeset caret!  But Scheme has been about 
cleaning up, and approaching an ideal.  When the equivalence of actors and 
procedures was discovered, it was at least recognised as something worth 
preserving.  Call/cc is a procedure because it could be done that way, and it 
was tinier.  CL is more about grudgingly accepting the things Scheme had proven 
to be strong concepts and incorporating them into their ball of mud.

My hope was, and is again (it was lost during the R6RS debacle) that Scheme can 
remain a language striving in that direction - we already have enough languages 
striving in other directions.  I wish the Clinger manifest would be 
procedurally implemented in the sense that having more concepts, or having 
restrictions on concepts, would require a strong justification in a companion 
document to the standard - even if these things were taken over from previous 
standards.

> It has been patched together over time
> from a subset of what MacLisp provided.

I know, she started skinny and with acne all over her face - but she may grow 
up to be a beauty.  I may be wrong in many of the things I propose - wrong in 
the sense that adopting those would make Scheme less ideal - but at least I 
hope this vision is shared for small Scheme, and I'll gladly be shown wrong 
where I am wrong if that means Scheme will be more pristine!

> What is more, it's not clear that
> standardizing a facade
> and not its underlying layers
> is the Right Thing.

I am not sure what you are referring to here.  Which façade and which 
underlying layers do you distinguish in my text?

> WG2 will standardize TCP library routines, but ..
> The `error` procedure in R7RS may ..

I like such restraint, but miss the connection with the previous bit - which is 
not so strange, as I didn't understand that bit.

>> Having explicit mutable locations ..

*> cells would have been better than mutable variables,

> how much of Scheme's fundamentals are
> based on sheer contingency.

Agreed.  But I see it as a goal to remove such warts bit by bit and clean up 
the language.  Nowadays it is perfectly feasible to build a cell layer 
underneath the language, lambda's compiling into cell-layer code that happens 
to assign mutable cells to all variables.  A fraction more compilation time, 
the same resulting code, but the option to code directly in the cell layer and 
get more efficient code with less possibility of error.

Let's (disregarding my earlier remarks concerning case sensitivity) assume that 
'lambda' builds closures using mutable cells with the behaviour we have come to 
expect, and 'Lambda' builds closures with immutable variables.  Likewise 
let/Let, et cetera.  It is trivial to define the lower case versions in terms 
of the upper case ones, so this is hardly a burden on the spec, and the lower 
case ones can be in a library.
The upper case ones are cleaner, requiring a smaller spec (e.g. set! becomes a 
procedure, set-car! and its ilk are no longer needed, (set! (car ..)) 
sufficing), so this is clearly a language clean-up that doesn't break existing 
programs but removes a restriction.  Fewer concepts + fewer restrictions --> 
Clinger-proof.  Clinger-proof + leading to faster code --> a Good Thing.

>> And other locations, such as the car and cdr of a pair, already excape,

> Well, why not provide both escaping and non-escaping locations?

Because (1) it is an extra concept with an extra restriction; (2) People 
routinely build structures around them that can escape in their entirety, which 
is more code, slower and more bug-prone; and (3) they only escape if you make 
them do so anyway.

>> some kind of locking will be necessary.
>> I think locations are the natural place for that:

> a single location is far too fine-grained for comprehensibility.
> Programmers are only human.

But compilers aren't.  The presence of locations doesn't preclude any of the 
existing approaches, but it allows a low-level approach by the compiler.  After 
all, it is the compiler that will write most parallel code, not the programmer. 
 Wherever (in-)variables are immutable, the compiler can parallise to its CPU's 
content, but when locations pop up that is a warning sign.  Whenever it can 
prove that no clash occurs, it can still write parallel code, and where it 
cannot prove it it can impose a locking mechanism (with priority to avoid 
deadlock: in case of doubt, evaluate left-to-right or whatever).  Whenever the 
programmer knows better, she can use higher-level constructs and relieve the 
compiler of its responsibilities.

>> Just reading or writing is no problem,
>> but writing a value that is computed from a read is.

> Alas, knowing whether a value to be written
> is computed from a value read is Turing-complete.

I know - that's why the 'whenevers' are in my previous paragraph.

>> the value of load would then be
>> the value of the last expression in the file loaded.

> it can't now be standardized.

May I ask why?

====
>> * Write/read invariance.

> across arbitrary Schemes
> running on arbitrarily different machines

I didn't mean that - even though I see fewer problems than you do (the code 
written/read could even be some flagged s-expression containing the required 
information, and every Scheme could interpret this in its own way - the way I 
can share a vector between systems).  I was rather thinking about e.g. dumping 
and reloading in a later session of the same Scheme (as in game 
saving/restoring), or of process sharing between running copies of the same 
Scheme.

> That serves some people's purposes,
> but definitely not everybody's.

It could be an optional feature.  I wrote many of these things before thinking 
in terms of small and large Scheme.

====
>> The principle of least surprise is already violated with macros. Macros
>> must be bound before use; there is no equivalent to anonymous lambdas.

> What's the point of that?

Have you never wanted to parametrise over, say, 'and' and 'or' without losing 
the short-circuit evaluation?  Of course, one can create higher-order functions 
around those macros and wrapping the arguments in chunks, but that is 
cumbersome, slow and ugly.  And that is only a very simple example.

Scheme currently suffers from macroitis: once something becomes a macro, other 
things may get infected.  Imagine Scheme only provided 2-argument logical 
macros, and I want to write a function that takes one of them and returns an 
arbitrary-arity version - a fold.  I am strongly pushed towards writing not a 
function, but a macro for that - possibly besides a fold function that folds 
functions.  Duplicating functionality (and wildly diverging code because one is 
in a rule language and the other in, well, Scheme) because some restriction was 
imposed on macros.

> If the rewrite rules stand next to the original code,

Ah, but normally they wouldn't - just as anonymous lambda's tend not to stand 
near the definition of a function that applies them, but near a call of that 
function.

====
>> Flushing an output port is the symmetric opposite
>> of peeking at an input port - or it ought to be.
>> Scheme could have a clean mathematical notion of ports

> There's an interesting idea,
> but I don't know what to do with it either.

I have lots of little bits of idea, but they don't build up to some whole yet.

====
>> * Time. Time is an elusive concept.

> What you describe here (snipped)
> is an interesting idea, but by no means core,
> to say nothing of jewel-like.

I basically meant to say: there is so much going on, let's just allow the user 
to define notions of time and how they relate, and allow for the fact that 
different notions may not be mappable (especially concerning the future, but 
also concerning much of the past).

I didn't even mention that most of the individual systems aren't even properly 
cyclic and dependent on future contingencies.  If we decide something will 
happen exactly five years from now, and a black hole passes at short distance 
of the sun and pulls it away from us - when is the instant we had decided on?  
If we had decided on a span of five Muslim years and the black hole reversed 
the rotation direction of the moon, would that time never appear, but instead 
previous years be doubled?

> WG2 will have a date-time library
> that may owe something to these notions.

Thanks again.

====
>> Wouldn't a Schemish string be a sequence of character objects (soco),

> the IEEE restriction

Ah.  I didn't know there was such a thing.

> R7RS-small has classical strings,
> but allows implementations ..

Any chance of them allowing the user to build strings (without her building an 
interpreter for them, obviously)?

Well, I suppose by now you are very sorry you answered me..

Thanks again!
Biep.


_______________________________________________
Scheme-reports mailing list
[email protected]
http://lists.scheme-reports.org/cgi-bin/mailman/listinfo/scheme-reports

Reply via email to