@@ -63,7 +63,7 @@ let fsiSession = FsiEvaluationSession.Create(fsiConfig, allArgs, inStream, outSt
6363Evaluating and executing code
6464-----------------------------
6565
66- The F# interactive service exposes two methods that can be used for interaction . The first
66+ The F# interactive service exposes several methods that can be used for evaluation . The first
6767is `EvalExpression` which evaluates an expression and returns its result. The result contains
6868the returned value (as `obj`) and the statically inferred type of the value:
6969*)
@@ -73,38 +73,40 @@ let evalExpression text =
7373 | Some value -> printfn " %A " value.ReflectionValue
7474 | None -> printfn " Got no result!"
7575
76+ (**
77+ This takes a string as an argument and evaluates (i.e. executes) it as F# code.
78+ *)
79+ evalExpression " 42+1" // prints '43'
80+
81+ (**
82+ This can be used in a strongly typed way as follows:
83+ *)
84+
7685/// Evaluate expression & return the result, strongly typed
7786let evalExpressionTyped < 'T > ( text ) =
7887 match fsiSession.EvalExpression( text) with
7988 | Some value -> value.ReflectionValue |> unbox< 'T>
8089 | None -> failwith " Got no result!"
8190
91+ evalExpressionTyped< int> " 42+1" // gives '43'
92+
93+
8294(**
83- The `EvalInteraction` method has no result. It can be used to evaluate side-effectful operations
84- such as printing, or other interactions that are not valid F# expressions, but can be entered in
95+ The `EvalInteraction` method can be used to evaluate side-effectful operations
96+ such as printing, declarations, or other interactions that are not valid F# expressions, but can be entered in
8597the F# Interactive console. Such commands include `#time "on"` (and other directives), `open System`
86- and other top-level statements.
87- *)
88- /// Evaluate interaction & ignore the result
89- let evalInteraction text =
90- fsiSession.EvalInteraction( text)
91- (**
92- The two functions each take a string as an argument and evaluate (or execute) it as F# code. The code
93- passed to them does not require `;;` at the end. Just enter the code that you want to execute:
98+ all declarations and other top-level statements. The code
99+ does not require `;;` at the end. Just enter the code that you want to execute:
94100*)
95- evalExpression " 42+1"
96- evalInteraction " printfn \" bye\" "
101+ fsiSession.EvalInteraction " printfn \" bye\" "
97102
98103
99104(**
100105The `EvalScript` method allows to evaluate a complete .fsx script.
101106*)
102- /// Evaluate script & ignore the result
103- let evalScript scriptPath =
104- fsiSession.EvalScript( scriptPath)
105107
106108File.WriteAllText( " sample.fsx" , " let twenty = 10 + 10" )
107- evalScript " sample.fsx"
109+ fsiSession.EvalScript " sample.fsx"
108110
109111(**
110112Catching errors
@@ -131,6 +133,7 @@ match result with
131133| Choice1Of2 () -> printfn " checked and executed ok"
132134| Choice2Of2 exn -> printfn " execution exception: %s " exn.Message
133135
136+
134137(**
135138Gives:
136139
@@ -146,30 +149,51 @@ Gives:
146149
147150 Warning The type 'float' does not match the type 'char' at 1,19
148151 Warning The type 'float' does not match the type 'char' at 1,17
152+
153+ For expressions:
149154*)
150155
151156
157+ let evalExpressionTyped2 < 'T > text =
158+ let res , warnings = fsiSession.EvalExpressionNonThrowing( text)
159+ for w in warnings do
160+ printfn " Warning %s at %d ,%d " w.Message w.StartLineAlternate w.StartColumn
161+ match res with
162+ | Choice1Of2 ( Some value) -> value.ReflectionValue |> unbox< 'T>
163+ | Choice1Of2 None -> failwith " null or no result"
164+ | Choice2Of2 ( exn: exn) -> failwith ( sprintf " exception %s " exn.Message)
165+
166+ evalExpressionTyped2< int> " 42+1" // gives '43'
167+
152168
153169(**
154170Executing in parallel
155171------------------
156172
157- To execute in parallel, submit async computations :
173+ By default the code passed to ``EvalExpression`` is executed immediately. To execute in parallel, submit a computation that starts a task :
158174*)
159175
160176open System.Threading .Tasks
161177
162- let sampleAsyncExpr =
178+ let sampleLongRunningExpr =
163179 """
164- async { do System.Threading.Thread.Sleep 5000
165- return 10 }
180+ async {
181+ // The code of what you want to run
182+ do System.Threading.Thread.Sleep 5000
183+ return 10
184+ }
166185 |> Async.StartAsTask"""
167186
168- let task1 = evalExpressionTyped< Task< int>>( sampleAsyncExpr)
169- let task2 = evalExpressionTyped< Task< int>>( sampleAsyncExpr)
187+ let task1 = evalExpressionTyped< Task< int>>( sampleLongRunningExpr)
188+ let task2 = evalExpressionTyped< Task< int>>( sampleLongRunningExpr)
189+
190+ (**
191+ Both computations have now started. You can now fetch the results:
192+ *)
193+
170194
171- task1.Result
172- task2.Result
195+ task1.Result // gives the result after completion (up to 5 seconds)
196+ task2.Result // gives the result after completion (up to 5 seconds)
173197
174198(**
175199Type checking in the evaluation context
@@ -180,7 +204,7 @@ in the context of the F# Interactive scripting session. For example, you first
180204evaluation a declaration:
181205*)
182206
183- evalInteraction " let xxx = 1 + 1"
207+ fsiSession.EvalInteraction " let xxx = 1 + 1"
184208
185209(**
186210
@@ -208,24 +232,6 @@ checkResults.GetToolTipTextAlternate(1, 2, "xxx + xx", ["xxx"], FSharpTokenTag.I
208232
209233checkResults.GetSymbolUseAtLocation( 1 , 2 , " xxx + xx" , [ " xxx" ]) // symbol xxx
210234
211- (**
212- Exception handling
213- ------------------
214-
215- If you want to handle compiler errors in a nicer way and report a useful error message, you might
216- want to use something like this:
217- *)
218-
219- try
220- evalExpression " 42 + 1.0"
221- with e ->
222- match e.InnerException with
223- | null ->
224- printfn " Error evaluating expression (%s )" e.Message
225- //| WrappedError(err, _) ->
226- // printfn "Error evaluating expression (Wrapped: %s)" err.Message
227- | _ ->
228- printfn " Error evaluating expression (%s )" e.Message
229235(**
230236The 'fsi' object
231237------------------
0 commit comments