unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
* %nil once again
@ 2009-07-16 13:47 Daniel Kraft
  2009-07-17  7:59 ` Neil Jerram
                   ` (2 more replies)
  0 siblings, 3 replies; 18+ messages in thread
From: Daniel Kraft @ 2009-07-16 13:47 UTC (permalink / raw)
  To: guile-devel; +Cc: Andy Wingo, Neil Jerram

Hi,

I think I got the test-suite as well as a basic macro implementation 
(the compiler framework is really cool, that was fairly easy to do); 
recursive macros do not yet work, but otherwise it looks fine.

However, I want to tackle quasi-quotes (besides others) now; and in 
Elisp %nil is not only #f of Scheme but also the end-of-list marker (I 
guess that's why simply using Scheme's #f for %nil does not work).

I did some experiments, and it seems that Scheme respects it partially:

scheme@(guile-user)> `(1 2 3 . ,%nil)
(1 2 3)

(is %nil in Scheme a variable because it needs the unquote?)

However:

scheme@(guile-user)> (null? %nil)
#f
scheme@(guile-user)> (equal? %nil (cdr (list 1)))
#f

It would be cool to teach Guile somehow to treat %nil as the "standard" 
end-of-list value, such that both of these queries would optimally 
return true.  At least, is there some way to construct lists terminated 
by %nil using something like the list primitive?  Other things needed 
would be for instance terminating rest-arguments by %nil rather than '() 
and the like.

So:  How is this handled by the interpreter?  Is there maybe some 
runtime-option to make Guile use %nil as end-of-list for lists 
constructed?  Or could we introduce some means to do so?

If that's not a good idea because of performance or other 
considerations, I guess I'll have to implement some conversion routine 
and use that?  This on the other hand will probably hit Elisp's performance.

Any suggestions and ideas welcome!  Maybe I just fail to see something...

Thanks,
Daniel

-- 
Done:  Arc-Bar-Cav-Ran-Rog-Sam-Tou-Val-Wiz
To go: Hea-Kni-Mon-Pri




^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: %nil once again
  2009-07-16 13:47 %nil once again Daniel Kraft
@ 2009-07-17  7:59 ` Neil Jerram
  2009-07-17  9:02   ` Daniel Kraft
  2009-07-20 18:17 ` Clinton Ebadi
  2009-07-23 20:35 ` Andy Wingo
  2 siblings, 1 reply; 18+ messages in thread
From: Neil Jerram @ 2009-07-17  7:59 UTC (permalink / raw)
  To: Daniel Kraft; +Cc: Andy Wingo, guile-devel

Daniel Kraft <d@domob.eu> writes:

> Hi,

Hi Daniel!

> I think I got the test-suite as well as a basic macro implementation
> (the compiler framework is really cool, that was fairly easy to do);
> recursive macros do not yet work, but otherwise it looks fine.
>
> However, I want to tackle quasi-quotes (besides others) now; and in
> Elisp %nil is not only #f of Scheme but also the end-of-list marker (I
> guess that's why simply using Scheme's #f for %nil does not work).
>
> I did some experiments, and it seems that Scheme respects it partially:
>
> scheme@(guile-user)> `(1 2 3 . ,%nil)
> (1 2 3)
>
> (is %nil in Scheme a variable because it needs the unquote?)

Do you mean why don't we just use the symbol nil?  If so, the answer
is because in Scheme, (cons 'a 'nil) should be (a . nil), not (a).

> However:
>
> scheme@(guile-user)> (null? %nil)
> #f
> scheme@(guile-user)> (equal? %nil (cdr (list 1)))
> #f

I believe those work in the interpreter, and so are VM bugs.  Can you
check that with ,o interp #t ?

> So:  How is this handled by the interpreter?

Currently, by the relevant places using SCM_NULL_OR_NIL_P.  (But I
expect that Mark Weaver's patch may change that; I haven't looked at
it in detail yet.)

>  Is there maybe some
> runtime-option to make Guile use %nil as end-of-list for lists
> constructed?

No, this ability is always enabled.

>  Or could we introduce some means to do so?
>
> If that's not a good idea because of performance or other
> considerations, I guess I'll have to implement some conversion routine
> and use that?  This on the other hand will probably hit Elisp's
> performance.
>
> Any suggestions and ideas welcome!  Maybe I just fail to see something...

Just a couple of VM bugs, I think...

Regards,
        Neil




^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: %nil once again
  2009-07-17  7:59 ` Neil Jerram
@ 2009-07-17  9:02   ` Daniel Kraft
  2009-07-17 14:20     ` Andreas Rottmann
  2009-07-19 18:28     ` Neil Jerram
  0 siblings, 2 replies; 18+ messages in thread
From: Daniel Kraft @ 2009-07-17  9:02 UTC (permalink / raw)
  To: Neil Jerram; +Cc: Andy Wingo, guile-devel

