[e-lang] TextWriter/__printOn expectations/contract questions

Mark Miller markm at cs.jhu.edu
Fri Mar 4 19:25:10 EST 2005

Kevin Reid wrote:
> I'm thinking about various extensions to the TextWriter protocol. I'd 
> like to hear your opinions on them, and the general issues I mention, 
> particularly as to whether they break reasonable security expectations 
> of the programmer writing __printOn methods.

Not only are these good questions, they are good examples of the kinds of 
issues that differentiate capability discipline from conventional POLA-unaware 
software engineering discipline.

I'll offer some quick reactions; but all these issues bear further discussion.

> 1. Outward privacy
> What can an object participating in printing expect to not be revealed 
> about its components?
> When an object provides a __printOn/1 method
>   def original := [1 => 2].diverge()
>   def readOnlyMap {
>     to __printOn(tw :TextWriter) {
>       tw.print(original, ".readOnly()")
>     }
>   }
> it expects the TextWriter guard to guarantee that 'tw' will not reveal 
> 'original' to its invoker, nor do anything other than printing it.
> But what qualifies as printing? What if, for example, 'tw' produced 
> output like this, creating element separators and showing alleged FQNs?
> __main$readOnlyMap<org.erights.e.elib.tables.FlexMap<"[", 
> org.erights.e.meta.java.math.EInt<"1">, " => ", 
> org.erights.e.meta.java.math.EInt<"2">, "]">, ".readOnly()">

I think showing the element separation should not be considered a violation. I 
think showing the FQNs, perhaps, should. But I don't feel strongly about the 

> Or, less excessively, what if 'tw' arranged to print cycles more 
> informatively, as Common Lisp's printer does? This would reveal some 
> information about sameness.
>   ? def thingy := [def a := [[].diverge(), a], def b := [[].diverge(), b]]
>   # value: [[[].diverge(), ***CYCLE***], [[].diverge(), ***CYCLE***]]
>   ? toQuoteWithCycleTagging(thingy)
>   # value: "[def cycle_1 := [[].diverge(), cycle_1], def cycle_2 := 
> [[].diverge(), cycle_2]]"

I think this would not only be fine, but would be a welcome improvement on the 
current system.

> 2. Inward privacy
> What can an object participating in printing expect to not be revealed 
> *to* its components?
> For example, suppose there was code in multiple (programming) languages 
> operating in the same Vat, and using the same ELib primitive objects. 
> TextWriter could be extended to provide access to an object describing 
> the syntax of the language.
>   def readOnlyMap {
>     to __printOn(tw :TextWriter) {
>       tw.getCodeSyntax().printCall(original, "readOnly", [])
>     }
>   }
>   ? NotE:toQuote readOnlyMap
>   ; value: "{1 = 2}:readOnly"
> This could even replace the specialized subPrintOn interface for ENodes 
> - the 'code syntax' object containing the 'priority' information.

If I understand correctly, this is not revealing information about the 
container to the contained that the container does not choose to reveal. 
Rather, it is allowing information in the TextWriter to be passed through to 
the contained. There is a danger here. But so long as the extra information is 
limited to data and DeepPassByCopy objects, it would seem we already have this 
danger with the TextWriter indent level. We should examine how one might abuse 
such a channel.

These issues remind be of the Throwable issue: Prior to the DarpaBrowser 
review, I thought that the restriction that one could only throw 
DeepPassByCopy data was adequate protection. Perhaps there's the same rude 
surprise lurking here?

> Or human languages (though a low-level object like this is not a 
> particularly good example):
>   ? makeSturdyRef
>   # value: <makeSturdyRef Off The Air>
>   ? interp.setLanguage("jbo")
>   ? makeSturdyRef
>   # value <makeSturdyRef noi ca nai tcana>
> Both of these would involve passing information (tw.getCodeSyntax(), 
> language code, etc) to the objects being printed. However, this allows 
> information to be communicated to objects not otherwise accessible, via 
> printing other objects that wrap them. (I assume the object called 
> tw.getCodeSyntax() would be required to be DeepFrozen, so no authority 
> is involved.)

Yes, we should at least insist on that restriction.

> Would allowing such parameterization break any intended properties of 
> the __printOn/TextWriter interface?
> (The current interface, of course, already reveals some information: the 
> time-ordering of __printOn messages vs. other messages.)

The question is hard to answer, since it depends on programmer psychology. The 
main "intended property" is that the programmer can write useful __printOn 
methods using the standard pattern and the TextWriter guard, and be fairly 
confident, without needing to think about it hard, that they haven't thereby 
blown the normal object-cap security properties that the rest of their program 
may be depending on.

> 3. Extension of output types
> What if the kinds of 'primitive' output (currently String, or rather, 
> stream-of-Characters) were extended? For example, styled text (or 
> markup), or 'printing' an image?
> At some point, it becomes more appropriate to provide a custom visitor 
> interface, but __printOn has the advantage of being universal, so such 
> special 'printing' could pass through preexisting 
> collection/container/proxy/slot/... objects.

I don't see a problem with that, but I haven't really thought about it.

Other opinions?

Text by me above is hereby placed in the public domain


More information about the e-lang mailing list