Looking for construct simto VB's WITH statement - fortran

Updating some archaic F77 that no longer fully supported our needs. I am looking for the functional equivalent of VB's "WITH" statement to support the conversion from a mass of F77 disconnected, individual variables to hierarchical derived Types. While the code is much easier to read and understand the downside is that the code becomes very cumbersome and prone to typos. So, the use of WITH would greatly ease the conversion burden.
VB's "WITH" statement executes a series of statements on a single object or a user-defined type.
Example:
if I want to reference elements my derived Type named Loads I would write code with Loads% prefixing each element and that is cumbersome. The WITH statement allows one to re-write the block with an assumed reference to Loads%.
WITH Loads%
ID = blah
Description = blahblah
Duty(I) = 2
End WITH
Suggestions...?

There's no Fortran construct which provides a precise analog to what you describe as VB's with statement. For your particular example, you could write something along the lines of ...
Given a derived type definition such as
type :: load
character(4) :: id
character(32) :: description
integer, dimension(4) :: duties
end type load
and a variable of that type
type(load) :: loads
you can use a default constructor to set the values of the members of loads, like this:
loads = load('myid', 'my description', [1,2,3,4])
or even like this:
loads = load(duties=[3,4,5,6], id = 'id2', description='description')
If you look around on SO for Qs and As on the subject of Fortran derived type constructor you'll find out how to build more complicated constructors which don't need all the members to be given values when they are called. There are some useful resources elsewhere on the internet too.
If one of your concerns is to avoid typing long, and possibly multipart, entity names then the associate construct might help. For example, if, rather than loads the name of the variable you wanted to avoid typing was something like long%structured%entity you might write
associate (shnm => long%structured%entity`)
shnm%id = 'idxx'
*etc*
end associate
I'm sure you could easily come up with more extensive examples of the use of with which would not be easy to translate to Fortran without repeated writing of loads%.

Related

How to automatically initialize component parameters?

While doing a game engine that uses .lua files in order to read parameter values, I got stuck when I had to read these values and assign them to the parameters of each component in C++. I tried to investigate the way Unity does it, but I didn't find it (and I'm starting to doubt that Unity has to do it at all).
I want the parameters to be initialized automatically, without the user having to do the process of
myComponentParameter = readFromLuaFile("myParameterName")
for each one of the parameters.
My initial idea is to use the std::variant type, and storing an array of variants in order to read them automatically. My problems with this are:
First of all, I don't know how to know the type that std::variant is storing at the moment (tried with std::variant::type, but it didn't work for the template), in order to cast from the untyped .lua value to the C++ value. For reference, my component initialization looks like this:
bool init(luabridge::LuaRef parameterTable)
{
myIntParameter = readVariable<int>(parameterTable, "myIntParameter");
myStringParameter = readVariable<std::string>(parameterTable, "myStringParameter");
return true;
}
(readVariable function is already written in this question, in case you're curious)
The second problem is that the user would have to write std::get(myIntParameter); whenever they want to access to the value stored by the variant, and that sounds like something worse than making the user read the parameter value.
The third problem is that I can't create an array of std::variant<any type>, which is what I would like to do in order to automatically initialize the parameters.
Is there any good solution for this kind of situation where I want the init function to not be necessary, and the user doesn't need to manually set up the parameter values?
Thanks in advance.
Let's expand my comment. In a nutshell, you need to get from
"I have some things entered by the user in some file"
to:
"the client code can read the value without std::get"
…which roughly translates to:
"input validation was done, and values are ready for direct use."
…which implies you do not store your variables in variants.
In the end it is a design question. One module somewhere must have the knowledge of which variable names exist, and the type of each, and the valid values.
The input of that module will be unverified values.
The output of the module will probably be some regular c++ struct.
And the body of that module will likely have a bunch of those:
config.foo = readVariable<int>("foo");
config.bar = readVariable<std::string>("bar");
// you also want to validate values there - all ints may not be valid values for foo,
// maybe bar must follow some specific rules, etc
assuming somewhere else it was defined as:
struct Configuration {
int fooVariable;
std::string bar;
};
Where that module lives depends on your application. If all expected types are known, there is no reason to ever use a variant, just parse right away.
You would read to variants if some things do not make sense until later. For instance if you want to read configuration values that will be used by plugins, so you cannot make sense of them yet.
(actually even then simply re-parsing the file later, or just saving values as text for later parsing would work)

How to support multiple versions of the 'same' derived type in Fortran?

EDIT to provide more details:
1) The code that provides the libraries cannot be (easily) changed so profile_v1_type and profile_v2_type should be assumed to be immutable.
I have implemented #francescalus suggestion and it works for my small test case, but I was insufficiently clear about the problem, I think. The reason being that I can only modify my code not the code/types coming from the library. The problem will be that both will have t in the profile_type that gets imported which clash with the parent type.
But I am going to implement something where I replicate the contents of the derived type that I want and then use pointers and type-bound procedures to point to the components of the profile_type version that I want to use. It's not as clean as I wanted it to be but it's much better than I have now.
I am supporting a code that interfaces with another that has 2 versions - the two versions are very similar in interface and although the inputs and outputs are identical in property, they are obviously different derived types (they come from different libraries and differ slightly in the variables contained within. Most variable names inside these types are the same though crucially).
It is (apparently) necessary to support both at runtime, otherwise I would preprocess this all at compile time.
At the moment I have lazily copied and pasted the same code for each version (and all of the versions of derived types it uses) into separate subroutines (*_v1.f90, *_v2.f90).
This is annoying and not very maintainable.
What I'd like to be able to do is use some kind of pointer that doesn't care about what it's pointing to (or rather gets its type information from what it points to and is smart enough to know what's inside).
As I said above, the names are mostly the same, e.g. (t, for temperature, say)
From v1 of library:
TYPE profile_v1_type
REAL :: t
! loads of other stuff
END TYPE profile_v1_type
From v2 of library:
TYPE profile_v2_type
REAL :: t
! loads of other stuff, more than the first version
END TYPE profile_v2_type
In my code:
TYPE profile_container_type
TYPE(profile_v1_type) :: profile_v1
TYPE(profile_v2_type) :: profile_v2
! other arrays that are common inputs to both
END TYPE
! It's actually USE'd then allocated and initialised elsewhere, but I hope you get the idea
!USE profile_container_mod, ONLY : profile_container
TYPE(profile_container_type), TARGET :: profile_container
TYPE(*) :: p
REAL :: t1
!Version determined by a namelist
IF (Version == 1) THEN
p => profile_container % profile_v1
ELSE IF (Version == 2) THEN
p => profile_container % profile_v2
ENDIF
t1 = p % t + 1
.
.
.
ifort 19 gives these (expected) errors:
test.f90(24): error #8776: An assumed type object must be a DUMMY argument. [P]
TYPE(*), POINTER :: p
--------------------^
test.f90(24): error #8772: An assumed type object must not have the ALLOCATABLE, CODIMENSION, POINTER, INTENT(OUT) or VALUE attribute. [P]
TYPE(*), POINTER :: p
--------------------^
test.f90(39): error #6460: This is not a field name that is defined in the encompassing structure. [T]
t1 = p % t + 1
---------^
compilation aborted for test.f90 (code 1)
replace TYPE(*) with CLASS(*) gives the (still expected):
test2.f90(39): error #6460: This is not a field name that is defined in the encompassing structure. [T]
t1 = p % t + 1 ! or some clever function...
---------^
compilation aborted for test2.f90 (code 1)
This is fixed by SELECTing the type that you want to handle, but my point is that I want to do the same thing for either the v1 and v2 code (it will never be both). And I want to do it many times, not in this routine but in about a dozen routines.
I am open to using C pointers if the responder is able to provide a simple example to follow. I have tried (not recently) to solve this problem using C interoperability, but obviously without success!
Unlimited polymorphic entities are not the correct approach here.
Instead, we can define a base type which incorporates all of the common data and processing for the various other types. Here, let's call this base type profile_base_type:
type profile_base_type
real t
end type
The other two specific profiles can extend this base:
type, extends(profile_base_type) :: profile_v1_type
! v1 specific parts
end type
type, extends(profile_base_type) :: profile_v2_type
! v2 specific parts
end type
Then we can declare a polymorphic pointer of the base type
class(profile_base_type), pointer :: p
which can point to targets of either of the extending types:
p => profile_container%profile_v1
p => profile_container%profile_v2
Now, we can access the components of p which are in the type profile_base_type
t1 = p%t + 1
without having to use a select type construct.
Naturally, those specific aspects of the extending types cannot be accessed in this way but there are other considerations for that.

How to log user defined POD struct in C++

I need to add logging to a legacy c++ project, which contains hundreds of user defined structs/classes. These structs only contain primary types as int, float, char[], enum.
Content of objects need to be logged ,preferred in human readable way , but not a must, as long as the object could be reconstructed.
Instead of writing different serialization methods for each class, is there any alternative method?
What you want is a Program Transformation System (PTS). These are tools that can read source code, build compiler data structures (usually ASTs) that represent the source code, and allow you to modify the ASTs and regenerate source code from the modified AST.
These are useful because they "step outside" the language, and thus have no language-imposed limitations on what you can analyze or transform. So it doesn't matter if your langauge doesn't have reflection for everything; a good PTS will give you full access to every detail of the language, including such arcana as comments and radix on numeric literals.
Some PTSes are specific to a targeted language (e.g, "Jackpot" is only usuable for Java). A really good PTS is provided a description of an arbitrary programming langauge, and can then manipulate that language. That description has to enable the PTS to parse the code, analyze it (build symbol tables at least) and prettyprint the parsed/modified result.
Good PTSes will allow you write the modifications you want to make using source-to-source transformations. These are rules specifying changes written in roughly the following form:
if you see *this*, replace it by *that* when *condition*
where this and that are patterns using the syntax of the target language being processed, and condition is a predicate (test) that must be true to enable the rule to be applied. The patterns represent well-formed code fragmens, and typically allow metavariables to represent placeholders for arbitrary subfragments.
You can use PTSes for a huge variety of program manipulation tasks. For OP's case, what he wants is to enumerate all the structs in the program, pick out the subset of interest, and then generate a serializer for each selected struct as a modification to the original program.
To be practical for this particular task, the PTS must be able to parse and name resolve (build symbol tables) C++. There are very few tools that can do this: Clang, our DMS Software Reengineering Toolkit, and the Rose compiler.
A solution using DMS looks something like this:
domain Cpp~GCC5; -- specify the language and specific dialect to process
pattern log_members( m: member_declarations ): statements = TAG;
-- declares a marker we can place on a subtree of struct member declarations
rule serialize_typedef_struct(s: statement, m: member_declarations, i: identifier):
statements->statements
= "typedef struct { \m } \i;" ->
"typedef struct { \m } \i;
void \make_derived_name\(serialize,\i) ( *\i argument, s: stream )
{ s << "logging" << \toString\(\i\);
\log_members\(\m\)
}"
if selected(i); -- make sure we want to serialize this one
rule generate_member_log_list(m: member_declarations, t: type_specification, n: identifier): statements -> statements
" \log_members\(\t \n; \m\)" -> " s << \n; \log_members\(\m\) ";
rule generate_member_log_base(t: type_specification, n: identifier): statements -> statements
" \log_members\(\t \n; \)" -> " s << \n; ";
ruleset generate_logging {
serialize_typedef struct,
generate_member_log_list,
generate_member_log_base
}
The domain declaration tells DMS which specific language front-end to use. Yes, GCC5 as a dialect is different than VisualStudio2013, and DMS can handle either.
The pattern log_members is used as a kind of transformational pointer, to remember that there is some work to do. It wraps a sequence of struct member_declarations as an agenda (tag). What the rules do is first mark structs of interest with log_members to establish the need to generate the logging code, and then generate the member logging actions. The log_members pattern acts as a list; it is processed one element at a time until a final element is processed, and then the log_members tag vanishes, having served its purpose.
The rule serialize_typedef_struct is essentially used to scan the code looking for suitable structs to serialize. When it finds a typedef for a struct, it checks that struct is one that OP wants serialized (otherwise one can just leave off the if conditional). The meta-function selected is custom-coded (not shown here) to recognize the names of structs of interest. When a suitable typedef statement is found, it is replaced by the typedef (thus preserving it), and by the shell of a serializing routine containing the agenda item log_members holding the entire list of members of the struct. (If the code declares structs in some other way, e.g., as a class, you will need additional rules to recognize the syntax of those cases). Processing the agenda item by rewriting it repeatedly produces the log actions for the individual members.
The rules are written in DMS rule-syntax; the C++ patterns are written inside metaquotes " ... " to enable DMS to distinguish rule syntax from C++ syntax. Placeholder variables v are declared in the rule header according thier syntactic categories, and show up in the meta-quoted patterns using an escape notation \v. [Note the unescaped i in the selected function call: it isn't inside metaquotes]. Similarly, meta-functions and patterns references inside the metaquotes are similarly escaped, thus initially odd looking \log\( ... \) including the escaped pattern name, and escaped meta-parentheses.
The two rules generate_member_log_xxx hand the general and final cases of log generation. The general case handles one member with more members to do; the final case handles the last member. (A slight variant would be to process an empty members list by rewriting to the trivial null statement ;). This is essentially walking down a list until you fall off the end. We "cheat" and write rather simple logging code, counting on overloading of stream writes to handle the different datatypes that OP claims he has. If he has more complex types requiring special treatment (e.g., pointer to...) he may want to write specialized rules that recognize those cases and produce different code.
The ruleset generate_logging packages these rules up into a neat bundle. You can trivially ask DMS to run this ruleset over entire files, applying rules until no rules can be further applied. The serialize_typdef_structure rule finds the structs of interest, generating the serializing function shell and the log_members agenda item, which are repeatedly re-written to produce the serialization of the members.
This is the basic idea. I haven't tested this code, and there is usually some surprising syntax variations you end up having to handle which means writing a few more rules along the same line.
But once implemented, you can run this rule over the code to get serialized results. (One might implement selected to reject named structs that already have a serialization routine, or alternatively, add rules that replace any existing serialization code with newly generated code, ensuring that the serialization procedures always match the struct definition). There's the obvious extension to generating a serialized struct reader.
You can arguably implement these same ideas with Clang and/or the Rose Compiler. However, those systems do not offer you source-to-source rewrite rules, so you have to write procedural code to climb up and down trees, inspect individual nodes, etc. It is IMHO a lot more work and a lot less readable.
And when you run into your next "C++ doesn't reflect that", you can tackle the problem with the same tool :-}
Since C++ does not have reflection there is no way for you to dynamically inspect the members of an object at runtime. Thus it follows that you need to write a specific serialization/streaming/logging function for each type.
If all the different types had members of the same name, then you could write a template function to handle them, but I assume that is not the case.
As C++ does not have reflection this is not that easy.
If you want to avoid a verbose solution you can use a variadic template.
E.g.
`class MyStruct {
private:
int a;
float f;
public:
void log()
{
log_fields(a, f);
}
};`
where log_fields() is the variadic template. It would need to be specialized for all the basic types found on those user defined types and also for a recursive case.

OCaml: Core.Univ usage example

So I have been looking at Core.Univ as a way of constructing heterogeneous arrays.
Suppose I do
let int_type = Core.Type_equal.Id.create ~name:"" Sexplib.Conv.sexp_of_int;;
let int_type' = Core.Type_equal.Id.create ~name:"" Sexplib.Conv.sexp_of_int;;
let i = Core_kernel.Univ.create int_type 5;;
let j = Core_kernel.Univ.create int_type' 5;;
When I do
Core_kernel.Univ.match_ i int_type'
It doesn't match as expected since the documentation for Type_equal.Id says that two calls to create with the exact same arguments will result in two distinct identifiers.
Does this mean that the API user is responsible for ensuring that only one instance of Type_equal.Id exists for each type?
Yes. I'd say that Core's terminology is a little bit unfortunate here.
Remember that once you compiled your program, at runtime there are (almost) no types in OCaml (see e.g. here or here for more information).
This means there's no way to introspect the values returned by Core.Type_equal.Id.create to detect for which type they really are and hence no way to detect if you already invoked create for an existing identical type (which would allow to return an already created identifier).
Rather than identifiers for types you should rather see these values as typed key identifiers. By controlling who has access to these key identifiers trough the module system you can control in a type safe way who can access the contents of universal values that were created with them.

Extract variables from Lua into C++

I'm working on a numerical C++ code. This C++ code has a config file with physical parameters of my system. I would like to be able to do mathematical computations and some programming in a config file. Lua seems perfect.
suppose my lua file computes variable vol and mass:
method = cube
len = 3
rho = 1.5
vol = len*len*len
mass = vol*rho
I'd like to pass vol and mass to C++ code. I also would like to pass method, which is a std::string.
I can do something like this. However, in this example, they go through elements of a table one-by-one without relying on the variables' names. I'd like C++ to extract values of variables based on their names. also the structure of the lua config code may be more complicated; I might be writing few functions to get those values.
I think you can make function such as GetGlobal(name), which will basically return the value of given variable. Then call this function from C++ with appriopriate parameter pushed onto the stack, and take the result from the stack.
Additionally, it might be worth protecting your code from variables with wrong type, using lua_is* functions.
I can post you the more complete solution of the code, but I didn't want you to spoil you the fun of writing it yourself ;), so let me know shall you need any additional information.