Hi Neil,

Neil Jerram wrote:
> Daniel Kraft <d@domob.eu> writes:
>> I think I got the test-suite as well as a basic macro implementation
>> (the compiler framework is really cool, that was fairly easy to do);
>> recursive macros do not yet work, but otherwise it looks fine.
>>
>> However, I want to tackle quasi-quotes (besides others) now; and in
>> Elisp %nil is not only #f of Scheme but also the end-of-list marker (I
>> guess that's why simply using Scheme's #f for %nil does not work).
>>
>> I did some experiments, and it seems that Scheme respects it partially:
>>
>> scheme@(guile-user)> `(1 2 3 . ,%nil)
>> (1 2 3)
>>
>> (is %nil in Scheme a variable because it needs the unquote?)
> 
> Do you mean why don't we just use the symbol nil?  If so, the answer
> is because in Scheme, (cons 'a 'nil) should be (a . nil), not (a).

No, I mean why '(1 2 3 . %nil) does yield (1 2 3 . %nil) while `(1 2 3 . 
,%nil) gives the expected (1 2 3).  But that does not matter much 
besides astonishing me, as this is only something related to the Scheme 
implementation of %nil, I guess.

>> However:
>>
>> scheme@(guile-user)> (null? %nil)
>> #f
>> scheme@(guile-user)> (equal? %nil (cdr (list 1)))
>> #f
> 
> I believe those work in the interpreter, and so are VM bugs.  Can you
> check that with ,o interp #t ?

The first one is indeed #t with the interpreter, the second one not. 
But unfortunatly I think that the elisp equivalent of

(equal?/eqv?/eq? (cdr (list 1)) nil)

(don't know which predicates take the place of eq?/eqv?/equal? in elisp 
yet)  should indeed yield true, as a perfectly valid way to check for 
(null? (cdr (list 1))), right?  So it seems that in this case even the 
Guile interpreter does not handle empty lists as it should for elisp -- 
or don't we need to ensure that test is true?

>>  Or could we introduce some means to do so?
>>
>> If that's not a good idea because of performance or other
>> considerations, I guess I'll have to implement some conversion routine
>> and use that?  This on the other hand will probably hit Elisp's
>> performance.
>>
>> Any suggestions and ideas welcome!  Maybe I just fail to see something...
> 
> Just a couple of VM bugs, I think...

Hm, ok, so if the one thing above is resolved (or can be ignored) I can 
without any problems just use Guile's primitive list and co. and take 
created lists as valid for Elisp, as long as those bug get fixed (maybe 
with the pending patch)?  So no need for ensuring myself that all '()'s 
get replaced by %nil's?

Daniel

-- 
Done:  Arc-Bar-Cav-Ran-Rog-Sam-Tou-Val-Wiz
To go: Hea-Kni-Mon-Pri




^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: %nil once again
  2009-07-17  9:02   ` Daniel Kraft
@ 2009-07-17 14:20     ` Andreas Rottmann
  2009-07-19 18:28     ` Neil Jerram
  1 sibling, 0 replies; 18+ messages in thread
From: Andreas Rottmann @ 2009-07-17 14:20 UTC (permalink / raw)
  To: Daniel Kraft; +Cc: Andy Wingo, guile-devel, Neil Jerram

Daniel Kraft <d@domob.eu> writes:

> Hi Neil,
>
> Neil Jerram wrote:
>> Daniel Kraft <d@domob.eu> writes:
>>> I think I got the test-suite as well as a basic macro implementation
>>> (the compiler framework is really cool, that was fairly easy to do);
>>> recursive macros do not yet work, but otherwise it looks fine.
>>>
>>> However, I want to tackle quasi-quotes (besides others) now; and in
>>> Elisp %nil is not only #f of Scheme but also the end-of-list marker (I
>>> guess that's why simply using Scheme's #f for %nil does not work).
>>>
>>> I did some experiments, and it seems that Scheme respects it partially:
>>>
>>> scheme@(guile-user)> `(1 2 3 . ,%nil)
>>> (1 2 3)
>>>
>>> (is %nil in Scheme a variable because it needs the unquote?)
>
Yes (although I'd say you need the unquote because you want to access
the variable, not the other way around </nitpick>).

>>
>> Do you mean why don't we just use the symbol nil?  If so, the answer
>> is because in Scheme, (cons 'a 'nil) should be (a . nil), not (a).
>
> No, I mean why '(1 2 3 . %nil) does yield (1 2 3 . %nil) while `(1 2 3
> . ,%nil) gives the expected (1 2 3).  But that does not matter much
> besides astonishing me, as this is only something related to the
> Scheme implementation of %nil, I guess.
>
The *symbol* '%nil has absolutely no special status in Scheme. It just
happens that Guile provides (in the default environment) a value bound
as %nil that has special properties.

Regards, Rotty
-- 
Andreas Rottmann -- <http://rotty.yi.org/>




