Home     |     .Net Programming    |     cSharp Home    |     Sql Server Home    |     Javascript / Client Side Development     |     Ajax Programming

Ruby on Rails Development     |     Perl Programming     |     C Programming Language     |     C++ Programming     |     IT Jobs

Python Programming Language     |     Laptop Suggestions?    |     TCL Scripting     |     Fortran Programming     |     Scheme Programming Language


 
 
Cervo Technologies
The Right Source to Outsource

MS Dynamics CRM 3.0

Scheme Programming Language

define-datatype and scope


I understand how the top-level variables f and target are bound to
/undefined/ and then assigned to (R5RS 7.2 If P is a program [etc] then the
meaning of P is [etc]) Therefore, the identifier target in the body of f is
in scope.

(define f
  (lambda (x)
    target))

(define target 1)

(f 2) ;=> 1

- - - - - - - - - -
Why doesn't it work the same way here?

(define f
  (lambda (x)
    (cases target x
      (direct-target (v) #t)
      (indirect-target (v) #f))))

(define-datatype target target?
  (direct-target (v number?))
  (indirect-target (v target?)))

cases: not a datatype name in: target

Marlene Miller skrev:

By design.

It is the programmer (Flatt?) that wrote the cases
macro, that decided to make it an error. The fail-early
principle is in my experience to be preferred over
delaying errors.

Note that the PLT Scheme implementation of the EOPL
define-datatype is different from the one that's
online at the book homepage. If you choose the R5RS langauge
in DrScheme, open

<http://www.cs.indiana.edu/eopl/code/interps/define-datatype.scm>,

add
   (define eopl:error (lambda (x) (/ x 0)))
this line at the top, and inserts your example
at the bottom, you'll notice that no error is
reported.

That is, both behaviours make sense.

--
Jens Axel Sgaard

"Jens Axel Sgaard" skrev:

Is it an error because they decided we shouldn't refer to a datatype before
it is declared, or is it an error because the datatype name is not a
top-level variable (which can be referred to before it is defined)?

The error is good, because I didn't realize the dependencies of the two
macros in separate files. But all macros have to be defined at the top. I
haven't figured out how to package things in Scheme.

; - - - - - - - - - -
PLT Scheme, Language Standard (R5RS)

(define-syntax define-datatype
  (syntax-rules ()
    ((_ Type-name Type-name?
       (Variant-name (Field-name Pred?) ...)
       ...)
     (begin
       (define Type-name
         (cons '(Variant-name ...)
           '((Variant-name Field-name ...) ...)))
       (define Type-name? (lambda (x) #t))
       (define Variant-name
         (lambda args (cons 'Variant-name args)))
       ...))))

(define-datatype target target?
  (direct-target (v number?))
  (indirect-target (v target?)))

target
;((direct-target indirect-target) (direct-target v) (indirect-target v))

It looks like the identifier target is a top-level variable.

;- - - - - - - - - -
PLT Scheme, Language: EOPL

(define-datatype target target?
  (direct-target (v number?))
  (indirect-target (v target?)))

target
;target: illegal use of syntax in: target

The identifier target is not a top-level variable? It is something else?

Is the definition of the PLT Scheme define-datatype available for ordinary
people to read?

Marlene Miller skrev:

> Is the definition of the PLT Scheme define-datatype available for ordinary
> people to read?

<http://ja.soegaard.net/planet/html/collects/eopl/datatype.ss>

--
Jens Axel Sgaard

Marlene Miller skrev:

> Is it an error because they decided we shouldn't refer to a datatype before
> it is declared, or is it an error because the datatype name is not a
> top-level variable (which can be referred to before it is defined)?

Because they (Flatt?) decided it should be that way.

> The error is good, because I didn't realize the dependencies of the two
> macros in separate files.

Agree.

> But all macros have to be defined at the top. I
> haven't figured out how to package things in Scheme.

I am not sure what you are thinking of here.
Are you talking about your own macros or the macros
definining define-datatype ?

If the latter, you can use define-datatype in a non-EOPL
langauge like this:

     (require (lib "datatype.ss" "eopl"))

 > ; - - - - - - - - - -

> PLT Scheme, Language Standard (R5RS)

> (define-syntax define-datatype
>   (syntax-rules ()

> target
> ;((direct-target indirect-target) (direct-target v) (indirect-target v))

> It looks like the identifier target is a top-level variable.

Yes, that's the way the book authors defined it. [They needed R5RS
compability, so they stricter requirements than Flatt].

> ;- - - - - - - - - -
> PLT Scheme, Language: EOPL

> (define-datatype target target?
>   (direct-target (v number?))
>   (indirect-target (v target?)))

> target
> ;target: illegal use of syntax in: target

> The identifier target is not a top-level variable? It is something else?

Yes.

   (define-syntax define-datatype
     (lambda (stx)
       (syntax-case stx ()
        [(_ name pred-name
            (variant-name (field-name field-pred) ...)
            ...)
         <a lot deleted>
         (define-syntax name
          (let ([cert (syntax-local-certifier)])
            (make-dt (cert (syntax pred-name))
                     (list
                      (make-vt (cert (syntax variant-name))
                               (cert (syntax variant?))
                               (cert (syntax variant-accessor))
                               variant-field-count)
                      ...))))
          <more deleted>

This means that name (i.e. target in the example) is bound in the
transfomer environment (that is, as syntax). It isn't bound to
a macro transformer, but to a value, a dt-structure, that represents
the datatype to be defined.

This value is used by the cases macro. As an example, it starts
with

  (let ([dt (and (identifier? (syntax datatype))
                 (syntax-local-value (syntax datatype)
                                     (lambda () #f)))])
           (unless (dt? dt)
             (raise-syntax-error
              'cases
              "not a datatype name"
              stx
              (syntax datatype)))

which checks that the datatype has been defined previously.
Later we see check the check that a variant mentioned in
the use of cases actually is a variant of the datatype.

   (let* ([variant (syntax variant)]
         [vt
          (ormap (lambda (dtv)
                   (let ([vt-name (vt-name-stx dtv)])
                     (and (module-identifier=? variant vt-name)
                          dtv)))
                 (dt-variants dt))]
          [orig-variant (and vt (vt-name-stx vt))])
     (unless orig-variant
       (raise-syntax-error #f
         (format "not a variant of `~a'"
           (syntax-object->datum (syntax datatype)))
            stx variant))

The source is at:

<http://ja.soegaard.net/planet/html/collects/eopl/datatype.ss>

--
Jens Axel Sgaard

Add to del.icio.us | Digg this | Stumble it | Powered by Megasolutions Inc