From leavens@cs.iastate.edu Thu Apr 8 21:38:03 2004 Date: Thu, 8 Apr 2004 21:30:41 -0500 (CDT) From: Gary T. Leavens To: Jason Cook Cc: cs342s@cs.iastate.edu Subject: Re: Homework 7 Problem 3 Hi Jason, On Thu, 8 Apr 2004, Jason Cook wrote: > I don't know how to start this problem. Where would you add/modify > code so that it would know that it has the incorrect number of > arguments? You compare two things: - the length of the list of formal parameters stored in the closure being applied, - the length of the list of actual parameter expressions given in the app-exp. > The actual procedure is called in the "in" part of a let, > so does this mean that I need to modify the code in a let-exp? No. If you mean that the call to apply-procval takes place within a Scheme let (in figure 3.7 on p. 88, for example) then you are confusing levels of the defined language and Scheme (the language we're using to write the interpreters). If you mean that the call happens in test data (defined language program inputs) that use a let-exp in the defined language, that is true but irrelevant; it might also be inside an if or a primapp-exp as well. > If > not, I don't understand how closure or proc-exp would know about it. The app-exp is where the procedures are applied. Try a simple example using $PUB/lib/3-5-reducer.scm, or trace the eval-expression procedure on a simple example to see what's happening. > Could you clarify as to where the code changes occur in these files? In the app-exp case. -- Gary T. Leavens Department of Computer Science, Iowa State University 229 Atanasoff Hall, Ames, Iowa 50011-1041 USA http://www.cs.iastate.edu/~leavens phone: +1-515-294-1580 ---------------------------------- From leavens@cs.iastate.edu Thu Apr 8 21:39:01 2004 Date: Thu, 8 Apr 2004 21:37:40 -0500 (CDT) From: Gary T. Leavens To: Jason Cook Cc: cs342s@cs.iastate.edu Subject: Re: Homework 7 Traceproc Hi Jason, On Thu, 8 Apr 2004, Jason Cook wrote: > How do we actually do the tracing for this problem? In the interpreter's code for the traceproc-exp. > Do we use the [Scheme] > procedure trace? No. > If so, is there any example of this procedure > anywhere so I know what it takes and how it works? (There is some quick documentation in http://www.cs.iastate.edu/~cs342/docs/debugging-chez-scheme.txt which has a pointer to more docuentation) > If not, how do we > trace all of the calls, and how do we have it print out information > like that? You will have to do some printing whenever the interpreter is evaluating the body of a traceproc expression. Think about when in the interpreter that happens. You might want to use the Scheme trace procedure to get a feel for when this happens. I leave it as a logical puzzle to figure out how to do this... > Here's what I've tried so far: > > (traceproc-exp (ids body) (trace > (procval->expressed > (closure ids body env)))) That is not right. > Which gives an error because trace returns nothing so this cases > clause is void? Yes. > So then I tried this: > > (traceproc-exp (ids body) (trace > (procval->expressed > (closure ids body env))) > (procval->expressed > (closure ids body env))) > > Thinking maybe it would trace it and return nothing, and then actually > evaluate it. But that gave a syntax error. Right, that also doesn't work. > I really do not understand how to do these types of problems. I > understood last homework a lot better, but this seems on a completely > different tangent to me and I'm not sure how to get this homework > done. What you should do is to try to be sure you understand the way that the interpreter processes proc expressions. If it helps, use $PUB/lib/3-5-reducer.scm or trace 3-5.scm to help see what's happening. Be sure to read section 3.5 in the book. Then just think, without coding first. > Are you sure there is no way this can get pushed back until the > following week so that I/we can have some time to study for the test? Yes. > I already know I will spend almost the whole weekend doing this > assignment. I hope not. -- Gary T. Leavens Department of Computer Science, Iowa State University 229 Atanasoff Hall, Ames, Iowa 50011-1041 USA http://www.cs.iastate.edu/~leavens phone: +1-515-294-1580 ---------------------- From leavens@cs.iastate.edu Thu Apr 8 21:54:06 2004 Date: Thu, 8 Apr 2004 21:53:51 -0500 (CDT) From: Gary T. Leavens To: Jason Cook Cc: cs342s@cs.iastate.edu Subject: Re: HW7 Problem 5 Hi Jason, On Thu, 8 Apr 2004, Jason Cook wrote: > Ok, disregard my previous email question for problem 5. Too late! I just replied... But I still think that the reply may be helpful, even if you've moved on... > Now my only > question is, how are we supposed to get the value what is being called > in the "in" part of the let for a traceproc? > > For example: > > (run "+(3, let double = traceproc(z) *(z,2) in (double 3))") > Call of traceproc(z) with arguments: > (3) > > How do we get the (3) out of (double 3)? It's passed as an argument to an app-exp. > This is part of the let-exp > isn't it? No, the let-exp is a red herring (irrelevant). The same output would be produced by the following: (run "+(3, (traceproc(z) *(z,2) 3))") > How can we get arguments from the let-exp while in the > traceproc-exp? Because we only have ids and body to work with right? > And ids will only return (z) and body *(z,2). Consider the following trace of the 3-5.scm interpreter. In it you can see the app-exp is evaluated by first making a closure out of the proc-exp and then the app-exp is evaluated, which calls apply-procval. See that the arguments to apply-procval are the closure and the argument list. These have all the information you need... typed> (trace eval-expression apply-procval) (eval-expression apply-procval) : void typed> (run "+(3, (proc(z) *(z,2) 3))") |(eval-expression (primapp-exp (add-prim) ((lit-exp 3) (app-exp (proc-exp (z) (primapp-exp (mult-prim) ((var-exp z) (lit-exp 2)))) ((lit-exp 3))))) (extended-env-record (i v x) #(1 5 10) (empty-env-record))) | (eval-expression (app-exp (proc-exp (z) (primapp-exp (mult-prim) ((var-exp z) (lit-exp 2)))) ((lit-exp 3))) (extended-env-record (i v x) #(1 5 10) (empty-env-record))) | |(eval-expression (lit-exp 3) (extended-env-record (i v x) #(1 5 10) (empty-env-record))) | |3 | |(eval-expression (proc-exp (z) (primapp-exp (mult-prim) ((var-exp z) (lit-exp 2)))) (extended-env-record (i v x) #(1 5 10) (empty-env-record))) | |(closure (z) (primapp-exp (mult-prim) ((var-exp z) (lit-exp 2))) (extended-env-record (i v x) #(1 5 10) (empty-env-record))) | (apply-procval (closure (z) (primapp-exp (mult-prim) ((var-exp z) (lit-exp 2))) (extended-env-record (i v x) #(1 5 10) (empty-env-record))) (3)) | (eval-expression (primapp-exp (mult-prim) ((var-exp z) (lit-exp 2))) (extended-env-record (z) #(3) (extended-env-record (i v x) #(1 5 10) (empty-env-record)))) | |(eval-expression (lit-exp 2) (extended-env-record (z) #(3) (extended-env-record (i v x) #(1 5 10) (empty-env-record)))) | |2 | |(eval-expression (var-exp z) (extended-env-record (z) #(3) (extended-env-record (i v x) #(1 5 10) (empty-env-record)))) | |3 | 6 | (eval-expression (lit-exp 3) (extended-env-record (i v x) #(1 5 10) (empty-env-record))) | 3 |9 9 : expressed-value I'm not sure it helps, but it might be easier to follow this with the reducer tool I put in the library: typed> (load "3-5-reducer.scm") Type checking "3-5-reducer.scm" ... ... typed> (run "+(3, (proc(z) *(z,2) 3))") (eval-expression <<+(3, (proc(z) *(z, 2) 3))>> (empty-env)) = { by proc-exp case of eval-expression } (eval-expression <<+(3, ((closure '(z) <<*(z, 2)>> (empty-env)) 3))>> (empty-env)) = { by app-exp case of eval-expression } (eval-expression <<+(3, (unfinished <<*(z, 2)>> (extend-env '(z) (list 3) (empty-env))))>> (empty-env)) = { by var-exp case of eval-expression } (eval-expression <<+(3, (unfinished <<*(3, 2)>> (extend-env '(z) (list 3) (empty-env))))>> (empty-env)) = { by primapp-exp case of eval-expression } (eval-expression <<+(3, (unfinished <<6>> (extend-env '(z) (list 3) (empty-env))))>> (empty-env)) = { by recognizing the formerly unfinished expression is finished } (eval-expression <<+(3, 6)>> (empty-env)) = { by primapp-exp case of eval-expression } 9 : expressed-value typed> > Any good nudges in the right directions would be extremely appreciated. I hope the above help. Of course, in this problem you'll have a traceproc-exp instead of a proc-exp, but we are applying them with app-exps, so the code for the app-exp case will also execute. So if you use the standard closures, by the time you get to the app-exp, you won't have enough information to do any output. That is the problem (hint, hint). -- Gary T. Leavens Department of Computer Science, Iowa State University 229 Atanasoff Hall, Ames, Iowa 50011-1041 USA http://www.cs.iastate.edu/~leavens phone: +1-515-294-1580 -------------------------- From leavens@cs.iastate.edu Thu Apr 8 22:00:06 2004 Date: Thu, 8 Apr 2004 21:59:04 -0500 (CDT) From: Gary T. Leavens To: ehennis@iastate.edu Cc: cs342s@cs.iastate.edu Subject: Re: Hw7, problem 2 Hi Evan, On Thu, 8 Apr 2004 ehennis@iastate.edu wrote: > I was trying to start homework 7. I am working on question #2. > Currently I just typed in the makemult procedure from the book. How do > I execute the let that I just wrote? My code loads ok but I was just > trying to see if I got the code right. First load the 3.5 interpreter (load-from-lib "3-5.scm") Then either: - use the run procedure and put your code in the string argument, like (run "..."), or - use the (read-eval-print) procedure and paste your code in at the prompt. I suggest putting the code in a file and editing from there to save retyping. The easist thing to do is to make a file that looks like: ;;; Scheme code (load-from-lib "3-5.scm") (run "... your code here ...") Then you edit the part in the call to run. To test, simply load that file into Scheme (use Scheme's load procedure). This is suggested in the homework file. -- Gary T. Leavens Department of Computer Science, Iowa State University 229 Atanasoff Hall, Ames, Iowa 50011-1041 USA http://www.cs.iastate.edu/~leavens phone: +1-515-294-1580 ---------------------------- From leavens@cs.iastate.edu Fri Apr 9 16:42:35 2004 Date: Fri, 9 Apr 2004 16:42:12 -0500 (CDT) From: Gary T. Leavens To: Eric Douglas Nath Cc: cs342s@cs.iastate.edu Subject: Re: one more HW 6 question.... Hi Eric, On Fri, 9 Apr 2004, Eric Douglas Nath wrote: > Hi again, sorry :( I figured out that problem I had earlier, although I am not sure how > that works... That's fine. > you simply have code > like (+ (car args) (cadr args))... how does that automatically recurse, and deal > with expressions that might not be > literals? This confused me. The environment is taken into account in the primapp-exp case of eval-expression. Take a look at that. That is where apply-primitive is called. Before the call the actual argument expressions are evaluated by calling eval-rands, which calls eval-rand, which (in this interpreter) just calls eval-expression; all of these take the environment. So a list of expressed values is passed to apply-primitive, not a list of expressions. > my other question is simpler: I can't seem to get my minus to work, although it looks > perfect to me: > > (minus-prim () ((number->expressed (- (expressed->number (car args)))))) > > It gives me the error "Attempt to apply non-procedure > Not a procedure: (number->expressed (- (expressed->number (car args)))) > Inferred type : expressed-value", but when I tested everything, I'm sure I have > everything casted properly. You have an extra set of parentheses around the expression given in the error message. Take those out and it will work fine. -- Gary T. Leavens Department of Computer Science, Iowa State University 229 Atanasoff Hall, Ames, Iowa 50011-1041 USA http://www.cs.iastate.edu/~leavens phone: +1-515-294-1580 From leavens@cs.iastate.edu Sun Apr 11 18:35:34 2004 Date: Sun, 11 Apr 2004 18:34:57 -0500 (CDT) From: Gary T. Leavens To: David Gillingham Cc: cs342s@cs.iastate.edu Subject: Re: [hw7] output question Hi David, On Sun, 11 Apr 2004, David Gillingham wrote: > In problems 3 and 5, we are expected to throw output to the screen. Are we > expected to exactly match your output or can we create our own format? For > example, in problem 3, is it sufficient to simply output an error that > states than an incorrect number of arguments were passed? You don't have to match exactly my formatting. For the incorrect number of arguments, it would be helpful to note in the message what the two numbers are, however. There are some Q&A messages relating to how to use eopl:error if that's giving you trouble. See $PUB/lib/r5rs.scm for more about eopl:error. -- Gary T. Leavens Department of Computer Science, Iowa State University 229 Atanasoff Hall, Ames, Iowa 50011-1041 USA http://www.cs.iastate.edu/~leavens phone: +1-515-294-1580 -------------------------------- From leavens@cs.iastate.edu Mon Apr 12 17:39:10 2004 Date: Mon, 12 Apr 2004 17:37:52 -0500 (CDT) From: Gary T. Leavens To: Jacob Lynch Cc: Computer Science 342 Staff Subject: Re: HW7 Problem 8 Hi Jacob, On Mon, 12 Apr 2004, Jacob Lynch wrote: > Well, for this problem I think I have the my-3-5-dynamic.scm figured out > alright, but the proctext-as-proc.scm has me completely confused. I've > tried a few things, but I don't really have a single clue what I'm supposed > to be going for here. Is there a place I can read on this, or could you > give me a tip? The book (from what I've seen so far) just treats this like > something we should figure out easily. I've looked at the lecture notes > about dynamic binding, and they seem to be examples of what it > produces. Essentially a proctext is just like a closure, but without the environment. > For the text procedure, well, I'm not even sure what that does. A proctext is a way of representing the information in a proc-exp for later use by the app-exp case of the interpreter. > I guess it > makes a list of symbols and an expression into a proctext, but I don't know > how. It just remembers them. If it helps, think of the procedural version. > The apply-proctext seems like you're supposed to [call?] eval-expression, > but I don't have a body or ids, so I don't know what to do there. I thought > maybe we could get it from the proctext, but I don't know to do that either. > Thanks in advance for any help! The equation that apply-proctext is supposed to satisfy is the following: (apply-proctext (proctext ids body) args env) = (eval-expression body (extend-env ids args env)) That should be sufficient to code apply-proctext in the procedural representation. You can also transform that to the AST representation... -- Gary T. Leavens Department of Computer Science, Iowa State University 229 Atanasoff Hall, Ames, Iowa 50011-1041 USA http://www.cs.iastate.edu/~leavens phone: +1-515-294-1580 ------------------------------------- From leavens@cs.iastate.edu Mon Apr 12 20:02:30 2004 Date: Mon, 12 Apr 2004 20:01:52 -0500 (CDT) From: Gary T. Leavens To: Jacob Lynch Cc: Computer Science 342 Staff Subject: RE: HW7 Problem 8 Hi Jacob, Start from the premise that there are two operations you have to define: (deftype text (-> ((list-of symbol) expression) proctext)) (deftype apply-proctext (-> (proctext (list-of Expressed-Value) environment) Expressed-Value)) and also you need to provide: (deftype proctext? (type-predicate-for proctext)) Then go back to what I said that relates these (with appropriate subsitution of text for proctext, as you don't want the procedure that creates a type to have the same name as the type for the procedural to AST transform): (apply-proctext (text ids body) args env) = (eval-expression body (extend-env ids args env)) Then think about which is the constructor and which is the observer. In the procedural version the observer is easy to define. And the body of the lambda that the constructor returns is pretty well given by the equation above... -- Gary T. Leavens Department of Computer Science, Iowa State University 229 Atanasoff Hall, Ames, Iowa 50011-1041 USA http://www.cs.iastate.edu/~leavens phone: +1-515-294-1580 ------------------------------------------------ From leavens@cs.iastate.edu Tue Apr 13 00:30:14 2004 Date: Tue, 13 Apr 2004 00:02:09 -0500 (CDT) From: Gary T. Leavens To: David Gillingham Cc: cs342s@cs.iastate.edu Subject: Re: [hw7] problem 5 type-checking problem Hi David, On Mon, 12 Apr 2004, David Gillingham wrote: > I think I have the idea behind problem 5 figured out, but I'm getting a > type-checking error that I can't figure out. This is the error that the > typed interpreter is returning: > > my-3-5.scm: lines 155 to 161: Unknown variable: procval Your typechecking problem with the solution to problem 5 is similar to the problem mentioned in my Saturday email of Saturday (also on the web page). The problem for type checking is that the name procval is hidden in my-procval-as-ast.scm. So the solution is, as in problem 3, to put the soution code for this problem in the file my-procval-as-ast.scm file, not in my-3-5.scm. So do it by modifying apply-procval in my-procval-as-ast.scm. (In this case it's an abstraction violation for you to be working with the papticular representation of procval in my-3-5.scm, instead of allowing it to only be known in my-procval-as-ast.scm.) -- Gary T. Leavens Department of Computer Science, Iowa State University 229 Atanasoff Hall, Ames, Iowa 50011-1041 USA http://www.cs.iastate.edu/~leavens phone: +1-515-294-1580 ------------------------------ From leavens@cs.iastate.edu Tue Apr 13 00:30:46 2004 Date: Tue, 13 Apr 2004 00:29:45 -0500 (CDT) From: Gary T. Leavens To: Jacob Lynch Cc: Computer Science 342 Staff Subject: RE: HW7 Problem 8 Hi Jacob, On Mon, 12 Apr 2004, Jacob Lynch wrote: > Oh, just so you know, I believe that text is the constructor, and apply-proc > is the observer. Yes. > If that's wrong, well then, I'm really messed up. You are not messed up. > As far > as the body of lambda goes for the constructor being in the equation, it > just doesn't seem like calling apply-proc with those arguments would be the > right thing to do (infinite loop), and I don't know what else to do there > besides just return (ids body), which is what I have it at right > now. In the procedural rep you return a Scheme closure, made by Scheme's lambda. > The > ol' apply-proc has me confused, though. I don't know how we convert that > list of expressed values to one expressed value. I've tried passing args to > proc, but it says it's the wrong number of arguments. Perhaps, I'll sort it > out with you tomorrow, thanks! It may help to think of the equation that governs apply-procval in lexical scoping: (apply-procval (closure ids body env) args) = (eval-expression body (extend-env ids args env)) So in the procedural representation of this we wrote: (define closure (lambda (ids body env) (lambda (args) (eval-expression body (extend-env ids args env))))) (define apply-procval (lambda (proc args) (proc args))) The reason that works comes from substituting these back in the equation (ignoring type casts for clarity): (apply-procval (closure ids body env) args) = { by definition of apply-procval } ((lambda (proc args) (proc args)) (closure ids body env) args) = { by definition of closure } ((lambda (proc args) (proc args)) ((lambda (ids body env) (lambda (args) (eval-expression body (extend-env ids args env)))) ids body env) args) = { by definition of application of a lambda in Scheme (on the 2nd lambda) } ((lambda (proc args) (proc args)) (lambda (args) (eval-expression body (extend-env ids args env))) args) = { by definition of application of a lambda in Scheme (on the 1st lambda) } ((lambda (args) (eval-expression body (extend-env ids args env))) args) = { by definition of application of a lambda in Scheme } (eval-expression body (extend-env ids args env)) Or you can think of it the other way around: If we want the equation (apply-procval (closure ids body env) args) = (eval-expression body (extend-env ids args env)) to hold, we have to have apply-procval take 2 arguments... (define apply-procval (lambda (proc args) ....)) and since this is a procedural rep and apply-procval is an observer, we want to just apply the procedure: (define apply-procval (lambda (proc args) (proc args))) That means that in the constructor, we'll have the 3 arguments it's passed: (define closure (lambda (ids body env) ...)) and we need to return a procedure (Scheme closure) that, from the definition of apply-procval takes 1 argument, which is a list of expressed values, so it looks like (define closure (lambda (ids body env) (lambda (args) ; this was the one argument given by the observer ...)) and we have to make it satisfy the equation above. Well, to make the result be (eval-expression body (extend-env ids args env)) since we have all those parts, we just stick that desired result in the body of closure: (define closure (lambda (ids body env) (lambda (args) (eval-expression body (extend-env ids args env))))) Try the same process with the equation I gave you... > > (apply-proctext (text ids body) args env) > > = (eval-expression body (extend-env ids args env)) -- Gary T. Leavens Department of Computer Science, Iowa State University 229 Atanasoff Hall, Ames, Iowa 50011-1041 USA http://www.cs.iastate.edu/~leavens phone: +1-515-294-1580