The Ocaml interpreter is able to display (print) any kind of value. For example, if a function returns an array, it can print an array. Also, this works even with custom types. For example, if I do :
type dummy = DUMMY of int * string;;
let x = DUMMY(1, "s");;
Then x;;
prints on this on the screen :
-: dummy = DUMMY(1, "s")
My question is, how can I access this functionality? For example, if I'm debugging some code and want to print some non-standard object (i.e, something other than int, string etc), then how can I do that using the function the interpreter uses, without having to create a separate print function for everything?
OCaml is a typeful language but it throws away its type information such as constructor names at runtime of standalone programs. Therefore you cannot have the general value printer which require such type information.
OCaml toplevel or REPL, which you referred as interpreter, is an exception: it keeps types in memory.
For now, if you want to print values a little easier you can auto-generate them using CamlP4 extensions such as "deriving". But it does not provide one generic printer but provides a printer for each type automatically. You still need to compose them like print_list print_dummy for printing values of dummy list.
Related
In Python, I could see the variable's type by typing:
>>> i = 123
>>> type(i)
<type 'int'>
Is there a way to do this in F#?
F# is a .NET language, and in .NET all types are descendants of System.Object, which has a GetType method:
let i = 123
let t = i.GetType()
Having said that, I must strongly urge you not to rely on runtime type information, except for debugging or similar purposes. Doing so will make your program way less maintainable and will come back to bite you in the long run.
In Python you can get away with this, because Python is dynamically typed anyway, so one more check deferred to runtime doesn't really make a difference. But F# is statically typed, and by deferring types to runtime you throw away any support the compiler can provide.
If you're wanting to do this in F# Interactive, you just need to evaluate the variable by typing its name (followed by ;; as with any other expression at the F# Interactive prompt). I.e., if you've already executed let num = 123, then you just type num;; at the F# Interactive prompt and you'll see the following printed out:
val it : int = 123
The word val means that F# Interactive is describing a value. The name it is a special name in F# Interactive, assigned to the last value that was evaluated. Then comes a colon, the value's type (in this case, int), then an equals sign, and then the value is printed out.
So all you have to do to see the value and type of a variable in F# Interactive is to just type that variable followed by ;;. Simple.
What's the advantage of having a type represent a function?
For example, I have observed the following snippet:
type Soldier = Soldier of PieceProperties
type King = King of PieceProperties
type Crown = Soldier -> King
Is it just to support Partial Application when additional args have yet to be satisfied?
As Fyodor Soikin says in the comments
Same reason you give names to everything else - values, functions,
modules, etc.
In other words, think about programming in assembly which typically does not use types, (yes I am aware of typed assembly) and all of the problems that one can have and then how many of those problems are solved or reduced by adding types.
So before you programmed with a language that supported functions but that used static typing, you typed everything. Now that you are using F# which has static typing and functions, just extend what you have been using typing for but now add the ability to type the functions.
To quote Benjamin C. Pierce from "Types and Programming Languages"
A type system is a tractable syntactic method for proving the absence
of certain program behaviors by classifying phrases according to the
kinds of values they compute.
As noted in "Types and Programming Languages" Section 1.2
What Type Systems Are Good For
Detecting Errors
Abstraction
Documentation
Language Safety
Efficiency
TL;DR
One of the places that I find named type function definitions invaluable is when I am building parser combinators. During the construction of the functions I fully type the functions so that I know what the types are as opposed to what type inferencing will infer they are which might be different than what I want. Since the function types typically have several parameters it is easier to just give the function type a name, and then use that name everywhere it is needed. This also saves time because the function definition is consistent and avoid having to debug an improperly declared function definition; yes I have made mistakes by doing each function type by hand and learned my lesson. Once all of the functions work, I then remove the type definitions from the functions, but leave the type definition as comments so that it makes the code easier to understand.
A side benefit of using the named type definitions is that when creating test cases, the typing rules in the named function will ensure that the data used for the test is of the correct type. This also makes understanding the data for the test much easier to understand when you come back to it after many months.
Another advantage is that using function names makes the code easier to understand because when a person new to the code looks at if for the first time they can spot the consistency of the names. Also if the names are meaningful then it makes understanding the code much easier.
You have to remember that functions are also values in F#. And you can do pretty much the same stuff with them as other types. For example you can have a function that returns other functions. Or you can have a list that stores functions. In these cases it will help if you are explicit about the function signature. The function type definition will help you to constrain on the parameters and return types. Also, you might have a complicated type signature, a type definition will make it more readable. This maybe a bit contrived but you can do fun(ky) stuff like this:
type FuncX = int -> int
type FuncZ = float -> float -> float
let addxy (x:int) :FuncX = (+) x
let subxy :FuncX = (-) x
let addz (x:float) :FuncZ =
fun (x:float) -> (fun y -> x + y)
let listofFunc = [addxy 10;addxy 20; subxy 10]
If you check the type of listofFunc you will see it's FuncX list. Also the :FuncX refers to the return type of the function. But we could you use it as an input type as well:
let compFunc (x:FuncX) (z:FuncX) =
[(x 10);(z 10)]
compFunc (addxy 10) (addxy 20)
I'm learning F#, when I type any code in Visual Studio and run them on F# Interactive it shows me things like
val foo : x:'a -> 'a
I imagine this mean that foo is a function that receive a paramater x of a type, and returns a value of same x's type.
But What does that ' mean? Many functions show such thing on intellisense too.
The single quote mark (') means that the type of that parameter is generic. It can be inferred, like the example you gave, or it can be explicitly applied.
See here under Implicitly Generic Constructs for more information.
'a represents a type variable, in other words a type that is not determined yet (and doesn't have to be determined yet).
Note that this is different than a', which is a regular variable whose name is two characters: a and '. Contrary to other languages like C#, the single quote is a permitted character in F# variable names, except as the first character in the name to disambiguate from type variables above.
There is need for tracing. The decorator should print function name, parameters values and return value. Instead of writing each time a decorator for each function, it would be terrific if it could be possible to do this programmatically.
The current function name can be discovered using reflection via MethodBase.GetCurrentMethod. Functions could be easily decorated with an inline function for logging:
let inline log args f =
let mi = System.Reflection.MethodBase.GetCurrentMethod()
let result = f ()
printf "%s %A -> %A" mi.Name args result
let add a b = log (a,b) (fun () -> a + b)
add 1 1
Which prints: add (1, 1) -> 2
EDIT: Another option would be to create a wrap function, i.e.:
let inline wrap f =
fun ps ->
let result = f args
printfn "%A -> %A" args result
result
let add (a,b) = a + b
wrap add (1,1)
However in this case there is not an easy way to programmatically retrieve the function name.
Yet another option might be to develop a Type Provider that takes an assembly path as a parameter and provides wrapped versions of all members.
I had the same desire previously and found that there are no current automated solutions for F#.
See: Converting OCaml to F#: Is there a simple way to simulate OCaml top-level #trace in F#
While OCaml's trace facility with time travel is the most useful debugging feature of comparison to what is desired, it is not an exact fit; but when I use OCaml it is the first inspection tool I use.
See: Using PostSharp with F# - Need documentation with working example
Also the suggestion of using AOP, i.e. PostSharp, was another good suggestion, as the response from Gael Fraiteur, the Principal Engineer of PostSharp points out:
PostSharp does not officially support F#.
Other than using reflection as suggested by Phillip Trelford, which I have not tried, the best solution I have found is to manually modify each function to be traced as I noted in Converting OCaml to F#: Is there a simple way to simulate OCaml top-level #trace in F# and save the results to a separate log file using NLog.
See: Using NLog with F# Interactive in Visual Studio - Need documentation
Another route to pursue would be check out the work of F# on Mono as there is a lot of work being done there to add extra tooling for use with F#.
Basically what I have found is that as my F# skills increase my need
to use a debugger or tracing decrease.
At present when I do run into a problem needing this level of inspection, adding the inspection code as noted in Converting OCaml to F#: Is there a simple way to simulate OCaml top-level #trace in F# helps to resolve my misunderstanding.
Also of note is that people who come from the C# world to the F# world tend to expect a debugger to be just as useful. Remember that imperative languages tend to be about manipulating data held in variables and that the debugger is used to inspect the values in these variables, while with functional programming, at least for me, I try to avoid mutable values and so the only values one needs to inspect are the values being passed to the function and no other values, thus reducing or obviating the need for a debugger or inspection beyond that of the function of question.
I'm learning F#, when I type any code in Visual Studio and run them on F# Interactive it shows me things like
val foo : x:'a -> 'a
I imagine this mean that foo is a function that receive a paramater x of a type, and returns a value of same x's type.
But What does that ' mean? Many functions show such thing on intellisense too.
The single quote mark (') means that the type of that parameter is generic. It can be inferred, like the example you gave, or it can be explicitly applied.
See here under Implicitly Generic Constructs for more information.
'a represents a type variable, in other words a type that is not determined yet (and doesn't have to be determined yet).
Note that this is different than a', which is a regular variable whose name is two characters: a and '. Contrary to other languages like C#, the single quote is a permitted character in F# variable names, except as the first character in the name to disambiguate from type variables above.