^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: %nil once again
  2009-07-17  9:02   ` Daniel Kraft
  2009-07-17 14:20     ` Andreas Rottmann
@ 2009-07-19 18:28     ` Neil Jerram
  2009-07-19 19:44       ` Daniel Kraft
  1 sibling, 1 reply; 18+ messages in thread
From: Neil Jerram @ 2009-07-19 18:28 UTC (permalink / raw)
  To: Daniel Kraft; +Cc: Andy Wingo, guile-devel

Daniel Kraft <d@domob.eu> writes:

>>> scheme@(guile-user)> (null? %nil)
>>> #f
>>> scheme@(guile-user)> (equal? %nil (cdr (list 1)))
>>> #f
>>
>> I believe those work in the interpreter, and so are VM bugs.  Can you
>> check that with ,o interp #t ?
>
> The first one is indeed #t with the interpreter, the second one
> not. But unfortunatly I think that the elisp equivalent of
>
> (equal?/eqv?/eq? (cdr (list 1)) nil)
>
> (don't know which predicates take the place of eq?/eqv?/equal? in elisp yet)  should indeed yield true, as a perfectly valid way to check for (null? (cdr (list 1))), right?  So it seems that in this case even the Guile interpreter does not handle empty lists as it should for elisp -- 
> or don't we need to ensure that test is true?

Hm, interesting point.  Is it a problem in practice though?  If so,
what is the practical context?

i.e. is there a lot of existing code that uses (equal ... nil) to test
for the end of a list, rather than (null ...) ?

> So no need for ensuring myself that
> all '()'s get replaced by %nil's?

I would say not - because much of the existing Scheme/Elisp design is
based on _not_ having to translate data as it passes between
languages.

Or, to put it another way, if we think that we _do_ have to accept
translating data, I think we could remove lots of special Elisp
support from the libguile core.

Regards,
        Neil




^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: %nil once again
  2009-07-19 18:28     ` Neil Jerram
@ 2009-07-19 19:44       ` Daniel Kraft
  2009-07-19 20:10         ` Neil Jerram
  0 siblings, 1 reply; 18+ messages in thread
From: Daniel Kraft @ 2009-07-19 19:44 UTC (permalink / raw)
  To: Neil Jerram; +Cc: Andy Wingo, guile-devel

Hi Neil,

Neil Jerram wrote:
> Daniel Kraft <d@domob.eu> writes:
> 
>>>> scheme@(guile-user)> (null? %nil)
>>>> #f
>>>> scheme@(guile-user)> (equal? %nil (cdr (list 1)))
>>>> #f
>>> I believe those work in the interpreter, and so are VM bugs.  Can you
>>> check that with ,o interp #t ?
>> The first one is indeed #t with the interpreter, the second one
>> not. But unfortunatly I think that the elisp equivalent of
>>
>> (equal?/eqv?/eq? (cdr (list 1)) nil)
>>
>> (don't know which predicates take the place of eq?/eqv?/equal? in elisp yet)  should indeed yield true, as a perfectly valid way to check for (null? (cdr (list 1))), right?  So it seems that in this case even the Guile interpreter does not handle empty lists as it should for elisp -- 
>> or don't we need to ensure that test is true?
> 
> Hm, interesting point.  Is it a problem in practice though?  If so,
> what is the practical context?
> 
> i.e. is there a lot of existing code that uses (equal ... nil) to test
> for the end of a list, rather than (null ...) ?

honestly, I don't know (but think in practice null shoud be used).

>> So no need for ensuring myself that
>> all '()'s get replaced by %nil's?
> 
> I would say not - because much of the existing Scheme/Elisp design is
> based on _not_ having to translate data as it passes between
> languages.

Good, that sounds reasonable and is also what I suggest.  If we are one 
day able to actually run existing elisp code through Guile, we'll find 
out if anything needs to be changed in order to get a usable 
implementation anyways.

BTW, I implemented also the function bindings of symbols using this 
fluid-based dynamic scoping at the moment -- but on second thought, 
there's no scoping at all for function slots (all are global), is there? 
   If this is true, we can get rid of this complication here and use the 
symbols in (language elisp runtime function-slot) directly without 
indirection via the fluids.

Yours,
Daniel

PS: Current status update (should mainly be pushed already):  Yesterday 
I implemented compiler handling of backquoting and a lot of new 
built-ins (mainly list stuff like cons, car/cdr or number-sequence). 
Currently I'm working on some "derived" control-structures (prog1, 
prog2, when, unless, dotimes, dolist), and then a lot of the basic stuff 
will already be in place.  However, there isn't yet a real elisp-reader, 
so maybe this is the next big project (but I can try to make use of the 
existing patches).

-- 
Done:  Arc-Bar-Cav-Ran-Rog-Sam-Tou-Val-Wiz
To go: Hea-Kni-Mon-Pri




^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: %nil once again
  2009-07-19 19:44       ` Daniel Kraft
@ 2009-07-19 20:10         ` Neil Jerram
  2009-07-20  3:33           ` Ken Raeburn
  0 siblings, 1 reply; 18+ messages in thread
From: Neil Jerram @ 2009-07-19 20:10 UTC (permalink / raw)
  To: Daniel Kraft; +Cc: Andy Wingo, guile-devel

Daniel Kraft <d@domob.eu> writes:

> Good, that sounds reasonable and is also what I suggest.  If we are
> one day able to actually run existing elisp code through Guile, we'll
> find out if anything needs to be changed in order to get a usable
> implementation anyways.

Agreed.

> BTW, I implemented also the function bindings of symbols using this
> fluid-based dynamic scoping at the moment -- but on second thought,
> there's no scoping at all for function slots (all are global), is
> there?

No, I don't think there is.  `let' can't operate on function slots.

Regards,
        Neil




^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: %nil once again
  2009-07-19 20:10         ` Neil Jerram
@ 2009-07-20  3:33           ` Ken Raeburn
  2009-07-20  8:12             ` Daniel Kraft
  2009-07-23 22:18             ` Andy Wingo
  0 siblings, 2 replies; 18+ messages in thread
From: Ken Raeburn @ 2009-07-20  3:33 UTC (permalink / raw)
  To: Neil Jerram; +Cc: Andy Wingo, Daniel Kraft, guile-devel

On Jul 19, 2009, at 16:10, Neil Jerram wrote:
>> BTW, I implemented also the function bindings of symbols using this
>> fluid-based dynamic scoping at the moment -- but on second thought,
>> there's no scoping at all for function slots (all are global), is
>> there?
>
> No, I don't think there is.  `let' can't operate on function slots.

Not in the main emacs lisp implementation.  However, cl-macs.el  
provides an "flet" macro that does work on function slots; it uses the  
"letf" macro which expands to include a use of unwind-protect to do  
its dirty work.

Ken




^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: %nil once again
  2009-07-20  3:33           ` Ken Raeburn
@ 2009-07-20  8:12             ` Daniel Kraft
  2009-07-20  9:15               ` Ken Raeburn
  2009-07-23 22:18             ` Andy Wingo
  1 sibling, 1 reply; 18+ messages in thread
From: Daniel Kraft @ 2009-07-20  8:12 UTC (permalink / raw)
  To: Ken Raeburn; +Cc: Andy Wingo, guile-devel, Neil Jerram

Ken Raeburn wrote:
> On Jul 19, 2009, at 16:10, Neil Jerram wrote:
>>> BTW, I implemented also the function bindings of symbols using this
>>> fluid-based dynamic scoping at the moment -- but on second thought,
>>> there's no scoping at all for function slots (all are global), is
>>> there?
>>
>> No, I don't think there is.  `let' can't operate on function slots.
> 
> Not in the main emacs lisp implementation.  However, cl-macs.el provides 
> an "flet" macro that does work on function slots; it uses the "letf" 
> macro which expands to include a use of unwind-protect to do its dirty 
> work.

But that's not part of the real "elisp semantics", and so if we don't 
want to include this as a genuine extension into Guile's compiler, we 
don't have to use the fluids for function slots.

With unwind-protect and friends one can, just like in emacs, implement 
this functionality, even without a fluid implementation.

However, if you agree that this would be a useful feature (dynamic 
scoping of functions) I can of course implement this as an extension to 
elisp...?  I agree that it might be of use sometimes, but am not 
convinced it is really "necessary".

Yours,
Daniel

-- 
Done:  Arc-Bar-Cav-Ran-Rog-Sam-Tou-Val-Wiz
To go: Hea-Kni-Mon-Pri




^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: %nil once again
  2009-07-20  8:12             ` Daniel Kraft
@ 2009-07-20  9:15               ` Ken Raeburn
  0 siblings, 0 replies; 18+ messages in thread
From: Ken Raeburn @ 2009-07-20  9:15 UTC (permalink / raw)
  To: Daniel Kraft; +Cc: Andy Wingo, guile-devel, Neil Jerram

On Jul 20, 2009, at 04:12, Daniel Kraft wrote:
>>> No, I don't think there is.  `let' can't operate on function slots.
>> Not in the main emacs lisp implementation.  However, cl-macs.el  
>> provides an "flet" macro that does work on function slots; it uses  
>> the "letf" macro which expands to include a use of unwind-protect  
>> to do its dirty work.
>
> But that's not part of the real "elisp semantics", and so if we  
> don't want to include this as a genuine extension into Guile's  
> compiler, we don't have to use the fluids for function slots.

True.

> With unwind-protect and friends one can, just like in emacs,  
> implement this functionality, even without a fluid implementation.

Yes... though it means the elisp implementation wouldn't be able to  
cleanly support a multithreaded implementation that makes "flet"  
possible to implement safely.  If we want multiple threads, we  
probably do want thread-safe flet, I would guess.

> However, if you agree that this would be a useful feature (dynamic  
> scoping of functions) I can of course implement this as an extension  
> to elisp...?  I agree that it might be of use sometimes, but am not  
> convinced it is really "necessary".

I haven't looked into what it's needed for in great detail, but it  
does seem to get used in some places (gnus, mh-e, org, vc-rcs, ...).   
I don't know if we'll get to multithreaded elisp (I kind of hope so)  
or if we'll care about having a thread-safe flet (???), or thread-safe  
versions of whatever other interesting things unwind-protect might be  
getting used for.

Ken




^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: %nil once again
  2009-07-16 13:47 %nil once again Daniel Kraft
  2009-07-17  7:59 ` Neil Jerram
@ 2009-07-20 18:17 ` Clinton Ebadi
  2009-07-30 21:38   ` Neil Jerram
  2009-07-23 20:35 ` Andy Wingo
  2 siblings, 1 reply; 18+ messages in thread
From: Clinton Ebadi @ 2009-07-20 18:17 UTC (permalink / raw)
  To: Daniel Kraft; +Cc: Andy Wingo, Neil Jerram, guile-devel

Daniel Kraft <d@domob.eu> writes:

> Hi,
>
> I think I got the test-suite as well as a basic macro implementation
> (the compiler framework is really cool, that was fairly easy to do);
> recursive macros do not yet work, but otherwise it looks fine.
>
> However, I want to tackle quasi-quotes (besides others) now; and in
> Elisp %nil is not only #f of Scheme but also the end-of-list marker (I
> guess that's why simply using Scheme's #f for %nil does not work).

[...]

> It would be cool to teach Guile somehow to treat %nil as the
> "standard" end-of-list value, such that both of these queries would
> optimally return true.  At least, is there some way to construct lists
> terminated by %nil using something like the list primitive?  Other
> things needed would be for instance terminating rest-arguments by %nil
> rather than '() and the like.

Why not eliminate %nil/#nil and replace it with ... '(). This would
allow elisp to reuse all (or at least most) of the Scheme list functions
without having to muddy Scheme semantics with special #f/#nil handling,
but would require a very tiny elisp specific truth predicate. Since
everything should be compiled into an IL instead of Scheme this should
be straightforward. This would have the rather nice advantage of
removing all special elisp support code from libguile itself (thus
cleaning up libguile a bit *and* making the elisp translator a much
better example for other language translators since every language can't
expect to have special support from libguile).

If the Scheme value #f leaked into an elisp lisp/vector/etc. then it
should *not* be treated as false to elisp because it is *not* an elisp
false value; likewise if '() leaks back into data used by Scheme there
is no particular reason to treat that as false and not end of list.

This has the slight downside that calling between elisp and Scheme may
not be so natural. Any elisp that would call Scheme must know it is
calling Scheme (or simply not-elisp) and that it ought to generate
Scheme false objects if it is calling a predicate of some sort, and any
Scheme calling elisp should know this and use null? to check for a false
return value. The only downside I can see to this is that if code were
to be ported from elisp to Scheme there would now be code that assumed a
'() return as false when #f would be false, but this could be fixed
using a predicate like elisp-false? (or null-or-false? or
... something).

Having multiple distinct false values is almost as bad as punning false
and end of list and so I think the few disadvantages do not outweigh the
advantages.

-- 
Leebert: You don't listen to music.
Leebert: You listen to the audio equivalent of /dev/urandom




^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: %nil once again
  2009-07-16 13:47 %nil once again Daniel Kraft
  2009-07-17  7:59 ` Neil Jerram
  2009-07-20 18:17 ` Clinton Ebadi
@ 2009-07-23 20:35 ` Andy Wingo
  2009-07-24  6:20   ` Daniel Kraft
  2009-07-30 21:50   ` Neil Jerram
  2 siblings, 2 replies; 18+ messages in thread
From: Andy Wingo @ 2009-07-23 20:35 UTC (permalink / raw)
  To: Daniel Kraft; +Cc: Neil Jerram, guile-devel

Hi Daniel!

Reviewing (and merging as much as possible of) your elisp branch is my
next Guile task, after taking care of that bug recently reported by
Martin Ward. Should be short work at this point.

This is a little late, but fwiw...

On Thu 16 Jul 2009 15:47, Daniel Kraft <d@domob.eu> writes:

> I think I got the test-suite as well as a basic macro implementation

Awesome!

> scheme@(guile-user)> `(1 2 3 . ,%nil)
> (1 2 3)
>
> (is %nil in Scheme a variable because it needs the unquote?)

Scheme's end-of-list has the read syntax `()'. Elisp's nil has no read
syntax, to Scheme. If you want to get it in Scheme, you have to do so
via a variable.

> scheme@(guile-user)> (null? %nil)
> #f

This is a bug with the VM.

> scheme@(guile-user)> (equal? %nil (cdr (list 1)))
> #f

Hmmmmmmm. It's not clear that nil and null are equal?. Probably they
should be. Should they be eqv ? I wonder.

> It would be cool to teach Guile somehow to treat %nil as the "standard"
> end-of-list value, such that both of these queries would optimally
> return true.

No, they need to be different. Otherwise (if (cdr '(a)) 'b 'c) would
give 'c, not 'b.

> At least, is there some way to construct lists terminated by %nil
> using something like the list primitive?

It would need to be something you implement as part of the emacs
runtime.

Otoh, (cons* a b c %nil) will do what you want.

> Other things needed would be for instance terminating rest-arguments
> by %nil rather than '() and the like.

Hmmmmm. This is a good question. I think that, on the bytecode side, you
would have to receive the normal Scheme rest argument, then run through
it and replace the terminating '() with %nil. So when compiling
functions that take rest args, they'd have this operation as one of
their first instructions. There could be a VM op for this if necessary.

> So:  How is this handled by the interpreter?  Is there maybe some
> runtime-option to make Guile use %nil as end-of-list for lists
> constructed?  Or could we introduce some means to do so?
>
> If that's not a good idea because of performance or other
> considerations, I guess I'll have to implement some conversion routine
> and use that?  This on the other hand will probably hit Elisp's
> performance.

Yes it's probably a good idea to implement this conversion routine, for
now at least.

On the other other hand... can we enumerate the set of circumstances in
which we'd want to change a Scheme list to an Elisp list? Call,
obviously. Probably we want to support tail recursion in calls within
elisp, so tail calls too. Reading, but the elisp reader has to be
slightly different anyway. If it's only calls, we can do tricks in the
VM to make things faster.

But for now, just compile in a call to a runtime conversion.

Cheers,

Andy
-- 
http://wingolog.org/




^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: %nil once again
  2009-07-20  3:33           ` Ken Raeburn
  2009-07-20  8:12             ` Daniel Kraft
@ 2009-07-23 22:18             ` Andy Wingo
  1 sibling, 0 replies; 18+ messages in thread
From: Andy Wingo @ 2009-07-23 22:18 UTC (permalink / raw)
  To: Ken Raeburn; +Cc: Daniel Kraft, guile-devel, Neil Jerram

On Mon 20 Jul 2009 05:33, Ken Raeburn <raeburn@raeburn.org> writes:

> On Jul 19, 2009, at 16:10, Neil Jerram wrote:
>>> BTW, I implemented also the function bindings of symbols using this
>>> fluid-based dynamic scoping at the moment -- but on second thought,
>>> there's no scoping at all for function slots (all are global), is
>>> there?
>>
>> No, I don't think there is.  `let' can't operate on function slots.
>
> Not in the main emacs lisp implementation.  However, cl-macs.el provides
> an "flet" macro that does work on function slots; it uses the  "letf"
> macro which expands to include a use of unwind-protect to do  its dirty
> work.

Then we should implement that in an efficient way in Guile too.

Andy
-- 
http://wingolog.org/




^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: %nil once again
  2009-07-23 20:35 ` Andy Wingo
@ 2009-07-24  6:20   ` Daniel Kraft
  2009-07-30 21:50   ` Neil Jerram
  1 sibling, 0 replies; 18+ messages in thread
From: Daniel Kraft @ 2009-07-24  6:20 UTC (permalink / raw)
  To: Andy Wingo; +Cc: Neil Jerram, guile-devel

Hi Andy,

thanks for your comments!

Andy Wingo wrote:
> Reviewing (and merging as much as possible of) your elisp branch is my
> next Guile task, after taking care of that bug recently reported by
> Martin Ward. Should be short work at this point.

Cool!  But just take your time ;)

>> At least, is there some way to construct lists terminated by %nil
>> using something like the list primitive?
> 
> It would need to be something you implement as part of the emacs
> runtime.
> 
> Otoh, (cons* a b c %nil) will do what you want.

Hm, that's an interesting option!  Another comment on this subject had 
been to try without converting the list ends and see how often code 
relys on exactly %nil being the end-of-list anyways, which is what I've 
been doing so far.  But I can give it a try to convert.

>> Other things needed would be for instance terminating rest-arguments
>> by %nil rather than '() and the like.
> 
> Hmmmmm. This is a good question. I think that, on the bytecode side, you
> would have to receive the normal Scheme rest argument, then run through
> it and replace the terminating '() with %nil. So when compiling
> functions that take rest args, they'd have this operation as one of
> their first instructions. There could be a VM op for this if necessary.

Yes, at the moment I already have to do some pre-processing of the rest 
argument at function entry anyways, to handle, for instance, optional 
arguments.  So I can just do the conversion there.

A VM op might be interesting, but as you suggested I'll just write a 
runtime-function and call it; we can do perfomance optimization later on 
when we really know what the problems are.

> On the other other hand... can we enumerate the set of circumstances in
> which we'd want to change a Scheme list to an Elisp list? Call,
> obviously. Probably we want to support tail recursion in calls within
> elisp, so tail calls too. Reading, but the elisp reader has to be
> slightly different anyway. If it's only calls, we can do tricks in the
> VM to make things faster.

I think it would be lists generated by the compiler for certain 
constructs (but I think all of those are only handed to primitives and 
never seen by elisp, so they don't matter), of course the rest arguments 
already mentioned, and most notably return values from primitives that 
return lists -- those need to be converted between the Guile primitive 
and elisp, but that should also be only a call to the conversion routine 
and hopefully not result in too bad performance.

So, maybe a next thing for me will be to work on this conversion.

Yours,
Daniel

-- 
Done:  Arc-Bar-Cav-Ran-Rog-Sam-Tou-Val-Wiz
To go: Hea-Kni-Mon-Pri




^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: %nil once again
  2009-07-20 18:17 ` Clinton Ebadi
@ 2009-07-30 21:38   ` Neil Jerram
  2009-07-31  5:03     ` Daniel Kraft
  0 siblings, 1 reply; 18+ messages in thread
From: Neil Jerram @ 2009-07-30 21:38 UTC (permalink / raw)
  To: Clinton Ebadi; +Cc: Andy Wingo, Daniel Kraft, guile-devel

Clinton Ebadi <clinton@unknownlamer.org> writes:

> Why not eliminate %nil/#nil and replace it with ... '(). This would
> allow elisp to reuse all (or at least most) of the Scheme list functions
> without having to muddy Scheme semantics with special #f/#nil handling,
> but would require a very tiny elisp specific truth predicate. Since
> everything should be compiled into an IL instead of Scheme this should
> be straightforward. This would have the rather nice advantage of
> removing all special elisp support code from libguile itself (thus
> cleaning up libguile a bit *and* making the elisp translator a much
> better example for other language translators since every language can't
> expect to have special support from libguile).

Yes.  It's just the Elisp->Scheme data translation point again,
though, as you say:

> This has the slight downside that calling between elisp and Scheme may
> not be so natural. Any elisp that would call Scheme must know it is
> calling Scheme (or simply not-elisp) and that it ought to generate
> Scheme false objects if it is calling a predicate of some sort,

Right.  Elisp code that generates a boolean result, for use by Scheme,
would need to have that result translated from () to #f.  But then
what about Elisp code that generates a vector of boolean results, or
an alist of vectors of boolean results...?

> and any
> Scheme calling elisp should know this and use null? to check for a false
> return value.

The ultimate point of multiple language support is that an application
user can write a hook or configuration tweak in whichever language
they feel comfortable with.  The driving C or Scheme code that calls
out to that hook or tweak needs to work regardless of the user's
language choice.

> The only downside I can see to this is that if code were
> to be ported from elisp to Scheme there would now be code that assumed a
> '() return as false when #f would be false, but this could be fixed
> using a predicate like elisp-false? (or null-or-false? or
> ... something).

I don't like that at all!

In my view, the only reasonable alternative solution above is the one
that would work by translating data passing between Elisp and Scheme.
The theoretical argument against that is that such translation could
be arbitrarily complex, and so have an unbounded performance cost, but
in practice I imagine that would almost never be the case.  Also there
is the point that languages other than Elisp will _require_ data
translation, and why should we make Elisp a special case?  Hence I
wouldn't rule out the possibility of switching to this design in
future; and then we could, as you say, make nil==() and remove most
elisp special cases from the libguile core.

Regards,
        Neil




^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: %nil once again
  2009-07-23 20:35 ` Andy Wingo
  2009-07-24  6:20   ` Daniel Kraft
@ 2009-07-30 21:50   ` Neil Jerram
  2009-07-31  5:05     ` Daniel Kraft
  1 sibling, 1 reply; 18+ messages in thread
From: Neil Jerram @ 2009-07-30 21:50 UTC (permalink / raw)
  To: Andy Wingo; +Cc: Daniel Kraft, guile-devel

Andy Wingo <wingo@pobox.com> writes:

>> Other things needed would be for instance terminating rest-arguments
>> by %nil rather than '() and the like.

Why is that needed?  I.e. Why is it important for a rest argument to
be terminated with %nil instead of with () ?

    Neil




^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: %nil once again
  2009-07-30 21:38   ` Neil Jerram
@ 2009-07-31  5:03     ` Daniel Kraft
  0 siblings, 0 replies; 18+ messages in thread
From: Daniel Kraft @ 2009-07-31  5:03 UTC (permalink / raw)
  To: Neil Jerram; +Cc: Clinton Ebadi, Andy Wingo, guile-devel

Hi Neil,

Neil Jerram wrote:
>> The only downside I can see to this is that if code were
>> to be ported from elisp to Scheme there would now be code that assumed a
>> '() return as false when #f would be false, but this could be fixed
>> using a predicate like elisp-false? (or null-or-false? or
>> ... something).
> 
> I don't like that at all!
> 
> In my view, the only reasonable alternative solution above is the one
> that would work by translating data passing between Elisp and Scheme.
> The theoretical argument against that is that such translation could
> be arbitrarily complex, and so have an unbounded performance cost, but
> in practice I imagine that would almost never be the case.  Also there
> is the point that languages other than Elisp will _require_ data
> translation, and why should we make Elisp a special case?  Hence I
> wouldn't rule out the possibility of switching to this design in
> future; and then we could, as you say, make nil==() and remove most
> elisp special cases from the libguile core.

I agree here; though I think we should get translation to a minimum as 
much as possible; for instance, I still think the Guile core should 
treat %nil as false and empty list if asked for.  This does not hurt 
Scheme, as %nil does not occur there, but it would allow us to just use 
TreeIL conditionals and the like without having to translate here.

On the other hand, if we want elisp semantics as faithfully as possible, 
we need to translate the way from Guile primitives to elisp code. 
Currently I'm already doing this for booleans; for instance, the = 
built-in of emacs is defined something like:

(lambda (a b)
   (if (= a b)
     t
     %nil))

so that the "false" value is really %nil.  On a later thought, this 
might be the real reason why my "tight while loop" performed worse than 
the Scheme version in the performance test.  But I don't see a way how 
to get around this, unfortunatly; except if we just assume that the 
elisp user won't test a false value for (eq value nil) but just use it 
as boolean in conditionals, too, so it does not matter if the value is 
%nil or #f.

The same applies to lists...  In general, one can write probably most 
elisp code without having to really care if the tail of a rest argument 
or the result from the list built-in or some quotation-expression is 
%nil or '() (and should actually check with null instead of (eq nil), I 
think).  At the moment it is like that, there's no '() <--> %nil 
translation happening by now.  As long as libguile/VM gets the patch to 
accept %nil as end-of-list (as the interpreter already does), one can 
still do (cons 'a (cons 'b nil)) in elisp and get the expected result...

I'm still not sure if we should actually do data translation from Scheme 
(Guile built-ins) to elisp user code or not...  But probably we should 
just do it and the performance hit will not be too painful.

Daniel

-- 
Done:  Arc-Bar-Cav-Ran-Rog-Sam-Tou-Val-Wiz
To go: Hea-Kni-Mon-Pri




^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: %nil once again
  2009-07-30 21:50   ` Neil Jerram
@ 2009-07-31  5:05     ` Daniel Kraft
  0 siblings, 0 replies; 18+ messages in thread
From: Daniel Kraft @ 2009-07-31  5:05 UTC (permalink / raw)
  To: Neil Jerram; +Cc: Andy Wingo, guile-devel

Neil Jerram wrote:
> Andy Wingo <wingo@pobox.com> writes:
> 
>>> Other things needed would be for instance terminating rest-arguments
>>> by %nil rather than '() and the like.
> 
> Why is that needed?  I.e. Why is it important for a rest argument to
> be terminated with %nil instead of with () ?

Well, I don't think it is "important" at all, but it would be needed for 
"complete elisp" semantics, just because it is a list and lists should 
be terminated by %nil in elisp.  Someone might try to check for the 
end-of-list with (eq tail nil) instead of (null tail) and it should 
still work.

BTW, for an empty rest argument the elisp documentation explicitly 
states it "should" be nil (well, but that's obviously so because nil is 
the empty list).

Daniel

-- 
Done:  Arc-Bar-Cav-Ran-Rog-Sam-Tou-Val-Wiz
To go: Hea-Kni-Mon-Pri




^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2009-07-31  5:05 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-07-16 13:47 %nil once again Daniel Kraft
2009-07-17  7:59 ` Neil Jerram
2009-07-17  9:02   ` Daniel Kraft
2009-07-17 14:20     ` Andreas Rottmann
2009-07-19 18:28     ` Neil Jerram
2009-07-19 19:44       ` Daniel Kraft
2009-07-19 20:10         ` Neil Jerram
2009-07-20  3:33           ` Ken Raeburn
2009-07-20  8:12             ` Daniel Kraft
2009-07-20  9:15               ` Ken Raeburn
2009-07-23 22:18             ` Andy Wingo
2009-07-20 18:17 ` Clinton Ebadi
2009-07-30 21:38   ` Neil Jerram
2009-07-31  5:03     ` Daniel Kraft
2009-07-23 20:35 ` Andy Wingo
2009-07-24  6:20   ` Daniel Kraft
2009-07-30 21:50   ` Neil Jerram
2009-07-31  5:05     ` Daniel Kraft

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).