Fortran: How to pass Type variables to Subroutine - fortran95

I want to calculate a derived data type in a subroutine (or function). How would I reference the variable in the subroutine arguments?
So far, I can achieve my objective by referencing the entire object, then referencing the variable inside the subroutine. Is there a way to reference only the variable myObj%var in the subroutine arguments?
PROGRAM test
TYPE obj
INTEGER :: var
END TYPE obj
TYPE (obj) :: myObj
CALL set(myObj)
PRINT*, myObj%var
CONTAINS
SUBROUTINE set(myObj)
TYPE (obj) :: myObj
myObj%var = 5
END SUBROUTINE set
END PROGRAM test

You could simply write
SUBROUTINE set(an_int)
integer, intent(inout) :: an_int
an_int = 5
END SUBROUTINE set
and then call the subroutine like this:
CALL set(myObj%var)
My opinion that it is perverse to package components into derived types and then unpack them to pass to procedures is just an opinion, you are free to ignore it. Personally I'd go with a more radical rewrite of your code, something like the following. Be warned though that this uses some features introduced in the 2003 standard, though these are implemented in current editions of the most widely used compilers.
MODULE mytype
IMPLICIT NONE
TYPE obj
INTEGER, PRIVATE :: var
CONTAINS
PROCEDURE, PASS :: get_var
PROCEDURE, PASS :: set_var
END TYPE obj
CONTAINS
SUBROUTINE set_var(this,an_int)
CLASS(obj), INTENT(inout) :: this
INTEGER, INTENT(in) :: an_int
this%var = an_int
END SUBROUTINE set_var
INTEGER FUNCTION get_var(this)
CLASS(obj), INTENT(inout) :: this
get_var = this%var
END FUNCTION get_var
END MODULE mytype
PROGRAM test
USE mytype
IMPLICIT NONE
TYPE (obj) :: myObj
CALL myobj%set_var(12)
PRINT*, myObj%get_var()
END PROGRAM test

If you only have an F95 compiler without all the 2003/2008 bits, this is how it can be done.
MODULE ObjMod
IMPLICIT NONE
TYPE ObjType
INTEGER, PRIVATE :: var
END TYPE ObjType
CONTAINS
SUBROUTINE ObjCreate(this)
TYPE(ObjType), POINTER :: this
allocate(this)
END SUBROUTINE ObjCreate
SUBROUTINE ObjDelete(this)
TYPE(ObjType), POINTER :: this
deallocate (this)
END SUBROUTINE ObjDelete
SUBROUTINE ObjSet(this, value)
TYPE(ObjType), INTENT(inout) :: this
INTEGER, INTENT(in) :: value
this%var = value
END SUBROUTINE ObjSet
INTEGER FUNCTION ObjGet(this)
TYPE(ObjType), INTENT(inout) :: this
ObjGet = this%var
END FUNCTION ObjGet
END MODULE ObjMod
PROGRAM test
USE ObjMod
IMPLICIT NONE
TYPE (ObjType), POINTER :: testObj
CALL ObjCreate(testObj)
CALL ObjSet(testObj, 12)
PRINT*, ObjGet(testObj)
CALL ObjDelete(testObj)
STOP
END PROGRAM test
I also used to code like that in C in the early 80s before a decent C++ compiler came out. What you will find is that many systems written in the 70s up to the early 90s use this technique. It will work in any language that supports structures and dynamic memory allocation.

Related

F# kprintf: missing warning about about redundant arguments

