I wonder if is there any ways to make OCaml compiler report warnings about unused functions? I googled but there are not much topics discussed about this feature.
In particular, in the following program, there are two functions "foo" and "bar" which are declared but "bar" is not used in the "_" function. So I think that the OCaml compiler should report "bar" as an unused function.
let foo x y = x + y
let bar x y z = x + y + z (* should be reported unused *)
let _ =
let x = foo 1 2 in
x
You need to define a (possibly-empty) .mli interface file saying what this module exports. Otherwise, you're just defining a bar function for other modules to use.
(and make sure you're compiling with warnings on, of course)
You can have a look at https://github.com/alainfrisch/dead_code_analyzer , which is a "global" dead code detector. It collects from .cmi files the set of exported values and from .cmt files the set of external references, thus allowing to detect exported values which are never used. (There is also some logic to analyze optional arguments and report which ones are never or always passed.)
Related
I am using LLVM to implement a simple language.
When a function that has not yet been JITTed yet and is being called from other already compiled function, I want to lazily JIT-compile it on demand. There is a neat tutorial on this here: https://llvm.org/docs/tutorial/BuildingAJIT4.html and generally it works.
Now, I want one additional feature - I want to make AST->IR compilation conditional on parameter's value the first time the function is called.
That is, let us say we have two functions, f() and g(int x).
In AST I have two g implementations - one for positive and one for negative x:
g_pos(x) = x + 1;
g_neg(x) = x - 1;
This can be more general, but the idea is that I want to lift the condition x > 0 out of my programme and into the JIT level.
So if now f() = g(7), after JITting I will have f always call g_pos(x).
Is there any way to get this kind of behaviour?
P.S.:
I would really appreciate as little as possible of "you should not do it" or "why would you need that" answers.
This does not work
There is various manuals on how to include C and C++ code in R without Rcpp. Following the first example in this manual and writing a c++ function
void double_me(int* x) {
// Doubles the value at the memory location pointed to by x
*x = *x + *x;
}
into a file doubler.cpp and compiling
R CMD SHLIB doubler.cpp
works fine. The process results in additional files doubler.o and doubler.so. The shared object can be loaded from R, but does not register the symbol double_me it is supposed to expose:
> dyn.load("doubler.so")
> getLoadedDLLs()
Filename
base base
methods /usr/lib/R/library/methods/libs/methods.so
utils /usr/lib/R/library/utils/libs/utils.so
grDevices /usr/lib/R/library/grDevices/libs/grDevices.so
graphics /usr/lib/R/library/graphics/libs/graphics.so
stats /usr/lib/R/library/stats/libs/stats.so
doubler /home/<user>/<path>/src/doubler.so
tools /usr/lib/R/library/tools/libs/tools.so
Dynamic.Lookup
base FALSE
methods FALSE
utils FALSE
grDevices FALSE
graphics FALSE
stats FALSE
doubler TRUE
tools FALSE
> getDLLRegisteredRoutines("doubler")
data frame with 0 columns and 0 rows
Consequently
> .C("double_me", as.integer(1))
Error in .C("double_me") : C symbol name "double_me" not in load table
And evidently, there is something missing - presumably the registration of the symbol (the name of the function) in the load table.
This works, but it is hard to understand, how
According to this manual we are supposed to apply
extern "C" {
}
to third functions in another file. In the manual, this is a function in X_main.o, compiled alongside the loaded library (X.so) that apparently gets registered in the load table without ever being explicitly loaded. And it can then be called with .C("X_main") nevertheless.
I am not sure how exactly this works or how it could be applied to the first example with the trivial double_me function.
Related questions
There are many questions that are likely related to this on Stackoverflow. Unfortunately, none of them has a well-explained answer. Examples are this one, this one, this one, and this one.
C++ allows for overloading, where you can have the same function with different arguments. In order to achieve this, they have to have different names in the compiled file. So when you declare void double_me(int* x) as a C++ function, it'll actually be compiled down to something with a horrible suffix on the name. See for example https://sourceware.org/binutils/docs/binutils/c_002b_002bfilt.html for details. If you specify C linkage, name mangling doesn't occur, and it gets output with a fairly normal name.
Back to your question, the function you want to call from R should probably have C linkage. That's it. You're getting confused about needing third functions, etc. Just mark double_me as extern "C" and you'll be all good.
You probably need to register the function with R, even so.....
Is it possible to declare a function in SML without printing the signature?
I found out that you can print a string without printing val it = () : unit by doing:
val _ = print("Test1");
Is it possible to the same with functions? something like:
val _ = fun foo x = x + 5;
foo 10;
The following program won't compile in SML.
I'm know that I can use let\local but then I can't use them outside the closure. Also I am looking for a way, without importing additional libraries.
What you ask of relates only to the REPL, as function signatures are only printed in the REPL. You can avoid for functions (or other value declarations) to show up by defining them in a local scope, as you suggest (let, local or opaque struct).
A little hack is that multiple re-definitions in a row will yield the latest definition, but then you still need one at the end.
If you want to re-use a value in your code without the REPL printing it, perhaps you are looking to completely disable REPL declaration output, or run a compiled binary?
In Moscow ML you can run the REPL without declaration output with
mosml -quietdec file.sml
But with SML/NJ and others I don't know.
How do I successfully throw away the return value of a function and treat it as if it's returning unit (for side-effects, obviously). The obvious approach is to do this:
let foo = begin
some_ignored_thing ();
actual_return
end
However, the compiler complains (with a warning) that the return type of some_ignored_thing isn't unit.
I could invent my own method, such as:
let ignore a = ()
Which seems at least concise and flags that something's going on, but is there anything in the language/stdlib that achieves the same thing? I'd have thought it would be a relatively common use case.
Indeed, there is an ignore : 'a -> unit function that does exactly this.
The compiler actually knows about ignore and hard-code a specific behavior that is generally very useful, but can occasionally be inconvenient: by default, ignoring a function (anything with a type of the form foo -> bar) will raise a warning.
The reason for this is that forgetting to add the last argument of a function is a relatively common mistake. You may write for example
ignore (List.map (fun x -> foo bar))
while you meant to write
ignore (List.map (fun x -> foo bar) li)
and the effects you expect to see applied are not.
So ignore will raise a warning in this case, which your hand-coded let ignore x = () does not do. People also sometimes write
let _ = foo in ...
to ignore foo, but this suffer from the same downside (it's easy to be wrong about what the type actually is). Kakadu recommends to use a type annotation there, and that's a reasonable advice.
(Some people also use let _ = ... for the "main" expression of their program. I recommend to rather use let () = ... for this same reason that it forces more type precision.)
Finally, some people prefer to use the let _ = ... form because they are in situations where using ; would force them to add parentheses or begin..end. I recommend that you always add parentheses or begin..end in these cases, because it's easy to shoot yourself in the foot with that -- obscure precedence rules for if..then..else.. for example.
Currently in my program I have several common blocks spread across several subprograms and functions. I sometimes forget to change all instances of a common block as I add variables to it. I want to make these common blocks into modules so I can add and remove variables to the module in one place without worrying about updating all instances of the module across my subprograms.
Do I need to include 'use' statements in the program that initializes the variables in the module or do I include the program in the module? I normally would use common blocks for this but am trying to implement modules because I think they will help my code remain readable as complexity increases.
NOTE: Some values of the variables in the modules need to be able to change as they are passed from one program to another.
I tried to write a simplified test program to become acquainted with modules but could not get it to work. I am familiar with fortran 77 but have never used modules before. I appreciate any help or advice.
I am using gfortran 4.6.1
Main.f
program main
use Words
use Vals
double precision x,y,z
character*5 Greet
integer i
Greet = 'Hello'
x = 4.1
y = 5.2
z = 10.0
i = 3
call foo ()
end program main
subroutine foo ()
use Words
use Vals
print *, Greet
z = x + y
print *, z
print *, i
end subroutine
module Words
character*5 Greet
save
end module
module Vals
double precision x,y
integer int
save
end module
You only need one instance of a module. You make it known to any main program or procedure (subroutine or function) that uses it with a use statement. If you have a subroutine that sets values then, like any other, it has to have a use statement. If are are setting initial values you can do so in the declaration. If the module is used by the main program then it will always be in scope and the values of the variables will persist throughout the run of the program. If the module is only used by procedure, in principle the module will go out of scope when none of those procedures are in the call chain and the compiler is allowed to forget the values of the module variables. (It is doubtful that any Fortran compiler actually does this.) This can be prevented by declaring each variable with SAVE. SAVE is implicit if you declare the variable with an initial value.
Normally you have to compile the modules first before they are used so that the compiler "knows" about them when it encounters the use statement. This is done either by putting them first in the file or compiling their files first. Here is your example reordered:
module Words
character*5 Greet
save
end module
module Vals
double precision x,y
integer i
save
end module
module my_subs
contains
subroutine foo ()
use Words
use Vals
double precision :: z
print *, Greet
z = x + y
print *, z
print *, i
end subroutine
end module my_subs
program main
use Words
use Vals
use my_subs
Greet = 'Hello'
x = 4.1
y = 5.2
i = 3
call foo ()
end program main
There are a couple of reasons why your code will not compile:
You have your modules positioned after your main program, which means they will not have been compiled by the time you use them there. Either put these in separate files and compile them before the main program, or put them before the main program.
You re-declare variables from your module in the main program, which the compiler will interpret as a name conflict. All module variables with the public attribute (which is the default) will become available in the scope where you use the module; this is called "use association". In other words, use vals is enough to make x, y and int available.
Additionally, modules are more like singleton objects rather than just data containers. They can also contain procedures, listed after a contains statement, which aids grouping variables and related procedures together. An example would be grouping your two modules into one, along with subroutine foo:
module vals
implicit none
double precision :: x = 4.1, y = 5.2
integer :: i = 3
character(5) :: greet = 'Hello'
contains
subroutine foo()
double precision :: z ! New local variable
print *, Greet
z = x + y
print *, z
print *, i
end subroutine
end module
Above, I have used the "new" :: double colon operator, which allows declaring and initialising multiple variables at once. Since module variables are already save'd implicitly, this is just fine.
Alternatively, if these modules are intended to be separate, you can also have contains sections in your main program (or any subprogram) and place the subroutine there. The advantage is that procedures declared in such a way always have explicit interfaces, which greatly benefits error diagnosis by the compiler and is even required in certain newer cases. This is one of the main improvements of F90, since F77 only dealt with external subprograms and implicit interfaces.
The simplest way to do common blocks is to have one include file per common block and make all your declarations within the include file. That way, the common block is only ever declared in one place. The problem of having to convert the code to use modules then just magically disappears.
Also, if you are starting new code, prefixing the name of the common block variables with the same name as the named common block will make coding a lot easier. It is a pain initially and the prima donnas who have been coding for years will refuse to conform. The people who maintain the code will just find it so easy: no greps or groks. Just by looking at the name, you know which common block it comes from.
Keeping the same convention with modules also helps. If all routine names and variable names begin with the module name, then just by looking at the name, you know which module it comes from.