unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
* our nil story
@ 2010-04-16  8:54 Andy Wingo
  2010-04-16 12:12 ` Ludovic Courtès
  2010-04-16 12:35 ` Daniel Kraft
  0 siblings, 2 replies; 5+ messages in thread
From: Andy Wingo @ 2010-04-16  8:54 UTC (permalink / raw)
  To: guile-devel

Hi all,

Just updated some docs on other languages and nil. It's in master, but
I'm pasting here for comments.

    0.1 Support for Other Languages
    ===============================

    In addition to Scheme, a user may write a Guile program in an increasing
    number of other languages. Currently supported languages include Emacs
    Lisp and ECMAScript.

       Guile is still fundamentally a Scheme, but it tries to support a wide
    variety of language building-blocks, so that a user can implement other
    languages on top of Guile. This section describes the languages that
    have been implemented.

       (For details on how to implement a language, *Note Compiling to the
    Virtual Machine::.)

    0.1.1 Using Other Languages
    ---------------------------

    There are currently only two ways to access other languages from within
    Guile: at the REPL, and via `compile' or `compile-file'.

       The REPL is Guile's command prompt (*note Using Guile
    Interactively::).  The REPL has a concept of the "current language",
    which defaults to Scheme. The user may change that language, via the
    meta-command `,language'.

       For example, the following meta-command enables Emacs Lisp input:

         scheme@(guile-user)> ,language elisp
         Happy hacking with Emacs Lisp!  To switch back, type `,L scheme'.
         elisp@(guile-user)> (eq 1 2)
         $1 = #nil

       Each language has its short name: for example, `elisp', for Elisp.
    The same short name may be used to compile source code programmatically,
    via `compile':

         elisp@(guile-user)> ,L scheme
         Happy hacking with Guile Scheme!  To switch back, type `,L elisp'.
         scheme@(guile-user)> (compile '(eq 1 2) #:from 'elisp)
         $2 = #nil

       Granted, as the input to `compile' is a datum, this works best for
    Lispy languages, which have a straightforward datum representation.
    Other languages that need more parsing are better dealt with as strings.

       The easiest way to deal with syntax-heavy language is with files, via
    `compile-file' and friends. However it is possible to invoke a
    language's reader on a port, and then compile the resulting expression
    (which is a datum at that point). For more information, *Note
    Compilation::.

       For more details on introspecting aspects of different languages,
    *Note Compiler Tower::.

    0.1.2 Emacs Lisp
    ----------------

    Emacs Lisp (Elisp) is a dynamically-scoped Lisp dialect used in the
    Emacs editor. *Note Overview: (elisp)top, for more information on Emacs
    Lisp.

       We hope that eventually Guile's implementation of Elisp will be good
    enough to replace Emacs' own implementation of Elisp. For that reason,
    we have thought long and hard about how to support the various features
    of Elisp in a performant and compatible manner.

       Readers familiar with Emacs Lisp might be curious about how exactly
    these various Elisp features are supported in Guile. The rest of this
    section focuses on addressing these concerns of the Elisp elect.

    0.1.2.1 Nil
    ...........

    `nil' in ELisp is an amalgam of Scheme's `#f' and `'()'.  It is false,
    and it is the end-of-list; thus it is a boolean, and a list as well.

       Guile has chosen to support `nil' as a separate value, distinct from
    `#f' and `'()'. This allows existing Scheme and Elisp code to maintain
    their current semantics. `nil', which in Elisp would just be written
    and read as `nil', in Scheme has the external representation `#nil'.

       This decision to have `nil' as a low-level distinct value
    facilitates interoperability between the two languages. Guile has chosen
    to have Scheme deal with `nil' as follows:

         (boolean? #nil) => #t
         (not #nil) => #t
         (null? #nil) => #t

       And in C, one has:

         scm_is_bool (SCM_ELISP_NIL) => 1
         scm_is_false (SCM_ELISP_NIL) => 1
         scm_is_null (SCM_ELISP_NIL) => 1

       In this way, a version of `fold' written in Scheme can correctly
    fold a function written in Elisp (or in fact any other language) over a
    nil-terminated list, as Elisp makes. The converse holds as well; a
    version of `fold' written in Elisp can fold over a `'()'-terminated
    list, as made by Scheme.

       On a low level, the bit representations for `#f', `#t', `nil', and
    `'()' are made in such a way that the differ by only one bit, and so a
    test for, for example, `#f'-or-`nil' may be made very efficiently. See
    `libguile/boolean.h', for more information.

    0.1.2.2 Equality
    ................

    Since Scheme's `equal?' must be transitive, and `'()' is not `equal?'
    to `#f', to Scheme `nil' is not `equal?' to `#f' or `'()'.

         (eq? #f '()) => #f
         (eq? #nil '()) => #f
         (eq? #nil #f) => #f
         (eqv? #f '()) => #f
         (eqv? #nil '()) => #f
         (eqv? #nil #f) => #f
         (equal? #f '()) => #f
         (equal? #nil '()) => #f
         (equal? #nil #f) => #f

       However, in Elisp, `'()', `#f', and `nil' are all `equal' (though
    not `eq').

         (defvar f (make-scheme-false))
         (defvar eol (make-scheme-null))
         (eq f eol) => nil
         (eq nil eol) => nil
         (eq nil f) => nil
         (equal f eol) => t
         (equal nil eol) => t
         (equal nil f) => t

       These choices facilitate interoperability between Elisp and Scheme
    code, but they are not perfect. Some code that is correct standard
    Scheme is not correct in the presence of a second false and null value.
    For example:

         (define (truthiness x)
           (if (eq? x #f)
               #f
               #t))

       This code seems to be meant to test a value for truth, but now that
    there are two false values, `#f' and `nil', it is no longer correct.

       Similarly, there is the loop:

         (define (my-length l)
           (let lp ((l l) (len 0))
             (if (eq? l '())
                 len
                 (lp (cdr l) (1+ len)))))

       Here, `my-length' will raise an error if L is a `nil'-terminated
    list.

       Both of these examples are correct standard Scheme, but, depending on
    what they really want to do, they are not correct Guile Scheme.
    Correctly written, they would test the _properties_ of falsehood or
    nullity, not the individual members of that set. That is to say, they
    should use `not' or `null?' to test for falsehood or nullity, not `eq?'
    or `memv' or the like.

       Fortunately, using `not' and `null?' is in good style, so all
    well-written standard Scheme programs are correct, in Guile Scheme.

       Here are correct versions of the above examples:

         (define (truthiness* x)
           (if (not x)
               #f
               #t))
         ;; or: (define (t* x) (not (not x)))
         ;; or: (define (t** x) x)

         (define (my-length* l)
           (let lp ((l l) (len 0))
             (if (null? l)
                 len
                 (lp (cdr l) (1+ len)))))

       This problem has a mirror-image case in Elisp:

         (deffn my-falsep (x)
           (if (eq x nil)
               t
               nil))

       Guile can warn when compiling code that has equality comparisons with
    `#f', `'()', or `nil'. *Note Compilation::, for details.

    0.1.2.3 Dynamic Binding
    .......................

    0.1.2.4 Other Elisp Features
    ............................

    0.1.3 ECMAScript
    ----------------

    ECMAScript was not the first non-Schemey language implemented by Guile,
    but it was the first implemented for Guile's bytecode compiler. The goal
    was to support ECMAScript version 3.1, a relatively small language, but
    the implementor was completely irresponsible and got distracted by other
    things before finishing the standard library, and even some bits of the
    syntax. So, ECMAScript does deserve a mention in the manual, but it
    doesn't deserve an endorsement until its implementation is completed,
    perhaps by some more responsible hacker.

       In the meantime, the charitable user might investigate such
    invocations as `,L ecmascript' and `cat
    test-suite/tests/ecmascript.test'.


-- 
http://wingolog.org/




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

* Re: our nil story
  2010-04-16  8:54 our nil story Andy Wingo
@ 2010-04-16 12:12 ` Ludovic Courtès
  2010-04-16 15:42   ` Andy Wingo
  2010-04-16 12:35 ` Daniel Kraft
  1 sibling, 1 reply; 5+ messages in thread
From: Ludovic Courtès @ 2010-04-16 12:12 UTC (permalink / raw)
  To: guile-devel

Hi!

Andy Wingo <wingo@pobox.com> writes:

> Just updated some docs on other languages and nil. It's in master, but
> I'm pasting here for comments.

Cool!

>     0.1 Support for Other Languages
>     ===============================
>
>     In addition to Scheme, a user may write a Guile program in an increasing
>     number of other languages. Currently supported languages include Emacs
>     Lisp and ECMAScript.
>
>        Guile is still fundamentally a Scheme, but it tries to support a wide
>     variety of language building-blocks, so that a user can implement other
>     languages on top of Guile.

... and so that users can write or extend applications in languages
other than Scheme, too.

>        The easiest way to deal with syntax-heavy language is with files, via
>     `compile-file' and friends. However it is possible to invoke a
>     language's reader on a port, and then compile the resulting expression
>     (which is a datum at that point). For more information, *Note
>     Compilation::.

Perhaps mention ‘read-and-compile’?

>        On a low level, the bit representations for `#f', `#t', `nil', and
>     `'()' are made in such a way that the differ by only one bit, and so a

Typo: “that _they_ differ”.

>        Both of these examples are correct standard Scheme, but, depending on
>     what they really want to do, they are not correct Guile Scheme.
>     Correctly written, they would test the _properties_ of falsehood or
>     nullity, not the individual members of that set. That is to say, they
>     should use `not' or `null?' to test for falsehood or nullity, not `eq?'
>     or `memv' or the like.

Excellent!  I think the examples and explanations in this section make
it perfectly clear how things interoperate and what the pitfalls are.

>        Guile can warn when compiling code that has equality comparisons with
>     `#f', `'()', or `nil'. *Note Compilation::, for details.

Hmm, not yet, right?  :-)

>     0.1.2.3 Dynamic Binding
>     .......................

@xref{Fluids}?

>     0.1.3 ECMAScript
>     ----------------
>
>     ECMAScript was not the first non-Schemey language implemented by Guile,

@url{http://.../the-spec.html, ECMAScript} maybe.

>     but it was the first implemented for Guile's bytecode compiler. The goal
>     was to support ECMAScript version 3.1, a relatively small language, but
>     the implementor was completely irresponsible and got distracted by other
>     things before finishing the standard library, and even some bits of the
>     syntax. So, ECMAScript does deserve a mention in the manual, but it
>     doesn't deserve an endorsement until its implementation is completed,
>     perhaps by some more responsible hacker.
>
>        In the meantime, the charitable user might investigate such
>     invocations as `,L ecmascript' and `cat
>     test-suite/tests/ecmascript.test'.

Heh heh.  What’s your take on ES support for 2.0?

Mine is that “we” should make the basics work, as they used to back when
you implemented it, and fill in ecmascript.test.  IOW, nothing fancy,
but just basic compilation.

Thanks!

Ludo’.





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

* Re: our nil story
  2010-04-16  8:54 our nil story Andy Wingo
  2010-04-16 12:12 ` Ludovic Courtès
@ 2010-04-16 12:35 ` Daniel Kraft
  2010-04-16 15:24   ` Andy Wingo
  1 sibling, 1 reply; 5+ messages in thread
From: Daniel Kraft @ 2010-04-16 12:35 UTC (permalink / raw)
  To: Andy Wingo; +Cc: guile-devel

Hi Andy,

sounds good!  With regards to some elisp details (like dynamic binding 
or others), IIRC there's still some info about implementation details 
and other stuff that may be interesting in the 
module/languages/elisp/README file.  You probably are aware of it 
anyway, though ;)

Yours,
Daniel




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

* Re: our nil story
  2010-04-16 12:35 ` Daniel Kraft
@ 2010-04-16 15:24   ` Andy Wingo
  0 siblings, 0 replies; 5+ messages in thread
From: Andy Wingo @ 2010-04-16 15:24 UTC (permalink / raw)
  To: Daniel Kraft; +Cc: guile-devel

Hi Daniel,

On Fri 16 Apr 2010 14:35, Daniel Kraft <d@domob.eu> writes:

> IIRC there's still some info about implementation details and other
> stuff that may be interesting in the module/languages/elisp/README
> file. You probably are aware of it anyway, though ;)

I had forgotten about it, actually. Good stuff!

Andy
-- 
http://wingolog.org/




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

* Re: our nil story
  2010-04-16 12:12 ` Ludovic Courtès
@ 2010-04-16 15:42   ` Andy Wingo
  0 siblings, 0 replies; 5+ messages in thread
From: Andy Wingo @ 2010-04-16 15:42 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: guile-devel

Hi!

Thanks for the comments, I've folded them in. [In the future though,
patches will be just as acceptable ;-)]

On Fri 16 Apr 2010 14:12, ludo@gnu.org (Ludovic Courtès) writes:

>>        Guile can warn when compiling code that has equality comparisons with
>>     `#f', `'()', or `nil'. *Note Compilation::, for details.
>
> Hmm, not yet, right?  :-)

Indeed, but that means we just have to fix the implementation and not
the docs ;-)

> Heh heh.  What’s your take on ES support for 2.0?
>
> Mine is that “we” should make the basics work, as they used to back when
> you implemented it, and fill in ecmascript.test.  IOW, nothing fancy,
> but just basic compilation.

Probably so. "Let's" get at it, then ;-)

Andy
-- 
http://wingolog.org/




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

end of thread, other threads:[~2010-04-16 15:42 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-04-16  8:54 our nil story Andy Wingo
2010-04-16 12:12 ` Ludovic Courtès
2010-04-16 15:42   ` Andy Wingo
2010-04-16 12:35 ` Daniel Kraft
2010-04-16 15:24   ` Andy Wingo

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