* 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-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-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-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-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-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-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-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: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