gnu-arch-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gnu-arch-users] Re: new language, arch, furth, etc.


From: Tom Lord
Subject: [Gnu-arch-users] Re: new language, arch, furth, etc.
Date: Tue, 20 Jul 2004 08:57:44 -0700 (PDT)


(Language design for version variables, continued)


* Values (Types)

  The configuration language so far has the grammar:


        <program> := <assignment>*
        <assignment> := "(" "define" <name> <value> ")"

        <name> := <initial> <subsequent>*
        <initial> := <letter>
        <subsequent> := <letter> | "-" | <digit>

        <value> := ``a value''

  The definition of 

      ``a value'' 

  needs to be filled in.   What kinds of values can a configuration
  parameter be bound to?


** Wrong Answer: Just Strings

  One idea is that configuration parameters are just bound to strings
  and nothing more.

  That would work out just fine for many kinds of configuration.  For
  example:

        (define my-id "Tom Lord <address@hidden>")
        (define my-default-archive "address@hidden")

  But "just strings" falls apart fairly quickly.    The first
  indication it has gone wrong is if we imagine needing
  a number, rather than a string:


        (define my-tetris-high-score 15000)

  First, if that "15000" is supposed to represent a string, it's 
  at the very least an odd string syntax (seeing as how it sure looks
  more like a number).

  Second, who is supposed to convert that string, "15000", into the
  desired number?  If it's the code implementing the configuration
  langauge, fine --- but then the language has numbers and strings,
  not just strings.  If it's the application code _using_ the
  configuration language implementation, how can we be sure that all
  applications will conver "15000" to the same number?  More
  realisitically, will every application have to learn how to 
  convert a value like:


        (define java-magic-number #xCAFEBABE)

  Third, strings and numbers are arguably easily converted back and
  forth but what about something like this:

        ; (not actually valid code, for reasons to be
        ; explained later -- but close enough for this 
        ; example.)
        ; 
        (define my-revlib-path ("~/{revlib}"
                                "/usr/storage/lord/{revlib}"
                                "/usr/src/{revlib}"))

  where the goal is to, in effect, bind `my-revlib-path' to a _list_ 
  of simpler values.  It would be nasty to tell the
  application that the value of `my-revlib-path' is:

        "(\"~/{revlib}\"\n\t\t\"/usr/storage/lord/{revlib} ..."

  and expect the application to parse that into a list.


** Wrong Answer: Different Dialects, Different Types

  Another idea is let applications extend the language with
  application-specific types.  For example, an X11 server might define
  some "structure" types and perhaps other types as in this example:

        ; not real code
        ;
        (define display-list  ((display name       => "acme"
                                        resolution => 1024x800
                                        [...])

                               (display name       => "coyote"
                                        resolution => 500x500
                                        [...])
                                [...]))


  The implication of that example is that the X11 server has
  extended the configuration language with definitions for
  "display" and with a type for representing pairs of integers
  such as 1024x800.

  That'd be fine for many purposes but what would happen if 
  some application _other_ than the X server wanted to read
  that config file.   What would that other application make
  of "display" or "1024x800"?   It would be hard if not impossible,
  for example, to write a generic program that could read any
  config file, for any application, and report what some of the
  settings are.


** Best Answer I Know:  Generic, Extensional Types
  
  An alternative to lots of application-specific types is to have 
  a small, fixed number of generic types out of which
  application-specific types can be built.

  For example, many applications will need "lists" or "sets" 
  of simpler values:  a generic `sequence' type would answer 
  their need.

  A special need like the X servers need for pairs of integers
  ("1024x800") can be seen as a special case: the X server can
  use a generic list of two integers.

  The choice of which generic types to support is fairly arbitrary.

  Lisp family languages offer one traditional choice (e.g., symbols,
  numbers, strings, cons-pairs, and arrays).  I decided not to use
  lisp types because they are, in part, a little too level for our
  needs: cons-pairs and arrays rather than simply "sequences"; no
  particularly clean way to make a structure-like type.

  Instead, I settled on this (which is very close to Lisp but uses a
  generic sequence type and provides a lua-like or python-like
  associative type for structures):


        <value> := <number-exp> 
                | <symbol-exp>
                | <string-exp>
                | <sequence-exp>
                | <assoc-exp>



        <nested-value> := <number-exp>
                       | <name>
                       | <string-exp>
                       | <sequence>
                       | <assoc>


        <number-exp> := ``a number in "the usual" notation''

        <symbol-exp> := "'" <name>
                     | "(" "quote" <name> ")"

        <string-exp> := ``a string in "the usual" quoted notation''

        <sequence-exp> := "'" <sequence>
                       |  "(" "quote" <sequence> ")"

        <sequence> := "(" <nested-value>* ")"

        <assoc-exp> := "'" <assoc>
                    |  "(" "quote" <assoc> ")"

        <assoc> := "{" <assoc-binding>* "}"

        <assoc-binding> := <name> "=>" <nested-value>


  The resulting language looks like this:

        (define display-list  '( {
                                   name       => "acme"
                                   resolution => (1024 800)
                                   [...]
                                 }

                                 {
                                   name       => "coyote"
                                   resolution => (500 500)
                                   [...]
                                 }

                                 [...]))

  Any implementation of the configuration language can parse and
  interpret that file since it consists only of generic data types.

  An X server can still treat this data in an application-specific
  way:  it can verify, for example, that all elements of the
  `display-list' are associative values with the required fields.

  
** Sneaky Feature: Quoting

  The grammar above contains a feature that is currently inexplicable
  and unjustifiable: quoting.

  In that grammar, one can define a name to be a number very simply:

        (define x 123)

  but defining a name to be a _list_ of numbers is weirder.  You might
  think it should be:

        (define x (1 2 3))

  and, indeed, nothing in the language design so far gives any reason 
  why that shouldn't work.

  However, I have "information from the future" in the sense that
  I already know some additional features we'll add to the langauge.
  Those additional features will require "quoting".   So, 
  to binding a name to a list, you need to use either:

        ; single quote quoting:
        ; 
        (define x '(1 2 3))

  or

        ; spelled-out quoting
        ; 
        (define x (quote (1 2 3)))


  Those two are in every way equivalent.  The single-quote form is
  just a short-hand for the spelled-out form.

  There is, at this point, no explanation for why quoting is needed.
  At this point in the design, it can be regarded as just some 
  arbitrary and slightly superfluous syntax.



-t





reply via email to

[Prev in Thread] Current Thread [Next in Thread]