Is there a way to do string formatting for Exceptions with kprintf (or similar) and still get warnings about redundant arguments? So far I have:
type MyException (s:string) =
inherit System.Exception(s)
static member Raise msg =
Printf.kprintf (fun s -> raise (MyException(s))) msg
do
MyException.Raise "boom %d" 9 1 // Gives NO warning about redundant arguments
failwithf "boom %d" 9 1 // Gives warning about redundant arguments
I know I could use the new $ formatting but would like to stay compatible with older versions of F#.
The problem does not come from kprintf, but from raise, which allows the return type of the function to be any type, including a curried function. The function failwithf has this warning as a special case.
If you return, let’s say, a string or a unit, you would actually get an error. The downside is that now you cannot raise in every position anymore, as then the return argument is not generic anymore.
You could fix that by forcing a type argument, but that would make it less than ideal for the caller.
For instance, this works, but if you change the return type of f to be a string, it fails:
open System
type MyException (s:string) =
inherit System.Exception(s)
static member Raise msg =
Printf.kprintf (fun s -> raise (MyException s) |> ignore) msg
module Test =
let f() : unit = // string won’t work
MyException.Raise "boom %d" 9 10 // error, as expected
Edit: workaround
Here's some kind of a workaround. You can use generic type constraints to limit the type, and use the fact that an F# function type is not comparable or equatable, does not have a proper value null.
Most types you'll use are equatable, because of F#'s powerful structural equality support. Other options for a type constraint are struct (only structs), null (this excludes record and DU types) or a certain inheritance constraint if that serves your use case.
Example:
type MyException (s:string) =
inherit System.Exception(s)
static member Raise<'T when 'T : equality> msg =
let raiser s =
raise (MyException s)
Unchecked.defaultof<'T> // fool the compiler
Printf.kprintf raiser msg
module Test =
let f() = MyException.Raise "boom %d" 9
let g() = MyException.Raise "boom %d" 9 10 // error
Downside, apart from the type restriction, is that the error you get will be a type error, not a warning as you requested.
The check for this warning in the compiler specifically looks for a number of known F# library functions. You can see the checks in the compiler source code and here (the functions are raise, failwith, failwithf, nullArg, invalidOp and invalidArg).
The reason for this is that, there is, in principle, nothing wrong with a generic function that returns 'T and is used so that 'T is inferred to be a function. For example, it is perfectly fine to do:
let id f = f
id sin 3.14
Here, we define a function id with one argument, but if I give it a function as an argument, it also becomes valid to call it with an extra argument as id sin 3.14.
The special functions are special in that they look like they return a value of a generic type, but they never actually return, because they raise an execption. The compiler cannot, in general, know whether that is the case for any custom function or method you yourself write - and so it only checks this for known special functions. (It would have to do more sophisticated analysis, possibly marking the return type of these functions as the bottom type, but that is beyond what F# does...).

F# quotation with spliced parameter of any type

I am trying to develop F# type provider.
It provides some DTOs (with the structure described in some external document) and a set of methods for processing them. The processing algorithm is based on reflection, and I want to have a single quotation representing it.
Generally, this algorithm must pass all method call arguments to the already written function serialize: obj -> MySerializationFormat, storing all results in a list, so I getting a value of MySerializationFormat list.
Code sample below shows, how I tried to do that for first time:
let serialize (value: obj) = ...
let processingCode: Expr list -> Expr =
fun args ->
let serializeArgExpr (arg: Expr) = <# serialize %%arg} #>
let argsExprs = List.map serializeArgExpr args
let serializedArgList =
List.foldBack (fun head tail -> <# (%head) :: (%tail)#>) argsExprs <# [] #>
// futher processing
At that point I faced with exception: In function serializeArgExpr the actual type of value in arg: Expr may vary, it can be some primitive type (e.g string, int, float), or some provided type. The problem is %% operator treats that arg as an expression of the obj type. Type check is performed on that line in Microsoft.FSharp.Quotations.Patterns module, in function fillHolesInRawExpr.
So, as the actual type of my term not matched the treated type for "hole" in the quotation, it throws invalidArg.
I have tried several technics to avoid these exceptions with casting operations in my quotation, but they don't work. Then I found Expr.Coerce(source, target) function, which looks like solving my problem. I have changed the code of serializeArgExpr to something like that:
let serializeArgExpr (arg: Expr) =
let value' = Expr.Coerce(value, typeof<obj>)
<# serialize %%value' } #>
Then faced a new strange exception:
The design-time type (point to a code line that uses my processingCode) utilized by a type provider was not found in the target reference assembly set
For me, it seems that my problem is to cast the type of value in any input Expr to an obj type. Thank you for diving in and trying to help.

OCaml functions passing in one less argument

I'm looking at solutions for a homework and the code implements an OCaml function that takes in two arguments but when its called, it's only passed one argument.
let rec func2 r x = match r with
| [] -> []
| (nt,rhs)::t -> if nt = x then rhs::(func2 t x) else func2 t x;;
let func1 r = fun x -> func2 r x;;
I would be calling func1 on a grammar rule like below by calling ( func1 awksub_rules )
let awksub_rules = [
Expr, [T"("; N Expr; T")"];
Expr, [N Num];
Num, [T"0"];
Num, [T"1"]
]
Expr and Num are just nonterminal types already defined and the T symbol means a terminal type.
I'm confused because func1 only takes in awksub_rules as an argument but the function declaration has two functions.
The intended output would be
function
| Expr -> [[T"("; N Expr; T")"]; [N Num]]
| Num -> [[T"0"]; [T"1"]]
I can see that func1 correctly returns a function and that func2 handles checking whether the left hand side (Expr or Num) is the same so it can concatenate to the list. But I have no idea what is passed into x.
When func1 is called with one argument, it returns another function, let's call it func3:
let func3 = func1 awksub_rules
At this point, there is no argument x yet. This new function still expects this argument to be passed in.
When you call this new function, you will pass in the value of x, and the computation will commence:
let result = func3 Num
I also would like to point out that func1 and func2 are logically equivalent because of the mechanism in ML called "partial application". That is, you can use func2 everywhere you use func1, and with same effect:
let func3 = func2 awksub_rules
let result = func3 Num
Fyodor Soikin's answer explains why func1 and func2 are logically the same. However, I don't want you to come away from this thinking that there is some magical language feature called "partial application". To stretch your mind, you need to understand how this arises from how functions work in OCaml.
In the ML languages, there is no such thing as a "function that takes in two arguments". Every function in ML takes exactly one argument (not zero, not two, not three; always one). The OCaml syntax
let rec func2 r x = ...
is syntactic sugar for
let rec func2 = function r -> function x -> ...
i.e. it is simply a definition of a function that returns another function. That's why the type of the function will be something like a -> b -> c (-> is right-associative, so that is the same as a -> (b -> c)) -- it says that it's a function that takes an a, and returns a function of type b -> c.
When you go to apply this function, what you think of as passing in two arguments, like func2 foo bar, is actually (because function application is left-associative) (func2 foo) bar, i.e. it is first applying func2 to the expression foo, and the result of that, a function, will then be applied to the expression bar.
The practice of taking in "multiple arguments" by taking in one argument and returning a function that takes another argument, etc. is called "currying". OCaml and other ML languages provide convenient syntax for defining curried functions (as you can see above, the common syntax let in OCaml allows you to define curried functions simply as listing the parameters next to each other), whereas in other languages, writing curried functions would require more verbose syntax. It's so convenient that, most of the time, we forget about it and think of it as multiple arguments. But it's always important to remember what it really means.
(Note that the OCaml compiler may or may not optimize curried functions into machine code functions that take multiple arguments, but that's an implementation detail that you shouldn't care about at the language level.)

How to read in an Int and use it in another function

I am trying to read in an Int and then use the read value in a pure function, but it does not seem to work properly. After searching through a lot of resources I use the from here.
So my code goes as the following:
main = do
putStrLn "Please input a number."
inputjar <- getLine
return (read inputjar :: Int)
Which works fine, but when I want to use it in my pure function:
usrSetBrick :: [[Int]] -> [[Int]]
usrSetBrick xs = setBrick (main) (main) (main) xs
I get a compile error:
Couldn't match expected type `Int' with actual type `IO Int'
In the first argument of `setBrick', namely `(main)'
In the expression: setBrick (main) (main) (main) xs
In an equation for `usrSetBrick':
usrSetBrick xs = setBrick (tull) (tull) (tull) xs
Failed, modules loaded: none.
So from what I understand does main return an int. Even it should, as I can understand from
return (read inputjar :: Int)
How can I make the read input usable in my function?
You probably don't want to be using main to return things since it's the entry point to your program. Instead, you can write a function
getInt :: IO Int
getInt = do
input <- getLine
return (read input) -- Don't have to specify Int here, GHC can figure it out from the type signature
However, your function setBrick, which presumably has the type Int -> Int -> Int -> [[Int]] -> [[Int]], can't use getInt directly. This is by design, Haskell's type system forces you to treat IO actions separately from pure functions (once you get used to it, it's a wonderful tool for reasoning about your code). Instead, you can do something like
promptInt :: IO Int
promptInt = do
putStrLn "Please input a number."
getInt
usrSetBrick :: [[Int]] -> IO [[Int]]
usrSetBrick xs = do
a <- promptInt
b <- promptInt
c <- promptInt
return $ setBrick a b c xs
The types Int and IO Int are not the same in Haskell, you can not use the interchangeably. This holds true for types like [Int], Maybe Int, and Either String Int as well, none of these the same as Int. Since main is an IO function, it doesn't return Int, it returns IO Int. In fact, return is not a special construct in Haskell at all, it's just a normal function that happens to wrap a value in a Monad. In this case, the Monad being used is IO, so return (read inputjar :: Int) has the type IO Int.
To expand on #Zeta's comment below, Haskell's return is not special and more importantly does not exit functions early. The following code will demonstrate this:
doSomething :: IO Int
doSomething = do
return "Test" -- Wouldn't type-check if this exited early
return 123 -- Would type check, but is ignored
putStrLn "You'll see this line printed"
return () -- Doesn't affect anything
x <- getLine -- Still happens
return 5678
putStrLn "Your input is meaningless! Here's a 0"
return ([1, 2], "hello", "world")
return 0 -- This is the actual return value
All those extra returns do nothing in Haskell (at least in the IO monad). All that happens is a value is wrapped in a constructor and chained together with the rest of the statements in that function. There are even some people in the Haskell community that view return as both unnecessary and confusing. Technically, return is equivalent to pure for Applicatives, and all Monads are also Applicatives, so it's not really providing us anything. At some point in the distant future, it's possible that the return function might disappear entirely, being completely superseded by pure. Again, neither of these functions are part of Haskell syntax, they're defined in the core libraries as plain, normal functions.

Delegate/Func conversion and misleading compiler error message

I thought that conversions between F# functions and System.Func had to be done manually, but there appears to be a case where the compiler (sometimes) does it for you. And when it goes wrong the error message isn't accurate:
module Foo =
let dict = new System.Collections.Generic.Dictionary<string, System.Func<obj,obj>>()
let f (x:obj) = x
do
// Question 1: why does this compile without explicit type conversion?
dict.["foo"] <- fun (x:obj) -> x
// Question 2: given that the above line compiles, why does this fail?
dict.["bar"] <- f
The last line fails to compile, and the error is:
This expression was expected to have type
System.Func<obj,obj>
but here has type
'a -> obj
Clearly the function f doesn't have a signature of 'a > obj. If the F# 3.1 compiler is happy with the first dictionary assignment, then why not the second?
The part of the spec that should explain this is 8.13.7 Type Directed Conversions at Member Invocations. In short, when invoking a member, an automatic conversion from an F# function to a delegate will be applied. Unfortunately, the spec is a bit unclear; from the wording it seems that this conversion might apply to any function expression, but in practice it only appears to apply to anonymous function expressions.
The spec is also a bit out of date; in F# 3.0 type directed conversions also enable a conversion to a System.Linq.Expressions.Expression<SomeDelegateType>.
EDIT
In looking at some past correspondence with the F# team, I think I've tracked down how a conversion could get applied to a non-syntactic function expression. I'll include it here for completeness, but it's a bit of a strange corner case, so for most purposes you should probably consider the rule to be that only syntactic functions will have the type directed conversion applied.
The exception is that overload resolution can result in converting an arbitrary expression of function type; this is partly explained by section 14.4 Method Application Resolution, although it's pretty dense and still not entirely clear. Basically, the argument expressions are only elaborated when there are multiple overloads; when there's just a single candidate method, the argument types are asserted against the unelaborated arguments (note: it's not obvious that this should actually matter in terms of whether the conversion is applicable, but it does matter empirically). Here's an example demonstrating this exception:
type T =
static member M(i:int) = "first overload"
static member M(f:System.Func<int,int>) = "second overload"
let f i = i + 1
T.M f |> printfn "%s"
EDIT: This answer explains only the mysterious promotion to 'a -> obj. #kvb points out that replacing obj with int in OPs example still doesn't work, so that promotion is in itself insufficient explanation for the observed behaviour.
To increase flexibility, the F# type elaborator may under certain conditions promote a named function from f : SomeType -> OtherType to f<'a where 'a :> SomeType> : 'a -> OtherType. This is to reduce the need for upcasts. (See spec. 14.4.2.)
Question 2 first:
dict["bar"] <- f (* Why does this fail? *)
Because f is a "named function", its type is promoted from f : obj -> obj following sec. 14.4.2 to the seemingly less restrictive f<'a where 'a :> obj> : 'a -> obj. But this type is incompatible with System.Func<obj, obj>.
Question 1:
dict["foo"] <- fun (x:obj) -> x (* Why doesn't this, then? *)
This is fine because the anonymous function is not named, and so sec. 14.4.2 does not apply. The type is never promoted from obj -> obj and so fits.
We can observe the interpreter exhibit behaviour following 14.4.2:
> let f = id : obj -> obj
val f : (obj -> obj) (* Ok, f has type obj -> obj *)
> f
val it : ('a -> obj) = <fun:it#135-31> (* f promoted when used. *)
(The interpreter doesn't output constraints to obj.)

Resources