Re: [racket] How to create 'Internal Definitions' in a schemeinterpreter.

2010-07-24 Thread Jos Koot
Yes, I did not think of that (rather new) feature.
Thanks for reminding me.
Jos. 

> -Original Message-
> From: [email protected] 
> [mailto:[email protected]] On Behalf Of Carl Eastlund
> Sent: 24 July 2010 19:20
> To: Jos Koot
> Cc: Pedro Del Gallego; [email protected]
> Subject: Re: [racket] How to create 'Internal Definitions' in 
> a schemeinterpreter.
> 
> On Sat, Jul 24, 2010 at 1:11 PM, Jos Koot 
>  wrote:
> > I did not study your interpreter thoroughly, but I see you 
> use a hash 
> > for an environment. This is bound to go wrong, for the same 
> variable 
> > may have different bindings in nested scopes. You'll need a 
> stack, or 
> > an association-list or something like that, in which 
> variables may be 
> > shaddowed.
> 
> Or replace the mutable hash table with an immutable hash 
> table.  They support functional update, so you can extend 
> them and pass them around, but you get efficient hash table 
> lookup for free.
> 
> --Carl


_
  For list-related administrative tasks:
  http://lists.racket-lang.org/listinfo/users


Re: [racket] How to create 'Internal Definitions' in a schemeinterpreter.

2010-07-24 Thread Carl Eastlund
On Sat, Jul 24, 2010 at 1:11 PM, Jos Koot  wrote:
> I did not study your interpreter thoroughly, but I see you use a hash for an
> environment. This is bound to go wrong, for the same variable may have
> different bindings in nested scopes. You'll need a stack, or an
> association-list or something like that, in which variables may be
> shaddowed.

Or replace the mutable hash table with an immutable hash table.  They
support functional update, so you can extend them and pass them
around, but you get efficient hash table lookup for free.

--Carl
_
  For list-related administrative tasks:
  http://lists.racket-lang.org/listinfo/users


Re: [racket] How to create 'Internal Definitions' in a schemeinterpreter.

2010-07-24 Thread Jos Koot
I did not study your interpreter thoroughly, but I see you use a hash for an
environment. This is bound to go wrong, for the same variable may have
different bindings in nested scopes. You'll need a stack, or an
association-list or something like that, in which variables may be
shaddowed. Your interpreter is bound to give a wrong result for:

(let ((a 1))
  (let ((a 2))'who-cares)
  a)

This should produce 2, but I guess your interpreter returns -who-cares-.

Internal definitions are tricky if you allow -define- to be rebound as in
((lambda (define a) (define a 2)) + 3)
When evaluating (define a 2), you have to check what -define- means in the
current context.
For example:

(let ((a 3) (b 4))
  (define (define a b) (+ a b))
  (define a b)) -> 5

A simple means to avoid these problems is to exclude the names of (some)
syntactic forms from being used as variables (but that is not scheme like).
Following what Matthias already said: first carefully describe your language
(syntactic forms, expressions and primitive functions included). That is
already difficult enough.

Jos

> -Original Message-
> From: [email protected] 
> [mailto:[email protected]] On Behalf Of Pedro Del Gallego
> Sent: 24 July 2010 18:28
> To: [email protected]
> Subject: [racket] How to create 'Internal Definitions' in a 
> schemeinterpreter.
> 
> Hi,
> 
> I am writing my first interpreter, but  I am struggling with 
> the definitions of  'define', 'let' and 'letrec'.
> 
> Here is the source code intrepreter (> 100 loc) . 
> http://gist.github.com/487501
> 
> The problem is that 'define' requires access to the 
> enviroment. I as understand define is equivalent to these expansions.
> 
>  Top level.
> (define (foo)
>(... (bar) ...))
> 
> => Will be
> 
> (define foo
> (lambda ()
>(... (bar) ...)))
> 
> 
>  In a lambda environment.
> 
> (define (my-proc)
>(define (local-proc-1)
>   ...)
>(define (local-proc-2)
>   ...)
>(local-proc-1)
>(local-proc-1))
> 
> => Will be
> 
> (define my-proc
> (lambda ()
>(letrec ((local-proc-1 (lambda () ...))
> (local-proc-2 (lambda () ...)))
>  (local-proc-1)
>  (local-proc-2)))
> 
> Can anyone point me how to implement this features. I am 
> trying to implement them out of the evaluator function, but I 
> guess that if they need access to the environment, maybe they 
> should be inside of the evaluator method. Maybe something like this?
> 
> [`(letrec ,binds ,eb)
>   (eval-letrec binds eb env)]
> 
> [`(let,binds ,eb)
>   (eval-let binds eb env)]
> 
> ; eval for letrec:
> (define (eval-letrec bindings body env)
>   (let* ((vars (map car bindings))
>  (exps (map cadr bindings))
>  (fs   (map (lambda _ #f) bindings))
>  (env* (extended-env* env vars fs))
>  (vals (map (evlis env*) exps)))
> (env-set!* env* vars vals)
> (eval body env*)))
> 
> ; eval for let:
> (define (eval-let bindings body env)
>   (let* ((vars (map car bindings))
>  (exps (map cadr bindings))
>  (vals (map (evlis env) exps))
>  (env* (extended-env* env vars vals)))
> (eval body env*)))
> 
> (define ? )
> 
> I am new in this list, so let me know if this question is "off-topic".
> 
> 
> Thx.
> --
> -
> Pedro Del Gallego
> 
> Email              :   [email protected] 
> _
>   For list-related administrative tasks:
>   http://lists.racket-lang.org/listinfo/users


_
  For list-related administrative tasks:
  http://lists.racket-lang.org/listinfo/users