Question: Programming in F# My program works but one test case does not This is the question : My code is: let example1 : expr =

Programming in F#

My program works but one test case does not

This is the question :

Programming in F# My program works but one test case does not

This is the question : My code is: let example1 : expr

My code is:

let example1 : expr =

LetFun ("f", "w", Let ("x", Num 2, Let ("y", Num 3, LetFun ("g", "z", Plus (Plus (Var "x", Var "y"), Var "z"), ["x"; "y"], Call ("g", Var "w")))), [], Call ("f", Num 4))

let example2 : expr =

LetFun ("f", "w", Let ("x", Num 2, Let ("y", Num 3, LetFun ("g", "z", Plus (Plus (Var "x", Var "y"), Var "z"), ["x"], Call ("g", Var "w")))), [], Call ("f", Num 4))

let rec eval (e : expr) (env : value envir) (fenv : closure envir) : value =

match e with

| Var x -> lookup x env

| Let (x, erhs, ebody) ->

let v = eval erhs env fenv

let env' = (x, v) :: env

eval ebody env' fenv

| Call (f, earg) ->

match lookup f fenv with

| F (x, ebody, env0, fenv0) as clo ->

let v = eval earg env fenv

let env' = (x, v) :: env0

let fenv' = (f, clo) :: fenv0

eval ebody env' fenv'

| LetFun (f, x, erhs, ys, ebody) -> // 2 i

let capturedEnv = List.filter (fun (y, _) -> List.exists ((=) y) ys) env

let fenv' = (f, F (x, erhs, capturedEnv, fenv)) :: fenv

eval ebody env fenv'

| Num i -> i

| Plus (e1, e2) ->

let i1, i2 = eval e1 env fenv, eval e2 env fenv

i1 + i2

answer to ii):

let concreteExample : expr =

Let ("x", Num 1,

LetFun ("f", "y",

Plus (Var "x", Var "y"),

["x"], Call ("f", Num 2)))

let env1 = [("x", 10)]

eval concreteExample env1 [] // Returns 3

*)

let rec dyneval (e : expr) (env : value envir) (fenv : closure envir) : value =

match e with

| Var x -> lookup x env

| Let (x, erhs, ebody) ->

let v = dyneval erhs env fenv

let env' = (x, v) :: env

dyneval ebody env' fenv

| Call (f, earg) ->

match lookup f fenv with

| F (x, ebody, env0, fenv0) as clo ->

let v = dyneval earg env fenv

let env' = env0 @ (x, v) :: (List.filter (fun (y, _) -> y x) env) // 2 iii

let fenv' = (f, clo) :: fenv0

dyneval ebody env' fenv'

| LetFun (f, x, erhs, ys, ebody) ->

let capturedEnv = env

let fenv' = (f, F (x, erhs, capturedEnv, fenv)) :: fenv

dyneval ebody env fenv'

| Num i -> i

| Plus (e1, e2) ->

let i1, i2 = dyneval e1 env fenv, dyneval e2 env fenv

i1 + i2

Here are the test cases

// > eval example1 [] [];;

// val it: value = 9

// > eval example2 [] [];;

// System.Exception: y not found

// > eval (LetFun ("f", "x", Var "y", [], Num 1)) [] [];;

// val it: value = 1

// > eval (LetFun ("f", "x", Var "y", [], Call ("f", Num 1))) [] [];;

// System.Exception: y not found

// > eval (LetFun ("f", "a", Plus (Plus (Var "x", Var "z"), Var "a"), ["x"; "z"], Let ("x", N- um 100, Call ("f", Num 25)))) ["x", 10; "y", 15; "z", 20] [];;

// val it: value = 55

// > dyneval example1 [] [];;

// val it: value = 9

// > dyneval example2 [] [];;

// val it: value = 9

// > dyneval (LetFun ("f", "x", Var "y", [], Num 1)) [] [];;

// val it: value = 1

// > dyneval (LetFun ("f", "a", Plus (Plus (Var "x", Var "z"), Var "a"), ["x"; "z"], Let ("x", Num 100, Call ("f", Num 25)))) ["x", 10; "y", 15; "z", 20] [];;

// val it: value = 55

// (You should also try to test dyneval on your expression from part

// (ii) to ensure it works correctly.)

All are working except this

// > eval (LetFun ("f", "a", Plus (Plus (Var "x", Var "z"), Var "a"), ["x"; "z"], Let ("x", N- um 100, Call ("f", Num 25)))) ["x", 10; "y", 15; "z", 20] [];;

// val it: value = 55

but I get stdin(33,88): error FS0039: The value or constructor 'N' is not defined. Need help to fix it.

2. In Assignment3.fs, there is a modification of the first-order language from FirstFun.fs. The main difference is that the LetFun construct also has a list of variable names [y1; y2; ; yn], which specifies the variables that the function wants to use in its body. The only variables the function body is allowed to use are those in the list, and the parameter of the function. These variables are statically scoped. Function names are also statically scoped, and functions do not need to say which function names they use. For example, evaluating should succeed (the result is 9 ), but evaluating let fw= (let x=2 in let y=3 in let g=x+y+z capturing [x] in g w) capturing [] in f4 should fail (because g cannot use y). (i) The LetFun case of eval does not work correctly; it ignores the variables to capture and constructs a closure that contains the wrong environment. For example, both of the examples above evaluate successfully. Fix the LetFun case of eval. Instead of preventing the body of the function from using variables that are not in the list, we could instead treat variables not in the list as dynamically scoped. (ii) Give an example (in concrete syntax) of an expression that would successfully evaluate if these variables ware dynamically scoped, but would fail if the body was not allowed to use them. (iii) Change the Call case of dyneval to match this new behaviour. (Do not change the LetFun case of dyneval, even though it is also broken. Also do not change the Call case of eval.)

Step by Step Solution

There are 3 Steps involved in it

1 Expert Approved Answer
Step: 1 Unlock blur-text-image
Question Has Been Solved by an Expert!

Get step-by-step solutions from verified subject matter experts

Step: 2 Unlock
Step: 3 Unlock

Students Have Also Explored These Related Databases Questions!