[e-lang] IRC log (was Why support var patterns ...)

Kevin Reid kpreid at mac.com
Thu Sep 28 11:32:05 CDT 2006


On Sep 27, 2006, at 22:19, Dean Tribble wrote:

> I'm currently getting the E-on-Squeak up to the current model, and  
> am working on the ObjectExpr piece (well, last weekend).   
> ObjectExprs now have a pattern as their name in the parse grammars  
> instead of generating FQDN strings (yay).  In 0.8.37, it can be a  
> def pattern or a var pattern (but not a bind pattern).  I was  
> wondering why the pattern is allowed to be anything other than a  
> def pattern.  Said differently,  why is it interesting to support:
>
> var x {
>    to zot() :any { return x }
> }
>
> In kernel (or even in full-E)?

This was discussed on IRC yesterday (along with many other E-related  
things)

<http://meme.b9.com/cview.html?channel=erights&date=060928>

I include the log here for the archives and those who weren't there.  
The section related to var patterns starts at 05:17:06.


02:11:59 <CIA-2> kpreid * r639 cl-e/ (. clrune iclrune lisp/ 
knot.lisp lisp/rune.lisp):
02:11:59 <CIA-2> Image-based startup. If you use the 'iclrune'  
script, E-on-CL is loaded once and a memory image is saved, (if the  
Lisp implementation supports this), which will be used for future  
runs. Currently only the Lisp code is
02:11:59 <CIA-2> saved in the image (no emakers nor initial vat  
structure). Tested on SBCL and OpenMCL.
02:28:20 --- quit: zooko (Read error: 110 (Connection timed out))
02:30:43 --- quit: eel (Remote closed the connection)
02:30:59 --- join: zooko (n=user at 209.97.232.45) joined #erights
02:31:43 --- join: eel (n=PircBot at 24-52-49-37.bflony.adelphia.net)  
joined #erights
02:42:01 <kpreid> dtribble_: ping
02:49:32 <dtribble_> hi.
02:51:10 <kpreid> so, my big accomplishment of the moment can be seen  
above
02:51:48 <dtribble_> oooh. image-based start-up!
02:52:29 <kpreid> it seems to be solid, but not wonderful
02:52:33 <dtribble_> how do I deermine what failed in my test run of  
eon-cl?
02:52:45 <dtribble_> how so?
02:52:46 <kpreid> since emaker loading and initial object graphs  
still happens post-image
02:52:53 <kpreid> so there's lots of initialization left
02:53:08 <dtribble_> ah
02:53:10 <kpreid> but ./iclrune --lisptest is pleasingly quick
02:53:25 <kpreid> what failed? well, what was the final complaint?
02:53:28 <dtribble_> should I run that?
02:53:51 <dtribble_> or a new self-test first?
02:54:24 <kpreid> erm, what?
02:54:49 <kpreid> if you already have a problem, the image-based  
system is highly unlikely to have anything to do with it
02:55:41 <dtribble_> I got an end result (after completion, I think)  
or 43 out of 2885 tests failed. Darn good!
02:55:51 <dtribble_> I was wondering if there's a summary of the  
failed tests written anywhere
02:56:10 <dtribble_> it then dumped into the debugger
02:56:11 <kpreid> no
02:56:20 <kpreid> you are expected to have a sufficiently long  
terminal scrollback
02:56:26 <dtribble_> heh
02:57:08 * dtribble_ looks for terminal options
02:57:55 <kpreid> I've made a little bit of progress with modules
02:57:57 * dtribble_ found it....
02:57:59 <dtribble_> yes?
02:58:11 <kpreid> it's roughly "think for two days, write a bit of  
code, repeat"
02:58:22 <dtribble_> that soundsabout right.
02:58:34 <kpreid> but I have emakers and resources supported
02:58:43 <kpreid> no dependencies, no cycles in emaker loading yet
02:59:15 <dtribble_> do you have a write-up on the model?
02:59:27 <kpreid> no, the model doesn't exist yet!
02:59:35 <kpreid> but there will be a test+doc file
02:59:36 <dtribble_> :)
03:00:13 <kpreid> oh, actually: http://www.slimy.com/~kpreid/darcs/e- 
modules/doc/usage.updoc
03:00:15 <dtribble_> that's what I meant...
03:00:22 <kpreid> very quarter-baked...
03:00:45 <dtribble_> I have a follow-up question on the objectExpr  
changes.
03:01:55 <kpreid> yes?
03:02:22 <dtribble_> As I writ ethe question, the answer keeps  
looking obvious so I'm trying to write the real question.
03:02:54 <dtribble_> Basically I'm trying to figure out the rewriting  
and rules surrounding the pattern of an objectExpr.
03:03:24 <dtribble_> This is complicated more by how my code used to  
rely on it always being a string than by the actual semantic model
03:03:38 <dtribble_> s I'm confused but that hasn't quite translated  
into a question.
03:04:16 <dtribble_> Essentially, the objectExpr scope contains  
references as defined by the patterns, and those same references are  
available afterwards (for the remainder of the containing scope).  
Correct?
03:04:49 <kpreid> yes
03:05:23 <dtribble_> as you can cimagine, the objectExpr processing  
is the most omplcicated piece of the slang compiler.
03:05:36 <kpreid> it's OK if those bindings are implemented  
differently, but the side effects must happen only once
03:05:40 <dtribble_> mostly around wiring scopes correctly.
03:05:45 <kpreid> ('bind' patterns are a side effect)
03:05:51 <dtribble_> say more...
03:06:27 <kpreid> well, that only makes sense given my own thoughts  
on implementing it in e-on-cl, so never mind
03:06:51 <dtribble_> OK.
03:07:03 <kpreid> hrm.
03:07:09 <kpreid> scratch that:
03:07:17 <kpreid> ? e`bind x {}`
03:07:17 <kpreid> # value: e`def via (__bind.run(x__Resolver)) _ :=  
def _ {
03:07:17 <kpreid> # }`
03:07:28 <dtribble_> It seems to me that the implementation can  
always translate into defining the slot, creatin the object, and then  
assigning to the slot.
03:07:48 <kpreid> uh. that works, actually, but it's a bad  
implementation, because the QN gets lost
03:08:06 <kpreid> def via (__bind.run(x__Resolver) _ := { def x  
{ ... } } should be OK
03:08:30 <kpreid> dtribble_: well, 'var' is trickier
03:08:57 <kpreid> oh, it isn't
03:09:09 <kpreid> EoJ at least rejects circular var
03:09:19 <kpreid> ? var x() :any { return x }
03:09:20 <kpreid> # syntax error: Circular 'var' definition not  
allowed: ["x"]
03:09:21 <eel> # syntax error: Circular 'var' definition not allowed:  
["x"]
03:09:40 <dtribble_> interesting. if that's the case, why bother  
supporting anything but def?
03:09:42 <kpreid> (all of these examples are from 0.8.36t)
03:10:02 <dtribble_> form 37:
03:10:03 <dtribble_> ? var x() :any { return x }
03:10:03 <dtribble_> # value: <x>
03:10:03 <eel> # syntax error: Circular 'var' definition not allowed:  
["x"]
03:10:17 <dtribble_> from 0.8.37a
03:10:18 <kpreid> oh, okay
03:10:43 <dtribble_> it's not clearto me why supporting var in that  
context is interesting.
03:10:45 <kpreid> hrm, this apparently *isn't* the verson I thought  
it was
03:10:51 <dtribble_> are there good examples?
03:10:58 <kpreid> ? e`var x {}`
03:10:58 <kpreid> # value: e`def var x := def "$x__C" {
03:10:58 <kpreid> # }`
03:11:29 <dtribble_> I get:
03:11:30 <dtribble_> # value: e`def var x {
03:11:30 <dtribble_> # }`
03:11:30 <kpreid> I thought 36t had the object-expr change, but I was  
wrong
03:11:51 <dtribble_> but I get the same expansion as you for bind
03:12:02 <kpreid> what do you get for 'bind x {}'?
03:12:13 <dtribble_> # value: e`def via (__bind.run(x__Resolver))  
_ := def _ {
03:12:13 <dtribble_> # }`
03:12:52 <kpreid> OK
03:13:04 <dtribble_> so that suggests I'll only see def and var  
patters in objectExprs.
03:13:13 <dtribble_> oh. I guss it could have a guard..
03:13:18 <kpreid> no
03:13:24 <kpreid> guards are specifically not allowed
03:13:36 <dtribble_> I see.
03:13:49 <dtribble_> so just def and var...
03:13:57 <dtribble_> again, why var?
03:14:06 <kpreid> dunno!
03:14:19 <dtribble_> composing message to list :)
03:14:31 * kpreid cheers dtribble_ on
03:14:38 <kpreid> messages to list good
03:16:54 <dtribble_> yes
03:17:23 <dtribble_> I transition jobs within Microsoft next week,  
which will at least return to me the part of my brain that has been  
caught up in intereviewing internally.
03:19:26 <dtribble_> sent
03:20:07 <dtribble_> in compiling sockets.updo, my cle can't find  
org.erights.e.elib.slot.near
03:20:47 <kpreid> (updoc files aren't compiled)
03:21:01 <kpreid> that means that it couldn't find your E-on-Java  
emakers
03:21:13 <kpreid> what version of sbcl are you using?
03:21:33 <dtribble_> the most recent package. how do I determine  
version?
03:21:48 <dtribble_> 0.9.8
03:22:43 <kpreid> (lisp-implementation-version)
03:22:48 <kpreid> hrm
03:23:06 <kpreid> anyway, there's a bug (which was fixed in 0.9.16)  
which prevents it from reading from the jar
03:23:28 <dtribble_> ah
03:23:29 <kpreid> so it'll try to use source instead
03:23:39 <dtribble_> I'll see about gettign a later release
03:23:47 <kpreid> it has a (I now know) silly rule for finding the  
source: it looks in $EHOME/src/
03:24:13 <kpreid> er, $EHOME/src/esrc/
03:25:00 <dtribble_> I must stop for a while and take more drugs.  
Shall I attempt to return later?
03:25:33 <dtribble_> markm expects to be available later as well, but  
I don't know how late
03:26:01 <dtribble_> (btw this was not a planned visit to the  
dentist :P)
03:27:06 <kpreid> erf
03:27:26 <kpreid> I can, but I don't want to stay up unless I know  
there's reason
03:27:35 <kpreid> I'd rather try to continue tomorrow, say
03:34:56 <kpreid> dtribble_: a point: FQDN is fully-qualified  
*domain* name, which is about domains.
03:35:42 <kpreid> E's thing is FQNs, fully-qualified names, which  
happen to often *incorporate* reversed FQDNs, but are otherwise  
unrelated
03:45:39 --- join: markm_  
(n=markm at ppp-68-120-198-222.dsl.pltn13.pacbell.net) joined #erights
03:59:35 <kpreid> markm_: http://cia.navi.cx/stats/project/e-on-cl
04:03:11 <kpreid> markm_: http://www.slimy.com/~kpreid/darcs/e-modules/
04:04:49 <kpreid> markm_: skype just dropped
04:05:52 <markm_> I'm calling you back now
04:06:09 <markm_> Skype says you're offline
04:06:11 <kpreid> I was in the middle of restarting skype; try again
04:07:02 <kpreid> anyway, module..eterm is deliberate: the working  
idea was that it's a name that can't be part of the content of a module
04:21:57 <markm_> http://scheme2006.cs.uchicago.edu/15-barzilay.pdf
04:24:33 <kpreid> http://eternity.iu.hio.no/promises.php
04:30:56 <markm_> you dropped again
04:45:32 --- quit: idnar (Nick collision from services.)
04:45:36 --- join: idnar_ (i=mithrand at unaffiliated/idnar) joined  
#erights
05:02:44 <markm_> http://scheme2006.cs.uchicago.edu/04-matthews.pdf
05:13:09 <CIA-2> 03kpreid * r640 10cl-e/iclrune: Remove  
accidentally included hardcoding of OpenMCL in the image generation  
command.
05:13:23 * dtribble_ waves
05:13:32 <markm_> hi dean
05:13:56 <dtribble_> hi.
05:17:06 <dtribble_> did you see my email asking why are we  
supporting "var foo {}"?
05:17:31 <markm_> I saw that it was there, but haven't read it yet.
05:17:38 <markm_> Kevin & I talked about it
05:17:42 <dtribble_> it's short...
05:17:49 <dtribble_> oh good. and the answer is?
05:17:53 <kpreid> whoops, there goes Skype again!
05:18:44 <markm_> I just read it
05:19:27 <markm_> My stance is: If there's no compelling reason to  
keep it or get rid of it...
05:20:05 <markm_> ...then it's better to keep it since it would make  
the language spec more irregular to disallow it
05:20:30 <markm_> OTOH, if there is a good reason to get rid of it,  
we could with no great loss
05:20:49 <markm_> Do you see a problem with it?
05:21:07 <dtribble_> implementing it is a pain with no discerniable  
value. It precludes some simple implementations or objects.
05:21:41 <markm_> Say more? How would you implement if it wasn't there?
05:21:42 <dtribble_> the complication it adds is not supported by its  
value. I don't see how it makes anything irregular. we don't allow  
bind in that position
05:21:53 <markm_> Yes we do
05:22:02 <dtribble_> references t self would bbecome self references,  
rather than sometimes being an indirection.
05:22:15 <dtribble_> bind in that position is currenly rewritten away
05:22:35 <dtribble_> e`bind x {}`
05:22:35 <dtribble_> # value: e`def via (__bind.run(x__Resolver))  
_ := def _ {
05:22:35 <dtribble_> # }`
05:22:39 <markm_> bind doesn't exist in Kernel-E, only E
05:22:47 <kpreid> sorry, it == var as object name
05:22:49 <kpreid> if it didn't exist, you'd write def initialFoo {};  
var foo := initialFoo
05:23:21 <kpreid> I actually can't imagine a sensible use for the  
semantics of referring to the current value of the var within the object
05:24:24 <dtribble_> are there other places we don't allow var?
05:24:40 <markm_> var doOnce() { ...; doOnce := def _(){} }
05:24:59 <kpreid> oy, that's a decent use case.
05:25:02 <kpreid> s/oy/okay/
05:25:29 <dtribble_> It's sufficiently infrequent that the more  
obvious solution is better:var doOnce() { ...; doOnce := def _(){}
05:25:33 <dtribble_> oops
05:25:49 <dtribble_> var doOnce= def _() { ...; doOnce := def _(){}
05:25:54 <dtribble_> oops
05:26:00 <dtribble_> var doOnce := def _() { ...; doOnce := def _(){}
05:27:24 <dtribble_> this is linked to last week's conversation about  
bind and promises that break when accessed if no resolved.
05:27:26 <kpreid> that will necessarily fail
05:27:53 <dtribble_> why?
05:28:07 <markm_> Your "var doOnce := def _() { ...; doOnce := def _() 
{}" is fine...
05:28:21 <kpreid> because it's a circular define with var, and  
circular define doesn't (shouldn't) know about object-exprs in  
particular
05:28:34 <kpreid> and "var x := [x]" is Bad
05:28:41 <markm_> ...and I'd be happy to have that be the only way,  
if we get rid of var-based ObjectExprs
05:29:37 <markm_> OOPS: That code would be rejected, because it's a  
circular *data* definition of a var
05:30:02 <markm_> That code being "var doOnce := def _() { ...;  
doOnce := def _(){}"
05:30:24 <dtribble_> e`var doOnce := def _() :any {doOnce := thunk{};  
x}`
05:30:25 <dtribble_> # syntax error: Circular 'var' definition not  
allowed: ["doOnce"]
05:30:41 <markm_> Yup.
05:31:27 <markm_> So, I'd no longer be as happy to get rid of var- 
based ObjectExprs. Interesting
05:31:41 <dtribble_> var doOnce :=null
05:32:36 <dtribble_> ? var doOnce :=null
05:32:36 <dtribble_> ? doOnce := thunk{doOnce := thunk{}; x}
05:32:36 <dtribble_> # value: <_>
05:32:36 <dtribble_> ? doOnce()
05:32:37 <dtribble_> # value: <x>
05:32:41 <dtribble_> ? doOnce()
05:32:43 <dtribble_> ?
05:32:43 <eel> # problem: Failed: Undefined variable: x
05:32:44 <eel> # problem: <NoSuchMethodException: <null>.run/0>
05:32:45 <eel> # problem: <NoSuchMethodException: <null>.run/0>
05:33:08 <kpreid> I think I remember writing that code a time or two
05:33:21 <markm_> Yeah, you could still get the effect. You're right,  
it'd be fine, if there's a reason to get rid of var-based ObjectExprs.
05:33:26 <dtribble_> it takes two lines. I thnk it's rare enough and  
strange enough that that's OK :) I note that it's not a god  
abstraction because the client of doOnce should not be able to assign  
it, so you'd really want a different approach anyway.
05:34:19 <markm_> But I still don't see a good reason to kill it, and  
a small reason (less irregularity) to keep it
05:34:31 <kpreid> oh, this reminds me of an idea I had:
05:34:42 <dtribble_> you generally want a spcial case in any  
implementation for references to self.
05:35:04 <dtribble_> var can't fit ithin that case, you get multiple  
representations, implementations, and code paths if you have a var  
reference.
05:35:22 <kpreid> ? def varToMutable(&current) { return def _ match  
msg { E.callWithPair(current, msg) } }
05:35:22 <eel> # value: <varToMutable>
05:35:32 <kpreid> ? var x := 1
05:35:32 <eel> # value: 1
05:35:42 <kpreid> ? def y := varToMutable(&x)
05:35:43 <eel> # value: 1
05:35:48 <kpreid> ? x += 1
05:35:49 <eel> # value: 2
05:35:51 <kpreid> ? y
05:35:51 <eel> # value: 2
05:36:24 <dtribble_> cute.
05:36:28 <dtribble_> evil, but cute.
05:36:35 <kpreid> ? def mutableToVar(object) { return def slot { to  
getValue() { return object.snapshot() } } } # less flexible
05:36:36 <eel> # value: <mutableToVar>
05:37:00 <kpreid> ? def l := [].diverge()
05:37:00 <eel> # value: [].diverge()
05:37:05 <kpreid> ? def &m := mutableToVar(l)
05:37:05 <eel> # value: <slot>
05:37:09 <kpreid> ? m
05:37:10 <eel> # value: []
05:37:14 <kpreid> ? l.push(1)
05:37:18 <kpreid> ? m
05:37:18 <eel> # value: [1]
05:37:26 <kpreid> -end-
05:37:41 <dtribble_> m isn't really a var, but a def, right? you  
can't assign it.
05:37:53 <dtribble_> ?m := [3]
05:37:54 <eel> # problem: <NoSuchMethodException: <a slot>.setValue/1>
05:37:56 <kpreid> well, it's read-only
05:38:09 <kpreid> you can make it mutable if the mutable object has a  
'replace contents' operation
05:38:16 <dtribble_> that's what I mean by not a var (I'm not  
complaining, just clarifying)
05:38:31 <kpreid> e.g. to setValue(new) { map.removeAll(); map.putAll 
(new) }
05:38:45 <dtribble_> that was an interesting way of getting a  
variable which is a view on a changing object.
05:39:26 <kpreid> particularly note that mutableToVar is not general,  
whereas varToMutable is
05:39:37 <dtribble_> yes.
05:39:50 <markm_> mutableToVar and varToMutable are not really  
related, are they?
05:39:54 <dtribble_> did you have a usage in mind?
05:40:00 <kpreid> dtribble_: no
05:40:11 <kpreid> markm_: they are related in that I thought of them  
at the same time :)
05:40:30 <markm_> oy^h^hokay
05:41:01 <dtribble_> :)
05:41:49 <markm_> I like mutableToVar.
05:42:00 <kpreid> here's a question:
05:42:27 <kpreid> what dynamic single-dispatch VMs (that run on  
reasonable OSes, are fast, etc) exist?
05:42:37 <kpreid> oh, and with garbage collection :)
05:42:49 <dtribble_> define "fast"
05:42:53 <kpreid> :-)
05:42:56 <dtribble_> does squeak wualify?
05:42:57 <markm_> It makes me want to translate "x += y" to  
(&x).update("add", [y])
05:43:09 <dtribble_> ew
05:43:13 <kpreid> squeak qualifies
05:43:23 <dtribble_> then "squeak" :)
05:43:45 <kpreid> dtribble: how does (&x).update(fn v { v + y })  
compare?
05:43:45 <dtribble_> if this is filtering for E, then bignums are  
important.
05:44:12 <markm_> so that mutable collections can update in place,  
but still provide the semantics of a var holding a const collection
05:44:15 <dtribble_> I'm not sure what context to evaluate the  
question in
05:44:20 <kpreid> Strongtalk and Self are both imaginable candidates,  
yes?
05:44:39 <kpreid> Objective-C/Cocoa would be if it had GC (which it  
is said it will in the next release)
05:44:41 <dtribble_> I'd dicount Self just because of memory footprint
05:44:50 <kpreid> OK
05:44:59 <dtribble_> there's likely some prolog runtimes.
05:45:11 <kpreid> Common Lisp, Scheme lack object-single-dispatch
05:45:12 <dtribble_> there's a few comercial smalltalk engines.
05:45:23 <dtribble_> what do you mean object-single-dispatch?
05:45:28 <markm_> "(&x).update(fn v { v + y })" wouldn't allow the  
flex-collection-as-var to update in place
05:45:37 <kpreid> markm_: oh, I see
05:46:12 <kpreid> dtribble_: CL has only multiple dispatch (and with  
redefinition and metafanciness), which makes it slower than otherwise
05:46:36 <kpreid> Scheme has no dispatch other than function calls,  
which are fine if you're willing to box all your numbers
05:46:50 <dtribble_> CommonLOS has multiple dispatch. As I recall,  
one can perfectly well opencode single dipatch in CL itself.
05:46:52 <kpreid> I should actually try running E-on-CL that way  
(every object is a closure)
05:46:56 <markm_> http://scheme2006.cs.uchicago.edu/07-clinger.pdf -  
"Rapid Case Dispatch in Scheme" by Clinger
05:46:59 <kpreid> dtribble_: true
05:47:45 <dtribble_> btw got benchmark numbers?
05:48:02 <dtribble_> you definitly don't want to box numbers....
05:48:59 <dtribble_> you'd haveto dynamically dispatch on the scheme  
type of the object, and only function cal for boxed objects. that's  
essentially what you'd do in a C runtime implementation. That's what  
my Joule on Scheme did.
05:49:29 <kpreid> yep
05:49:46 <dtribble_> BTW the doOnce unction rang a bell: one of my  
comments to Mark is that there are at least a few places that E  
requires use-once fucntions, like resume keys in KeyKOS.
05:50:02 <kpreid> I have a E-on-CL version that builds its own single  
dispatch. I never got around to optimizing it interestingly
05:50:10 <dtribble_> Is there a simplifying abstraction there? I know  
that hveing the for spcial form expand to code the implements use-one  
behavior is really sucky.
05:51:08 <dtribble_> does OCaml qualify? it would have theoretically  
boed integers, but it might efficiently implement the unboxed case.
05:52:47 <kpreid> dunno
05:53:07 <dtribble_> to which: the use once or ocaml?
05:53:26 <kpreid> both, actually
05:53:35 <kpreid> but to go back to an earlier topic, E-on-Objective- 
C seems interesting to me
05:53:41 <dtribble_> use once shows up in for, ejectors, resolvers,  
whenResolved handlers.
05:53:55 <kpreid> I think objc dispatch itself would be Fast Enough  
for non-numbers
05:54:10 <kpreid> dunno what to do about numbers
05:54:20 <dtribble_> whythe question? looking for other  
implementation targets?
05:54:21 <kpreid> it would depend on the VM you build for running E  
objects
05:54:25 <kpreid> yep
05:54:37 <kpreid> something that's more oriented to doing single  
dispatch fast
05:54:48 <kpreid> built into the low-level representation etc.
05:56:10 <dtribble_> this actaully ties into my issue with the  
subclass-superclass loop. In smalltalk, you'd like that to map to the  
superclass chain, but the mapping isn't great.
05:56:30 <kpreid> subclass-superclass loop?
05:57:01 <dtribble_> def x extends abstractY(x) {...
05:57:21 <dtribble_> x points at Super, which points at x.
05:57:29 <kpreid> ah
05:57:45 <kpreid> +h
05:57:47 <kpreid> it is not a good idea to map that to host-language  
inheritance, I tink
05:57:52 <kpreid> because the semantics are different
05:58:02 <dtribble_> ? e`def x extends abstractY(x) {}`
05:58:03 <eel> # value: e`def [x__3, xR__5] := Ref.promise()
05:58:04 <eel> # def res__7 := def x := {
05:58:05 <eel> # def super := abstractY.run(x__3)
05:58:06 <eel> # def "$x__C" {
05:58:07 <eel> # match pair__1 {
05:58:08 <eel> # E.callWithPair(super, pair__1)
05:58:09 <eel> ...
05:58:43 <dtribble_> if not, then objects in a hierarchy are very  
expensive.
05:59:48 <kpreid> that would be an *optimizing* compiler
05:59:55 <kpreid> start with the *working* compiler :-)
05:59:56 <dtribble_> hmm. it would require inlining abstractY, so we  
are probably stuck there for now.
06:00:25 <dtribble_> a god point, and why I did not try to do taht  
for e on squeak
06:00:29 <dtribble_> good
06:00:34 <kpreid> it would be really nice to get E running in one of  
those Magic Inlining VMs :)
06:00:45 <dtribble_> strongtalk?
06:01:02 <kpreid> or self
06:01:04 <dtribble_> runnin on would get us much of he way there.
06:01:11 <dtribble_> yes.
06:01:29 <kpreid> all I know is that I can run Self now and I can't  
run Strongtalk yet :)
06:01:46 <dtribble_> you can run squeak now!
06:01:55 <dtribble_> I didn't realize that you can run Self :)
06:01:59 <kpreid> yes, but squeak doesn't do Magic Inlining™ :)
06:02:18 <dtribble_> fair enough.
06:02:24 * dtribble_ goes and looks for Self
06:02:37 <kpreid> url coming shortly
06:02:55 <kpreid> http://research.sun.com/self/release_4.3/release.html
06:04:39 <dtribble_> self doesn't have a linux or windows port that I  
can see
06:05:12 <kpreid> good point.
06:05:30 <kpreid> and it's less likely to get one in the future than  
strongtalk
06:06:00 <dtribble_> so my theory is that I will get it runnign on  
squeak, with the assumption that squeak will incorporate strongtalk  
technology at some point. failing that if strongtalk works, it should  
be a pretty easy port.
06:06:19 * kpreid nods
06:06:46 <dtribble_> did markm go away? or are you still on the phone?
06:06:53 <markm_> I'm here
06:07:09 <markm_> Reading, nothing to write (but this)
06:07:34 <dtribble_> so back to my use-Once question....
06:07:53 <dtribble_> The analogy of useOnce in Joule was resolving a  
promise
06:08:07 <dtribble_> not sure that's useful but thought I'd mention it.
06:08:20 <dtribble_> oops. must run and take drugs. back in a moment.
06:08:21 <kpreid> hah
06:08:35 <markm_> I like the suggestion in the abstract. I don't know  
what it would mean concretely
06:08:46 <kpreid> ? def state
06:08:46 <eel> # value: <Resolver>
06:08:59 <kpreid> ? when (state) -> { print("ding") }
06:09:00 <eel> # value: <Promise>
06:09:19 <kpreid> ? def useOnce() { state__Resolver.resolveRace(null) }
06:09:20 <eel> # value: <useOnce>
06:09:24 <kpreid> ? useOnce()
06:09:25 <eel> ding -- kpreid
06:09:27 <kpreid> ? useOnce()
06:09:42 <kpreid> not that I'm *recommending* this, but...
06:09:42 <markm_> Cute
06:10:08 <kpreid> (it won't work if you want synchronous operation)
06:10:17 <markm_> Yup
06:10:35 <dtribble_> why not?
06:10:44 <dtribble_> is it not possible to resolve withitn the same  
turn?
06:10:58 <kpreid> the when is async
06:11:07 <markm_> Yup
06:11:38 <dtribble_> oh. sure.
06:12:49 <dtribble_> I'm looking at the expansion of e`for x in y {z}`
06:13:26 <dtribble_> what I really want is "once" analogous to "thunk"
06:14:04 <dtribble_> once finish() {print("ding")}
06:14:13 <kpreid> ? def once := <import:org.erights.e.facet.once>
06:14:16 <eel> # value: <once>
06:14:32 <kpreid> ? def o := once(thunk { print("ding") })
06:14:33 <eel> # value: <...eel.1>
06:14:38 <kpreid> ? o()
06:14:39 <eel> ding -- kpreid
06:14:42 <kpreid> ? o()
06:14:43 <eel> # problem: used up
06:15:33 <dtribble_> yes...but not primitive, so can't be used in for  
expansion, etc.
06:15:47 <kpreid> um.
06:15:50 <kpreid> "require", used in the for expansion, is not  
"primitive"
06:16:01 <dtribble_> fair enough.
06:16:25 <markm_> This "once" is explained at http://www.erights.org/ 
elang/concurrency/race.html
06:16:40 <markm_> approximately
06:17:00 <kpreid> the only requirement is, of course, that 'for'  
isn't used in the definition of 'once'
06:17:18 <markm_> It's not
06:17:41 <dtribble_> I do care abou efficieny in my loops as well, so  
let's not go too wild :)
06:17:53 <kpreid> I'd rather see for expanded to a lambda-args  
protocol operation, actually
06:18:16 <markm_> Yup
06:18:40 <dtribble_> ejectors are use-once....
06:19:00 <dtribble_> you'd rather see for expanded that way?
06:19:07 <dtribble_> instead of a use of loop()?
06:19:09 <markm_> But a non-special for couldn't invisibly bind break  
& continue
06:19:10 <kpreid> which reminds me; the current lambda-args bugs me a  
bit because the protocol for implementing a control structure is so  
complex
06:19:26 <kpreid> markm_: I meant the special for would expand to use  
the protocol a non-special for would
06:19:51 <kpreid> but with break/continue added, and the same input  
syntax
06:20:03 <markm_> Cool, I like that
06:20:36 <dtribble_> any real macro system would be able to bind  
break/continue :)
06:20:43 <markm_> Do you have a suggestion for a simpler but adequate  
protocol?
06:20:57 <kpreid> no!
06:21:13 <markm_> Any read macro system breaks http://www.erights.org/ 
data/irrelevance.html
06:21:29 <kpreid> Smalltalk has it easier because it doesn't have  
pattern failures
06:21:55 <kpreid> one call site, I mean
06:22:00 <kpreid> also in ST it's natural to map a control structure  
to *one* invocation
06:22:09 <markm_> Smalltalk doesn't provide any equivalent to break  
and continue
06:22:21 <kpreid> not relevant
06:22:41 <markm_> I'm missing the point
06:22:47 <kpreid> the lambda-args protocol doesn't do anything with  
break and continue either
06:22:49 <kpreid> I'm just comparing lambda-args to ST's use of blocks
06:22:55 <markm_> Ah
06:22:59 <dtribble_> ah
06:23:22 <kpreid> you just implement eachFoo:inFunnyCase: and you're  
done, not three nested objects etc
06:23:42 <markm_> Yup
06:25:15 <kpreid> are we out of things to discuss?
06:26:04 <markm_> yup
06:26:09 <dtribble_> in the statement: "The reader of a fragment of a  
Scheme program that might be using hygienic macros must still do  
everything listed above before scope analysis allows them to  
disqualify any of the program from relevance to their question.
06:26:09 <dtribble_> " I don't know what "the list above " is
06:26:16 <dtribble_> I'm not, I'm just slow....
06:27:48 <dtribble_> I think hygeinic macros prserve scope.
06:28:40 <markm_> the reader would have to simulate the expansion in  
their head before that could use scope analysis. This requires the  
reader would have to simulate the expansion in their head before that  
could use scope analysis. This requires understanding which calls are  
actually macro calls, and it requires looking up the definition of  
all those macros and understanding them.
06:29:25 <dtribble_> ah. since hygiene prserves scope (I think), why  
would the user need to simulate macro expansion?
06:29:40 <markm_> They don't preserve any scope the human reader can  
figure out without looking up the macro definitions
06:29:57 <markm_> I think you're confused about "preserves scope"
06:30:05 <dtribble_> do you have an example?
06:30:24 <markm_> (foo x (y x))
06:31:51 <dtribble_> I see. Thisis no relevant to the break/continue  
example, which is why I couldn't come up wit it.
06:33:03 <dtribble_> By preserving scope, I meant that those refer to  
the same "x". You just can't tell if it's a defining occurence. Thus,  
the confusion is engenderred if you shadow variables, ut I  
wouldcontend tha you have most of hte confusion anyway.
06:33:27 <markm_> Huh?
06:33:37 <dtribble_> if there is no an outer use reference to "x",  
then either foo defines x or the program fails.
06:33:59 <markm_> And if there is?
06:34:26 <dtribble_> if there's an outer definition? then you wrote a  
confusing program, and should change it.
06:34:28 <dtribble_> :)
06:34:47 <markm_> Even if there isn't, which of these occurrences of  
"x" in foo are defining, and which are use?
06:34:55 <dtribble_> seriously even in E that would be hard to sort  
out. the conclusion is that the outer x might be leaked through this,  
so the failure is a conservative one.
06:35:17 <markm_> Huh?
06:35:40 <dtribble_> so there's a reordering issue. I was thinking  
that a plausible E rule is that the outer one must be the defining  
occurrence. (you can't move a reference past a definin occurrence).  
That is also true in scheme
06:36:59 <markm_> In Scheme, it would be perfectly fine if the inner  
"x" were defining, so long as the outer "x" ended up after it *post*  
expansion
06:37:08 <dtribble_> if you have (foo x (bar x (baz x))), the inner  
"x" may leak either of the outer x's, given no oher information about  
foo and bar. Thus, you can conservatively determine that the outer x  
might be exposed by the inner x. You should never consider shadowing  
a security feature becauseit's so easy to accidentally change.
06:37:22 <dtribble_> notin hygeinc macros.
06:37:37 <dtribble_> (I think).
06:38:06 <dtribble_> bcause hte inner syntactic context does no  
contain the outer syntactic context.
06:38:33 <dtribble_> (I might be wrong, but it's a plausible stance  
for E!)
06:39:09 <markm_> The stance I take in this document is, I think,  
quite similar to what you're proposing
06:39:34 <dtribble_> Thus, the reference in B is either a use of teh  
one defined/refernced in foo or a defining occurrence of the one used  
in baz
06:40:07 <dtribble_> so. since the above issue seems plausible and is  
unrelated to teh continue/break, I rest my case :)
06:40:07 <markm_> but it would still prohibit foo from silently  
(anaphorically?) binding "break" and "continue", because that  
violates the ability to do pre-expansion scope analysis
06:40:32 <dtribble_> not so.
06:40:36 <markm_> B?
06:41:30 <markm_> (foo (bar break))
06:41:30 <dtribble_> for/break/continue are macros defined in the  
same syntactic context aroun the definition of the __break name. the  
reference by break to __break is to the one that for defined.
06:41:54 <markm_> Did foo or bar bind break?
06:41:56 <dtribble_> there's no break special form ther try again....
06:42:11 <markm_> (foo (bar (break)))
06:42:39 <dtribble_> neither foo nor bar bound break. They might have  
bound __break which break also has a reference to.
06:42:57 <markm_> Ok, which of foo or bar bound __break?
06:43:14 <dtribble_> why do we care?
06:43:30 <dtribble_> break is in scope of both
06:43:35 <markm_> Uh, that's sorta the whole point of that paper
06:44:08 <markm_> What do you mean "break is in scope of both"?
06:44:14 <dtribble_> what I mean is that from a pre-expansion point  
of view, break is in the scope of both fo and bar, so my scope  
analysis can proceed on the assumption that it refers to something in  
scop.
06:44:35 <markm_> Huh?
06:44:40 <dtribble_> hmmm.
06:45:35 <dtribble_> what problem are we protecting against?
06:46:12 <markm_> "Scope analysis is the reader's main tool for  
quickly determining, when looking at a program fragment, which things  
cannot influence what other things. Scope analysis gives a first  
conservative bound on possible influence analysis."
06:46:14 <dtribble_> we wantto know that a defined spcial form can't  
leak references in the program. Not a problem with hygeine, because  
they can't capture a reference.
06:46:48 <dtribble_> interesting.
06:47:07 <dtribble_> so because they have a hidden reference, they  
can influence each other?
06:47:17 <markm_> Yup
06:47:35 <dtribble_> the essentailly precludes many useful control  
constructs.
06:47:39 <markm_> I'm getting tired
06:47:53 <dtribble_> OK one idea and then you can go :)
06:47:58 <markm_> Ok
06:48:29 <dtribble_> labels ironically address this issue for loops:  
if you want break and/or continue, you need to name the loop and aply  
break/continue to the "label".
06:48:30 <markm_> But you have to contribute the idea!
06:48:36 <dtribble_> :P
06:48:43 <dtribble_> funny man
06:48:49 <kpreid> label.break()
06:49:05 <dtribble_> loop.continue()
06:49:17 <kpreid> that's really just explicit binding of break and  
continue :)
06:49:39 <dtribble_> the thing I like about it is that most loops  
don't have break or continue. It's nice to have a heads up that there  
might be one :)
06:49:45 <kpreid> for(collection, fn label, element { if (...)  
{ label.break() } })
06:49:56 <markm_> The "escape" special form is effectively a named  
label construct
06:50:08 <kpreid> escape need not be a special form!
06:50:18 <kpreid> (but my compiler is happy that it is)
06:50:29 <dtribble_> yes, but you can't use it easily for both break  
and continue :)
06:50:39 * dtribble_ goes off to coun uses of break and continue in E  
CODE>
06:50:51 <dtribble_> on that note, good night.
06:50:57 <markm_> Yes, it could be defined using lambda-args and a  
primitive procedure
06:51:31 <markm_> Yeah, I think I'll sign off too.
06:51:36 <kpreid> markm: the case dispatch paper seems not to cover  
implementation details of the clause index to code part
06:52:01 <kpreid> true or did I miss something?
06:52:03 <dtribble_> 7 usages of continue...
06:52:06 <kpreid> the "Related Work" section seems to almost say it
06:52:18 <kpreid> s/almost say it/list everything they *don't* do/
06:52:21 <markm_> I'll have to take a closer look soon. (I've only  
skimmed so far.)
06:52:25 <dtribble_> I lied. 0 uses of continue.
06:52:27 <kpreid> oh ok
06:52:48 <markm_> g'night
06:52:53 <kpreid> night
06:53:01 --- quit: markm_ ("Trillian (http://www.ceruleanstudios.com")
06:53:27 <dtribble_> and 0 uses of break
06:53:30 <dtribble_> gnite!

-- 
Kevin Reid                            <http://homepage.mac.com/kpreid/>





More information about the e-lang mailing list