* Me no understand scoping
@ 2008-07-29 21:18 Maciek Godek
2008-07-30 3:24 ` Clinton Ebadi
0 siblings, 1 reply; 23+ messages in thread
From: Maciek Godek @ 2008-07-29 21:18 UTC (permalink / raw
To: guile-user
Hi,
consider the following code (simple iteration
construct invented mainly to cause naming
conflict, as the function 'times' is already
defined in guile)
(define-macro (times n f)
`(let ((env (the-environment)))
(let loop ((i 0))
(if (< i ,n)
(begin
(local-eval ,f env)
(loop (1+ i))
)
)
)
)
)
the whole thing with env was made as
a workaround disallowing f to see the
i variable defined in the macro (and to
perhaps see the value that otherwise
would be shadowed)
however,
(times 20 (display i))
yields
012345678910111213141516171819
Why?
--
Regards
M.
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Me no understand scoping
2008-07-29 21:18 Me no understand scoping Maciek Godek
@ 2008-07-30 3:24 ` Clinton Ebadi
2008-07-30 8:42 ` Maciek Godek
0 siblings, 1 reply; 23+ messages in thread
From: Clinton Ebadi @ 2008-07-30 3:24 UTC (permalink / raw
To: guile-user
"Maciek Godek" <pstrychuj@gmail.com> writes:
> Hi,
> consider the following code (simple iteration
> construct invented mainly to cause naming
> conflict, as the function 'times' is already
> defined in guile)
>
> (define-macro (times n f)
> `(let ((env (the-environment)))
> (let loop ((i 0))
> (if (< i ,n)
> (begin
> (local-eval ,f env)
> (loop (1+ i))
> )
> )
> )
> )
> )
>
> the whole thing with env was made as
> a workaround disallowing f to see the
> i variable defined in the macro (and to
> perhaps see the value that otherwise
> would be shadowed)
>
> however,
>
> (times 20 (display i))
>
> yields
>
> 012345678910111213141516171819
>
> Why?
`macroexpand-1' is helpful here -- (local-eval ,f env) is wrong.
As a matter of style, you probably want to avoid local-eval as it will
have to be removed whenever Guile ends up with a faster compiler (one
day when guile-vm is integrated into core and lexical environments
become fixed arrays or similar), and messing with existing lexical
environments is Very Bad (tm). Avoiding all uses of eval and, by
extension, local-eval is a good idea.
--
The hubbub of the waking life might close a door
which in the dreamy Subliminal might remain ajar...
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Me no understand scoping
2008-07-30 3:24 ` Clinton Ebadi
@ 2008-07-30 8:42 ` Maciek Godek
2008-07-30 14:03 ` Jon Wilson
0 siblings, 1 reply; 23+ messages in thread
From: Maciek Godek @ 2008-07-30 8:42 UTC (permalink / raw
To: guile-user
Clinton Ebadi:
> `macroexpand-1' is helpful here -- (local-eval ,f env) is wrong.
>
> As a matter of style, you probably want to avoid local-eval as it will
> have to be removed whenever Guile ends up with a faster compiler
On the other hand, local-eval is explained in guile manual,
while I couldn't find any documentation for guile's macroexpand-1,
nor for scheme macroexpand-1 (there are some explanations available
for the lisp language). So it's probably equally evil ;]
> (one day when guile-vm is integrated into core and lexical environments
> become fixed arrays or similar), and messing with existing lexical
> environments is Very Bad (tm). Avoiding all uses of eval and, by
> extension, local-eval is a good idea.
as for eval, it will always be there (in RnRS)
besides I don't imagine not messing with lexical
environments :) The bad thing is that scopes aren't
explicitly definable and the report doesn't say
much about their properties. I don't know how
about practical performance, but I'd find it best
if they were implemented as (implicit) hash tables
that could be bound to variables and passed as
arguments. I think that they could perform
equally good as fixed arrays for memoized
procedures.
Thanks,
M.
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Me no understand scoping
2008-07-30 8:42 ` Maciek Godek
@ 2008-07-30 14:03 ` Jon Wilson
2008-07-30 15:04 ` Klaus Schilling
2008-07-30 19:24 ` Maciek Godek
0 siblings, 2 replies; 23+ messages in thread
From: Jon Wilson @ 2008-07-30 14:03 UTC (permalink / raw
To: guile-user
Maciek Godek wrote:
> as for eval, it will always be there (in RnRS)
EVAL has not been in every report. R4RS did not specify EVAL, nor did
R3RS, RRRS, RRS.
> besides I don't imagine not messing with lexical
> environments :) The bad thing is that scopes aren't
> explicitly definable and the report doesn't say
> much about their properties. I don't know how
> about practical performance, but I'd find it best
> if they were implemented as (implicit) hash tables
> that could be bound to variables and passed as
> arguments. I think that they could perform
> equally good as fixed arrays for memoized
> procedures.
The view of the scheme community as a whole is that first class lexical
environments are irreconcilable with the need to compile (optimize)
code. In many cases, once you have done some variety of compilation, a
lot of the lexical environments you think you ought to have will have
been optimized away; conversely, preserving these environments will
prevent entire classes of compilation.
I am of the suspicion that in most cases, the environment would never be
reified, the compiler could prove this, and optimization could proceed
as desired. However, I would still agree with Clinton that you should
avoid messing with environments, first class or otherwise, whenever
possible. When you must, you should quarantine it: use it in a very
limited part of your code, where you wrap it in a more mundane
abstraction, then use that abstraction elsewhere. CALL/CC should be
treated the same way usually.
Broadening the topic a bit, it seems that first class envs and macros
(and maybe not macros!) are all that would be needed to define a module
system in scheme, rather than building it into the interpreter. Then
the module system could be put in a file which any r5rs+envs (or
whatever standard you like) scheme could LOAD (most likely implicitly at
startup) without modification to the interpreter itself. It might even
be the case that DEFMACROs and reified environments would be sufficient
to make low-level hygienic macros a library too (but I'm no macrologist,
for sure). You would still have to deal with the compilation issues,
but as I said, my gut feeling is that these are solvable.
Regards,
Jon
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Me no understand scoping
2008-07-30 14:03 ` Jon Wilson
@ 2008-07-30 15:04 ` Klaus Schilling
2008-07-30 19:24 ` Maciek Godek
1 sibling, 0 replies; 23+ messages in thread
From: Klaus Schilling @ 2008-07-30 15:04 UTC (permalink / raw
To: jsw; +Cc: guile-user
From: Jon Wilson <jsw@wilsonjc.us>
Subject: Re: Me no understand scoping
Date: Wed, 30 Jul 2008 10:03:21 -0400
> The view of the scheme community as a whole
I don't care what the community as a whole says, first-class
environments are the best thing since sliced bread, as proven by
Queinnec and De Roure. They allow for a unified approach for many different
things involving code-sharing.
Klaus Schilling
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Me no understand scoping
[not found] <cmu-lmtpd-29005-1217434291-0@mail-imap1.uio.no>
@ 2008-07-30 16:18 ` Kjetil S. Matheussen
2008-07-30 19:03 ` Clinton Ebadi
0 siblings, 1 reply; 23+ messages in thread
From: Kjetil S. Matheussen @ 2008-07-30 16:18 UTC (permalink / raw
To: guile-user
Clinton Ebadi:
>
> As a matter of style, you probably want to avoid local-eval as it will
> have to be removed whenever Guile ends up with a faster compiler (one
I've never heard this before, and I think you are way wrong.
first-class environments etc. is what makes Guile special
and it would be insane to remove it since there are xx other very
good scheme implementations. No more first-class environments,
no more Guile for me. Well, I guess someone would fork Guile
very quick in case it happened though.
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Me no understand scoping
2008-07-30 16:18 ` Kjetil S. Matheussen
@ 2008-07-30 19:03 ` Clinton Ebadi
0 siblings, 0 replies; 23+ messages in thread
From: Clinton Ebadi @ 2008-07-30 19:03 UTC (permalink / raw
To: Kjetil S. Matheussen; +Cc: guile-user
"Kjetil S. Matheussen" <k.s.matheussen@notam02.no> writes:
> Clinton Ebadi:
>>
>> As a matter of style, you probably want to avoid local-eval as it will
>> have to be removed whenever Guile ends up with a faster compiler (one
>
> I've never heard this before, and I think you are way wrong.
> first-class environments etc. is what makes Guile special
> and it would be insane to remove it since there are xx other very
> good scheme implementations. No more first-class environments,
> no more Guile for me. Well, I guess someone would fork Guile
> very quick in case it happened though.
Mutable first class environments available at runtime prevent a number
of useful optimizations. Immutable environments at runtime ought to be
fine (with nothing more than some space overhead).
Mutable environments provided at compile time for macros should be
fine however. I think most everything you'd want to do with an
environment at runtime could be done at compile time instead, and
there is not much convenience lost as you could always recompile a
block to effect a change to its lexical environment.
--
And did those feet in ancient times
Walk bare upon these lonely streets like mine?
Does God watch us from that penthouse high above
His children down below who live on air and love?
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Me no understand scoping
2008-07-30 14:03 ` Jon Wilson
2008-07-30 15:04 ` Klaus Schilling
@ 2008-07-30 19:24 ` Maciek Godek
2008-07-31 7:20 ` Neil Jerram
1 sibling, 1 reply; 23+ messages in thread
From: Maciek Godek @ 2008-07-30 19:24 UTC (permalink / raw
To: Jon Wilson; +Cc: guile-user
>> as for eval, it will always be there (in RnRS)
>
> EVAL has not been in every report. R4RS did not specify EVAL, nor did R3RS,
> RRRS, RRS.
The fact that R5RS does only proves the fact that they should have :)
By the way I have a question (regarding not using eval).
I want to pass the contents of a list to a function that accepts the
so-called "rest" args.
(let ((l '(1 2 3 4 5)))
(let ((operation (append '(+) l)))
(primitive-eval operation)
)
)
How to achieve this effect without using eval?
(I've tried (+ . l) but it didn't work out)
>> besides I don't imagine not messing with lexical
>> environments :) The bad thing is that scopes aren't
>> explicitly definable and the report doesn't say
>> much about their properties. I don't know how
>> about practical performance, but I'd find it best
>> if they were implemented as (implicit) hash tables
>> that could be bound to variables and passed as
>> arguments. I think that they could perform
>> equally good as fixed arrays for memoized
>> procedures.
>
> The view of the scheme community as a whole is that first class lexical
> environments are irreconcilable with the need to compile (optimize) code.
Certainly there's a faction that thinks differently :]
> In many cases, once you have done some variety of compilation, a lot of the
> lexical environments you think you ought to have will have been optimized
> away; conversely, preserving these environments will prevent entire classes
> of compilation.
Unless some limitations are to be imposed on compiled closures
(and some control over optimization is given to the programmer)
I see no problem with that.
> I am of the suspicion that in most cases, the environment would never be
> reified, the compiler could prove this, and optimization could proceed as
> desired. However, I would still agree with Clinton that you should avoid
> messing with environments, first class or otherwise, whenever possible.
> When you must, you should quarantine it: use it in a very limited part of
> your code, where you wrap it in a more mundane abstraction, then use that
> abstraction elsewhere. CALL/CC should be treated the same way usually.
Yeah, I always write additional layers so the code corresponds to the
way I think. (Everybody does, don't they?)
> Broadening the topic a bit, it seems that first class envs and macros (and
> maybe not macros!) are all that would be needed to define a module system in
> scheme, rather than building it into the interpreter. Then the module
> system could be put in a file which any r5rs+envs (or whatever standard you
> like) scheme could LOAD (most likely implicitly at startup) without
> modification to the interpreter itself. It might even be the case that
> DEFMACROs and reified environments would be sufficient to make low-level
> hygienic macros a library too (but I'm no macrologist, for sure). You would
> still have to deal with the compilation issues, but as I said, my gut
> feeling is that these are solvable.
Such a pretty vision you have :)
("and no religion too..." :P)
The thing is that this would really make *everything* simpler.
(or maybe it's just another collective hallucination)
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Me no understand scoping
2008-07-30 19:24 ` Maciek Godek
@ 2008-07-31 7:20 ` Neil Jerram
2008-07-31 19:21 ` Maciek Godek
0 siblings, 1 reply; 23+ messages in thread
From: Neil Jerram @ 2008-07-31 7:20 UTC (permalink / raw
To: Maciek Godek; +Cc: guile-user
2008/7/30 Maciek Godek <pstrychuj@gmail.com>:
>
> By the way I have a question (regarding not using eval).
> I want to pass the contents of a list to a function that accepts the
> so-called "rest" args.
> (let ((l '(1 2 3 4 5)))
> (let ((operation (append '(+) l)))
> (primitive-eval operation)
> )
> )
>
> How to achieve this effect without using eval?
> (I've tried (+ . l) but it didn't work out)
(apply + l)
>> The view of the scheme community as a whole is that first class lexical
>> environments are irreconcilable with the need to compile (optimize) code.
>
> Certainly there's a faction that thinks differently :]
If and when we have an optimized compiler, I imagine there would be
some way of allowing the environment to be optimized away when not
explicitly wanted, but kept available when it is wanted.
> Yeah, I always write additional layers so the code corresponds to the
> way I think. (Everybody does, don't they?)
Yes!
Regards,
Neil
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Me no understand scoping
2008-07-31 7:20 ` Neil Jerram
@ 2008-07-31 19:21 ` Maciek Godek
2008-07-31 21:37 ` Neil Jerram
2008-07-31 23:48 ` Clinton Ebadi
0 siblings, 2 replies; 23+ messages in thread
From: Maciek Godek @ 2008-07-31 19:21 UTC (permalink / raw
To: guile-user
Neil Jerram <neiljerram@googlemail.com>:
>> How to achieve this effect without using eval?
>> (I've tried (+ . l) but it didn't work out)
>
> (apply + l)
Correct :)
Here comes another one:
Suppose I want to define a variable, but I don't know its name
-- it is contained in another variable. For example:
(define a 'b)
I want to assign a value to the symbol "contained" in a.
(that would be b in this example). The problem is that "define"
quotes its first argument. How to achieve it?
>> Yeah, I always write additional layers so the code corresponds to the
>> way I think. (Everybody does, don't they?)
>
> Yes!
'(:-)
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Me no understand scoping
2008-07-31 19:21 ` Maciek Godek
@ 2008-07-31 21:37 ` Neil Jerram
2008-07-31 23:07 ` Maciek Godek
2008-07-31 23:48 ` Clinton Ebadi
1 sibling, 1 reply; 23+ messages in thread
From: Neil Jerram @ 2008-07-31 21:37 UTC (permalink / raw
To: Maciek Godek; +Cc: guile-user
2008/7/31 Maciek Godek <pstrychuj@gmail.com>:
> Here comes another one:
> Suppose I want to define a variable, but I don't know its name
> -- it is contained in another variable. For example:
> (define a 'b)
> I want to assign a value to the symbol "contained" in a.
> (that would be b in this example). The problem is that "define"
> quotes its first argument. How to achieve it?
I'm not so sure about this one, but I think that
(eval `(define ,(car a) 1))
should work.
Now, stepping back a bit - and purely out of interest - did you
mention before why you are doing these strange things? Is it your way
of exploring and learning, or is there (also) a specific requirement?
Neil
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Me no understand scoping
2008-07-31 21:37 ` Neil Jerram
@ 2008-07-31 23:07 ` Maciek Godek
2008-08-02 17:43 ` Neil Jerram
0 siblings, 1 reply; 23+ messages in thread
From: Maciek Godek @ 2008-07-31 23:07 UTC (permalink / raw
To: Neil Jerram; +Cc: guile-user
>> Here comes another one:
>> Suppose I want to define a variable, but I don't know its name
>> -- it is contained in another variable. For example:
>> (define a 'b)
>> I want to assign a value to the symbol "contained" in a.
>> (that would be b in this example). The problem is that "define"
>> quotes its first argument. How to achieve it?
>
> I'm not so sure about this one, but I think that
>
> (eval `(define ,(car a) 1))
>
> should work.
I eventually came up with something similar:
(define (define@ name value) (primitive-eval `(define ,name ,value)))
> Now, stepping back a bit - and purely out of interest - did you
> mention before why you are doing these strange things? Is it your way
> of exploring and learning, or is there (also) a specific requirement?
I can't tell you precisely (because I don't know myself).
It's just that whenever I try to do something in scheme,
I end up with questions of that sort. (Maybe the thing is
that I try to write as little code as possible -- the prettiness
and simplicity of scheme convinces me to do so).
I'm currently working on a little project (in my spare time).
I can't give you the source right now, because it's in its
infancy and there's definitely nothing to boast with.
However, I wrote the specification about a week ago
(originally it was meant to be a post to this group,
but as I wrote it, it replied to all my doubts and so
there was nothing to ask).
I hereby copy the contents of the specification file (to feed
your curiosity):
=BEGIN
Dear fellows,
For some time, I've been designing a network-oriented
object system, with interface callable from client side
and executed on server.
The toughest issue I have to deal with is the implementation
of RPC protocol.
The idea is fairly simple. Each client connected to
a server may request an object to be created, so the client
side session could look like this:
(noos-init)
(define connection (noos-connect address port))
; on success, noos-connect returns a valid connection handler
; or #f if fails
(if (not connection) (quit))
(noos-get-classes connection)
; noos-get-classes returns the list of valid noos-classes.
=> (class1 class2 class3)
; We can further inquire for the definition of a given class:
(noos-declaration connection 'class1)
; A noos-class declaration consists of:
; - list of public variables (readable by all clients connected)
; - list of private variables (readable by the owner of the class)
; - list of interface function prototypes. From the clients'
; point of view, they consist of the name of the function and
; the list of its parameters.
=> ((v1 v2 v3)(h1 h2 h3)((set-private v1 v2 v3)(do-something-else a1)))
; Knowing the interface, we can create instances of classes
(define y (noos-instance 'class1))
; noos-instance returns an object handler. it contains a local
; copy of hidden and public variables for immediate usage:
(y 'public)
=> #(0 0 0)
(y 'private)
=> #(0 0 0)
(y 'v1)
=> 0
; As you can see, the state is kept inside vectors, so they
; can be accessed very quickly.
; We can call the object's member functions:
(y 'set-private 1 2 3)
(y 'do-something-else "like what?")
; Note we can only pass numbers or strings as arguments,
; therefore the following calls would be invalid (regardless
; of the internal method definitions)
(!) (in y (set-public 'symbol1 (the-environment) #f))
(!) (in y (do-something-else (make-hash-table)))
; As the noos can be implemented over the UDP protocol,
; there's no guarrantee that the variables of out obiects
; are updated.
(y 'private)
=> (0 0 0)
; We can force it to do so using the `update'
; procedure if needed:
(update y)
(y 'private)
=> (1 2 3)
; It doesn't mean that the normal invocations of member
; functions are unable to change that state on client
; machine. If the packet is properly delivered to server,
; it immadietly changes the state of an object on the server.
; It also sends an event to a client -- it contains the new
; state of the object
; The update function sends request to a server and
; waits for the event to occur. If it doesn't (within
; specified amount of time), it sends it again and
; again, until the timeout is exceeded and then returns
; #f. If the response is sent properly, it returns #t
; (or something else different from #f)
; There's also another way of making sure that the
; remote member call is performed properly:
(assure (y 'set-public 1 2 3))
; This isn't currently implemented, but it looks tempting :D
== SERVER SIDE ==
; OK, now that we know how the system looks like from client's
; point of view, it's time to see it from the server's perspective.
; First of all, there are class definitions
(noos-class class1
(v1 v2 v3)
(h1 h2 h3)
(
(set-private a1 a2 a3) (
(set! v1 a1)
(set! v2 a2)
(set! v3 a3)
(send-event owner state)
)
(do-something-else a1) (
(send-event owner "do you really want to `" a1 "'")
)
)
; watch out! the next line defines an update function
; -- more about this later
((set! v1 (+ v1 h1)) (set! v2 (+ v2 h2)) (set! v3 (+ v3 h3)))
)
; As you can see, there are some variables of special
; meaning: namely 'owner' and 'state' (and a few others,
; like 'private', 'public' and 'neighbors' -- the last
; one to be explained later)
; noos adds a fairly sophisticated concept of meetings to
; the traditional object-oriented view on programming.
; In this concept, the world of objects is divided into
; subspaces (that are nothing but special objects that
; just hold references to their children)
; Obviously, there's a good reason for it. Under certain
; circumstances, two objects can meet. The circumstances
; are specified by a meeting predicate, ie.
(meeting-circumstances ((<sphere> x) (<sphere> y))
(and
(< (- (x 'v1) (y 'v1)) 1)
(< (- (x 'v2) (y 'v2)) 1)
(< (- (x 'v3) (y 'v3)) 1)
)
)
== IMPLEMENTATION ==
1. PROTOCOL
Firstly let's focus on how the underlaying protocol is
implemented. Information about the sender is contained
in the header of UDP packet -- therefore we don't have
to transmit any additional data.
; The server maintains a hash table in which all clients'
; addresses are stored.
(define clients-by-address (make-hash-table))
; When a client sends its first packet, a
; new entry in the hash table is created, assigning
; the client a unique identifier.
(define clients '())
(let ((cl (hash-ref clients-by-address address)))
(if (not cl)
(begin
(set! clients (cons (new-client) clients))
(hash-set! clients-by-address address (car clients))
)
(let ((object (vector-ref cl ob)))
(let ((function (vector-ref (object 'interface)) fn))
(local-call object function args)
)
)
)
; Is that all? Well, almost. The presented code assumes that
; when a packet is received, it is parsed to the variables
; ob, fn and args that are further processed by us.
; In practice that code is implemented in C (hoping it to
; perform better), as well as our parsing function.
; Current implementation uses the portable SDL_Net library
; to perform data exchange over UDP protocol.
; The protocol is text based and rather simple: client packets
; consist of an object number followed by a function number
; followed by argument list. The packets are therefore very
; lispish, although the types are limited to numbers, strings
; and lists.
; An example packet could look like this:
0 0 (1 (2 3))0+2i 3.4"one""two" (NULL-TERMINATED)
; Officially a single space is a separator, but the parser
; is written liberally and treats any sequence of white spaces
; as a separator. Like in lisp, no additional separator is needed
; after parentheses and double-quotes.
; Certainly this implementation of protocol isn't too efficient
; but an additional compression tunnel can be used in the future
; to provide faster data exchange (my goal now is just to make a
; working system, alright?)
// And this is how the packet is parsed (note we
// take advantage of the fact that the packets are
// meant to be null-terminated strings):
SCM parse(const char *packet) {
static char *arglist[1024]; // or whatever the limitation of UDP is
sprintf(arglist, "(quote (%s) )", packet);
return eval(arglist);
}
// obviously, in this form the code is rather dangerous and
// it requires a more sophisticated control -- you have to be
// aware of this fact when using current implementation of
// noos. (don't say I didn't warn you). On the other hand,
// since the code here is quoted, it won't be executed unless
// you make it do so.
SCM parsed = parse(packet.data);
int ob = scm_to_int(car(parsed));
int fn = scm_to_int(cadr(parsed));
SCM args = cddr(parsed);
// And that's how it's done on server.
; Situation on client machine is to some extent similar.
; In this case, however, the object's method simply invokes
; a `remote-call' function with specified parameters.
; The remote call of a member function consists of:
; - getting an object id from object handler
; - getting a function id from object handler
; - passing these among with the rest arguments to a function
; that builds a packet
; - sending the packet to the server.
; The other thing that can happen is the server signialising
; an event. This is also a remote-call, but invoked by the
; server and executed by the client.
=END
Surprisingly, this system isn't just a whim of a sick.
It's only a tiny part of a much larger whim: I'm making
a game engine. I already have a customizable input
system (it's the best: you can bind any thunk to any
key or any binary function to mouse move) and I'm
planning to make guile bindings to ogre3d display
engine (and several others) later on.
Obviously everybody's free to join :)
(but I warn you that I'm terribly fussy if it comes
to programming style (esp. my own), very likely
to change function and variable names and that
I don't have much experience in collective
programming)
I can let you know when I get the first working implementation
if you want.
Thanks for attention :)
M.
PS gdm rocks! (thankyouthankyouthankyou!! it really did change
my way of writing the code)
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Me no understand scoping
2008-07-31 19:21 ` Maciek Godek
2008-07-31 21:37 ` Neil Jerram
@ 2008-07-31 23:48 ` Clinton Ebadi
2008-08-01 22:00 ` Maciek Godek
1 sibling, 1 reply; 23+ messages in thread
From: Clinton Ebadi @ 2008-07-31 23:48 UTC (permalink / raw
To: Maciek Godek; +Cc: guile-user
"Maciek Godek" <pstrychuj@gmail.com> writes:
> Neil Jerram <neiljerram@googlemail.com>:
>
>>> How to achieve this effect without using eval?
>>> (I've tried (+ . l) but it didn't work out)
>>
>> (apply + l)
>
> Correct :)
> Here comes another one:
> Suppose I want to define a variable, but I don't know its name
> -- it is contained in another variable. For example:
> (define a 'b)
> I want to assign a value to the symbol "contained" in a.
> (that would be b in this example). The problem is that "define"
> quotes its first argument. How to achieve it?
module-define! MODULE NAME VALUE
e.g.
(let ((foo 'bar))
(module-define! (current-module) foo 5)
bar)
=> 5
Issue: this will be a top level binding, but a solution using `eval'
would also produce a top level binding (as it executes there to allow
lexical environments to be optimized...).
Doing such things, however, is fairly unschemey.
--
emacsen: every copy of Emacs comes with a bag of pot and 5 hits of acid
emacsen: and a hotel coffee maker
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Me no understand scoping
2008-07-31 23:48 ` Clinton Ebadi
@ 2008-08-01 22:00 ` Maciek Godek
2008-08-02 5:13 ` Jon Wilson
0 siblings, 1 reply; 23+ messages in thread
From: Maciek Godek @ 2008-08-01 22:00 UTC (permalink / raw
To: guile-user
2008/8/1 Clinton Ebadi <clinton@unknownlamer.org>:
>
> module-define! MODULE NAME VALUE
>
> e.g.
> (let ((foo 'bar))
> (module-define! (current-module) foo 5)
> bar)
> => 5
>
> Issue: this will be a top level binding, but a solution using `eval'
> would also produce a top level binding (as it executes there to allow
> lexical environments to be optimized...).
I've been trying to make it using local-eval to be able
to make a definition within a closure. There's only a
tiny problem: it's not working. When I execute:
(local-eval (list 'define a 5) (the-environment))
everything works fine, but when I make a function of it,
(define (define@ name value) (local-eval (list 'define name value)
(the-environment)))
and when I invoke it, it breaks with "Bad define placement".
The problem gets solved when I make a macro of it:
(define-macro (define@ name value) `(local-eval (list define ,name
,value)(the-environment)))
but it still breaks when called from a nested local-eval.
> Doing such things, however, is fairly unschemey.
What things and why?
What I'm trying to do is to understand the rules of making
and using environments. As for now, these rules seem to be quite
random and unpredictable (so it's rather hard to call them rules
actually), which is sad because closures are a very powerful
yet simple mechanism (definitely simpler than what GOOPS or
CLOS have to offer if it comes to OOP -- both in concepts and
implementation)
See you around :)
M.
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Me no understand scoping
2008-08-01 22:00 ` Maciek Godek
@ 2008-08-02 5:13 ` Jon Wilson
2008-08-02 21:35 ` Maciek Godek
0 siblings, 1 reply; 23+ messages in thread
From: Jon Wilson @ 2008-08-02 5:13 UTC (permalink / raw
To: guile-user
Time to trot out the tired old koan [1] ...
Maciek Godek wrote:
> which is sad because closures are a very powerful
> yet simple mechanism (definitely simpler than what GOOPS or
> CLOS have to offer if it comes to OOP -- both in concepts and
> implementation)
" The venerable master Qc Na was walking with his student, Anton.
Hoping to
prompt the master into a discussion, Anton said "Master, I have heard that
objects are a very good thing - is this true?" Qc Na looked pityingly at
his student and replied, "Foolish pupil - objects are merely a poor man's
closures."
" Chastised, Anton took his leave from his master and returned to his cell,
intent on studying closures. He carefully read the entire "Lambda: The
Ultimate..." series of papers and its cousins, and implemented a small
Scheme interpreter with a closure-based object system. He learned much, and
looked forward to informing his master of his progress.
" On his next walk with Qc Na, Anton attempted to impress his master by
saying "Master, I have diligently studied the matter, and now understand
that objects are truly a poor man's closures." Qc Na responded by hitting
Anton with his stick, saying "When will you learn? Closures are a poor man's
object." At that moment, Anton became enlightened.
[1] http://people.csail.mit.edu/gregs/ll1-discuss-archive-html/msg03277.html
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Me no understand scoping
2008-07-31 23:07 ` Maciek Godek
@ 2008-08-02 17:43 ` Neil Jerram
2008-08-02 21:36 ` Maciek Godek
0 siblings, 1 reply; 23+ messages in thread
From: Neil Jerram @ 2008-08-02 17:43 UTC (permalink / raw
To: Maciek Godek; +Cc: guile-user
2008/8/1 Maciek Godek <pstrychuj@gmail.com>:
>
> I can't tell you precisely (because I don't know myself).
> It's just that whenever I try to do something in scheme,
> I end up with questions of that sort. (Maybe the thing is
> that I try to write as little code as possible -- the prettiness
> and simplicity of scheme convinces me to do so).
>
> I'm currently working on a little project (in my spare time). [...]
Many thanks for providing this description. The project looks fun, so
I hope it continues to go well.
A few thoughts occurred to me when reading through.
1. IMO this could be really beautifully done in GOOPS, by defining
custom metaclasses and slot types.
2. You say that your protocol is lisp-ish. I have found it really
useful, both in GDS and in another client/server project, to express
the protocol entirely in lisp forms. Simply because this means that
you can use `read' to read exactly one protocol instruction; no
parsing required!
3. It's still not obvious to me how this ends up using the-environment
and local-eval. If class variables never interact directly with the
real environment, they could be just stored in a hash table..
> PS gdm rocks! (thankyouthankyouthankyou!! it really did change
> my way of writing the code)
Do you mean GDS? If so, thanks for your thanks!
Regards,
Neil
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Me no understand scoping
2008-08-02 5:13 ` Jon Wilson
@ 2008-08-02 21:35 ` Maciek Godek
0 siblings, 0 replies; 23+ messages in thread
From: Maciek Godek @ 2008-08-02 21:35 UTC (permalink / raw
To: Jon Wilson, guile-user
> Time to trot out the tired old koan [1] ...
>
> " The venerable master Qc Na was walking with his student, Anton. Hoping to
> prompt the master into a discussion, Anton said "Master, I have heard that
> objects are a very good thing - is this true?" Qc Na looked pityingly at
> his student and replied, "Foolish pupil - objects are merely a poor man's
> closures."
>
> " Chastised, Anton took his leave from his master and returned to his cell,
> intent on studying closures. He carefully read the entire "Lambda: The
> Ultimate..." series of papers and its cousins, and implemented a small
> Scheme interpreter with a closure-based object system. He learned much, and
> looked forward to informing his master of his progress.
>
> " On his next walk with Qc Na, Anton attempted to impress his master by
> saying "Master, I have diligently studied the matter, and now understand
> that objects are truly a poor man's closures." Qc Na responded by hitting
> Anton with his stick, saying "When will you learn? Closures are a poor man's
> object." At that moment, Anton became enlightened.
>
>
> [1] http://people.csail.mit.edu/gregs/ll1-discuss-archive-html/msg03277.html
I only wonder if the idea of explicit closures was floating in the air at the
time when this koan was coined. Does anybody know?
(because I can't loose the impression that explicit closures
could be the rich man's objects)
M.
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Me no understand scoping
2008-08-02 17:43 ` Neil Jerram
@ 2008-08-02 21:36 ` Maciek Godek
2008-08-08 20:54 ` Neil Jerram
2008-08-09 11:05 ` Andy Wingo
0 siblings, 2 replies; 23+ messages in thread
From: Maciek Godek @ 2008-08-02 21:36 UTC (permalink / raw
To: guile-user
>> I'm currently working on a little project (in my spare time). [...]
>
> Many thanks for providing this description. The project looks fun, so
> I hope it continues to go well.
>
> A few thoughts occurred to me when reading through.
>
> 1. IMO this could be really beautifully done in GOOPS, by defining
> custom metaclasses and slot types.
I've been considering that, and I'm still having doubts.
The main reason is that there's no documented way
of accessing GOOPS objects from C (except from using
scm_c_eval_string etc.), or at least I couldn't find any
documentation for that.
Besides (which is the matter of personal taste), I don't
like the idea of using generics and trashing the global
namespace with them. (I mean, the sole idea of generics
is fine, but I wouldn't want to be forced to use them)
I also get this unpleasant feeling that all these 'getters'
and 'setters' are entities multiplied beyond necessity
(even the infamous C++ doesn't explicate them)
I'm really trying to get close
to the classical OOP notation: object.method() -- and
it's probably why I explore the potential of using these
"poor man's objects"
> 2. You say that your protocol is lisp-ish. I have found it really
> useful, both in GDS and in another client/server project, to express
> the protocol entirely in lisp forms. Simply because this means that
> you can use `read' to read exactly one protocol instruction; no
> parsing required!
Yeah, I had a similar idea, although at first I thought of
making a more efficient (but less elastic) binary protocol
that would require some mechanisms to convert various
supported guile types to binary form. I eventually concluded
that it's better to keep everything textual not only to praise
my laziness, but also it would be better to make a statistical
information-theory based compression protocol to speed
it up (if it turns out necessary).
> 3. It's still not obvious to me how this ends up using the-environment
> and local-eval. If class variables never interact directly with the
> real environment, they could be just stored in a hash table..
I'm just looking for the most expressive way to use the language.
I've first heard of lisp like two years ago or so and even started
to learn that language from David Lamkins' "Successful Lisp"
and caught some of its spirit from Petet Graham's "On Lisp",
but I always kept getting distracted, finding other things to do.
But the point is that I saw that there is a 'make-hash-table' function
available in lisp -- and this lead me to the conclusion that it's probably
because the scopes/closures/environments implicitly use hash
tables to store their bindings (and the same mechanism was given
explicitly to the programmer).
And so I never stopped to believe that (define x 5) is more or
less equivalent to (hash-set! global-scope 'x 5).
>> PS gdm rocks! (thankyouthankyouthankyou!! it really did change
>> my way of writing the code)
>
> Do you mean GDS? If so, thanks for your thanks!
Yes, it's a great piece of software, regardless of its name :)
There's no need for your thanks for my thanks as they are deserved.
M.
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Me no understand scoping
2008-08-02 21:36 ` Maciek Godek
@ 2008-08-08 20:54 ` Neil Jerram
2008-08-10 21:49 ` Maciek Godek
2008-08-09 11:05 ` Andy Wingo
1 sibling, 1 reply; 23+ messages in thread
From: Neil Jerram @ 2008-08-08 20:54 UTC (permalink / raw
To: Maciek Godek; +Cc: guile-user
2008/8/2 Maciek Godek <pstrychuj@gmail.com>:
>> 1. IMO this could be really beautifully done in GOOPS, by defining
>> custom metaclasses and slot types.
>
> I've been considering that, and I'm still having doubts.
> The main reason is that there's no documented way
> of accessing GOOPS objects from C (except from using
> scm_c_eval_string etc.), or at least I couldn't find any
> documentation for that.
Yes, that's a fair point. And one that keeps coming up. I hope we
can remedy this some time soon.
> Besides (which is the matter of personal taste), I don't
> like the idea of using generics and trashing the global
> namespace with them. (I mean, the sole idea of generics
> is fine, but I wouldn't want to be forced to use them)
They can of course be confined to modules, like any other names.
> I also get this unpleasant feeling that all these 'getters'
> and 'setters' are entities multiplied beyond necessity
> (even the infamous C++ doesn't explicate them)
I don't understand you here. And in any case, getters and setters are
optional. You can just use slot-ref and slot-set! if you prefer.
> I'm really trying to get close
> to the classical OOP notation: object.method() -- and
> it's probably why I explore the potential of using these
> "poor man's objects"
Unfortunately that's only "classical" for non-Lisp-like languages!
Still, I'd take your point if you said you wanted to write something
that would be familiar to OO programmers in non-Lisp languages.
> But the point is that I saw that there is a 'make-hash-table' function
> available in lisp -- and this lead me to the conclusion that it's probably
> because the scopes/closures/environments implicitly use hash
> tables to store their bindings
Right (more or less).
> (and the same mechanism was given
> explicitly to the programmer).
You mean in the sense that can one create and manipulate a hash table
where the keys are symbols? I'd certainly agree with that.
> And so I never stopped to believe that (define x 5) is more or
> less equivalent to (hash-set! global-scope 'x 5).
Well yes.... but I'm afraid I'm still not sure how that leads us to
local-eval ! Sorry if I'm being dumb about this!
Regards,
Neil
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Me no understand scoping
2008-08-02 21:36 ` Maciek Godek
2008-08-08 20:54 ` Neil Jerram
@ 2008-08-09 11:05 ` Andy Wingo
2008-08-10 22:30 ` Maciek Godek
2008-09-11 14:56 ` JonWilson
1 sibling, 2 replies; 23+ messages in thread
From: Andy Wingo @ 2008-08-09 11:05 UTC (permalink / raw
To: Maciek Godek; +Cc: guile-user
Hi Maciek,
On Sat 02 Aug 2008 23:36, "Maciek Godek" <pstrychuj@gmail.com> writes:
> [Neil]
>> 1. IMO this could be really beautifully done in GOOPS, by defining
>> custom metaclasses and slot types.
>
> I've been considering that, and I'm still having doubts.
> The main reason is that there's no documented way
> of accessing GOOPS objects from C (except from using
> scm_c_eval_string etc.), or at least I couldn't find any
> documentation for that.
You can use scm_slot_ref et al. See goops.h.
> Besides (which is the matter of personal taste), I don't
> like the idea of using generics and trashing the global
> namespace with them. (I mean, the sole idea of generics
> is fine, but I wouldn't want to be forced to use them)
[...]
> I'm really trying to get close
> to the classical OOP notation: object.method() -- and
> it's probably why I explore the potential of using these
> "poor man's objects"
I wrote about this notational issue a while back on my blog,
http://wingolog.org/; I'm offline at the moment, so unfortunately I
don't have a link. Search for "slot-ref". I think with-accessors is an
elegant solution to this problem.
> But the point is that I saw that there is a 'make-hash-table' function
> available in lisp -- and this lead me to the conclusion that it's probably
> because the scopes/closures/environments implicitly use hash
> tables to store their bindings (and the same mechanism was given
> explicitly to the programmer).
This is false. Consider the closure:
(let ((val 0))
(lambda ()
(set! val (1+ val))
val))
Lexical scoping + closures was one of the fundamental ideas of scheme.
You can analyze this code /lexically/ to determine that we only need to
allocate storage for one variable. Wherever you see `val' in the body of
the lambda, you know /lexically/ that you are referring to a location
that is one step out in the stack frame, and the 0th location in that
frame, the frame created by `let'. So there is no need to store the
name, "val", at all!
By way of illustration, look at this disassembly of that closure in
guile-vm:
scheme@(guile-user)> (let ((val 0)) (lambda () (set! val (1+ val)) val))
$1 = #<program b6fbf388>
scheme@(guile-user)> ,x $1
Disassembly of #<program b6fbf388>:
nargs = 0 nrest = 0 nlocs = 0 nexts = 0
Bytecode:
0 (late-variable-ref 0)
2 (external-ref 0)
4 (call 1)
6 (external-set 0)
8 (external-ref 0)
10 (return)
Objects:
0 ((guile-user) . 1+)
Externals:
0 0
Sources:
6 #(1 36 #f)
8 #(1 26 #f)
The external shown there, "0 0" refers exactly to the outer stack frame,
the zeroeth location. The external-ref and external-set instructions
manipulate that storage location /by index and not by name/.
Do you see now why local-eval can't possibly work in the presence of
efficient compilation? Scheme does not give you the particular kind of
dynamism that you want. There is no hash table lurking inside a closure.
On the other hand, modules do have hash tables, and modules are
evaluation environments; and they have been treated in some literature
as closures. Perhaps consider using modules as your first-class objects?
> And so I never stopped to believe that (define x 5) is more or
> less equivalent to (hash-set! global-scope 'x 5).
At the top level it is; but s/global-scope/the current module/.
But internal defines are completely different.
Happy hacking,
Andy
--
http://wingolog.org/
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Me no understand scoping
2008-08-08 20:54 ` Neil Jerram
@ 2008-08-10 21:49 ` Maciek Godek
0 siblings, 0 replies; 23+ messages in thread
From: Maciek Godek @ 2008-08-10 21:49 UTC (permalink / raw
To: Neil Jerram; +Cc: guile-user
2008/8/8 Neil Jerram <neiljerram@googlemail.com>:
>> The main reason is that there's no documented way
>> of accessing GOOPS objects from C (except from using
>> scm_c_eval_string etc.), or at least I couldn't find any
>> documentation for that.
>
> Yes, that's a fair point. And one that keeps coming up. I hope we
> can remedy this some time soon.
I obviously started to develop my own OO system -- purely
to understand everything. By the way I came up with some
conclusions regarding objects and classes and that is:
- a class can be implemented as a vector of three elements:
* vector of methods (closures)
* hash table mapping method names to their closures
* hash table mapping slot names to vector indices.
- an object (instance) could also be implemented as a
simple vector -- its first field would be a reference to its
class, and the remaining ones would be the slots.
Interfacing such a system from the C level is rather
straightforward (or at least as straightforward as accessing
scm_vectors) and efficient.
(Perhaps goops does it more efficiently, I dunno)
>> I also get this unpleasant feeling that all these 'getters'
>> and 'setters' are entities multiplied beyond necessity
>> (even the infamous C++ doesn't explicate them)
>
> I don't understand you here. And in any case, getters and setters are
> optional. You can just use slot-ref and slot-set! if you prefer.
I bet you're right. I'm just learning and trying to justify all the
features that are provided by goops. Anyway, I can't get rid of
a feeling that many of them are redundant and quite random,
but I'm still examining it.
>> I'm really trying to get close
>> to the classical OOP notation: object.method() -- and
>> it's probably why I explore the potential of using these
>> "poor man's objects"
>
> Unfortunately that's only "classical" for non-Lisp-like languages!
> Still, I'd take your point if you said you wanted to write something
> that would be familiar to OO programmers in non-Lisp languages.
Fortunately Andy Wingo recommended his essay about this.
>> And so I never stopped to believe that (define x 5) is more or
>> less equivalent to (hash-set! global-scope 'x 5).
>
> Well yes.... but I'm afraid I'm still not sure how that leads us to
> local-eval ! Sorry if I'm being dumb about this!
Its genesis reaches the Kejtil's suggestion for accessing closure's
scope. The fact that it is possible in guile lead me to the conclusion
that it can be done to implement a simple oo system. (I'm just
beginning to realize how inefficient this can be).
Thanks a lot
M.
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Me no understand scoping
2008-08-09 11:05 ` Andy Wingo
@ 2008-08-10 22:30 ` Maciek Godek
2008-09-11 14:56 ` JonWilson
1 sibling, 0 replies; 23+ messages in thread
From: Maciek Godek @ 2008-08-10 22:30 UTC (permalink / raw
To: Andy Wingo; +Cc: guile-user
Hello Andy!
>> [Neil]
>>> 1. IMO this could be really beautifully done in GOOPS, by defining
>>> custom metaclasses and slot types.
>>
>> I've been considering that, and I'm still having doubts.
>> The main reason is that there's no documented way
>> of accessing GOOPS objects from C (except from using
>> scm_c_eval_string etc.), or at least I couldn't find any
>> documentation for that.
>
> You can use scm_slot_ref et al. See goops.h.
I took a glimpse. The one thing that stinks to me is an
immanent inefficiency which comes from the fact that
the slots are looked up by their names and therefore
aren't accessed directly. (I wrote a follow-up to Neil's
post in this thread with an efficient solution)
>> Besides (which is the matter of personal taste), I don't
>> like the idea of using generics and trashing the global
>> namespace with them. (I mean, the sole idea of generics
>> is fine, but I wouldn't want to be forced to use them)
> [...]
>> I'm really trying to get close
>> to the classical OOP notation: object.method() -- and
>> it's probably why I explore the potential of using these
>> "poor man's objects"
>
> I wrote about this notational issue a while back on my blog,
> http://wingolog.org/; I'm offline at the moment, so unfortunately I
> don't have a link. Search for "slot-ref". I think with-accessors is an
> elegant solution to this problem.
I've been looking for such thing for a month or so, it's brilliant
(or at least on a good way to be -- I have to examine it in more
detail). BTW I'm placing the link here for the others:
http://wingolog.org/archives/2008/04/22/object-closure-and-the-negative-specification
>> But the point is that I saw that there is a 'make-hash-table' function
>> available in lisp -- and this lead me to the conclusion that it's probably
>> because the scopes/closures/environments implicitly use hash
>> tables to store their bindings (and the same mechanism was given
>> explicitly to the programmer).
>
> This is false. Consider the closure:
>
> (let ((val 0))
> (lambda ()
> (set! val (1+ val))
> val))
>
> Lexical scoping + closures was one of the fundamental ideas of scheme.
> You can analyze this code /lexically/ to determine that we only need to
> allocate storage for one variable. Wherever you see `val' in the body of
> the lambda, you know /lexically/ that you are referring to a location
> that is one step out in the stack frame, and the 0th location in that
> frame, the frame created by `let'. So there is no need to store the
> name, "val", at all!
[...]
> Do you see now why local-eval can't possibly work in the presence of
> efficient compilation? Scheme does not give you the particular kind of
> dynamism that you want. There is no hash table lurking inside a closure.
Yeah, you've convinced me. I was stupid and irresponsible but now I can
see clearly why local-eval shouldn't be abused.
> On the other hand, modules do have hash tables, and modules are
> evaluation environments; and they have been treated in some literature
> as closures. Perhaps consider using modules as your first-class objects?
Thanks a lot, I think it was the second thing I've been looking for.
I'll read some more on that.
>> And so I never stopped to believe that (define x 5) is more or
>> less equivalent to (hash-set! global-scope 'x 5).
>
> At the top level it is; but s/global-scope/the current module/.
> But internal defines are completely different.
I've heard that in current implementation of guile they are only
different in that they are not storing data in hash-tables but in
assoc lists :) (That's what Ludovic says)
Thanks a lot
M.
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Me no understand scoping
2008-08-09 11:05 ` Andy Wingo
2008-08-10 22:30 ` Maciek Godek
@ 2008-09-11 14:56 ` JonWilson
1 sibling, 0 replies; 23+ messages in thread
From: JonWilson @ 2008-09-11 14:56 UTC (permalink / raw
To: guile-user
Hi Andy,
Andy Wingo wrote:
> Do you see now why local-eval can't possibly work in the presence of
> efficient compilation? Scheme does not give you the particular kind of
> dynamism that you want. There is no hash table lurking inside a closure.
Why not compile most closures away, but leave those that are necessary
for the sort of semantics Maciek wants to work? Maciek more or less
wants to reify environments (it seems), and have those be semantically
the same as the variable lookup mechanism inside closures.
It is certainly true that most continuations are not reified, many are
compiled away, but it is still possible to reify exactly the ones that
are needed and no others. Is it impossible for program analysis to
reveal which environments need to be reified? If necessary, one could
even require some sort of explicit tag on lambdas to say "This one gets
reified."
Of course, #scheme is probably a good place to discuss this sort of
thing, but I can't really hold my own once a really technical discussion
gets started there... Whether that's because I lack the expertise
(likely) or because certain personalities are perhaps overly dominating
(also likely), I don't know.
Regards,
Jon
^ permalink raw reply [flat|nested] 23+ messages in thread
end of thread, other threads:[~2008-09-11 14:56 UTC | newest]
Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-07-29 21:18 Me no understand scoping Maciek Godek
2008-07-30 3:24 ` Clinton Ebadi
2008-07-30 8:42 ` Maciek Godek
2008-07-30 14:03 ` Jon Wilson
2008-07-30 15:04 ` Klaus Schilling
2008-07-30 19:24 ` Maciek Godek
2008-07-31 7:20 ` Neil Jerram
2008-07-31 19:21 ` Maciek Godek
2008-07-31 21:37 ` Neil Jerram
2008-07-31 23:07 ` Maciek Godek
2008-08-02 17:43 ` Neil Jerram
2008-08-02 21:36 ` Maciek Godek
2008-08-08 20:54 ` Neil Jerram
2008-08-10 21:49 ` Maciek Godek
2008-08-09 11:05 ` Andy Wingo
2008-08-10 22:30 ` Maciek Godek
2008-09-11 14:56 ` JonWilson
2008-07-31 23:48 ` Clinton Ebadi
2008-08-01 22:00 ` Maciek Godek
2008-08-02 5:13 ` Jon Wilson
2008-08-02 21:35 ` Maciek Godek
[not found] <cmu-lmtpd-29005-1217434291-0@mail-imap1.uio.no>
2008-07-30 16:18 ` Kjetil S. Matheussen
2008-07-30 19:03 ` Clinton Ebadi
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).